omdev 0.0.0.dev223__py3-none-any.whl → 0.0.0.dev225__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.
@@ -128,7 +128,7 @@ InjectorProviderFn = ta.Callable[['Injector'], ta.Any]
128
128
  InjectorProviderFnMap = ta.Mapping['InjectorKey', 'InjectorProviderFn']
129
129
  InjectorBindingOrBindings = ta.Union['InjectorBinding', 'InjectorBindings']
130
130
 
131
- # ../../omlish/subprocesses.py
131
+ # ../../omlish/subprocesses/base.py
132
132
  SubprocessChannelOption = ta.Literal['pipe', 'stdout', 'devnull'] # ta.TypeAlias
133
133
 
134
134
 
@@ -5625,6 +5625,98 @@ class JsonLogFormatter(logging.Formatter):
5625
5625
  return self._json_dumps(dct)
5626
5626
 
5627
5627
 
5628
+ ########################################
5629
+ # ../../../omlish/subprocesses/run.py
5630
+
5631
+
5632
+ ##
5633
+
5634
+
5635
+ @dc.dataclass(frozen=True)
5636
+ class SubprocessRunOutput(ta.Generic[T]):
5637
+ proc: T
5638
+
5639
+ returncode: int # noqa
5640
+
5641
+ stdout: ta.Optional[bytes] = None
5642
+ stderr: ta.Optional[bytes] = None
5643
+
5644
+
5645
+ ##
5646
+
5647
+
5648
+ @dc.dataclass(frozen=True)
5649
+ class SubprocessRun:
5650
+ cmd: ta.Sequence[str]
5651
+ input: ta.Any = None
5652
+ timeout: ta.Optional[float] = None
5653
+ check: bool = False
5654
+ capture_output: ta.Optional[bool] = None
5655
+ kwargs: ta.Optional[ta.Mapping[str, ta.Any]] = None
5656
+
5657
+ @classmethod
5658
+ def of(
5659
+ cls,
5660
+ *cmd: str,
5661
+ input: ta.Any = None, # noqa
5662
+ timeout: ta.Optional[float] = None,
5663
+ check: bool = False, # noqa
5664
+ capture_output: ta.Optional[bool] = None,
5665
+ **kwargs: ta.Any,
5666
+ ) -> 'SubprocessRun':
5667
+ return cls(
5668
+ cmd=cmd,
5669
+ input=input,
5670
+ timeout=timeout,
5671
+ check=check,
5672
+ capture_output=capture_output,
5673
+ kwargs=kwargs,
5674
+ )
5675
+
5676
+ #
5677
+
5678
+ _DEFAULT_SUBPROCESSES: ta.ClassVar[ta.Optional[ta.Any]] = None # AbstractSubprocesses
5679
+
5680
+ def run(
5681
+ self,
5682
+ subprocesses: ta.Optional[ta.Any] = None, # AbstractSubprocesses
5683
+ ) -> SubprocessRunOutput:
5684
+ if subprocesses is None:
5685
+ subprocesses = self._DEFAULT_SUBPROCESSES
5686
+ return check.not_none(subprocesses).run_(self) # type: ignore[attr-defined]
5687
+
5688
+ _DEFAULT_ASYNC_SUBPROCESSES: ta.ClassVar[ta.Optional[ta.Any]] = None # AbstractAsyncSubprocesses
5689
+
5690
+ async def async_run(
5691
+ self,
5692
+ async_subprocesses: ta.Optional[ta.Any] = None, # AbstractAsyncSubprocesses
5693
+ ) -> SubprocessRunOutput:
5694
+ if async_subprocesses is None:
5695
+ async_subprocesses = self._DEFAULT_ASYNC_SUBPROCESSES
5696
+ return await check.not_none(async_subprocesses).run_(self) # type: ignore[attr-defined]
5697
+
5698
+
5699
+ ##
5700
+
5701
+
5702
+ class SubprocessRunnable(abc.ABC, ta.Generic[T]):
5703
+ @abc.abstractmethod
5704
+ def make_run(self) -> SubprocessRun:
5705
+ raise NotImplementedError
5706
+
5707
+ @abc.abstractmethod
5708
+ def handle_run_output(self, output: SubprocessRunOutput) -> T:
5709
+ raise NotImplementedError
5710
+
5711
+ #
5712
+
5713
+ def run(self, subprocesses: ta.Optional[ta.Any] = None) -> T: # AbstractSubprocesses
5714
+ return self.handle_run_output(self.make_run().run(subprocesses))
5715
+
5716
+ async def async_run(self, async_subprocesses: ta.Optional[ta.Any] = None) -> T: # AbstractAsyncSubprocesses
5717
+ return self.handle_run_output(await self.make_run().async_run(async_subprocesses))
5718
+
5719
+
5628
5720
  ########################################
5629
5721
  # ../../interp/types.py
5630
5722
 
@@ -5863,23 +5955,7 @@ def configure_standard_logging(
5863
5955
 
5864
5956
 
5865
5957
  ########################################
5866
- # ../../../omlish/subprocesses.py
5867
-
5868
-
5869
- ##
5870
-
5871
-
5872
- # Valid channel type kwarg values:
5873
- # - A special flag negative int
5874
- # - A positive fd int
5875
- # - A file-like object
5876
- # - None
5877
-
5878
- SUBPROCESS_CHANNEL_OPTION_VALUES: ta.Mapping[SubprocessChannelOption, int] = {
5879
- 'pipe': subprocess.PIPE,
5880
- 'stdout': subprocess.STDOUT,
5881
- 'devnull': subprocess.DEVNULL,
5882
- }
5958
+ # ../../../omlish/subprocesses/wrap.py
5883
5959
 
5884
5960
 
5885
5961
  ##
@@ -5899,22 +5975,68 @@ def subprocess_maybe_shell_wrap_exec(*cmd: str) -> ta.Tuple[str, ...]:
5899
5975
  return cmd
5900
5976
 
5901
5977
 
5978
+ ########################################
5979
+ # ../../interp/providers/base.py
5980
+ """
5981
+ TODO:
5982
+ - backends
5983
+ - local builds
5984
+ - deadsnakes?
5985
+ - uv
5986
+ - loose versions
5987
+ """
5988
+
5989
+
5902
5990
  ##
5903
5991
 
5904
5992
 
5905
- def subprocess_close(
5906
- proc: subprocess.Popen,
5907
- timeout: ta.Optional[float] = None,
5908
- ) -> None:
5909
- # TODO: terminate, sleep, kill
5910
- if proc.stdout:
5911
- proc.stdout.close()
5912
- if proc.stderr:
5913
- proc.stderr.close()
5914
- if proc.stdin:
5915
- proc.stdin.close()
5993
+ class InterpProvider(abc.ABC):
5994
+ name: ta.ClassVar[str]
5995
+
5996
+ def __init_subclass__(cls, **kwargs: ta.Any) -> None:
5997
+ super().__init_subclass__(**kwargs)
5998
+ if abc.ABC not in cls.__bases__ and 'name' not in cls.__dict__:
5999
+ sfx = 'InterpProvider'
6000
+ if not cls.__name__.endswith(sfx):
6001
+ raise NameError(cls)
6002
+ setattr(cls, 'name', snake_case(cls.__name__[:-len(sfx)]))
6003
+
6004
+ @abc.abstractmethod
6005
+ def get_installed_versions(self, spec: InterpSpecifier) -> ta.Awaitable[ta.Sequence[InterpVersion]]:
6006
+ raise NotImplementedError
6007
+
6008
+ @abc.abstractmethod
6009
+ def get_installed_version(self, version: InterpVersion) -> ta.Awaitable[Interp]:
6010
+ raise NotImplementedError
6011
+
6012
+ async def get_installable_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
6013
+ return []
6014
+
6015
+ async def install_version(self, version: InterpVersion) -> Interp:
6016
+ raise TypeError
6017
+
6018
+
6019
+ InterpProviders = ta.NewType('InterpProviders', ta.Sequence[InterpProvider])
6020
+
6021
+
6022
+ ########################################
6023
+ # ../../../omlish/subprocesses/base.py
6024
+
6025
+
6026
+ ##
6027
+
6028
+
6029
+ # Valid channel type kwarg values:
6030
+ # - A special flag negative int
6031
+ # - A positive fd int
6032
+ # - A file-like object
6033
+ # - None
5916
6034
 
5917
- proc.wait(timeout)
6035
+ SUBPROCESS_CHANNEL_OPTION_VALUES: ta.Mapping[SubprocessChannelOption, int] = {
6036
+ 'pipe': subprocess.PIPE,
6037
+ 'stdout': subprocess.STDOUT,
6038
+ 'devnull': subprocess.DEVNULL,
6039
+ }
5918
6040
 
5919
6041
 
5920
6042
  ##
@@ -6101,32 +6223,104 @@ class BaseSubprocesses(abc.ABC): # noqa
6101
6223
  return e
6102
6224
 
6103
6225
 
6104
- ##
6226
+ ########################################
6227
+ # ../../interp/resolvers.py
6105
6228
 
6106
6229
 
6107
6230
  @dc.dataclass(frozen=True)
6108
- class SubprocessRun:
6109
- cmd: ta.Sequence[str]
6110
- input: ta.Any = None
6111
- timeout: ta.Optional[float] = None
6112
- check: bool = False
6113
- capture_output: ta.Optional[bool] = None
6114
- kwargs: ta.Optional[ta.Mapping[str, ta.Any]] = None
6231
+ class InterpResolverProviders:
6232
+ providers: ta.Sequence[ta.Tuple[str, InterpProvider]]
6115
6233
 
6116
6234
 
6117
- @dc.dataclass(frozen=True)
6118
- class SubprocessRunOutput(ta.Generic[T]):
6119
- proc: T
6235
+ class InterpResolver:
6236
+ def __init__(
6237
+ self,
6238
+ providers: InterpResolverProviders,
6239
+ ) -> None:
6240
+ super().__init__()
6120
6241
 
6121
- returncode: int # noqa
6242
+ self._providers: ta.Mapping[str, InterpProvider] = collections.OrderedDict(providers.providers)
6122
6243
 
6123
- stdout: ta.Optional[bytes] = None
6124
- stderr: ta.Optional[bytes] = None
6244
+ async def _resolve_installed(self, spec: InterpSpecifier) -> ta.Optional[ta.Tuple[InterpProvider, InterpVersion]]:
6245
+ lst = [
6246
+ (i, si)
6247
+ for i, p in enumerate(self._providers.values())
6248
+ for si in await p.get_installed_versions(spec)
6249
+ if spec.contains(si)
6250
+ ]
6125
6251
 
6252
+ slst = sorted(lst, key=lambda t: (-t[0], t[1].version))
6253
+ if not slst:
6254
+ return None
6126
6255
 
6127
- class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
6256
+ bi, bv = slst[-1]
6257
+ bp = list(self._providers.values())[bi]
6258
+ return (bp, bv)
6259
+
6260
+ async def resolve(
6261
+ self,
6262
+ spec: InterpSpecifier,
6263
+ *,
6264
+ install: bool = False,
6265
+ ) -> ta.Optional[Interp]:
6266
+ tup = await self._resolve_installed(spec)
6267
+ if tup is not None:
6268
+ bp, bv = tup
6269
+ return await bp.get_installed_version(bv)
6270
+
6271
+ if not install:
6272
+ return None
6273
+
6274
+ tp = list(self._providers.values())[0] # noqa
6275
+
6276
+ sv = sorted(
6277
+ [s for s in await tp.get_installable_versions(spec) if s in spec],
6278
+ key=lambda s: s.version,
6279
+ )
6280
+ if not sv:
6281
+ return None
6282
+
6283
+ bv = sv[-1]
6284
+ return await tp.install_version(bv)
6285
+
6286
+ async def list(self, spec: InterpSpecifier) -> None:
6287
+ print('installed:')
6288
+ for n, p in self._providers.items():
6289
+ lst = [
6290
+ si
6291
+ for si in await p.get_installed_versions(spec)
6292
+ if spec.contains(si)
6293
+ ]
6294
+ if lst:
6295
+ print(f' {n}')
6296
+ for si in lst:
6297
+ print(f' {si}')
6298
+
6299
+ print()
6300
+
6301
+ print('installable:')
6302
+ for n, p in self._providers.items():
6303
+ lst = [
6304
+ si
6305
+ for si in await p.get_installable_versions(spec)
6306
+ if spec.contains(si)
6307
+ ]
6308
+ if lst:
6309
+ print(f' {n}')
6310
+ for si in lst:
6311
+ print(f' {si}')
6312
+
6313
+
6314
+ ########################################
6315
+ # ../../../omlish/subprocesses/async_.py
6316
+
6317
+
6318
+ ##
6319
+
6320
+
6321
+ class AbstractAsyncSubprocesses(BaseSubprocesses):
6128
6322
  @abc.abstractmethod
6129
- def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
6323
+ async def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
6130
6324
  raise NotImplementedError
6131
6325
 
6132
6326
  def run(
@@ -6137,7 +6331,7 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
6137
6331
  check: bool = False,
6138
6332
  capture_output: ta.Optional[bool] = None,
6139
6333
  **kwargs: ta.Any,
6140
- ) -> SubprocessRunOutput:
6334
+ ) -> ta.Awaitable[SubprocessRunOutput]:
6141
6335
  return self.run_(SubprocessRun(
6142
6336
  cmd=cmd,
6143
6337
  input=input,
@@ -6150,7 +6344,7 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
6150
6344
  #
6151
6345
 
6152
6346
  @abc.abstractmethod
6153
- def check_call(
6347
+ async def check_call(
6154
6348
  self,
6155
6349
  *cmd: str,
6156
6350
  stdout: ta.Any = sys.stderr,
@@ -6159,7 +6353,7 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
6159
6353
  raise NotImplementedError
6160
6354
 
6161
6355
  @abc.abstractmethod
6162
- def check_output(
6356
+ async def check_output(
6163
6357
  self,
6164
6358
  *cmd: str,
6165
6359
  **kwargs: ta.Any,
@@ -6168,96 +6362,56 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
6168
6362
 
6169
6363
  #
6170
6364
 
6171
- def check_output_str(
6365
+ async def check_output_str(
6172
6366
  self,
6173
6367
  *cmd: str,
6174
6368
  **kwargs: ta.Any,
6175
6369
  ) -> str:
6176
- return self.check_output(*cmd, **kwargs).decode().strip()
6370
+ return (await self.check_output(*cmd, **kwargs)).decode().strip()
6177
6371
 
6178
6372
  #
6179
6373
 
6180
- def try_call(
6374
+ async def try_call(
6181
6375
  self,
6182
6376
  *cmd: str,
6183
6377
  **kwargs: ta.Any,
6184
6378
  ) -> bool:
6185
- if isinstance(self.try_fn(self.check_call, *cmd, **kwargs), Exception):
6379
+ if isinstance(await self.async_try_fn(self.check_call, *cmd, **kwargs), Exception):
6186
6380
  return False
6187
6381
  else:
6188
6382
  return True
6189
6383
 
6190
- def try_output(
6384
+ async def try_output(
6191
6385
  self,
6192
6386
  *cmd: str,
6193
6387
  **kwargs: ta.Any,
6194
6388
  ) -> ta.Optional[bytes]:
6195
- if isinstance(ret := self.try_fn(self.check_output, *cmd, **kwargs), Exception):
6389
+ if isinstance(ret := await self.async_try_fn(self.check_output, *cmd, **kwargs), Exception):
6196
6390
  return None
6197
6391
  else:
6198
6392
  return ret
6199
6393
 
6200
- def try_output_str(
6394
+ async def try_output_str(
6201
6395
  self,
6202
6396
  *cmd: str,
6203
6397
  **kwargs: ta.Any,
6204
6398
  ) -> ta.Optional[str]:
6205
- if (ret := self.try_output(*cmd, **kwargs)) is None:
6399
+ if (ret := await self.try_output(*cmd, **kwargs)) is None:
6206
6400
  return None
6207
6401
  else:
6208
6402
  return ret.decode().strip()
6209
6403
 
6210
6404
 
6211
- ##
6212
-
6213
-
6214
- class Subprocesses(AbstractSubprocesses):
6215
- def run_(self, run: SubprocessRun) -> SubprocessRunOutput[subprocess.CompletedProcess]:
6216
- proc = subprocess.run(
6217
- run.cmd,
6218
- input=run.input,
6219
- timeout=run.timeout,
6220
- check=run.check,
6221
- capture_output=run.capture_output or False,
6222
- **(run.kwargs or {}),
6223
- )
6224
-
6225
- return SubprocessRunOutput(
6226
- proc=proc,
6227
-
6228
- returncode=proc.returncode,
6229
-
6230
- stdout=proc.stdout, # noqa
6231
- stderr=proc.stderr, # noqa
6232
- )
6233
-
6234
- def check_call(
6235
- self,
6236
- *cmd: str,
6237
- stdout: ta.Any = sys.stderr,
6238
- **kwargs: ta.Any,
6239
- ) -> None:
6240
- with self.prepare_and_wrap(*cmd, stdout=stdout, **kwargs) as (cmd, kwargs): # noqa
6241
- subprocess.check_call(cmd, **kwargs)
6242
-
6243
- def check_output(
6244
- self,
6245
- *cmd: str,
6246
- **kwargs: ta.Any,
6247
- ) -> bytes:
6248
- with self.prepare_and_wrap(*cmd, **kwargs) as (cmd, kwargs): # noqa
6249
- return subprocess.check_output(cmd, **kwargs)
6250
-
6251
-
6252
- subprocesses = Subprocesses()
6405
+ ########################################
6406
+ # ../../../omlish/subprocesses/sync.py
6253
6407
 
6254
6408
 
6255
6409
  ##
6256
6410
 
6257
6411
 
6258
- class AbstractAsyncSubprocesses(BaseSubprocesses):
6412
+ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
6259
6413
  @abc.abstractmethod
6260
- async def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
6414
+ def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
6261
6415
  raise NotImplementedError
6262
6416
 
6263
6417
  def run(
@@ -6268,7 +6422,7 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
6268
6422
  check: bool = False,
6269
6423
  capture_output: ta.Optional[bool] = None,
6270
6424
  **kwargs: ta.Any,
6271
- ) -> ta.Awaitable[SubprocessRunOutput]:
6425
+ ) -> SubprocessRunOutput:
6272
6426
  return self.run_(SubprocessRun(
6273
6427
  cmd=cmd,
6274
6428
  input=input,
@@ -6281,7 +6435,7 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
6281
6435
  #
6282
6436
 
6283
6437
  @abc.abstractmethod
6284
- async def check_call(
6438
+ def check_call(
6285
6439
  self,
6286
6440
  *cmd: str,
6287
6441
  stdout: ta.Any = sys.stderr,
@@ -6290,7 +6444,7 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
6290
6444
  raise NotImplementedError
6291
6445
 
6292
6446
  @abc.abstractmethod
6293
- async def check_output(
6447
+ def check_output(
6294
6448
  self,
6295
6449
  *cmd: str,
6296
6450
  **kwargs: ta.Any,
@@ -6299,46 +6453,96 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
6299
6453
 
6300
6454
  #
6301
6455
 
6302
- async def check_output_str(
6456
+ def check_output_str(
6303
6457
  self,
6304
6458
  *cmd: str,
6305
6459
  **kwargs: ta.Any,
6306
6460
  ) -> str:
6307
- return (await self.check_output(*cmd, **kwargs)).decode().strip()
6461
+ return self.check_output(*cmd, **kwargs).decode().strip()
6308
6462
 
6309
6463
  #
6310
6464
 
6311
- async def try_call(
6465
+ def try_call(
6312
6466
  self,
6313
6467
  *cmd: str,
6314
6468
  **kwargs: ta.Any,
6315
6469
  ) -> bool:
6316
- if isinstance(await self.async_try_fn(self.check_call, *cmd, **kwargs), Exception):
6470
+ if isinstance(self.try_fn(self.check_call, *cmd, **kwargs), Exception):
6317
6471
  return False
6318
6472
  else:
6319
6473
  return True
6320
6474
 
6321
- async def try_output(
6475
+ def try_output(
6322
6476
  self,
6323
6477
  *cmd: str,
6324
6478
  **kwargs: ta.Any,
6325
6479
  ) -> ta.Optional[bytes]:
6326
- if isinstance(ret := await self.async_try_fn(self.check_output, *cmd, **kwargs), Exception):
6480
+ if isinstance(ret := self.try_fn(self.check_output, *cmd, **kwargs), Exception):
6327
6481
  return None
6328
6482
  else:
6329
6483
  return ret
6330
6484
 
6331
- async def try_output_str(
6485
+ def try_output_str(
6332
6486
  self,
6333
6487
  *cmd: str,
6334
6488
  **kwargs: ta.Any,
6335
6489
  ) -> ta.Optional[str]:
6336
- if (ret := await self.try_output(*cmd, **kwargs)) is None:
6490
+ if (ret := self.try_output(*cmd, **kwargs)) is None:
6337
6491
  return None
6338
6492
  else:
6339
6493
  return ret.decode().strip()
6340
6494
 
6341
6495
 
6496
+ ##
6497
+
6498
+
6499
+ class Subprocesses(AbstractSubprocesses):
6500
+ def run_(self, run: SubprocessRun) -> SubprocessRunOutput[subprocess.CompletedProcess]:
6501
+ with self.prepare_and_wrap(
6502
+ *run.cmd,
6503
+ input=run.input,
6504
+ timeout=run.timeout,
6505
+ check=run.check,
6506
+ capture_output=run.capture_output or False,
6507
+ **(run.kwargs or {}),
6508
+ ) as (cmd, kwargs):
6509
+ proc = subprocess.run(cmd, **kwargs) # noqa
6510
+
6511
+ return SubprocessRunOutput(
6512
+ proc=proc,
6513
+
6514
+ returncode=proc.returncode,
6515
+
6516
+ stdout=proc.stdout, # noqa
6517
+ stderr=proc.stderr, # noqa
6518
+ )
6519
+
6520
+ def check_call(
6521
+ self,
6522
+ *cmd: str,
6523
+ stdout: ta.Any = sys.stderr,
6524
+ **kwargs: ta.Any,
6525
+ ) -> None:
6526
+ with self.prepare_and_wrap(*cmd, stdout=stdout, **kwargs) as (cmd, kwargs): # noqa
6527
+ subprocess.check_call(cmd, **kwargs)
6528
+
6529
+ def check_output(
6530
+ self,
6531
+ *cmd: str,
6532
+ **kwargs: ta.Any,
6533
+ ) -> bytes:
6534
+ with self.prepare_and_wrap(*cmd, **kwargs) as (cmd, kwargs): # noqa
6535
+ return subprocess.check_output(cmd, **kwargs)
6536
+
6537
+
6538
+ ##
6539
+
6540
+
6541
+ subprocesses = Subprocesses()
6542
+
6543
+ SubprocessRun._DEFAULT_SUBPROCESSES = subprocesses # noqa
6544
+
6545
+
6342
6546
  ########################################
6343
6547
  # ../../git/revisions.py
6344
6548
 
@@ -6385,50 +6589,6 @@ def get_git_revision(
6385
6589
  return dirty_rev + ('-untracked' if has_untracked else '')
6386
6590
 
6387
6591
 
6388
- ########################################
6389
- # ../../interp/providers/base.py
6390
- """
6391
- TODO:
6392
- - backends
6393
- - local builds
6394
- - deadsnakes?
6395
- - uv
6396
- - loose versions
6397
- """
6398
-
6399
-
6400
- ##
6401
-
6402
-
6403
- class InterpProvider(abc.ABC):
6404
- name: ta.ClassVar[str]
6405
-
6406
- def __init_subclass__(cls, **kwargs: ta.Any) -> None:
6407
- super().__init_subclass__(**kwargs)
6408
- if abc.ABC not in cls.__bases__ and 'name' not in cls.__dict__:
6409
- sfx = 'InterpProvider'
6410
- if not cls.__name__.endswith(sfx):
6411
- raise NameError(cls)
6412
- setattr(cls, 'name', snake_case(cls.__name__[:-len(sfx)]))
6413
-
6414
- @abc.abstractmethod
6415
- def get_installed_versions(self, spec: InterpSpecifier) -> ta.Awaitable[ta.Sequence[InterpVersion]]:
6416
- raise NotImplementedError
6417
-
6418
- @abc.abstractmethod
6419
- def get_installed_version(self, version: InterpVersion) -> ta.Awaitable[Interp]:
6420
- raise NotImplementedError
6421
-
6422
- async def get_installable_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
6423
- return []
6424
-
6425
- async def install_version(self, version: InterpVersion) -> Interp:
6426
- raise TypeError
6427
-
6428
-
6429
- InterpProviders = ta.NewType('InterpProviders', ta.Sequence[InterpProvider])
6430
-
6431
-
6432
6592
  ########################################
6433
6593
  # ../../../omlish/asyncs/asyncio/subprocesses.py
6434
6594
 
@@ -6571,19 +6731,19 @@ class AsyncioSubprocesses(AbstractAsyncSubprocesses):
6571
6731
  timeout: ta.Optional[float] = None,
6572
6732
  **kwargs: ta.Any,
6573
6733
  ) -> ta.AsyncGenerator[asyncio.subprocess.Process, None]:
6574
- fac: ta.Any
6575
- if shell:
6576
- fac = functools.partial(
6577
- asyncio.create_subprocess_shell,
6578
- check.single(cmd),
6579
- )
6580
- else:
6581
- fac = functools.partial(
6582
- asyncio.create_subprocess_exec,
6583
- *cmd,
6584
- )
6585
-
6586
6734
  with self.prepare_and_wrap( *cmd, shell=shell, **kwargs) as (cmd, kwargs): # noqa
6735
+ fac: ta.Any
6736
+ if shell:
6737
+ fac = functools.partial(
6738
+ asyncio.create_subprocess_shell,
6739
+ check.single(cmd),
6740
+ )
6741
+ else:
6742
+ fac = functools.partial(
6743
+ asyncio.create_subprocess_exec,
6744
+ *cmd,
6745
+ )
6746
+
6587
6747
  proc: asyncio.subprocess.Process = await fac(**kwargs)
6588
6748
  try:
6589
6749
  yield proc
@@ -6824,94 +6984,6 @@ class Pyenv:
6824
6984
  return True
6825
6985
 
6826
6986
 
6827
- ########################################
6828
- # ../../interp/resolvers.py
6829
-
6830
-
6831
- @dc.dataclass(frozen=True)
6832
- class InterpResolverProviders:
6833
- providers: ta.Sequence[ta.Tuple[str, InterpProvider]]
6834
-
6835
-
6836
- class InterpResolver:
6837
- def __init__(
6838
- self,
6839
- providers: InterpResolverProviders,
6840
- ) -> None:
6841
- super().__init__()
6842
-
6843
- self._providers: ta.Mapping[str, InterpProvider] = collections.OrderedDict(providers.providers)
6844
-
6845
- async def _resolve_installed(self, spec: InterpSpecifier) -> ta.Optional[ta.Tuple[InterpProvider, InterpVersion]]:
6846
- lst = [
6847
- (i, si)
6848
- for i, p in enumerate(self._providers.values())
6849
- for si in await p.get_installed_versions(spec)
6850
- if spec.contains(si)
6851
- ]
6852
-
6853
- slst = sorted(lst, key=lambda t: (-t[0], t[1].version))
6854
- if not slst:
6855
- return None
6856
-
6857
- bi, bv = slst[-1]
6858
- bp = list(self._providers.values())[bi]
6859
- return (bp, bv)
6860
-
6861
- async def resolve(
6862
- self,
6863
- spec: InterpSpecifier,
6864
- *,
6865
- install: bool = False,
6866
- ) -> ta.Optional[Interp]:
6867
- tup = await self._resolve_installed(spec)
6868
- if tup is not None:
6869
- bp, bv = tup
6870
- return await bp.get_installed_version(bv)
6871
-
6872
- if not install:
6873
- return None
6874
-
6875
- tp = list(self._providers.values())[0] # noqa
6876
-
6877
- sv = sorted(
6878
- [s for s in await tp.get_installable_versions(spec) if s in spec],
6879
- key=lambda s: s.version,
6880
- )
6881
- if not sv:
6882
- return None
6883
-
6884
- bv = sv[-1]
6885
- return await tp.install_version(bv)
6886
-
6887
- async def list(self, spec: InterpSpecifier) -> None:
6888
- print('installed:')
6889
- for n, p in self._providers.items():
6890
- lst = [
6891
- si
6892
- for si in await p.get_installed_versions(spec)
6893
- if spec.contains(si)
6894
- ]
6895
- if lst:
6896
- print(f' {n}')
6897
- for si in lst:
6898
- print(f' {si}')
6899
-
6900
- print()
6901
-
6902
- print('installable:')
6903
- for n, p in self._providers.items():
6904
- lst = [
6905
- si
6906
- for si in await p.get_installable_versions(spec)
6907
- if spec.contains(si)
6908
- ]
6909
- if lst:
6910
- print(f' {n}')
6911
- for si in lst:
6912
- print(f' {si}')
6913
-
6914
-
6915
6987
  ########################################
6916
6988
  # ../../revisions.py
6917
6989
  """