omdev 0.0.0.dev124__tar.gz → 0.0.0.dev137__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.dev124/omdev.egg-info → omdev-0.0.0.dev137}/PKG-INFO +2 -2
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/.manifests.json +16 -1
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/amalg/amalg.py +40 -12
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/sysconfig.py +3 -3
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cli/clicli.py +2 -2
- omdev-0.0.0.dev137/omdev/json/__main__.py +11 -0
- omdev-0.0.0.dev137/omdev/json/cli.py +299 -0
- omdev-0.0.0.dev137/omdev/json/formats.py +71 -0
- omdev-0.0.0.dev137/omdev/json/io.py +74 -0
- omdev-0.0.0.dev137/omdev/json/parsing.py +83 -0
- omdev-0.0.0.dev137/omdev/json/processing.py +48 -0
- omdev-0.0.0.dev137/omdev/json/rendering.py +92 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/packaging/marshal.py +1 -1
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/ptk/__init__.py +6 -1
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/pycharm/cli.py +60 -17
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/revisions.py +1 -1
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/scripts/interp.py +43 -4
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/scripts/pyproject.py +54 -12
- omdev-0.0.0.dev137/omdev/tokens.py +76 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/tools/git.py +8 -2
- omdev-0.0.0.dev137/omdev/tools/pawk/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137/omdev.egg-info}/PKG-INFO +2 -2
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev.egg-info/SOURCES.txt +8 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev.egg-info/requires.txt +1 -1
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/pyproject.toml +2 -2
- omdev-0.0.0.dev124/omdev/tokens.py +0 -42
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/LICENSE +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/MANIFEST.in +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/README.rst +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/__about__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/amalg/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/amalg/__main__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/antlr/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/antlr/consts.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/antlr/gen.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/bracepy.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/compute/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/compute/cache.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/compute/contexts.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/compute/currents.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/compute/fns.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/compute/resolvers.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/compute/storage.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/compute/types.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/data/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/data/actions.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/data/cache.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/data/consts.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/data/defaults.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/data/manifests.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cache/data/specs.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_boilerplate.cc +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/LICENSE +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/build_ext.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/compilers/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/compilers/ccompiler.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/compilers/options.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/compilers/unixccompiler.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/dir_util.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/errors.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/extension.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/file_util.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/modified.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/spawn.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/util.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/_distutils/version.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/build.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/cmake.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/importhook.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/magic.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cexts/scan.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/classdot.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cli/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cli/__main__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cli/_pathhack.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cli/install.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cli/main.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cli/managers.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cli/types.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/clipboard/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/clipboard/clipboard.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/clipboard/darwin_cf.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/clipboard/linux_x.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/cmake.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/findimports.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/git.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/imgur.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/interp/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/interp/__main__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/interp/cli.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/interp/inspect.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/interp/providers.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/interp/pyenv.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/interp/resolvers.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/interp/standalone.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/interp/system.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/interp/types.py +0 -0
- {omdev-0.0.0.dev124/omdev/mypy → omdev-0.0.0.dev137/omdev/json}/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/magic/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/magic/find.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/magic/magic.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/magic/prepare.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/magic/styles.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/manifests/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/manifests/build.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/manifests/load.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/manifests/types.py +0 -0
- {omdev-0.0.0.dev124/omdev/packaging → omdev-0.0.0.dev137/omdev/mypy}/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/mypy/debug.py +0 -0
- {omdev-0.0.0.dev124/omdev/precheck → omdev-0.0.0.dev137/omdev/packaging}/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/packaging/names.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/packaging/requires.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/packaging/specifiers.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/packaging/versions.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/pip.py +0 -0
- {omdev-0.0.0.dev124/omdev/ptk/apps → omdev-0.0.0.dev137/omdev/precheck}/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/precheck/__main__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/precheck/base.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/precheck/git.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/precheck/lite.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/precheck/main.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/precheck/manifests.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/precheck/scripts.py +0 -0
- {omdev-0.0.0.dev124/omdev/pycharm → omdev-0.0.0.dev137/omdev/ptk/apps}/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/ptk/apps/ncdu.py +0 -0
- {omdev-0.0.0.dev124/omdev/tools/pawk → omdev-0.0.0.dev137/omdev/pycharm}/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/pycharm/__main__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/pyproject/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/pyproject/__main__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/pyproject/cexts.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/pyproject/cli.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/pyproject/configs.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/pyproject/pkg.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/pyproject/reqs.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/scripts/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/scripts/bumpversion.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/scripts/execrss.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/scripts/exectime.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/scripts/importtrace.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/scripts/slowcat.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/scripts/tmpexec.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/secrets.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/toml/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/toml/parser.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/toml/writer.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/tools/__init__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/tools/doc.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/tools/docker.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/tools/importscan.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/tools/mkrelimp.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/tools/notebook.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/tools/pawk/__main__.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/tools/pawk/pawk.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/tools/pip.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/tools/prof.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/tools/qr.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/tools/sqlrepl.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev/wheelfile.py +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev.egg-info/dependency_links.txt +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev.egg-info/entry_points.txt +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/omdev.egg-info/top_level.txt +0 -0
- {omdev-0.0.0.dev124 → omdev-0.0.0.dev137}/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.dev137
|
|
4
4
|
Summary: omdev
|
|
5
5
|
Author: wrmsr
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -12,7 +12,7 @@ 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.dev137
|
|
16
16
|
Provides-Extra: all
|
|
17
17
|
Requires-Dist: black~=24.10; extra == "all"
|
|
18
18
|
Requires-Dist: pycparser~=2.22; extra == "all"
|
|
@@ -95,6 +95,21 @@
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
|
+
{
|
|
99
|
+
"module": ".json.__main__",
|
|
100
|
+
"attr": "_CLI_MODULE",
|
|
101
|
+
"file": "omdev/json/__main__.py",
|
|
102
|
+
"line": 4,
|
|
103
|
+
"value": {
|
|
104
|
+
"$.cli.types.CliModule": {
|
|
105
|
+
"cmd_name": [
|
|
106
|
+
"json",
|
|
107
|
+
"j"
|
|
108
|
+
],
|
|
109
|
+
"mod_name": "omdev.json.__main__"
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
},
|
|
98
113
|
{
|
|
99
114
|
"module": ".magic.find",
|
|
100
115
|
"attr": "_CLI_MODULE",
|
|
@@ -243,7 +258,7 @@
|
|
|
243
258
|
"module": ".tools.git",
|
|
244
259
|
"attr": "_CLI_MODULE",
|
|
245
260
|
"file": "omdev/tools/git.py",
|
|
246
|
-
"line":
|
|
261
|
+
"line": 211,
|
|
247
262
|
"value": {
|
|
248
263
|
"$.cli.types.CliModule": {
|
|
249
264
|
"cmd_name": "git",
|
|
@@ -222,22 +222,30 @@ class Typing:
|
|
|
222
222
|
toks: Tokens = dc.field(repr=False)
|
|
223
223
|
|
|
224
224
|
|
|
225
|
-
def _is_typing(
|
|
225
|
+
def _is_typing(
|
|
226
|
+
lts: Tokens,
|
|
227
|
+
*,
|
|
228
|
+
exclude_newtypes: bool = False,
|
|
229
|
+
) -> bool:
|
|
226
230
|
es = tks.join_toks(lts).strip()
|
|
227
231
|
if any(es.endswith(sfx) for sfx in (TYPE_ALIAS_COMMENT, NOQA_TYPE_ALIAS_COMMENT)):
|
|
228
232
|
return True
|
|
229
233
|
|
|
230
234
|
wts = list(tks.ignore_ws(lts))
|
|
231
|
-
if (
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
):
|
|
238
|
-
return
|
|
235
|
+
if not tks.match_toks(wts, [
|
|
236
|
+
('NAME', None),
|
|
237
|
+
('OP', '='),
|
|
238
|
+
('NAME', 'ta'),
|
|
239
|
+
('OP', '.'),
|
|
240
|
+
(None, None),
|
|
241
|
+
]):
|
|
242
|
+
return False
|
|
243
|
+
|
|
244
|
+
if exclude_newtypes:
|
|
245
|
+
if wts[4].name == 'NAME' and wts[4].src == 'NewType':
|
|
246
|
+
return False
|
|
239
247
|
|
|
240
|
-
return
|
|
248
|
+
return True
|
|
241
249
|
|
|
242
250
|
|
|
243
251
|
def make_typing(
|
|
@@ -248,7 +256,7 @@ def make_typing(
|
|
|
248
256
|
if not lts or lts[0].name == 'UNIMPORTANT_WS':
|
|
249
257
|
return None
|
|
250
258
|
|
|
251
|
-
if not _is_typing(lts):
|
|
259
|
+
if not _is_typing(lts, exclude_newtypes=True):
|
|
252
260
|
return None
|
|
253
261
|
|
|
254
262
|
ft = next(iter(tks.ignore_ws(lts)))
|
|
@@ -265,6 +273,19 @@ def make_typing(
|
|
|
265
273
|
##
|
|
266
274
|
|
|
267
275
|
|
|
276
|
+
def is_root_level_if_type_checking_block(lts: Tokens) -> bool:
|
|
277
|
+
return tks.match_toks(tks.ignore_ws(lts, keep=['INDENT']), [
|
|
278
|
+
('NAME', 'if'),
|
|
279
|
+
('NAME', 'ta'),
|
|
280
|
+
('OP', '.'),
|
|
281
|
+
('NAME', 'TYPE_CHECKING'),
|
|
282
|
+
('OP', ':'),
|
|
283
|
+
])
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
##
|
|
287
|
+
|
|
288
|
+
|
|
268
289
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
269
290
|
class SrcFile:
|
|
270
291
|
path: str
|
|
@@ -344,6 +365,13 @@ def make_src_file(
|
|
|
344
365
|
for ml in mls
|
|
345
366
|
])
|
|
346
367
|
|
|
368
|
+
elif is_root_level_if_type_checking_block(line):
|
|
369
|
+
while True:
|
|
370
|
+
nl = cls[i]
|
|
371
|
+
if nl and nl[0].name != 'INDENT':
|
|
372
|
+
break
|
|
373
|
+
i += 1
|
|
374
|
+
|
|
347
375
|
else:
|
|
348
376
|
ctls.append(line)
|
|
349
377
|
|
|
@@ -498,7 +526,7 @@ def gen_amalg(
|
|
|
498
526
|
if i:
|
|
499
527
|
out.write('\n')
|
|
500
528
|
if f is not mf:
|
|
501
|
-
rp = os.path.relpath(f.path, mf.path)
|
|
529
|
+
rp = os.path.relpath(f.path, os.path.dirname(mf.path))
|
|
502
530
|
else:
|
|
503
531
|
rp = os.path.basename(f.path)
|
|
504
532
|
out.write(f'# {rp}\n')
|
|
@@ -73,7 +73,7 @@ def get_python_version():
|
|
|
73
73
|
Return a string containing the major and minor Python version, leaving off the patchlevel. Sample return values
|
|
74
74
|
could be '1.5' or '2.2'.
|
|
75
75
|
"""
|
|
76
|
-
return '%d.%d' % sys.version_info[:2]
|
|
76
|
+
return '%d.%d' % sys.version_info[:2] # noqa
|
|
77
77
|
|
|
78
78
|
|
|
79
79
|
def get_python_inc(plat_specific=0, prefix=None):
|
|
@@ -193,9 +193,9 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
|
|
|
193
193
|
|
|
194
194
|
if prefix is None:
|
|
195
195
|
if standard_lib:
|
|
196
|
-
prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX
|
|
196
|
+
prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX # noqa
|
|
197
197
|
else:
|
|
198
|
-
prefix = plat_specific and EXEC_PREFIX or PREFIX
|
|
198
|
+
prefix = plat_specific and EXEC_PREFIX or PREFIX # noqa
|
|
199
199
|
|
|
200
200
|
if os.name == 'posix':
|
|
201
201
|
if plat_specific or standard_lib:
|
|
@@ -21,11 +21,11 @@ class CliCli(ap.Cli):
|
|
|
21
21
|
|
|
22
22
|
#
|
|
23
23
|
|
|
24
|
-
@ap.command(name='version')
|
|
24
|
+
@ap.command(name='version', aliases=['ver'])
|
|
25
25
|
def print_version(self) -> None:
|
|
26
26
|
print(__about__.__version__)
|
|
27
27
|
|
|
28
|
-
@ap.command(name='revision')
|
|
28
|
+
@ap.command(name='revision', aliases=['rev'])
|
|
29
29
|
def print_revision(self) -> None:
|
|
30
30
|
print(__about__.__revision__)
|
|
31
31
|
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- read from http
|
|
4
|
+
- jmespath output flat, unquoted strs like jq '.[]'
|
|
5
|
+
|
|
6
|
+
==
|
|
7
|
+
|
|
8
|
+
jq Command options:
|
|
9
|
+
-n, --null-input use `null` as the single input value;
|
|
10
|
+
-R, --raw-input read each line as string instead of JSON;
|
|
11
|
+
-s, --slurp read all inputs into an array and use it as the single input value;
|
|
12
|
+
-c, --compact-output compact instead of pretty-printed output;
|
|
13
|
+
-r, --raw-output output strings without escapes and quotes;
|
|
14
|
+
--raw-output0 implies -r and output NUL after each output;
|
|
15
|
+
-j, --join-output implies -r and output without newline after each output;
|
|
16
|
+
-a, --ascii-output output strings by only ASCII characters using escape sequences;
|
|
17
|
+
-S, --sort-keys sort keys of each object on output;
|
|
18
|
+
-C, --color-output colorize JSON output;
|
|
19
|
+
-M, --monochrome-output disable colored output;
|
|
20
|
+
--tab use tabs for indentation;
|
|
21
|
+
--indent n use n spaces for indentation (max 7 spaces);
|
|
22
|
+
--unbuffered flush output stream after each output;
|
|
23
|
+
--stream parse the input value in streaming fashion;
|
|
24
|
+
--stream-errors implies --stream and report parse error as an array;
|
|
25
|
+
--seq parse input/output as application/json-seq;
|
|
26
|
+
-f, --from-file file load filter from the file;
|
|
27
|
+
-L directory search modules from the directory;
|
|
28
|
+
--arg name value set $name to the string value;
|
|
29
|
+
--argjson name value set $name to the JSON value;
|
|
30
|
+
--slurpfile name file set $name to an array of JSON values read from the file;
|
|
31
|
+
--rawfile name file set $name to string contents of file;
|
|
32
|
+
--args consume remaining arguments as positional string values;
|
|
33
|
+
--jsonargs consume remaining arguments as positional JSON values;
|
|
34
|
+
-e, --exit-status set exit status code based on the output;
|
|
35
|
+
-V, --version show the version;
|
|
36
|
+
--build-configuration show jq's build configuration;
|
|
37
|
+
-h, --help show the help;
|
|
38
|
+
-- terminates argument processing;
|
|
39
|
+
"""
|
|
40
|
+
import argparse
|
|
41
|
+
import contextlib
|
|
42
|
+
import dataclasses as dc
|
|
43
|
+
import io
|
|
44
|
+
import os
|
|
45
|
+
import subprocess
|
|
46
|
+
import sys
|
|
47
|
+
import typing as ta
|
|
48
|
+
|
|
49
|
+
from omlish import check
|
|
50
|
+
from omlish import lang
|
|
51
|
+
from omlish.funcs import pipes as fp
|
|
52
|
+
|
|
53
|
+
from .formats import FORMATS_BY_NAME
|
|
54
|
+
from .formats import Format
|
|
55
|
+
from .formats import Formats
|
|
56
|
+
from .parsing import DelimitingParser
|
|
57
|
+
from .parsing import EagerParser
|
|
58
|
+
from .parsing import StreamBuilder
|
|
59
|
+
from .parsing import StreamParser
|
|
60
|
+
from .processing import ProcessingOptions
|
|
61
|
+
from .processing import Processor
|
|
62
|
+
from .rendering import EagerRenderer
|
|
63
|
+
from .rendering import RenderingOptions
|
|
64
|
+
from .rendering import StreamRenderer
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
T = ta.TypeVar('T')
|
|
68
|
+
U = ta.TypeVar('U')
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _build_args_parser() -> argparse.ArgumentParser:
|
|
72
|
+
parser = argparse.ArgumentParser()
|
|
73
|
+
|
|
74
|
+
parser.add_argument('file', nargs='?')
|
|
75
|
+
|
|
76
|
+
parser.add_argument('--stream', action='store_true')
|
|
77
|
+
parser.add_argument('--stream-build', action='store_true')
|
|
78
|
+
|
|
79
|
+
parser.add_argument('-l', '--lines', action='store_true')
|
|
80
|
+
|
|
81
|
+
parser.add_argument('--read-buffer-size', type=int, default=0x4000)
|
|
82
|
+
|
|
83
|
+
parser.add_argument('-f', '--format')
|
|
84
|
+
|
|
85
|
+
parser.add_argument('-x', '--jmespath-expr')
|
|
86
|
+
parser.add_argument('-F', '--flat', action='store_true')
|
|
87
|
+
|
|
88
|
+
parser.add_argument('-z', '--compact', action='store_true')
|
|
89
|
+
parser.add_argument('-p', '--pretty', action='store_true')
|
|
90
|
+
parser.add_argument('-i', '--indent')
|
|
91
|
+
parser.add_argument('-s', '--sort-keys', action='store_true')
|
|
92
|
+
parser.add_argument('-R', '--raw', action='store_true')
|
|
93
|
+
parser.add_argument('-U', '--unicode', action='store_true')
|
|
94
|
+
parser.add_argument('-c', '--color', action='store_true')
|
|
95
|
+
|
|
96
|
+
parser.add_argument('-L', '--less', action='store_true')
|
|
97
|
+
|
|
98
|
+
return parser
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _parse_args(args: ta.Any = None) -> ta.Any:
|
|
102
|
+
return _build_args_parser().parse_args(args)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
106
|
+
class RunConfiguration:
|
|
107
|
+
format: Format
|
|
108
|
+
processing: ProcessingOptions
|
|
109
|
+
rendering: RenderingOptions
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _process_args(args: ta.Any) -> RunConfiguration:
|
|
113
|
+
fmt_name = args.format
|
|
114
|
+
if fmt_name is None:
|
|
115
|
+
if args.file is not None:
|
|
116
|
+
ext = args.file.rpartition('.')[2]
|
|
117
|
+
if ext in FORMATS_BY_NAME:
|
|
118
|
+
fmt_name = ext
|
|
119
|
+
if fmt_name is None:
|
|
120
|
+
fmt_name = 'json'
|
|
121
|
+
format = FORMATS_BY_NAME[fmt_name] # noqa
|
|
122
|
+
|
|
123
|
+
if args.stream:
|
|
124
|
+
check.arg(format is Formats.JSON.value)
|
|
125
|
+
|
|
126
|
+
#
|
|
127
|
+
|
|
128
|
+
processing = ProcessingOptions(
|
|
129
|
+
jmespath_expr=args.jmespath_expr,
|
|
130
|
+
flat=args.flat,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
#
|
|
134
|
+
|
|
135
|
+
separators = None
|
|
136
|
+
if args.compact:
|
|
137
|
+
separators = (',', ':')
|
|
138
|
+
|
|
139
|
+
indent = None
|
|
140
|
+
if args.pretty:
|
|
141
|
+
indent = 2
|
|
142
|
+
if args.indent:
|
|
143
|
+
try:
|
|
144
|
+
indent = int(args.indent)
|
|
145
|
+
except ValueError:
|
|
146
|
+
indent = args.indent
|
|
147
|
+
|
|
148
|
+
rendering = RenderingOptions(
|
|
149
|
+
indent=indent,
|
|
150
|
+
separators=separators,
|
|
151
|
+
sort_keys=args.sort_keys,
|
|
152
|
+
raw=args.raw,
|
|
153
|
+
unicode=args.unicode,
|
|
154
|
+
color=args.color,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
#
|
|
158
|
+
|
|
159
|
+
return RunConfiguration(
|
|
160
|
+
format=format,
|
|
161
|
+
processing=processing,
|
|
162
|
+
rendering=rendering,
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _main() -> None:
|
|
167
|
+
args = _parse_args()
|
|
168
|
+
|
|
169
|
+
#
|
|
170
|
+
|
|
171
|
+
cfg = _process_args(args)
|
|
172
|
+
|
|
173
|
+
#
|
|
174
|
+
|
|
175
|
+
with contextlib.ExitStack() as es:
|
|
176
|
+
if args.file is None:
|
|
177
|
+
in_file = sys.stdin.buffer
|
|
178
|
+
|
|
179
|
+
else:
|
|
180
|
+
in_file = es.enter_context(open(args.file, 'rb'))
|
|
181
|
+
|
|
182
|
+
def yield_input() -> ta.Generator[bytes, None, None]:
|
|
183
|
+
fd = check.isinstance(in_file.fileno(), int)
|
|
184
|
+
|
|
185
|
+
while True:
|
|
186
|
+
buf = os.read(fd, args.read_buffer_size)
|
|
187
|
+
|
|
188
|
+
yield buf
|
|
189
|
+
|
|
190
|
+
if not buf:
|
|
191
|
+
break
|
|
192
|
+
|
|
193
|
+
#
|
|
194
|
+
|
|
195
|
+
if args.less:
|
|
196
|
+
less = subprocess.Popen(
|
|
197
|
+
[
|
|
198
|
+
'less',
|
|
199
|
+
*(['-R'] if cfg.rendering.color else []),
|
|
200
|
+
],
|
|
201
|
+
stdin=subprocess.PIPE,
|
|
202
|
+
encoding='utf-8',
|
|
203
|
+
)
|
|
204
|
+
out = check.not_none(less.stdin)
|
|
205
|
+
|
|
206
|
+
def close_less() -> None:
|
|
207
|
+
out.close()
|
|
208
|
+
less.wait()
|
|
209
|
+
|
|
210
|
+
es.enter_context(lang.defer(close_less)) # noqa
|
|
211
|
+
|
|
212
|
+
else:
|
|
213
|
+
out = sys.stdout
|
|
214
|
+
|
|
215
|
+
#
|
|
216
|
+
|
|
217
|
+
parser: ta.Any
|
|
218
|
+
renderer: ta.Any
|
|
219
|
+
|
|
220
|
+
if args.stream:
|
|
221
|
+
with contextlib.ExitStack() as es2:
|
|
222
|
+
parser = es2.enter_context(StreamParser())
|
|
223
|
+
|
|
224
|
+
def flush_output(
|
|
225
|
+
fn: ta.Callable[[T], ta.Iterable[U]],
|
|
226
|
+
i: T,
|
|
227
|
+
) -> ta.Generator[U, None, None]:
|
|
228
|
+
n = 0
|
|
229
|
+
for o in fn(i):
|
|
230
|
+
yield o
|
|
231
|
+
n += 1
|
|
232
|
+
if n:
|
|
233
|
+
out.flush()
|
|
234
|
+
|
|
235
|
+
pipeline: ta.Any
|
|
236
|
+
|
|
237
|
+
if args.stream_build:
|
|
238
|
+
builder: StreamBuilder = es2.enter_context(StreamBuilder())
|
|
239
|
+
processor = Processor(cfg.processing)
|
|
240
|
+
renderer = EagerRenderer(cfg.rendering)
|
|
241
|
+
trailing_newline = False
|
|
242
|
+
|
|
243
|
+
def append_newlines(
|
|
244
|
+
fn: ta.Callable[[T], ta.Iterable[str]],
|
|
245
|
+
i: T,
|
|
246
|
+
) -> ta.Generator[str, None, None]:
|
|
247
|
+
yield from fn(i)
|
|
248
|
+
yield '\n'
|
|
249
|
+
|
|
250
|
+
pipeline = lambda v: (renderer.render(v),) # Any -> [str] # noqa
|
|
251
|
+
pipeline = fp.bind(append_newlines, pipeline) # Any -> [str]
|
|
252
|
+
pipeline = fp.bind(lang.flatmap, pipeline) # [Any] -> [str]
|
|
253
|
+
pipeline = fp.pipe(fp.bind(lang.flatmap, processor.process), pipeline) # [Any] -> [str]
|
|
254
|
+
pipeline = fp.pipe(fp.bind(lang.flatmap, builder.build), pipeline) # [JsonStreamParserEvent] -> [str] # noqa
|
|
255
|
+
pipeline = fp.pipe(parser.parse, pipeline) # bytes -> [str]
|
|
256
|
+
|
|
257
|
+
else:
|
|
258
|
+
renderer = StreamRenderer(cfg.rendering)
|
|
259
|
+
trailing_newline = True
|
|
260
|
+
|
|
261
|
+
pipeline = renderer.render # JsonStreamParserEvent -> [str]
|
|
262
|
+
pipeline = fp.bind(lang.flatmap, pipeline) # [JsonStreamParserEvent] -> [str]
|
|
263
|
+
pipeline = fp.pipe(parser.parse, pipeline) # bytes -> [str]
|
|
264
|
+
|
|
265
|
+
pipeline = fp.bind(flush_output, pipeline) # bytes -> [str]
|
|
266
|
+
|
|
267
|
+
for buf in yield_input():
|
|
268
|
+
for s in pipeline(buf):
|
|
269
|
+
print(s, file=out, end='')
|
|
270
|
+
|
|
271
|
+
if trailing_newline:
|
|
272
|
+
print(file=out)
|
|
273
|
+
|
|
274
|
+
elif args.lines:
|
|
275
|
+
parser = DelimitingParser(cfg.format)
|
|
276
|
+
processor = Processor(cfg.processing)
|
|
277
|
+
renderer = EagerRenderer(cfg.rendering)
|
|
278
|
+
|
|
279
|
+
for buf in yield_input():
|
|
280
|
+
for v in parser.parse(buf):
|
|
281
|
+
for e in processor.process(v):
|
|
282
|
+
s = renderer.render(e)
|
|
283
|
+
print(s, file=out)
|
|
284
|
+
|
|
285
|
+
else:
|
|
286
|
+
parser = EagerParser(cfg.format)
|
|
287
|
+
processor = Processor(cfg.processing)
|
|
288
|
+
renderer = EagerRenderer(cfg.rendering)
|
|
289
|
+
|
|
290
|
+
with io.TextIOWrapper(in_file) as tf:
|
|
291
|
+
v = parser.parse(tf)
|
|
292
|
+
|
|
293
|
+
for e in processor.process(v):
|
|
294
|
+
s = renderer.render(e)
|
|
295
|
+
print(s, file=out)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
if __name__ == '__main__':
|
|
299
|
+
_main()
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- options lol - csv header, newline, etc
|
|
4
|
+
"""
|
|
5
|
+
import dataclasses as dc
|
|
6
|
+
import enum
|
|
7
|
+
import json
|
|
8
|
+
import typing as ta
|
|
9
|
+
|
|
10
|
+
from omlish import lang
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
if ta.TYPE_CHECKING:
|
|
14
|
+
import ast
|
|
15
|
+
import csv
|
|
16
|
+
import tomllib
|
|
17
|
+
|
|
18
|
+
import yaml
|
|
19
|
+
|
|
20
|
+
from omlish.formats import dotenv
|
|
21
|
+
from omlish.formats import props
|
|
22
|
+
from omlish.formats import xml
|
|
23
|
+
|
|
24
|
+
else:
|
|
25
|
+
ast = lang.proxy_import('ast')
|
|
26
|
+
csv = lang.proxy_import('csv')
|
|
27
|
+
tomllib = lang.proxy_import('tomllib')
|
|
28
|
+
|
|
29
|
+
yaml = lang.proxy_import('yaml')
|
|
30
|
+
|
|
31
|
+
dotenv = lang.proxy_import('omlish.formats.dotenv')
|
|
32
|
+
props = lang.proxy_import('omlish.formats.props')
|
|
33
|
+
xml = lang.proxy_import('omlish.formats.xml')
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dc.dataclass(frozen=True)
|
|
40
|
+
class Format:
|
|
41
|
+
names: ta.Sequence[str]
|
|
42
|
+
load: ta.Callable[[ta.TextIO], ta.Any]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class Formats(enum.Enum):
|
|
46
|
+
JSON = Format(['json'], json.load)
|
|
47
|
+
|
|
48
|
+
YAML = Format(['yaml', 'yml'], lambda f: yaml.safe_load(f))
|
|
49
|
+
|
|
50
|
+
TOML = Format(['toml'], lambda f: tomllib.loads(f.read()))
|
|
51
|
+
|
|
52
|
+
ENV = Format(['env', 'dotenv'], lambda f: dotenv.dotenv_values(stream=f))
|
|
53
|
+
|
|
54
|
+
PROPS = Format(['properties', 'props'], lambda f: dict(props.Properties().load(f.read())))
|
|
55
|
+
|
|
56
|
+
PY = Format(['py', 'python', 'repr'], lambda f: ast.literal_eval(f.read()))
|
|
57
|
+
|
|
58
|
+
XML = Format(['xml'], lambda f: xml.build_simple_element(xml.parse_tree(f.read()).getroot()).as_dict())
|
|
59
|
+
|
|
60
|
+
CSV = Format(['csv'], lambda f: list(csv.DictReader(f)))
|
|
61
|
+
TSV = Format(['tsv'], lambda f: list(csv.DictReader(f, delimiter='\t')))
|
|
62
|
+
FLAT_CSV = Format(['fcsv'], lambda f: list(csv.reader(f)))
|
|
63
|
+
FLAT_TSV = Format(['ftsv'], lambda f: list(csv.reader(f, delimiter='\t')))
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
FORMATS_BY_NAME: ta.Mapping[str, Format] = {
|
|
67
|
+
n: f
|
|
68
|
+
for e in Formats
|
|
69
|
+
for f in [e.value]
|
|
70
|
+
for n in f.names
|
|
71
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# """
|
|
2
|
+
# TODO:
|
|
3
|
+
# - -I/-Ogz, lz4, etc
|
|
4
|
+
# - fnpairs? or not yet just do it
|
|
5
|
+
# """
|
|
6
|
+
# import abc
|
|
7
|
+
# import contextlib
|
|
8
|
+
# import dataclasses as dc
|
|
9
|
+
# import gzip
|
|
10
|
+
# import os
|
|
11
|
+
# import typing as ta
|
|
12
|
+
#
|
|
13
|
+
# from .... import lang
|
|
14
|
+
#
|
|
15
|
+
#
|
|
16
|
+
# if ta.TYPE_CHECKING:
|
|
17
|
+
# import bz2 as _bz2
|
|
18
|
+
# import gzip as _gzip
|
|
19
|
+
# import lzma as _lzma
|
|
20
|
+
# else:
|
|
21
|
+
# _bz2 = lang.proxy_import('bz2')
|
|
22
|
+
# _gzip = lang.proxy_import('gzip')
|
|
23
|
+
# _lzma = lang.proxy_import('lzma')
|
|
24
|
+
#
|
|
25
|
+
#
|
|
26
|
+
# ##
|
|
27
|
+
#
|
|
28
|
+
#
|
|
29
|
+
# class BaseIo(lang.Abstract):
|
|
30
|
+
# def close(self) -> None:
|
|
31
|
+
# raise NotImplementedError
|
|
32
|
+
#
|
|
33
|
+
# def fileno(self) -> int | None:
|
|
34
|
+
# return None
|
|
35
|
+
#
|
|
36
|
+
#
|
|
37
|
+
# class Input(BaseIo):
|
|
38
|
+
# @abc.abstractmethod
|
|
39
|
+
# def read(self, sz: int | None = None) -> bytes:
|
|
40
|
+
# raise NotImplementedError
|
|
41
|
+
#
|
|
42
|
+
#
|
|
43
|
+
# class Output(BaseIo):
|
|
44
|
+
# @abc.abstractmethod
|
|
45
|
+
# def write(self, data: bytes) -> int:
|
|
46
|
+
# raise NotImplementedError
|
|
47
|
+
#
|
|
48
|
+
#
|
|
49
|
+
# #
|
|
50
|
+
#
|
|
51
|
+
#
|
|
52
|
+
# DEFAULT_READ_SZ = 0x4000
|
|
53
|
+
#
|
|
54
|
+
#
|
|
55
|
+
# @dc.dataclass(frozen=True)
|
|
56
|
+
# class FdIo(Input, Output):
|
|
57
|
+
# fd: int
|
|
58
|
+
#
|
|
59
|
+
# default_read_sz: int = DEFAULT_READ_SZ
|
|
60
|
+
#
|
|
61
|
+
# def read(self, sz: int | None = None) -> bytes:
|
|
62
|
+
# return os.read(self.fd, sz or self.default_read_sz)
|
|
63
|
+
#
|
|
64
|
+
# def write(self, data: bytes) -> int:
|
|
65
|
+
# return os.write(self.fd, data)
|
|
66
|
+
#
|
|
67
|
+
#
|
|
68
|
+
# ##
|
|
69
|
+
#
|
|
70
|
+
#
|
|
71
|
+
# @contextlib.contextmanager
|
|
72
|
+
# def gzip_io_codec(f: ta.IO, mode: str) -> ta.ContextManager[ta.IO]:
|
|
73
|
+
# with gzip.open(f, mode) as o:
|
|
74
|
+
# yield o
|