omdev 0.0.0.dev440__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 +17 -29
- 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/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 +1 -1
- 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 +398 -80
- omdev/scripts/interp.py +193 -35
- omdev/scripts/lib/inject.py +74 -27
- omdev/scripts/lib/logs.py +75 -27
- omdev/scripts/lib/marshal.py +67 -25
- omdev/scripts/pyproject.py +941 -90
- omdev/tools/git/cli.py +10 -0
- 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.dev440.dist-info → omdev-0.0.0.dev486.dist-info}/METADATA +11 -9
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev486.dist-info}/RECORD +119 -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.dev440.dist-info → omdev-0.0.0.dev486.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev486.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev486.dist-info}/licenses/LICENSE +0 -0
- {omdev-0.0.0.dev440.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
|
|
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
|
+
}
|
|
584
733
|
|
|
585
|
-
seen = set(cls.__dict__)
|
|
586
|
-
for b in cls.__bases__:
|
|
587
|
-
ams.update({a: b for a in set(getattr(b, _ABSTRACT_METHODS_ATTR, [])) - seen}) # noqa
|
|
588
|
-
seen.update(dir(b))
|
|
589
|
-
|
|
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
|
|
|
@@ -2968,6 +3225,7 @@ TODO:
|
|
|
2968
3225
|
- pre-run, post-run hooks
|
|
2969
3226
|
- exitstack?
|
|
2970
3227
|
- suggestion - difflib.get_close_matches
|
|
3228
|
+
- add_argument_group - group kw on ArgparseKwarg?
|
|
2971
3229
|
"""
|
|
2972
3230
|
|
|
2973
3231
|
|
|
@@ -2978,6 +3236,7 @@ TODO:
|
|
|
2978
3236
|
class ArgparseArg:
|
|
2979
3237
|
args: ta.Sequence[ta.Any]
|
|
2980
3238
|
kwargs: ta.Mapping[str, ta.Any]
|
|
3239
|
+
group: ta.Optional[str] = None
|
|
2981
3240
|
dest: ta.Optional[str] = None
|
|
2982
3241
|
|
|
2983
3242
|
def __get__(self, instance, owner=None):
|
|
@@ -2987,7 +3246,11 @@ class ArgparseArg:
|
|
|
2987
3246
|
|
|
2988
3247
|
|
|
2989
3248
|
def argparse_arg(*args, **kwargs) -> ArgparseArg:
|
|
2990
|
-
return ArgparseArg(
|
|
3249
|
+
return ArgparseArg(
|
|
3250
|
+
args=args,
|
|
3251
|
+
group=kwargs.pop('group', None),
|
|
3252
|
+
kwargs=kwargs,
|
|
3253
|
+
)
|
|
2991
3254
|
|
|
2992
3255
|
|
|
2993
3256
|
def argparse_arg_(*args, **kwargs) -> ta.Any:
|
|
@@ -3157,6 +3420,10 @@ class ArgparseCli:
|
|
|
3157
3420
|
subparser.set_defaults(_cmd=obj)
|
|
3158
3421
|
|
|
3159
3422
|
elif isinstance(obj, ArgparseArg):
|
|
3423
|
+
if obj.group is not None:
|
|
3424
|
+
# FIXME: add_argument_group
|
|
3425
|
+
raise NotImplementedError
|
|
3426
|
+
|
|
3160
3427
|
if att in anns:
|
|
3161
3428
|
ann_kwargs = _get_argparse_arg_ann_kwargs(anns[att])
|
|
3162
3429
|
obj.kwargs = {**ann_kwargs, **obj.kwargs}
|
|
@@ -3202,7 +3469,7 @@ class ArgparseCli:
|
|
|
3202
3469
|
|
|
3203
3470
|
if self._unknown_args and not (cmd is not None and cmd.accepts_unknown):
|
|
3204
3471
|
msg = f'unrecognized arguments: {" ".join(self._unknown_args)}'
|
|
3205
|
-
if (parser := self.get_parser()).exit_on_error:
|
|
3472
|
+
if (parser := self.get_parser()).exit_on_error: # noqa
|
|
3206
3473
|
parser.error(msg)
|
|
3207
3474
|
else:
|
|
3208
3475
|
raise argparse.ArgumentError(None, msg)
|
|
@@ -3222,7 +3489,10 @@ class ArgparseCli:
|
|
|
3222
3489
|
return fn()
|
|
3223
3490
|
|
|
3224
3491
|
def cli_run_and_exit(self) -> ta.NoReturn:
|
|
3225
|
-
|
|
3492
|
+
rc = self.cli_run()
|
|
3493
|
+
if not isinstance(rc, int):
|
|
3494
|
+
rc = 0
|
|
3495
|
+
raise SystemExit(rc)
|
|
3226
3496
|
|
|
3227
3497
|
def __call__(self, *, exit: bool = False) -> ta.Optional[int]: # noqa
|
|
3228
3498
|
if exit:
|
|
@@ -3254,6 +3524,72 @@ class ArgparseCli:
|
|
|
3254
3524
|
return fn()
|
|
3255
3525
|
|
|
3256
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
|
+
|
|
3257
3593
|
########################################
|
|
3258
3594
|
# ../../../omlish/http/parsing.py
|
|
3259
3595
|
# PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
|
@@ -4587,8 +4923,6 @@ class _JustMaybe(_Maybe[T]):
|
|
|
4587
4923
|
__slots__ = ('_v', '_hash')
|
|
4588
4924
|
|
|
4589
4925
|
def __init__(self, v: T) -> None:
|
|
4590
|
-
super().__init__()
|
|
4591
|
-
|
|
4592
4926
|
self._v = v
|
|
4593
4927
|
|
|
4594
4928
|
@property
|
|
@@ -4646,6 +4980,13 @@ class _EmptyMaybe(_Maybe[T]):
|
|
|
4646
4980
|
Maybe._empty = _EmptyMaybe() # noqa
|
|
4647
4981
|
|
|
4648
4982
|
|
|
4983
|
+
##
|
|
4984
|
+
|
|
4985
|
+
|
|
4986
|
+
setattr(Maybe, 'just', _JustMaybe) # noqa
|
|
4987
|
+
setattr(Maybe, 'empty', functools.partial(operator.attrgetter('_empty'), Maybe))
|
|
4988
|
+
|
|
4989
|
+
|
|
4649
4990
|
########################################
|
|
4650
4991
|
# ../../../omlish/lite/runtime.py
|
|
4651
4992
|
|
|
@@ -7927,7 +8268,7 @@ def configure_standard_logging(
|
|
|
7927
8268
|
##
|
|
7928
8269
|
|
|
7929
8270
|
|
|
7930
|
-
def
|
|
8271
|
+
def exception_logging(log): # noqa
|
|
7931
8272
|
def outer(fn):
|
|
7932
8273
|
@functools.wraps(fn)
|
|
7933
8274
|
def inner(*args, **kwargs):
|
|
@@ -9247,48 +9588,21 @@ class CoroHttpServer:
|
|
|
9247
9588
|
|
|
9248
9589
|
#
|
|
9249
9590
|
|
|
9250
|
-
class Io(Abstract):
|
|
9251
|
-
pass
|
|
9252
|
-
|
|
9253
|
-
#
|
|
9254
|
-
|
|
9255
|
-
class AnyLogIo(Io):
|
|
9256
|
-
pass
|
|
9257
|
-
|
|
9258
9591
|
@dc.dataclass(frozen=True)
|
|
9259
|
-
class ParsedRequestLogIo(AnyLogIo):
|
|
9592
|
+
class ParsedRequestLogIo(CoroHttpIo.AnyLogIo):
|
|
9260
9593
|
request: ParsedHttpRequest
|
|
9261
9594
|
|
|
9262
9595
|
@dc.dataclass(frozen=True)
|
|
9263
|
-
class ErrorLogIo(AnyLogIo):
|
|
9596
|
+
class ErrorLogIo(CoroHttpIo.AnyLogIo):
|
|
9264
9597
|
error: 'CoroHttpServer.Error'
|
|
9265
9598
|
|
|
9266
9599
|
#
|
|
9267
9600
|
|
|
9268
|
-
class AnyReadIo(Io): # noqa
|
|
9269
|
-
pass
|
|
9270
|
-
|
|
9271
|
-
@dc.dataclass(frozen=True)
|
|
9272
|
-
class ReadIo(AnyReadIo):
|
|
9273
|
-
sz: int
|
|
9274
|
-
|
|
9275
|
-
@dc.dataclass(frozen=True)
|
|
9276
|
-
class ReadLineIo(AnyReadIo):
|
|
9277
|
-
sz: int
|
|
9278
|
-
|
|
9279
|
-
#
|
|
9280
|
-
|
|
9281
|
-
@dc.dataclass(frozen=True)
|
|
9282
|
-
class WriteIo(Io):
|
|
9283
|
-
data: bytes
|
|
9284
|
-
|
|
9285
|
-
#
|
|
9286
|
-
|
|
9287
9601
|
@dc.dataclass(frozen=True)
|
|
9288
9602
|
class CoroHandleResult:
|
|
9289
9603
|
close_reason: ta.Literal['response', 'internal', None] = None
|
|
9290
9604
|
|
|
9291
|
-
def coro_handle(self) -> ta.Generator[Io, ta.Optional[bytes], CoroHandleResult]:
|
|
9605
|
+
def coro_handle(self) -> ta.Generator[CoroHttpIo.Io, ta.Optional[bytes], CoroHandleResult]:
|
|
9292
9606
|
return self._coro_run_handler(self._coro_handle_one())
|
|
9293
9607
|
|
|
9294
9608
|
class Close(Exception): # noqa
|
|
@@ -9297,20 +9611,20 @@ class CoroHttpServer:
|
|
|
9297
9611
|
def _coro_run_handler(
|
|
9298
9612
|
self,
|
|
9299
9613
|
gen: ta.Generator[
|
|
9300
|
-
ta.Union[AnyLogIo, AnyReadIo, _Response],
|
|
9614
|
+
ta.Union[CoroHttpIo.AnyLogIo, CoroHttpIo.AnyReadIo, _Response],
|
|
9301
9615
|
ta.Optional[bytes],
|
|
9302
9616
|
None,
|
|
9303
9617
|
],
|
|
9304
|
-
) -> ta.Generator[Io, ta.Optional[bytes], CoroHandleResult]:
|
|
9618
|
+
) -> ta.Generator[CoroHttpIo.Io, ta.Optional[bytes], CoroHandleResult]:
|
|
9305
9619
|
i: ta.Optional[bytes]
|
|
9306
9620
|
o: ta.Any = next(gen)
|
|
9307
9621
|
while True:
|
|
9308
9622
|
try:
|
|
9309
|
-
if isinstance(o,
|
|
9623
|
+
if isinstance(o, CoroHttpIo.AnyLogIo):
|
|
9310
9624
|
i = None
|
|
9311
9625
|
yield o
|
|
9312
9626
|
|
|
9313
|
-
elif isinstance(o,
|
|
9627
|
+
elif isinstance(o, CoroHttpIo.AnyReadIo):
|
|
9314
9628
|
i = check.isinstance((yield o), bytes)
|
|
9315
9629
|
|
|
9316
9630
|
elif isinstance(o, self._Response):
|
|
@@ -9318,10 +9632,10 @@ class CoroHttpServer:
|
|
|
9318
9632
|
|
|
9319
9633
|
r = self._preprocess_response(o)
|
|
9320
9634
|
hb = self._build_response_head_bytes(r)
|
|
9321
|
-
check.none((yield
|
|
9635
|
+
check.none((yield CoroHttpIo.WriteIo(hb)))
|
|
9322
9636
|
|
|
9323
9637
|
for b in self._yield_response_data(r):
|
|
9324
|
-
yield
|
|
9638
|
+
yield CoroHttpIo.WriteIo(b)
|
|
9325
9639
|
|
|
9326
9640
|
o.close()
|
|
9327
9641
|
if o.close_connection:
|
|
@@ -9349,7 +9663,7 @@ class CoroHttpServer:
|
|
|
9349
9663
|
raise
|
|
9350
9664
|
|
|
9351
9665
|
def _coro_handle_one(self) -> ta.Generator[
|
|
9352
|
-
ta.Union[AnyLogIo, AnyReadIo, _Response],
|
|
9666
|
+
ta.Union[CoroHttpIo.AnyLogIo, CoroHttpIo.AnyReadIo, _Response],
|
|
9353
9667
|
ta.Optional[bytes],
|
|
9354
9668
|
None,
|
|
9355
9669
|
]:
|
|
@@ -9359,7 +9673,7 @@ class CoroHttpServer:
|
|
|
9359
9673
|
sz = next(gen)
|
|
9360
9674
|
while True:
|
|
9361
9675
|
try:
|
|
9362
|
-
line = check.isinstance((yield
|
|
9676
|
+
line = check.isinstance((yield CoroHttpIo.ReadLineIo(sz)), bytes)
|
|
9363
9677
|
sz = gen.send(line)
|
|
9364
9678
|
except StopIteration as e:
|
|
9365
9679
|
parsed = e.value
|
|
@@ -9398,7 +9712,7 @@ class CoroHttpServer:
|
|
|
9398
9712
|
|
|
9399
9713
|
request_data: ta.Optional[bytes]
|
|
9400
9714
|
if (cl := parsed.headers.get('Content-Length')) is not None:
|
|
9401
|
-
request_data = check.isinstance((yield
|
|
9715
|
+
request_data = check.isinstance((yield CoroHttpIo.ReadIo(int(cl))), bytes)
|
|
9402
9716
|
else:
|
|
9403
9717
|
request_data = None
|
|
9404
9718
|
|
|
@@ -10753,6 +11067,10 @@ class VerboseCalledProcessError(subprocess.CalledProcessError):
|
|
|
10753
11067
|
class BaseSubprocesses(Abstract):
|
|
10754
11068
|
DEFAULT_LOGGER: ta.ClassVar[ta.Optional[LoggerLike]] = None
|
|
10755
11069
|
|
|
11070
|
+
PIPE: ta.ClassVar[int] = subprocess.PIPE
|
|
11071
|
+
STDOUT: ta.ClassVar[int] = subprocess.STDOUT
|
|
11072
|
+
DEVNULL: ta.ClassVar[int] = subprocess.DEVNULL
|
|
11073
|
+
|
|
10756
11074
|
def __init__(
|
|
10757
11075
|
self,
|
|
10758
11076
|
*,
|
|
@@ -11443,7 +11761,7 @@ class CoroHttpServerSocketHandler(SocketHandler_):
|
|
|
11443
11761
|
server_factory: CoroHttpServerFactory,
|
|
11444
11762
|
*,
|
|
11445
11763
|
keep_alive: bool = False,
|
|
11446
|
-
log_handler: ta.Optional[ta.Callable[[CoroHttpServer,
|
|
11764
|
+
log_handler: ta.Optional[ta.Callable[[CoroHttpServer, CoroHttpIo.AnyLogIo], None]] = None,
|
|
11447
11765
|
) -> None:
|
|
11448
11766
|
super().__init__()
|
|
11449
11767
|
|
|
@@ -11472,18 +11790,18 @@ class CoroHttpServerSocketHandler(SocketHandler_):
|
|
|
11472
11790
|
|
|
11473
11791
|
o = next(gen)
|
|
11474
11792
|
while True:
|
|
11475
|
-
if isinstance(o,
|
|
11793
|
+
if isinstance(o, CoroHttpIo.AnyLogIo):
|
|
11476
11794
|
i = None
|
|
11477
11795
|
if self._log_handler is not None:
|
|
11478
11796
|
self._log_handler(server, o)
|
|
11479
11797
|
|
|
11480
|
-
elif isinstance(o,
|
|
11481
|
-
i = fp.r.read(o.sz)
|
|
11798
|
+
elif isinstance(o, CoroHttpIo.ReadIo):
|
|
11799
|
+
i = fp.r.read(check.not_none(o.sz))
|
|
11482
11800
|
|
|
11483
|
-
elif isinstance(o,
|
|
11801
|
+
elif isinstance(o, CoroHttpIo.ReadLineIo):
|
|
11484
11802
|
i = fp.r.readline(o.sz)
|
|
11485
11803
|
|
|
11486
|
-
elif isinstance(o,
|
|
11804
|
+
elif isinstance(o, CoroHttpIo.WriteIo):
|
|
11487
11805
|
i = None
|
|
11488
11806
|
fp.w.write(o.data)
|
|
11489
11807
|
fp.w.flush()
|
|
@@ -15376,7 +15694,7 @@ async def _async_main() -> ta.Optional[int]:
|
|
|
15376
15694
|
def _main() -> None:
|
|
15377
15695
|
configure_standard_logging('DEBUG')
|
|
15378
15696
|
|
|
15379
|
-
|
|
15697
|
+
raise SystemExit(rc if isinstance(rc := asyncio.run(_async_main()), int) else 0)
|
|
15380
15698
|
|
|
15381
15699
|
|
|
15382
15700
|
if __name__ == '__main__':
|