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/toml/writer.py ADDED
@@ -0,0 +1,104 @@
1
+ import string
2
+ import typing as ta
3
+
4
+
5
+ class TomlWriter:
6
+ def __init__(self, out: ta.TextIO) -> None:
7
+ super().__init__()
8
+ self._out = out
9
+
10
+ self._indent = 0
11
+ self._wrote_indent = False
12
+
13
+ #
14
+
15
+ def _w(self, s: str) -> None:
16
+ if not self._wrote_indent:
17
+ self._out.write(' ' * self._indent)
18
+ self._wrote_indent = True
19
+ self._out.write(s)
20
+
21
+ def _nl(self) -> None:
22
+ self._out.write('\n')
23
+ self._wrote_indent = False
24
+
25
+ def _needs_quote(self, s: str) -> bool:
26
+ return (
27
+ not s or
28
+ any(c in s for c in '\'"\n') or
29
+ s[0] not in string.ascii_letters
30
+ )
31
+
32
+ def _maybe_quote(self, s: str) -> str:
33
+ if self._needs_quote(s):
34
+ return repr(s)
35
+ else:
36
+ return s
37
+
38
+ #
39
+
40
+ def write_root(self, obj: ta.Mapping) -> None:
41
+ for i, (k, v) in enumerate(obj.items()):
42
+ if i:
43
+ self._nl()
44
+ self._w('[')
45
+ self._w(self._maybe_quote(k))
46
+ self._w(']')
47
+ self._nl()
48
+ self.write_table_contents(v)
49
+
50
+ def write_table_contents(self, obj: ta.Mapping) -> None:
51
+ for k, v in obj.items():
52
+ self.write_key(k)
53
+ self._w(' = ')
54
+ self.write_value(v)
55
+ self._nl()
56
+
57
+ def write_array(self, obj: ta.Sequence) -> None:
58
+ self._w('[')
59
+ self._nl()
60
+ self._indent += 1
61
+ for e in obj:
62
+ self.write_value(e)
63
+ self._w(',')
64
+ self._nl()
65
+ self._indent -= 1
66
+ self._w(']')
67
+
68
+ def write_inline_table(self, obj: ta.Mapping) -> None:
69
+ self._w('{')
70
+ for i, (k, v) in enumerate(obj.items()):
71
+ if i:
72
+ self._w(', ')
73
+ self.write_key(k)
74
+ self._w(' = ')
75
+ self.write_value(v)
76
+ self._w('}')
77
+
78
+ def write_inline_array(self, obj: ta.Sequence) -> None:
79
+ self._w('[')
80
+ for i, e in enumerate(obj):
81
+ if i:
82
+ self._w(', ')
83
+ self.write_value(e)
84
+ self._w(']')
85
+
86
+ def write_key(self, obj: ta.Any) -> None:
87
+ if isinstance(obj, str):
88
+ self._w(self._maybe_quote(obj.replace('_', '-')))
89
+ elif isinstance(obj, int):
90
+ self._w(repr(str(obj)))
91
+ else:
92
+ raise TypeError(obj)
93
+
94
+ def write_value(self, obj: ta.Any) -> None:
95
+ if isinstance(obj, bool):
96
+ self._w(str(obj).lower())
97
+ elif isinstance(obj, (str, int, float)):
98
+ self._w(repr(obj))
99
+ elif isinstance(obj, ta.Mapping):
100
+ self.write_inline_table(obj)
101
+ elif isinstance(obj, ta.Sequence):
102
+ self.write_array(obj)
103
+ else:
104
+ raise TypeError(obj)
File without changes
@@ -0,0 +1,81 @@
1
+ import os
2
+ import shutil
3
+ import subprocess
4
+
5
+ from omlish import argparse as ap
6
+ from omlish import check
7
+ from omlish import lang
8
+ from omlish import logs
9
+
10
+
11
+ @lang.cached_function
12
+ def docker_exe() -> str:
13
+ return check.not_none(shutil.which('docker'))
14
+
15
+
16
+ @lang.cached_function
17
+ def get_local_platform() -> str:
18
+ return subprocess.check_output([
19
+ docker_exe(),
20
+ 'system',
21
+ 'info',
22
+ '--format',
23
+ '{{.OSType}}/{{.Architecture}}',
24
+ ]).decode().strip()
25
+
26
+
27
+ class Cli(ap.Cli):
28
+ @ap.command(
29
+ ap.arg('args', nargs='*'),
30
+ )
31
+ def ns1(self) -> None:
32
+ """
33
+ - https://gist.github.com/BretFisher/5e1a0c7bcca4c735e716abf62afad389
34
+ - https://github.com/justincormack/nsenter1/blob/8d3ba504b2c14d73c70cf34f1ec6943c093f1b02/nsenter1.c
35
+
36
+ alt:
37
+ - nc -U ~/Library/Containers/com.docker.docker/Data/debug-shell.sock
38
+ """
39
+ os.execl(
40
+ exe := docker_exe(),
41
+ exe,
42
+ 'run',
43
+ '--platform', get_local_platform(),
44
+ '--privileged',
45
+ '--pid=host',
46
+ '-it', 'debian',
47
+ 'nsenter',
48
+ '-t', '1',
49
+ '-m', # mount
50
+ '-u', # uts
51
+ '-i', # ipc
52
+ '-n', # net
53
+ '-p', # pid
54
+ '-C', # cgroup
55
+ # '-U', # user
56
+ '-T', # time
57
+ *self.args.args,
58
+ )
59
+
60
+ @ap.command(
61
+ ap.arg('--amd64', action='store_true'),
62
+ )
63
+ def enable_ptrace(self) -> None:
64
+ """
65
+ - https://github.com/docker/for-mac/issues/5191
66
+ - https://forums.docker.com/t/sys-ptrace-capability-for-linux-amd64/138482/4
67
+ """
68
+ os.execl(
69
+ exe := docker_exe(),
70
+ exe,
71
+ 'run',
72
+ *(('--platform', 'linux/x86_64') if self.args.amd64 else ()),
73
+ '--privileged',
74
+ '-it', 'debian',
75
+ 'sh', '-c', 'echo 0 > /proc/sys/kernel/yama/ptrace_scope',
76
+ )
77
+
78
+
79
+ if __name__ == '__main__':
80
+ logs.configure_standard_logging('INFO')
81
+ Cli()()
omdev/tools/sqlrepl.py ADDED
@@ -0,0 +1,193 @@
1
+ import dataclasses as dc
2
+ import os.path
3
+ import shutil
4
+ import sys
5
+ import typing as ta
6
+ import urllib.parse
7
+ import warnings
8
+
9
+ import yaml
10
+
11
+ from omlish import argparse as ap
12
+ from omlish import check
13
+ from omlish import lang
14
+ from omlish import logs
15
+
16
+
17
+ @dc.dataclass(frozen=True)
18
+ class ServerSpec:
19
+ host: str
20
+ port: int | None = None
21
+ username: str | None = None
22
+ password: str | None = None
23
+ db: str | None = None
24
+
25
+ @classmethod
26
+ def from_url(cls, url: str) -> 'ServerSpec':
27
+ parsed = urllib.parse.urlparse(url)
28
+ if not parsed.hostname:
29
+ raise NameError(parsed.hostname)
30
+ if parsed.path:
31
+ if not parsed.path.startswith('/'):
32
+ raise NameError(parsed.path)
33
+ db = parsed.path[1:]
34
+ else:
35
+ db = None
36
+ return ServerSpec(
37
+ host=parsed.hostname,
38
+ port=parsed.port or None,
39
+ username=parsed.username or None,
40
+ password=parsed.password or None,
41
+ db=db,
42
+ )
43
+
44
+
45
+ def spec_from_mysql_docker_compose(svc: ta.Mapping[str, ta.Any]) -> ServerSpec:
46
+ env = svc['environment']
47
+ return ServerSpec(
48
+ host='localhost',
49
+ port=int(svc['ports'][0].split(':')[0]),
50
+ username=env.get('MYSQL_USER') or None,
51
+ password=env.get('MYSQL_PASSWORD') or None,
52
+ )
53
+
54
+
55
+ def spec_from_postgres_docker_compose(svc: ta.Mapping[str, ta.Any]) -> ServerSpec:
56
+ env = svc['environment']
57
+ return ServerSpec(
58
+ host='localhost',
59
+ port=int(svc['ports'][0].split(':')[0]),
60
+ username=env.get('POSTGRES_USER') or None,
61
+ password=env.get('POSTGRES_PASSWORD') or None,
62
+ )
63
+
64
+
65
+ def spec_from_cfg(cfg: ta.Mapping[str, ta.Any], prefix: str) -> ServerSpec:
66
+ return ServerSpec(
67
+ host=cfg[prefix + '_host'],
68
+ port=cfg.get(prefix + '_port'),
69
+ username=cfg.get(prefix + '_user'),
70
+ password=cfg.get(prefix + '_pass'),
71
+ )
72
+
73
+
74
+ @lang.cached_function
75
+ def _maybe_warn_pgcli_keyring() -> None:
76
+ import pgcli.config
77
+
78
+ c = pgcli.config.get_config()
79
+ if c['main'].as_bool('keyring'):
80
+ warnings.warn(
81
+ 'pgcli keyring is not disabled, it will try to store credentials. '
82
+ 'set `keyring = False` in ~/.config/pgcli/config',
83
+ )
84
+
85
+
86
+ def _dbcli_or_fallback_exe(dbcli_mod: str | None, default_exe: str) -> tuple[ta.Sequence[str], bool]:
87
+ if dbcli_mod is not None:
88
+ main_mod = dbcli_mod + '.main'
89
+ try:
90
+ __import__(main_mod)
91
+ except ImportError:
92
+ pass
93
+ else:
94
+ if dbcli_mod == 'pgcli':
95
+ _maybe_warn_pgcli_keyring()
96
+ return [sys.executable, '-m', main_mod], True
97
+ return [check.not_none(shutil.which(default_exe))], False
98
+
99
+
100
+ def exec_mysql_cli(
101
+ spec: ServerSpec,
102
+ *extra_args: str,
103
+ exe: ta.Iterable[str] | None = None,
104
+ no_dbcli: bool = False,
105
+ ) -> ta.NoReturn:
106
+ if exe is not None:
107
+ args, is_dbcli = list(exe), False
108
+ else:
109
+ argsx, is_dbcli = _dbcli_or_fallback_exe(
110
+ 'mycli' if not no_dbcli else None,
111
+ 'mysql',
112
+ )
113
+ args = list(argsx)
114
+ if spec.username:
115
+ args.extend(['--user', spec.username])
116
+ if spec.password:
117
+ os.environ['MYSQL_PWD'] = spec.password
118
+ args.extend(['--host', spec.host])
119
+ if not is_dbcli:
120
+ args.append('--protocol=TCP')
121
+ if spec.port:
122
+ args.extend(['--port', str(spec.port)])
123
+ if spec.db:
124
+ args.append(spec.db)
125
+ args.extend(extra_args)
126
+ os.execvp(args[0], args)
127
+
128
+
129
+ def exec_postgres_cli(
130
+ spec: ServerSpec,
131
+ *extra_args: str,
132
+ exe: ta.Iterable[str] | None = None,
133
+ no_dbcli: bool = False,
134
+ ) -> ta.NoReturn:
135
+ if exe is not None:
136
+ args, is_dbcli = list(exe), False
137
+ else:
138
+ argsx, is_dbcli = _dbcli_or_fallback_exe(
139
+ 'pgcli' if not no_dbcli else None,
140
+ 'psql',
141
+ )
142
+ args = list(argsx)
143
+ if spec.username:
144
+ args.extend(['--username', spec.username])
145
+ if spec.password:
146
+ os.environ['PGPASSWORD'] = spec.password
147
+ if spec.host:
148
+ args.extend(['--host', spec.host])
149
+ if spec.port:
150
+ args.extend(['--port', str(spec.port)])
151
+ if spec.db:
152
+ args.append(spec.db)
153
+ args.extend(extra_args)
154
+ os.execvp(args[0], args)
155
+
156
+
157
+ class Cli(ap.Cli):
158
+ @ap.command(
159
+ ap.arg('--no-dbcli', action='store_true'),
160
+ ap.arg('dialect'),
161
+ ap.arg('target'),
162
+ ap.arg('args', nargs='*'),
163
+ )
164
+ def repl(self) -> None:
165
+ l, _, r = (target := self.args.target).partition(':')
166
+ _, lf = os.path.dirname(l), os.path.basename(l)
167
+ if not lf.endswith('.yml'):
168
+ raise Exception(f'unhandled target: {target=}')
169
+ with open(l) as f:
170
+ cfg = yaml.safe_load(f.read())
171
+ dialect = self.args.dialect
172
+ if lf == 'compose.yml':
173
+ svc = cfg['services'][r]
174
+ if dialect == 'mysql':
175
+ spec = spec_from_mysql_docker_compose(svc)
176
+ elif dialect == 'postgres':
177
+ spec = spec_from_postgres_docker_compose(svc)
178
+ else:
179
+ raise Exception(f'unhandled dialect: {dialect=}')
180
+ else:
181
+ spec = spec_from_cfg(cfg, r)
182
+
183
+ if dialect == 'mysql':
184
+ exec_mysql_cli(spec, *self.args.args, no_dbcli=self.args.no_dbcli)
185
+ elif dialect == 'postgres':
186
+ exec_postgres_cli(spec, *self.args.args, no_dbcli=self.args.no_dbcli)
187
+ else:
188
+ raise Exception(f'unhandled dialect: {dialect=}')
189
+
190
+
191
+ if __name__ == '__main__':
192
+ logs.configure_standard_logging('INFO')
193
+ Cli()()
@@ -0,0 +1 @@
1
+ # @omlish-lite