omdev 0.0.0.dev439__py3-none-any.whl → 0.0.0.dev486__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.
Potentially problematic release.
This version of omdev might be problematic. Click here for more details.
- omdev/.omlish-manifests.json +18 -30
- omdev/__about__.py +9 -7
- omdev/amalg/gen/gen.py +49 -6
- omdev/amalg/gen/imports.py +1 -1
- omdev/amalg/gen/manifests.py +1 -1
- omdev/amalg/gen/resources.py +1 -1
- omdev/amalg/gen/srcfiles.py +13 -3
- omdev/amalg/gen/strip.py +1 -1
- omdev/amalg/gen/types.py +1 -1
- omdev/amalg/gen/typing.py +1 -1
- omdev/amalg/info.py +32 -0
- omdev/cache/data/actions.py +1 -1
- omdev/cache/data/specs.py +1 -1
- omdev/cexts/_boilerplate.cc +2 -3
- omdev/cexts/cmake.py +4 -1
- omdev/ci/cli.py +1 -2
- omdev/ci/github/api/v2/api.py +2 -0
- omdev/cmdlog/cli.py +1 -2
- omdev/dataclasses/_dumping.py +1960 -0
- omdev/dataclasses/_template.py +22 -0
- omdev/dataclasses/cli.py +6 -1
- omdev/dataclasses/codegen.py +340 -60
- omdev/dataclasses/dumping.py +200 -0
- omdev/interp/uv/provider.py +1 -0
- omdev/interp/venvs.py +1 -0
- omdev/irc/messages/base.py +50 -0
- omdev/irc/messages/formats.py +92 -0
- omdev/irc/messages/messages.py +775 -0
- omdev/irc/messages/parsing.py +99 -0
- omdev/irc/numerics/__init__.py +0 -0
- omdev/irc/numerics/formats.py +97 -0
- omdev/irc/numerics/numerics.py +865 -0
- omdev/irc/numerics/types.py +59 -0
- omdev/irc/protocol/LICENSE +11 -0
- omdev/irc/protocol/__init__.py +61 -0
- omdev/irc/protocol/consts.py +6 -0
- omdev/irc/protocol/errors.py +30 -0
- omdev/irc/protocol/message.py +21 -0
- omdev/irc/protocol/nuh.py +55 -0
- omdev/irc/protocol/parsing.py +158 -0
- omdev/irc/protocol/rendering.py +153 -0
- omdev/irc/protocol/tags.py +102 -0
- omdev/irc/protocol/utils.py +30 -0
- omdev/manifests/_dumping.py +125 -25
- omdev/markdown/__init__.py +0 -0
- omdev/markdown/incparse.py +116 -0
- omdev/markdown/tokens.py +51 -0
- omdev/packaging/marshal.py +8 -8
- omdev/packaging/requires.py +6 -6
- omdev/packaging/specifiers.py +2 -1
- omdev/packaging/versions.py +4 -4
- omdev/packaging/wheelfile.py +2 -0
- omdev/precheck/blanklines.py +66 -0
- omdev/precheck/caches.py +1 -1
- omdev/precheck/imports.py +14 -1
- omdev/precheck/main.py +4 -3
- omdev/precheck/unicode.py +39 -15
- omdev/py/asts/__init__.py +0 -0
- omdev/py/asts/parents.py +28 -0
- omdev/py/asts/toplevel.py +123 -0
- omdev/py/asts/visitors.py +18 -0
- omdev/py/attrdocs.py +6 -7
- omdev/py/bracepy.py +12 -4
- omdev/py/reprs.py +32 -0
- omdev/py/srcheaders.py +1 -1
- omdev/py/tokens/__init__.py +0 -0
- omdev/py/tools/mkrelimp.py +1 -1
- omdev/py/tools/pipdepup.py +629 -0
- omdev/pyproject/pkg.py +190 -45
- omdev/pyproject/reqs.py +31 -9
- omdev/pyproject/tools/__init__.py +0 -0
- omdev/pyproject/tools/aboutdeps.py +55 -0
- omdev/pyproject/venvs.py +8 -1
- omdev/rs/__init__.py +0 -0
- omdev/scripts/ci.py +400 -80
- omdev/scripts/interp.py +193 -35
- omdev/scripts/lib/__init__.py +0 -0
- omdev/scripts/{inject.py → lib/inject.py} +75 -28
- omdev/scripts/lib/logs.py +2079 -0
- omdev/scripts/{marshal.py → lib/marshal.py} +68 -26
- omdev/scripts/pyproject.py +941 -90
- omdev/tools/git/cli.py +12 -1
- omdev/tools/json/processing.py +5 -2
- omdev/tools/jsonview/cli.py +31 -5
- omdev/tools/pawk/pawk.py +2 -2
- omdev/tools/pip.py +8 -0
- omdev/tui/__init__.py +0 -0
- omdev/tui/apps/__init__.py +0 -0
- omdev/tui/apps/edit/__init__.py +0 -0
- omdev/tui/apps/edit/main.py +163 -0
- omdev/tui/apps/irc/__init__.py +0 -0
- omdev/tui/apps/irc/__main__.py +4 -0
- omdev/tui/apps/irc/app.py +278 -0
- omdev/tui/apps/irc/client.py +187 -0
- omdev/tui/apps/irc/commands.py +175 -0
- omdev/tui/apps/irc/main.py +26 -0
- omdev/tui/apps/markdown/__init__.py +0 -0
- omdev/tui/apps/markdown/__main__.py +11 -0
- omdev/{ptk → tui/apps}/markdown/cli.py +5 -7
- omdev/tui/rich/__init__.py +34 -0
- omdev/tui/rich/console2.py +20 -0
- omdev/tui/rich/markdown2.py +186 -0
- omdev/tui/textual/__init__.py +226 -0
- omdev/tui/textual/app2.py +11 -0
- omdev/tui/textual/autocomplete/LICENSE +21 -0
- omdev/tui/textual/autocomplete/__init__.py +33 -0
- omdev/tui/textual/autocomplete/matching.py +226 -0
- omdev/tui/textual/autocomplete/paths.py +202 -0
- omdev/tui/textual/autocomplete/widget.py +612 -0
- omdev/tui/textual/drivers2.py +55 -0
- {omdev-0.0.0.dev439.dist-info → omdev-0.0.0.dev486.dist-info}/METADATA +11 -9
- {omdev-0.0.0.dev439.dist-info → omdev-0.0.0.dev486.dist-info}/RECORD +121 -73
- omdev/ptk/__init__.py +0 -103
- omdev/ptk/apps/ncdu.py +0 -167
- omdev/ptk/confirm.py +0 -60
- omdev/ptk/markdown/LICENSE +0 -22
- omdev/ptk/markdown/__init__.py +0 -10
- omdev/ptk/markdown/__main__.py +0 -11
- omdev/ptk/markdown/border.py +0 -94
- omdev/ptk/markdown/markdown.py +0 -390
- omdev/ptk/markdown/parser.py +0 -42
- omdev/ptk/markdown/styles.py +0 -29
- omdev/ptk/markdown/tags.py +0 -299
- omdev/ptk/markdown/utils.py +0 -366
- omdev/pyproject/cexts.py +0 -110
- /omdev/{ptk/apps → irc}/__init__.py +0 -0
- /omdev/{tokens → irc/messages}/__init__.py +0 -0
- /omdev/{tokens → py/tokens}/all.py +0 -0
- /omdev/{tokens → py/tokens}/tokenizert.py +0 -0
- /omdev/{tokens → py/tokens}/utils.py +0 -0
- {omdev-0.0.0.dev439.dist-info → omdev-0.0.0.dev486.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev439.dist-info → omdev-0.0.0.dev486.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev439.dist-info → omdev-0.0.0.dev486.dist-info}/licenses/LICENSE +0 -0
- {omdev-0.0.0.dev439.dist-info → omdev-0.0.0.dev486.dist-info}/top_level.txt +0 -0
omdev/scripts/ci.py
CHANGED
|
@@ -49,6 +49,7 @@ import io
|
|
|
49
49
|
import itertools
|
|
50
50
|
import json
|
|
51
51
|
import logging
|
|
52
|
+
import operator
|
|
52
53
|
import os
|
|
53
54
|
import os.path
|
|
54
55
|
import re
|
|
@@ -83,6 +84,122 @@ if sys.version_info < (3, 8):
|
|
|
83
84
|
raise OSError(f'Requires python (3, 8), got {sys.version_info} from {sys.executable}') # noqa
|
|
84
85
|
|
|
85
86
|
|
|
87
|
+
def __omlish_amalg__(): # noqa
|
|
88
|
+
return dict(
|
|
89
|
+
src_files=[
|
|
90
|
+
dict(path='consts.py', sha1='ef00d55ab4cdd799b22f2e8b736eacd52ee8a80e'),
|
|
91
|
+
dict(path='github/env.py', sha1='c7a2389048f008f46f59f6bcc11e0d15655f2b1c'),
|
|
92
|
+
dict(path='shell.py', sha1='a59e59b812394d0502837f4c198e1cf604f90227'),
|
|
93
|
+
dict(path='utils.py', sha1='f0f9ef0778db316b1ba83e6eeac79c8fd132d86a'),
|
|
94
|
+
dict(path='../oci/compression.py', sha1='7d165bc51a77db13ff45927daecc42839cfd75ea'),
|
|
95
|
+
dict(path='../../omlish/asyncs/asyncio/utils.py', sha1='34691d4d0e5bab68f14e193a6200df040cfd0136'),
|
|
96
|
+
dict(path='../../omlish/docker/ports.py', sha1='a3202c69b85bc4f1034479df3400fddc86130e5c'),
|
|
97
|
+
dict(path='../../omlish/http/urllib.py', sha1='25431c5bdc7dd5cbecfcb8c0bdffaabf8c1691b9'),
|
|
98
|
+
dict(path='../../omlish/http/versions.py', sha1='197685ffbb62a457a0e8d4047a9df26aebd7dae4'),
|
|
99
|
+
dict(path='../../omlish/lite/abstract.py', sha1='a2fc3f3697fa8de5247761e9d554e70176f37aac'),
|
|
100
|
+
dict(path='../../omlish/lite/cached.py', sha1='0c33cf961ac8f0727284303c7a30c5ea98f714f2'),
|
|
101
|
+
dict(path='../../omlish/lite/check.py', sha1='bb6b6b63333699b84462951a854d99ae83195b94'),
|
|
102
|
+
dict(path='../../omlish/lite/contextmanagers.py', sha1='993f5ed96d3410f739a20363f55670d5e5267fa3'),
|
|
103
|
+
dict(path='../../omlish/lite/dataclasses.py', sha1='73b7f5e5493c7ed12ff0ce36e37b596e5984cb08'),
|
|
104
|
+
dict(path='../../omlish/lite/json.py', sha1='57eeddc4d23a17931e00284ffa5cb6e3ce089486'),
|
|
105
|
+
dict(path='../../omlish/lite/objects.py', sha1='9566bbf3530fd71fcc56321485216b592fae21e9'),
|
|
106
|
+
dict(path='../../omlish/lite/reflect.py', sha1='c4fec44bf144e9d93293c996af06f6c65fc5e63d'),
|
|
107
|
+
dict(path='../../omlish/lite/strings.py', sha1='89831ecbc34ad80e118a865eceb390ed399dc4d6'),
|
|
108
|
+
dict(path='../../omlish/logs/levels.py', sha1='91405563d082a5eba874da82aac89d83ce7b6152'),
|
|
109
|
+
dict(path='../../omlish/logs/std/filters.py', sha1='f36aab646d84d31e295b33aaaaa6f8b67ff38b3d'),
|
|
110
|
+
dict(path='../../omlish/logs/std/proxy.py', sha1='3e7301a2aa351127f9c85f61b2f85dcc3f15aafb'),
|
|
111
|
+
dict(path='../../omlish/logs/warnings.py', sha1='c4eb694b24773351107fcc058f3620f1dbfb6799'),
|
|
112
|
+
dict(path='../../omlish/os/files.py', sha1='32f4fe2e7d32a6b368619081bd300e6f150e312b'),
|
|
113
|
+
dict(path='../../omlish/os/paths.py', sha1='56c40b7c2aa84d1778d60ee4cda498f8c380cc8d'),
|
|
114
|
+
dict(path='../../omlish/secrets/ssl.py', sha1='68af8abad22d64afa1736a8363036aa2121ada78'),
|
|
115
|
+
dict(path='../../omlish/sockets/addresses.py', sha1='26533e88a8073f89646c0f77f1fbe0869282ab0e'),
|
|
116
|
+
dict(path='../../omlish/sockets/io.py', sha1='b6b8a73ac0f29893c7128f9d4f62240efbd917bb'),
|
|
117
|
+
dict(path='docker/utils.py', sha1='082e2b962ca1bc8e6b3f9bbe6ecfcadff310d54f'),
|
|
118
|
+
dict(path='github/api/v1/api.py', sha1='1985c16447f5d245b659936571d361285374c5d9'),
|
|
119
|
+
dict(path='github/api/v2/api.py', sha1='08322895cd895db1cbffceb1e5bfc7b10cac50cc'),
|
|
120
|
+
dict(path='github/bootstrap.py', sha1='9bf24b05603cd1a82db8be8b645bbad3e0d3f22f'),
|
|
121
|
+
dict(path='../oci/datarefs.py', sha1='793ce5f2774e052b28d04b226a5f1eff6eec0a72'),
|
|
122
|
+
dict(path='../oci/pack/unpacking.py', sha1='f43dee9a2eee79cbbb90f0721ed234a2bc35daa7'),
|
|
123
|
+
dict(path='../../omlish/argparse/cli.py', sha1='f4dc3cd353d14386b5da0306768700e396afd2b3'),
|
|
124
|
+
dict(path='../../omlish/http/coro/io.py', sha1='2cdf6529c37a37cc0c1db2e02032157cf906d5d6'),
|
|
125
|
+
dict(path='../../omlish/http/parsing.py', sha1='3fea28dc6341908ba7c8fad42bf7bbe711f21b82'),
|
|
126
|
+
dict(path='../../omlish/lite/marshal.py', sha1='96348f5f2a26dc27d842d33cc3927e9da163436b'),
|
|
127
|
+
dict(path='../../omlish/lite/maybes.py', sha1='bdf5136654ccd14b6a072588cad228925bdfbabd'),
|
|
128
|
+
dict(path='../../omlish/lite/runtime.py', sha1='2e752a27ae2bf89b1bb79b4a2da522a3ec360c70'),
|
|
129
|
+
dict(path='../../omlish/lite/timeouts.py', sha1='a0f673033a6943f242e35848d78a41892b9c62a1'),
|
|
130
|
+
dict(path='../../omlish/logs/infos.py', sha1='4dd104bd468a8c438601dd0bbda619b47d2f1620'),
|
|
131
|
+
dict(path='../../omlish/logs/protocols.py', sha1='05ca4d1d7feb50c4e3b9f22ee371aa7bf4b3dbd1'),
|
|
132
|
+
dict(path='../../omlish/logs/std/json.py', sha1='2a75553131e4d5331bb0cedde42aa183f403fc3b'),
|
|
133
|
+
dict(path='../../omlish/os/temp.py', sha1='fba3470ac095a6c3f893156cc4437bda1b8796cb'),
|
|
134
|
+
dict(path='../../omlish/sockets/bind.py', sha1='d0040d74960fb00c30ae9ece5252c270b59ae3f4'),
|
|
135
|
+
dict(path='../../omlish/sockets/handlers.py', sha1='733a4855d563001ad09df511531d710aa2632770'),
|
|
136
|
+
dict(path='../../omlish/text/mangle.py', sha1='5631de37ca659e064eb1afcf2213d317b626f8bd'),
|
|
137
|
+
dict(path='../dataserver/targets.py', sha1='661fc3e60ad436646c8acff3c547d5b86ceb0bd6'),
|
|
138
|
+
dict(path='../oci/data.py', sha1='9cfc3bb8e23fb4cd746c6e8f0e02624e8f63f234'),
|
|
139
|
+
dict(path='../oci/repositories.py', sha1='bd0ac0fb906f679a660c87124da268370733fcc6'),
|
|
140
|
+
dict(path='../oci/tars.py', sha1='3ed00e97a494bd92c6a6149d22d51469bc0af384'),
|
|
141
|
+
dict(path='../../omlish/asyncs/asyncio/sockets.py', sha1='8d24dae988a30bb73f167a9ab62d4fc9eef4ad06'),
|
|
142
|
+
dict(path='../../omlish/asyncs/asyncio/timeouts.py', sha1='4d31b02b3c39b8f2fa7e94db36552fde6942e36a'),
|
|
143
|
+
dict(path='../../omlish/http/handlers.py', sha1='40629060bac22ea5e94b720b57001861a4ec9031'),
|
|
144
|
+
dict(path='../../omlish/lite/inject.py', sha1='6f097e3170019a34ff6834d36fcc9cbeed3a7ab4'),
|
|
145
|
+
dict(path='../../omlish/logs/contexts.py', sha1='7456964ade9ac66460e9ade4e242dbdc24b39501'),
|
|
146
|
+
dict(path='../../omlish/logs/standard.py', sha1='818b674f7d15012f25b79f52f6e8e7368b633038'),
|
|
147
|
+
dict(path='../../omlish/logs/utils.py', sha1='8430cddbb7de34afb2793ab8a0cc6fbee47fef2c'),
|
|
148
|
+
dict(path='../../omlish/sockets/server/handlers.py', sha1='6f9adca9fa04774a28a488a4e2a11bb4492c71d0'),
|
|
149
|
+
dict(path='../../omlish/subprocesses/run.py', sha1='8200e48f0c49d164df3503cd0143038d0c4d30aa'),
|
|
150
|
+
dict(path='../../omlish/subprocesses/wrap.py', sha1='8a9b7d2255481fae15c05f5624b0cdc0766f4b3f'),
|
|
151
|
+
dict(path='../dataserver/handlers.py', sha1='f624715f2500087226ec3374315cc8a1ea47a29b'),
|
|
152
|
+
dict(path='../dataserver/routes.py', sha1='0186bb2e84ff4d5c05af2a57c61f6fd605eba790'),
|
|
153
|
+
dict(path='../oci/media.py', sha1='a20324c5b0661c9a9a7679406d019ab3ba4acd98'),
|
|
154
|
+
dict(path='../oci/pack/packing.py', sha1='7585c3dea6b8a62b6ca63fe78968497db915ea57'),
|
|
155
|
+
dict(path='../../omlish/http/coro/server/server.py', sha1='c0a980afa8346dbc20570acddb2b3b579bfc1ce0'),
|
|
156
|
+
dict(path='../../omlish/logs/base.py', sha1='a376460b11b9dc0555fd4ead5437af62c2109a4b'),
|
|
157
|
+
dict(path='../../omlish/logs/std/records.py', sha1='8bbf6ef9eccb3a012c6ca416ddf3969450fd8fc9'),
|
|
158
|
+
dict(path='../../omlish/secrets/tempssl.py', sha1='360d4cd98483357bcf013e156dafd92fd37ed220'),
|
|
159
|
+
dict(path='../../omlish/sockets/server/server.py', sha1='a93a74f6beb38d69e0fb9047c932f2a95aa37eca'),
|
|
160
|
+
dict(path='../../omlish/sockets/server/ssl.py', sha1='790dfd208f4d267c826d491d4eb5deeda5ebdddc'),
|
|
161
|
+
dict(path='../../omlish/sockets/server/threading.py', sha1='0ba3c7a3d15781326610b12feef94e53903d0ce9'),
|
|
162
|
+
dict(path='../../omlish/subprocesses/base.py', sha1='cb9f668be5422fecb27222caabb67daac6c1bab9'),
|
|
163
|
+
dict(path='docker/cacheserved/manifests.py', sha1='80a65d08319d152f0bc6f893351e23368b3de93b'),
|
|
164
|
+
dict(path='../dataserver/server.py', sha1='e1ba8ca6f85458a64ede4ca07836aa103246132a'),
|
|
165
|
+
dict(path='../oci/building.py', sha1='b4fea06c03ba02d3ecfc6d10d955dc76f263846a'),
|
|
166
|
+
dict(path='../oci/loading.py', sha1='64d806ffad8d24087ccc29f759f672e6d795bee2'),
|
|
167
|
+
dict(path='../../omlish/http/coro/server/sockets.py', sha1='40ef4aa43f94f1a1a2a431a012cb961f25905ff4'),
|
|
168
|
+
dict(path='../../omlish/logs/std/loggers.py', sha1='daa35bdc4adea5006e442688017f0de3392579b7'),
|
|
169
|
+
dict(path='../../omlish/subprocesses/asyncs.py', sha1='bba44d524c24c6ac73168aee6343488414e5bf48'),
|
|
170
|
+
dict(path='../../omlish/subprocesses/sync.py', sha1='8434919eba4da67825773d56918fdc0cb2f1883b'),
|
|
171
|
+
dict(path='requirements.py', sha1='c370a65958a00412e00608a0e1f12795e276aee1'),
|
|
172
|
+
dict(path='../dataserver/http.py', sha1='f85ca91015bac434281326ef7885babd9d6d834c'),
|
|
173
|
+
dict(path='../oci/dataserver.py', sha1='dd147b56282b054cef264556a0ff3b3d1719bcee'),
|
|
174
|
+
dict(path='../../omlish/asyncs/asyncio/subprocesses.py', sha1='b6b5f9ae3fd0b9c83593bad2e04a08f726e5904d'),
|
|
175
|
+
dict(path='../../omlish/http/coro/server/simple.py', sha1='2332079fe29993123c68d7dbc266b47cd44cd6a6'),
|
|
176
|
+
dict(path='../../omlish/logs/modules.py', sha1='99e73cde6872fd5eda6af3dbf0fc9322bdeb641a'),
|
|
177
|
+
dict(path='cache.py', sha1='9353e5c3b73bed47258680fd15ac49417113f0ca'),
|
|
178
|
+
dict(path='compose.py', sha1='d2bec1385701979c7ff9913456b72d8c7b31f70b'),
|
|
179
|
+
dict(path='docker/cmds.py', sha1='5528c384f68f9003732bfaf6be302e84747909dd'),
|
|
180
|
+
dict(path='docker/dataserver.py', sha1='949e561ab756846425a39c05964c0fb256ae61db'),
|
|
181
|
+
dict(path='../../omlish/lite/timing.py', sha1='af5022f5a508939f1b433ed0514ede340fd0d672'),
|
|
182
|
+
dict(path='docker/cache.py', sha1='07a9e3d00bdd60f1a0a9b55aca12430fa1b4e3d9'),
|
|
183
|
+
dict(path='docker/repositories.py', sha1='e4bfc0e91c3bf20259895ce7c95a1eb3f6507518'),
|
|
184
|
+
dict(path='github/api/clients.py', sha1='8ddc0f5ccf718f1b530f4a965f0cc56b68a6a2a8'),
|
|
185
|
+
dict(path='github/api/v2/azure.py', sha1='19052e8e2babb8b2953ec10e6b9dcee97c21419a'),
|
|
186
|
+
dict(path='../oci/pack/repositories.py', sha1='e9bf6fa8bdaae2031dd0967d07a56c93a2e099b6'),
|
|
187
|
+
dict(path='docker/buildcaching.py', sha1='7b2633d5b8dac6aab01dd459e273cb370c5b11c8'),
|
|
188
|
+
dict(path='docker/cacheserved/cache.py', sha1='69732c658dba7ccf260e784132ff0c60192e3c69'),
|
|
189
|
+
dict(path='docker/imagepulling.py', sha1='d6b1ca1ecb9aa5c593a25e6deb78e942c75ebcb4'),
|
|
190
|
+
dict(path='github/api/v1/client.py', sha1='6ddd600cd8a7ff72a6a3408ded14240bafab6944'),
|
|
191
|
+
dict(path='github/api/v2/client.py', sha1='e28f27c07011487d5a3f4ae32fdfa1a857d02459'),
|
|
192
|
+
dict(path='ci.py', sha1='87b82e2bd86aa886764f1e0067251b056e359650'),
|
|
193
|
+
dict(path='docker/inject.py', sha1='69acac65fae413cb58c1f9aa739d2cc1c3ffa09d'),
|
|
194
|
+
dict(path='github/cache.py', sha1='d91f9c87d167574e94c99817e6c3a0f75925dfb9'),
|
|
195
|
+
dict(path='github/cli.py', sha1='6d14b0eb4ca5f606ad2821b63b9707ce57f50406'),
|
|
196
|
+
dict(path='github/inject.py', sha1='99c0dd7c55767e7c49f70b7edac25da67f718b2e'),
|
|
197
|
+
dict(path='inject.py', sha1='e86b16d79a113a4f387e68ed0db1d067bcada93a'),
|
|
198
|
+
dict(path='cli.py', sha1='49bcd482bd814ba436237099b4bdb62f77d6c054'),
|
|
199
|
+
],
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
|
|
86
203
|
########################################
|
|
87
204
|
|
|
88
205
|
|
|
@@ -345,6 +462,8 @@ async def asyncio_wait_concurrent(
|
|
|
345
462
|
if isinstance(concurrency, asyncio.Semaphore):
|
|
346
463
|
semaphore = concurrency
|
|
347
464
|
elif isinstance(concurrency, int):
|
|
465
|
+
if concurrency < 1:
|
|
466
|
+
raise ValueError(f'Concurrency must be >= 1, got {concurrency}')
|
|
348
467
|
semaphore = asyncio.Semaphore(concurrency)
|
|
349
468
|
else:
|
|
350
469
|
raise TypeError(concurrency)
|
|
@@ -508,25 +627,49 @@ def is_abstract_method(obj: ta.Any) -> bool:
|
|
|
508
627
|
return bool(getattr(obj, _IS_ABSTRACT_METHOD_ATTR, False))
|
|
509
628
|
|
|
510
629
|
|
|
511
|
-
def
|
|
630
|
+
def compute_abstract_methods(cls: type) -> ta.FrozenSet[str]:
|
|
631
|
+
# ~> https://github.com/python/cpython/blob/f3476c6507381ca860eec0989f53647b13517423/Modules/_abc.c#L358
|
|
632
|
+
|
|
633
|
+
# Stage 1: direct abstract methods
|
|
634
|
+
|
|
635
|
+
abstracts = {
|
|
636
|
+
a
|
|
637
|
+
# Get items as a list to avoid mutation issues during iteration
|
|
638
|
+
for a, v in list(cls.__dict__.items())
|
|
639
|
+
if is_abstract_method(v)
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
# Stage 2: inherited abstract methods
|
|
643
|
+
|
|
644
|
+
for base in cls.__bases__:
|
|
645
|
+
# Get __abstractmethods__ from base if it exists
|
|
646
|
+
if (base_abstracts := getattr(base, _ABSTRACT_METHODS_ATTR, None)) is None:
|
|
647
|
+
continue
|
|
648
|
+
|
|
649
|
+
# Iterate over abstract methods in base
|
|
650
|
+
for key in base_abstracts:
|
|
651
|
+
# Check if this class has an attribute with this name
|
|
652
|
+
try:
|
|
653
|
+
value = getattr(cls, key)
|
|
654
|
+
except AttributeError:
|
|
655
|
+
# Attribute not found in this class, skip
|
|
656
|
+
continue
|
|
657
|
+
|
|
658
|
+
# Check if it's still abstract
|
|
659
|
+
if is_abstract_method(value):
|
|
660
|
+
abstracts.add(key)
|
|
661
|
+
|
|
662
|
+
return frozenset(abstracts)
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
def update_abstracts(cls: ta.Type[T], *, force: bool = False) -> ta.Type[T]:
|
|
512
666
|
if not force and not hasattr(cls, _ABSTRACT_METHODS_ATTR):
|
|
513
667
|
# Per stdlib: We check for __abstractmethods__ here because cls might by a C implementation or a python
|
|
514
668
|
# implementation (especially during testing), and we want to handle both cases.
|
|
515
669
|
return cls
|
|
516
670
|
|
|
517
|
-
abstracts
|
|
518
|
-
|
|
519
|
-
for scls in cls.__bases__:
|
|
520
|
-
for name in getattr(scls, _ABSTRACT_METHODS_ATTR, ()):
|
|
521
|
-
value = getattr(cls, name, None)
|
|
522
|
-
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
|
523
|
-
abstracts.add(name)
|
|
524
|
-
|
|
525
|
-
for name, value in cls.__dict__.items():
|
|
526
|
-
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
|
527
|
-
abstracts.add(name)
|
|
528
|
-
|
|
529
|
-
setattr(cls, _ABSTRACT_METHODS_ATTR, frozenset(abstracts))
|
|
671
|
+
abstracts = compute_abstract_methods(cls)
|
|
672
|
+
setattr(cls, _ABSTRACT_METHODS_ATTR, abstracts)
|
|
530
673
|
return cls
|
|
531
674
|
|
|
532
675
|
|
|
@@ -580,23 +723,26 @@ class Abstract:
|
|
|
580
723
|
super().__init_subclass__(**kwargs)
|
|
581
724
|
|
|
582
725
|
if not (Abstract in cls.__bases__ or abc.ABC in cls.__bases__):
|
|
583
|
-
ams
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
726
|
+
if ams := compute_abstract_methods(cls):
|
|
727
|
+
amd = {
|
|
728
|
+
a: mcls
|
|
729
|
+
for mcls in cls.__mro__[::-1]
|
|
730
|
+
for a in ams
|
|
731
|
+
if a in mcls.__dict__
|
|
732
|
+
}
|
|
589
733
|
|
|
590
|
-
if ams:
|
|
591
734
|
raise AbstractTypeError(
|
|
592
735
|
f'Cannot subclass abstract class {cls.__name__} with abstract methods: ' +
|
|
593
736
|
', '.join(sorted([
|
|
594
737
|
'.'.join([
|
|
595
|
-
*([
|
|
596
|
-
|
|
738
|
+
*([
|
|
739
|
+
*([m] if (m := getattr(c, '__module__')) else []),
|
|
740
|
+
getattr(c, '__qualname__', getattr(c, '__name__')),
|
|
741
|
+
] if c is not None else '?'),
|
|
597
742
|
a,
|
|
598
743
|
])
|
|
599
|
-
for a
|
|
744
|
+
for a in ams
|
|
745
|
+
for c in [amd.get(a)]
|
|
600
746
|
])),
|
|
601
747
|
)
|
|
602
748
|
|
|
@@ -670,6 +816,62 @@ def async_cached_nullary(fn): # ta.Callable[..., T]) -> ta.Callable[..., T]:
|
|
|
670
816
|
return _AsyncCachedNullary(fn)
|
|
671
817
|
|
|
672
818
|
|
|
819
|
+
##
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
cached_property = functools.cached_property
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
class _cached_property: # noqa
|
|
826
|
+
"""Backported to pick up https://github.com/python/cpython/commit/056dfc71dce15f81887f0bd6da09d6099d71f979 ."""
|
|
827
|
+
|
|
828
|
+
def __init__(self, func):
|
|
829
|
+
self.func = func
|
|
830
|
+
self.attrname = None # noqa
|
|
831
|
+
self.__doc__ = func.__doc__
|
|
832
|
+
self.__module__ = func.__module__
|
|
833
|
+
|
|
834
|
+
_NOT_FOUND = object()
|
|
835
|
+
|
|
836
|
+
def __set_name__(self, owner, name):
|
|
837
|
+
if self.attrname is None:
|
|
838
|
+
self.attrname = name # noqa
|
|
839
|
+
elif name != self.attrname:
|
|
840
|
+
raise TypeError(
|
|
841
|
+
f'Cannot assign the same cached_property to two different names ({self.attrname!r} and {name!r}).',
|
|
842
|
+
)
|
|
843
|
+
|
|
844
|
+
def __get__(self, instance, owner=None):
|
|
845
|
+
if instance is None:
|
|
846
|
+
return self
|
|
847
|
+
if self.attrname is None:
|
|
848
|
+
raise TypeError('Cannot use cached_property instance without calling __set_name__ on it.')
|
|
849
|
+
|
|
850
|
+
try:
|
|
851
|
+
cache = instance.__dict__
|
|
852
|
+
except AttributeError: # not all objects have __dict__ (e.g. class defines slots)
|
|
853
|
+
raise TypeError(
|
|
854
|
+
f"No '__dict__' attribute on {type(instance).__name__!r} instance to cache {self.attrname!r} property.",
|
|
855
|
+
) from None
|
|
856
|
+
|
|
857
|
+
val = cache.get(self.attrname, self._NOT_FOUND)
|
|
858
|
+
|
|
859
|
+
if val is self._NOT_FOUND:
|
|
860
|
+
val = self.func(instance)
|
|
861
|
+
try:
|
|
862
|
+
cache[self.attrname] = val
|
|
863
|
+
except TypeError:
|
|
864
|
+
raise TypeError(
|
|
865
|
+
f"The '__dict__' attribute on {type(instance).__name__!r} instance does not support item "
|
|
866
|
+
f"assignment for caching {self.attrname!r} property.",
|
|
867
|
+
) from None
|
|
868
|
+
|
|
869
|
+
return val
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
globals()['cached_property'] = _cached_property
|
|
873
|
+
|
|
874
|
+
|
|
673
875
|
########################################
|
|
674
876
|
# ../../../omlish/lite/check.py
|
|
675
877
|
"""
|
|
@@ -1209,7 +1411,7 @@ class ExitStacked:
|
|
|
1209
1411
|
es.__enter__()
|
|
1210
1412
|
try:
|
|
1211
1413
|
self._enter_contexts()
|
|
1212
|
-
except
|
|
1414
|
+
except BaseException: # noqa
|
|
1213
1415
|
es.__exit__(*sys.exc_info())
|
|
1214
1416
|
raise
|
|
1215
1417
|
return self
|
|
@@ -1220,7 +1422,7 @@ class ExitStacked:
|
|
|
1220
1422
|
return None
|
|
1221
1423
|
try:
|
|
1222
1424
|
self._exit_contexts()
|
|
1223
|
-
except
|
|
1425
|
+
except BaseException: # noqa
|
|
1224
1426
|
es.__exit__(*sys.exc_info())
|
|
1225
1427
|
raise
|
|
1226
1428
|
return es.__exit__(exc_type, exc_val, exc_tb)
|
|
@@ -1268,7 +1470,7 @@ class AsyncExitStacked:
|
|
|
1268
1470
|
await es.__aenter__()
|
|
1269
1471
|
try:
|
|
1270
1472
|
await self._async_enter_contexts()
|
|
1271
|
-
except
|
|
1473
|
+
except BaseException: # noqa
|
|
1272
1474
|
await es.__aexit__(*sys.exc_info())
|
|
1273
1475
|
raise
|
|
1274
1476
|
return self
|
|
@@ -1279,7 +1481,7 @@ class AsyncExitStacked:
|
|
|
1279
1481
|
return None
|
|
1280
1482
|
try:
|
|
1281
1483
|
await self._async_exit_contexts()
|
|
1282
|
-
except
|
|
1484
|
+
except BaseException: # noqa
|
|
1283
1485
|
await es.__aexit__(*sys.exc_info())
|
|
1284
1486
|
raise
|
|
1285
1487
|
return await es.__aexit__(exc_type, exc_val, exc_tb)
|
|
@@ -1366,6 +1568,17 @@ aclosing = AsyncClosingManager
|
|
|
1366
1568
|
##
|
|
1367
1569
|
|
|
1368
1570
|
|
|
1571
|
+
def dataclass_shallow_astuple(o: ta.Any) -> ta.Tuple[ta.Any, ...]:
|
|
1572
|
+
return tuple(getattr(o, f.name) for f in dc.fields(o))
|
|
1573
|
+
|
|
1574
|
+
|
|
1575
|
+
def dataclass_shallow_asdict(o: ta.Any) -> ta.Dict[str, ta.Any]:
|
|
1576
|
+
return {f.name: getattr(o, f.name) for f in dc.fields(o)}
|
|
1577
|
+
|
|
1578
|
+
|
|
1579
|
+
##
|
|
1580
|
+
|
|
1581
|
+
|
|
1369
1582
|
def is_immediate_dataclass(cls: type) -> bool:
|
|
1370
1583
|
if not isinstance(cls, type):
|
|
1371
1584
|
raise TypeError(cls)
|
|
@@ -1448,6 +1661,36 @@ def dataclass_repr_omit_falsey(obj: ta.Any) -> str:
|
|
|
1448
1661
|
##
|
|
1449
1662
|
|
|
1450
1663
|
|
|
1664
|
+
def dataclass_descriptor_method(*bind_attrs: str, bind_owner: bool = False) -> ta.Callable:
|
|
1665
|
+
if not bind_attrs:
|
|
1666
|
+
def __get__(self, instance, owner=None): # noqa
|
|
1667
|
+
return self
|
|
1668
|
+
|
|
1669
|
+
elif bind_owner:
|
|
1670
|
+
def __get__(self, instance, owner=None): # noqa
|
|
1671
|
+
# Guaranteed to return a new instance even with no attrs
|
|
1672
|
+
return dc.replace(self, **{
|
|
1673
|
+
a: v.__get__(instance, owner) if (v := getattr(self, a)) is not None else None
|
|
1674
|
+
for a in bind_attrs
|
|
1675
|
+
})
|
|
1676
|
+
|
|
1677
|
+
else:
|
|
1678
|
+
def __get__(self, instance, owner=None): # noqa
|
|
1679
|
+
if instance is None:
|
|
1680
|
+
return self
|
|
1681
|
+
|
|
1682
|
+
# Guaranteed to return a new instance even with no attrs
|
|
1683
|
+
return dc.replace(self, **{
|
|
1684
|
+
a: v.__get__(instance, owner) if (v := getattr(self, a)) is not None else None
|
|
1685
|
+
for a in bind_attrs
|
|
1686
|
+
})
|
|
1687
|
+
|
|
1688
|
+
return __get__
|
|
1689
|
+
|
|
1690
|
+
|
|
1691
|
+
##
|
|
1692
|
+
|
|
1693
|
+
|
|
1451
1694
|
def dataclass_kw_only_init():
|
|
1452
1695
|
def inner(cls):
|
|
1453
1696
|
if not isinstance(cls, type) and dc.is_dataclass(cls):
|
|
@@ -1511,6 +1754,20 @@ def dataclass_kw_only_init():
|
|
|
1511
1754
|
return inner
|
|
1512
1755
|
|
|
1513
1756
|
|
|
1757
|
+
##
|
|
1758
|
+
|
|
1759
|
+
|
|
1760
|
+
@dc.dataclass()
|
|
1761
|
+
class DataclassFieldRequiredError(Exception):
|
|
1762
|
+
name: str
|
|
1763
|
+
|
|
1764
|
+
|
|
1765
|
+
def dataclass_field_required(name: str) -> ta.Callable[[], ta.Any]:
|
|
1766
|
+
def inner() -> ta.NoReturn:
|
|
1767
|
+
raise DataclassFieldRequiredError(name)
|
|
1768
|
+
return inner
|
|
1769
|
+
|
|
1770
|
+
|
|
1514
1771
|
########################################
|
|
1515
1772
|
# ../../../omlish/lite/json.py
|
|
1516
1773
|
|
|
@@ -2547,6 +2804,7 @@ class GithubCacheServiceV2:
|
|
|
2547
2804
|
class CreateCacheEntryResponse:
|
|
2548
2805
|
ok: bool
|
|
2549
2806
|
signed_upload_url: str
|
|
2807
|
+
message: ta.Optional[str] = None
|
|
2550
2808
|
|
|
2551
2809
|
CREATE_CACHE_ENTRY_METHOD: Method[
|
|
2552
2810
|
CreateCacheEntryRequest,
|
|
@@ -2570,6 +2828,7 @@ class GithubCacheServiceV2:
|
|
|
2570
2828
|
class FinalizeCacheEntryUploadResponse:
|
|
2571
2829
|
ok: bool
|
|
2572
2830
|
entry_id: str
|
|
2831
|
+
message: ta.Optional[str] = None
|
|
2573
2832
|
|
|
2574
2833
|
FINALIZE_CACHE_ENTRY_METHOD: Method[
|
|
2575
2834
|
FinalizeCacheEntryUploadRequest,
|
|
@@ -2966,6 +3225,7 @@ TODO:
|
|
|
2966
3225
|
- pre-run, post-run hooks
|
|
2967
3226
|
- exitstack?
|
|
2968
3227
|
- suggestion - difflib.get_close_matches
|
|
3228
|
+
- add_argument_group - group kw on ArgparseKwarg?
|
|
2969
3229
|
"""
|
|
2970
3230
|
|
|
2971
3231
|
|
|
@@ -2976,6 +3236,7 @@ TODO:
|
|
|
2976
3236
|
class ArgparseArg:
|
|
2977
3237
|
args: ta.Sequence[ta.Any]
|
|
2978
3238
|
kwargs: ta.Mapping[str, ta.Any]
|
|
3239
|
+
group: ta.Optional[str] = None
|
|
2979
3240
|
dest: ta.Optional[str] = None
|
|
2980
3241
|
|
|
2981
3242
|
def __get__(self, instance, owner=None):
|
|
@@ -2985,7 +3246,11 @@ class ArgparseArg:
|
|
|
2985
3246
|
|
|
2986
3247
|
|
|
2987
3248
|
def argparse_arg(*args, **kwargs) -> ArgparseArg:
|
|
2988
|
-
return ArgparseArg(
|
|
3249
|
+
return ArgparseArg(
|
|
3250
|
+
args=args,
|
|
3251
|
+
group=kwargs.pop('group', None),
|
|
3252
|
+
kwargs=kwargs,
|
|
3253
|
+
)
|
|
2989
3254
|
|
|
2990
3255
|
|
|
2991
3256
|
def argparse_arg_(*args, **kwargs) -> ta.Any:
|
|
@@ -3155,6 +3420,10 @@ class ArgparseCli:
|
|
|
3155
3420
|
subparser.set_defaults(_cmd=obj)
|
|
3156
3421
|
|
|
3157
3422
|
elif isinstance(obj, ArgparseArg):
|
|
3423
|
+
if obj.group is not None:
|
|
3424
|
+
# FIXME: add_argument_group
|
|
3425
|
+
raise NotImplementedError
|
|
3426
|
+
|
|
3158
3427
|
if att in anns:
|
|
3159
3428
|
ann_kwargs = _get_argparse_arg_ann_kwargs(anns[att])
|
|
3160
3429
|
obj.kwargs = {**ann_kwargs, **obj.kwargs}
|
|
@@ -3200,7 +3469,7 @@ class ArgparseCli:
|
|
|
3200
3469
|
|
|
3201
3470
|
if self._unknown_args and not (cmd is not None and cmd.accepts_unknown):
|
|
3202
3471
|
msg = f'unrecognized arguments: {" ".join(self._unknown_args)}'
|
|
3203
|
-
if (parser := self.get_parser()).exit_on_error:
|
|
3472
|
+
if (parser := self.get_parser()).exit_on_error: # noqa
|
|
3204
3473
|
parser.error(msg)
|
|
3205
3474
|
else:
|
|
3206
3475
|
raise argparse.ArgumentError(None, msg)
|
|
@@ -3220,7 +3489,10 @@ class ArgparseCli:
|
|
|
3220
3489
|
return fn()
|
|
3221
3490
|
|
|
3222
3491
|
def cli_run_and_exit(self) -> ta.NoReturn:
|
|
3223
|
-
|
|
3492
|
+
rc = self.cli_run()
|
|
3493
|
+
if not isinstance(rc, int):
|
|
3494
|
+
rc = 0
|
|
3495
|
+
raise SystemExit(rc)
|
|
3224
3496
|
|
|
3225
3497
|
def __call__(self, *, exit: bool = False) -> ta.Optional[int]: # noqa
|
|
3226
3498
|
if exit:
|
|
@@ -3252,6 +3524,72 @@ class ArgparseCli:
|
|
|
3252
3524
|
return fn()
|
|
3253
3525
|
|
|
3254
3526
|
|
|
3527
|
+
########################################
|
|
3528
|
+
# ../../../omlish/http/coro/io.py
|
|
3529
|
+
|
|
3530
|
+
|
|
3531
|
+
##
|
|
3532
|
+
|
|
3533
|
+
|
|
3534
|
+
class CoroHttpIo:
|
|
3535
|
+
def __new__(cls, *args, **kwargs): # noqa
|
|
3536
|
+
raise TypeError
|
|
3537
|
+
|
|
3538
|
+
def __init_subclass__(cls, **kwargs): # noqa
|
|
3539
|
+
raise TypeError
|
|
3540
|
+
|
|
3541
|
+
#
|
|
3542
|
+
|
|
3543
|
+
MAX_LINE: ta.ClassVar[int] = 65536
|
|
3544
|
+
|
|
3545
|
+
#
|
|
3546
|
+
|
|
3547
|
+
class Io(Abstract):
|
|
3548
|
+
pass
|
|
3549
|
+
|
|
3550
|
+
#
|
|
3551
|
+
|
|
3552
|
+
class AnyLogIo(Io, Abstract):
|
|
3553
|
+
pass
|
|
3554
|
+
|
|
3555
|
+
#
|
|
3556
|
+
|
|
3557
|
+
@dc.dataclass(frozen=True)
|
|
3558
|
+
class ConnectIo(Io):
|
|
3559
|
+
args: ta.Tuple[ta.Any, ...]
|
|
3560
|
+
kwargs: ta.Optional[ta.Dict[str, ta.Any]] = None
|
|
3561
|
+
|
|
3562
|
+
server_hostname: ta.Optional[str] = None
|
|
3563
|
+
|
|
3564
|
+
#
|
|
3565
|
+
|
|
3566
|
+
class CloseIo(Io):
|
|
3567
|
+
pass
|
|
3568
|
+
|
|
3569
|
+
#
|
|
3570
|
+
|
|
3571
|
+
class AnyReadIo(Io): # noqa
|
|
3572
|
+
pass
|
|
3573
|
+
|
|
3574
|
+
@dc.dataclass(frozen=True)
|
|
3575
|
+
class ReadIo(AnyReadIo):
|
|
3576
|
+
sz: ta.Optional[int]
|
|
3577
|
+
|
|
3578
|
+
@dc.dataclass(frozen=True)
|
|
3579
|
+
class ReadLineIo(AnyReadIo):
|
|
3580
|
+
sz: int
|
|
3581
|
+
|
|
3582
|
+
@dc.dataclass(frozen=True)
|
|
3583
|
+
class PeekIo(AnyReadIo):
|
|
3584
|
+
sz: int
|
|
3585
|
+
|
|
3586
|
+
#
|
|
3587
|
+
|
|
3588
|
+
@dc.dataclass(frozen=True)
|
|
3589
|
+
class WriteIo(Io):
|
|
3590
|
+
data: bytes
|
|
3591
|
+
|
|
3592
|
+
|
|
3255
3593
|
########################################
|
|
3256
3594
|
# ../../../omlish/http/parsing.py
|
|
3257
3595
|
# PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
|
@@ -4585,8 +4923,6 @@ class _JustMaybe(_Maybe[T]):
|
|
|
4585
4923
|
__slots__ = ('_v', '_hash')
|
|
4586
4924
|
|
|
4587
4925
|
def __init__(self, v: T) -> None:
|
|
4588
|
-
super().__init__()
|
|
4589
|
-
|
|
4590
4926
|
self._v = v
|
|
4591
4927
|
|
|
4592
4928
|
@property
|
|
@@ -4644,6 +4980,13 @@ class _EmptyMaybe(_Maybe[T]):
|
|
|
4644
4980
|
Maybe._empty = _EmptyMaybe() # noqa
|
|
4645
4981
|
|
|
4646
4982
|
|
|
4983
|
+
##
|
|
4984
|
+
|
|
4985
|
+
|
|
4986
|
+
setattr(Maybe, 'just', _JustMaybe) # noqa
|
|
4987
|
+
setattr(Maybe, 'empty', functools.partial(operator.attrgetter('_empty'), Maybe))
|
|
4988
|
+
|
|
4989
|
+
|
|
4647
4990
|
########################################
|
|
4648
4991
|
# ../../../omlish/lite/runtime.py
|
|
4649
4992
|
|
|
@@ -7925,7 +8268,7 @@ def configure_standard_logging(
|
|
|
7925
8268
|
##
|
|
7926
8269
|
|
|
7927
8270
|
|
|
7928
|
-
def
|
|
8271
|
+
def exception_logging(log): # noqa
|
|
7929
8272
|
def outer(fn):
|
|
7930
8273
|
@functools.wraps(fn)
|
|
7931
8274
|
def inner(*args, **kwargs):
|
|
@@ -9245,48 +9588,21 @@ class CoroHttpServer:
|
|
|
9245
9588
|
|
|
9246
9589
|
#
|
|
9247
9590
|
|
|
9248
|
-
class Io(Abstract):
|
|
9249
|
-
pass
|
|
9250
|
-
|
|
9251
|
-
#
|
|
9252
|
-
|
|
9253
|
-
class AnyLogIo(Io):
|
|
9254
|
-
pass
|
|
9255
|
-
|
|
9256
9591
|
@dc.dataclass(frozen=True)
|
|
9257
|
-
class ParsedRequestLogIo(AnyLogIo):
|
|
9592
|
+
class ParsedRequestLogIo(CoroHttpIo.AnyLogIo):
|
|
9258
9593
|
request: ParsedHttpRequest
|
|
9259
9594
|
|
|
9260
9595
|
@dc.dataclass(frozen=True)
|
|
9261
|
-
class ErrorLogIo(AnyLogIo):
|
|
9596
|
+
class ErrorLogIo(CoroHttpIo.AnyLogIo):
|
|
9262
9597
|
error: 'CoroHttpServer.Error'
|
|
9263
9598
|
|
|
9264
9599
|
#
|
|
9265
9600
|
|
|
9266
|
-
class AnyReadIo(Io): # noqa
|
|
9267
|
-
pass
|
|
9268
|
-
|
|
9269
|
-
@dc.dataclass(frozen=True)
|
|
9270
|
-
class ReadIo(AnyReadIo):
|
|
9271
|
-
sz: int
|
|
9272
|
-
|
|
9273
|
-
@dc.dataclass(frozen=True)
|
|
9274
|
-
class ReadLineIo(AnyReadIo):
|
|
9275
|
-
sz: int
|
|
9276
|
-
|
|
9277
|
-
#
|
|
9278
|
-
|
|
9279
|
-
@dc.dataclass(frozen=True)
|
|
9280
|
-
class WriteIo(Io):
|
|
9281
|
-
data: bytes
|
|
9282
|
-
|
|
9283
|
-
#
|
|
9284
|
-
|
|
9285
9601
|
@dc.dataclass(frozen=True)
|
|
9286
9602
|
class CoroHandleResult:
|
|
9287
9603
|
close_reason: ta.Literal['response', 'internal', None] = None
|
|
9288
9604
|
|
|
9289
|
-
def coro_handle(self) -> ta.Generator[Io, ta.Optional[bytes], CoroHandleResult]:
|
|
9605
|
+
def coro_handle(self) -> ta.Generator[CoroHttpIo.Io, ta.Optional[bytes], CoroHandleResult]:
|
|
9290
9606
|
return self._coro_run_handler(self._coro_handle_one())
|
|
9291
9607
|
|
|
9292
9608
|
class Close(Exception): # noqa
|
|
@@ -9295,20 +9611,20 @@ class CoroHttpServer:
|
|
|
9295
9611
|
def _coro_run_handler(
|
|
9296
9612
|
self,
|
|
9297
9613
|
gen: ta.Generator[
|
|
9298
|
-
ta.Union[AnyLogIo, AnyReadIo, _Response],
|
|
9614
|
+
ta.Union[CoroHttpIo.AnyLogIo, CoroHttpIo.AnyReadIo, _Response],
|
|
9299
9615
|
ta.Optional[bytes],
|
|
9300
9616
|
None,
|
|
9301
9617
|
],
|
|
9302
|
-
) -> ta.Generator[Io, ta.Optional[bytes], CoroHandleResult]:
|
|
9618
|
+
) -> ta.Generator[CoroHttpIo.Io, ta.Optional[bytes], CoroHandleResult]:
|
|
9303
9619
|
i: ta.Optional[bytes]
|
|
9304
9620
|
o: ta.Any = next(gen)
|
|
9305
9621
|
while True:
|
|
9306
9622
|
try:
|
|
9307
|
-
if isinstance(o,
|
|
9623
|
+
if isinstance(o, CoroHttpIo.AnyLogIo):
|
|
9308
9624
|
i = None
|
|
9309
9625
|
yield o
|
|
9310
9626
|
|
|
9311
|
-
elif isinstance(o,
|
|
9627
|
+
elif isinstance(o, CoroHttpIo.AnyReadIo):
|
|
9312
9628
|
i = check.isinstance((yield o), bytes)
|
|
9313
9629
|
|
|
9314
9630
|
elif isinstance(o, self._Response):
|
|
@@ -9316,10 +9632,10 @@ class CoroHttpServer:
|
|
|
9316
9632
|
|
|
9317
9633
|
r = self._preprocess_response(o)
|
|
9318
9634
|
hb = self._build_response_head_bytes(r)
|
|
9319
|
-
check.none((yield
|
|
9635
|
+
check.none((yield CoroHttpIo.WriteIo(hb)))
|
|
9320
9636
|
|
|
9321
9637
|
for b in self._yield_response_data(r):
|
|
9322
|
-
yield
|
|
9638
|
+
yield CoroHttpIo.WriteIo(b)
|
|
9323
9639
|
|
|
9324
9640
|
o.close()
|
|
9325
9641
|
if o.close_connection:
|
|
@@ -9347,7 +9663,7 @@ class CoroHttpServer:
|
|
|
9347
9663
|
raise
|
|
9348
9664
|
|
|
9349
9665
|
def _coro_handle_one(self) -> ta.Generator[
|
|
9350
|
-
ta.Union[AnyLogIo, AnyReadIo, _Response],
|
|
9666
|
+
ta.Union[CoroHttpIo.AnyLogIo, CoroHttpIo.AnyReadIo, _Response],
|
|
9351
9667
|
ta.Optional[bytes],
|
|
9352
9668
|
None,
|
|
9353
9669
|
]:
|
|
@@ -9357,7 +9673,7 @@ class CoroHttpServer:
|
|
|
9357
9673
|
sz = next(gen)
|
|
9358
9674
|
while True:
|
|
9359
9675
|
try:
|
|
9360
|
-
line = check.isinstance((yield
|
|
9676
|
+
line = check.isinstance((yield CoroHttpIo.ReadLineIo(sz)), bytes)
|
|
9361
9677
|
sz = gen.send(line)
|
|
9362
9678
|
except StopIteration as e:
|
|
9363
9679
|
parsed = e.value
|
|
@@ -9396,7 +9712,7 @@ class CoroHttpServer:
|
|
|
9396
9712
|
|
|
9397
9713
|
request_data: ta.Optional[bytes]
|
|
9398
9714
|
if (cl := parsed.headers.get('Content-Length')) is not None:
|
|
9399
|
-
request_data = check.isinstance((yield
|
|
9715
|
+
request_data = check.isinstance((yield CoroHttpIo.ReadIo(int(cl))), bytes)
|
|
9400
9716
|
else:
|
|
9401
9717
|
request_data = None
|
|
9402
9718
|
|
|
@@ -10751,6 +11067,10 @@ class VerboseCalledProcessError(subprocess.CalledProcessError):
|
|
|
10751
11067
|
class BaseSubprocesses(Abstract):
|
|
10752
11068
|
DEFAULT_LOGGER: ta.ClassVar[ta.Optional[LoggerLike]] = None
|
|
10753
11069
|
|
|
11070
|
+
PIPE: ta.ClassVar[int] = subprocess.PIPE
|
|
11071
|
+
STDOUT: ta.ClassVar[int] = subprocess.STDOUT
|
|
11072
|
+
DEVNULL: ta.ClassVar[int] = subprocess.DEVNULL
|
|
11073
|
+
|
|
10754
11074
|
def __init__(
|
|
10755
11075
|
self,
|
|
10756
11076
|
*,
|
|
@@ -11441,7 +11761,7 @@ class CoroHttpServerSocketHandler(SocketHandler_):
|
|
|
11441
11761
|
server_factory: CoroHttpServerFactory,
|
|
11442
11762
|
*,
|
|
11443
11763
|
keep_alive: bool = False,
|
|
11444
|
-
log_handler: ta.Optional[ta.Callable[[CoroHttpServer,
|
|
11764
|
+
log_handler: ta.Optional[ta.Callable[[CoroHttpServer, CoroHttpIo.AnyLogIo], None]] = None,
|
|
11445
11765
|
) -> None:
|
|
11446
11766
|
super().__init__()
|
|
11447
11767
|
|
|
@@ -11470,18 +11790,18 @@ class CoroHttpServerSocketHandler(SocketHandler_):
|
|
|
11470
11790
|
|
|
11471
11791
|
o = next(gen)
|
|
11472
11792
|
while True:
|
|
11473
|
-
if isinstance(o,
|
|
11793
|
+
if isinstance(o, CoroHttpIo.AnyLogIo):
|
|
11474
11794
|
i = None
|
|
11475
11795
|
if self._log_handler is not None:
|
|
11476
11796
|
self._log_handler(server, o)
|
|
11477
11797
|
|
|
11478
|
-
elif isinstance(o,
|
|
11479
|
-
i = fp.r.read(o.sz)
|
|
11798
|
+
elif isinstance(o, CoroHttpIo.ReadIo):
|
|
11799
|
+
i = fp.r.read(check.not_none(o.sz))
|
|
11480
11800
|
|
|
11481
|
-
elif isinstance(o,
|
|
11801
|
+
elif isinstance(o, CoroHttpIo.ReadLineIo):
|
|
11482
11802
|
i = fp.r.readline(o.sz)
|
|
11483
11803
|
|
|
11484
|
-
elif isinstance(o,
|
|
11804
|
+
elif isinstance(o, CoroHttpIo.WriteIo):
|
|
11485
11805
|
i = None
|
|
11486
11806
|
fp.w.write(o.data)
|
|
11487
11807
|
fp.w.flush()
|
|
@@ -15374,7 +15694,7 @@ async def _async_main() -> ta.Optional[int]:
|
|
|
15374
15694
|
def _main() -> None:
|
|
15375
15695
|
configure_standard_logging('DEBUG')
|
|
15376
15696
|
|
|
15377
|
-
|
|
15697
|
+
raise SystemExit(rc if isinstance(rc := asyncio.run(_async_main()), int) else 0)
|
|
15378
15698
|
|
|
15379
15699
|
|
|
15380
15700
|
if __name__ == '__main__':
|