omdev 0.0.0.dev179__py3-none-any.whl → 0.0.0.dev181__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.
@@ -66,7 +66,7 @@ import time
66
66
  import types
67
67
  import typing as ta
68
68
  import uuid
69
- import weakref # noqa
69
+ import weakref
70
70
  import zipfile
71
71
 
72
72
 
@@ -108,13 +108,18 @@ CheckOnRaiseFn = ta.Callable[[Exception], None] # ta.TypeAlias
108
108
  CheckExceptionFactory = ta.Callable[..., Exception] # ta.TypeAlias
109
109
  CheckArgsRenderer = ta.Callable[..., ta.Optional[str]] # ta.TypeAlias
110
110
 
111
+ # ../../omlish/lite/typing.py
112
+ A0 = ta.TypeVar('A0')
113
+ A1 = ta.TypeVar('A1')
114
+ A2 = ta.TypeVar('A2')
115
+
111
116
  # ../packaging/specifiers.py
112
117
  UnparsedVersion = ta.Union['Version', str]
113
118
  UnparsedVersionVar = ta.TypeVar('UnparsedVersionVar', bound=UnparsedVersion)
114
119
  CallableVersionOperator = ta.Callable[['Version', str], bool]
115
120
 
116
121
  # ../../omlish/argparse/cli.py
117
- ArgparseCommandFn = ta.Callable[[], ta.Optional[int]] # ta.TypeAlias
122
+ ArgparseCmdFn = ta.Callable[[], ta.Optional[int]] # ta.TypeAlias
118
123
 
119
124
  # ../../omlish/lite/inject.py
120
125
  U = ta.TypeVar('U')
@@ -2575,6 +2580,54 @@ def format_num_bytes(num_bytes: int) -> str:
2575
2580
  return f'{num_bytes / 1024 ** (len(FORMAT_NUM_BYTES_SUFFIXES) - 1):.2f}{FORMAT_NUM_BYTES_SUFFIXES[-1]}'
2576
2581
 
2577
2582
 
2583
+ ########################################
2584
+ # ../../../omlish/lite/typing.py
2585
+
2586
+
2587
+ ##
2588
+ # A workaround for typing deficiencies (like `Argument 2 to NewType(...) must be subclassable`).
2589
+
2590
+
2591
+ @dc.dataclass(frozen=True)
2592
+ class AnyFunc(ta.Generic[T]):
2593
+ fn: ta.Callable[..., T]
2594
+
2595
+ def __call__(self, *args: ta.Any, **kwargs: ta.Any) -> T:
2596
+ return self.fn(*args, **kwargs)
2597
+
2598
+
2599
+ @dc.dataclass(frozen=True)
2600
+ class Func0(ta.Generic[T]):
2601
+ fn: ta.Callable[[], T]
2602
+
2603
+ def __call__(self) -> T:
2604
+ return self.fn()
2605
+
2606
+
2607
+ @dc.dataclass(frozen=True)
2608
+ class Func1(ta.Generic[A0, T]):
2609
+ fn: ta.Callable[[A0], T]
2610
+
2611
+ def __call__(self, a0: A0) -> T:
2612
+ return self.fn(a0)
2613
+
2614
+
2615
+ @dc.dataclass(frozen=True)
2616
+ class Func2(ta.Generic[A0, A1, T]):
2617
+ fn: ta.Callable[[A0, A1], T]
2618
+
2619
+ def __call__(self, a0: A0, a1: A1) -> T:
2620
+ return self.fn(a0, a1)
2621
+
2622
+
2623
+ @dc.dataclass(frozen=True)
2624
+ class Func3(ta.Generic[A0, A1, A2, T]):
2625
+ fn: ta.Callable[[A0, A1, A2], T]
2626
+
2627
+ def __call__(self, a0: A0, a1: A1, a2: A2) -> T:
2628
+ return self.fn(a0, a1, a2)
2629
+
2630
+
2578
2631
  ########################################
2579
2632
  # ../../../omlish/logs/filters.py
2580
2633
 
@@ -2910,16 +2963,6 @@ def find_magic_py_modules(
2910
2963
  yield fp
2911
2964
 
2912
2965
 
2913
- ##
2914
-
2915
-
2916
- # # @omlish-manifest
2917
- # _CLI_MODULE = {'$omdev.cli.types.CliModule': {
2918
- # 'cmd_name': 'py/findmagic',
2919
- # 'mod_name': __name__,
2920
- # }}
2921
-
2922
-
2923
2966
  ########################################
2924
2967
  # ../../packaging/specifiers.py
2925
2968
  # Copyright (c) Donald Stufft and individual contributors.
@@ -3553,15 +3596,15 @@ def argparse_arg(*args, **kwargs) -> ArgparseArg:
3553
3596
 
3554
3597
 
3555
3598
  @dc.dataclass(eq=False)
3556
- class ArgparseCommand:
3599
+ class ArgparseCmd:
3557
3600
  name: str
3558
- fn: ArgparseCommandFn
3601
+ fn: ArgparseCmdFn
3559
3602
  args: ta.Sequence[ArgparseArg] = () # noqa
3560
3603
 
3561
3604
  # _: dc.KW_ONLY
3562
3605
 
3563
3606
  aliases: ta.Optional[ta.Sequence[str]] = None
3564
- parent: ta.Optional['ArgparseCommand'] = None
3607
+ parent: ta.Optional['ArgparseCmd'] = None
3565
3608
  accepts_unknown: bool = False
3566
3609
 
3567
3610
  def __post_init__(self) -> None:
@@ -3576,7 +3619,7 @@ class ArgparseCommand:
3576
3619
 
3577
3620
  check.arg(callable(self.fn))
3578
3621
  check.arg(all(isinstance(a, ArgparseArg) for a in self.args))
3579
- check.isinstance(self.parent, (ArgparseCommand, type(None)))
3622
+ check.isinstance(self.parent, (ArgparseCmd, type(None)))
3580
3623
  check.isinstance(self.accepts_unknown, bool)
3581
3624
 
3582
3625
  functools.update_wrapper(self, self.fn)
@@ -3590,21 +3633,21 @@ class ArgparseCommand:
3590
3633
  return self.fn(*args, **kwargs)
3591
3634
 
3592
3635
 
3593
- def argparse_command(
3636
+ def argparse_cmd(
3594
3637
  *args: ArgparseArg,
3595
3638
  name: ta.Optional[str] = None,
3596
3639
  aliases: ta.Optional[ta.Iterable[str]] = None,
3597
- parent: ta.Optional[ArgparseCommand] = None,
3640
+ parent: ta.Optional[ArgparseCmd] = None,
3598
3641
  accepts_unknown: bool = False,
3599
- ) -> ta.Any: # ta.Callable[[ArgparseCommandFn], ArgparseCommand]: # FIXME
3642
+ ) -> ta.Any: # ta.Callable[[ArgparseCmdFn], ArgparseCmd]: # FIXME
3600
3643
  for arg in args:
3601
3644
  check.isinstance(arg, ArgparseArg)
3602
3645
  check.isinstance(name, (str, type(None)))
3603
- check.isinstance(parent, (ArgparseCommand, type(None)))
3646
+ check.isinstance(parent, (ArgparseCmd, type(None)))
3604
3647
  check.not_isinstance(aliases, str)
3605
3648
 
3606
3649
  def inner(fn):
3607
- return ArgparseCommand(
3650
+ return ArgparseCmd(
3608
3651
  (name if name is not None else fn.__name__).replace('_', '-'),
3609
3652
  fn,
3610
3653
  args,
@@ -3659,7 +3702,7 @@ class ArgparseCli:
3659
3702
  for bns in [bcls.__dict__ for bcls in reversed(mro)] + [ns]:
3660
3703
  bseen = set() # type: ignore
3661
3704
  for k, v in bns.items():
3662
- if isinstance(v, (ArgparseCommand, ArgparseArg)):
3705
+ if isinstance(v, (ArgparseCmd, ArgparseArg)):
3663
3706
  check.not_in(v, bseen)
3664
3707
  bseen.add(v)
3665
3708
  objs[k] = v
@@ -3686,7 +3729,7 @@ class ArgparseCli:
3686
3729
  subparsers = parser.add_subparsers()
3687
3730
 
3688
3731
  for att, obj in objs.items():
3689
- if isinstance(obj, ArgparseCommand):
3732
+ if isinstance(obj, ArgparseCmd):
3690
3733
  if obj.parent is not None:
3691
3734
  raise NotImplementedError
3692
3735
 
@@ -3748,7 +3791,7 @@ class ArgparseCli:
3748
3791
 
3749
3792
  #
3750
3793
 
3751
- def _bind_cli_cmd(self, cmd: ArgparseCommand) -> ta.Callable:
3794
+ def _bind_cli_cmd(self, cmd: ArgparseCmd) -> ta.Callable:
3752
3795
  return cmd.__get__(self, type(self))
3753
3796
 
3754
3797
  def prepare_cli_run(self) -> ta.Optional[ta.Callable]:
@@ -5557,104 +5600,6 @@ def bind_interp_uv() -> InjectorBindings:
5557
5600
  return inj.as_bindings(*lst)
5558
5601
 
5559
5602
 
5560
- ########################################
5561
- # ../configs.py
5562
-
5563
-
5564
- @dc.dataclass(frozen=True)
5565
- class VenvConfig:
5566
- inherits: ta.Optional[ta.Sequence[str]] = None
5567
- interp: ta.Optional[str] = None
5568
- requires: ta.Optional[ta.List[str]] = None
5569
- docker: ta.Optional[str] = None
5570
- srcs: ta.Optional[ta.List[str]] = None
5571
- use_uv: ta.Optional[bool] = None
5572
-
5573
-
5574
- @dc.dataclass(frozen=True)
5575
- class PyprojectConfig:
5576
- pkgs: ta.Sequence[str] = dc.field(default_factory=list)
5577
- srcs: ta.Mapping[str, ta.Sequence[str]] = dc.field(default_factory=dict)
5578
- venvs: ta.Mapping[str, VenvConfig] = dc.field(default_factory=dict)
5579
-
5580
- venvs_dir: str = '.venvs'
5581
- versions_file: ta.Optional[str] = '.versions'
5582
-
5583
-
5584
- class PyprojectConfigPreparer:
5585
- def __init__(
5586
- self,
5587
- *,
5588
- python_versions: ta.Optional[ta.Mapping[str, str]] = None,
5589
- ) -> None:
5590
- super().__init__()
5591
-
5592
- self._python_versions = python_versions or {}
5593
-
5594
- def _inherit_venvs(self, m: ta.Mapping[str, VenvConfig]) -> ta.Mapping[str, VenvConfig]:
5595
- done: ta.Dict[str, VenvConfig] = {}
5596
-
5597
- def rec(k):
5598
- try:
5599
- return done[k]
5600
- except KeyError:
5601
- pass
5602
-
5603
- c = m[k]
5604
- kw = dc.asdict(c)
5605
- for i in c.inherits or ():
5606
- ic = rec(i)
5607
- kw.update({k: v for k, v in dc.asdict(ic).items() if v is not None and kw.get(k) is None})
5608
- del kw['inherits']
5609
-
5610
- d = done[k] = VenvConfig(**kw)
5611
- return d
5612
-
5613
- for k in m:
5614
- rec(k)
5615
- return done
5616
-
5617
- def _resolve_srcs(
5618
- self,
5619
- lst: ta.Sequence[str],
5620
- aliases: ta.Mapping[str, ta.Sequence[str]],
5621
- ) -> ta.List[str]:
5622
- todo = list(reversed(lst))
5623
- raw: ta.List[str] = []
5624
- seen: ta.Set[str] = set()
5625
-
5626
- while todo:
5627
- cur = todo.pop()
5628
- if cur in seen:
5629
- continue
5630
-
5631
- seen.add(cur)
5632
- if not cur.startswith('@'):
5633
- raw.append(cur)
5634
- continue
5635
-
5636
- todo.extend(aliases[cur[1:]][::-1])
5637
-
5638
- return raw
5639
-
5640
- def _fixup_interp(self, s: ta.Optional[str]) -> ta.Optional[str]:
5641
- if not s or not s.startswith('@'):
5642
- return s
5643
- return self._python_versions[s[1:]]
5644
-
5645
- def prepare_config(self, dct: ta.Mapping[str, ta.Any]) -> PyprojectConfig:
5646
- pcfg: PyprojectConfig = unmarshal_obj(dct, PyprojectConfig)
5647
-
5648
- ivs = dict(self._inherit_venvs(pcfg.venvs or {}))
5649
- for k, v in ivs.items():
5650
- v = dc.replace(v, srcs=self._resolve_srcs(v.srcs or [], pcfg.srcs or {}))
5651
- v = dc.replace(v, interp=self._fixup_interp(v.interp))
5652
- ivs[k] = v
5653
-
5654
- pcfg = dc.replace(pcfg, venvs=ivs)
5655
- return pcfg
5656
-
5657
-
5658
5603
  ########################################
5659
5604
  # ../../../omlish/logs/standard.py
5660
5605
  """
@@ -6453,9 +6398,15 @@ class InterpInspection:
6453
6398
 
6454
6399
 
6455
6400
  class InterpInspector:
6456
- def __init__(self) -> None:
6401
+ def __init__(
6402
+ self,
6403
+ *,
6404
+ log: ta.Optional[logging.Logger] = None,
6405
+ ) -> None:
6457
6406
  super().__init__()
6458
6407
 
6408
+ self._log = log
6409
+
6459
6410
  self._cache: ta.Dict[str, ta.Optional[InterpInspection]] = {}
6460
6411
 
6461
6412
  _RAW_INSPECTION_CODE = """
@@ -6504,8 +6455,8 @@ class InterpInspector:
6504
6455
  try:
6505
6456
  ret = await self._inspect(exe)
6506
6457
  except Exception as e: # noqa
6507
- if log.isEnabledFor(logging.DEBUG):
6508
- log.exception('Failed to inspect interp: %s', exe)
6458
+ if self._log is not None and self._log.isEnabledFor(logging.DEBUG):
6459
+ self._log.exception('Failed to inspect interp: %s', exe)
6509
6460
  ret = None
6510
6461
  self._cache[exe] = ret
6511
6462
  return ret
@@ -6765,12 +6716,14 @@ class SystemInterpProvider(InterpProvider):
6765
6716
  options: Options = Options(),
6766
6717
  *,
6767
6718
  inspector: ta.Optional[InterpInspector] = None,
6719
+ log: ta.Optional[logging.Logger] = None,
6768
6720
  ) -> None:
6769
6721
  super().__init__()
6770
6722
 
6771
6723
  self._options = options
6772
6724
 
6773
6725
  self._inspector = inspector
6726
+ self._log = log
6774
6727
 
6775
6728
  #
6776
6729
 
@@ -6844,7 +6797,8 @@ class SystemInterpProvider(InterpProvider):
6844
6797
  lst = []
6845
6798
  for e in self.exes():
6846
6799
  if (ev := await self.get_exe_version(e)) is None:
6847
- log.debug('Invalid system version: %s', e)
6800
+ if self._log is not None:
6801
+ self._log.debug('Invalid system version: %s', e)
6848
6802
  continue
6849
6803
  lst.append((e, ev))
6850
6804
  return lst
@@ -7201,6 +7155,7 @@ class PyenvInterpProvider(InterpProvider):
7201
7155
  *,
7202
7156
  pyenv: Pyenv,
7203
7157
  inspector: InterpInspector,
7158
+ log: ta.Optional[logging.Logger] = None,
7204
7159
  ) -> None:
7205
7160
  super().__init__()
7206
7161
 
@@ -7208,6 +7163,7 @@ class PyenvInterpProvider(InterpProvider):
7208
7163
 
7209
7164
  self._pyenv = pyenv
7210
7165
  self._inspector = inspector
7166
+ self._log = log
7211
7167
 
7212
7168
  #
7213
7169
 
@@ -7252,7 +7208,8 @@ class PyenvInterpProvider(InterpProvider):
7252
7208
  ret: ta.List[PyenvInterpProvider.Installed] = []
7253
7209
  for vn, ep in await self._pyenv.version_exes():
7254
7210
  if (i := await self._make_installed(vn, ep)) is None:
7255
- log.debug('Invalid pyenv version: %s', vn)
7211
+ if self._log is not None:
7212
+ self._log.debug('Invalid pyenv version: %s', vn)
7256
7213
  continue
7257
7214
  ret.append(i)
7258
7215
  return ret
@@ -7955,31 +7912,47 @@ def get_default_interp_resolver() -> InterpResolver:
7955
7912
 
7956
7913
 
7957
7914
  ########################################
7958
- # ../venvs.py
7915
+ # ../../interp/venvs.py
7959
7916
 
7960
7917
 
7961
7918
  ##
7962
7919
 
7963
7920
 
7964
- class Venv:
7921
+ @dc.dataclass(frozen=True)
7922
+ class InterpVenvConfig:
7923
+ interp: ta.Optional[str] = None
7924
+ requires: ta.Optional[ta.Sequence[str]] = None
7925
+ use_uv: ta.Optional[bool] = None
7926
+
7927
+
7928
+ class InterpVenvRequirementsProcessor(Func2['InterpVenv', ta.Sequence[str], ta.Sequence[str]]):
7929
+ pass
7930
+
7931
+
7932
+ class InterpVenv:
7965
7933
  def __init__(
7966
7934
  self,
7967
- name: str,
7968
- cfg: VenvConfig,
7935
+ path: str,
7936
+ cfg: InterpVenvConfig,
7937
+ *,
7938
+ requirements_processor: ta.Optional[InterpVenvRequirementsProcessor] = None,
7939
+ log: ta.Optional[logging.Logger] = None,
7969
7940
  ) -> None:
7970
7941
  super().__init__()
7971
- self._name = name
7942
+
7943
+ self._path = path
7972
7944
  self._cfg = cfg
7973
7945
 
7974
- @property
7975
- def cfg(self) -> VenvConfig:
7976
- return self._cfg
7946
+ self._requirements_processor = requirements_processor
7947
+ self._log = log
7977
7948
 
7978
- DIR_NAME = '.venvs'
7949
+ @property
7950
+ def path(self) -> str:
7951
+ return self._path
7979
7952
 
7980
7953
  @property
7981
- def dir_name(self) -> str:
7982
- return os.path.join(self.DIR_NAME, self._name)
7954
+ def cfg(self) -> InterpVenvConfig:
7955
+ return self._cfg
7983
7956
 
7984
7957
  @async_cached_nullary
7985
7958
  async def interp_exe(self) -> str:
@@ -7988,19 +7961,23 @@ class Venv:
7988
7961
 
7989
7962
  @cached_nullary
7990
7963
  def exe(self) -> str:
7991
- ve = os.path.join(self.dir_name, 'bin/python')
7964
+ ve = os.path.join(self._path, 'bin/python')
7992
7965
  if not os.path.isfile(ve):
7993
7966
  raise Exception(f'venv exe {ve} does not exist or is not a file!')
7994
7967
  return ve
7995
7968
 
7996
7969
  @async_cached_nullary
7997
7970
  async def create(self) -> bool:
7998
- if os.path.exists(dn := self.dir_name):
7971
+ if os.path.exists(dn := self._path):
7999
7972
  if not os.path.isdir(dn):
8000
7973
  raise Exception(f'{dn} exists but is not a directory!')
8001
7974
  return False
8002
7975
 
8003
- log.info('Using interpreter %s', (ie := await self.interp_exe()))
7976
+ ie = await self.interp_exe()
7977
+
7978
+ if self._log is not None:
7979
+ self._log.info('Using interpreter %s', ie)
7980
+
8004
7981
  await asyncio_subprocesses.check_call(ie, '-m', 'venv', dn)
8005
7982
 
8006
7983
  ve = self.exe()
@@ -8017,8 +7994,9 @@ class Venv:
8017
7994
  )
8018
7995
 
8019
7996
  if sr := self._cfg.requires:
8020
- rr = RequirementsRewriter(self._name)
8021
- reqs = [rr.rewrite(req) for req in sr]
7997
+ reqs = list(sr)
7998
+ if self._requirements_processor is not None:
7999
+ reqs = list(self._requirements_processor(self, reqs))
8022
8000
 
8023
8001
  # TODO: automatically try slower uv download when it fails? lol
8024
8002
  # Caused by: Failed to download distribution due to network timeout. Try increasing UV_HTTP_TIMEOUT (current value: 30s). # noqa
@@ -8036,6 +8014,150 @@ class Venv:
8036
8014
 
8037
8015
  return True
8038
8016
 
8017
+
8018
+ ########################################
8019
+ # ../configs.py
8020
+
8021
+
8022
+ @dc.dataclass(frozen=True)
8023
+ class VenvConfig(InterpVenvConfig):
8024
+ inherits: ta.Optional[ta.Sequence[str]] = None
8025
+ docker: ta.Optional[str] = None
8026
+ srcs: ta.Optional[ta.List[str]] = None
8027
+
8028
+
8029
+ @dc.dataclass(frozen=True)
8030
+ class PyprojectConfig:
8031
+ pkgs: ta.Sequence[str] = dc.field(default_factory=list)
8032
+ srcs: ta.Mapping[str, ta.Sequence[str]] = dc.field(default_factory=dict)
8033
+ venvs: ta.Mapping[str, VenvConfig] = dc.field(default_factory=dict)
8034
+
8035
+ venvs_dir: str = '.venvs'
8036
+ versions_file: ta.Optional[str] = '.versions'
8037
+
8038
+
8039
+ class PyprojectConfigPreparer:
8040
+ def __init__(
8041
+ self,
8042
+ *,
8043
+ python_versions: ta.Optional[ta.Mapping[str, str]] = None,
8044
+ ) -> None:
8045
+ super().__init__()
8046
+
8047
+ self._python_versions = python_versions or {}
8048
+
8049
+ def _inherit_venvs(self, m: ta.Mapping[str, VenvConfig]) -> ta.Mapping[str, VenvConfig]:
8050
+ done: ta.Dict[str, VenvConfig] = {}
8051
+
8052
+ def rec(k):
8053
+ try:
8054
+ return done[k]
8055
+ except KeyError:
8056
+ pass
8057
+
8058
+ c = m[k]
8059
+ kw = dc.asdict(c)
8060
+ for i in c.inherits or ():
8061
+ ic = rec(i)
8062
+ kw.update({k: v for k, v in dc.asdict(ic).items() if v is not None and kw.get(k) is None})
8063
+ del kw['inherits']
8064
+
8065
+ d = done[k] = VenvConfig(**kw)
8066
+ return d
8067
+
8068
+ for k in m:
8069
+ rec(k)
8070
+ return done
8071
+
8072
+ def _resolve_srcs(
8073
+ self,
8074
+ lst: ta.Sequence[str],
8075
+ aliases: ta.Mapping[str, ta.Sequence[str]],
8076
+ ) -> ta.List[str]:
8077
+ todo = list(reversed(lst))
8078
+ raw: ta.List[str] = []
8079
+ seen: ta.Set[str] = set()
8080
+
8081
+ while todo:
8082
+ cur = todo.pop()
8083
+ if cur in seen:
8084
+ continue
8085
+
8086
+ seen.add(cur)
8087
+ if not cur.startswith('@'):
8088
+ raw.append(cur)
8089
+ continue
8090
+
8091
+ todo.extend(aliases[cur[1:]][::-1])
8092
+
8093
+ return raw
8094
+
8095
+ def _fixup_interp(self, s: ta.Optional[str]) -> ta.Optional[str]:
8096
+ if not s or not s.startswith('@'):
8097
+ return s
8098
+ return self._python_versions[s[1:]]
8099
+
8100
+ def prepare_config(self, dct: ta.Mapping[str, ta.Any]) -> PyprojectConfig:
8101
+ pcfg: PyprojectConfig = unmarshal_obj(dct, PyprojectConfig)
8102
+
8103
+ ivs = dict(self._inherit_venvs(pcfg.venvs or {}))
8104
+ for k, v in ivs.items():
8105
+ v = dc.replace(v, srcs=self._resolve_srcs(v.srcs or [], pcfg.srcs or {}))
8106
+ v = dc.replace(v, interp=self._fixup_interp(v.interp))
8107
+ ivs[k] = v
8108
+
8109
+ pcfg = dc.replace(pcfg, venvs=ivs)
8110
+ return pcfg
8111
+
8112
+
8113
+ ########################################
8114
+ # ../venvs.py
8115
+
8116
+
8117
+ ##
8118
+
8119
+
8120
+ class Venv:
8121
+ def __init__(
8122
+ self,
8123
+ name: str,
8124
+ cfg: VenvConfig,
8125
+ ) -> None:
8126
+ super().__init__()
8127
+ self._name = name
8128
+ self._cfg = cfg
8129
+
8130
+ @property
8131
+ def cfg(self) -> VenvConfig:
8132
+ return self._cfg
8133
+
8134
+ DIR_NAME = '.venvs'
8135
+
8136
+ @property
8137
+ def dir_name(self) -> str:
8138
+ return os.path.join(self.DIR_NAME, self._name)
8139
+
8140
+ @cached_nullary
8141
+ def _iv(self) -> InterpVenv:
8142
+ rr = RequirementsRewriter(self._name)
8143
+
8144
+ return InterpVenv(
8145
+ self.dir_name,
8146
+ self._cfg,
8147
+ requirements_processor=InterpVenvRequirementsProcessor(
8148
+ lambda iv, reqs: [rr.rewrite(req) for req in reqs] # noqa
8149
+ ),
8150
+ log=log,
8151
+ )
8152
+
8153
+ @cached_nullary
8154
+ def exe(self) -> str:
8155
+ return self._iv().exe()
8156
+
8157
+ @async_cached_nullary
8158
+ async def create(self) -> bool:
8159
+ return await self._iv().create()
8160
+
8039
8161
  @staticmethod
8040
8162
  def _resolve_srcs(raw: ta.List[str]) -> ta.List[str]:
8041
8163
  out: list[str] = []
@@ -8152,7 +8274,7 @@ class Run:
8152
8274
  class PyprojectCli(ArgparseCli):
8153
8275
  _docker_container = argparse_arg('--_docker_container', help=argparse.SUPPRESS)
8154
8276
 
8155
- @argparse_command(
8277
+ @argparse_cmd(
8156
8278
  argparse_arg('name'),
8157
8279
  argparse_arg('-e', '--docker-env', action='append'),
8158
8280
  argparse_arg('cmd', nargs='?'),
@@ -8234,7 +8356,7 @@ class PyprojectCli(ArgparseCli):
8234
8356
  else:
8235
8357
  raise Exception(f'unknown subcommand: {cmd}')
8236
8358
 
8237
- @argparse_command(
8359
+ @argparse_cmd(
8238
8360
  argparse_arg('-b', '--build', action='store_true'),
8239
8361
  argparse_arg('-r', '--revision', action='store_true'),
8240
8362
  argparse_arg('-j', '--jobs', type=int),
omdev/tools/doc.py CHANGED
@@ -64,7 +64,7 @@ class Cli(ap.Cli):
64
64
 
65
65
  return src, name
66
66
 
67
- @ap.command(
67
+ @ap.cmd(
68
68
  ap.arg('input-file', nargs='?'),
69
69
  ap.arg('--report-level', type=int),
70
70
  ap.arg('-O', '--open', action='store_true'),
@@ -85,7 +85,7 @@ class Cli(ap.Cli):
85
85
  else:
86
86
  print(html)
87
87
 
88
- @ap.command(
88
+ @ap.cmd(
89
89
  ap.arg('input-file', nargs='?'),
90
90
  ap.arg('-O', '--open', action='store_true'),
91
91
  )