omdev 0.0.0.dev224__py3-none-any.whl → 0.0.0.dev225__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- omdev/amalg/typing.py +7 -1
- omdev/ci/requirements.py +1 -1
- omdev/git/revisions.py +2 -2
- omdev/git/shallow.py +1 -1
- omdev/git/status.py +1 -1
- omdev/precheck/lite.py +1 -1
- omdev/pyproject/pkg.py +1 -1
- omdev/scripts/ci.py +324 -271
- omdev/scripts/interp.py +230 -318
- omdev/scripts/pyproject.py +349 -296
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev225.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev225.dist-info}/RECORD +16 -16
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev225.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev225.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev225.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev225.dist-info}/top_level.txt +0 -0
omdev/scripts/interp.py
CHANGED
@@ -87,7 +87,7 @@ InjectorProviderFn = ta.Callable[['Injector'], ta.Any]
|
|
87
87
|
InjectorProviderFnMap = ta.Mapping['InjectorKey', 'InjectorProviderFn']
|
88
88
|
InjectorBindingOrBindings = ta.Union['InjectorBinding', 'InjectorBindings']
|
89
89
|
|
90
|
-
# ../../omlish/subprocesses.py
|
90
|
+
# ../../omlish/subprocesses/base.py
|
91
91
|
SubprocessChannelOption = ta.Literal['pipe', 'stdout', 'devnull'] # ta.TypeAlias
|
92
92
|
|
93
93
|
|
@@ -3369,6 +3369,98 @@ class JsonLogFormatter(logging.Formatter):
|
|
3369
3369
|
return self._json_dumps(dct)
|
3370
3370
|
|
3371
3371
|
|
3372
|
+
########################################
|
3373
|
+
# ../../../omlish/subprocesses/run.py
|
3374
|
+
|
3375
|
+
|
3376
|
+
##
|
3377
|
+
|
3378
|
+
|
3379
|
+
@dc.dataclass(frozen=True)
|
3380
|
+
class SubprocessRunOutput(ta.Generic[T]):
|
3381
|
+
proc: T
|
3382
|
+
|
3383
|
+
returncode: int # noqa
|
3384
|
+
|
3385
|
+
stdout: ta.Optional[bytes] = None
|
3386
|
+
stderr: ta.Optional[bytes] = None
|
3387
|
+
|
3388
|
+
|
3389
|
+
##
|
3390
|
+
|
3391
|
+
|
3392
|
+
@dc.dataclass(frozen=True)
|
3393
|
+
class SubprocessRun:
|
3394
|
+
cmd: ta.Sequence[str]
|
3395
|
+
input: ta.Any = None
|
3396
|
+
timeout: ta.Optional[float] = None
|
3397
|
+
check: bool = False
|
3398
|
+
capture_output: ta.Optional[bool] = None
|
3399
|
+
kwargs: ta.Optional[ta.Mapping[str, ta.Any]] = None
|
3400
|
+
|
3401
|
+
@classmethod
|
3402
|
+
def of(
|
3403
|
+
cls,
|
3404
|
+
*cmd: str,
|
3405
|
+
input: ta.Any = None, # noqa
|
3406
|
+
timeout: ta.Optional[float] = None,
|
3407
|
+
check: bool = False, # noqa
|
3408
|
+
capture_output: ta.Optional[bool] = None,
|
3409
|
+
**kwargs: ta.Any,
|
3410
|
+
) -> 'SubprocessRun':
|
3411
|
+
return cls(
|
3412
|
+
cmd=cmd,
|
3413
|
+
input=input,
|
3414
|
+
timeout=timeout,
|
3415
|
+
check=check,
|
3416
|
+
capture_output=capture_output,
|
3417
|
+
kwargs=kwargs,
|
3418
|
+
)
|
3419
|
+
|
3420
|
+
#
|
3421
|
+
|
3422
|
+
_DEFAULT_SUBPROCESSES: ta.ClassVar[ta.Optional[ta.Any]] = None # AbstractSubprocesses
|
3423
|
+
|
3424
|
+
def run(
|
3425
|
+
self,
|
3426
|
+
subprocesses: ta.Optional[ta.Any] = None, # AbstractSubprocesses
|
3427
|
+
) -> SubprocessRunOutput:
|
3428
|
+
if subprocesses is None:
|
3429
|
+
subprocesses = self._DEFAULT_SUBPROCESSES
|
3430
|
+
return check.not_none(subprocesses).run_(self) # type: ignore[attr-defined]
|
3431
|
+
|
3432
|
+
_DEFAULT_ASYNC_SUBPROCESSES: ta.ClassVar[ta.Optional[ta.Any]] = None # AbstractAsyncSubprocesses
|
3433
|
+
|
3434
|
+
async def async_run(
|
3435
|
+
self,
|
3436
|
+
async_subprocesses: ta.Optional[ta.Any] = None, # AbstractAsyncSubprocesses
|
3437
|
+
) -> SubprocessRunOutput:
|
3438
|
+
if async_subprocesses is None:
|
3439
|
+
async_subprocesses = self._DEFAULT_ASYNC_SUBPROCESSES
|
3440
|
+
return await check.not_none(async_subprocesses).run_(self) # type: ignore[attr-defined]
|
3441
|
+
|
3442
|
+
|
3443
|
+
##
|
3444
|
+
|
3445
|
+
|
3446
|
+
class SubprocessRunnable(abc.ABC, ta.Generic[T]):
|
3447
|
+
@abc.abstractmethod
|
3448
|
+
def make_run(self) -> SubprocessRun:
|
3449
|
+
raise NotImplementedError
|
3450
|
+
|
3451
|
+
@abc.abstractmethod
|
3452
|
+
def handle_run_output(self, output: SubprocessRunOutput) -> T:
|
3453
|
+
raise NotImplementedError
|
3454
|
+
|
3455
|
+
#
|
3456
|
+
|
3457
|
+
def run(self, subprocesses: ta.Optional[ta.Any] = None) -> T: # AbstractSubprocesses
|
3458
|
+
return self.handle_run_output(self.make_run().run(subprocesses))
|
3459
|
+
|
3460
|
+
async def async_run(self, async_subprocesses: ta.Optional[ta.Any] = None) -> T: # AbstractAsyncSubprocesses
|
3461
|
+
return self.handle_run_output(await self.make_run().async_run(async_subprocesses))
|
3462
|
+
|
3463
|
+
|
3372
3464
|
########################################
|
3373
3465
|
# ../types.py
|
3374
3466
|
|
@@ -3607,23 +3699,7 @@ def configure_standard_logging(
|
|
3607
3699
|
|
3608
3700
|
|
3609
3701
|
########################################
|
3610
|
-
# ../../../omlish/subprocesses.py
|
3611
|
-
|
3612
|
-
|
3613
|
-
##
|
3614
|
-
|
3615
|
-
|
3616
|
-
# Valid channel type kwarg values:
|
3617
|
-
# - A special flag negative int
|
3618
|
-
# - A positive fd int
|
3619
|
-
# - A file-like object
|
3620
|
-
# - None
|
3621
|
-
|
3622
|
-
SUBPROCESS_CHANNEL_OPTION_VALUES: ta.Mapping[SubprocessChannelOption, int] = {
|
3623
|
-
'pipe': subprocess.PIPE,
|
3624
|
-
'stdout': subprocess.STDOUT,
|
3625
|
-
'devnull': subprocess.DEVNULL,
|
3626
|
-
}
|
3702
|
+
# ../../../omlish/subprocesses/wrap.py
|
3627
3703
|
|
3628
3704
|
|
3629
3705
|
##
|
@@ -3643,22 +3719,68 @@ def subprocess_maybe_shell_wrap_exec(*cmd: str) -> ta.Tuple[str, ...]:
|
|
3643
3719
|
return cmd
|
3644
3720
|
|
3645
3721
|
|
3722
|
+
########################################
|
3723
|
+
# ../providers/base.py
|
3724
|
+
"""
|
3725
|
+
TODO:
|
3726
|
+
- backends
|
3727
|
+
- local builds
|
3728
|
+
- deadsnakes?
|
3729
|
+
- uv
|
3730
|
+
- loose versions
|
3731
|
+
"""
|
3732
|
+
|
3733
|
+
|
3646
3734
|
##
|
3647
3735
|
|
3648
3736
|
|
3649
|
-
|
3650
|
-
|
3651
|
-
timeout: ta.Optional[float] = None,
|
3652
|
-
) -> None:
|
3653
|
-
# TODO: terminate, sleep, kill
|
3654
|
-
if proc.stdout:
|
3655
|
-
proc.stdout.close()
|
3656
|
-
if proc.stderr:
|
3657
|
-
proc.stderr.close()
|
3658
|
-
if proc.stdin:
|
3659
|
-
proc.stdin.close()
|
3737
|
+
class InterpProvider(abc.ABC):
|
3738
|
+
name: ta.ClassVar[str]
|
3660
3739
|
|
3661
|
-
|
3740
|
+
def __init_subclass__(cls, **kwargs: ta.Any) -> None:
|
3741
|
+
super().__init_subclass__(**kwargs)
|
3742
|
+
if abc.ABC not in cls.__bases__ and 'name' not in cls.__dict__:
|
3743
|
+
sfx = 'InterpProvider'
|
3744
|
+
if not cls.__name__.endswith(sfx):
|
3745
|
+
raise NameError(cls)
|
3746
|
+
setattr(cls, 'name', snake_case(cls.__name__[:-len(sfx)]))
|
3747
|
+
|
3748
|
+
@abc.abstractmethod
|
3749
|
+
def get_installed_versions(self, spec: InterpSpecifier) -> ta.Awaitable[ta.Sequence[InterpVersion]]:
|
3750
|
+
raise NotImplementedError
|
3751
|
+
|
3752
|
+
@abc.abstractmethod
|
3753
|
+
def get_installed_version(self, version: InterpVersion) -> ta.Awaitable[Interp]:
|
3754
|
+
raise NotImplementedError
|
3755
|
+
|
3756
|
+
async def get_installable_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
3757
|
+
return []
|
3758
|
+
|
3759
|
+
async def install_version(self, version: InterpVersion) -> Interp:
|
3760
|
+
raise TypeError
|
3761
|
+
|
3762
|
+
|
3763
|
+
InterpProviders = ta.NewType('InterpProviders', ta.Sequence[InterpProvider])
|
3764
|
+
|
3765
|
+
|
3766
|
+
########################################
|
3767
|
+
# ../../../omlish/subprocesses/base.py
|
3768
|
+
|
3769
|
+
|
3770
|
+
##
|
3771
|
+
|
3772
|
+
|
3773
|
+
# Valid channel type kwarg values:
|
3774
|
+
# - A special flag negative int
|
3775
|
+
# - A positive fd int
|
3776
|
+
# - A file-like object
|
3777
|
+
# - None
|
3778
|
+
|
3779
|
+
SUBPROCESS_CHANNEL_OPTION_VALUES: ta.Mapping[SubprocessChannelOption, int] = {
|
3780
|
+
'pipe': subprocess.PIPE,
|
3781
|
+
'stdout': subprocess.STDOUT,
|
3782
|
+
'devnull': subprocess.DEVNULL,
|
3783
|
+
}
|
3662
3784
|
|
3663
3785
|
|
3664
3786
|
##
|
@@ -3845,174 +3967,96 @@ class BaseSubprocesses(abc.ABC): # noqa
|
|
3845
3967
|
return e
|
3846
3968
|
|
3847
3969
|
|
3848
|
-
|
3849
|
-
|
3850
|
-
|
3851
|
-
@dc.dataclass(frozen=True)
|
3852
|
-
class SubprocessRun:
|
3853
|
-
cmd: ta.Sequence[str]
|
3854
|
-
input: ta.Any = None
|
3855
|
-
timeout: ta.Optional[float] = None
|
3856
|
-
check: bool = False
|
3857
|
-
capture_output: ta.Optional[bool] = None
|
3858
|
-
kwargs: ta.Optional[ta.Mapping[str, ta.Any]] = None
|
3859
|
-
|
3860
|
-
@classmethod
|
3861
|
-
def of(
|
3862
|
-
cls,
|
3863
|
-
*cmd: str,
|
3864
|
-
input: ta.Any = None, # noqa
|
3865
|
-
timeout: ta.Optional[float] = None,
|
3866
|
-
check: bool = False,
|
3867
|
-
capture_output: ta.Optional[bool] = None,
|
3868
|
-
**kwargs: ta.Any,
|
3869
|
-
) -> 'SubprocessRun':
|
3870
|
-
return cls(
|
3871
|
-
cmd=cmd,
|
3872
|
-
input=input,
|
3873
|
-
timeout=timeout,
|
3874
|
-
check=check,
|
3875
|
-
capture_output=capture_output,
|
3876
|
-
kwargs=kwargs,
|
3877
|
-
)
|
3970
|
+
########################################
|
3971
|
+
# ../resolvers.py
|
3878
3972
|
|
3879
3973
|
|
3880
3974
|
@dc.dataclass(frozen=True)
|
3881
|
-
class
|
3882
|
-
|
3883
|
-
|
3884
|
-
returncode: int # noqa
|
3885
|
-
|
3886
|
-
stdout: ta.Optional[bytes] = None
|
3887
|
-
stderr: ta.Optional[bytes] = None
|
3888
|
-
|
3889
|
-
|
3890
|
-
class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
3891
|
-
@abc.abstractmethod
|
3892
|
-
def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
|
3893
|
-
raise NotImplementedError
|
3894
|
-
|
3895
|
-
def run(
|
3896
|
-
self,
|
3897
|
-
*cmd: str,
|
3898
|
-
input: ta.Any = None, # noqa
|
3899
|
-
timeout: ta.Optional[float] = None,
|
3900
|
-
check: bool = False,
|
3901
|
-
capture_output: ta.Optional[bool] = None,
|
3902
|
-
**kwargs: ta.Any,
|
3903
|
-
) -> SubprocessRunOutput:
|
3904
|
-
return self.run_(SubprocessRun(
|
3905
|
-
cmd=cmd,
|
3906
|
-
input=input,
|
3907
|
-
timeout=timeout,
|
3908
|
-
check=check,
|
3909
|
-
capture_output=capture_output,
|
3910
|
-
kwargs=kwargs,
|
3911
|
-
))
|
3975
|
+
class InterpResolverProviders:
|
3976
|
+
providers: ta.Sequence[ta.Tuple[str, InterpProvider]]
|
3912
3977
|
|
3913
|
-
#
|
3914
3978
|
|
3915
|
-
|
3916
|
-
def
|
3979
|
+
class InterpResolver:
|
3980
|
+
def __init__(
|
3917
3981
|
self,
|
3918
|
-
|
3919
|
-
stdout: ta.Any = sys.stderr,
|
3920
|
-
**kwargs: ta.Any,
|
3982
|
+
providers: InterpResolverProviders,
|
3921
3983
|
) -> None:
|
3922
|
-
|
3923
|
-
|
3924
|
-
@abc.abstractmethod
|
3925
|
-
def check_output(
|
3926
|
-
self,
|
3927
|
-
*cmd: str,
|
3928
|
-
**kwargs: ta.Any,
|
3929
|
-
) -> bytes:
|
3930
|
-
raise NotImplementedError
|
3984
|
+
super().__init__()
|
3931
3985
|
|
3932
|
-
|
3986
|
+
self._providers: ta.Mapping[str, InterpProvider] = collections.OrderedDict(providers.providers)
|
3933
3987
|
|
3934
|
-
def
|
3935
|
-
|
3936
|
-
|
3937
|
-
|
3938
|
-
|
3939
|
-
|
3988
|
+
async def _resolve_installed(self, spec: InterpSpecifier) -> ta.Optional[ta.Tuple[InterpProvider, InterpVersion]]:
|
3989
|
+
lst = [
|
3990
|
+
(i, si)
|
3991
|
+
for i, p in enumerate(self._providers.values())
|
3992
|
+
for si in await p.get_installed_versions(spec)
|
3993
|
+
if spec.contains(si)
|
3994
|
+
]
|
3940
3995
|
|
3941
|
-
|
3996
|
+
slst = sorted(lst, key=lambda t: (-t[0], t[1].version))
|
3997
|
+
if not slst:
|
3998
|
+
return None
|
3942
3999
|
|
3943
|
-
|
3944
|
-
|
3945
|
-
|
3946
|
-
**kwargs: ta.Any,
|
3947
|
-
) -> bool:
|
3948
|
-
if isinstance(self.try_fn(self.check_call, *cmd, **kwargs), Exception):
|
3949
|
-
return False
|
3950
|
-
else:
|
3951
|
-
return True
|
4000
|
+
bi, bv = slst[-1]
|
4001
|
+
bp = list(self._providers.values())[bi]
|
4002
|
+
return (bp, bv)
|
3952
4003
|
|
3953
|
-
def
|
4004
|
+
async def resolve(
|
3954
4005
|
self,
|
3955
|
-
|
3956
|
-
|
3957
|
-
|
3958
|
-
|
3959
|
-
|
3960
|
-
|
3961
|
-
|
4006
|
+
spec: InterpSpecifier,
|
4007
|
+
*,
|
4008
|
+
install: bool = False,
|
4009
|
+
) -> ta.Optional[Interp]:
|
4010
|
+
tup = await self._resolve_installed(spec)
|
4011
|
+
if tup is not None:
|
4012
|
+
bp, bv = tup
|
4013
|
+
return await bp.get_installed_version(bv)
|
3962
4014
|
|
3963
|
-
|
3964
|
-
self,
|
3965
|
-
*cmd: str,
|
3966
|
-
**kwargs: ta.Any,
|
3967
|
-
) -> ta.Optional[str]:
|
3968
|
-
if (ret := self.try_output(*cmd, **kwargs)) is None:
|
4015
|
+
if not install:
|
3969
4016
|
return None
|
3970
|
-
else:
|
3971
|
-
return ret.decode().strip()
|
3972
|
-
|
3973
|
-
|
3974
|
-
##
|
3975
4017
|
|
4018
|
+
tp = list(self._providers.values())[0] # noqa
|
3976
4019
|
|
3977
|
-
|
3978
|
-
|
3979
|
-
|
3980
|
-
run.cmd,
|
3981
|
-
input=run.input,
|
3982
|
-
timeout=run.timeout,
|
3983
|
-
check=run.check,
|
3984
|
-
capture_output=run.capture_output or False,
|
3985
|
-
**(run.kwargs or {}),
|
4020
|
+
sv = sorted(
|
4021
|
+
[s for s in await tp.get_installable_versions(spec) if s in spec],
|
4022
|
+
key=lambda s: s.version,
|
3986
4023
|
)
|
4024
|
+
if not sv:
|
4025
|
+
return None
|
3987
4026
|
|
3988
|
-
|
3989
|
-
|
3990
|
-
|
3991
|
-
returncode=proc.returncode,
|
4027
|
+
bv = sv[-1]
|
4028
|
+
return await tp.install_version(bv)
|
3992
4029
|
|
3993
|
-
|
3994
|
-
|
3995
|
-
)
|
4030
|
+
async def list(self, spec: InterpSpecifier) -> None:
|
4031
|
+
print('installed:')
|
4032
|
+
for n, p in self._providers.items():
|
4033
|
+
lst = [
|
4034
|
+
si
|
4035
|
+
for si in await p.get_installed_versions(spec)
|
4036
|
+
if spec.contains(si)
|
4037
|
+
]
|
4038
|
+
if lst:
|
4039
|
+
print(f' {n}')
|
4040
|
+
for si in lst:
|
4041
|
+
print(f' {si}')
|
3996
4042
|
|
3997
|
-
|
3998
|
-
self,
|
3999
|
-
*cmd: str,
|
4000
|
-
stdout: ta.Any = sys.stderr,
|
4001
|
-
**kwargs: ta.Any,
|
4002
|
-
) -> None:
|
4003
|
-
with self.prepare_and_wrap(*cmd, stdout=stdout, **kwargs) as (cmd, kwargs): # noqa
|
4004
|
-
subprocess.check_call(cmd, **kwargs)
|
4043
|
+
print()
|
4005
4044
|
|
4006
|
-
|
4007
|
-
|
4008
|
-
|
4009
|
-
|
4010
|
-
|
4011
|
-
|
4012
|
-
|
4045
|
+
print('installable:')
|
4046
|
+
for n, p in self._providers.items():
|
4047
|
+
lst = [
|
4048
|
+
si
|
4049
|
+
for si in await p.get_installable_versions(spec)
|
4050
|
+
if spec.contains(si)
|
4051
|
+
]
|
4052
|
+
if lst:
|
4053
|
+
print(f' {n}')
|
4054
|
+
for si in lst:
|
4055
|
+
print(f' {si}')
|
4013
4056
|
|
4014
4057
|
|
4015
|
-
|
4058
|
+
########################################
|
4059
|
+
# ../../../omlish/subprocesses/async_.py
|
4016
4060
|
|
4017
4061
|
|
4018
4062
|
##
|
@@ -4102,50 +4146,6 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
|
|
4102
4146
|
return ret.decode().strip()
|
4103
4147
|
|
4104
4148
|
|
4105
|
-
########################################
|
4106
|
-
# ../providers/base.py
|
4107
|
-
"""
|
4108
|
-
TODO:
|
4109
|
-
- backends
|
4110
|
-
- local builds
|
4111
|
-
- deadsnakes?
|
4112
|
-
- uv
|
4113
|
-
- loose versions
|
4114
|
-
"""
|
4115
|
-
|
4116
|
-
|
4117
|
-
##
|
4118
|
-
|
4119
|
-
|
4120
|
-
class InterpProvider(abc.ABC):
|
4121
|
-
name: ta.ClassVar[str]
|
4122
|
-
|
4123
|
-
def __init_subclass__(cls, **kwargs: ta.Any) -> None:
|
4124
|
-
super().__init_subclass__(**kwargs)
|
4125
|
-
if abc.ABC not in cls.__bases__ and 'name' not in cls.__dict__:
|
4126
|
-
sfx = 'InterpProvider'
|
4127
|
-
if not cls.__name__.endswith(sfx):
|
4128
|
-
raise NameError(cls)
|
4129
|
-
setattr(cls, 'name', snake_case(cls.__name__[:-len(sfx)]))
|
4130
|
-
|
4131
|
-
@abc.abstractmethod
|
4132
|
-
def get_installed_versions(self, spec: InterpSpecifier) -> ta.Awaitable[ta.Sequence[InterpVersion]]:
|
4133
|
-
raise NotImplementedError
|
4134
|
-
|
4135
|
-
@abc.abstractmethod
|
4136
|
-
def get_installed_version(self, version: InterpVersion) -> ta.Awaitable[Interp]:
|
4137
|
-
raise NotImplementedError
|
4138
|
-
|
4139
|
-
async def get_installable_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
4140
|
-
return []
|
4141
|
-
|
4142
|
-
async def install_version(self, version: InterpVersion) -> Interp:
|
4143
|
-
raise TypeError
|
4144
|
-
|
4145
|
-
|
4146
|
-
InterpProviders = ta.NewType('InterpProviders', ta.Sequence[InterpProvider])
|
4147
|
-
|
4148
|
-
|
4149
4149
|
########################################
|
4150
4150
|
# ../../../omlish/asyncs/asyncio/subprocesses.py
|
4151
4151
|
|
@@ -4288,19 +4288,19 @@ class AsyncioSubprocesses(AbstractAsyncSubprocesses):
|
|
4288
4288
|
timeout: ta.Optional[float] = None,
|
4289
4289
|
**kwargs: ta.Any,
|
4290
4290
|
) -> ta.AsyncGenerator[asyncio.subprocess.Process, None]:
|
4291
|
-
fac: ta.Any
|
4292
|
-
if shell:
|
4293
|
-
fac = functools.partial(
|
4294
|
-
asyncio.create_subprocess_shell,
|
4295
|
-
check.single(cmd),
|
4296
|
-
)
|
4297
|
-
else:
|
4298
|
-
fac = functools.partial(
|
4299
|
-
asyncio.create_subprocess_exec,
|
4300
|
-
*cmd,
|
4301
|
-
)
|
4302
|
-
|
4303
4291
|
with self.prepare_and_wrap( *cmd, shell=shell, **kwargs) as (cmd, kwargs): # noqa
|
4292
|
+
fac: ta.Any
|
4293
|
+
if shell:
|
4294
|
+
fac = functools.partial(
|
4295
|
+
asyncio.create_subprocess_shell,
|
4296
|
+
check.single(cmd),
|
4297
|
+
)
|
4298
|
+
else:
|
4299
|
+
fac = functools.partial(
|
4300
|
+
asyncio.create_subprocess_exec,
|
4301
|
+
*cmd,
|
4302
|
+
)
|
4303
|
+
|
4304
4304
|
proc: asyncio.subprocess.Process = await fac(**kwargs)
|
4305
4305
|
try:
|
4306
4306
|
yield proc
|
@@ -4541,94 +4541,6 @@ class Pyenv:
|
|
4541
4541
|
return True
|
4542
4542
|
|
4543
4543
|
|
4544
|
-
########################################
|
4545
|
-
# ../resolvers.py
|
4546
|
-
|
4547
|
-
|
4548
|
-
@dc.dataclass(frozen=True)
|
4549
|
-
class InterpResolverProviders:
|
4550
|
-
providers: ta.Sequence[ta.Tuple[str, InterpProvider]]
|
4551
|
-
|
4552
|
-
|
4553
|
-
class InterpResolver:
|
4554
|
-
def __init__(
|
4555
|
-
self,
|
4556
|
-
providers: InterpResolverProviders,
|
4557
|
-
) -> None:
|
4558
|
-
super().__init__()
|
4559
|
-
|
4560
|
-
self._providers: ta.Mapping[str, InterpProvider] = collections.OrderedDict(providers.providers)
|
4561
|
-
|
4562
|
-
async def _resolve_installed(self, spec: InterpSpecifier) -> ta.Optional[ta.Tuple[InterpProvider, InterpVersion]]:
|
4563
|
-
lst = [
|
4564
|
-
(i, si)
|
4565
|
-
for i, p in enumerate(self._providers.values())
|
4566
|
-
for si in await p.get_installed_versions(spec)
|
4567
|
-
if spec.contains(si)
|
4568
|
-
]
|
4569
|
-
|
4570
|
-
slst = sorted(lst, key=lambda t: (-t[0], t[1].version))
|
4571
|
-
if not slst:
|
4572
|
-
return None
|
4573
|
-
|
4574
|
-
bi, bv = slst[-1]
|
4575
|
-
bp = list(self._providers.values())[bi]
|
4576
|
-
return (bp, bv)
|
4577
|
-
|
4578
|
-
async def resolve(
|
4579
|
-
self,
|
4580
|
-
spec: InterpSpecifier,
|
4581
|
-
*,
|
4582
|
-
install: bool = False,
|
4583
|
-
) -> ta.Optional[Interp]:
|
4584
|
-
tup = await self._resolve_installed(spec)
|
4585
|
-
if tup is not None:
|
4586
|
-
bp, bv = tup
|
4587
|
-
return await bp.get_installed_version(bv)
|
4588
|
-
|
4589
|
-
if not install:
|
4590
|
-
return None
|
4591
|
-
|
4592
|
-
tp = list(self._providers.values())[0] # noqa
|
4593
|
-
|
4594
|
-
sv = sorted(
|
4595
|
-
[s for s in await tp.get_installable_versions(spec) if s in spec],
|
4596
|
-
key=lambda s: s.version,
|
4597
|
-
)
|
4598
|
-
if not sv:
|
4599
|
-
return None
|
4600
|
-
|
4601
|
-
bv = sv[-1]
|
4602
|
-
return await tp.install_version(bv)
|
4603
|
-
|
4604
|
-
async def list(self, spec: InterpSpecifier) -> None:
|
4605
|
-
print('installed:')
|
4606
|
-
for n, p in self._providers.items():
|
4607
|
-
lst = [
|
4608
|
-
si
|
4609
|
-
for si in await p.get_installed_versions(spec)
|
4610
|
-
if spec.contains(si)
|
4611
|
-
]
|
4612
|
-
if lst:
|
4613
|
-
print(f' {n}')
|
4614
|
-
for si in lst:
|
4615
|
-
print(f' {si}')
|
4616
|
-
|
4617
|
-
print()
|
4618
|
-
|
4619
|
-
print('installable:')
|
4620
|
-
for n, p in self._providers.items():
|
4621
|
-
lst = [
|
4622
|
-
si
|
4623
|
-
for si in await p.get_installable_versions(spec)
|
4624
|
-
if spec.contains(si)
|
4625
|
-
]
|
4626
|
-
if lst:
|
4627
|
-
print(f' {n}')
|
4628
|
-
for si in lst:
|
4629
|
-
print(f' {si}')
|
4630
|
-
|
4631
|
-
|
4632
4544
|
########################################
|
4633
4545
|
# ../providers/running.py
|
4634
4546
|
|