omdev 0.0.0.dev179__py3-none-any.whl → 0.0.0.dev181__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/cli/clicli.py +6 -6
- omdev/imgur.py +1 -1
- omdev/interp/cli.py +3 -3
- omdev/interp/inspect.py +9 -4
- omdev/interp/providers/system.py +5 -2
- omdev/interp/pyenv/pyenv.py +5 -2
- omdev/interp/venvs.py +114 -0
- 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/configs.py +3 -4
- omdev/pyproject/inject.py +12 -0
- omdev/pyproject/venvs.py +16 -52
- omdev/scripts/interp.py +32 -27
- omdev/scripts/pyproject.py +267 -145
- 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.dev179.dist-info → omdev-0.0.0.dev181.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev179.dist-info → omdev-0.0.0.dev181.dist-info}/RECORD +31 -27
- {omdev-0.0.0.dev179.dist-info → omdev-0.0.0.dev181.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev179.dist-info → omdev-0.0.0.dev181.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev179.dist-info → omdev-0.0.0.dev181.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev179.dist-info → omdev-0.0.0.dev181.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/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
@@ -12,7 +12,7 @@ import typing as ta
|
|
12
12
|
|
13
13
|
from omlish.argparse.cli import ArgparseCli
|
14
14
|
from omlish.argparse.cli import argparse_arg
|
15
|
-
from omlish.argparse.cli import
|
15
|
+
from omlish.argparse.cli import argparse_cmd
|
16
16
|
from omlish.lite.cached import cached_nullary
|
17
17
|
from omlish.lite.check import check
|
18
18
|
from omlish.lite.inject import Injector
|
@@ -37,7 +37,7 @@ class InterpCli(ArgparseCli):
|
|
37
37
|
|
38
38
|
#
|
39
39
|
|
40
|
-
@
|
40
|
+
@argparse_cmd(
|
41
41
|
argparse_arg('version'),
|
42
42
|
argparse_arg('-d', '--debug', action='store_true'),
|
43
43
|
)
|
@@ -46,7 +46,7 @@ class InterpCli(ArgparseCli):
|
|
46
46
|
s = InterpSpecifier.parse(self.args.version)
|
47
47
|
await r.list(s)
|
48
48
|
|
49
|
-
@
|
49
|
+
@argparse_cmd(
|
50
50
|
argparse_arg('version'),
|
51
51
|
argparse_arg('-p', '--provider'),
|
52
52
|
argparse_arg('-d', '--debug', action='store_true'),
|
omdev/interp/inspect.py
CHANGED
@@ -6,7 +6,6 @@ import sys
|
|
6
6
|
import typing as ta
|
7
7
|
|
8
8
|
from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
|
9
|
-
from omlish.lite.logs import log
|
10
9
|
|
11
10
|
from ..packaging.versions import Version
|
12
11
|
from .types import InterpOpts
|
@@ -43,9 +42,15 @@ class InterpInspection:
|
|
43
42
|
|
44
43
|
|
45
44
|
class InterpInspector:
|
46
|
-
def __init__(
|
45
|
+
def __init__(
|
46
|
+
self,
|
47
|
+
*,
|
48
|
+
log: ta.Optional[logging.Logger] = None,
|
49
|
+
) -> None:
|
47
50
|
super().__init__()
|
48
51
|
|
52
|
+
self._log = log
|
53
|
+
|
49
54
|
self._cache: ta.Dict[str, ta.Optional[InterpInspection]] = {}
|
50
55
|
|
51
56
|
_RAW_INSPECTION_CODE = """
|
@@ -94,8 +99,8 @@ class InterpInspector:
|
|
94
99
|
try:
|
95
100
|
ret = await self._inspect(exe)
|
96
101
|
except Exception as e: # noqa
|
97
|
-
if
|
98
|
-
|
102
|
+
if self._log is not None and self._log.isEnabledFor(logging.DEBUG):
|
103
|
+
self._log.exception('Failed to inspect interp: %s', exe)
|
99
104
|
ret = None
|
100
105
|
self._cache[exe] = ret
|
101
106
|
return ret
|
omdev/interp/providers/system.py
CHANGED
@@ -5,13 +5,13 @@ TODO:
|
|
5
5
|
- check if path py's are venvs: sys.prefix != sys.base_prefix
|
6
6
|
"""
|
7
7
|
import dataclasses as dc
|
8
|
+
import logging
|
8
9
|
import os
|
9
10
|
import re
|
10
11
|
import typing as ta
|
11
12
|
|
12
13
|
from omlish.lite.cached import cached_nullary
|
13
14
|
from omlish.lite.check import check
|
14
|
-
from omlish.lite.logs import log
|
15
15
|
|
16
16
|
from ...packaging.versions import InvalidVersion
|
17
17
|
from ..inspect import InterpInspector
|
@@ -37,12 +37,14 @@ class SystemInterpProvider(InterpProvider):
|
|
37
37
|
options: Options = Options(),
|
38
38
|
*,
|
39
39
|
inspector: ta.Optional[InterpInspector] = None,
|
40
|
+
log: ta.Optional[logging.Logger] = None,
|
40
41
|
) -> None:
|
41
42
|
super().__init__()
|
42
43
|
|
43
44
|
self._options = options
|
44
45
|
|
45
46
|
self._inspector = inspector
|
47
|
+
self._log = log
|
46
48
|
|
47
49
|
#
|
48
50
|
|
@@ -116,7 +118,8 @@ class SystemInterpProvider(InterpProvider):
|
|
116
118
|
lst = []
|
117
119
|
for e in self.exes():
|
118
120
|
if (ev := await self.get_exe_version(e)) is None:
|
119
|
-
|
121
|
+
if self._log is not None:
|
122
|
+
self._log.debug('Invalid system version: %s', e)
|
120
123
|
continue
|
121
124
|
lst.append((e, ev))
|
122
125
|
return lst
|
omdev/interp/pyenv/pyenv.py
CHANGED
@@ -13,6 +13,7 @@ TODO:
|
|
13
13
|
import abc
|
14
14
|
import dataclasses as dc
|
15
15
|
import itertools
|
16
|
+
import logging
|
16
17
|
import os.path
|
17
18
|
import shutil
|
18
19
|
import sys
|
@@ -22,7 +23,6 @@ from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
|
|
22
23
|
from omlish.lite.cached import async_cached_nullary
|
23
24
|
from omlish.lite.cached import cached_nullary
|
24
25
|
from omlish.lite.check import check
|
25
|
-
from omlish.lite.logs import log
|
26
26
|
|
27
27
|
from ...packaging.versions import InvalidVersion
|
28
28
|
from ...packaging.versions import Version
|
@@ -355,6 +355,7 @@ class PyenvInterpProvider(InterpProvider):
|
|
355
355
|
*,
|
356
356
|
pyenv: Pyenv,
|
357
357
|
inspector: InterpInspector,
|
358
|
+
log: ta.Optional[logging.Logger] = None,
|
358
359
|
) -> None:
|
359
360
|
super().__init__()
|
360
361
|
|
@@ -362,6 +363,7 @@ class PyenvInterpProvider(InterpProvider):
|
|
362
363
|
|
363
364
|
self._pyenv = pyenv
|
364
365
|
self._inspector = inspector
|
366
|
+
self._log = log
|
365
367
|
|
366
368
|
#
|
367
369
|
|
@@ -406,7 +408,8 @@ class PyenvInterpProvider(InterpProvider):
|
|
406
408
|
ret: ta.List[PyenvInterpProvider.Installed] = []
|
407
409
|
for vn, ep in await self._pyenv.version_exes():
|
408
410
|
if (i := await self._make_installed(vn, ep)) is None:
|
409
|
-
|
411
|
+
if self._log is not None:
|
412
|
+
self._log.debug('Invalid pyenv version: %s', vn)
|
410
413
|
continue
|
411
414
|
ret.append(i)
|
412
415
|
return ret
|
omdev/interp/venvs.py
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
import dataclasses as dc
|
3
|
+
import logging
|
4
|
+
import os.path
|
5
|
+
import typing as ta
|
6
|
+
|
7
|
+
from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
|
8
|
+
from omlish.lite.cached import async_cached_nullary
|
9
|
+
from omlish.lite.cached import cached_nullary
|
10
|
+
from omlish.lite.check import check
|
11
|
+
from omlish.lite.typing import Func2
|
12
|
+
|
13
|
+
from .default import get_default_interp_resolver
|
14
|
+
from .types import InterpSpecifier
|
15
|
+
|
16
|
+
|
17
|
+
##
|
18
|
+
|
19
|
+
|
20
|
+
@dc.dataclass(frozen=True)
|
21
|
+
class InterpVenvConfig:
|
22
|
+
interp: ta.Optional[str] = None
|
23
|
+
requires: ta.Optional[ta.Sequence[str]] = None
|
24
|
+
use_uv: ta.Optional[bool] = None
|
25
|
+
|
26
|
+
|
27
|
+
class InterpVenvRequirementsProcessor(Func2['InterpVenv', ta.Sequence[str], ta.Sequence[str]]):
|
28
|
+
pass
|
29
|
+
|
30
|
+
|
31
|
+
class InterpVenv:
|
32
|
+
def __init__(
|
33
|
+
self,
|
34
|
+
path: str,
|
35
|
+
cfg: InterpVenvConfig,
|
36
|
+
*,
|
37
|
+
requirements_processor: ta.Optional[InterpVenvRequirementsProcessor] = None,
|
38
|
+
log: ta.Optional[logging.Logger] = None,
|
39
|
+
) -> None:
|
40
|
+
super().__init__()
|
41
|
+
|
42
|
+
self._path = path
|
43
|
+
self._cfg = cfg
|
44
|
+
|
45
|
+
self._requirements_processor = requirements_processor
|
46
|
+
self._log = log
|
47
|
+
|
48
|
+
@property
|
49
|
+
def path(self) -> str:
|
50
|
+
return self._path
|
51
|
+
|
52
|
+
@property
|
53
|
+
def cfg(self) -> InterpVenvConfig:
|
54
|
+
return self._cfg
|
55
|
+
|
56
|
+
@async_cached_nullary
|
57
|
+
async def interp_exe(self) -> str:
|
58
|
+
i = InterpSpecifier.parse(check.not_none(self._cfg.interp))
|
59
|
+
return check.not_none(await get_default_interp_resolver().resolve(i, install=True)).exe
|
60
|
+
|
61
|
+
@cached_nullary
|
62
|
+
def exe(self) -> str:
|
63
|
+
ve = os.path.join(self._path, 'bin/python')
|
64
|
+
if not os.path.isfile(ve):
|
65
|
+
raise Exception(f'venv exe {ve} does not exist or is not a file!')
|
66
|
+
return ve
|
67
|
+
|
68
|
+
@async_cached_nullary
|
69
|
+
async def create(self) -> bool:
|
70
|
+
if os.path.exists(dn := self._path):
|
71
|
+
if not os.path.isdir(dn):
|
72
|
+
raise Exception(f'{dn} exists but is not a directory!')
|
73
|
+
return False
|
74
|
+
|
75
|
+
ie = await self.interp_exe()
|
76
|
+
|
77
|
+
if self._log is not None:
|
78
|
+
self._log.info('Using interpreter %s', ie)
|
79
|
+
|
80
|
+
await asyncio_subprocesses.check_call(ie, '-m', 'venv', dn)
|
81
|
+
|
82
|
+
ve = self.exe()
|
83
|
+
uv = self._cfg.use_uv
|
84
|
+
|
85
|
+
await asyncio_subprocesses.check_call(
|
86
|
+
ve,
|
87
|
+
'-m', 'pip',
|
88
|
+
'install', '-v', '--upgrade',
|
89
|
+
'pip',
|
90
|
+
'setuptools',
|
91
|
+
'wheel',
|
92
|
+
*(['uv'] if uv else []),
|
93
|
+
)
|
94
|
+
|
95
|
+
if sr := self._cfg.requires:
|
96
|
+
reqs = list(sr)
|
97
|
+
if self._requirements_processor is not None:
|
98
|
+
reqs = list(self._requirements_processor(self, reqs))
|
99
|
+
|
100
|
+
# TODO: automatically try slower uv download when it fails? lol
|
101
|
+
# Caused by: Failed to download distribution due to network timeout. Try increasing UV_HTTP_TIMEOUT (current value: 30s). # noqa
|
102
|
+
# UV_CONCURRENT_DOWNLOADS=4 UV_HTTP_TIMEOUT=3600
|
103
|
+
|
104
|
+
await asyncio_subprocesses.check_call(
|
105
|
+
ve,
|
106
|
+
'-m',
|
107
|
+
*(['uv'] if uv else []),
|
108
|
+
'pip',
|
109
|
+
'install',
|
110
|
+
*([] if uv else ['-v']),
|
111
|
+
*reqs,
|
112
|
+
)
|
113
|
+
|
114
|
+
return True
|
omdev/magic/__main__.py
ADDED
omdev/magic/cli.py
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from omlish.argparse.cli import ArgparseCli
|
5
|
+
from omlish.argparse.cli import argparse_arg
|
6
|
+
from omlish.argparse.cli import argparse_cmd
|
7
|
+
|
8
|
+
from .find import find_magic_files
|
9
|
+
from .find import find_magic_py_modules
|
10
|
+
from .styles import C_MAGIC_STYLE
|
11
|
+
from .styles import PY_MAGIC_STYLE
|
12
|
+
|
13
|
+
|
14
|
+
##
|
15
|
+
|
16
|
+
|
17
|
+
class MagicCli(ArgparseCli):
|
18
|
+
@argparse_cmd(
|
19
|
+
argparse_arg('--style', '-s', default='py'),
|
20
|
+
argparse_arg('--key', '-k', dest='keys', action='append'),
|
21
|
+
argparse_arg('--modules', action='store_true'),
|
22
|
+
argparse_arg('roots', nargs='*'),
|
23
|
+
)
|
24
|
+
def find(self) -> None:
|
25
|
+
style = {
|
26
|
+
'py': PY_MAGIC_STYLE,
|
27
|
+
'c': C_MAGIC_STYLE,
|
28
|
+
}[self.args.style]
|
29
|
+
|
30
|
+
kw: dict = dict(
|
31
|
+
roots=self.args.roots,
|
32
|
+
style=style,
|
33
|
+
keys=self.args.keys,
|
34
|
+
)
|
35
|
+
|
36
|
+
fn: ta.Callable
|
37
|
+
if self.args.modules:
|
38
|
+
fn = find_magic_py_modules
|
39
|
+
else:
|
40
|
+
fn = find_magic_files
|
41
|
+
|
42
|
+
for out in fn(**kw):
|
43
|
+
print(out)
|
44
|
+
|
45
|
+
|
46
|
+
##
|
47
|
+
|
48
|
+
|
49
|
+
def _main(argv=None) -> None:
|
50
|
+
MagicCli(argv).cli_run_and_exit()
|
51
|
+
|
52
|
+
|
53
|
+
if __name__ == '__main__':
|
54
|
+
_main()
|
omdev/magic/find.py
CHANGED
@@ -7,7 +7,6 @@ import typing as ta
|
|
7
7
|
from .magic import Magic
|
8
8
|
from .prepare import MagicPrepareError
|
9
9
|
from .prepare import py_compile_magic_preparer
|
10
|
-
from .styles import C_MAGIC_STYLE
|
11
10
|
from .styles import PY_MAGIC_STYLE
|
12
11
|
from .styles import MagicStyle
|
13
12
|
|
@@ -222,47 +221,3 @@ def find_magic_py_modules(
|
|
222
221
|
yield fp[:-3].replace(os.sep, '.')
|
223
222
|
else:
|
224
223
|
yield fp
|
225
|
-
|
226
|
-
|
227
|
-
##
|
228
|
-
|
229
|
-
|
230
|
-
# @omlish-manifest
|
231
|
-
_CLI_MODULE = {'$omdev.cli.types.CliModule': {
|
232
|
-
'cmd_name': 'py/findmagic',
|
233
|
-
'mod_name': __name__,
|
234
|
-
}}
|
235
|
-
|
236
|
-
|
237
|
-
if __name__ == '__main__':
|
238
|
-
def _main(argv=None) -> None:
|
239
|
-
import argparse
|
240
|
-
|
241
|
-
arg_parser = argparse.ArgumentParser()
|
242
|
-
arg_parser.add_argument('--style', '-s', default='py')
|
243
|
-
arg_parser.add_argument('--key', '-k', dest='keys', action='append')
|
244
|
-
arg_parser.add_argument('--modules', action='store_true')
|
245
|
-
arg_parser.add_argument('roots', nargs='*')
|
246
|
-
args = arg_parser.parse_args(argv)
|
247
|
-
|
248
|
-
style = {
|
249
|
-
'py': PY_MAGIC_STYLE,
|
250
|
-
'c': C_MAGIC_STYLE,
|
251
|
-
}[args.style]
|
252
|
-
|
253
|
-
kw: dict = dict(
|
254
|
-
roots=args.roots,
|
255
|
-
style=style,
|
256
|
-
keys=args.keys,
|
257
|
-
)
|
258
|
-
|
259
|
-
fn: ta.Callable
|
260
|
-
if args.modules:
|
261
|
-
fn = find_magic_py_modules
|
262
|
-
else:
|
263
|
-
fn = find_magic_files
|
264
|
-
|
265
|
-
for out in fn(**kw):
|
266
|
-
print(out)
|
267
|
-
|
268
|
-
_main()
|
omdev/pycharm/cli.py
CHANGED
@@ -77,11 +77,11 @@ def parse_wmctrl_lxp_line(l: str) -> WmctrlLine:
|
|
77
77
|
|
78
78
|
|
79
79
|
class Cli(ap.Cli):
|
80
|
-
@ap.
|
80
|
+
@ap.cmd()
|
81
81
|
def version(self) -> None:
|
82
82
|
print(get_pycharm_version())
|
83
83
|
|
84
|
-
@ap.
|
84
|
+
@ap.cmd(
|
85
85
|
ap.arg('python-exe'),
|
86
86
|
ap.arg('args', nargs=ap.REMAINDER),
|
87
87
|
)
|
@@ -99,7 +99,7 @@ class Cli(ap.Cli):
|
|
99
99
|
proc = subprocess.run([exe, src_file, *self.args.args], check=False)
|
100
100
|
return proc.returncode
|
101
101
|
|
102
|
-
@ap.
|
102
|
+
@ap.cmd(
|
103
103
|
ap.arg('dir', nargs='?'),
|
104
104
|
ap.arg('--clion', action='store_true'),
|
105
105
|
)
|
omdev/pyproject/cli.py
CHANGED
@@ -35,7 +35,7 @@ import typing as ta
|
|
35
35
|
|
36
36
|
from omlish.argparse.cli import ArgparseCli
|
37
37
|
from omlish.argparse.cli import argparse_arg
|
38
|
-
from omlish.argparse.cli import
|
38
|
+
from omlish.argparse.cli import argparse_cmd
|
39
39
|
from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
|
40
40
|
from omlish.lite.cached import cached_nullary
|
41
41
|
from omlish.lite.check import check
|
@@ -141,7 +141,7 @@ class Run:
|
|
141
141
|
class PyprojectCli(ArgparseCli):
|
142
142
|
_docker_container = argparse_arg('--_docker_container', help=argparse.SUPPRESS)
|
143
143
|
|
144
|
-
@
|
144
|
+
@argparse_cmd(
|
145
145
|
argparse_arg('name'),
|
146
146
|
argparse_arg('-e', '--docker-env', action='append'),
|
147
147
|
argparse_arg('cmd', nargs='?'),
|
@@ -223,7 +223,7 @@ class PyprojectCli(ArgparseCli):
|
|
223
223
|
else:
|
224
224
|
raise Exception(f'unknown subcommand: {cmd}')
|
225
225
|
|
226
|
-
@
|
226
|
+
@argparse_cmd(
|
227
227
|
argparse_arg('-b', '--build', action='store_true'),
|
228
228
|
argparse_arg('-r', '--revision', action='store_true'),
|
229
229
|
argparse_arg('-j', '--jobs', type=int),
|
omdev/pyproject/configs.py
CHANGED
@@ -4,15 +4,14 @@ import typing as ta
|
|
4
4
|
|
5
5
|
from omlish.lite.marshal import unmarshal_obj
|
6
6
|
|
7
|
+
from ..interp.venvs import InterpVenvConfig
|
8
|
+
|
7
9
|
|
8
10
|
@dc.dataclass(frozen=True)
|
9
|
-
class VenvConfig:
|
11
|
+
class VenvConfig(InterpVenvConfig):
|
10
12
|
inherits: ta.Optional[ta.Sequence[str]] = None
|
11
|
-
interp: ta.Optional[str] = None
|
12
|
-
requires: ta.Optional[ta.List[str]] = None
|
13
13
|
docker: ta.Optional[str] = None
|
14
14
|
srcs: ta.Optional[ta.List[str]] = None
|
15
|
-
use_uv: ta.Optional[bool] = None
|
16
15
|
|
17
16
|
|
18
17
|
@dc.dataclass(frozen=True)
|
@@ -0,0 +1,12 @@
|
|
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
|
+
|
9
|
+
def bind_pyproject() -> InjectorBindings:
|
10
|
+
lst: ta.List[InjectorBindingOrBindings] = []
|
11
|
+
|
12
|
+
return inj.as_bindings(*lst)
|
omdev/pyproject/venvs.py
CHANGED
@@ -3,14 +3,12 @@ import glob
|
|
3
3
|
import os.path
|
4
4
|
import typing as ta
|
5
5
|
|
6
|
-
from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
|
7
6
|
from omlish.lite.cached import async_cached_nullary
|
8
7
|
from omlish.lite.cached import cached_nullary
|
9
|
-
from omlish.lite.check import check
|
10
8
|
from omlish.lite.logs import log
|
11
9
|
|
12
|
-
from ..interp.
|
13
|
-
from ..interp.
|
10
|
+
from ..interp.venvs import InterpVenv
|
11
|
+
from ..interp.venvs import InterpVenvRequirementsProcessor
|
14
12
|
from .configs import VenvConfig
|
15
13
|
from .reqs import RequirementsRewriter
|
16
14
|
|
@@ -38,60 +36,26 @@ class Venv:
|
|
38
36
|
def dir_name(self) -> str:
|
39
37
|
return os.path.join(self.DIR_NAME, self._name)
|
40
38
|
|
41
|
-
@
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
@cached_nullary
|
40
|
+
def _iv(self) -> InterpVenv:
|
41
|
+
rr = RequirementsRewriter(self._name)
|
42
|
+
|
43
|
+
return InterpVenv(
|
44
|
+
self.dir_name,
|
45
|
+
self._cfg,
|
46
|
+
requirements_processor=InterpVenvRequirementsProcessor(
|
47
|
+
lambda iv, reqs: [rr.rewrite(req) for req in reqs] # noqa
|
48
|
+
),
|
49
|
+
log=log,
|
50
|
+
)
|
45
51
|
|
46
52
|
@cached_nullary
|
47
53
|
def exe(self) -> str:
|
48
|
-
|
49
|
-
if not os.path.isfile(ve):
|
50
|
-
raise Exception(f'venv exe {ve} does not exist or is not a file!')
|
51
|
-
return ve
|
54
|
+
return self._iv().exe()
|
52
55
|
|
53
56
|
@async_cached_nullary
|
54
57
|
async def create(self) -> bool:
|
55
|
-
|
56
|
-
if not os.path.isdir(dn):
|
57
|
-
raise Exception(f'{dn} exists but is not a directory!')
|
58
|
-
return False
|
59
|
-
|
60
|
-
log.info('Using interpreter %s', (ie := await self.interp_exe()))
|
61
|
-
await asyncio_subprocesses.check_call(ie, '-m', 'venv', dn)
|
62
|
-
|
63
|
-
ve = self.exe()
|
64
|
-
uv = self._cfg.use_uv
|
65
|
-
|
66
|
-
await asyncio_subprocesses.check_call(
|
67
|
-
ve,
|
68
|
-
'-m', 'pip',
|
69
|
-
'install', '-v', '--upgrade',
|
70
|
-
'pip',
|
71
|
-
'setuptools',
|
72
|
-
'wheel',
|
73
|
-
*(['uv'] if uv else []),
|
74
|
-
)
|
75
|
-
|
76
|
-
if sr := self._cfg.requires:
|
77
|
-
rr = RequirementsRewriter(self._name)
|
78
|
-
reqs = [rr.rewrite(req) for req in sr]
|
79
|
-
|
80
|
-
# TODO: automatically try slower uv download when it fails? lol
|
81
|
-
# Caused by: Failed to download distribution due to network timeout. Try increasing UV_HTTP_TIMEOUT (current value: 30s). # noqa
|
82
|
-
# UV_CONCURRENT_DOWNLOADS=4 UV_HTTP_TIMEOUT=3600
|
83
|
-
|
84
|
-
await asyncio_subprocesses.check_call(
|
85
|
-
ve,
|
86
|
-
'-m',
|
87
|
-
*(['uv'] if uv else []),
|
88
|
-
'pip',
|
89
|
-
'install',
|
90
|
-
*([] if uv else ['-v']),
|
91
|
-
*reqs,
|
92
|
-
)
|
93
|
-
|
94
|
-
return True
|
58
|
+
return await self._iv().create()
|
95
59
|
|
96
60
|
@staticmethod
|
97
61
|
def _resolve_srcs(raw: ta.List[str]) -> ta.List[str]:
|