omdev 0.0.0.dev463__py3-none-any.whl → 0.0.0.dev465__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of omdev might be problematic. Click here for more details.

omdev/__about__.py CHANGED
@@ -58,7 +58,8 @@ class Project(ProjectBase):
58
58
 
59
59
 
60
60
  class Setuptools(SetuptoolsBase):
61
- cexts = True
61
+ cext = True
62
+ rs = True
62
63
 
63
64
  find_packages = {
64
65
  'include': [Project.name, f'{Project.name}.*'],
omdev/pyproject/pkg.py CHANGED
@@ -28,10 +28,12 @@ vcs+protocol://repo_url/#egg=pkg&subdirectory=pkg_dir
28
28
  import abc
29
29
  import dataclasses as dc
30
30
  import importlib
31
+ import inspect
31
32
  import os.path
32
33
  import shutil
33
34
  import sys
34
35
  import tempfile
36
+ import textwrap
35
37
  import types
36
38
  import typing as ta
37
39
 
@@ -260,6 +262,7 @@ class BasePyprojectPackageGenerator(Abstract):
260
262
  )
261
263
 
262
264
  if output_dir is not None:
265
+ log.info(lambda: f'Copying {dist_dir} to {output_dir}')
263
266
  for fn in os.listdir(dist_dir):
264
267
  shutil.copyfile(os.path.join(dist_dir, fn), os.path.join(output_dir, fn))
265
268
 
@@ -315,7 +318,11 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
315
318
  st = dict(specs.setuptools)
316
319
  pyp_dct['tool.setuptools'] = st
317
320
 
318
- st.pop('cexts', None)
321
+ for k in [
322
+ 'cext',
323
+ 'rs',
324
+ ]:
325
+ st.pop(k, None)
319
326
 
320
327
  #
321
328
 
@@ -388,13 +395,20 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
388
395
  def children(self) -> ta.Sequence[BasePyprojectPackageGenerator]:
389
396
  out: ta.List[BasePyprojectPackageGenerator] = []
390
397
 
391
- if self.build_specs().setuptools.get('cexts'):
398
+ if self.build_specs().setuptools.get('cext'):
392
399
  out.append(_PyprojectCextPackageGenerator(
393
400
  self._dir_name,
394
401
  self._pkgs_root,
395
402
  pkg_suffix='-cext',
396
403
  ))
397
404
 
405
+ if self.build_specs().setuptools.get('rs'):
406
+ out.append(_PyprojectRsPackageGenerator(
407
+ self._dir_name,
408
+ self._pkgs_root,
409
+ pkg_suffix='-rs',
410
+ ))
411
+
398
412
  if self.build_specs().pyproject.get('cli_scripts'):
399
413
  out.append(_PyprojectCliPackageGenerator(
400
414
  self._dir_name,
@@ -405,10 +419,67 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
405
419
  return out
406
420
 
407
421
 
408
- #
422
+ ##
409
423
 
410
424
 
411
- class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
425
+ class _PyprojectExtensionPackageGenerator(BasePyprojectPackageGenerator, Abstract):
426
+ #
427
+
428
+ def _build_project_dict(self) -> ta.Dict[str, ta.Any]:
429
+ prj = dict(self.build_specs().pyproject)
430
+
431
+ prj['dependencies'] = [f'{prj["name"]} == {prj["version"]}']
432
+ prj['name'] += self._pkg_suffix
433
+
434
+ for k in [
435
+ 'optional_dependencies',
436
+ 'entry_points',
437
+ 'scripts',
438
+ 'cli_scripts',
439
+ ]:
440
+ prj.pop(k, None)
441
+
442
+ return prj
443
+
444
+ def _build_setuptools_dict(self) -> ta.Dict[str, ta.Any]:
445
+ st = dict(self.build_specs().setuptools)
446
+
447
+ for k in [
448
+ 'cext',
449
+ 'rs',
450
+
451
+ 'find_packages',
452
+ 'package_data',
453
+ 'manifest_in',
454
+ ]:
455
+ st.pop(k, None)
456
+
457
+ return st
458
+
459
+ #
460
+
461
+ @dc.dataclass(frozen=True)
462
+ class FileContents:
463
+ pyproject_dct: ta.Mapping[str, ta.Any]
464
+ setup_py: str
465
+
466
+ @abc.abstractmethod
467
+ def file_contents(self) -> FileContents:
468
+ raise NotImplementedError
469
+
470
+ #
471
+
472
+ def _write_file_contents(self) -> None:
473
+ fc = self.file_contents()
474
+
475
+ with open(os.path.join(self._pkg_dir(), 'pyproject.toml'), 'w') as f:
476
+ TomlWriter(f).write_root(fc.pyproject_dct)
477
+
478
+ with open(os.path.join(self._pkg_dir(), 'setup.py'), 'w') as f:
479
+ f.write(fc.setup_py)
480
+
481
+
482
+ class _PyprojectCextPackageGenerator(_PyprojectExtensionPackageGenerator):
412
483
  @cached_nullary
413
484
  def find_cext_srcs(self) -> ta.Sequence[str]:
414
485
  return sorted(find_magic_files(
@@ -419,14 +490,10 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
419
490
 
420
491
  #
421
492
 
422
- @dc.dataclass(frozen=True)
423
- class FileContents:
424
- pyproject_dct: ta.Mapping[str, ta.Any]
425
- setup_py: str
426
-
427
493
  @cached_nullary
428
- def file_contents(self) -> FileContents:
429
- specs = self.build_specs()
494
+ def file_contents(self) -> _PyprojectExtensionPackageGenerator.FileContents:
495
+ prj = self._build_project_dict()
496
+ st = self._build_setuptools_dict()
430
497
 
431
498
  #
432
499
 
@@ -437,33 +504,9 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
437
504
  'build-backend': 'setuptools.build_meta',
438
505
  }
439
506
 
440
- prj = specs.pyproject
441
- prj['dependencies'] = [f'{prj["name"]} == {prj["version"]}']
442
- prj['name'] += self._pkg_suffix
443
- for k in [
444
- 'optional_dependencies',
445
- 'entry_points',
446
- 'scripts',
447
- 'cli_scripts',
448
- ]:
449
- prj.pop(k, None)
450
-
451
507
  pyp_dct['project'] = prj
452
-
453
- #
454
-
455
- st = dict(specs.setuptools)
456
508
  pyp_dct['tool.setuptools'] = st
457
509
 
458
- for k in [
459
- 'cexts',
460
-
461
- 'find_packages',
462
- 'package_data',
463
- 'manifest_in',
464
- ]:
465
- st.pop(k, None)
466
-
467
510
  pyp_dct['tool.setuptools.packages.find'] = {
468
511
  'include': [],
469
512
  }
@@ -501,14 +544,110 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
501
544
  src,
502
545
  )
503
546
 
504
- def _write_file_contents(self) -> None:
505
- fc = self.file_contents()
506
547
 
507
- with open(os.path.join(self._pkg_dir(), 'pyproject.toml'), 'w') as f:
508
- TomlWriter(f).write_root(fc.pyproject_dct)
548
+ class _PyprojectRsPackageGenerator(_PyprojectExtensionPackageGenerator):
549
+ @cached_nullary
550
+ def find_rs_dirs(self) -> ta.Sequence[str]:
551
+ return sorted(
552
+ dp
553
+ for dp, dns, fns in os.walk(self._dir_name)
554
+ for fn in fns
555
+ if fn == '.omlish-rs-ext'
556
+ )
509
557
 
510
- with open(os.path.join(self._pkg_dir(), 'setup.py'), 'w') as f:
511
- f.write(fc.setup_py)
558
+ #
559
+
560
+ @staticmethod
561
+ def _sdist_patch_body() -> None:
562
+ def _patch_sdist():
563
+ def _sdist_add_defaults(old, self):
564
+ import os.path
565
+
566
+ old(self)
567
+
568
+ if self.distribution.rust_extensions and len(self.distribution.rust_extensions) > 0:
569
+ build_rust = self.get_finalized_command('build_rust') # noqa
570
+ for ext in build_rust.extensions:
571
+ ext_dir = os.path.dirname(ext.path)
572
+ for n in os.listdir(ext_dir):
573
+ if n.startswith('.') or n == 'target':
574
+ continue
575
+ p = os.path.join(ext_dir, n)
576
+ if os.path.isfile(p):
577
+ self.filelist.append(p)
578
+ elif os.path.isdir(p):
579
+ self.filelist.extend(os.path.join(dp, f) for dp, dn, fn in os.walk(p) for f in fn)
580
+
581
+ # Sadly, we can't just subclass sdist and override it via cmdclass because manifest_maker calls
582
+ # `sdist.add_defaults` as an unbound function, not a bound method:
583
+ # https://github.com/pypa/setuptools/blob/9c4d383631d3951fcae0afd73b5d08ff5a262976/setuptools/command/egg_info.py#L581
584
+ from setuptools.command.sdist import sdist # noqa
585
+ sdist.add_defaults = (lambda old: lambda sdist: _sdist_add_defaults(old, sdist))(sdist.add_defaults) # noqa
586
+
587
+ _patch_sdist()
588
+
589
+ @cached_nullary
590
+ def sdist_patch_code(self) -> str:
591
+ return textwrap.dedent(''.join(inspect.getsource(self._sdist_patch_body).splitlines(keepends=True)[2:])).strip()
592
+
593
+ #
594
+
595
+ @cached_nullary
596
+ def file_contents(self) -> _PyprojectExtensionPackageGenerator.FileContents:
597
+ prj = self._build_project_dict()
598
+ st = self._build_setuptools_dict()
599
+
600
+ #
601
+
602
+ pyp_dct = {}
603
+
604
+ pyp_dct['build-system'] = {
605
+ 'requires': ['setuptools', 'setuptools-rust'],
606
+ 'build-backend': 'setuptools.build_meta',
607
+ }
608
+
609
+ pyp_dct['project'] = prj
610
+ pyp_dct['tool.setuptools'] = st
611
+
612
+ pyp_dct['tool.setuptools.packages.find'] = {
613
+ 'include': [],
614
+ }
615
+
616
+ #
617
+
618
+ ext_lines: list = []
619
+
620
+ for ext_dir in self.find_rs_dirs(): # noqa
621
+ ext_name = ext_dir.replace(os.sep, '.')
622
+ ext_lines.extend([
623
+ 'st_rs.RustExtension(',
624
+ f" '{ext_name}',",
625
+ f" path='{ext_dir}/Cargo.toml',",
626
+ '),',
627
+ ])
628
+
629
+ src = '\n'.join([
630
+ 'import setuptools as st',
631
+ 'import setuptools_rust as st_rs',
632
+ '',
633
+ '',
634
+ self.sdist_patch_code(),
635
+ '',
636
+ '',
637
+ 'st.setup(',
638
+ ' rust_extensions=[',
639
+ *[' ' + l for l in ext_lines],
640
+ ' ],',
641
+ ')',
642
+ '',
643
+ ])
644
+
645
+ #
646
+
647
+ return self.FileContents(
648
+ pyp_dct,
649
+ src,
650
+ )
512
651
 
513
652
 
514
653
  ##
@@ -553,7 +692,8 @@ class _PyprojectCliPackageGenerator(BasePyprojectPackageGenerator):
553
692
  pyp_dct['tool.setuptools'] = st
554
693
 
555
694
  for k in [
556
- 'cexts',
695
+ 'cext',
696
+ 'rs',
557
697
 
558
698
  'find_packages',
559
699
  'package_data',
omdev/rs/__init__.py ADDED
File without changes
@@ -65,6 +65,7 @@ import subprocess
65
65
  import sys
66
66
  import tarfile
67
67
  import tempfile
68
+ import textwrap
68
69
  import threading
69
70
  import time
70
71
  import traceback
@@ -11016,6 +11017,7 @@ class BasePyprojectPackageGenerator(Abstract):
11016
11017
  )
11017
11018
 
11018
11019
  if output_dir is not None:
11020
+ log.info(lambda: f'Copying {dist_dir} to {output_dir}')
11019
11021
  for fn in os.listdir(dist_dir):
11020
11022
  shutil.copyfile(os.path.join(dist_dir, fn), os.path.join(output_dir, fn))
11021
11023
 
@@ -11071,7 +11073,11 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
11071
11073
  st = dict(specs.setuptools)
11072
11074
  pyp_dct['tool.setuptools'] = st
11073
11075
 
11074
- st.pop('cexts', None)
11076
+ for k in [
11077
+ 'cext',
11078
+ 'rs',
11079
+ ]:
11080
+ st.pop(k, None)
11075
11081
 
11076
11082
  #
11077
11083
 
@@ -11144,13 +11150,20 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
11144
11150
  def children(self) -> ta.Sequence[BasePyprojectPackageGenerator]:
11145
11151
  out: ta.List[BasePyprojectPackageGenerator] = []
11146
11152
 
11147
- if self.build_specs().setuptools.get('cexts'):
11153
+ if self.build_specs().setuptools.get('cext'):
11148
11154
  out.append(_PyprojectCextPackageGenerator(
11149
11155
  self._dir_name,
11150
11156
  self._pkgs_root,
11151
11157
  pkg_suffix='-cext',
11152
11158
  ))
11153
11159
 
11160
+ if self.build_specs().setuptools.get('rs'):
11161
+ out.append(_PyprojectRsPackageGenerator(
11162
+ self._dir_name,
11163
+ self._pkgs_root,
11164
+ pkg_suffix='-rs',
11165
+ ))
11166
+
11154
11167
  if self.build_specs().pyproject.get('cli_scripts'):
11155
11168
  out.append(_PyprojectCliPackageGenerator(
11156
11169
  self._dir_name,
@@ -11161,10 +11174,67 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
11161
11174
  return out
11162
11175
 
11163
11176
 
11164
- #
11177
+ ##
11165
11178
 
11166
11179
 
11167
- class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
11180
+ class _PyprojectExtensionPackageGenerator(BasePyprojectPackageGenerator, Abstract):
11181
+ #
11182
+
11183
+ def _build_project_dict(self) -> ta.Dict[str, ta.Any]:
11184
+ prj = dict(self.build_specs().pyproject)
11185
+
11186
+ prj['dependencies'] = [f'{prj["name"]} == {prj["version"]}']
11187
+ prj['name'] += self._pkg_suffix
11188
+
11189
+ for k in [
11190
+ 'optional_dependencies',
11191
+ 'entry_points',
11192
+ 'scripts',
11193
+ 'cli_scripts',
11194
+ ]:
11195
+ prj.pop(k, None)
11196
+
11197
+ return prj
11198
+
11199
+ def _build_setuptools_dict(self) -> ta.Dict[str, ta.Any]:
11200
+ st = dict(self.build_specs().setuptools)
11201
+
11202
+ for k in [
11203
+ 'cext',
11204
+ 'rs',
11205
+
11206
+ 'find_packages',
11207
+ 'package_data',
11208
+ 'manifest_in',
11209
+ ]:
11210
+ st.pop(k, None)
11211
+
11212
+ return st
11213
+
11214
+ #
11215
+
11216
+ @dc.dataclass(frozen=True)
11217
+ class FileContents:
11218
+ pyproject_dct: ta.Mapping[str, ta.Any]
11219
+ setup_py: str
11220
+
11221
+ @abc.abstractmethod
11222
+ def file_contents(self) -> FileContents:
11223
+ raise NotImplementedError
11224
+
11225
+ #
11226
+
11227
+ def _write_file_contents(self) -> None:
11228
+ fc = self.file_contents()
11229
+
11230
+ with open(os.path.join(self._pkg_dir(), 'pyproject.toml'), 'w') as f:
11231
+ TomlWriter(f).write_root(fc.pyproject_dct)
11232
+
11233
+ with open(os.path.join(self._pkg_dir(), 'setup.py'), 'w') as f:
11234
+ f.write(fc.setup_py)
11235
+
11236
+
11237
+ class _PyprojectCextPackageGenerator(_PyprojectExtensionPackageGenerator):
11168
11238
  @cached_nullary
11169
11239
  def find_cext_srcs(self) -> ta.Sequence[str]:
11170
11240
  return sorted(find_magic_files(
@@ -11175,14 +11245,10 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
11175
11245
 
11176
11246
  #
11177
11247
 
11178
- @dc.dataclass(frozen=True)
11179
- class FileContents:
11180
- pyproject_dct: ta.Mapping[str, ta.Any]
11181
- setup_py: str
11182
-
11183
11248
  @cached_nullary
11184
- def file_contents(self) -> FileContents:
11185
- specs = self.build_specs()
11249
+ def file_contents(self) -> _PyprojectExtensionPackageGenerator.FileContents:
11250
+ prj = self._build_project_dict()
11251
+ st = self._build_setuptools_dict()
11186
11252
 
11187
11253
  #
11188
11254
 
@@ -11193,33 +11259,9 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
11193
11259
  'build-backend': 'setuptools.build_meta',
11194
11260
  }
11195
11261
 
11196
- prj = specs.pyproject
11197
- prj['dependencies'] = [f'{prj["name"]} == {prj["version"]}']
11198
- prj['name'] += self._pkg_suffix
11199
- for k in [
11200
- 'optional_dependencies',
11201
- 'entry_points',
11202
- 'scripts',
11203
- 'cli_scripts',
11204
- ]:
11205
- prj.pop(k, None)
11206
-
11207
11262
  pyp_dct['project'] = prj
11208
-
11209
- #
11210
-
11211
- st = dict(specs.setuptools)
11212
11263
  pyp_dct['tool.setuptools'] = st
11213
11264
 
11214
- for k in [
11215
- 'cexts',
11216
-
11217
- 'find_packages',
11218
- 'package_data',
11219
- 'manifest_in',
11220
- ]:
11221
- st.pop(k, None)
11222
-
11223
11265
  pyp_dct['tool.setuptools.packages.find'] = {
11224
11266
  'include': [],
11225
11267
  }
@@ -11257,14 +11299,110 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
11257
11299
  src,
11258
11300
  )
11259
11301
 
11260
- def _write_file_contents(self) -> None:
11261
- fc = self.file_contents()
11262
11302
 
11263
- with open(os.path.join(self._pkg_dir(), 'pyproject.toml'), 'w') as f:
11264
- TomlWriter(f).write_root(fc.pyproject_dct)
11303
+ class _PyprojectRsPackageGenerator(_PyprojectExtensionPackageGenerator):
11304
+ @cached_nullary
11305
+ def find_rs_dirs(self) -> ta.Sequence[str]:
11306
+ return sorted(
11307
+ dp
11308
+ for dp, dns, fns in os.walk(self._dir_name)
11309
+ for fn in fns
11310
+ if fn == '.omlish-rs-ext'
11311
+ )
11265
11312
 
11266
- with open(os.path.join(self._pkg_dir(), 'setup.py'), 'w') as f:
11267
- f.write(fc.setup_py)
11313
+ #
11314
+
11315
+ @staticmethod
11316
+ def _sdist_patch_body() -> None:
11317
+ def _patch_sdist():
11318
+ def _sdist_add_defaults(old, self):
11319
+ import os.path
11320
+
11321
+ old(self)
11322
+
11323
+ if self.distribution.rust_extensions and len(self.distribution.rust_extensions) > 0:
11324
+ build_rust = self.get_finalized_command('build_rust') # noqa
11325
+ for ext in build_rust.extensions:
11326
+ ext_dir = os.path.dirname(ext.path)
11327
+ for n in os.listdir(ext_dir):
11328
+ if n.startswith('.') or n == 'target':
11329
+ continue
11330
+ p = os.path.join(ext_dir, n)
11331
+ if os.path.isfile(p):
11332
+ self.filelist.append(p)
11333
+ elif os.path.isdir(p):
11334
+ self.filelist.extend(os.path.join(dp, f) for dp, dn, fn in os.walk(p) for f in fn)
11335
+
11336
+ # Sadly, we can't just subclass sdist and override it via cmdclass because manifest_maker calls
11337
+ # `sdist.add_defaults` as an unbound function, not a bound method:
11338
+ # https://github.com/pypa/setuptools/blob/9c4d383631d3951fcae0afd73b5d08ff5a262976/setuptools/command/egg_info.py#L581
11339
+ from setuptools.command.sdist import sdist # noqa
11340
+ sdist.add_defaults = (lambda old: lambda sdist: _sdist_add_defaults(old, sdist))(sdist.add_defaults) # noqa
11341
+
11342
+ _patch_sdist()
11343
+
11344
+ @cached_nullary
11345
+ def sdist_patch_code(self) -> str:
11346
+ return textwrap.dedent(''.join(inspect.getsource(self._sdist_patch_body).splitlines(keepends=True)[2:])).strip()
11347
+
11348
+ #
11349
+
11350
+ @cached_nullary
11351
+ def file_contents(self) -> _PyprojectExtensionPackageGenerator.FileContents:
11352
+ prj = self._build_project_dict()
11353
+ st = self._build_setuptools_dict()
11354
+
11355
+ #
11356
+
11357
+ pyp_dct = {}
11358
+
11359
+ pyp_dct['build-system'] = {
11360
+ 'requires': ['setuptools', 'setuptools-rust'],
11361
+ 'build-backend': 'setuptools.build_meta',
11362
+ }
11363
+
11364
+ pyp_dct['project'] = prj
11365
+ pyp_dct['tool.setuptools'] = st
11366
+
11367
+ pyp_dct['tool.setuptools.packages.find'] = {
11368
+ 'include': [],
11369
+ }
11370
+
11371
+ #
11372
+
11373
+ ext_lines: list = []
11374
+
11375
+ for ext_dir in self.find_rs_dirs(): # noqa
11376
+ ext_name = ext_dir.replace(os.sep, '.')
11377
+ ext_lines.extend([
11378
+ 'st_rs.RustExtension(',
11379
+ f" '{ext_name}',",
11380
+ f" path='{ext_dir}/Cargo.toml',",
11381
+ '),',
11382
+ ])
11383
+
11384
+ src = '\n'.join([
11385
+ 'import setuptools as st',
11386
+ 'import setuptools_rust as st_rs',
11387
+ '',
11388
+ '',
11389
+ self.sdist_patch_code(),
11390
+ '',
11391
+ '',
11392
+ 'st.setup(',
11393
+ ' rust_extensions=[',
11394
+ *[' ' + l for l in ext_lines],
11395
+ ' ],',
11396
+ ')',
11397
+ '',
11398
+ ])
11399
+
11400
+ #
11401
+
11402
+ return self.FileContents(
11403
+ pyp_dct,
11404
+ src,
11405
+ )
11268
11406
 
11269
11407
 
11270
11408
  ##
@@ -11309,7 +11447,8 @@ class _PyprojectCliPackageGenerator(BasePyprojectPackageGenerator):
11309
11447
  pyp_dct['tool.setuptools'] = st
11310
11448
 
11311
11449
  for k in [
11312
- 'cexts',
11450
+ 'cext',
11451
+ 'rs',
11313
11452
 
11314
11453
  'find_packages',
11315
11454
  'package_data',
@@ -9,6 +9,7 @@ with _lang.auto_proxy_init(globals()):
9
9
  from rich import console # noqa
10
10
  from rich import live # noqa
11
11
  from rich import markdown # noqa
12
+ from rich import repr # noqa
12
13
  from rich import text # noqa
13
14
  from rich.console import Console # noqa
14
15
  from rich.live import Live # noqa
@@ -8,13 +8,16 @@ with _lang.auto_proxy_init(globals()):
8
8
 
9
9
  from textual import app # noqa
10
10
  from textual import binding # noqa
11
+ from textual import constants # noqa
11
12
  from textual import containers # noqa
12
13
  from textual import content # noqa
13
14
  from textual import driver # noqa
14
15
  from textual import events # noqa
16
+ from textual import geometry # noqa
15
17
  from textual import markup # noqa
16
18
  from textual import message # noqa
17
19
  from textual import messages # noqa
20
+ from textual import on # noqa
18
21
  from textual import pad # noqa
19
22
  from textual import reactive # noqa
20
23
  from textual import screen # noqa
@@ -116,6 +119,16 @@ with _lang.auto_proxy_init(globals()):
116
119
  from textual.events import Show # noqa
117
120
  from textual.events import Timer as TimerEvent # noqa
118
121
  from textual.events import Unmount # noqa
122
+ from textual.geometry import NULL_OFFSET # noqa
123
+ from textual.geometry import NULL_REGION # noqa
124
+ from textual.geometry import NULL_SIZE # noqa
125
+ from textual.geometry import NULL_SPACING # noqa
126
+ from textual.geometry import Offset # noqa
127
+ from textual.geometry import Region # noqa
128
+ from textual.geometry import Size # noqa
129
+ from textual.geometry import Spacing # noqa
130
+ from textual.geometry import SpacingDimensions # noqa
131
+ from textual.geometry import clamp # noqa
119
132
  from textual.markup import MarkupError # noqa
120
133
  from textual.markup import MarkupTokenizer # noqa
121
134
  from textual.markup import StyleTokenizer # noqa
@@ -197,6 +210,9 @@ with _lang.auto_proxy_init(globals()):
197
210
  from textual.widgets import Tooltip # noqa
198
211
  from textual.widgets import Tree # noqa
199
212
  from textual.widgets import Welcome # noqa
213
+ from textual.widgets.option_list import OptionDoesNotExist # noqa
214
+ from textual.widgets.option_list import Option # noqa
215
+ from textual.widgets.option_list import DuplicateID # noqa
200
216
 
201
217
  ##
202
218
 
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Darren Burns
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.