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.
Files changed (67) hide show
  1. omdev/__about__.py +35 -0
  2. omdev/__init__.py +0 -0
  3. omdev/amalg/__init__.py +0 -0
  4. omdev/amalg/__main__.py +4 -0
  5. omdev/amalg/amalg.py +513 -0
  6. omdev/classdot.py +61 -0
  7. omdev/cmake.py +164 -0
  8. omdev/exts/__init__.py +0 -0
  9. omdev/exts/_distutils/__init__.py +10 -0
  10. omdev/exts/_distutils/build_ext.py +367 -0
  11. omdev/exts/_distutils/compilers/__init__.py +3 -0
  12. omdev/exts/_distutils/compilers/ccompiler.py +1032 -0
  13. omdev/exts/_distutils/compilers/options.py +80 -0
  14. omdev/exts/_distutils/compilers/unixccompiler.py +385 -0
  15. omdev/exts/_distutils/dir_util.py +76 -0
  16. omdev/exts/_distutils/errors.py +62 -0
  17. omdev/exts/_distutils/extension.py +107 -0
  18. omdev/exts/_distutils/file_util.py +216 -0
  19. omdev/exts/_distutils/modified.py +47 -0
  20. omdev/exts/_distutils/spawn.py +103 -0
  21. omdev/exts/_distutils/sysconfig.py +349 -0
  22. omdev/exts/_distutils/util.py +201 -0
  23. omdev/exts/_distutils/version.py +308 -0
  24. omdev/exts/build.py +43 -0
  25. omdev/exts/cmake.py +195 -0
  26. omdev/exts/importhook.py +88 -0
  27. omdev/exts/scan.py +74 -0
  28. omdev/interp/__init__.py +1 -0
  29. omdev/interp/__main__.py +4 -0
  30. omdev/interp/cli.py +63 -0
  31. omdev/interp/inspect.py +105 -0
  32. omdev/interp/providers.py +67 -0
  33. omdev/interp/pyenv.py +353 -0
  34. omdev/interp/resolvers.py +76 -0
  35. omdev/interp/standalone.py +187 -0
  36. omdev/interp/system.py +125 -0
  37. omdev/interp/types.py +92 -0
  38. omdev/mypy/__init__.py +0 -0
  39. omdev/mypy/debug.py +86 -0
  40. omdev/pyproject/__init__.py +1 -0
  41. omdev/pyproject/__main__.py +4 -0
  42. omdev/pyproject/cli.py +319 -0
  43. omdev/pyproject/configs.py +97 -0
  44. omdev/pyproject/ext.py +107 -0
  45. omdev/pyproject/pkg.py +196 -0
  46. omdev/scripts/__init__.py +0 -0
  47. omdev/scripts/execrss.py +19 -0
  48. omdev/scripts/findimports.py +62 -0
  49. omdev/scripts/findmagic.py +70 -0
  50. omdev/scripts/interp.py +2118 -0
  51. omdev/scripts/pyproject.py +3584 -0
  52. omdev/scripts/traceimport.py +502 -0
  53. omdev/tokens.py +42 -0
  54. omdev/toml/__init__.py +1 -0
  55. omdev/toml/parser.py +823 -0
  56. omdev/toml/writer.py +104 -0
  57. omdev/tools/__init__.py +0 -0
  58. omdev/tools/dockertools.py +81 -0
  59. omdev/tools/sqlrepl.py +193 -0
  60. omdev/versioning/__init__.py +1 -0
  61. omdev/versioning/specifiers.py +531 -0
  62. omdev/versioning/versions.py +416 -0
  63. omdev-0.0.0.dev7.dist-info/LICENSE +21 -0
  64. omdev-0.0.0.dev7.dist-info/METADATA +24 -0
  65. omdev-0.0.0.dev7.dist-info/RECORD +67 -0
  66. omdev-0.0.0.dev7.dist-info/WHEEL +5 -0
  67. 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
@@ -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()