ominfra 0.0.0.dev438__py3-none-any.whl → 0.0.0.dev483__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 ominfra might be problematic. Click here for more details.
- ominfra/clouds/aws/instancetypes/cache.json.gz +0 -0
- ominfra/clouds/aws/models/gen/gen.py +8 -5
- ominfra/clouds/aws/models/services/__init__.py +7 -0
- ominfra/clouds/aws/models/services/_dataclasses.py +47718 -0
- ominfra/clouds/aws/models/services/ec2.py +103 -0
- ominfra/clouds/aws/models/services/lambda_.py +129 -0
- ominfra/clouds/aws/models/services/rds.py +210 -77
- ominfra/clouds/aws/models/services/s3.py +2 -0
- ominfra/manage/main.py +1 -2
- ominfra/scripts/journald2aws.py +408 -52
- ominfra/scripts/manage.py +391 -64
- ominfra/scripts/supervisor.py +539 -98
- {ominfra-0.0.0.dev438.dist-info → ominfra-0.0.0.dev483.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev438.dist-info → ominfra-0.0.0.dev483.dist-info}/RECORD +18 -17
- {ominfra-0.0.0.dev438.dist-info → ominfra-0.0.0.dev483.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev438.dist-info → ominfra-0.0.0.dev483.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev438.dist-info → ominfra-0.0.0.dev483.dist-info}/licenses/LICENSE +0 -0
- {ominfra-0.0.0.dev438.dist-info → ominfra-0.0.0.dev483.dist-info}/top_level.txt +0 -0
ominfra/scripts/manage.py
CHANGED
|
@@ -34,6 +34,7 @@ import io
|
|
|
34
34
|
import itertools
|
|
35
35
|
import json
|
|
36
36
|
import logging
|
|
37
|
+
import operator
|
|
37
38
|
import os
|
|
38
39
|
import os.path
|
|
39
40
|
import platform
|
|
@@ -65,6 +66,142 @@ if sys.version_info < (3, 8):
|
|
|
65
66
|
raise OSError(f'Requires python (3, 8), got {sys.version_info} from {sys.executable}') # noqa
|
|
66
67
|
|
|
67
68
|
|
|
69
|
+
def __omlish_amalg__(): # noqa
|
|
70
|
+
return dict(
|
|
71
|
+
src_files=[
|
|
72
|
+
dict(path='../../omdev/packaging/versions.py', sha1='71627ad600b3529b829b0e227b0952f2c63c7271'),
|
|
73
|
+
dict(path='config.py', sha1='6ff640634488fa142d9aadee5aec95db462ce46f'),
|
|
74
|
+
dict(path='deploy/config.py', sha1='b11f480014b42206531ea897e76dd0220eb59969'),
|
|
75
|
+
dict(path='deploy/paths/types.py', sha1='4364179744afb2344f2b44d188e37f786c955970'),
|
|
76
|
+
dict(path='deploy/types.py', sha1='41b2becf7a9d009e18235a8b49cfbe0419785190'),
|
|
77
|
+
dict(path='../pyremote.py', sha1='2131faabec13af3d29747d9430286394603445ca'),
|
|
78
|
+
dict(path='../../omlish/asyncs/asyncio/channels.py', sha1='36cec6ea48887baaf536ae6301ec6ebc70f9f19b'),
|
|
79
|
+
dict(path='../../omlish/asyncs/asyncio/streams.py', sha1='78a498b78b51805d3b44ba7fe8c10c575389c6a9'),
|
|
80
|
+
dict(path='../../omlish/configs/types.py', sha1='f7a5584cd6eccb77d18d729796072a162e9a8790'),
|
|
81
|
+
dict(path='../../omlish/formats/ini/sections.py', sha1='731c92cce82e183d1d4bdc23fc781fad62187394'),
|
|
82
|
+
dict(path='../../omlish/formats/toml/parser.py', sha1='73dac82289350ab951c4bcdbfe61167fa221f26f'),
|
|
83
|
+
dict(path='../../omlish/formats/toml/writer.py', sha1='6ea41d7e724bb1dcf6bd84b88993ff4e8798e021'),
|
|
84
|
+
dict(path='../../omlish/lite/abstract.py', sha1='a2fc3f3697fa8de5247761e9d554e70176f37aac'),
|
|
85
|
+
dict(path='../../omlish/lite/attrops.py', sha1='c1ebfb8573d766d34593c452a2377208d02726dc'),
|
|
86
|
+
dict(path='../../omlish/lite/cached.py', sha1='0c33cf961ac8f0727284303c7a30c5ea98f714f2'),
|
|
87
|
+
dict(path='../../omlish/lite/check.py', sha1='bb6b6b63333699b84462951a854d99ae83195b94'),
|
|
88
|
+
dict(path='../../omlish/lite/contextmanagers.py', sha1='993f5ed96d3410f739a20363f55670d5e5267fa3'),
|
|
89
|
+
dict(path='../../omlish/lite/json.py', sha1='57eeddc4d23a17931e00284ffa5cb6e3ce089486'),
|
|
90
|
+
dict(path='../../omlish/lite/objects.py', sha1='9566bbf3530fd71fcc56321485216b592fae21e9'),
|
|
91
|
+
dict(path='../../omlish/lite/pycharm.py', sha1='6f84e57f02e2f1075918002f89e4201910d2a15e'),
|
|
92
|
+
dict(path='../../omlish/lite/reflect.py', sha1='c4fec44bf144e9d93293c996af06f6c65fc5e63d'),
|
|
93
|
+
dict(path='../../omlish/lite/resources.py', sha1='1365cb6046eb929358e7c86a3fda20d95fd4a296'),
|
|
94
|
+
dict(path='../../omlish/lite/strings.py', sha1='89831ecbc34ad80e118a865eceb390ed399dc4d6'),
|
|
95
|
+
dict(path='../../omlish/lite/typing.py', sha1='deaaa560b63d9a0e40991ec0006451f5f0df04c1'),
|
|
96
|
+
dict(path='../../omlish/logs/levels.py', sha1='91405563d082a5eba874da82aac89d83ce7b6152'),
|
|
97
|
+
dict(path='../../omlish/logs/std/filters.py', sha1='f36aab646d84d31e295b33aaaaa6f8b67ff38b3d'),
|
|
98
|
+
dict(path='../../omlish/logs/std/proxy.py', sha1='3e7301a2aa351127f9c85f61b2f85dcc3f15aafb'),
|
|
99
|
+
dict(path='../../omlish/logs/warnings.py', sha1='c4eb694b24773351107fcc058f3620f1dbfb6799'),
|
|
100
|
+
dict(path='../../omlish/os/deathsig.py', sha1='5d3f1a22132b7029d32e29b13c1cc20497c8f7a8'),
|
|
101
|
+
dict(path='../../omlish/os/environ.py', sha1='5e9ed4817af65683b496af49fef996630c3113b1'),
|
|
102
|
+
dict(path='../../omlish/os/linux.py', sha1='b6433d321eba7afab353b04107819fdc72f1d836'),
|
|
103
|
+
dict(path='../../omlish/os/paths.py', sha1='56c40b7c2aa84d1778d60ee4cda498f8c380cc8d'),
|
|
104
|
+
dict(path='../../omlish/shlex.py', sha1='a69721913bcd4f4008600e390fb7822637c2a8ec'),
|
|
105
|
+
dict(path='../../omdev/home/paths.py', sha1='a83516c97a2e99e79153a414db3d23091186bb23'),
|
|
106
|
+
dict(path='../../omdev/packaging/specifiers.py', sha1='a56ab4e8c9b174adb523921f6280ac41e0fce749'),
|
|
107
|
+
dict(path='deploy/paths/specs.py', sha1='023167da1ad9fcf09d9d44963177175591a97377'),
|
|
108
|
+
dict(path='remote/config.py', sha1='48f9367e9db4b23166657ff34eb644c9869d48a8'),
|
|
109
|
+
dict(path='remote/payload.py', sha1='acacf4c2901b7708224af5d4414ecb823947297a'),
|
|
110
|
+
dict(path='targets/bestpython.py', sha1='75c16ab86397a8e81017f148a2ef711567b6ab27'),
|
|
111
|
+
dict(path='targets/targets.py', sha1='d07f2d30c31bad89bd4a3b44bb6a5b6c95c05888'),
|
|
112
|
+
dict(path='../../omlish/argparse/cli.py', sha1='f4dc3cd353d14386b5da0306768700e396afd2b3'),
|
|
113
|
+
dict(path='../../omlish/configs/formats.py', sha1='9bc4f953b4b8700f6f109e6f49e2d70f8e48ce7c'),
|
|
114
|
+
dict(path='../../omlish/lite/marshal.py', sha1='96348f5f2a26dc27d842d33cc3927e9da163436b'),
|
|
115
|
+
dict(path='../../omlish/lite/maybes.py', sha1='bdf5136654ccd14b6a072588cad228925bdfbabd'),
|
|
116
|
+
dict(path='../../omlish/lite/runtime.py', sha1='2e752a27ae2bf89b1bb79b4a2da522a3ec360c70'),
|
|
117
|
+
dict(path='../../omlish/lite/timeouts.py', sha1='a0f673033a6943f242e35848d78a41892b9c62a1'),
|
|
118
|
+
dict(path='../../omlish/logs/infos.py', sha1='4dd104bd468a8c438601dd0bbda619b47d2f1620'),
|
|
119
|
+
dict(path='../../omlish/logs/protocols.py', sha1='05ca4d1d7feb50c4e3b9f22ee371aa7bf4b3dbd1'),
|
|
120
|
+
dict(path='../../omlish/logs/std/json.py', sha1='2a75553131e4d5331bb0cedde42aa183f403fc3b'),
|
|
121
|
+
dict(path='../../omlish/os/atomics.py', sha1='ccb62620b95f60ac50561c283d50e5fcfdccb215'),
|
|
122
|
+
dict(path='../../omlish/text/indent.py', sha1='cc23647bdcd8d26c8afe9e36a0aefb32da58cbb8'),
|
|
123
|
+
dict(path='../../omdev/interp/types.py', sha1='cfc14929777fb19f723c875bcafc8f7c66593d6d'),
|
|
124
|
+
dict(path='commands/base.py', sha1='17310f7272b6ac7b6438e32bfd7b24004d284399'),
|
|
125
|
+
dict(path='deploy/conf/specs.py', sha1='d191fa887c59198f5eff5c62414031204a76fa65'),
|
|
126
|
+
dict(path='deploy/tags.py', sha1='e6e7a1f4fcee9f5764acbe7f307b31e26f81bbc3'),
|
|
127
|
+
dict(path='marshal.py', sha1='175f59215a92afd42468f6258f1202b9ec3362cb'),
|
|
128
|
+
dict(path='remote/channel.py', sha1='2b6498da48ff89901b88a6a1ef84c58b37ddb410'),
|
|
129
|
+
dict(path='../../omlish/asyncs/asyncio/timeouts.py', sha1='4d31b02b3c39b8f2fa7e94db36552fde6942e36a'),
|
|
130
|
+
dict(path='../../omlish/configs/nginx.py', sha1='d0ad33c21674fc02f23281247517c827f455eb0b'),
|
|
131
|
+
dict(path='../../omlish/lite/configs.py', sha1='c8602e0e197ef1133e7e8e248935ac745bfd46cb'),
|
|
132
|
+
dict(path='../../omlish/lite/inject.py', sha1='6f097e3170019a34ff6834d36fcc9cbeed3a7ab4'),
|
|
133
|
+
dict(path='../../omlish/logs/contexts.py', sha1='7456964ade9ac66460e9ade4e242dbdc24b39501'),
|
|
134
|
+
dict(path='../../omlish/logs/standard.py', sha1='818b674f7d15012f25b79f52f6e8e7368b633038'),
|
|
135
|
+
dict(path='../../omlish/subprocesses/run.py', sha1='8200e48f0c49d164df3503cd0143038d0c4d30aa'),
|
|
136
|
+
dict(path='../../omlish/subprocesses/wrap.py', sha1='8a9b7d2255481fae15c05f5624b0cdc0766f4b3f'),
|
|
137
|
+
dict(path='../../omdev/interp/providers/base.py', sha1='f5d068c21f230d742e9015b033cd6320f4c68898'),
|
|
138
|
+
dict(path='commands/injection.py', sha1='f7d8aec3c33efc61da1f0c6700bdfbe7bcc10e56'),
|
|
139
|
+
dict(path='commands/marshal.py', sha1='a21c3a75fe17bb80d32d10a3d5524d67a96ea210'),
|
|
140
|
+
dict(path='commands/ping.py', sha1='af4c34e9b1811269c954cf502b336a6446639a2a'),
|
|
141
|
+
dict(path='commands/types.py', sha1='10b88571981b9964287f30f27abf6d09400b51c6'),
|
|
142
|
+
dict(path='deploy/paths/paths.py', sha1='bf7794e998caa1611277ac5809eb7ec91a76d1e8'),
|
|
143
|
+
dict(path='deploy/specs.py', sha1='b3a411b32b47f81f5ad673d8b0338970a6eb6ff9'),
|
|
144
|
+
dict(path='../../omlish/logs/base.py', sha1='a376460b11b9dc0555fd4ead5437af62c2109a4b'),
|
|
145
|
+
dict(path='../../omlish/logs/std/records.py', sha1='8bbf6ef9eccb3a012c6ca416ddf3969450fd8fc9'),
|
|
146
|
+
dict(path='../../omlish/subprocesses/base.py', sha1='cb9f668be5422fecb27222caabb67daac6c1bab9'),
|
|
147
|
+
dict(path='../../omdev/interp/resolvers.py', sha1='817b8e76401cd7a19eb43ca54d65272e4c8a4b0e'),
|
|
148
|
+
dict(path='commands/local.py', sha1='db3c5b0a1f067f54e2133234e36e7db393e4dec3'),
|
|
149
|
+
dict(path='deploy/conf/manager.py', sha1='7450a8616dbc46f6c68387192035a6ea258aebe2'),
|
|
150
|
+
dict(path='deploy/paths/owners.py', sha1='382bcec4824f0fc71dddf083c6e88748b5c62ef2'),
|
|
151
|
+
dict(path='../../omlish/logs/std/loggers.py', sha1='daa35bdc4adea5006e442688017f0de3392579b7'),
|
|
152
|
+
dict(path='../../omlish/subprocesses/asyncs.py', sha1='bba44d524c24c6ac73168aee6343488414e5bf48'),
|
|
153
|
+
dict(path='../../omlish/subprocesses/sync.py', sha1='8434919eba4da67825773d56918fdc0cb2f1883b'),
|
|
154
|
+
dict(path='../../omdev/git/shallow.py', sha1='7b5f9d77b7a01df5828ca61a2adc6dae54cf676b'),
|
|
155
|
+
dict(path='deploy/injection.py', sha1='7d641dd20ff0c75de5679079c52647653849d6cc'),
|
|
156
|
+
dict(path='deploy/paths/manager.py', sha1='eb1c84e0ca03083f69b53cee25bf7ffd752cc7a9'),
|
|
157
|
+
dict(path='deploy/tmp.py', sha1='d8b7aeaa26ab58e64aba371d46bc661462d47c5e'),
|
|
158
|
+
dict(path='../../omlish/asyncs/asyncio/subprocesses.py', sha1='b6b5f9ae3fd0b9c83593bad2e04a08f726e5904d'),
|
|
159
|
+
dict(path='../../omlish/logs/modules.py', sha1='99e73cde6872fd5eda6af3dbf0fc9322bdeb641a'),
|
|
160
|
+
dict(path='../../omdev/interp/inspect.py', sha1='736287b4ec8d14a8c30afa0ba23996fdc0662caa'),
|
|
161
|
+
dict(path='../../omdev/interp/pyenv/pyenv.py', sha1='d1f6e657c671c1b1a5b0e627284df656fe2d10d3'),
|
|
162
|
+
dict(path='../../omdev/interp/uv/uv.py', sha1='8c6515cd6755efab3972da92a285e94ccb255515'),
|
|
163
|
+
dict(path='commands/subprocess.py', sha1='788bd859701fce066bd00c820919f826b43b8b57'),
|
|
164
|
+
dict(path='deploy/conf/inject.py', sha1='d006b45d92f3b5f30a797b65fbed23f90c3db490'),
|
|
165
|
+
dict(path='deploy/git.py', sha1='5ee2e816e18fef493cb2ccc33f33ad673175ad7a'),
|
|
166
|
+
dict(path='deploy/paths/inject.py', sha1='1c501d086fcbde9c2b9ead21fc3c7b175bbf4f76'),
|
|
167
|
+
dict(path='deploy/systemd.py', sha1='773c4482e85a974443bb26237a86b1dfbcd9936c'),
|
|
168
|
+
dict(path='remote/execution.py', sha1='005da809e58790a0e5255df8e57afd5cd6268d7d'),
|
|
169
|
+
dict(path='remote/spawning.py', sha1='9cb6b5da1ba6daabb35a5742be647748c01d40d3'),
|
|
170
|
+
dict(path='system/packages.py', sha1='9988fc93dbca9336c378bf5fad6f68f5b8c0260e'),
|
|
171
|
+
dict(path='system/platforms.py', sha1='f3fc312318cff15f97dd9b10fa5f2408abc45a1b'),
|
|
172
|
+
dict(path='../../omdev/interp/providers/running.py', sha1='85c9cc69ff6fbd6c8cf78ed6262619a30856c2f1'),
|
|
173
|
+
dict(path='../../omdev/interp/providers/system.py', sha1='9638a154475ca98775159d27739563ac7fb2eb16'),
|
|
174
|
+
dict(path='../../omdev/interp/pyenv/install.py', sha1='4a10a19717364b4ba9f3b8bf1d12621cf21ba8b8'),
|
|
175
|
+
dict(path='../../omdev/interp/uv/provider.py', sha1='149f19f95eb701ffad5dc74392f4692c21b5f8c0'),
|
|
176
|
+
dict(path='commands/inject.py', sha1='7a95b6487b01230dd2fe0d9f67382d8889039e7b'),
|
|
177
|
+
dict(path='system/commands.py', sha1='17bbaa945b6ded0a88d31c52b410cbce8fc324a0'),
|
|
178
|
+
dict(path='system/config.py', sha1='fd1ebc2cf36fd312ff69d1af100a7e9c638f1fcc'),
|
|
179
|
+
dict(path='../../omdev/interp/providers/inject.py', sha1='7cc9ebf58cf2ec09545321456bd9da9f9a3a79fb'),
|
|
180
|
+
dict(path='../../omdev/interp/pyenv/provider.py', sha1='377542ce01a35849e2a5b4a4dbafedc26882f983'),
|
|
181
|
+
dict(path='../../omdev/interp/uv/inject.py', sha1='e95d058c2340baa5a3155ec3440f311d1daa10a8'),
|
|
182
|
+
dict(path='bootstrap.py', sha1='e66138947a41e8a49576885cf4b1390315d44f88'),
|
|
183
|
+
dict(path='system/inject.py', sha1='8a34be1b982cb42981c08306f12994a0fff258bd'),
|
|
184
|
+
dict(path='../../omdev/interp/pyenv/inject.py', sha1='b8fb68f5a7cae86c70fe1bad6c29a8b2dfc985c3'),
|
|
185
|
+
dict(path='remote/_main.py', sha1='5ae1dc673ce22f2d40612c66b3a5c3d01ebb6718'),
|
|
186
|
+
dict(path='../../omdev/interp/inject.py', sha1='b039abbadf0b096d2724182af2e0ebda2a230852'),
|
|
187
|
+
dict(path='remote/connection.py', sha1='18bc6c4a446a9bef3c54b861a01418b1b7ba39ff'),
|
|
188
|
+
dict(path='../../omdev/interp/default.py', sha1='a799969a0d3f4b57538587b13ceb08f6334ebc16'),
|
|
189
|
+
dict(path='remote/inject.py', sha1='8713a421b18ff7625c95017616380f0500c3c39c'),
|
|
190
|
+
dict(path='targets/connection.py', sha1='891f1d35ee3814bed32e6de71e1ca47574635da1'),
|
|
191
|
+
dict(path='deploy/interp.py', sha1='89371a87a275fea2e8566a0983e4906cda46a105'),
|
|
192
|
+
dict(path='deploy/venvs.py', sha1='7ad41a11098dd68d83a0804d2ea95779d0be4de0'),
|
|
193
|
+
dict(path='targets/inject.py', sha1='e4bfba31b044da9545d4c00965e7e15b97a40cce'),
|
|
194
|
+
dict(path='deploy/apps.py', sha1='6df5d728b6715583a792d1e92268c0c07502509f'),
|
|
195
|
+
dict(path='deploy/deploy.py', sha1='635f84ad370b22797406d2ae55d78621ea1f7b2b'),
|
|
196
|
+
dict(path='deploy/commands.py', sha1='0e9fdd122fe3a4028efede0862b059c091cc13cb'),
|
|
197
|
+
dict(path='deploy/inject.py', sha1='d84e9c3e980c5a1ec62d18628d8911f5b6bb125f'),
|
|
198
|
+
dict(path='inject.py', sha1='b1c173df021f190d3631f3828470fa1564e0b4b4'),
|
|
199
|
+
dict(path='bootstrap_.py', sha1='c7d7c3e88703200a836df63e395f7154bf871f36'),
|
|
200
|
+
dict(path='main.py', sha1='ddddcdb54aabe67188dce6a5f65e04ce296a75b0'),
|
|
201
|
+
],
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
|
|
68
205
|
########################################
|
|
69
206
|
|
|
70
207
|
|
|
@@ -90,7 +227,7 @@ TomlParseFloat = ta.Callable[[str], ta.Any] # ta.TypeAlias
|
|
|
90
227
|
TomlKey = ta.Tuple[str, ...] # ta.TypeAlias
|
|
91
228
|
TomlPos = int # ta.TypeAlias
|
|
92
229
|
|
|
93
|
-
# ../../omlish/lite/
|
|
230
|
+
# ../../omlish/lite/abstract.py
|
|
94
231
|
T = ta.TypeVar('T')
|
|
95
232
|
|
|
96
233
|
# ../../omlish/lite/cached.py
|
|
@@ -281,12 +418,12 @@ class _BaseVersion:
|
|
|
281
418
|
|
|
282
419
|
def __lt__(self, other: '_BaseVersion') -> bool:
|
|
283
420
|
if not isinstance(other, _BaseVersion):
|
|
284
|
-
return NotImplemented
|
|
421
|
+
return NotImplemented
|
|
285
422
|
return self._key < other._key
|
|
286
423
|
|
|
287
424
|
def __le__(self, other: '_BaseVersion') -> bool:
|
|
288
425
|
if not isinstance(other, _BaseVersion):
|
|
289
|
-
return NotImplemented
|
|
426
|
+
return NotImplemented
|
|
290
427
|
return self._key <= other._key
|
|
291
428
|
|
|
292
429
|
def __eq__(self, other: object) -> bool:
|
|
@@ -296,12 +433,12 @@ class _BaseVersion:
|
|
|
296
433
|
|
|
297
434
|
def __ge__(self, other: '_BaseVersion') -> bool:
|
|
298
435
|
if not isinstance(other, _BaseVersion):
|
|
299
|
-
return NotImplemented
|
|
436
|
+
return NotImplemented
|
|
300
437
|
return self._key >= other._key
|
|
301
438
|
|
|
302
439
|
def __gt__(self, other: '_BaseVersion') -> bool:
|
|
303
440
|
if not isinstance(other, _BaseVersion):
|
|
304
|
-
return NotImplemented
|
|
441
|
+
return NotImplemented
|
|
305
442
|
return self._key > other._key
|
|
306
443
|
|
|
307
444
|
def __ne__(self, other: object) -> bool:
|
|
@@ -2394,25 +2531,49 @@ def is_abstract_method(obj: ta.Any) -> bool:
|
|
|
2394
2531
|
return bool(getattr(obj, _IS_ABSTRACT_METHOD_ATTR, False))
|
|
2395
2532
|
|
|
2396
2533
|
|
|
2397
|
-
def
|
|
2534
|
+
def compute_abstract_methods(cls: type) -> ta.FrozenSet[str]:
|
|
2535
|
+
# ~> https://github.com/python/cpython/blob/f3476c6507381ca860eec0989f53647b13517423/Modules/_abc.c#L358
|
|
2536
|
+
|
|
2537
|
+
# Stage 1: direct abstract methods
|
|
2538
|
+
|
|
2539
|
+
abstracts = {
|
|
2540
|
+
a
|
|
2541
|
+
# Get items as a list to avoid mutation issues during iteration
|
|
2542
|
+
for a, v in list(cls.__dict__.items())
|
|
2543
|
+
if is_abstract_method(v)
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
# Stage 2: inherited abstract methods
|
|
2547
|
+
|
|
2548
|
+
for base in cls.__bases__:
|
|
2549
|
+
# Get __abstractmethods__ from base if it exists
|
|
2550
|
+
if (base_abstracts := getattr(base, _ABSTRACT_METHODS_ATTR, None)) is None:
|
|
2551
|
+
continue
|
|
2552
|
+
|
|
2553
|
+
# Iterate over abstract methods in base
|
|
2554
|
+
for key in base_abstracts:
|
|
2555
|
+
# Check if this class has an attribute with this name
|
|
2556
|
+
try:
|
|
2557
|
+
value = getattr(cls, key)
|
|
2558
|
+
except AttributeError:
|
|
2559
|
+
# Attribute not found in this class, skip
|
|
2560
|
+
continue
|
|
2561
|
+
|
|
2562
|
+
# Check if it's still abstract
|
|
2563
|
+
if is_abstract_method(value):
|
|
2564
|
+
abstracts.add(key)
|
|
2565
|
+
|
|
2566
|
+
return frozenset(abstracts)
|
|
2567
|
+
|
|
2568
|
+
|
|
2569
|
+
def update_abstracts(cls: ta.Type[T], *, force: bool = False) -> ta.Type[T]:
|
|
2398
2570
|
if not force and not hasattr(cls, _ABSTRACT_METHODS_ATTR):
|
|
2399
2571
|
# Per stdlib: We check for __abstractmethods__ here because cls might by a C implementation or a python
|
|
2400
2572
|
# implementation (especially during testing), and we want to handle both cases.
|
|
2401
2573
|
return cls
|
|
2402
2574
|
|
|
2403
|
-
abstracts
|
|
2404
|
-
|
|
2405
|
-
for scls in cls.__bases__:
|
|
2406
|
-
for name in getattr(scls, _ABSTRACT_METHODS_ATTR, ()):
|
|
2407
|
-
value = getattr(cls, name, None)
|
|
2408
|
-
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
|
2409
|
-
abstracts.add(name)
|
|
2410
|
-
|
|
2411
|
-
for name, value in cls.__dict__.items():
|
|
2412
|
-
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
|
2413
|
-
abstracts.add(name)
|
|
2414
|
-
|
|
2415
|
-
setattr(cls, _ABSTRACT_METHODS_ATTR, frozenset(abstracts))
|
|
2575
|
+
abstracts = compute_abstract_methods(cls)
|
|
2576
|
+
setattr(cls, _ABSTRACT_METHODS_ATTR, abstracts)
|
|
2416
2577
|
return cls
|
|
2417
2578
|
|
|
2418
2579
|
|
|
@@ -2466,23 +2627,26 @@ class Abstract:
|
|
|
2466
2627
|
super().__init_subclass__(**kwargs)
|
|
2467
2628
|
|
|
2468
2629
|
if not (Abstract in cls.__bases__ or abc.ABC in cls.__bases__):
|
|
2469
|
-
ams
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2630
|
+
if ams := compute_abstract_methods(cls):
|
|
2631
|
+
amd = {
|
|
2632
|
+
a: mcls
|
|
2633
|
+
for mcls in cls.__mro__[::-1]
|
|
2634
|
+
for a in ams
|
|
2635
|
+
if a in mcls.__dict__
|
|
2636
|
+
}
|
|
2475
2637
|
|
|
2476
|
-
if ams:
|
|
2477
2638
|
raise AbstractTypeError(
|
|
2478
2639
|
f'Cannot subclass abstract class {cls.__name__} with abstract methods: ' +
|
|
2479
2640
|
', '.join(sorted([
|
|
2480
2641
|
'.'.join([
|
|
2481
|
-
*([
|
|
2482
|
-
|
|
2642
|
+
*([
|
|
2643
|
+
*([m] if (m := getattr(c, '__module__')) else []),
|
|
2644
|
+
getattr(c, '__qualname__', getattr(c, '__name__')),
|
|
2645
|
+
] if c is not None else '?'),
|
|
2483
2646
|
a,
|
|
2484
2647
|
])
|
|
2485
|
-
for a
|
|
2648
|
+
for a in ams
|
|
2649
|
+
for c in [amd.get(a)]
|
|
2486
2650
|
])),
|
|
2487
2651
|
)
|
|
2488
2652
|
|
|
@@ -2507,6 +2671,8 @@ TODO:
|
|
|
2507
2671
|
- per-attr repr transform / filter
|
|
2508
2672
|
- __ne__ ? cases where it still matters
|
|
2509
2673
|
- ordering ?
|
|
2674
|
+
- repr_filter: ta.Union[ta.Callable[[ta.Any], ta.Optional[str]], ta.Literal['not_none', 'truthy']]] ?
|
|
2675
|
+
- unify repr/repr_fn/repr_filter
|
|
2510
2676
|
"""
|
|
2511
2677
|
|
|
2512
2678
|
|
|
@@ -2524,6 +2690,8 @@ class AttrOps(ta.Generic[T]):
|
|
|
2524
2690
|
display: ta.Optional[str] = None,
|
|
2525
2691
|
|
|
2526
2692
|
repr: bool = True, # noqa
|
|
2693
|
+
repr_fn: ta.Optional[ta.Callable[[ta.Any], ta.Optional[str]]] = None,
|
|
2694
|
+
|
|
2527
2695
|
hash: bool = True, # noqa
|
|
2528
2696
|
eq: bool = True,
|
|
2529
2697
|
) -> None:
|
|
@@ -2538,6 +2706,8 @@ class AttrOps(ta.Generic[T]):
|
|
|
2538
2706
|
self._display = display
|
|
2539
2707
|
|
|
2540
2708
|
self._repr = repr
|
|
2709
|
+
self._repr_fn = repr_fn
|
|
2710
|
+
|
|
2541
2711
|
self._hash = hash
|
|
2542
2712
|
self._eq = eq
|
|
2543
2713
|
|
|
@@ -2545,21 +2715,30 @@ class AttrOps(ta.Generic[T]):
|
|
|
2545
2715
|
def of(
|
|
2546
2716
|
cls,
|
|
2547
2717
|
o: ta.Union[
|
|
2548
|
-
str,
|
|
2549
|
-
ta.Tuple[str, str],
|
|
2550
2718
|
'AttrOps.Attr',
|
|
2719
|
+
str,
|
|
2720
|
+
ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
|
|
2721
|
+
ta.Mapping[str, ta.Any],
|
|
2551
2722
|
],
|
|
2552
2723
|
) -> 'AttrOps.Attr':
|
|
2553
2724
|
if isinstance(o, AttrOps.Attr):
|
|
2554
2725
|
return o
|
|
2555
2726
|
elif isinstance(o, str):
|
|
2556
2727
|
return cls(o)
|
|
2728
|
+
elif isinstance(o, tuple):
|
|
2729
|
+
name, x = o
|
|
2730
|
+
kw: ta.Mapping[str, ta.Any]
|
|
2731
|
+
if isinstance(x, str):
|
|
2732
|
+
kw = dict(display=x)
|
|
2733
|
+
elif isinstance(x, ta.Mapping):
|
|
2734
|
+
kw = x
|
|
2735
|
+
else:
|
|
2736
|
+
raise TypeError(x)
|
|
2737
|
+
return cls(name, **kw)
|
|
2738
|
+
elif isinstance(o, ta.Mapping):
|
|
2739
|
+
return cls(**o)
|
|
2557
2740
|
else:
|
|
2558
|
-
|
|
2559
|
-
return cls(
|
|
2560
|
-
name,
|
|
2561
|
-
display=disp,
|
|
2562
|
-
)
|
|
2741
|
+
raise TypeError(o)
|
|
2563
2742
|
|
|
2564
2743
|
@property
|
|
2565
2744
|
def name(self) -> str:
|
|
@@ -2577,19 +2756,34 @@ class AttrOps(ta.Generic[T]):
|
|
|
2577
2756
|
def eq(self) -> bool:
|
|
2578
2757
|
return self._eq
|
|
2579
2758
|
|
|
2759
|
+
@staticmethod
|
|
2760
|
+
def opt_repr(o: ta.Any) -> ta.Optional[str]:
|
|
2761
|
+
return repr(o) if o is not None else None
|
|
2762
|
+
|
|
2763
|
+
@staticmethod
|
|
2764
|
+
def truthy_repr(o: ta.Any) -> ta.Optional[str]:
|
|
2765
|
+
return repr(o) if o else None
|
|
2766
|
+
|
|
2767
|
+
#
|
|
2768
|
+
|
|
2580
2769
|
@ta.overload
|
|
2581
2770
|
def __init__(
|
|
2582
2771
|
self,
|
|
2583
2772
|
*attrs: ta.Sequence[ta.Union[
|
|
2584
2773
|
str,
|
|
2585
|
-
ta.Tuple[str, str],
|
|
2774
|
+
ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
|
|
2775
|
+
ta.Mapping[str, ta.Any],
|
|
2586
2776
|
Attr,
|
|
2587
2777
|
]],
|
|
2778
|
+
|
|
2588
2779
|
with_module: bool = False,
|
|
2589
2780
|
use_qualname: bool = False,
|
|
2590
2781
|
with_id: bool = False,
|
|
2782
|
+
terse: bool = False,
|
|
2591
2783
|
repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
|
|
2592
2784
|
recursive: bool = False,
|
|
2785
|
+
|
|
2786
|
+
cache_hash: ta.Union[bool, str] = False,
|
|
2593
2787
|
subtypes_eq: bool = False,
|
|
2594
2788
|
) -> None:
|
|
2595
2789
|
...
|
|
@@ -2599,16 +2793,20 @@ class AttrOps(ta.Generic[T]):
|
|
|
2599
2793
|
self,
|
|
2600
2794
|
attrs_fn: ta.Callable[[T], ta.Tuple[ta.Union[
|
|
2601
2795
|
ta.Any,
|
|
2602
|
-
ta.Tuple[str, ta.Any],
|
|
2796
|
+
ta.Tuple[ta.Any, ta.Union[str, ta.Mapping[str, ta.Any]]],
|
|
2603
2797
|
Attr,
|
|
2604
2798
|
], ...]],
|
|
2605
2799
|
/,
|
|
2606
2800
|
*,
|
|
2801
|
+
|
|
2607
2802
|
with_module: bool = False,
|
|
2608
2803
|
use_qualname: bool = False,
|
|
2609
2804
|
with_id: bool = False,
|
|
2805
|
+
terse: bool = False,
|
|
2610
2806
|
repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
|
|
2611
2807
|
recursive: bool = False,
|
|
2808
|
+
|
|
2809
|
+
cache_hash: ta.Union[bool, str] = False,
|
|
2612
2810
|
subtypes_eq: bool = False,
|
|
2613
2811
|
) -> None:
|
|
2614
2812
|
...
|
|
@@ -2616,11 +2814,15 @@ class AttrOps(ta.Generic[T]):
|
|
|
2616
2814
|
def __init__(
|
|
2617
2815
|
self,
|
|
2618
2816
|
*args,
|
|
2817
|
+
|
|
2619
2818
|
with_module=False,
|
|
2620
2819
|
use_qualname=False,
|
|
2621
2820
|
with_id=False,
|
|
2821
|
+
terse=False,
|
|
2622
2822
|
repr_filter=None,
|
|
2623
2823
|
recursive=False,
|
|
2824
|
+
|
|
2825
|
+
cache_hash=False,
|
|
2624
2826
|
subtypes_eq=False,
|
|
2625
2827
|
) -> None:
|
|
2626
2828
|
if args and len(args) == 1 and callable(args[0]):
|
|
@@ -2631,8 +2833,11 @@ class AttrOps(ta.Generic[T]):
|
|
|
2631
2833
|
self._with_module: bool = with_module
|
|
2632
2834
|
self._use_qualname: bool = use_qualname
|
|
2633
2835
|
self._with_id: bool = with_id
|
|
2836
|
+
self._terse: bool = terse
|
|
2634
2837
|
self._repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = repr_filter
|
|
2635
2838
|
self._recursive: bool = recursive
|
|
2839
|
+
|
|
2840
|
+
self._cache_hash: ta.Union[bool, str] = cache_hash
|
|
2636
2841
|
self._subtypes_eq: bool = subtypes_eq
|
|
2637
2842
|
|
|
2638
2843
|
@property
|
|
@@ -2667,20 +2872,27 @@ class AttrOps(ta.Generic[T]):
|
|
|
2667
2872
|
|
|
2668
2873
|
attrs: ta.List[AttrOps.Attr] = []
|
|
2669
2874
|
for o in raw:
|
|
2670
|
-
if isinstance(o, AttrOps.Attr):
|
|
2671
|
-
attrs.append(o)
|
|
2875
|
+
if isinstance(o, (AttrOps.Attr, ta.Mapping)):
|
|
2876
|
+
attrs.append(AttrOps.Attr.of(o))
|
|
2672
2877
|
continue
|
|
2673
2878
|
|
|
2879
|
+
kw: ta.Mapping[str, ta.Any]
|
|
2674
2880
|
if isinstance(o, tuple):
|
|
2675
|
-
|
|
2881
|
+
cap, x = o
|
|
2882
|
+
if isinstance(x, str):
|
|
2883
|
+
kw = dict(display=x)
|
|
2884
|
+
elif isinstance(x, ta.Mapping):
|
|
2885
|
+
kw = x
|
|
2886
|
+
else:
|
|
2887
|
+
raise TypeError(x)
|
|
2676
2888
|
else:
|
|
2677
|
-
|
|
2889
|
+
cap, kw = o, {}
|
|
2678
2890
|
|
|
2679
2891
|
path = tuple(rec(cap))
|
|
2680
2892
|
|
|
2681
2893
|
attrs.append(AttrOps.Attr(
|
|
2682
2894
|
'.'.join(path),
|
|
2683
|
-
|
|
2895
|
+
**kw,
|
|
2684
2896
|
))
|
|
2685
2897
|
|
|
2686
2898
|
return attrs
|
|
@@ -2697,19 +2909,27 @@ class AttrOps(ta.Generic[T]):
|
|
|
2697
2909
|
pass
|
|
2698
2910
|
|
|
2699
2911
|
def _repr(o: T) -> str:
|
|
2700
|
-
vs =
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
if self._repr_filter is None
|
|
2706
|
-
|
|
2912
|
+
vs: ta.List[str] = []
|
|
2913
|
+
for a in self._attrs:
|
|
2914
|
+
if not a._repr: # noqa
|
|
2915
|
+
continue
|
|
2916
|
+
v = getattr(o, a._name) # noqa
|
|
2917
|
+
if self._repr_filter is not None and not self._repr_filter(v):
|
|
2918
|
+
continue
|
|
2919
|
+
if (rfn := a._repr_fn) is None: # noqa
|
|
2920
|
+
rfn = repr
|
|
2921
|
+
if (vr := rfn(v)) is None:
|
|
2922
|
+
continue
|
|
2923
|
+
if self._terse:
|
|
2924
|
+
vs.append(vr)
|
|
2925
|
+
else:
|
|
2926
|
+
vs.append(f'{a._display}={vr}') # noqa
|
|
2707
2927
|
|
|
2708
2928
|
return (
|
|
2709
2929
|
f'{o.__class__.__module__ + "." if self._with_module else ""}'
|
|
2710
2930
|
f'{o.__class__.__qualname__ if self._use_qualname else o.__class__.__name__}'
|
|
2711
2931
|
f'{("@" + hex(id(o))[2:]) if self._with_id else ""}' # noqa
|
|
2712
|
-
f'({vs})'
|
|
2932
|
+
f'({", ".join(vs)})'
|
|
2713
2933
|
)
|
|
2714
2934
|
|
|
2715
2935
|
if self._recursive:
|
|
@@ -2734,6 +2954,8 @@ class AttrOps(ta.Generic[T]):
|
|
|
2734
2954
|
|
|
2735
2955
|
#
|
|
2736
2956
|
|
|
2957
|
+
_DEFAULT_CACHED_HASH_ATTR: ta.ClassVar[str] = '__cached_hash__'
|
|
2958
|
+
|
|
2737
2959
|
_hash: ta.Callable[[T], int]
|
|
2738
2960
|
|
|
2739
2961
|
@property
|
|
@@ -2743,13 +2965,33 @@ class AttrOps(ta.Generic[T]):
|
|
|
2743
2965
|
except AttributeError:
|
|
2744
2966
|
pass
|
|
2745
2967
|
|
|
2746
|
-
def
|
|
2968
|
+
def _calc_hash(o: T) -> int:
|
|
2747
2969
|
return hash(tuple(
|
|
2748
2970
|
getattr(o, a._name) # noqa
|
|
2749
2971
|
for a in self._attrs
|
|
2750
2972
|
if a._hash # noqa
|
|
2751
2973
|
))
|
|
2752
2974
|
|
|
2975
|
+
if (ch := self._cache_hash) is not False:
|
|
2976
|
+
if ch is True:
|
|
2977
|
+
cha = self._DEFAULT_CACHED_HASH_ATTR
|
|
2978
|
+
elif isinstance(ch, str):
|
|
2979
|
+
cha = ch
|
|
2980
|
+
else:
|
|
2981
|
+
raise TypeError(ch)
|
|
2982
|
+
|
|
2983
|
+
def _cached_hash(o: T) -> int:
|
|
2984
|
+
try:
|
|
2985
|
+
return object.__getattribute__(o, cha)
|
|
2986
|
+
except AttributeError:
|
|
2987
|
+
object.__setattr__(o, cha, h := _calc_hash(o))
|
|
2988
|
+
return h
|
|
2989
|
+
|
|
2990
|
+
_hash = _cached_hash
|
|
2991
|
+
|
|
2992
|
+
else:
|
|
2993
|
+
_hash = _calc_hash
|
|
2994
|
+
|
|
2753
2995
|
self._hash = _hash
|
|
2754
2996
|
return _hash
|
|
2755
2997
|
|
|
@@ -2890,6 +3132,62 @@ def async_cached_nullary(fn): # ta.Callable[..., T]) -> ta.Callable[..., T]:
|
|
|
2890
3132
|
return _AsyncCachedNullary(fn)
|
|
2891
3133
|
|
|
2892
3134
|
|
|
3135
|
+
##
|
|
3136
|
+
|
|
3137
|
+
|
|
3138
|
+
cached_property = functools.cached_property
|
|
3139
|
+
|
|
3140
|
+
|
|
3141
|
+
class _cached_property: # noqa
|
|
3142
|
+
"""Backported to pick up https://github.com/python/cpython/commit/056dfc71dce15f81887f0bd6da09d6099d71f979 ."""
|
|
3143
|
+
|
|
3144
|
+
def __init__(self, func):
|
|
3145
|
+
self.func = func
|
|
3146
|
+
self.attrname = None # noqa
|
|
3147
|
+
self.__doc__ = func.__doc__
|
|
3148
|
+
self.__module__ = func.__module__
|
|
3149
|
+
|
|
3150
|
+
_NOT_FOUND = object()
|
|
3151
|
+
|
|
3152
|
+
def __set_name__(self, owner, name):
|
|
3153
|
+
if self.attrname is None:
|
|
3154
|
+
self.attrname = name # noqa
|
|
3155
|
+
elif name != self.attrname:
|
|
3156
|
+
raise TypeError(
|
|
3157
|
+
f'Cannot assign the same cached_property to two different names ({self.attrname!r} and {name!r}).',
|
|
3158
|
+
)
|
|
3159
|
+
|
|
3160
|
+
def __get__(self, instance, owner=None):
|
|
3161
|
+
if instance is None:
|
|
3162
|
+
return self
|
|
3163
|
+
if self.attrname is None:
|
|
3164
|
+
raise TypeError('Cannot use cached_property instance without calling __set_name__ on it.')
|
|
3165
|
+
|
|
3166
|
+
try:
|
|
3167
|
+
cache = instance.__dict__
|
|
3168
|
+
except AttributeError: # not all objects have __dict__ (e.g. class defines slots)
|
|
3169
|
+
raise TypeError(
|
|
3170
|
+
f"No '__dict__' attribute on {type(instance).__name__!r} instance to cache {self.attrname!r} property.",
|
|
3171
|
+
) from None
|
|
3172
|
+
|
|
3173
|
+
val = cache.get(self.attrname, self._NOT_FOUND)
|
|
3174
|
+
|
|
3175
|
+
if val is self._NOT_FOUND:
|
|
3176
|
+
val = self.func(instance)
|
|
3177
|
+
try:
|
|
3178
|
+
cache[self.attrname] = val
|
|
3179
|
+
except TypeError:
|
|
3180
|
+
raise TypeError(
|
|
3181
|
+
f"The '__dict__' attribute on {type(instance).__name__!r} instance does not support item "
|
|
3182
|
+
f"assignment for caching {self.attrname!r} property.",
|
|
3183
|
+
) from None
|
|
3184
|
+
|
|
3185
|
+
return val
|
|
3186
|
+
|
|
3187
|
+
|
|
3188
|
+
globals()['cached_property'] = _cached_property
|
|
3189
|
+
|
|
3190
|
+
|
|
2893
3191
|
########################################
|
|
2894
3192
|
# ../../../omlish/lite/check.py
|
|
2895
3193
|
"""
|
|
@@ -3429,7 +3727,7 @@ class ExitStacked:
|
|
|
3429
3727
|
es.__enter__()
|
|
3430
3728
|
try:
|
|
3431
3729
|
self._enter_contexts()
|
|
3432
|
-
except
|
|
3730
|
+
except BaseException: # noqa
|
|
3433
3731
|
es.__exit__(*sys.exc_info())
|
|
3434
3732
|
raise
|
|
3435
3733
|
return self
|
|
@@ -3440,7 +3738,7 @@ class ExitStacked:
|
|
|
3440
3738
|
return None
|
|
3441
3739
|
try:
|
|
3442
3740
|
self._exit_contexts()
|
|
3443
|
-
except
|
|
3741
|
+
except BaseException: # noqa
|
|
3444
3742
|
es.__exit__(*sys.exc_info())
|
|
3445
3743
|
raise
|
|
3446
3744
|
return es.__exit__(exc_type, exc_val, exc_tb)
|
|
@@ -3488,7 +3786,7 @@ class AsyncExitStacked:
|
|
|
3488
3786
|
await es.__aenter__()
|
|
3489
3787
|
try:
|
|
3490
3788
|
await self._async_enter_contexts()
|
|
3491
|
-
except
|
|
3789
|
+
except BaseException: # noqa
|
|
3492
3790
|
await es.__aexit__(*sys.exc_info())
|
|
3493
3791
|
raise
|
|
3494
3792
|
return self
|
|
@@ -3499,7 +3797,7 @@ class AsyncExitStacked:
|
|
|
3499
3797
|
return None
|
|
3500
3798
|
try:
|
|
3501
3799
|
await self._async_exit_contexts()
|
|
3502
|
-
except
|
|
3800
|
+
except BaseException: # noqa
|
|
3503
3801
|
await es.__aexit__(*sys.exc_info())
|
|
3504
3802
|
raise
|
|
3505
3803
|
return await es.__aexit__(exc_type, exc_val, exc_tb)
|
|
@@ -3697,7 +3995,7 @@ def dir_dict(o: ta.Any) -> ta.Dict[str, ta.Any]:
|
|
|
3697
3995
|
##
|
|
3698
3996
|
|
|
3699
3997
|
|
|
3700
|
-
DEFAULT_PYCHARM_VERSION = '
|
|
3998
|
+
DEFAULT_PYCHARM_VERSION = '252.26199.168'
|
|
3701
3999
|
|
|
3702
4000
|
|
|
3703
4001
|
@dc.dataclass(frozen=True)
|
|
@@ -3941,6 +4239,12 @@ def format_num_bytes(num_bytes: int) -> str:
|
|
|
3941
4239
|
|
|
3942
4240
|
##
|
|
3943
4241
|
# A workaround for typing deficiencies (like `Argument 2 to NewType(...) must be subclassable`).
|
|
4242
|
+
#
|
|
4243
|
+
# Note that this problem doesn't happen at runtime - it happens in mypy:
|
|
4244
|
+
#
|
|
4245
|
+
# mypy <(echo "import typing as ta; MyCallback = ta.NewType('MyCallback', ta.Callable[[], None])")
|
|
4246
|
+
# /dev/fd/11:1:22: error: Argument 2 to NewType(...) must be subclassable (got "Callable[[], None]") [valid-newtype]
|
|
4247
|
+
#
|
|
3944
4248
|
|
|
3945
4249
|
|
|
3946
4250
|
@dc.dataclass(frozen=True)
|
|
@@ -5483,7 +5787,7 @@ class SpecifierSet(BaseSpecifier):
|
|
|
5483
5787
|
if isinstance(other, str):
|
|
5484
5788
|
other = SpecifierSet(other)
|
|
5485
5789
|
elif not isinstance(other, SpecifierSet):
|
|
5486
|
-
return NotImplemented
|
|
5790
|
+
return NotImplemented
|
|
5487
5791
|
|
|
5488
5792
|
specifier = SpecifierSet()
|
|
5489
5793
|
specifier._specs = frozenset(self._specs | other._specs)
|
|
@@ -5503,6 +5807,7 @@ class SpecifierSet(BaseSpecifier):
|
|
|
5503
5807
|
if isinstance(other, (str, Specifier)):
|
|
5504
5808
|
other = SpecifierSet(str(other))
|
|
5505
5809
|
elif not isinstance(other, SpecifierSet):
|
|
5810
|
+
|
|
5506
5811
|
return NotImplemented
|
|
5507
5812
|
|
|
5508
5813
|
return self._specs == other._specs
|
|
@@ -5789,6 +6094,7 @@ TODO:
|
|
|
5789
6094
|
- pre-run, post-run hooks
|
|
5790
6095
|
- exitstack?
|
|
5791
6096
|
- suggestion - difflib.get_close_matches
|
|
6097
|
+
- add_argument_group - group kw on ArgparseKwarg?
|
|
5792
6098
|
"""
|
|
5793
6099
|
|
|
5794
6100
|
|
|
@@ -5799,6 +6105,7 @@ TODO:
|
|
|
5799
6105
|
class ArgparseArg:
|
|
5800
6106
|
args: ta.Sequence[ta.Any]
|
|
5801
6107
|
kwargs: ta.Mapping[str, ta.Any]
|
|
6108
|
+
group: ta.Optional[str] = None
|
|
5802
6109
|
dest: ta.Optional[str] = None
|
|
5803
6110
|
|
|
5804
6111
|
def __get__(self, instance, owner=None):
|
|
@@ -5808,7 +6115,11 @@ class ArgparseArg:
|
|
|
5808
6115
|
|
|
5809
6116
|
|
|
5810
6117
|
def argparse_arg(*args, **kwargs) -> ArgparseArg:
|
|
5811
|
-
return ArgparseArg(
|
|
6118
|
+
return ArgparseArg(
|
|
6119
|
+
args=args,
|
|
6120
|
+
group=kwargs.pop('group', None),
|
|
6121
|
+
kwargs=kwargs,
|
|
6122
|
+
)
|
|
5812
6123
|
|
|
5813
6124
|
|
|
5814
6125
|
def argparse_arg_(*args, **kwargs) -> ta.Any:
|
|
@@ -5978,6 +6289,10 @@ class ArgparseCli:
|
|
|
5978
6289
|
subparser.set_defaults(_cmd=obj)
|
|
5979
6290
|
|
|
5980
6291
|
elif isinstance(obj, ArgparseArg):
|
|
6292
|
+
if obj.group is not None:
|
|
6293
|
+
# FIXME: add_argument_group
|
|
6294
|
+
raise NotImplementedError
|
|
6295
|
+
|
|
5981
6296
|
if att in anns:
|
|
5982
6297
|
ann_kwargs = _get_argparse_arg_ann_kwargs(anns[att])
|
|
5983
6298
|
obj.kwargs = {**ann_kwargs, **obj.kwargs}
|
|
@@ -6023,7 +6338,7 @@ class ArgparseCli:
|
|
|
6023
6338
|
|
|
6024
6339
|
if self._unknown_args and not (cmd is not None and cmd.accepts_unknown):
|
|
6025
6340
|
msg = f'unrecognized arguments: {" ".join(self._unknown_args)}'
|
|
6026
|
-
if (parser := self.get_parser()).exit_on_error:
|
|
6341
|
+
if (parser := self.get_parser()).exit_on_error: # noqa
|
|
6027
6342
|
parser.error(msg)
|
|
6028
6343
|
else:
|
|
6029
6344
|
raise argparse.ArgumentError(None, msg)
|
|
@@ -6043,7 +6358,10 @@ class ArgparseCli:
|
|
|
6043
6358
|
return fn()
|
|
6044
6359
|
|
|
6045
6360
|
def cli_run_and_exit(self) -> ta.NoReturn:
|
|
6046
|
-
|
|
6361
|
+
rc = self.cli_run()
|
|
6362
|
+
if not isinstance(rc, int):
|
|
6363
|
+
rc = 0
|
|
6364
|
+
raise SystemExit(rc)
|
|
6047
6365
|
|
|
6048
6366
|
def __call__(self, *, exit: bool = False) -> ta.Optional[int]: # noqa
|
|
6049
6367
|
if exit:
|
|
@@ -7228,8 +7546,6 @@ class _JustMaybe(_Maybe[T]):
|
|
|
7228
7546
|
__slots__ = ('_v', '_hash')
|
|
7229
7547
|
|
|
7230
7548
|
def __init__(self, v: T) -> None:
|
|
7231
|
-
super().__init__()
|
|
7232
|
-
|
|
7233
7549
|
self._v = v
|
|
7234
7550
|
|
|
7235
7551
|
@property
|
|
@@ -7287,6 +7603,13 @@ class _EmptyMaybe(_Maybe[T]):
|
|
|
7287
7603
|
Maybe._empty = _EmptyMaybe() # noqa
|
|
7288
7604
|
|
|
7289
7605
|
|
|
7606
|
+
##
|
|
7607
|
+
|
|
7608
|
+
|
|
7609
|
+
setattr(Maybe, 'just', _JustMaybe) # noqa
|
|
7610
|
+
setattr(Maybe, 'empty', functools.partial(operator.attrgetter('_empty'), Maybe))
|
|
7611
|
+
|
|
7612
|
+
|
|
7290
7613
|
########################################
|
|
7291
7614
|
# ../../../omlish/lite/runtime.py
|
|
7292
7615
|
|
|
@@ -11889,6 +12212,10 @@ class VerboseCalledProcessError(subprocess.CalledProcessError):
|
|
|
11889
12212
|
class BaseSubprocesses(Abstract):
|
|
11890
12213
|
DEFAULT_LOGGER: ta.ClassVar[ta.Optional[LoggerLike]] = None
|
|
11891
12214
|
|
|
12215
|
+
PIPE: ta.ClassVar[int] = subprocess.PIPE
|
|
12216
|
+
STDOUT: ta.ClassVar[int] = subprocess.STDOUT
|
|
12217
|
+
DEVNULL: ta.ClassVar[int] = subprocess.DEVNULL
|
|
12218
|
+
|
|
11892
12219
|
def __init__(
|
|
11893
12220
|
self,
|
|
11894
12221
|
*,
|
|
@@ -16826,7 +17153,7 @@ class MainCli(ArgparseCli):
|
|
|
16826
17153
|
|
|
16827
17154
|
|
|
16828
17155
|
def _main() -> None:
|
|
16829
|
-
|
|
17156
|
+
raise SystemExit(asyncio.run(MainCli().async_cli_run()))
|
|
16830
17157
|
|
|
16831
17158
|
|
|
16832
17159
|
if __name__ == '__main__':
|