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.
- 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]:
|