omdev 0.0.0.dev178__py3-none-any.whl → 0.0.0.dev180__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- omdev/.manifests.json +5 -5
- omdev/amalg/main.py +1 -0
- omdev/cexts/importhook.py +1 -1
- omdev/cli/clicli.py +6 -6
- omdev/imgur.py +1 -1
- omdev/interp/cli.py +44 -43
- omdev/interp/default.py +10 -0
- omdev/interp/inject.py +54 -0
- omdev/interp/inspect.py +0 -3
- omdev/interp/providers/__init__.py +0 -0
- omdev/interp/{providers.py → providers/base.py} +4 -24
- omdev/interp/providers/inject.py +26 -0
- omdev/interp/providers/running.py +27 -0
- omdev/interp/{system.py → providers/system.py} +27 -15
- omdev/interp/pyenv/__init__.py +0 -0
- omdev/interp/pyenv/inject.py +21 -0
- omdev/interp/{pyenv.py → pyenv/pyenv.py} +24 -23
- omdev/interp/resolvers.py +7 -22
- omdev/interp/types.py +12 -0
- omdev/interp/uv/__init__.py +0 -0
- omdev/interp/uv/inject.py +12 -0
- omdev/interp/{uv.py → uv/uv.py} +4 -4
- omdev/magic/__main__.py +11 -0
- omdev/magic/cli.py +54 -0
- omdev/magic/find.py +0 -45
- omdev/pycharm/cli.py +3 -3
- omdev/pyproject/cli.py +3 -3
- omdev/pyproject/venvs.py +2 -2
- omdev/scripts/interp.py +1968 -466
- omdev/scripts/pyproject.py +3320 -2093
- omdev/tools/doc.py +2 -2
- omdev/tools/docker.py +8 -8
- omdev/tools/git.py +7 -7
- omdev/tools/notebook.py +1 -1
- omdev/tools/pip.py +4 -4
- omdev/tools/prof.py +1 -1
- omdev/tools/sqlrepl.py +1 -1
- {omdev-0.0.0.dev178.dist-info → omdev-0.0.0.dev180.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev178.dist-info → omdev-0.0.0.dev180.dist-info}/RECORD +44 -33
- /omdev/interp/{standalone.py → providers/standalone.py} +0 -0
- {omdev-0.0.0.dev178.dist-info → omdev-0.0.0.dev180.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev178.dist-info → omdev-0.0.0.dev180.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev178.dist-info → omdev-0.0.0.dev180.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev178.dist-info → omdev-0.0.0.dev180.dist-info}/top_level.txt +0 -0
omdev/.manifests.json
CHANGED
@@ -96,14 +96,14 @@
|
|
96
96
|
}
|
97
97
|
},
|
98
98
|
{
|
99
|
-
"module": ".magic.
|
99
|
+
"module": ".magic.__main__",
|
100
100
|
"attr": "_CLI_MODULE",
|
101
|
-
"file": "omdev/magic/
|
102
|
-
"line":
|
101
|
+
"file": "omdev/magic/__main__.py",
|
102
|
+
"line": 4,
|
103
103
|
"value": {
|
104
104
|
"$.cli.types.CliModule": {
|
105
|
-
"cmd_name": "
|
106
|
-
"mod_name": "omdev.magic.
|
105
|
+
"cmd_name": "magic",
|
106
|
+
"mod_name": "omdev.magic.__main__"
|
107
107
|
}
|
108
108
|
}
|
109
109
|
},
|
omdev/amalg/main.py
CHANGED
@@ -5,6 +5,7 @@ Conventions:
|
|
5
5
|
|
6
6
|
TODO:
|
7
7
|
- !! check only importing lite code
|
8
|
+
- check no rel impots
|
8
9
|
- !! strip manifests? or relegate them to a separate tiny module ala __main__.py?
|
9
10
|
- # @omlish-no-amalg ? in cli.types? will strip stmt (more than 1 line) following @manifest, so shouldn't import
|
10
11
|
- more sanity checks lol
|
omdev/cexts/importhook.py
CHANGED
@@ -26,7 +26,7 @@ def load_dynamic(name: str, path: str) -> types.ModuleType:
|
|
26
26
|
spec = importlib.machinery.ModuleSpec(name=name, loader=loader, origin=path)
|
27
27
|
|
28
28
|
import importlib._bootstrap # FIXME: # noqa
|
29
|
-
return importlib._bootstrap._load(spec) # noqa
|
29
|
+
return importlib._bootstrap._load(spec) # type: ignore # noqa
|
30
30
|
|
31
31
|
|
32
32
|
##
|
omdev/cli/clicli.py
CHANGED
@@ -21,15 +21,15 @@ class CliCli(ap.Cli):
|
|
21
21
|
|
22
22
|
#
|
23
23
|
|
24
|
-
@ap.
|
24
|
+
@ap.cmd(name='version', aliases=['ver'])
|
25
25
|
def print_version(self) -> None:
|
26
26
|
print(__about__.__version__)
|
27
27
|
|
28
|
-
@ap.
|
28
|
+
@ap.cmd(name='revision', aliases=['rev'])
|
29
29
|
def print_revision(self) -> None:
|
30
30
|
print(__about__.__revision__)
|
31
31
|
|
32
|
-
@ap.
|
32
|
+
@ap.cmd(name='home')
|
33
33
|
def print_home(self) -> None:
|
34
34
|
print(sys.prefix)
|
35
35
|
|
@@ -52,7 +52,7 @@ class CliCli(ap.Cli):
|
|
52
52
|
],
|
53
53
|
)
|
54
54
|
|
55
|
-
@ap.
|
55
|
+
@ap.cmd(
|
56
56
|
ap.arg('args', nargs=ap.REMAINDER),
|
57
57
|
name='python',
|
58
58
|
accepts_unknown=True,
|
@@ -60,7 +60,7 @@ class CliCli(ap.Cli):
|
|
60
60
|
def python_cmd(self) -> None:
|
61
61
|
self._passthrough_args_cmd(sys.executable)
|
62
62
|
|
63
|
-
@ap.
|
63
|
+
@ap.cmd(
|
64
64
|
ap.arg('args', nargs=ap.REMAINDER),
|
65
65
|
name='pip',
|
66
66
|
accepts_unknown=True,
|
@@ -70,7 +70,7 @@ class CliCli(ap.Cli):
|
|
70
70
|
|
71
71
|
#
|
72
72
|
|
73
|
-
@ap.
|
73
|
+
@ap.cmd(
|
74
74
|
ap.arg('--url', default=DEFAULT_REINSTALL_URL),
|
75
75
|
ap.arg('--local', action='store_true'),
|
76
76
|
ap.arg('extra_deps', nargs='*'),
|
omdev/imgur.py
CHANGED
omdev/interp/cli.py
CHANGED
@@ -7,66 +7,67 @@ TODO:
|
|
7
7
|
- https://github.com/asdf-vm/asdf support (instead of pyenv) ?
|
8
8
|
- colon sep provider name prefix - pyenv:3.12
|
9
9
|
"""
|
10
|
-
import argparse
|
11
10
|
import asyncio
|
12
11
|
import typing as ta
|
13
12
|
|
13
|
+
from omlish.argparse.cli import ArgparseCli
|
14
|
+
from omlish.argparse.cli import argparse_arg
|
15
|
+
from omlish.argparse.cli import argparse_cmd
|
16
|
+
from omlish.lite.cached import cached_nullary
|
14
17
|
from omlish.lite.check import check
|
18
|
+
from omlish.lite.inject import Injector
|
19
|
+
from omlish.lite.inject import inj
|
15
20
|
from omlish.lite.runtime import check_lite_runtime_version
|
16
21
|
from omlish.logs.standard import configure_standard_logging
|
17
22
|
|
18
|
-
from .
|
19
|
-
from .resolvers import INTERP_PROVIDER_TYPES_BY_NAME
|
23
|
+
from .inject import bind_interp
|
20
24
|
from .resolvers import InterpResolver
|
25
|
+
from .resolvers import InterpResolverProviders
|
21
26
|
from .types import InterpSpecifier
|
22
27
|
|
23
28
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
29
|
+
class InterpCli(ArgparseCli):
|
30
|
+
@cached_nullary
|
31
|
+
def injector(self) -> Injector:
|
32
|
+
return inj.create_injector(bind_interp())
|
33
|
+
|
34
|
+
@cached_nullary
|
35
|
+
def providers(self) -> InterpResolverProviders:
|
36
|
+
return self.injector()[InterpResolverProviders]
|
37
|
+
|
38
|
+
#
|
39
|
+
|
40
|
+
@argparse_cmd(
|
41
|
+
argparse_arg('version'),
|
42
|
+
argparse_arg('-d', '--debug', action='store_true'),
|
43
|
+
)
|
44
|
+
async def list(self) -> None:
|
45
|
+
r = InterpResolver(self.providers())
|
46
|
+
s = InterpSpecifier.parse(self.args.version)
|
47
|
+
await r.list(s)
|
48
|
+
|
49
|
+
@argparse_cmd(
|
50
|
+
argparse_arg('version'),
|
51
|
+
argparse_arg('-p', '--provider'),
|
52
|
+
argparse_arg('-d', '--debug', action='store_true'),
|
53
|
+
argparse_arg('-i', '--install', action='store_true'),
|
54
|
+
)
|
55
|
+
async def resolve(self) -> None:
|
56
|
+
if self.args.provider:
|
57
|
+
p = check.single([p for n, p in self.providers().providers if n == self.args.provider])
|
58
|
+
r = InterpResolver(InterpResolverProviders([(p.name, p)]))
|
59
|
+
else:
|
60
|
+
r = InterpResolver(self.providers())
|
61
|
+
s = InterpSpecifier.parse(self.args.version)
|
62
|
+
print(check.not_none(await r.resolve(s, install=bool(self.args.install))).exe)
|
58
63
|
|
59
64
|
|
60
65
|
async def _async_main(argv: ta.Optional[ta.Sequence[str]] = None) -> None:
|
61
66
|
check_lite_runtime_version()
|
62
67
|
configure_standard_logging()
|
63
68
|
|
64
|
-
|
65
|
-
|
66
|
-
if not getattr(args, 'func', None):
|
67
|
-
parser.print_help()
|
68
|
-
else:
|
69
|
-
await args.func(args)
|
69
|
+
cli = ArgparseCli(argv)
|
70
|
+
await cli.async_cli_run()
|
70
71
|
|
71
72
|
|
72
73
|
def _main(argv: ta.Optional[ta.Sequence[str]] = None) -> None:
|
omdev/interp/default.py
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
from omlish.lite.cached import cached_nullary
|
2
|
+
from omlish.lite.inject import inj
|
3
|
+
|
4
|
+
from .inject import bind_interp
|
5
|
+
from .resolvers import InterpResolver
|
6
|
+
|
7
|
+
|
8
|
+
@cached_nullary
|
9
|
+
def get_default_interp_resolver() -> InterpResolver:
|
10
|
+
return inj.create_injector(bind_interp())[InterpResolver]
|
omdev/interp/inject.py
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from omlish.lite.inject import Injector
|
5
|
+
from omlish.lite.inject import InjectorBindingOrBindings
|
6
|
+
from omlish.lite.inject import InjectorBindings
|
7
|
+
from omlish.lite.inject import inj
|
8
|
+
|
9
|
+
from .inspect import InterpInspector
|
10
|
+
from .providers.inject import bind_interp_providers
|
11
|
+
from .providers.running import RunningInterpProvider
|
12
|
+
from .providers.system import SystemInterpProvider
|
13
|
+
from .pyenv.inject import bind_interp_pyenv
|
14
|
+
from .pyenv.pyenv import PyenvInterpProvider
|
15
|
+
from .resolvers import InterpResolver
|
16
|
+
from .resolvers import InterpResolverProviders
|
17
|
+
from .uv.inject import bind_interp_uv
|
18
|
+
|
19
|
+
|
20
|
+
def bind_interp() -> InjectorBindings:
|
21
|
+
lst: ta.List[InjectorBindingOrBindings] = [
|
22
|
+
bind_interp_providers(),
|
23
|
+
|
24
|
+
bind_interp_pyenv(),
|
25
|
+
|
26
|
+
bind_interp_uv(),
|
27
|
+
|
28
|
+
inj.bind(InterpInspector, singleton=True),
|
29
|
+
]
|
30
|
+
|
31
|
+
#
|
32
|
+
|
33
|
+
def provide_interp_resolver_providers(injector: Injector) -> InterpResolverProviders:
|
34
|
+
# FIXME: lol
|
35
|
+
rps: ta.List[ta.Any] = [
|
36
|
+
injector.provide(c)
|
37
|
+
for c in [
|
38
|
+
PyenvInterpProvider,
|
39
|
+
RunningInterpProvider,
|
40
|
+
SystemInterpProvider,
|
41
|
+
]
|
42
|
+
]
|
43
|
+
|
44
|
+
return InterpResolverProviders([(rp.name, rp) for rp in rps])
|
45
|
+
|
46
|
+
lst.append(inj.bind(provide_interp_resolver_providers, singleton=True))
|
47
|
+
|
48
|
+
lst.extend([
|
49
|
+
inj.bind(InterpResolver, singleton=True),
|
50
|
+
])
|
51
|
+
|
52
|
+
#
|
53
|
+
|
54
|
+
return inj.as_bindings(*lst)
|
omdev/interp/inspect.py
CHANGED
File without changes
|
@@ -7,16 +7,13 @@ TODO:
|
|
7
7
|
- loose versions
|
8
8
|
"""
|
9
9
|
import abc
|
10
|
-
import sys
|
11
10
|
import typing as ta
|
12
11
|
|
13
|
-
from omlish.lite.cached import cached_nullary
|
14
12
|
from omlish.lite.strings import snake_case
|
15
13
|
|
16
|
-
from
|
17
|
-
from
|
18
|
-
from
|
19
|
-
from .types import InterpVersion
|
14
|
+
from ..types import Interp
|
15
|
+
from ..types import InterpSpecifier
|
16
|
+
from ..types import InterpVersion
|
20
17
|
|
21
18
|
|
22
19
|
##
|
@@ -48,21 +45,4 @@ class InterpProvider(abc.ABC):
|
|
48
45
|
raise TypeError
|
49
46
|
|
50
47
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
class RunningInterpProvider(InterpProvider):
|
55
|
-
@cached_nullary
|
56
|
-
def version(self) -> InterpVersion:
|
57
|
-
return InterpInspector.running().iv
|
58
|
-
|
59
|
-
async def get_installed_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
60
|
-
return [self.version()]
|
61
|
-
|
62
|
-
async def get_installed_version(self, version: InterpVersion) -> Interp:
|
63
|
-
if version != self.version():
|
64
|
-
raise KeyError(version)
|
65
|
-
return Interp(
|
66
|
-
exe=sys.executable,
|
67
|
-
version=self.version(),
|
68
|
-
)
|
48
|
+
InterpProviders = ta.NewType('InterpProviders', ta.Sequence[InterpProvider])
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from omlish.lite.inject import InjectorBindingOrBindings
|
5
|
+
from omlish.lite.inject import InjectorBindings
|
6
|
+
from omlish.lite.inject import inj
|
7
|
+
|
8
|
+
from .base import InterpProvider
|
9
|
+
from .base import InterpProviders
|
10
|
+
from .running import RunningInterpProvider
|
11
|
+
from .system import SystemInterpProvider
|
12
|
+
|
13
|
+
|
14
|
+
def bind_interp_providers() -> InjectorBindings:
|
15
|
+
lst: ta.List[InjectorBindingOrBindings] = [
|
16
|
+
inj.bind_array(InterpProvider),
|
17
|
+
inj.bind_array_type(InterpProvider, InterpProviders),
|
18
|
+
|
19
|
+
inj.bind(RunningInterpProvider, singleton=True),
|
20
|
+
inj.bind(InterpProvider, to_key=RunningInterpProvider, array=True),
|
21
|
+
|
22
|
+
inj.bind(SystemInterpProvider, singleton=True),
|
23
|
+
inj.bind(InterpProvider, to_key=SystemInterpProvider, array=True),
|
24
|
+
]
|
25
|
+
|
26
|
+
return inj.as_bindings(*lst)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import sys
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from omlish.lite.cached import cached_nullary
|
5
|
+
|
6
|
+
from ..inspect import InterpInspector
|
7
|
+
from ..types import Interp
|
8
|
+
from ..types import InterpSpecifier
|
9
|
+
from ..types import InterpVersion
|
10
|
+
from .base import InterpProvider
|
11
|
+
|
12
|
+
|
13
|
+
class RunningInterpProvider(InterpProvider):
|
14
|
+
@cached_nullary
|
15
|
+
def version(self) -> InterpVersion:
|
16
|
+
return InterpInspector.running().iv
|
17
|
+
|
18
|
+
async def get_installed_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
19
|
+
return [self.version()]
|
20
|
+
|
21
|
+
async def get_installed_version(self, version: InterpVersion) -> Interp:
|
22
|
+
if version != self.version():
|
23
|
+
raise KeyError(version)
|
24
|
+
return Interp(
|
25
|
+
exe=sys.executable,
|
26
|
+
version=self.version(),
|
27
|
+
)
|
@@ -10,27 +10,39 @@ import re
|
|
10
10
|
import typing as ta
|
11
11
|
|
12
12
|
from omlish.lite.cached import cached_nullary
|
13
|
+
from omlish.lite.check import check
|
13
14
|
from omlish.lite.logs import log
|
14
15
|
|
15
|
-
from
|
16
|
-
from
|
17
|
-
from
|
18
|
-
from
|
19
|
-
from
|
20
|
-
from .
|
21
|
-
from .types import InterpVersion
|
16
|
+
from ...packaging.versions import InvalidVersion
|
17
|
+
from ..inspect import InterpInspector
|
18
|
+
from ..types import Interp
|
19
|
+
from ..types import InterpSpecifier
|
20
|
+
from ..types import InterpVersion
|
21
|
+
from .base import InterpProvider
|
22
22
|
|
23
23
|
|
24
24
|
##
|
25
25
|
|
26
26
|
|
27
|
-
@dc.dataclass(frozen=True)
|
28
27
|
class SystemInterpProvider(InterpProvider):
|
29
|
-
|
30
|
-
|
28
|
+
@dc.dataclass(frozen=True)
|
29
|
+
class Options:
|
30
|
+
cmd: str = 'python3' # FIXME: unused lol
|
31
|
+
path: ta.Optional[str] = None
|
31
32
|
|
32
|
-
|
33
|
-
|
33
|
+
inspect: bool = False
|
34
|
+
|
35
|
+
def __init__(
|
36
|
+
self,
|
37
|
+
options: Options = Options(),
|
38
|
+
*,
|
39
|
+
inspector: ta.Optional[InterpInspector] = None,
|
40
|
+
) -> None:
|
41
|
+
super().__init__()
|
42
|
+
|
43
|
+
self._options = options
|
44
|
+
|
45
|
+
self._inspector = inspector
|
34
46
|
|
35
47
|
#
|
36
48
|
|
@@ -82,13 +94,13 @@ class SystemInterpProvider(InterpProvider):
|
|
82
94
|
def exes(self) -> ta.List[str]:
|
83
95
|
return self._re_which(
|
84
96
|
re.compile(r'python3(\.\d+)?'),
|
85
|
-
path=self.path,
|
97
|
+
path=self._options.path,
|
86
98
|
)
|
87
99
|
|
88
100
|
#
|
89
101
|
|
90
102
|
async def get_exe_version(self, exe: str) -> ta.Optional[InterpVersion]:
|
91
|
-
if not self.inspect:
|
103
|
+
if not self._options.inspect:
|
92
104
|
s = os.path.basename(exe)
|
93
105
|
if s.startswith('python'):
|
94
106
|
s = s[len('python'):]
|
@@ -97,7 +109,7 @@ class SystemInterpProvider(InterpProvider):
|
|
97
109
|
return InterpVersion.parse(s)
|
98
110
|
except InvalidVersion:
|
99
111
|
pass
|
100
|
-
ii = await self.
|
112
|
+
ii = await check.not_none(self._inspector).inspect(exe)
|
101
113
|
return ii.iv if ii is not None else None
|
102
114
|
|
103
115
|
async def exe_versions(self) -> ta.Sequence[ta.Tuple[str, InterpVersion]]:
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from omlish.lite.inject import InjectorBindingOrBindings
|
5
|
+
from omlish.lite.inject import InjectorBindings
|
6
|
+
from omlish.lite.inject import inj
|
7
|
+
|
8
|
+
from ..providers.base import InterpProvider
|
9
|
+
from .pyenv import Pyenv
|
10
|
+
from .pyenv import PyenvInterpProvider
|
11
|
+
|
12
|
+
|
13
|
+
def bind_interp_pyenv() -> InjectorBindings:
|
14
|
+
lst: ta.List[InjectorBindingOrBindings] = [
|
15
|
+
inj.bind(Pyenv, singleton=True),
|
16
|
+
|
17
|
+
inj.bind(PyenvInterpProvider, singleton=True),
|
18
|
+
inj.bind(InterpProvider, to_key=PyenvInterpProvider, array=True),
|
19
|
+
]
|
20
|
+
|
21
|
+
return inj.as_bindings(*lst)
|
@@ -24,15 +24,14 @@ from omlish.lite.cached import cached_nullary
|
|
24
24
|
from omlish.lite.check import check
|
25
25
|
from omlish.lite.logs import log
|
26
26
|
|
27
|
-
from
|
28
|
-
from
|
29
|
-
from
|
30
|
-
from .
|
31
|
-
from
|
32
|
-
from
|
33
|
-
from
|
34
|
-
from
|
35
|
-
from .types import InterpVersion
|
27
|
+
from ...packaging.versions import InvalidVersion
|
28
|
+
from ...packaging.versions import Version
|
29
|
+
from ..inspect import InterpInspector
|
30
|
+
from ..providers.base import InterpProvider
|
31
|
+
from ..types import Interp
|
32
|
+
from ..types import InterpOpts
|
33
|
+
from ..types import InterpSpecifier
|
34
|
+
from ..types import InterpVersion
|
36
35
|
|
37
36
|
|
38
37
|
##
|
@@ -251,9 +250,10 @@ class PyenvVersionInstaller:
|
|
251
250
|
opts: ta.Optional[PyenvInstallOpts] = None,
|
252
251
|
interp_opts: InterpOpts = InterpOpts(),
|
253
252
|
*,
|
253
|
+
pyenv: Pyenv,
|
254
|
+
|
254
255
|
install_name: ta.Optional[str] = None,
|
255
256
|
no_default_opts: bool = False,
|
256
|
-
pyenv: Pyenv = Pyenv(),
|
257
257
|
) -> None:
|
258
258
|
super().__init__()
|
259
259
|
|
@@ -343,26 +343,26 @@ class PyenvVersionInstaller:
|
|
343
343
|
|
344
344
|
|
345
345
|
class PyenvInterpProvider(InterpProvider):
|
346
|
-
|
347
|
-
|
348
|
-
|
346
|
+
@dc.dataclass(frozen=True)
|
347
|
+
class Options:
|
348
|
+
inspect: bool = False
|
349
349
|
|
350
|
-
|
351
|
-
inspector: InterpInspector = INTERP_INSPECTOR,
|
350
|
+
try_update: bool = False
|
352
351
|
|
352
|
+
def __init__(
|
353
|
+
self,
|
354
|
+
options: Options = Options(),
|
353
355
|
*,
|
354
|
-
|
355
|
-
|
356
|
+
pyenv: Pyenv,
|
357
|
+
inspector: InterpInspector,
|
356
358
|
) -> None:
|
357
359
|
super().__init__()
|
358
360
|
|
359
|
-
self.
|
361
|
+
self._options = options
|
360
362
|
|
361
|
-
self.
|
363
|
+
self._pyenv = pyenv
|
362
364
|
self._inspector = inspector
|
363
365
|
|
364
|
-
self._try_update = try_update
|
365
|
-
|
366
366
|
#
|
367
367
|
|
368
368
|
@staticmethod
|
@@ -387,7 +387,7 @@ class PyenvInterpProvider(InterpProvider):
|
|
387
387
|
|
388
388
|
async def _make_installed(self, vn: str, ep: str) -> ta.Optional[Installed]:
|
389
389
|
iv: ta.Optional[InterpVersion]
|
390
|
-
if self.
|
390
|
+
if self._options.inspect:
|
391
391
|
try:
|
392
392
|
iv = check.not_none(await self._inspector.inspect(ep)).iv
|
393
393
|
except Exception as e: # noqa
|
@@ -443,7 +443,7 @@ class PyenvInterpProvider(InterpProvider):
|
|
443
443
|
async def get_installable_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
444
444
|
lst = await self._get_installable_versions(spec)
|
445
445
|
|
446
|
-
if self.
|
446
|
+
if self._options.try_update and not any(v in spec for v in lst):
|
447
447
|
if self._pyenv.update():
|
448
448
|
lst = await self._get_installable_versions(spec)
|
449
449
|
|
@@ -459,6 +459,7 @@ class PyenvInterpProvider(InterpProvider):
|
|
459
459
|
installer = PyenvVersionInstaller(
|
460
460
|
inst_version,
|
461
461
|
interp_opts=inst_opts,
|
462
|
+
pyenv=self._pyenv,
|
462
463
|
)
|
463
464
|
|
464
465
|
exe = await installer.install()
|
omdev/interp/resolvers.py
CHANGED
@@ -1,32 +1,27 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
|
-
import abc
|
3
2
|
import collections
|
3
|
+
import dataclasses as dc
|
4
4
|
import typing as ta
|
5
5
|
|
6
|
-
from
|
7
|
-
|
8
|
-
from .providers import InterpProvider
|
9
|
-
from .providers import RunningInterpProvider
|
10
|
-
from .pyenv import PyenvInterpProvider
|
11
|
-
from .system import SystemInterpProvider
|
6
|
+
from .providers.base import InterpProvider
|
12
7
|
from .types import Interp
|
13
8
|
from .types import InterpSpecifier
|
14
9
|
from .types import InterpVersion
|
15
10
|
|
16
11
|
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
@dc.dataclass(frozen=True)
|
13
|
+
class InterpResolverProviders:
|
14
|
+
providers: ta.Sequence[ta.Tuple[str, InterpProvider]]
|
20
15
|
|
21
16
|
|
22
17
|
class InterpResolver:
|
23
18
|
def __init__(
|
24
19
|
self,
|
25
|
-
providers:
|
20
|
+
providers: InterpResolverProviders,
|
26
21
|
) -> None:
|
27
22
|
super().__init__()
|
28
23
|
|
29
|
-
self._providers: ta.Mapping[str, InterpProvider] = collections.OrderedDict(providers)
|
24
|
+
self._providers: ta.Mapping[str, InterpProvider] = collections.OrderedDict(providers.providers)
|
30
25
|
|
31
26
|
async def _resolve_installed(self, spec: InterpSpecifier) -> ta.Optional[ta.Tuple[InterpProvider, InterpVersion]]:
|
32
27
|
lst = [
|
@@ -96,13 +91,3 @@ class InterpResolver:
|
|
96
91
|
print(f' {n}')
|
97
92
|
for si in lst:
|
98
93
|
print(f' {si}')
|
99
|
-
|
100
|
-
|
101
|
-
DEFAULT_INTERP_RESOLVER = InterpResolver([(p.name, p) for p in [
|
102
|
-
# pyenv is preferred to system interpreters as it tends to have more support for things like tkinter
|
103
|
-
PyenvInterpProvider(try_update=True),
|
104
|
-
|
105
|
-
RunningInterpProvider(),
|
106
|
-
|
107
|
-
SystemInterpProvider(),
|
108
|
-
]])
|
omdev/interp/types.py
CHANGED
@@ -8,6 +8,9 @@ from ..packaging.versions import InvalidVersion
|
|
8
8
|
from ..packaging.versions import Version
|
9
9
|
|
10
10
|
|
11
|
+
##
|
12
|
+
|
13
|
+
|
11
14
|
# See https://peps.python.org/pep-3149/
|
12
15
|
INTERP_OPT_GLYPHS_BY_ATTR: ta.Mapping[str, str] = collections.OrderedDict([
|
13
16
|
('debug', 'd'),
|
@@ -39,6 +42,9 @@ class InterpOpts:
|
|
39
42
|
return s, cls(**kw)
|
40
43
|
|
41
44
|
|
45
|
+
##
|
46
|
+
|
47
|
+
|
42
48
|
@dc.dataclass(frozen=True)
|
43
49
|
class InterpVersion:
|
44
50
|
version: Version
|
@@ -64,6 +70,9 @@ class InterpVersion:
|
|
64
70
|
return None
|
65
71
|
|
66
72
|
|
73
|
+
##
|
74
|
+
|
75
|
+
|
67
76
|
@dc.dataclass(frozen=True)
|
68
77
|
class InterpSpecifier:
|
69
78
|
specifier: Specifier
|
@@ -91,6 +100,9 @@ class InterpSpecifier:
|
|
91
100
|
return self.contains(iv)
|
92
101
|
|
93
102
|
|
103
|
+
##
|
104
|
+
|
105
|
+
|
94
106
|
@dc.dataclass(frozen=True)
|
95
107
|
class Interp:
|
96
108
|
exe: str
|