omdev 0.0.0.dev7__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/__about__.py +35 -0
- omdev/__init__.py +0 -0
- omdev/amalg/__init__.py +0 -0
- omdev/amalg/__main__.py +4 -0
- omdev/amalg/amalg.py +513 -0
- omdev/classdot.py +61 -0
- omdev/cmake.py +164 -0
- omdev/exts/__init__.py +0 -0
- omdev/exts/_distutils/__init__.py +10 -0
- omdev/exts/_distutils/build_ext.py +367 -0
- omdev/exts/_distutils/compilers/__init__.py +3 -0
- omdev/exts/_distutils/compilers/ccompiler.py +1032 -0
- omdev/exts/_distutils/compilers/options.py +80 -0
- omdev/exts/_distutils/compilers/unixccompiler.py +385 -0
- omdev/exts/_distutils/dir_util.py +76 -0
- omdev/exts/_distutils/errors.py +62 -0
- omdev/exts/_distutils/extension.py +107 -0
- omdev/exts/_distutils/file_util.py +216 -0
- omdev/exts/_distutils/modified.py +47 -0
- omdev/exts/_distutils/spawn.py +103 -0
- omdev/exts/_distutils/sysconfig.py +349 -0
- omdev/exts/_distutils/util.py +201 -0
- omdev/exts/_distutils/version.py +308 -0
- omdev/exts/build.py +43 -0
- omdev/exts/cmake.py +195 -0
- omdev/exts/importhook.py +88 -0
- omdev/exts/scan.py +74 -0
- omdev/interp/__init__.py +1 -0
- omdev/interp/__main__.py +4 -0
- omdev/interp/cli.py +63 -0
- omdev/interp/inspect.py +105 -0
- omdev/interp/providers.py +67 -0
- omdev/interp/pyenv.py +353 -0
- omdev/interp/resolvers.py +76 -0
- omdev/interp/standalone.py +187 -0
- omdev/interp/system.py +125 -0
- omdev/interp/types.py +92 -0
- omdev/mypy/__init__.py +0 -0
- omdev/mypy/debug.py +86 -0
- omdev/pyproject/__init__.py +1 -0
- omdev/pyproject/__main__.py +4 -0
- omdev/pyproject/cli.py +319 -0
- omdev/pyproject/configs.py +97 -0
- omdev/pyproject/ext.py +107 -0
- omdev/pyproject/pkg.py +196 -0
- omdev/scripts/__init__.py +0 -0
- omdev/scripts/execrss.py +19 -0
- omdev/scripts/findimports.py +62 -0
- omdev/scripts/findmagic.py +70 -0
- omdev/scripts/interp.py +2118 -0
- omdev/scripts/pyproject.py +3584 -0
- omdev/scripts/traceimport.py +502 -0
- omdev/tokens.py +42 -0
- omdev/toml/__init__.py +1 -0
- omdev/toml/parser.py +823 -0
- omdev/toml/writer.py +104 -0
- omdev/tools/__init__.py +0 -0
- omdev/tools/dockertools.py +81 -0
- omdev/tools/sqlrepl.py +193 -0
- omdev/versioning/__init__.py +1 -0
- omdev/versioning/specifiers.py +531 -0
- omdev/versioning/versions.py +416 -0
- omdev-0.0.0.dev7.dist-info/LICENSE +21 -0
- omdev-0.0.0.dev7.dist-info/METADATA +24 -0
- omdev-0.0.0.dev7.dist-info/RECORD +67 -0
- omdev-0.0.0.dev7.dist-info/WHEEL +5 -0
- omdev-0.0.0.dev7.dist-info/top_level.txt +1 -0
omdev/pyproject/pkg.py
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- ext scanning
|
|
4
|
+
- __revision__
|
|
5
|
+
- entry_points
|
|
6
|
+
|
|
7
|
+
https://setuptools.pypa.io/en/latest/references/keywords.html
|
|
8
|
+
https://packaging.python.org/en/latest/specifications/pyproject-toml
|
|
9
|
+
|
|
10
|
+
How to build a C extension in keeping with PEP 517, i.e. with pyproject.toml instead of setup.py?
|
|
11
|
+
https://stackoverflow.com/a/66479252
|
|
12
|
+
|
|
13
|
+
https://github.com/pypa/sampleproject/blob/db5806e0a3204034c51b1c00dde7d5eb3fa2532e/setup.py
|
|
14
|
+
|
|
15
|
+
https://pip.pypa.io/en/stable/cli/pip_install/#vcs-support
|
|
16
|
+
vcs+protocol://repo_url/#egg=pkg&subdirectory=pkg_dir
|
|
17
|
+
'git+https://github.com/wrmsr/omlish@master#subdirectory=.pip/omlish'
|
|
18
|
+
"""
|
|
19
|
+
# ruff: noqa: UP006 UP007
|
|
20
|
+
import dataclasses as dc
|
|
21
|
+
import importlib
|
|
22
|
+
import os.path
|
|
23
|
+
import shutil
|
|
24
|
+
import subprocess
|
|
25
|
+
import sys
|
|
26
|
+
import types
|
|
27
|
+
import typing as ta
|
|
28
|
+
|
|
29
|
+
from omlish.lite.cached import cached_nullary
|
|
30
|
+
|
|
31
|
+
from ..toml.writer import TomlWriter
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class PyprojectPackageGenerator:
|
|
35
|
+
def __init__(
|
|
36
|
+
self,
|
|
37
|
+
dir_name: str,
|
|
38
|
+
build_root: str,
|
|
39
|
+
) -> None:
|
|
40
|
+
super().__init__()
|
|
41
|
+
self._dir_name = dir_name
|
|
42
|
+
self._build_root = build_root
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
|
|
46
|
+
@cached_nullary
|
|
47
|
+
def about(self) -> types.ModuleType:
|
|
48
|
+
return importlib.import_module(f'{self._dir_name}.__about__')
|
|
49
|
+
|
|
50
|
+
@cached_nullary
|
|
51
|
+
def project_cls(self) -> type:
|
|
52
|
+
return self.about().Project
|
|
53
|
+
|
|
54
|
+
@cached_nullary
|
|
55
|
+
def setuptools_cls(self) -> type:
|
|
56
|
+
return self.about().Setuptools
|
|
57
|
+
|
|
58
|
+
#
|
|
59
|
+
|
|
60
|
+
@cached_nullary
|
|
61
|
+
def _build_dir(self) -> str:
|
|
62
|
+
build_dir: str = os.path.join(self._build_root, self._dir_name)
|
|
63
|
+
if os.path.isdir(build_dir):
|
|
64
|
+
shutil.rmtree(build_dir)
|
|
65
|
+
os.makedirs(build_dir)
|
|
66
|
+
return build_dir
|
|
67
|
+
|
|
68
|
+
#
|
|
69
|
+
|
|
70
|
+
def _write_git_ignore(self) -> None:
|
|
71
|
+
git_ignore = [
|
|
72
|
+
'/*.egg-info/',
|
|
73
|
+
'/dist',
|
|
74
|
+
]
|
|
75
|
+
with open(os.path.join(self._build_dir(), '.gitignore'), 'w') as f:
|
|
76
|
+
f.write('\n'.join(git_ignore))
|
|
77
|
+
|
|
78
|
+
#
|
|
79
|
+
|
|
80
|
+
def _symlink_source_dir(self) -> None:
|
|
81
|
+
os.symlink(
|
|
82
|
+
os.path.relpath(self._dir_name, self._build_dir()),
|
|
83
|
+
os.path.join(self._build_dir(), self._dir_name),
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
#
|
|
87
|
+
|
|
88
|
+
@dc.dataclass(frozen=True)
|
|
89
|
+
class FileContents:
|
|
90
|
+
pyproject_dct: ta.Mapping[str, ta.Any]
|
|
91
|
+
manifest_in: ta.Optional[ta.Sequence[str]]
|
|
92
|
+
|
|
93
|
+
@staticmethod
|
|
94
|
+
def _build_cls_dct(cls: type) -> ta.Dict[str, ta.Any]: # noqa
|
|
95
|
+
dct = {}
|
|
96
|
+
for b in reversed(cls.__mro__):
|
|
97
|
+
for k, v in b.__dict__.items():
|
|
98
|
+
if k.startswith('_'):
|
|
99
|
+
continue
|
|
100
|
+
dct[k] = v
|
|
101
|
+
return dct
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def _move_dict_key(
|
|
105
|
+
sd: ta.Dict[str, ta.Any],
|
|
106
|
+
sk: str,
|
|
107
|
+
dd: ta.Dict[str, ta.Any],
|
|
108
|
+
dk: str,
|
|
109
|
+
) -> None:
|
|
110
|
+
if sk in sd:
|
|
111
|
+
dd[dk] = sd.pop(sk)
|
|
112
|
+
|
|
113
|
+
@cached_nullary
|
|
114
|
+
def file_contents(self) -> FileContents:
|
|
115
|
+
pyp_dct = {}
|
|
116
|
+
|
|
117
|
+
pyp_dct['build-system'] = {
|
|
118
|
+
'requires': ['setuptools'],
|
|
119
|
+
'build-backend': 'setuptools.build_meta',
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
prj = self._build_cls_dct(self.project_cls())
|
|
123
|
+
pyp_dct['project'] = prj
|
|
124
|
+
self._move_dict_key(prj, 'optional_dependencies', pyp_dct, 'project.optional-dependencies')
|
|
125
|
+
|
|
126
|
+
st = self._build_cls_dct(self.setuptools_cls())
|
|
127
|
+
pyp_dct['tool.setuptools'] = st
|
|
128
|
+
self._move_dict_key(st, 'find_packages', pyp_dct, 'tool.setuptools.packages.find')
|
|
129
|
+
|
|
130
|
+
mani_in = st.pop('manifest_in', None)
|
|
131
|
+
|
|
132
|
+
return self.FileContents(
|
|
133
|
+
pyp_dct,
|
|
134
|
+
mani_in,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
def _write_file_contents(self) -> None:
|
|
138
|
+
fc = self.file_contents()
|
|
139
|
+
|
|
140
|
+
with open(os.path.join(self._build_dir(), 'pyproject.toml'), 'w') as f:
|
|
141
|
+
TomlWriter(f).write_root(fc.pyproject_dct)
|
|
142
|
+
|
|
143
|
+
if fc.manifest_in:
|
|
144
|
+
with open(os.path.join(self._build_dir(), 'MANIFEST.in'), 'w') as f:
|
|
145
|
+
f.write('\n'.join(fc.manifest_in)) # noqa
|
|
146
|
+
|
|
147
|
+
#
|
|
148
|
+
|
|
149
|
+
_STANDARD_FILES: ta.Sequence[str] = [
|
|
150
|
+
'LICENSE',
|
|
151
|
+
'README.rst',
|
|
152
|
+
]
|
|
153
|
+
|
|
154
|
+
def _symlink_standard_files(self) -> None:
|
|
155
|
+
for fn in self._STANDARD_FILES:
|
|
156
|
+
if os.path.exists(fn):
|
|
157
|
+
os.symlink(os.path.relpath(fn, self._build_dir()), os.path.join(self._build_dir(), fn))
|
|
158
|
+
|
|
159
|
+
#
|
|
160
|
+
|
|
161
|
+
def _run_build(
|
|
162
|
+
self,
|
|
163
|
+
build_output_dir: ta.Optional[str] = None,
|
|
164
|
+
) -> None:
|
|
165
|
+
subprocess.check_call(
|
|
166
|
+
[
|
|
167
|
+
sys.executable,
|
|
168
|
+
'-m',
|
|
169
|
+
'build',
|
|
170
|
+
],
|
|
171
|
+
cwd=self._build_dir(),
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
if build_output_dir is not None:
|
|
175
|
+
dist_dir = os.path.join(self._build_dir(), 'dist')
|
|
176
|
+
for fn in os.listdir(dist_dir):
|
|
177
|
+
shutil.copyfile(os.path.join(dist_dir, fn), os.path.join(build_output_dir, fn))
|
|
178
|
+
|
|
179
|
+
#
|
|
180
|
+
|
|
181
|
+
def gen(
|
|
182
|
+
self,
|
|
183
|
+
*,
|
|
184
|
+
run_build: bool = False,
|
|
185
|
+
build_output_dir: ta.Optional[str] = None,
|
|
186
|
+
) -> str:
|
|
187
|
+
self._build_dir()
|
|
188
|
+
self._write_git_ignore()
|
|
189
|
+
self._symlink_source_dir()
|
|
190
|
+
self._write_file_contents()
|
|
191
|
+
self._symlink_standard_files()
|
|
192
|
+
|
|
193
|
+
if run_build:
|
|
194
|
+
self._run_build(build_output_dir)
|
|
195
|
+
|
|
196
|
+
return self._build_dir()
|
|
File without changes
|
omdev/scripts/execrss.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import resource
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def _get_rss() -> int:
|
|
7
|
+
return resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _main() -> None:
|
|
11
|
+
[src] = sys.argv[1:]
|
|
12
|
+
start = _get_rss()
|
|
13
|
+
exec(src)
|
|
14
|
+
end = _get_rss()
|
|
15
|
+
print(end - start)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
if __name__ == '__main__':
|
|
19
|
+
_main()
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
TODO:
|
|
4
|
+
- multiple commands:
|
|
5
|
+
- dumb cmp (a = set(sys.modules); import ...; print(set(sys.modules) - a)
|
|
6
|
+
"""
|
|
7
|
+
import ast
|
|
8
|
+
import importlib.machinery
|
|
9
|
+
import importlib.util
|
|
10
|
+
import os.path
|
|
11
|
+
import sys
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
_BUILTIN_MODULE_NAMES = frozenset([*sys.builtin_module_names, *sys.stdlib_module_names])
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _main() -> None:
|
|
18
|
+
def handle(fp: str) -> None:
|
|
19
|
+
def rec(n):
|
|
20
|
+
nodes.append(n)
|
|
21
|
+
for c in ast.iter_child_nodes(n):
|
|
22
|
+
rec(c)
|
|
23
|
+
# if not os.path.isfile(os.path.join(os.path.dirname(fp), '__init__.py')):
|
|
24
|
+
# return
|
|
25
|
+
with open(fp, 'r') as f:
|
|
26
|
+
buf = f.read()
|
|
27
|
+
nodes: list[ast.AST] = []
|
|
28
|
+
rec(ast.parse(buf))
|
|
29
|
+
imps.update(na.name for i in nodes if isinstance(i, ast.Import) for na in i.names)
|
|
30
|
+
imps.update(i.module for i in nodes if isinstance(i, ast.ImportFrom) if i.module and not i.level)
|
|
31
|
+
|
|
32
|
+
imps: set[str] = set()
|
|
33
|
+
for rootp in sys.argv[1:]:
|
|
34
|
+
if os.path.isfile(rootp):
|
|
35
|
+
if rootp.endswith('.py'):
|
|
36
|
+
handle(os.path.join(os.path.dirname(rootp), os.path.basename(rootp)))
|
|
37
|
+
else:
|
|
38
|
+
for dp, dns, fns in os.walk(os.path.expanduser(rootp)): # noqa
|
|
39
|
+
for fn in fns:
|
|
40
|
+
if fn.endswith('.py'):
|
|
41
|
+
handle(os.path.join(dp, fn))
|
|
42
|
+
|
|
43
|
+
def whichmod(i: str) -> str:
|
|
44
|
+
try:
|
|
45
|
+
l = importlib.util.find_spec(i)
|
|
46
|
+
except (ImportError, ValueError):
|
|
47
|
+
return 'bad'
|
|
48
|
+
if not isinstance(l, importlib.machinery.ModuleSpec) or not l.origin:
|
|
49
|
+
return 'bad'
|
|
50
|
+
# if l.origin.startswith(sys.base_prefix) or l.origin == 'frozen':
|
|
51
|
+
# return 'builtin'
|
|
52
|
+
if i in _BUILTIN_MODULE_NAMES:
|
|
53
|
+
return 'builtin'
|
|
54
|
+
return 'dep'
|
|
55
|
+
|
|
56
|
+
eimps = {n for n in imps for n in [n.split('.')[0]] if n not in sys.builtin_module_names}
|
|
57
|
+
deps = {i for i in eimps if whichmod(i) != 'builtin'}
|
|
58
|
+
print(chr(10).join(sorted(deps)))
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
if __name__ == '__main__':
|
|
62
|
+
_main()
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import os.path
|
|
3
|
+
import re
|
|
4
|
+
import typing as ta
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def find_magic(
|
|
8
|
+
roots: ta.Sequence[str],
|
|
9
|
+
magics: ta.Sequence[str],
|
|
10
|
+
exts: ta.Sequence[str],
|
|
11
|
+
*,
|
|
12
|
+
py: bool = False,
|
|
13
|
+
) -> ta.Iterator[str]:
|
|
14
|
+
if not magics:
|
|
15
|
+
raise Exception('Must specify magics')
|
|
16
|
+
if not exts:
|
|
17
|
+
raise Exception('Must specify extensions')
|
|
18
|
+
|
|
19
|
+
pats = [
|
|
20
|
+
re.compile('^' + re.escape(m) + r'($|(\s.*))')
|
|
21
|
+
for m in magics
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
for root in roots:
|
|
25
|
+
for dp, dns, fns in os.walk(root): # noqa
|
|
26
|
+
for fn in fns:
|
|
27
|
+
if not any(fn.endswith(f'.{x}') for x in exts):
|
|
28
|
+
continue
|
|
29
|
+
|
|
30
|
+
fp = os.path.join(dp, fn)
|
|
31
|
+
with open(fp) as f:
|
|
32
|
+
src = f.read()
|
|
33
|
+
|
|
34
|
+
if not any(
|
|
35
|
+
any(pat.fullmatch(l) for pat in pats)
|
|
36
|
+
for l in src.splitlines()
|
|
37
|
+
):
|
|
38
|
+
continue
|
|
39
|
+
|
|
40
|
+
if py:
|
|
41
|
+
if fn == '__init__.py':
|
|
42
|
+
out = dp.replace(os.sep, '.')
|
|
43
|
+
elif fn.endswith('.py'):
|
|
44
|
+
out = fp[:-3].replace(os.sep, '.')
|
|
45
|
+
else:
|
|
46
|
+
out = fp
|
|
47
|
+
else:
|
|
48
|
+
out = fp
|
|
49
|
+
yield out
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _main(argv=None) -> None:
|
|
53
|
+
arg_parser = argparse.ArgumentParser()
|
|
54
|
+
arg_parser.add_argument('--ext', '-x', dest='exts', action='append')
|
|
55
|
+
arg_parser.add_argument('--magic', '-m', dest='magics', action='append')
|
|
56
|
+
arg_parser.add_argument('--py', action='store_true')
|
|
57
|
+
arg_parser.add_argument('roots', nargs='*')
|
|
58
|
+
args = arg_parser.parse_args(argv)
|
|
59
|
+
|
|
60
|
+
for out in find_magic(
|
|
61
|
+
roots=args.roots,
|
|
62
|
+
magics=args.magics,
|
|
63
|
+
exts=args.exts,
|
|
64
|
+
py=args.py,
|
|
65
|
+
):
|
|
66
|
+
print(out)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
if __name__ == '__main__':
|
|
70
|
+
_main()
|