omdev 0.0.0.dev19__tar.gz → 0.0.0.dev21__tar.gz
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.
Potentially problematic release.
This version of omdev might be problematic. Click here for more details.
- {omdev-0.0.0.dev19/omdev.egg-info → omdev-0.0.0.dev21}/PKG-INFO +5 -2
- omdev-0.0.0.dev21/README.rst +10 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/__about__.py +4 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/interp/cli.py +2 -1
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/interp/providers.py +1 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/interp/pyenv.py +49 -15
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/interp/resolvers.py +36 -5
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/interp/types.py +3 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/pyproject/cli.py +13 -4
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/pyproject/configs.py +1 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/pyproject/pkg.py +1 -1
- omdev-0.0.0.dev21/omdev/pyproject/reqs.py +78 -0
- {omdev-0.0.0.dev19/omdev/tools → omdev-0.0.0.dev21/omdev}/revisions.py +1 -1
- omdev-0.0.0.dev21/omdev/scripts/__init__.py +1 -0
- omdev-0.0.0.dev21/omdev/scripts/bumpversion.py +43 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/scripts/interp.py +91 -23
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/scripts/pyproject.py +186 -29
- omdev-0.0.0.dev21/omdev/tools/__init__.py +1 -0
- omdev-0.0.0.dev21/omdev/tools/rst.py +44 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21/omdev.egg-info}/PKG-INFO +5 -2
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev.egg-info/SOURCES.txt +4 -1
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev.egg-info/requires.txt +5 -1
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/pyproject.toml +6 -2
- omdev-0.0.0.dev19/README.rst +0 -5
- omdev-0.0.0.dev19/omdev/scripts/__init__.py +0 -0
- omdev-0.0.0.dev19/omdev/tools/__init__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/LICENSE +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/MANIFEST.in +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/__init__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/amalg/__init__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/amalg/__main__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/amalg/amalg.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/bracepy.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/__init__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/__init__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/build_ext.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/compilers/__init__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/compilers/ccompiler.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/compilers/options.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/compilers/unixccompiler.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/dir_util.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/errors.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/extension.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/file_util.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/modified.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/spawn.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/sysconfig.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/util.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/_distutils/version.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/build.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/cmake.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/importhook.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/magic.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cexts/scan.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/classdot.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/cmake.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/findimports.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/findmagic.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/interp/__init__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/interp/__main__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/interp/inspect.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/interp/standalone.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/interp/system.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/mypy/__init__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/mypy/debug.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/precheck/__init__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/precheck/__main__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/precheck/precheck.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/pyproject/__init__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/pyproject/__main__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/pyproject/cexts.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/scripts/execrss.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/tokens.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/toml/__init__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/toml/parser.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/toml/writer.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/tools/dockertools.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/tools/gittools.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/tools/sqlrepl.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/tools/traceimport.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/versioning/__init__.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/versioning/specifiers.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/versioning/versions.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev/wheelfile.py +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev.egg-info/dependency_links.txt +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/omdev.egg-info/top_level.txt +0 -0
- {omdev-0.0.0.dev19 → omdev-0.0.0.dev21}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: omdev
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev21
|
|
4
4
|
Summary: omdev
|
|
5
5
|
Author: wrmsr
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -12,11 +12,12 @@ Classifier: Operating System :: OS Independent
|
|
|
12
12
|
Classifier: Operating System :: POSIX
|
|
13
13
|
Requires-Python: ~=3.12
|
|
14
14
|
License-File: LICENSE
|
|
15
|
-
Requires-Dist: omlish==0.0.0.
|
|
15
|
+
Requires-Dist: omlish==0.0.0.dev21
|
|
16
16
|
Provides-Extra: all
|
|
17
17
|
Requires-Dist: pycparser~=2.22; extra == "all"
|
|
18
18
|
Requires-Dist: cffi~=1.17; extra == "all"
|
|
19
19
|
Requires-Dist: pcpp~=1.30; extra == "all"
|
|
20
|
+
Requires-Dist: docutils~=0.21; extra == "all"
|
|
20
21
|
Requires-Dist: mypy~=1.11; extra == "all"
|
|
21
22
|
Requires-Dist: tokenize_rt~=6.0; extra == "all"
|
|
22
23
|
Requires-Dist: wheel~=0.44; extra == "all"
|
|
@@ -24,6 +25,8 @@ Provides-Extra: c
|
|
|
24
25
|
Requires-Dist: pycparser~=2.22; extra == "c"
|
|
25
26
|
Requires-Dist: cffi~=1.17; extra == "c"
|
|
26
27
|
Requires-Dist: pcpp~=1.30; extra == "c"
|
|
28
|
+
Provides-Extra: docutils
|
|
29
|
+
Requires-Dist: docutils~=0.21; extra == "docutils"
|
|
27
30
|
Provides-Extra: mypy
|
|
28
31
|
Requires-Dist: mypy~=1.11; extra == "mypy"
|
|
29
32
|
Provides-Extra: tokens
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
It's like my previous python monorepo-ey thing `omnibus
|
|
2
|
+
<https://github.com/wrmsr/omnibus/tree/wrmsr_exp_split>`_... ish.
|
|
3
|
+
|
|
4
|
+
Core packages begin with ``om``, scratch app is in ``app``, temp / dump code is in ``x``.
|
|
5
|
+
|
|
6
|
+
Core packages installable from git via:
|
|
7
|
+
|
|
8
|
+
.. code-block::
|
|
9
|
+
|
|
10
|
+
pip install 'git+https://github.com/wrmsr/omlish@master#subdirectory=.pkg/<pkg>'
|
|
@@ -10,6 +10,7 @@ TODO:
|
|
|
10
10
|
import argparse
|
|
11
11
|
import typing as ta
|
|
12
12
|
|
|
13
|
+
from omlish.lite.check import check_not_none
|
|
13
14
|
from omlish.lite.logs import configure_standard_logging
|
|
14
15
|
from omlish.lite.runtime import check_runtime_version
|
|
15
16
|
|
|
@@ -26,7 +27,7 @@ def _list_cmd(args) -> None:
|
|
|
26
27
|
def _resolve_cmd(args) -> None:
|
|
27
28
|
r = DEFAULT_INTERP_RESOLVER
|
|
28
29
|
s = InterpSpecifier.parse(args.version)
|
|
29
|
-
print(r.resolve(s).exe)
|
|
30
|
+
print(check_not_none(r.resolve(s)).exe)
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
def _build_parser() -> argparse.ArgumentParser:
|
|
@@ -116,6 +116,7 @@ class PyenvInstallOpts:
|
|
|
116
116
|
|
|
117
117
|
DEFAULT_PYENV_INSTALL_OPTS = PyenvInstallOpts(opts=['-s', '-v'])
|
|
118
118
|
DEBUG_PYENV_INSTALL_OPTS = PyenvInstallOpts(opts=['-g'])
|
|
119
|
+
THREADED_PYENV_INSTALL_OPTS = PyenvInstallOpts(conf_opts=['--disable-gil'])
|
|
119
120
|
|
|
120
121
|
|
|
121
122
|
#
|
|
@@ -176,19 +177,19 @@ class DarwinPyenvInstallOpts(PyenvInstallOptsProvider):
|
|
|
176
177
|
f"--with-tcltk-libs='-L{tcl_tk_prefix}/lib -ltcl{tcl_tk_ver} -ltk{tcl_tk_ver}'",
|
|
177
178
|
])
|
|
178
179
|
|
|
179
|
-
@cached_nullary
|
|
180
|
-
def brew_ssl_opts(self) -> PyenvInstallOpts:
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
180
|
+
# @cached_nullary
|
|
181
|
+
# def brew_ssl_opts(self) -> PyenvInstallOpts:
|
|
182
|
+
# pkg_config_path = subprocess_check_output_str('brew', '--prefix', 'openssl')
|
|
183
|
+
# if 'PKG_CONFIG_PATH' in os.environ:
|
|
184
|
+
# pkg_config_path += ':' + os.environ['PKG_CONFIG_PATH']
|
|
185
|
+
# return PyenvInstallOpts(env={'PKG_CONFIG_PATH': pkg_config_path})
|
|
185
186
|
|
|
186
187
|
def opts(self) -> PyenvInstallOpts:
|
|
187
188
|
return PyenvInstallOpts().merge(
|
|
188
189
|
self.framework_opts(),
|
|
189
190
|
self.brew_deps_opts(),
|
|
190
191
|
self.brew_tcl_opts(),
|
|
191
|
-
self.brew_ssl_opts(),
|
|
192
|
+
# self.brew_ssl_opts(),
|
|
192
193
|
)
|
|
193
194
|
|
|
194
195
|
|
|
@@ -202,27 +203,39 @@ PLATFORM_PYENV_INSTALL_OPTS: ta.Dict[str, PyenvInstallOptsProvider] = {
|
|
|
202
203
|
|
|
203
204
|
|
|
204
205
|
class PyenvVersionInstaller:
|
|
206
|
+
"""
|
|
207
|
+
Messy: can install freethreaded build with a 't' suffixed version str _or_ by THREADED_PYENV_INSTALL_OPTS - need
|
|
208
|
+
latter to build custom interp with ft, need former to use canned / blessed interps. Muh.
|
|
209
|
+
"""
|
|
205
210
|
|
|
206
211
|
def __init__(
|
|
207
212
|
self,
|
|
208
213
|
version: str,
|
|
209
214
|
opts: ta.Optional[PyenvInstallOpts] = None,
|
|
215
|
+
interp_opts: InterpOpts = InterpOpts(),
|
|
210
216
|
*,
|
|
211
|
-
|
|
217
|
+
no_default_opts: bool = False,
|
|
212
218
|
pyenv: Pyenv = Pyenv(),
|
|
213
219
|
) -> None:
|
|
214
220
|
super().__init__()
|
|
215
221
|
|
|
216
|
-
if
|
|
217
|
-
|
|
218
|
-
|
|
222
|
+
if no_default_opts:
|
|
223
|
+
if opts is None:
|
|
224
|
+
opts = PyenvInstallOpts()
|
|
225
|
+
else:
|
|
226
|
+
lst = [opts if opts is not None else DEFAULT_PYENV_INSTALL_OPTS]
|
|
227
|
+
if interp_opts.debug:
|
|
219
228
|
lst.append(DEBUG_PYENV_INSTALL_OPTS)
|
|
229
|
+
if interp_opts.threaded:
|
|
230
|
+
lst.append(THREADED_PYENV_INSTALL_OPTS)
|
|
220
231
|
lst.append(PLATFORM_PYENV_INSTALL_OPTS[sys.platform].opts())
|
|
221
232
|
opts = PyenvInstallOpts().merge(*lst)
|
|
222
233
|
|
|
223
234
|
self._version = version
|
|
224
235
|
self._opts = opts
|
|
225
|
-
self.
|
|
236
|
+
self._interp_opts = interp_opts
|
|
237
|
+
|
|
238
|
+
self._no_default_opts = no_default_opts
|
|
226
239
|
self._pyenv = pyenv
|
|
227
240
|
|
|
228
241
|
@property
|
|
@@ -235,7 +248,7 @@ class PyenvVersionInstaller:
|
|
|
235
248
|
|
|
236
249
|
@cached_nullary
|
|
237
250
|
def install_name(self) -> str:
|
|
238
|
-
return self._version + ('-debug' if self.
|
|
251
|
+
return self._version + ('-debug' if self._interp_opts.debug else '')
|
|
239
252
|
|
|
240
253
|
@cached_nullary
|
|
241
254
|
def install_dir(self) -> str:
|
|
@@ -243,7 +256,7 @@ class PyenvVersionInstaller:
|
|
|
243
256
|
|
|
244
257
|
@cached_nullary
|
|
245
258
|
def install(self) -> str:
|
|
246
|
-
env =
|
|
259
|
+
env = {**os.environ, **self._opts.env}
|
|
247
260
|
for k, l in [
|
|
248
261
|
('CFLAGS', self._opts.cflags),
|
|
249
262
|
('LDFLAGS', self._opts.ldflags),
|
|
@@ -254,7 +267,13 @@ class PyenvVersionInstaller:
|
|
|
254
267
|
v += ' ' + os.environ[k]
|
|
255
268
|
env[k] = v
|
|
256
269
|
|
|
257
|
-
subprocess_check_call(
|
|
270
|
+
subprocess_check_call(
|
|
271
|
+
self._pyenv.exe(),
|
|
272
|
+
'install',
|
|
273
|
+
*self._opts.opts,
|
|
274
|
+
self._version,
|
|
275
|
+
env=env,
|
|
276
|
+
)
|
|
258
277
|
|
|
259
278
|
exe = os.path.join(self.install_dir(), 'bin', 'python')
|
|
260
279
|
if not os.path.isfile(exe):
|
|
@@ -355,3 +374,18 @@ class PyenvInterpProvider(InterpProvider):
|
|
|
355
374
|
for d in [False, True]:
|
|
356
375
|
lst.append(dc.replace(iv, opts=dc.replace(iv.opts, debug=d)))
|
|
357
376
|
return lst
|
|
377
|
+
|
|
378
|
+
def install_version(self, version: InterpVersion) -> Interp:
|
|
379
|
+
inst_version = str(version.version)
|
|
380
|
+
inst_opts = version.opts
|
|
381
|
+
if inst_opts.threaded:
|
|
382
|
+
inst_version += 't'
|
|
383
|
+
inst_opts = dc.replace(inst_opts, threaded=False)
|
|
384
|
+
|
|
385
|
+
installer = PyenvVersionInstaller(
|
|
386
|
+
inst_version,
|
|
387
|
+
interp_opts=inst_opts,
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
exe = installer.install()
|
|
391
|
+
return Interp(exe, version)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ruff: noqa: UP006
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
|
2
2
|
import abc
|
|
3
3
|
import collections
|
|
4
4
|
import typing as ta
|
|
@@ -11,6 +11,7 @@ from .pyenv import PyenvInterpProvider
|
|
|
11
11
|
from .system import SystemInterpProvider
|
|
12
12
|
from .types import Interp
|
|
13
13
|
from .types import InterpSpecifier
|
|
14
|
+
from .types import InterpVersion
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
INTERP_PROVIDER_TYPES_BY_NAME: ta.Mapping[str, ta.Type[InterpProvider]] = {
|
|
@@ -26,17 +27,47 @@ class InterpResolver:
|
|
|
26
27
|
super().__init__()
|
|
27
28
|
self._providers: ta.Mapping[str, InterpProvider] = collections.OrderedDict(providers)
|
|
28
29
|
|
|
29
|
-
def
|
|
30
|
+
def _resolve_installed(self, spec: InterpSpecifier) -> ta.Optional[ta.Tuple[InterpProvider, InterpVersion]]:
|
|
30
31
|
lst = [
|
|
31
32
|
(i, si)
|
|
32
33
|
for i, p in enumerate(self._providers.values())
|
|
33
34
|
for si in p.get_installed_versions(spec)
|
|
34
35
|
if spec.contains(si)
|
|
35
36
|
]
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
|
|
38
|
+
slst = sorted(lst, key=lambda t: (-t[0], t[1]))
|
|
39
|
+
if not slst:
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
bi, bv = slst[-1]
|
|
38
43
|
bp = list(self._providers.values())[bi]
|
|
39
|
-
return bp
|
|
44
|
+
return (bp, bv)
|
|
45
|
+
|
|
46
|
+
def resolve(
|
|
47
|
+
self,
|
|
48
|
+
spec: InterpSpecifier,
|
|
49
|
+
*,
|
|
50
|
+
install: bool = False,
|
|
51
|
+
) -> ta.Optional[Interp]:
|
|
52
|
+
tup = self._resolve_installed(spec)
|
|
53
|
+
if tup is not None:
|
|
54
|
+
bp, bv = tup
|
|
55
|
+
return bp.get_installed_version(bv)
|
|
56
|
+
|
|
57
|
+
if not install:
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
tp = list(self._providers.values())[0] # noqa
|
|
61
|
+
|
|
62
|
+
sv = sorted(
|
|
63
|
+
[s for s in tp.get_installable_versions(spec) if s in spec],
|
|
64
|
+
key=lambda s: s.version,
|
|
65
|
+
)
|
|
66
|
+
if not sv:
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
bv = sv[-1]
|
|
70
|
+
return tp.install_version(bv)
|
|
40
71
|
|
|
41
72
|
def list(self, spec: InterpSpecifier) -> None:
|
|
42
73
|
print('installed:')
|
|
@@ -85,6 +85,9 @@ class InterpSpecifier:
|
|
|
85
85
|
def contains(self, iv: InterpVersion) -> bool:
|
|
86
86
|
return self.specifier.contains(iv.version) and self.opts == iv.opts
|
|
87
87
|
|
|
88
|
+
def __contains__(self, iv: InterpVersion) -> bool:
|
|
89
|
+
return self.contains(iv)
|
|
90
|
+
|
|
88
91
|
|
|
89
92
|
@dc.dataclass(frozen=True)
|
|
90
93
|
class Interp:
|
|
@@ -8,6 +8,7 @@ TODO:
|
|
|
8
8
|
- build / package / publish / version roll
|
|
9
9
|
- {pkg_name: [src_dirs]}, default excludes, generate MANIFST.in, ...
|
|
10
10
|
- env vars - PYTHONPATH
|
|
11
|
+
- optional uv backend
|
|
11
12
|
|
|
12
13
|
lookit:
|
|
13
14
|
- https://pdm-project.org/en/latest/
|
|
@@ -48,6 +49,7 @@ from .configs import PyprojectConfig
|
|
|
48
49
|
from .configs import PyprojectConfigPreparer
|
|
49
50
|
from .configs import VenvConfig
|
|
50
51
|
from .pkg import PyprojectPackageGenerator
|
|
52
|
+
from .reqs import RequirementsRewriter
|
|
51
53
|
|
|
52
54
|
|
|
53
55
|
##
|
|
@@ -121,7 +123,7 @@ class Venv:
|
|
|
121
123
|
@cached_nullary
|
|
122
124
|
def interp_exe(self) -> str:
|
|
123
125
|
i = InterpSpecifier.parse(check_not_none(self._cfg.interp))
|
|
124
|
-
return DEFAULT_INTERP_RESOLVER.resolve(i).exe
|
|
126
|
+
return check_not_none(DEFAULT_INTERP_RESOLVER.resolve(i, install=True)).exe
|
|
125
127
|
|
|
126
128
|
@cached_nullary
|
|
127
129
|
def exe(self) -> str:
|
|
@@ -141,6 +143,7 @@ class Venv:
|
|
|
141
143
|
subprocess_check_call(ie, '-m', 'venv', dn)
|
|
142
144
|
|
|
143
145
|
ve = self.exe()
|
|
146
|
+
uv = self._cfg.use_uv
|
|
144
147
|
|
|
145
148
|
subprocess_check_call(
|
|
146
149
|
ve,
|
|
@@ -149,14 +152,20 @@ class Venv:
|
|
|
149
152
|
'pip',
|
|
150
153
|
'setuptools',
|
|
151
154
|
'wheel',
|
|
155
|
+
*(['uv'] if uv else []),
|
|
152
156
|
)
|
|
153
157
|
|
|
154
158
|
if (sr := self._cfg.requires):
|
|
159
|
+
rr = RequirementsRewriter(self._name)
|
|
160
|
+
reqs = [rr.rewrite(req) for req in sr]
|
|
155
161
|
subprocess_check_call(
|
|
156
162
|
ve,
|
|
157
|
-
'-m',
|
|
158
|
-
'
|
|
159
|
-
|
|
163
|
+
'-m',
|
|
164
|
+
*(['uv'] if uv else []),
|
|
165
|
+
'pip',
|
|
166
|
+
'install',
|
|
167
|
+
*([] if uv else ['-v']),
|
|
168
|
+
*reqs,
|
|
160
169
|
)
|
|
161
170
|
|
|
162
171
|
return True
|
|
@@ -40,8 +40,8 @@ from omlish.lite.logs import log
|
|
|
40
40
|
|
|
41
41
|
from ..cexts.magic import CextMagic
|
|
42
42
|
from ..findmagic import find_magic
|
|
43
|
+
from ..revisions import GitRevisionAdder
|
|
43
44
|
from ..toml.writer import TomlWriter
|
|
44
|
-
from ..tools.revisions import GitRevisionAdder
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
#
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- embed pip._internal.req.parse_requirements, add additional env stuff? breaks compat with raw pip
|
|
4
|
+
"""
|
|
5
|
+
# ruff: noqa: UP007
|
|
6
|
+
import os.path
|
|
7
|
+
import tempfile
|
|
8
|
+
import typing as ta
|
|
9
|
+
|
|
10
|
+
from omlish.lite.cached import cached_nullary
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class RequirementsRewriter:
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
venv: ta.Optional[str] = None,
|
|
17
|
+
) -> None:
|
|
18
|
+
super().__init__()
|
|
19
|
+
self._venv = venv
|
|
20
|
+
|
|
21
|
+
@cached_nullary
|
|
22
|
+
def _tmp_dir(self) -> str:
|
|
23
|
+
return tempfile.mkdtemp('-omlish-reqs')
|
|
24
|
+
|
|
25
|
+
VENV_MAGIC = '# @omdev-venv'
|
|
26
|
+
|
|
27
|
+
def rewrite_file(self, in_file: str) -> str:
|
|
28
|
+
with open(in_file) as f:
|
|
29
|
+
src = f.read()
|
|
30
|
+
|
|
31
|
+
in_lines = src.splitlines(keepends=True)
|
|
32
|
+
out_lines = []
|
|
33
|
+
|
|
34
|
+
for l in in_lines:
|
|
35
|
+
if self.VENV_MAGIC in l:
|
|
36
|
+
lp, _, rp = l.partition(self.VENV_MAGIC)
|
|
37
|
+
rp = rp.partition('#')[0]
|
|
38
|
+
omit = False
|
|
39
|
+
for v in rp.split():
|
|
40
|
+
if v[0] == '!':
|
|
41
|
+
if self._venv is not None and self._venv == v[1:]:
|
|
42
|
+
omit = True
|
|
43
|
+
break
|
|
44
|
+
else:
|
|
45
|
+
raise NotImplementedError
|
|
46
|
+
|
|
47
|
+
if omit:
|
|
48
|
+
out_lines.append('# OMITTED: ' + l)
|
|
49
|
+
continue
|
|
50
|
+
|
|
51
|
+
out_req = self.rewrite(l.rstrip('\n'), for_file=True)
|
|
52
|
+
out_lines.append(out_req + '\n')
|
|
53
|
+
|
|
54
|
+
out_file = os.path.join(self._tmp_dir(), os.path.basename(in_file))
|
|
55
|
+
if os.path.exists(out_file):
|
|
56
|
+
raise Exception(f'file exists: {out_file}')
|
|
57
|
+
|
|
58
|
+
with open(out_file, 'w') as f:
|
|
59
|
+
f.write(''.join(out_lines))
|
|
60
|
+
return out_file
|
|
61
|
+
|
|
62
|
+
def rewrite(self, in_req: str, *, for_file: bool = False) -> str:
|
|
63
|
+
if in_req.strip().startswith('-r'):
|
|
64
|
+
l = in_req.strip()
|
|
65
|
+
lp, _, rp = l.partition(' ')
|
|
66
|
+
if lp == '-r':
|
|
67
|
+
inc_in_file, _, rest = rp.partition(' ')
|
|
68
|
+
else:
|
|
69
|
+
inc_in_file, rest = lp[2:], rp
|
|
70
|
+
|
|
71
|
+
inc_out_file = self.rewrite_file(inc_in_file)
|
|
72
|
+
if for_file:
|
|
73
|
+
return ' '.join(['-r ', inc_out_file, rest])
|
|
74
|
+
else:
|
|
75
|
+
return '-r' + inc_out_file
|
|
76
|
+
|
|
77
|
+
else:
|
|
78
|
+
return in_req
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Depless, self-contained scripts with no reason to be imported from any other module."""
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# @omlish-lite
|
|
3
|
+
# @omlish-script
|
|
4
|
+
import argparse
|
|
5
|
+
import re
|
|
6
|
+
import string
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
_VERSION_PAT = re.compile(r"__version__ = '(?P<version>[^\']+)'")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _main() -> None:
|
|
13
|
+
parser = argparse.ArgumentParser()
|
|
14
|
+
|
|
15
|
+
parser.add_argument('file')
|
|
16
|
+
parser.add_argument('-w', '--write', action='store_true')
|
|
17
|
+
args = parser.parse_args()
|
|
18
|
+
|
|
19
|
+
with open(args.file) as f:
|
|
20
|
+
src = f.read()
|
|
21
|
+
|
|
22
|
+
lines = src.splitlines(keepends=True)
|
|
23
|
+
for i, l in enumerate(lines):
|
|
24
|
+
if (m := _VERSION_PAT.fullmatch(l.strip())) is None:
|
|
25
|
+
continue
|
|
26
|
+
parts = m.groupdict()['version'].split('.')
|
|
27
|
+
rp = parts[-1]
|
|
28
|
+
ni = [i for i in range(len(rp)) if rp[i] not in string.digits][-1] + 1
|
|
29
|
+
tp, np = rp[:ni], rp[ni:]
|
|
30
|
+
n = int(np)
|
|
31
|
+
nv = '.'.join([*parts[:-1], tp + str(n + 1)])
|
|
32
|
+
lines[i] = f"__version__ = '{nv}'\n"
|
|
33
|
+
new_src = ''.join(lines)
|
|
34
|
+
|
|
35
|
+
if args.write:
|
|
36
|
+
with open(args.file, 'w') as f:
|
|
37
|
+
f.write(new_src)
|
|
38
|
+
else:
|
|
39
|
+
print(new_src)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
if __name__ == '__main__':
|
|
43
|
+
_main()
|