ominfra 0.0.0.dev433__py3-none-any.whl → 0.0.0.dev501__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/README.md +26 -0
- ominfra/__about__.py +5 -2
- ominfra/clouds/aws/instancetypes/cache.json.gz +0 -0
- ominfra/clouds/aws/journald2aws/main.py +1 -1
- ominfra/clouds/aws/models/{base.py → base/__init__.py} +6 -0
- ominfra/clouds/aws/models/base/_dataclasses.py +721 -0
- ominfra/clouds/aws/models/gen/cli.py +2 -1
- ominfra/clouds/aws/models/gen/gen.py +16 -7
- ominfra/clouds/aws/models/services/{ec2.py → ec2/__init__.py} +123 -1
- ominfra/clouds/aws/models/services/ec2/_dataclasses.py +30654 -0
- ominfra/clouds/aws/models/services/{lambda_.py → lambda_/__init__.py} +139 -1
- ominfra/clouds/aws/models/services/lambda_/_dataclasses.py +4182 -0
- ominfra/clouds/aws/models/services/{rds.py → rds/__init__.py} +244 -78
- ominfra/clouds/aws/models/services/rds/_dataclasses.py +8231 -0
- ominfra/clouds/aws/models/services/{s3.py → s3/__init__.py} +9 -1
- ominfra/clouds/aws/models/services/s3/_dataclasses.py +5014 -0
- ominfra/manage/bootstrap_.py +1 -1
- ominfra/manage/main.py +1 -2
- ominfra/manage/targets/bestpython.sh +1 -1
- ominfra/scripts/journald2aws.py +748 -71
- ominfra/scripts/manage.py +824 -99
- ominfra/scripts/supervisor.py +925 -123
- ominfra/supervisor/main.py +1 -1
- {ominfra-0.0.0.dev433.dist-info → ominfra-0.0.0.dev501.dist-info}/METADATA +7 -5
- {ominfra-0.0.0.dev433.dist-info → ominfra-0.0.0.dev501.dist-info}/RECORD +29 -23
- {ominfra-0.0.0.dev433.dist-info → ominfra-0.0.0.dev501.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev433.dist-info → ominfra-0.0.0.dev501.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev433.dist-info → ominfra-0.0.0.dev501.dist-info}/licenses/LICENSE +0 -0
- {ominfra-0.0.0.dev433.dist-info → ominfra-0.0.0.dev501.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,22 +66,160 @@ 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/asyncs.py', sha1='b3f2251c56617ce548abf9c333ac996b63edb23e'),
|
|
86
|
+
dict(path='../../omlish/lite/attrops.py', sha1='c1ebfb8573d766d34593c452a2377208d02726dc'),
|
|
87
|
+
dict(path='../../omlish/lite/cached.py', sha1='0c33cf961ac8f0727284303c7a30c5ea98f714f2'),
|
|
88
|
+
dict(path='../../omlish/lite/check.py', sha1='bb6b6b63333699b84462951a854d99ae83195b94'),
|
|
89
|
+
dict(path='../../omlish/lite/contextmanagers.py', sha1='993f5ed96d3410f739a20363f55670d5e5267fa3'),
|
|
90
|
+
dict(path='../../omlish/lite/json.py', sha1='57eeddc4d23a17931e00284ffa5cb6e3ce089486'),
|
|
91
|
+
dict(path='../../omlish/lite/objects.py', sha1='9566bbf3530fd71fcc56321485216b592fae21e9'),
|
|
92
|
+
dict(path='../../omlish/lite/pycharm.py', sha1='6f84e57f02e2f1075918002f89e4201910d2a15e'),
|
|
93
|
+
dict(path='../../omlish/lite/reflect.py', sha1='c4fec44bf144e9d93293c996af06f6c65fc5e63d'),
|
|
94
|
+
dict(path='../../omlish/lite/resources.py', sha1='1365cb6046eb929358e7c86a3fda20d95fd4a296'),
|
|
95
|
+
dict(path='../../omlish/lite/strings.py', sha1='89831ecbc34ad80e118a865eceb390ed399dc4d6'),
|
|
96
|
+
dict(path='../../omlish/lite/typing.py', sha1='048bb5fb8ecad5be101516f8f3b7996707f5bc42'),
|
|
97
|
+
dict(path='../../omlish/logs/levels.py', sha1='91405563d082a5eba874da82aac89d83ce7b6152'),
|
|
98
|
+
dict(path='../../omlish/logs/std/filters.py', sha1='f36aab646d84d31e295b33aaaaa6f8b67ff38b3d'),
|
|
99
|
+
dict(path='../../omlish/logs/std/proxy.py', sha1='3e7301a2aa351127f9c85f61b2f85dcc3f15aafb'),
|
|
100
|
+
dict(path='../../omlish/logs/warnings.py', sha1='c4eb694b24773351107fcc058f3620f1dbfb6799'),
|
|
101
|
+
dict(path='../../omlish/os/deathsig.py', sha1='5d3f1a22132b7029d32e29b13c1cc20497c8f7a8'),
|
|
102
|
+
dict(path='../../omlish/os/environ.py', sha1='5e9ed4817af65683b496af49fef996630c3113b1'),
|
|
103
|
+
dict(path='../../omlish/os/linux.py', sha1='b6433d321eba7afab353b04107819fdc72f1d836'),
|
|
104
|
+
dict(path='../../omlish/os/paths.py', sha1='56c40b7c2aa84d1778d60ee4cda498f8c380cc8d'),
|
|
105
|
+
dict(path='../../omlish/shlex.py', sha1='a69721913bcd4f4008600e390fb7822637c2a8ec'),
|
|
106
|
+
dict(path='../../omdev/home/paths.py', sha1='a83516c97a2e99e79153a414db3d23091186bb23'),
|
|
107
|
+
dict(path='../../omdev/packaging/specifiers.py', sha1='a56ab4e8c9b174adb523921f6280ac41e0fce749'),
|
|
108
|
+
dict(path='deploy/paths/specs.py', sha1='023167da1ad9fcf09d9d44963177175591a97377'),
|
|
109
|
+
dict(path='remote/config.py', sha1='48f9367e9db4b23166657ff34eb644c9869d48a8'),
|
|
110
|
+
dict(path='remote/payload.py', sha1='acacf4c2901b7708224af5d4414ecb823947297a'),
|
|
111
|
+
dict(path='targets/bestpython.py', sha1='75c16ab86397a8e81017f148a2ef711567b6ab27'),
|
|
112
|
+
dict(path='targets/targets.py', sha1='d07f2d30c31bad89bd4a3b44bb6a5b6c95c05888'),
|
|
113
|
+
dict(path='../../omlish/argparse/cli.py', sha1='f4dc3cd353d14386b5da0306768700e396afd2b3'),
|
|
114
|
+
dict(path='../../omlish/configs/formats.py', sha1='9bc4f953b4b8700f6f109e6f49e2d70f8e48ce7c'),
|
|
115
|
+
dict(path='../../omlish/lite/marshal.py', sha1='96348f5f2a26dc27d842d33cc3927e9da163436b'),
|
|
116
|
+
dict(path='../../omlish/lite/maybes.py', sha1='04d2fcbea17028a5e6b8e7a7fb742375495ed233'),
|
|
117
|
+
dict(path='../../omlish/lite/runtime.py', sha1='2e752a27ae2bf89b1bb79b4a2da522a3ec360c70'),
|
|
118
|
+
dict(path='../../omlish/lite/timeouts.py', sha1='a0f673033a6943f242e35848d78a41892b9c62a1'),
|
|
119
|
+
dict(path='../../omlish/logs/infos.py', sha1='4dd104bd468a8c438601dd0bbda619b47d2f1620'),
|
|
120
|
+
dict(path='../../omlish/logs/protocols.py', sha1='05ca4d1d7feb50c4e3b9f22ee371aa7bf4b3dbd1'),
|
|
121
|
+
dict(path='../../omlish/logs/std/json.py', sha1='2a75553131e4d5331bb0cedde42aa183f403fc3b'),
|
|
122
|
+
dict(path='../../omlish/os/atomics.py', sha1='ccb62620b95f60ac50561c283d50e5fcfdccb215'),
|
|
123
|
+
dict(path='../../omlish/text/indent.py', sha1='cc23647bdcd8d26c8afe9e36a0aefb32da58cbb8'),
|
|
124
|
+
dict(path='../../omdev/interp/types.py', sha1='caf068a6e81fb6e221d777b341ac5777d92b8091'),
|
|
125
|
+
dict(path='commands/base.py', sha1='17310f7272b6ac7b6438e32bfd7b24004d284399'),
|
|
126
|
+
dict(path='deploy/conf/specs.py', sha1='d191fa887c59198f5eff5c62414031204a76fa65'),
|
|
127
|
+
dict(path='deploy/tags.py', sha1='e6e7a1f4fcee9f5764acbe7f307b31e26f81bbc3'),
|
|
128
|
+
dict(path='marshal.py', sha1='175f59215a92afd42468f6258f1202b9ec3362cb'),
|
|
129
|
+
dict(path='remote/channel.py', sha1='2b6498da48ff89901b88a6a1ef84c58b37ddb410'),
|
|
130
|
+
dict(path='../../omlish/asyncs/asyncio/timeouts.py', sha1='4d31b02b3c39b8f2fa7e94db36552fde6942e36a'),
|
|
131
|
+
dict(path='../../omlish/configs/nginx.py', sha1='d0ad33c21674fc02f23281247517c827f455eb0b'),
|
|
132
|
+
dict(path='../../omlish/lite/configs.py', sha1='c8602e0e197ef1133e7e8e248935ac745bfd46cb'),
|
|
133
|
+
dict(path='../../omlish/lite/inject.py', sha1='6f097e3170019a34ff6834d36fcc9cbeed3a7ab4'),
|
|
134
|
+
dict(path='../../omlish/logs/contexts.py', sha1='1000a6d5ddfb642865ca532e34b1d50759781cf0'),
|
|
135
|
+
dict(path='../../omlish/logs/std/standard.py', sha1='5c97c1b9f7ead58d6127d047b873398f708f288d'),
|
|
136
|
+
dict(path='../../omlish/subprocesses/run.py', sha1='8200e48f0c49d164df3503cd0143038d0c4d30aa'),
|
|
137
|
+
dict(path='../../omlish/subprocesses/wrap.py', sha1='8a9b7d2255481fae15c05f5624b0cdc0766f4b3f'),
|
|
138
|
+
dict(path='../../omdev/interp/providers/base.py', sha1='f5d068c21f230d742e9015b033cd6320f4c68898'),
|
|
139
|
+
dict(path='commands/injection.py', sha1='f7d8aec3c33efc61da1f0c6700bdfbe7bcc10e56'),
|
|
140
|
+
dict(path='commands/marshal.py', sha1='a21c3a75fe17bb80d32d10a3d5524d67a96ea210'),
|
|
141
|
+
dict(path='commands/ping.py', sha1='af4c34e9b1811269c954cf502b336a6446639a2a'),
|
|
142
|
+
dict(path='commands/types.py', sha1='10b88571981b9964287f30f27abf6d09400b51c6'),
|
|
143
|
+
dict(path='deploy/paths/paths.py', sha1='bf7794e998caa1611277ac5809eb7ec91a76d1e8'),
|
|
144
|
+
dict(path='deploy/specs.py', sha1='b3a411b32b47f81f5ad673d8b0338970a6eb6ff9'),
|
|
145
|
+
dict(path='../../omlish/logs/base.py', sha1='8d06faee05fead6b1dd98c9035a5b042af4aebb1'),
|
|
146
|
+
dict(path='../../omlish/logs/std/records.py', sha1='8bbf6ef9eccb3a012c6ca416ddf3969450fd8fc9'),
|
|
147
|
+
dict(path='../../omlish/subprocesses/base.py', sha1='cb9f668be5422fecb27222caabb67daac6c1bab9'),
|
|
148
|
+
dict(path='../../omdev/interp/resolvers.py', sha1='817b8e76401cd7a19eb43ca54d65272e4c8a4b0e'),
|
|
149
|
+
dict(path='commands/local.py', sha1='db3c5b0a1f067f54e2133234e36e7db393e4dec3'),
|
|
150
|
+
dict(path='deploy/conf/manager.py', sha1='7450a8616dbc46f6c68387192035a6ea258aebe2'),
|
|
151
|
+
dict(path='deploy/paths/owners.py', sha1='382bcec4824f0fc71dddf083c6e88748b5c62ef2'),
|
|
152
|
+
dict(path='../../omlish/logs/asyncs.py', sha1='ab11b70033d9f2e9a4e70254185aa1c6130c6077'),
|
|
153
|
+
dict(path='../../omlish/logs/std/loggers.py', sha1='a569179445d6a8a942b5dcfad1d1f77702868803'),
|
|
154
|
+
dict(path='../../omlish/subprocesses/asyncs.py', sha1='bba44d524c24c6ac73168aee6343488414e5bf48'),
|
|
155
|
+
dict(path='../../omlish/subprocesses/sync.py', sha1='8434919eba4da67825773d56918fdc0cb2f1883b'),
|
|
156
|
+
dict(path='../../omdev/git/shallow.py', sha1='7b5f9d77b7a01df5828ca61a2adc6dae54cf676b'),
|
|
157
|
+
dict(path='deploy/injection.py', sha1='7d641dd20ff0c75de5679079c52647653849d6cc'),
|
|
158
|
+
dict(path='deploy/paths/manager.py', sha1='eb1c84e0ca03083f69b53cee25bf7ffd752cc7a9'),
|
|
159
|
+
dict(path='deploy/tmp.py', sha1='d8b7aeaa26ab58e64aba371d46bc661462d47c5e'),
|
|
160
|
+
dict(path='../../omlish/asyncs/asyncio/subprocesses.py', sha1='b6b5f9ae3fd0b9c83593bad2e04a08f726e5904d'),
|
|
161
|
+
dict(path='../../omlish/logs/modules.py', sha1='dd7d5f8e63fe8829dfb49460f3929ab64b68ee14'),
|
|
162
|
+
dict(path='../../omdev/interp/inspect.py', sha1='736287b4ec8d14a8c30afa0ba23996fdc0662caa'),
|
|
163
|
+
dict(path='../../omdev/interp/pyenv/pyenv.py', sha1='d1f6e657c671c1b1a5b0e627284df656fe2d10d3'),
|
|
164
|
+
dict(path='../../omdev/interp/uv/uv.py', sha1='8c6515cd6755efab3972da92a285e94ccb255515'),
|
|
165
|
+
dict(path='commands/subprocess.py', sha1='788bd859701fce066bd00c820919f826b43b8b57'),
|
|
166
|
+
dict(path='deploy/conf/inject.py', sha1='d006b45d92f3b5f30a797b65fbed23f90c3db490'),
|
|
167
|
+
dict(path='deploy/git.py', sha1='5ee2e816e18fef493cb2ccc33f33ad673175ad7a'),
|
|
168
|
+
dict(path='deploy/paths/inject.py', sha1='1c501d086fcbde9c2b9ead21fc3c7b175bbf4f76'),
|
|
169
|
+
dict(path='deploy/systemd.py', sha1='773c4482e85a974443bb26237a86b1dfbcd9936c'),
|
|
170
|
+
dict(path='remote/execution.py', sha1='005da809e58790a0e5255df8e57afd5cd6268d7d'),
|
|
171
|
+
dict(path='remote/spawning.py', sha1='9cb6b5da1ba6daabb35a5742be647748c01d40d3'),
|
|
172
|
+
dict(path='system/packages.py', sha1='9988fc93dbca9336c378bf5fad6f68f5b8c0260e'),
|
|
173
|
+
dict(path='system/platforms.py', sha1='f3fc312318cff15f97dd9b10fa5f2408abc45a1b'),
|
|
174
|
+
dict(path='../../omdev/interp/providers/running.py', sha1='85c9cc69ff6fbd6c8cf78ed6262619a30856c2f1'),
|
|
175
|
+
dict(path='../../omdev/interp/providers/system.py', sha1='9638a154475ca98775159d27739563ac7fb2eb16'),
|
|
176
|
+
dict(path='../../omdev/interp/pyenv/install.py', sha1='4a10a19717364b4ba9f3b8bf1d12621cf21ba8b8'),
|
|
177
|
+
dict(path='../../omdev/interp/uv/provider.py', sha1='3c3980878ad2b9fd2cd02172f9424954759c7f06'),
|
|
178
|
+
dict(path='commands/inject.py', sha1='7a95b6487b01230dd2fe0d9f67382d8889039e7b'),
|
|
179
|
+
dict(path='system/commands.py', sha1='17bbaa945b6ded0a88d31c52b410cbce8fc324a0'),
|
|
180
|
+
dict(path='system/config.py', sha1='fd1ebc2cf36fd312ff69d1af100a7e9c638f1fcc'),
|
|
181
|
+
dict(path='../../omdev/interp/providers/inject.py', sha1='7cc9ebf58cf2ec09545321456bd9da9f9a3a79fb'),
|
|
182
|
+
dict(path='../../omdev/interp/pyenv/provider.py', sha1='377542ce01a35849e2a5b4a4dbafedc26882f983'),
|
|
183
|
+
dict(path='../../omdev/interp/uv/inject.py', sha1='e95d058c2340baa5a3155ec3440f311d1daa10a8'),
|
|
184
|
+
dict(path='bootstrap.py', sha1='e66138947a41e8a49576885cf4b1390315d44f88'),
|
|
185
|
+
dict(path='system/inject.py', sha1='8a34be1b982cb42981c08306f12994a0fff258bd'),
|
|
186
|
+
dict(path='../../omdev/interp/pyenv/inject.py', sha1='b8fb68f5a7cae86c70fe1bad6c29a8b2dfc985c3'),
|
|
187
|
+
dict(path='remote/_main.py', sha1='5ae1dc673ce22f2d40612c66b3a5c3d01ebb6718'),
|
|
188
|
+
dict(path='../../omdev/interp/inject.py', sha1='b039abbadf0b096d2724182af2e0ebda2a230852'),
|
|
189
|
+
dict(path='remote/connection.py', sha1='18bc6c4a446a9bef3c54b861a01418b1b7ba39ff'),
|
|
190
|
+
dict(path='../../omdev/interp/default.py', sha1='a799969a0d3f4b57538587b13ceb08f6334ebc16'),
|
|
191
|
+
dict(path='remote/inject.py', sha1='8713a421b18ff7625c95017616380f0500c3c39c'),
|
|
192
|
+
dict(path='targets/connection.py', sha1='891f1d35ee3814bed32e6de71e1ca47574635da1'),
|
|
193
|
+
dict(path='deploy/interp.py', sha1='89371a87a275fea2e8566a0983e4906cda46a105'),
|
|
194
|
+
dict(path='deploy/venvs.py', sha1='7ad41a11098dd68d83a0804d2ea95779d0be4de0'),
|
|
195
|
+
dict(path='targets/inject.py', sha1='e4bfba31b044da9545d4c00965e7e15b97a40cce'),
|
|
196
|
+
dict(path='deploy/apps.py', sha1='6df5d728b6715583a792d1e92268c0c07502509f'),
|
|
197
|
+
dict(path='deploy/deploy.py', sha1='635f84ad370b22797406d2ae55d78621ea1f7b2b'),
|
|
198
|
+
dict(path='deploy/commands.py', sha1='0e9fdd122fe3a4028efede0862b059c091cc13cb'),
|
|
199
|
+
dict(path='deploy/inject.py', sha1='d84e9c3e980c5a1ec62d18628d8911f5b6bb125f'),
|
|
200
|
+
dict(path='inject.py', sha1='b1c173df021f190d3631f3828470fa1564e0b4b4'),
|
|
201
|
+
dict(path='bootstrap_.py', sha1='96fff62e0152795271c79ea29face58dadab0894'),
|
|
202
|
+
dict(path='main.py', sha1='ddddcdb54aabe67188dce6a5f65e04ce296a75b0'),
|
|
203
|
+
],
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
|
|
68
207
|
########################################
|
|
69
208
|
|
|
70
209
|
|
|
71
210
|
# ../../omdev/packaging/versions.py
|
|
72
|
-
VersionLocalType = ta.Tuple[ta.Union[int, str], ...]
|
|
73
|
-
VersionCmpPrePostDevType = ta.Union['InfinityVersionType', 'NegativeInfinityVersionType', ta.Tuple[str, int]]
|
|
74
|
-
_VersionCmpLocalType0 = ta.Tuple[ta.Union[ta.Tuple[int, str], ta.Tuple['NegativeInfinityVersionType', ta.Union[int, str]]], ...] # noqa
|
|
75
|
-
VersionCmpLocalType = ta.Union['NegativeInfinityVersionType', _VersionCmpLocalType0]
|
|
76
|
-
VersionCmpKey = ta.Tuple[int, ta.Tuple[int, ...], VersionCmpPrePostDevType, VersionCmpPrePostDevType, VersionCmpPrePostDevType, VersionCmpLocalType] # noqa
|
|
77
|
-
VersionComparisonMethod = ta.Callable[[VersionCmpKey, VersionCmpKey], bool]
|
|
211
|
+
VersionLocalType = ta.Tuple[ta.Union[int, str], ...] # ta.TypeAlias
|
|
212
|
+
VersionCmpPrePostDevType = ta.Union['InfinityVersionType', 'NegativeInfinityVersionType', ta.Tuple[str, int]] # ta.TypeAlias # noqa
|
|
213
|
+
_VersionCmpLocalType0 = ta.Tuple[ta.Union[ta.Tuple[int, str], ta.Tuple['NegativeInfinityVersionType', ta.Union[int, str]]], ...] # ta.TypeAlias # noqa
|
|
214
|
+
VersionCmpLocalType = ta.Union['NegativeInfinityVersionType', _VersionCmpLocalType0] # ta.TypeAlias
|
|
215
|
+
VersionCmpKey = ta.Tuple[int, ta.Tuple[int, ...], VersionCmpPrePostDevType, VersionCmpPrePostDevType, VersionCmpPrePostDevType, VersionCmpLocalType] # ta.TypeAlias # noqa
|
|
216
|
+
VersionComparisonMethod = ta.Callable[[VersionCmpKey, VersionCmpKey], bool] # ta.TypeAlias
|
|
78
217
|
|
|
79
218
|
# deploy/paths/types.py
|
|
80
219
|
DeployPathKind = ta.Literal['dir', 'file'] # ta.TypeAlias
|
|
81
220
|
|
|
82
221
|
# ../../omlish/configs/types.py
|
|
83
|
-
ConfigMap = ta.Mapping[str, ta.Any]
|
|
222
|
+
ConfigMap = ta.Mapping[str, ta.Any] # ta.TypeAlias
|
|
84
223
|
|
|
85
224
|
# ../../omlish/formats/ini/sections.py
|
|
86
225
|
IniSectionSettingsMap = ta.Mapping[str, ta.Mapping[str, ta.Union[str, ta.Sequence[str]]]] # ta.TypeAlias
|
|
@@ -90,7 +229,7 @@ TomlParseFloat = ta.Callable[[str], ta.Any] # ta.TypeAlias
|
|
|
90
229
|
TomlKey = ta.Tuple[str, ...] # ta.TypeAlias
|
|
91
230
|
TomlPos = int # ta.TypeAlias
|
|
92
231
|
|
|
93
|
-
# ../../omlish/lite/
|
|
232
|
+
# ../../omlish/lite/abstract.py
|
|
94
233
|
T = ta.TypeVar('T')
|
|
95
234
|
|
|
96
235
|
# ../../omlish/lite/cached.py
|
|
@@ -117,9 +256,9 @@ A2 = ta.TypeVar('A2')
|
|
|
117
256
|
LogLevel = int # ta.TypeAlias
|
|
118
257
|
|
|
119
258
|
# ../../omdev/packaging/specifiers.py
|
|
120
|
-
UnparsedVersion = ta.Union['Version', str]
|
|
259
|
+
UnparsedVersion = ta.Union['Version', str] # ta.TypeAlias
|
|
121
260
|
UnparsedVersionVar = ta.TypeVar('UnparsedVersionVar', bound=UnparsedVersion)
|
|
122
|
-
CallableVersionOperator = ta.Callable[['Version', str], bool]
|
|
261
|
+
CallableVersionOperator = ta.Callable[['Version', str], bool] # ta.TypeAlias
|
|
123
262
|
|
|
124
263
|
# ../../omlish/argparse/cli.py
|
|
125
264
|
ArgparseCmdFn = ta.Callable[[], ta.Optional[int]] # ta.TypeAlias
|
|
@@ -141,7 +280,7 @@ LoggingExcInfoArg = ta.Union[LoggingExcInfo, bool, None] # ta.TypeAlias
|
|
|
141
280
|
LoggingContextInfo = ta.Any # ta.TypeAlias
|
|
142
281
|
|
|
143
282
|
# ../../omlish/os/atomics.py
|
|
144
|
-
AtomicPathSwapKind = ta.Literal['dir', 'file']
|
|
283
|
+
AtomicPathSwapKind = ta.Literal['dir', 'file'] # ta.TypeAlias
|
|
145
284
|
AtomicPathSwapState = ta.Literal['open', 'committed', 'aborted'] # ta.TypeAlias
|
|
146
285
|
|
|
147
286
|
# commands/base.py
|
|
@@ -152,10 +291,10 @@ CommandOutputT = ta.TypeVar('CommandOutputT', bound='Command.Output')
|
|
|
152
291
|
AwaitableT = ta.TypeVar('AwaitableT', bound=ta.Awaitable)
|
|
153
292
|
|
|
154
293
|
# ../../omlish/lite/inject.py
|
|
155
|
-
InjectorKeyCls = ta.Union[type, ta.NewType]
|
|
156
|
-
InjectorProviderFn = ta.Callable[['Injector'], ta.Any]
|
|
157
|
-
InjectorProviderFnMap = ta.Mapping['InjectorKey', 'InjectorProviderFn']
|
|
158
|
-
InjectorBindingOrBindings = ta.Union['InjectorBinding', 'InjectorBindings']
|
|
294
|
+
InjectorKeyCls = ta.Union[type, ta.NewType] # ta.TypeAlias
|
|
295
|
+
InjectorProviderFn = ta.Callable[['Injector'], ta.Any] # ta.TypeAlias
|
|
296
|
+
InjectorProviderFnMap = ta.Mapping['InjectorKey', 'InjectorProviderFn'] # ta.TypeAlias
|
|
297
|
+
InjectorBindingOrBindings = ta.Union['InjectorBinding', 'InjectorBindings'] # ta.TypeAlias
|
|
159
298
|
|
|
160
299
|
# ../../omlish/logs/contexts.py
|
|
161
300
|
LoggingContextInfoT = ta.TypeVar('LoggingContextInfoT', bound=LoggingContextInfo)
|
|
@@ -281,12 +420,12 @@ class _BaseVersion:
|
|
|
281
420
|
|
|
282
421
|
def __lt__(self, other: '_BaseVersion') -> bool:
|
|
283
422
|
if not isinstance(other, _BaseVersion):
|
|
284
|
-
return NotImplemented
|
|
423
|
+
return NotImplemented
|
|
285
424
|
return self._key < other._key
|
|
286
425
|
|
|
287
426
|
def __le__(self, other: '_BaseVersion') -> bool:
|
|
288
427
|
if not isinstance(other, _BaseVersion):
|
|
289
|
-
return NotImplemented
|
|
428
|
+
return NotImplemented
|
|
290
429
|
return self._key <= other._key
|
|
291
430
|
|
|
292
431
|
def __eq__(self, other: object) -> bool:
|
|
@@ -296,12 +435,12 @@ class _BaseVersion:
|
|
|
296
435
|
|
|
297
436
|
def __ge__(self, other: '_BaseVersion') -> bool:
|
|
298
437
|
if not isinstance(other, _BaseVersion):
|
|
299
|
-
return NotImplemented
|
|
438
|
+
return NotImplemented
|
|
300
439
|
return self._key >= other._key
|
|
301
440
|
|
|
302
441
|
def __gt__(self, other: '_BaseVersion') -> bool:
|
|
303
442
|
if not isinstance(other, _BaseVersion):
|
|
304
|
-
return NotImplemented
|
|
443
|
+
return NotImplemented
|
|
305
444
|
return self._key > other._key
|
|
306
445
|
|
|
307
446
|
def __ne__(self, other: object) -> bool:
|
|
@@ -2394,25 +2533,49 @@ def is_abstract_method(obj: ta.Any) -> bool:
|
|
|
2394
2533
|
return bool(getattr(obj, _IS_ABSTRACT_METHOD_ATTR, False))
|
|
2395
2534
|
|
|
2396
2535
|
|
|
2397
|
-
def
|
|
2536
|
+
def compute_abstract_methods(cls: type) -> ta.FrozenSet[str]:
|
|
2537
|
+
# ~> https://github.com/python/cpython/blob/f3476c6507381ca860eec0989f53647b13517423/Modules/_abc.c#L358
|
|
2538
|
+
|
|
2539
|
+
# Stage 1: direct abstract methods
|
|
2540
|
+
|
|
2541
|
+
abstracts = {
|
|
2542
|
+
a
|
|
2543
|
+
# Get items as a list to avoid mutation issues during iteration
|
|
2544
|
+
for a, v in list(cls.__dict__.items())
|
|
2545
|
+
if is_abstract_method(v)
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
# Stage 2: inherited abstract methods
|
|
2549
|
+
|
|
2550
|
+
for base in cls.__bases__:
|
|
2551
|
+
# Get __abstractmethods__ from base if it exists
|
|
2552
|
+
if (base_abstracts := getattr(base, _ABSTRACT_METHODS_ATTR, None)) is None:
|
|
2553
|
+
continue
|
|
2554
|
+
|
|
2555
|
+
# Iterate over abstract methods in base
|
|
2556
|
+
for key in base_abstracts:
|
|
2557
|
+
# Check if this class has an attribute with this name
|
|
2558
|
+
try:
|
|
2559
|
+
value = getattr(cls, key)
|
|
2560
|
+
except AttributeError:
|
|
2561
|
+
# Attribute not found in this class, skip
|
|
2562
|
+
continue
|
|
2563
|
+
|
|
2564
|
+
# Check if it's still abstract
|
|
2565
|
+
if is_abstract_method(value):
|
|
2566
|
+
abstracts.add(key)
|
|
2567
|
+
|
|
2568
|
+
return frozenset(abstracts)
|
|
2569
|
+
|
|
2570
|
+
|
|
2571
|
+
def update_abstracts(cls: ta.Type[T], *, force: bool = False) -> ta.Type[T]:
|
|
2398
2572
|
if not force and not hasattr(cls, _ABSTRACT_METHODS_ATTR):
|
|
2399
2573
|
# Per stdlib: We check for __abstractmethods__ here because cls might by a C implementation or a python
|
|
2400
2574
|
# implementation (especially during testing), and we want to handle both cases.
|
|
2401
2575
|
return cls
|
|
2402
2576
|
|
|
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))
|
|
2577
|
+
abstracts = compute_abstract_methods(cls)
|
|
2578
|
+
setattr(cls, _ABSTRACT_METHODS_ATTR, abstracts)
|
|
2416
2579
|
return cls
|
|
2417
2580
|
|
|
2418
2581
|
|
|
@@ -2466,23 +2629,26 @@ class Abstract:
|
|
|
2466
2629
|
super().__init_subclass__(**kwargs)
|
|
2467
2630
|
|
|
2468
2631
|
if not (Abstract in cls.__bases__ or abc.ABC in cls.__bases__):
|
|
2469
|
-
ams
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2632
|
+
if ams := compute_abstract_methods(cls):
|
|
2633
|
+
amd = {
|
|
2634
|
+
a: mcls
|
|
2635
|
+
for mcls in cls.__mro__[::-1]
|
|
2636
|
+
for a in ams
|
|
2637
|
+
if a in mcls.__dict__
|
|
2638
|
+
}
|
|
2475
2639
|
|
|
2476
|
-
if ams:
|
|
2477
2640
|
raise AbstractTypeError(
|
|
2478
2641
|
f'Cannot subclass abstract class {cls.__name__} with abstract methods: ' +
|
|
2479
2642
|
', '.join(sorted([
|
|
2480
2643
|
'.'.join([
|
|
2481
|
-
*([
|
|
2482
|
-
|
|
2644
|
+
*([
|
|
2645
|
+
*([m] if (m := getattr(c, '__module__')) else []),
|
|
2646
|
+
getattr(c, '__qualname__', getattr(c, '__name__')),
|
|
2647
|
+
] if c is not None else '?'),
|
|
2483
2648
|
a,
|
|
2484
2649
|
])
|
|
2485
|
-
for a
|
|
2650
|
+
for a in ams
|
|
2651
|
+
for c in [amd.get(a)]
|
|
2486
2652
|
])),
|
|
2487
2653
|
)
|
|
2488
2654
|
|
|
@@ -2499,6 +2665,150 @@ class Abstract:
|
|
|
2499
2665
|
update_abstracts(cls, force=True)
|
|
2500
2666
|
|
|
2501
2667
|
|
|
2668
|
+
########################################
|
|
2669
|
+
# ../../../omlish/lite/asyncs.py
|
|
2670
|
+
|
|
2671
|
+
|
|
2672
|
+
##
|
|
2673
|
+
|
|
2674
|
+
|
|
2675
|
+
async def opt_await(aw: ta.Optional[ta.Awaitable[T]]) -> ta.Optional[T]:
|
|
2676
|
+
return (await aw if aw is not None else None)
|
|
2677
|
+
|
|
2678
|
+
|
|
2679
|
+
async def async_list(ai: ta.AsyncIterable[T]) -> ta.List[T]:
|
|
2680
|
+
return [v async for v in ai]
|
|
2681
|
+
|
|
2682
|
+
|
|
2683
|
+
async def async_enumerate(ai: ta.AsyncIterable[T]) -> ta.AsyncIterable[ta.Tuple[int, T]]:
|
|
2684
|
+
i = 0
|
|
2685
|
+
async for e in ai:
|
|
2686
|
+
yield (i, e)
|
|
2687
|
+
i += 1
|
|
2688
|
+
|
|
2689
|
+
|
|
2690
|
+
##
|
|
2691
|
+
|
|
2692
|
+
|
|
2693
|
+
def as_async(fn: ta.Callable[..., T], *, wrap: bool = False) -> ta.Callable[..., ta.Awaitable[T]]:
|
|
2694
|
+
async def inner(*args, **kwargs):
|
|
2695
|
+
return fn(*args, **kwargs)
|
|
2696
|
+
|
|
2697
|
+
return functools.wraps(fn)(inner) if wrap else inner
|
|
2698
|
+
|
|
2699
|
+
|
|
2700
|
+
##
|
|
2701
|
+
|
|
2702
|
+
|
|
2703
|
+
class SyncAwaitCoroutineNotTerminatedError(Exception):
|
|
2704
|
+
pass
|
|
2705
|
+
|
|
2706
|
+
|
|
2707
|
+
def sync_await(aw: ta.Awaitable[T]) -> T:
|
|
2708
|
+
"""
|
|
2709
|
+
Allows for the synchronous execution of async functions which will never actually *externally* await anything. These
|
|
2710
|
+
functions are allowed to await any number of other functions - including contextmanagers and generators - so long as
|
|
2711
|
+
nothing ever actually 'leaks' out of the function, presumably to an event loop.
|
|
2712
|
+
"""
|
|
2713
|
+
|
|
2714
|
+
ret = missing = object()
|
|
2715
|
+
|
|
2716
|
+
async def thunk():
|
|
2717
|
+
nonlocal ret
|
|
2718
|
+
|
|
2719
|
+
ret = await aw
|
|
2720
|
+
|
|
2721
|
+
cr = thunk()
|
|
2722
|
+
try:
|
|
2723
|
+
try:
|
|
2724
|
+
cr.send(None)
|
|
2725
|
+
except StopIteration:
|
|
2726
|
+
pass
|
|
2727
|
+
|
|
2728
|
+
if ret is missing or cr.cr_await is not None or cr.cr_running:
|
|
2729
|
+
raise SyncAwaitCoroutineNotTerminatedError('Not terminated')
|
|
2730
|
+
|
|
2731
|
+
finally:
|
|
2732
|
+
cr.close()
|
|
2733
|
+
|
|
2734
|
+
return ta.cast(T, ret)
|
|
2735
|
+
|
|
2736
|
+
|
|
2737
|
+
#
|
|
2738
|
+
|
|
2739
|
+
|
|
2740
|
+
def sync_aiter(ai: ta.AsyncIterator[T]) -> ta.Iterator[T]:
|
|
2741
|
+
while True:
|
|
2742
|
+
try:
|
|
2743
|
+
o = sync_await(ai.__anext__())
|
|
2744
|
+
except StopAsyncIteration:
|
|
2745
|
+
break
|
|
2746
|
+
yield o
|
|
2747
|
+
|
|
2748
|
+
|
|
2749
|
+
def sync_async_list(ai: ta.AsyncIterable[T]) -> ta.List[T]:
|
|
2750
|
+
"""
|
|
2751
|
+
Uses `sync_await` to synchronously read the full contents of a function call returning an async iterator, given that
|
|
2752
|
+
the function never externally awaits anything.
|
|
2753
|
+
"""
|
|
2754
|
+
|
|
2755
|
+
lst: ta.Optional[ta.List[T]] = None
|
|
2756
|
+
|
|
2757
|
+
async def inner():
|
|
2758
|
+
nonlocal lst
|
|
2759
|
+
|
|
2760
|
+
lst = [v async for v in ai]
|
|
2761
|
+
|
|
2762
|
+
sync_await(inner())
|
|
2763
|
+
|
|
2764
|
+
if not isinstance(lst, list):
|
|
2765
|
+
raise TypeError(lst)
|
|
2766
|
+
|
|
2767
|
+
return lst
|
|
2768
|
+
|
|
2769
|
+
|
|
2770
|
+
#
|
|
2771
|
+
|
|
2772
|
+
|
|
2773
|
+
@ta.final
|
|
2774
|
+
class SyncAwaitContextManager(ta.Generic[T]):
|
|
2775
|
+
def __init__(self, acm: ta.AsyncContextManager[T]) -> None:
|
|
2776
|
+
self._acm = acm
|
|
2777
|
+
|
|
2778
|
+
def __repr__(self) -> str:
|
|
2779
|
+
return f'{self.__class__.__name__}({self._acm!r})'
|
|
2780
|
+
|
|
2781
|
+
def __enter__(self) -> T:
|
|
2782
|
+
return sync_await(self._acm.__aenter__())
|
|
2783
|
+
|
|
2784
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
2785
|
+
return sync_await(self._acm.__aexit__(exc_type, exc_val, exc_tb))
|
|
2786
|
+
|
|
2787
|
+
|
|
2788
|
+
sync_async_with = SyncAwaitContextManager
|
|
2789
|
+
|
|
2790
|
+
|
|
2791
|
+
##
|
|
2792
|
+
|
|
2793
|
+
|
|
2794
|
+
@ta.final
|
|
2795
|
+
class SyncToAsyncContextManager(ta.Generic[T]):
|
|
2796
|
+
def __init__(self, cm: ta.ContextManager[T]) -> None:
|
|
2797
|
+
self._cm = cm
|
|
2798
|
+
|
|
2799
|
+
def __repr__(self) -> str:
|
|
2800
|
+
return f'{self.__class__.__name__}({self._cm!r})'
|
|
2801
|
+
|
|
2802
|
+
async def __aenter__(self) -> T:
|
|
2803
|
+
return self._cm.__enter__()
|
|
2804
|
+
|
|
2805
|
+
async def __aexit__(self, exc_type, exc_value, traceback, /):
|
|
2806
|
+
return self._cm.__exit__(exc_type, exc_value, traceback)
|
|
2807
|
+
|
|
2808
|
+
|
|
2809
|
+
as_async_context_manager = SyncToAsyncContextManager
|
|
2810
|
+
|
|
2811
|
+
|
|
2502
2812
|
########################################
|
|
2503
2813
|
# ../../../omlish/lite/attrops.py
|
|
2504
2814
|
"""
|
|
@@ -2507,6 +2817,8 @@ TODO:
|
|
|
2507
2817
|
- per-attr repr transform / filter
|
|
2508
2818
|
- __ne__ ? cases where it still matters
|
|
2509
2819
|
- ordering ?
|
|
2820
|
+
- repr_filter: ta.Union[ta.Callable[[ta.Any], ta.Optional[str]], ta.Literal['not_none', 'truthy']]] ?
|
|
2821
|
+
- unify repr/repr_fn/repr_filter
|
|
2510
2822
|
"""
|
|
2511
2823
|
|
|
2512
2824
|
|
|
@@ -2524,6 +2836,8 @@ class AttrOps(ta.Generic[T]):
|
|
|
2524
2836
|
display: ta.Optional[str] = None,
|
|
2525
2837
|
|
|
2526
2838
|
repr: bool = True, # noqa
|
|
2839
|
+
repr_fn: ta.Optional[ta.Callable[[ta.Any], ta.Optional[str]]] = None,
|
|
2840
|
+
|
|
2527
2841
|
hash: bool = True, # noqa
|
|
2528
2842
|
eq: bool = True,
|
|
2529
2843
|
) -> None:
|
|
@@ -2538,6 +2852,8 @@ class AttrOps(ta.Generic[T]):
|
|
|
2538
2852
|
self._display = display
|
|
2539
2853
|
|
|
2540
2854
|
self._repr = repr
|
|
2855
|
+
self._repr_fn = repr_fn
|
|
2856
|
+
|
|
2541
2857
|
self._hash = hash
|
|
2542
2858
|
self._eq = eq
|
|
2543
2859
|
|
|
@@ -2545,21 +2861,30 @@ class AttrOps(ta.Generic[T]):
|
|
|
2545
2861
|
def of(
|
|
2546
2862
|
cls,
|
|
2547
2863
|
o: ta.Union[
|
|
2548
|
-
str,
|
|
2549
|
-
ta.Tuple[str, str],
|
|
2550
2864
|
'AttrOps.Attr',
|
|
2865
|
+
str,
|
|
2866
|
+
ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
|
|
2867
|
+
ta.Mapping[str, ta.Any],
|
|
2551
2868
|
],
|
|
2552
2869
|
) -> 'AttrOps.Attr':
|
|
2553
2870
|
if isinstance(o, AttrOps.Attr):
|
|
2554
2871
|
return o
|
|
2555
2872
|
elif isinstance(o, str):
|
|
2556
2873
|
return cls(o)
|
|
2874
|
+
elif isinstance(o, tuple):
|
|
2875
|
+
name, x = o
|
|
2876
|
+
kw: ta.Mapping[str, ta.Any]
|
|
2877
|
+
if isinstance(x, str):
|
|
2878
|
+
kw = dict(display=x)
|
|
2879
|
+
elif isinstance(x, ta.Mapping):
|
|
2880
|
+
kw = x
|
|
2881
|
+
else:
|
|
2882
|
+
raise TypeError(x)
|
|
2883
|
+
return cls(name, **kw)
|
|
2884
|
+
elif isinstance(o, ta.Mapping):
|
|
2885
|
+
return cls(**o)
|
|
2557
2886
|
else:
|
|
2558
|
-
|
|
2559
|
-
return cls(
|
|
2560
|
-
name,
|
|
2561
|
-
display=disp,
|
|
2562
|
-
)
|
|
2887
|
+
raise TypeError(o)
|
|
2563
2888
|
|
|
2564
2889
|
@property
|
|
2565
2890
|
def name(self) -> str:
|
|
@@ -2577,19 +2902,34 @@ class AttrOps(ta.Generic[T]):
|
|
|
2577
2902
|
def eq(self) -> bool:
|
|
2578
2903
|
return self._eq
|
|
2579
2904
|
|
|
2905
|
+
@staticmethod
|
|
2906
|
+
def opt_repr(o: ta.Any) -> ta.Optional[str]:
|
|
2907
|
+
return repr(o) if o is not None else None
|
|
2908
|
+
|
|
2909
|
+
@staticmethod
|
|
2910
|
+
def truthy_repr(o: ta.Any) -> ta.Optional[str]:
|
|
2911
|
+
return repr(o) if o else None
|
|
2912
|
+
|
|
2913
|
+
#
|
|
2914
|
+
|
|
2580
2915
|
@ta.overload
|
|
2581
2916
|
def __init__(
|
|
2582
2917
|
self,
|
|
2583
2918
|
*attrs: ta.Sequence[ta.Union[
|
|
2584
2919
|
str,
|
|
2585
|
-
ta.Tuple[str, str],
|
|
2920
|
+
ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
|
|
2921
|
+
ta.Mapping[str, ta.Any],
|
|
2586
2922
|
Attr,
|
|
2587
2923
|
]],
|
|
2924
|
+
|
|
2588
2925
|
with_module: bool = False,
|
|
2589
2926
|
use_qualname: bool = False,
|
|
2590
2927
|
with_id: bool = False,
|
|
2928
|
+
terse: bool = False,
|
|
2591
2929
|
repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
|
|
2592
2930
|
recursive: bool = False,
|
|
2931
|
+
|
|
2932
|
+
cache_hash: ta.Union[bool, str] = False,
|
|
2593
2933
|
subtypes_eq: bool = False,
|
|
2594
2934
|
) -> None:
|
|
2595
2935
|
...
|
|
@@ -2599,16 +2939,20 @@ class AttrOps(ta.Generic[T]):
|
|
|
2599
2939
|
self,
|
|
2600
2940
|
attrs_fn: ta.Callable[[T], ta.Tuple[ta.Union[
|
|
2601
2941
|
ta.Any,
|
|
2602
|
-
ta.Tuple[str, ta.Any],
|
|
2942
|
+
ta.Tuple[ta.Any, ta.Union[str, ta.Mapping[str, ta.Any]]],
|
|
2603
2943
|
Attr,
|
|
2604
2944
|
], ...]],
|
|
2605
2945
|
/,
|
|
2606
2946
|
*,
|
|
2947
|
+
|
|
2607
2948
|
with_module: bool = False,
|
|
2608
2949
|
use_qualname: bool = False,
|
|
2609
2950
|
with_id: bool = False,
|
|
2951
|
+
terse: bool = False,
|
|
2610
2952
|
repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
|
|
2611
2953
|
recursive: bool = False,
|
|
2954
|
+
|
|
2955
|
+
cache_hash: ta.Union[bool, str] = False,
|
|
2612
2956
|
subtypes_eq: bool = False,
|
|
2613
2957
|
) -> None:
|
|
2614
2958
|
...
|
|
@@ -2616,11 +2960,15 @@ class AttrOps(ta.Generic[T]):
|
|
|
2616
2960
|
def __init__(
|
|
2617
2961
|
self,
|
|
2618
2962
|
*args,
|
|
2963
|
+
|
|
2619
2964
|
with_module=False,
|
|
2620
2965
|
use_qualname=False,
|
|
2621
2966
|
with_id=False,
|
|
2967
|
+
terse=False,
|
|
2622
2968
|
repr_filter=None,
|
|
2623
2969
|
recursive=False,
|
|
2970
|
+
|
|
2971
|
+
cache_hash=False,
|
|
2624
2972
|
subtypes_eq=False,
|
|
2625
2973
|
) -> None:
|
|
2626
2974
|
if args and len(args) == 1 and callable(args[0]):
|
|
@@ -2631,8 +2979,11 @@ class AttrOps(ta.Generic[T]):
|
|
|
2631
2979
|
self._with_module: bool = with_module
|
|
2632
2980
|
self._use_qualname: bool = use_qualname
|
|
2633
2981
|
self._with_id: bool = with_id
|
|
2982
|
+
self._terse: bool = terse
|
|
2634
2983
|
self._repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = repr_filter
|
|
2635
2984
|
self._recursive: bool = recursive
|
|
2985
|
+
|
|
2986
|
+
self._cache_hash: ta.Union[bool, str] = cache_hash
|
|
2636
2987
|
self._subtypes_eq: bool = subtypes_eq
|
|
2637
2988
|
|
|
2638
2989
|
@property
|
|
@@ -2667,20 +3018,27 @@ class AttrOps(ta.Generic[T]):
|
|
|
2667
3018
|
|
|
2668
3019
|
attrs: ta.List[AttrOps.Attr] = []
|
|
2669
3020
|
for o in raw:
|
|
2670
|
-
if isinstance(o, AttrOps.Attr):
|
|
2671
|
-
attrs.append(o)
|
|
3021
|
+
if isinstance(o, (AttrOps.Attr, ta.Mapping)):
|
|
3022
|
+
attrs.append(AttrOps.Attr.of(o))
|
|
2672
3023
|
continue
|
|
2673
3024
|
|
|
3025
|
+
kw: ta.Mapping[str, ta.Any]
|
|
2674
3026
|
if isinstance(o, tuple):
|
|
2675
|
-
|
|
3027
|
+
cap, x = o
|
|
3028
|
+
if isinstance(x, str):
|
|
3029
|
+
kw = dict(display=x)
|
|
3030
|
+
elif isinstance(x, ta.Mapping):
|
|
3031
|
+
kw = x
|
|
3032
|
+
else:
|
|
3033
|
+
raise TypeError(x)
|
|
2676
3034
|
else:
|
|
2677
|
-
|
|
3035
|
+
cap, kw = o, {}
|
|
2678
3036
|
|
|
2679
3037
|
path = tuple(rec(cap))
|
|
2680
3038
|
|
|
2681
3039
|
attrs.append(AttrOps.Attr(
|
|
2682
3040
|
'.'.join(path),
|
|
2683
|
-
|
|
3041
|
+
**kw,
|
|
2684
3042
|
))
|
|
2685
3043
|
|
|
2686
3044
|
return attrs
|
|
@@ -2697,19 +3055,27 @@ class AttrOps(ta.Generic[T]):
|
|
|
2697
3055
|
pass
|
|
2698
3056
|
|
|
2699
3057
|
def _repr(o: T) -> str:
|
|
2700
|
-
vs =
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
if self._repr_filter is None
|
|
2706
|
-
|
|
3058
|
+
vs: ta.List[str] = []
|
|
3059
|
+
for a in self._attrs:
|
|
3060
|
+
if not a._repr: # noqa
|
|
3061
|
+
continue
|
|
3062
|
+
v = getattr(o, a._name) # noqa
|
|
3063
|
+
if self._repr_filter is not None and not self._repr_filter(v):
|
|
3064
|
+
continue
|
|
3065
|
+
if (rfn := a._repr_fn) is None: # noqa
|
|
3066
|
+
rfn = repr
|
|
3067
|
+
if (vr := rfn(v)) is None:
|
|
3068
|
+
continue
|
|
3069
|
+
if self._terse:
|
|
3070
|
+
vs.append(vr)
|
|
3071
|
+
else:
|
|
3072
|
+
vs.append(f'{a._display}={vr}') # noqa
|
|
2707
3073
|
|
|
2708
3074
|
return (
|
|
2709
3075
|
f'{o.__class__.__module__ + "." if self._with_module else ""}'
|
|
2710
3076
|
f'{o.__class__.__qualname__ if self._use_qualname else o.__class__.__name__}'
|
|
2711
|
-
f'{("@" + hex(id(o))[2:]) if self._with_id else ""}'
|
|
2712
|
-
f'({vs})'
|
|
3077
|
+
f'{("@" + hex(id(o))[2:]) if self._with_id else ""}' # noqa
|
|
3078
|
+
f'({", ".join(vs)})'
|
|
2713
3079
|
)
|
|
2714
3080
|
|
|
2715
3081
|
if self._recursive:
|
|
@@ -2734,6 +3100,8 @@ class AttrOps(ta.Generic[T]):
|
|
|
2734
3100
|
|
|
2735
3101
|
#
|
|
2736
3102
|
|
|
3103
|
+
_DEFAULT_CACHED_HASH_ATTR: ta.ClassVar[str] = '__cached_hash__'
|
|
3104
|
+
|
|
2737
3105
|
_hash: ta.Callable[[T], int]
|
|
2738
3106
|
|
|
2739
3107
|
@property
|
|
@@ -2743,13 +3111,33 @@ class AttrOps(ta.Generic[T]):
|
|
|
2743
3111
|
except AttributeError:
|
|
2744
3112
|
pass
|
|
2745
3113
|
|
|
2746
|
-
def
|
|
3114
|
+
def _calc_hash(o: T) -> int:
|
|
2747
3115
|
return hash(tuple(
|
|
2748
3116
|
getattr(o, a._name) # noqa
|
|
2749
3117
|
for a in self._attrs
|
|
2750
3118
|
if a._hash # noqa
|
|
2751
3119
|
))
|
|
2752
3120
|
|
|
3121
|
+
if (ch := self._cache_hash) is not False:
|
|
3122
|
+
if ch is True:
|
|
3123
|
+
cha = self._DEFAULT_CACHED_HASH_ATTR
|
|
3124
|
+
elif isinstance(ch, str):
|
|
3125
|
+
cha = ch
|
|
3126
|
+
else:
|
|
3127
|
+
raise TypeError(ch)
|
|
3128
|
+
|
|
3129
|
+
def _cached_hash(o: T) -> int:
|
|
3130
|
+
try:
|
|
3131
|
+
return object.__getattribute__(o, cha)
|
|
3132
|
+
except AttributeError:
|
|
3133
|
+
object.__setattr__(o, cha, h := _calc_hash(o))
|
|
3134
|
+
return h
|
|
3135
|
+
|
|
3136
|
+
_hash = _cached_hash
|
|
3137
|
+
|
|
3138
|
+
else:
|
|
3139
|
+
_hash = _calc_hash
|
|
3140
|
+
|
|
2753
3141
|
self._hash = _hash
|
|
2754
3142
|
return _hash
|
|
2755
3143
|
|
|
@@ -2890,6 +3278,62 @@ def async_cached_nullary(fn): # ta.Callable[..., T]) -> ta.Callable[..., T]:
|
|
|
2890
3278
|
return _AsyncCachedNullary(fn)
|
|
2891
3279
|
|
|
2892
3280
|
|
|
3281
|
+
##
|
|
3282
|
+
|
|
3283
|
+
|
|
3284
|
+
cached_property = functools.cached_property
|
|
3285
|
+
|
|
3286
|
+
|
|
3287
|
+
class _cached_property: # noqa
|
|
3288
|
+
"""Backported to pick up https://github.com/python/cpython/commit/056dfc71dce15f81887f0bd6da09d6099d71f979 ."""
|
|
3289
|
+
|
|
3290
|
+
def __init__(self, func):
|
|
3291
|
+
self.func = func
|
|
3292
|
+
self.attrname = None # noqa
|
|
3293
|
+
self.__doc__ = func.__doc__
|
|
3294
|
+
self.__module__ = func.__module__
|
|
3295
|
+
|
|
3296
|
+
_NOT_FOUND = object()
|
|
3297
|
+
|
|
3298
|
+
def __set_name__(self, owner, name):
|
|
3299
|
+
if self.attrname is None:
|
|
3300
|
+
self.attrname = name # noqa
|
|
3301
|
+
elif name != self.attrname:
|
|
3302
|
+
raise TypeError(
|
|
3303
|
+
f'Cannot assign the same cached_property to two different names ({self.attrname!r} and {name!r}).',
|
|
3304
|
+
)
|
|
3305
|
+
|
|
3306
|
+
def __get__(self, instance, owner=None):
|
|
3307
|
+
if instance is None:
|
|
3308
|
+
return self
|
|
3309
|
+
if self.attrname is None:
|
|
3310
|
+
raise TypeError('Cannot use cached_property instance without calling __set_name__ on it.')
|
|
3311
|
+
|
|
3312
|
+
try:
|
|
3313
|
+
cache = instance.__dict__
|
|
3314
|
+
except AttributeError: # not all objects have __dict__ (e.g. class defines slots)
|
|
3315
|
+
raise TypeError(
|
|
3316
|
+
f"No '__dict__' attribute on {type(instance).__name__!r} instance to cache {self.attrname!r} property.",
|
|
3317
|
+
) from None
|
|
3318
|
+
|
|
3319
|
+
val = cache.get(self.attrname, self._NOT_FOUND)
|
|
3320
|
+
|
|
3321
|
+
if val is self._NOT_FOUND:
|
|
3322
|
+
val = self.func(instance)
|
|
3323
|
+
try:
|
|
3324
|
+
cache[self.attrname] = val
|
|
3325
|
+
except TypeError:
|
|
3326
|
+
raise TypeError(
|
|
3327
|
+
f"The '__dict__' attribute on {type(instance).__name__!r} instance does not support item "
|
|
3328
|
+
f"assignment for caching {self.attrname!r} property.",
|
|
3329
|
+
) from None
|
|
3330
|
+
|
|
3331
|
+
return val
|
|
3332
|
+
|
|
3333
|
+
|
|
3334
|
+
globals()['cached_property'] = _cached_property
|
|
3335
|
+
|
|
3336
|
+
|
|
2893
3337
|
########################################
|
|
2894
3338
|
# ../../../omlish/lite/check.py
|
|
2895
3339
|
"""
|
|
@@ -3429,7 +3873,7 @@ class ExitStacked:
|
|
|
3429
3873
|
es.__enter__()
|
|
3430
3874
|
try:
|
|
3431
3875
|
self._enter_contexts()
|
|
3432
|
-
except
|
|
3876
|
+
except BaseException: # noqa
|
|
3433
3877
|
es.__exit__(*sys.exc_info())
|
|
3434
3878
|
raise
|
|
3435
3879
|
return self
|
|
@@ -3440,7 +3884,7 @@ class ExitStacked:
|
|
|
3440
3884
|
return None
|
|
3441
3885
|
try:
|
|
3442
3886
|
self._exit_contexts()
|
|
3443
|
-
except
|
|
3887
|
+
except BaseException: # noqa
|
|
3444
3888
|
es.__exit__(*sys.exc_info())
|
|
3445
3889
|
raise
|
|
3446
3890
|
return es.__exit__(exc_type, exc_val, exc_tb)
|
|
@@ -3488,7 +3932,7 @@ class AsyncExitStacked:
|
|
|
3488
3932
|
await es.__aenter__()
|
|
3489
3933
|
try:
|
|
3490
3934
|
await self._async_enter_contexts()
|
|
3491
|
-
except
|
|
3935
|
+
except BaseException: # noqa
|
|
3492
3936
|
await es.__aexit__(*sys.exc_info())
|
|
3493
3937
|
raise
|
|
3494
3938
|
return self
|
|
@@ -3499,7 +3943,7 @@ class AsyncExitStacked:
|
|
|
3499
3943
|
return None
|
|
3500
3944
|
try:
|
|
3501
3945
|
await self._async_exit_contexts()
|
|
3502
|
-
except
|
|
3946
|
+
except BaseException: # noqa
|
|
3503
3947
|
await es.__aexit__(*sys.exc_info())
|
|
3504
3948
|
raise
|
|
3505
3949
|
return await es.__aexit__(exc_type, exc_val, exc_tb)
|
|
@@ -3697,7 +4141,7 @@ def dir_dict(o: ta.Any) -> ta.Dict[str, ta.Any]:
|
|
|
3697
4141
|
##
|
|
3698
4142
|
|
|
3699
4143
|
|
|
3700
|
-
DEFAULT_PYCHARM_VERSION = '
|
|
4144
|
+
DEFAULT_PYCHARM_VERSION = '252.26199.168'
|
|
3701
4145
|
|
|
3702
4146
|
|
|
3703
4147
|
@dc.dataclass(frozen=True)
|
|
@@ -3941,6 +4385,12 @@ def format_num_bytes(num_bytes: int) -> str:
|
|
|
3941
4385
|
|
|
3942
4386
|
##
|
|
3943
4387
|
# A workaround for typing deficiencies (like `Argument 2 to NewType(...) must be subclassable`).
|
|
4388
|
+
#
|
|
4389
|
+
# Note that this problem doesn't happen at runtime - it happens in mypy:
|
|
4390
|
+
#
|
|
4391
|
+
# mypy <(echo "import typing as ta; MyCallback = ta.NewType('MyCallback', ta.Callable[[], None])")
|
|
4392
|
+
# /dev/fd/11:1:22: error: Argument 2 to NewType(...) must be subclassable (got "Callable[[], None]") [valid-newtype]
|
|
4393
|
+
#
|
|
3944
4394
|
|
|
3945
4395
|
|
|
3946
4396
|
@dc.dataclass(frozen=True)
|
|
@@ -3986,6 +4436,39 @@ class Func3(ta.Generic[A0, A1, A2, T]):
|
|
|
3986
4436
|
##
|
|
3987
4437
|
|
|
3988
4438
|
|
|
4439
|
+
@dc.dataclass(frozen=True)
|
|
4440
|
+
class CachedFunc0(ta.Generic[T]):
|
|
4441
|
+
fn: ta.Callable[[], T]
|
|
4442
|
+
|
|
4443
|
+
def __call__(self) -> T:
|
|
4444
|
+
try:
|
|
4445
|
+
return object.__getattribute__(self, '_value')
|
|
4446
|
+
except AttributeError:
|
|
4447
|
+
pass
|
|
4448
|
+
|
|
4449
|
+
value = self.fn()
|
|
4450
|
+
object.__setattr__(self, '_value', value)
|
|
4451
|
+
return value
|
|
4452
|
+
|
|
4453
|
+
|
|
4454
|
+
@dc.dataclass(frozen=True)
|
|
4455
|
+
class AsyncCachedFunc0(ta.Generic[T]):
|
|
4456
|
+
fn: ta.Callable[[], ta.Awaitable[T]]
|
|
4457
|
+
|
|
4458
|
+
async def __call__(self) -> T:
|
|
4459
|
+
try:
|
|
4460
|
+
return object.__getattribute__(self, '_value')
|
|
4461
|
+
except AttributeError:
|
|
4462
|
+
pass
|
|
4463
|
+
|
|
4464
|
+
value = await self.fn()
|
|
4465
|
+
object.__setattr__(self, '_value', value)
|
|
4466
|
+
return value
|
|
4467
|
+
|
|
4468
|
+
|
|
4469
|
+
##
|
|
4470
|
+
|
|
4471
|
+
|
|
3989
4472
|
_TYPING_ANNOTATIONS_ATTR = '__annotate__' if sys.version_info >= (3, 14) else '__annotations__'
|
|
3990
4473
|
|
|
3991
4474
|
|
|
@@ -5483,7 +5966,7 @@ class SpecifierSet(BaseSpecifier):
|
|
|
5483
5966
|
if isinstance(other, str):
|
|
5484
5967
|
other = SpecifierSet(other)
|
|
5485
5968
|
elif not isinstance(other, SpecifierSet):
|
|
5486
|
-
return NotImplemented
|
|
5969
|
+
return NotImplemented
|
|
5487
5970
|
|
|
5488
5971
|
specifier = SpecifierSet()
|
|
5489
5972
|
specifier._specs = frozenset(self._specs | other._specs)
|
|
@@ -5503,6 +5986,7 @@ class SpecifierSet(BaseSpecifier):
|
|
|
5503
5986
|
if isinstance(other, (str, Specifier)):
|
|
5504
5987
|
other = SpecifierSet(str(other))
|
|
5505
5988
|
elif not isinstance(other, SpecifierSet):
|
|
5989
|
+
|
|
5506
5990
|
return NotImplemented
|
|
5507
5991
|
|
|
5508
5992
|
return self._specs == other._specs
|
|
@@ -5654,7 +6138,7 @@ BEST_PYTHON_SH = """\
|
|
|
5654
6138
|
bv=""
|
|
5655
6139
|
bx=""
|
|
5656
6140
|
|
|
5657
|
-
for v in "" 3 3.{8..
|
|
6141
|
+
for v in "" 3 3.{8..14}; do
|
|
5658
6142
|
x="python$v"
|
|
5659
6143
|
v=$($x -c "import sys; print((\\"%02d\\" * 3) % sys.version_info[:3])" 2>/dev/null)
|
|
5660
6144
|
if [ $? -eq 0 ] && [ "$v" \\> 030799 ] && ([ -z "$bv" ] || [ "$v" \\> "$bv" ]); then
|
|
@@ -5789,6 +6273,7 @@ TODO:
|
|
|
5789
6273
|
- pre-run, post-run hooks
|
|
5790
6274
|
- exitstack?
|
|
5791
6275
|
- suggestion - difflib.get_close_matches
|
|
6276
|
+
- add_argument_group - group kw on ArgparseKwarg?
|
|
5792
6277
|
"""
|
|
5793
6278
|
|
|
5794
6279
|
|
|
@@ -5799,6 +6284,7 @@ TODO:
|
|
|
5799
6284
|
class ArgparseArg:
|
|
5800
6285
|
args: ta.Sequence[ta.Any]
|
|
5801
6286
|
kwargs: ta.Mapping[str, ta.Any]
|
|
6287
|
+
group: ta.Optional[str] = None
|
|
5802
6288
|
dest: ta.Optional[str] = None
|
|
5803
6289
|
|
|
5804
6290
|
def __get__(self, instance, owner=None):
|
|
@@ -5808,7 +6294,11 @@ class ArgparseArg:
|
|
|
5808
6294
|
|
|
5809
6295
|
|
|
5810
6296
|
def argparse_arg(*args, **kwargs) -> ArgparseArg:
|
|
5811
|
-
return ArgparseArg(
|
|
6297
|
+
return ArgparseArg(
|
|
6298
|
+
args=args,
|
|
6299
|
+
group=kwargs.pop('group', None),
|
|
6300
|
+
kwargs=kwargs,
|
|
6301
|
+
)
|
|
5812
6302
|
|
|
5813
6303
|
|
|
5814
6304
|
def argparse_arg_(*args, **kwargs) -> ta.Any:
|
|
@@ -5978,6 +6468,10 @@ class ArgparseCli:
|
|
|
5978
6468
|
subparser.set_defaults(_cmd=obj)
|
|
5979
6469
|
|
|
5980
6470
|
elif isinstance(obj, ArgparseArg):
|
|
6471
|
+
if obj.group is not None:
|
|
6472
|
+
# FIXME: add_argument_group
|
|
6473
|
+
raise NotImplementedError
|
|
6474
|
+
|
|
5981
6475
|
if att in anns:
|
|
5982
6476
|
ann_kwargs = _get_argparse_arg_ann_kwargs(anns[att])
|
|
5983
6477
|
obj.kwargs = {**ann_kwargs, **obj.kwargs}
|
|
@@ -6023,7 +6517,7 @@ class ArgparseCli:
|
|
|
6023
6517
|
|
|
6024
6518
|
if self._unknown_args and not (cmd is not None and cmd.accepts_unknown):
|
|
6025
6519
|
msg = f'unrecognized arguments: {" ".join(self._unknown_args)}'
|
|
6026
|
-
if (parser := self.get_parser()).exit_on_error:
|
|
6520
|
+
if (parser := self.get_parser()).exit_on_error: # noqa
|
|
6027
6521
|
parser.error(msg)
|
|
6028
6522
|
else:
|
|
6029
6523
|
raise argparse.ArgumentError(None, msg)
|
|
@@ -6043,7 +6537,10 @@ class ArgparseCli:
|
|
|
6043
6537
|
return fn()
|
|
6044
6538
|
|
|
6045
6539
|
def cli_run_and_exit(self) -> ta.NoReturn:
|
|
6046
|
-
|
|
6540
|
+
rc = self.cli_run()
|
|
6541
|
+
if not isinstance(rc, int):
|
|
6542
|
+
rc = 0
|
|
6543
|
+
raise SystemExit(rc)
|
|
6047
6544
|
|
|
6048
6545
|
def __call__(self, *, exit: bool = False) -> ta.Optional[int]: # noqa
|
|
6049
6546
|
if exit:
|
|
@@ -7174,6 +7671,13 @@ class Maybe(ta.Generic[T]):
|
|
|
7174
7671
|
else:
|
|
7175
7672
|
return other
|
|
7176
7673
|
|
|
7674
|
+
@ta.final
|
|
7675
|
+
def or_none(self) -> ta.Optional[T]:
|
|
7676
|
+
if self.present:
|
|
7677
|
+
return self.must()
|
|
7678
|
+
else:
|
|
7679
|
+
return None
|
|
7680
|
+
|
|
7177
7681
|
@ta.final
|
|
7178
7682
|
def or_else_get(self, supplier: ta.Callable[[], ta.Union[T, U]]) -> ta.Union[T, U]:
|
|
7179
7683
|
if self.present:
|
|
@@ -7228,8 +7732,6 @@ class _JustMaybe(_Maybe[T]):
|
|
|
7228
7732
|
__slots__ = ('_v', '_hash')
|
|
7229
7733
|
|
|
7230
7734
|
def __init__(self, v: T) -> None:
|
|
7231
|
-
super().__init__()
|
|
7232
|
-
|
|
7233
7735
|
self._v = v
|
|
7234
7736
|
|
|
7235
7737
|
@property
|
|
@@ -7287,6 +7789,13 @@ class _EmptyMaybe(_Maybe[T]):
|
|
|
7287
7789
|
Maybe._empty = _EmptyMaybe() # noqa
|
|
7288
7790
|
|
|
7289
7791
|
|
|
7792
|
+
##
|
|
7793
|
+
|
|
7794
|
+
|
|
7795
|
+
setattr(Maybe, 'just', _JustMaybe) # noqa
|
|
7796
|
+
setattr(Maybe, 'empty', functools.partial(operator.attrgetter('_empty'), Maybe))
|
|
7797
|
+
|
|
7798
|
+
|
|
7290
7799
|
########################################
|
|
7291
7800
|
# ../../../omlish/lite/runtime.py
|
|
7292
7801
|
|
|
@@ -8289,9 +8798,10 @@ class InterpSpecifier:
|
|
|
8289
8798
|
def parse(cls, s: str) -> 'InterpSpecifier':
|
|
8290
8799
|
s, o = InterpOpts.parse_suffix(s)
|
|
8291
8800
|
if not any(s.startswith(o) for o in Specifier.OPERATORS):
|
|
8292
|
-
s = '~=' + s
|
|
8293
8801
|
if s.count('.') < 2:
|
|
8294
|
-
s
|
|
8802
|
+
s = '~=' + s + '.0'
|
|
8803
|
+
else:
|
|
8804
|
+
s = '==' + s
|
|
8295
8805
|
return cls(
|
|
8296
8806
|
specifier=Specifier(s),
|
|
8297
8807
|
opts=o,
|
|
@@ -10190,6 +10700,9 @@ class CaptureLoggingContextImpl(CaptureLoggingContext):
|
|
|
10190
10700
|
self._infos[type(info)] = info
|
|
10191
10701
|
return self
|
|
10192
10702
|
|
|
10703
|
+
def get_infos(self) -> ta.Mapping[ta.Type[LoggingContextInfo], LoggingContextInfo]:
|
|
10704
|
+
return self._infos
|
|
10705
|
+
|
|
10193
10706
|
def get_info(self, ty: ta.Type[LoggingContextInfoT]) -> ta.Optional[LoggingContextInfoT]:
|
|
10194
10707
|
return self._infos.get(ty)
|
|
10195
10708
|
|
|
@@ -10212,7 +10725,7 @@ class CaptureLoggingContextImpl(CaptureLoggingContext):
|
|
|
10212
10725
|
_stack_offset: int
|
|
10213
10726
|
_stack_info: bool
|
|
10214
10727
|
|
|
10215
|
-
def inc_stack_offset(self, ofs: int = 1) -> '
|
|
10728
|
+
def inc_stack_offset(self, ofs: int = 1) -> 'CaptureLoggingContextImpl':
|
|
10216
10729
|
if hasattr(self, '_stack_offset'):
|
|
10217
10730
|
self._stack_offset += ofs
|
|
10218
10731
|
return self
|
|
@@ -10244,10 +10757,9 @@ class CaptureLoggingContextImpl(CaptureLoggingContext):
|
|
|
10244
10757
|
|
|
10245
10758
|
|
|
10246
10759
|
########################################
|
|
10247
|
-
# ../../../omlish/logs/standard.py
|
|
10760
|
+
# ../../../omlish/logs/std/standard.py
|
|
10248
10761
|
"""
|
|
10249
10762
|
TODO:
|
|
10250
|
-
- !! move to std !!
|
|
10251
10763
|
- structured
|
|
10252
10764
|
- prefixed
|
|
10253
10765
|
- debug
|
|
@@ -11022,6 +11534,11 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
11022
11534
|
|
|
11023
11535
|
##
|
|
11024
11536
|
|
|
11537
|
+
# This will be 1 for [Sync]Logger and 0 for AsyncLogger - in sync loggers these methods remain present on the stack,
|
|
11538
|
+
# in async loggers they return a coroutine to be awaited and thus aren't actually present when said coroutine is
|
|
11539
|
+
# awaited.
|
|
11540
|
+
_level_proxy_method_stack_offset: int
|
|
11541
|
+
|
|
11025
11542
|
@ta.overload
|
|
11026
11543
|
def log(self, level: LogLevel, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
|
11027
11544
|
...
|
|
@@ -11036,7 +11553,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
11036
11553
|
|
|
11037
11554
|
@ta.final
|
|
11038
11555
|
def log(self, level: LogLevel, *args, **kwargs):
|
|
11039
|
-
return self._log(
|
|
11556
|
+
return self._log(
|
|
11557
|
+
CaptureLoggingContextImpl(
|
|
11558
|
+
level,
|
|
11559
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
11560
|
+
),
|
|
11561
|
+
*args,
|
|
11562
|
+
**kwargs,
|
|
11563
|
+
)
|
|
11040
11564
|
|
|
11041
11565
|
#
|
|
11042
11566
|
|
|
@@ -11054,7 +11578,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
11054
11578
|
|
|
11055
11579
|
@ta.final
|
|
11056
11580
|
def debug(self, *args, **kwargs):
|
|
11057
|
-
return self._log(
|
|
11581
|
+
return self._log(
|
|
11582
|
+
CaptureLoggingContextImpl(
|
|
11583
|
+
NamedLogLevel.DEBUG,
|
|
11584
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
11585
|
+
),
|
|
11586
|
+
*args,
|
|
11587
|
+
**kwargs,
|
|
11588
|
+
)
|
|
11058
11589
|
|
|
11059
11590
|
#
|
|
11060
11591
|
|
|
@@ -11072,7 +11603,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
11072
11603
|
|
|
11073
11604
|
@ta.final
|
|
11074
11605
|
def info(self, *args, **kwargs):
|
|
11075
|
-
return self._log(
|
|
11606
|
+
return self._log(
|
|
11607
|
+
CaptureLoggingContextImpl(
|
|
11608
|
+
NamedLogLevel.INFO,
|
|
11609
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
11610
|
+
),
|
|
11611
|
+
*args,
|
|
11612
|
+
**kwargs,
|
|
11613
|
+
)
|
|
11076
11614
|
|
|
11077
11615
|
#
|
|
11078
11616
|
|
|
@@ -11090,7 +11628,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
11090
11628
|
|
|
11091
11629
|
@ta.final
|
|
11092
11630
|
def warning(self, *args, **kwargs):
|
|
11093
|
-
return self._log(
|
|
11631
|
+
return self._log(
|
|
11632
|
+
CaptureLoggingContextImpl(
|
|
11633
|
+
NamedLogLevel.WARNING,
|
|
11634
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
11635
|
+
),
|
|
11636
|
+
*args,
|
|
11637
|
+
**kwargs,
|
|
11638
|
+
)
|
|
11094
11639
|
|
|
11095
11640
|
#
|
|
11096
11641
|
|
|
@@ -11108,7 +11653,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
11108
11653
|
|
|
11109
11654
|
@ta.final
|
|
11110
11655
|
def error(self, *args, **kwargs):
|
|
11111
|
-
return self._log(
|
|
11656
|
+
return self._log(
|
|
11657
|
+
CaptureLoggingContextImpl(
|
|
11658
|
+
NamedLogLevel.ERROR,
|
|
11659
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
11660
|
+
),
|
|
11661
|
+
*args,
|
|
11662
|
+
**kwargs,
|
|
11663
|
+
)
|
|
11112
11664
|
|
|
11113
11665
|
#
|
|
11114
11666
|
|
|
@@ -11126,7 +11678,15 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
11126
11678
|
|
|
11127
11679
|
@ta.final
|
|
11128
11680
|
def exception(self, *args, exc_info: LoggingExcInfoArg = True, **kwargs):
|
|
11129
|
-
return self._log(
|
|
11681
|
+
return self._log(
|
|
11682
|
+
CaptureLoggingContextImpl(
|
|
11683
|
+
NamedLogLevel.ERROR,
|
|
11684
|
+
exc_info=exc_info,
|
|
11685
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
11686
|
+
),
|
|
11687
|
+
*args,
|
|
11688
|
+
**kwargs,
|
|
11689
|
+
)
|
|
11130
11690
|
|
|
11131
11691
|
#
|
|
11132
11692
|
|
|
@@ -11144,24 +11704,53 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
11144
11704
|
|
|
11145
11705
|
@ta.final
|
|
11146
11706
|
def critical(self, *args, **kwargs):
|
|
11147
|
-
return self._log(
|
|
11707
|
+
return self._log(
|
|
11708
|
+
CaptureLoggingContextImpl(
|
|
11709
|
+
NamedLogLevel.CRITICAL,
|
|
11710
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
11711
|
+
),
|
|
11712
|
+
*args,
|
|
11713
|
+
**kwargs,
|
|
11714
|
+
)
|
|
11148
11715
|
|
|
11149
11716
|
##
|
|
11150
11717
|
|
|
11151
11718
|
@abc.abstractmethod
|
|
11152
|
-
def _log(
|
|
11719
|
+
def _log(
|
|
11720
|
+
self,
|
|
11721
|
+
ctx: CaptureLoggingContext,
|
|
11722
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
11723
|
+
*args: ta.Any,
|
|
11724
|
+
**kwargs: ta.Any,
|
|
11725
|
+
) -> T:
|
|
11153
11726
|
raise NotImplementedError
|
|
11154
11727
|
|
|
11155
11728
|
|
|
11156
11729
|
class Logger(AnyLogger[None], Abstract):
|
|
11730
|
+
_level_proxy_method_stack_offset: int = 1
|
|
11731
|
+
|
|
11157
11732
|
@abc.abstractmethod
|
|
11158
|
-
def _log(
|
|
11733
|
+
def _log(
|
|
11734
|
+
self,
|
|
11735
|
+
ctx: CaptureLoggingContext,
|
|
11736
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
11737
|
+
*args: ta.Any,
|
|
11738
|
+
**kwargs: ta.Any,
|
|
11739
|
+
) -> None:
|
|
11159
11740
|
raise NotImplementedError
|
|
11160
11741
|
|
|
11161
11742
|
|
|
11162
11743
|
class AsyncLogger(AnyLogger[ta.Awaitable[None]], Abstract):
|
|
11744
|
+
_level_proxy_method_stack_offset: int = 0
|
|
11745
|
+
|
|
11163
11746
|
@abc.abstractmethod
|
|
11164
|
-
def _log(
|
|
11747
|
+
def _log(
|
|
11748
|
+
self,
|
|
11749
|
+
ctx: CaptureLoggingContext,
|
|
11750
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
11751
|
+
*args: ta.Any,
|
|
11752
|
+
**kwargs: ta.Any,
|
|
11753
|
+
) -> ta.Awaitable[None]:
|
|
11165
11754
|
raise NotImplementedError
|
|
11166
11755
|
|
|
11167
11756
|
|
|
@@ -11176,13 +11765,25 @@ class AnyNopLogger(AnyLogger[T], Abstract):
|
|
|
11176
11765
|
|
|
11177
11766
|
@ta.final
|
|
11178
11767
|
class NopLogger(AnyNopLogger[None], Logger):
|
|
11179
|
-
def _log(
|
|
11768
|
+
def _log(
|
|
11769
|
+
self,
|
|
11770
|
+
ctx: CaptureLoggingContext,
|
|
11771
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
11772
|
+
*args: ta.Any,
|
|
11773
|
+
**kwargs: ta.Any,
|
|
11774
|
+
) -> None:
|
|
11180
11775
|
pass
|
|
11181
11776
|
|
|
11182
11777
|
|
|
11183
11778
|
@ta.final
|
|
11184
11779
|
class AsyncNopLogger(AnyNopLogger[ta.Awaitable[None]], AsyncLogger):
|
|
11185
|
-
async def _log(
|
|
11780
|
+
async def _log(
|
|
11781
|
+
self,
|
|
11782
|
+
ctx: CaptureLoggingContext,
|
|
11783
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
11784
|
+
*args: ta.Any,
|
|
11785
|
+
**kwargs: ta.Any,
|
|
11786
|
+
) -> None:
|
|
11186
11787
|
pass
|
|
11187
11788
|
|
|
11188
11789
|
|
|
@@ -11889,6 +12490,10 @@ class VerboseCalledProcessError(subprocess.CalledProcessError):
|
|
|
11889
12490
|
class BaseSubprocesses(Abstract):
|
|
11890
12491
|
DEFAULT_LOGGER: ta.ClassVar[ta.Optional[LoggerLike]] = None
|
|
11891
12492
|
|
|
12493
|
+
PIPE: ta.ClassVar[int] = subprocess.PIPE
|
|
12494
|
+
STDOUT: ta.ClassVar[int] = subprocess.STDOUT
|
|
12495
|
+
DEVNULL: ta.ClassVar[int] = subprocess.DEVNULL
|
|
12496
|
+
|
|
11892
12497
|
def __init__(
|
|
11893
12498
|
self,
|
|
11894
12499
|
*,
|
|
@@ -12456,6 +13061,70 @@ class SingleDirDeployPathOwner(DeployPathOwner, Abstract):
|
|
|
12456
13061
|
return self._owned_deploy_paths
|
|
12457
13062
|
|
|
12458
13063
|
|
|
13064
|
+
########################################
|
|
13065
|
+
# ../../../omlish/logs/asyncs.py
|
|
13066
|
+
|
|
13067
|
+
|
|
13068
|
+
##
|
|
13069
|
+
|
|
13070
|
+
|
|
13071
|
+
class AsyncLoggerToLogger(Logger):
|
|
13072
|
+
def __init__(self, u: AsyncLogger) -> None:
|
|
13073
|
+
super().__init__()
|
|
13074
|
+
|
|
13075
|
+
self._u = u
|
|
13076
|
+
|
|
13077
|
+
def get_effective_level(self) -> LogLevel:
|
|
13078
|
+
return self._u.get_effective_level()
|
|
13079
|
+
|
|
13080
|
+
def _log(
|
|
13081
|
+
self,
|
|
13082
|
+
ctx: CaptureLoggingContext,
|
|
13083
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
13084
|
+
*args: ta.Any,
|
|
13085
|
+
**kwargs: ta.Any,
|
|
13086
|
+
) -> None:
|
|
13087
|
+
# Nope out early to avoid sync_await if possible - don't bother in the LoggerToAsyncLogger.
|
|
13088
|
+
if not self.is_enabled_for(ctx.must_get_info(LoggingContextInfos.Level).level):
|
|
13089
|
+
return
|
|
13090
|
+
|
|
13091
|
+
# Note: we hardcode the stack offset of sync_await (which is 2 - sync_await + sync_await.thunk). In non-lite
|
|
13092
|
+
# code, lang.sync_await uses a cext if present to avoid being on the py stack, which would obviously complicate
|
|
13093
|
+
# this, but this is lite code so we will always have the non-c version.
|
|
13094
|
+
sync_await(
|
|
13095
|
+
self._u._log( # noqa
|
|
13096
|
+
check.isinstance(ctx, CaptureLoggingContextImpl).inc_stack_offset(3),
|
|
13097
|
+
msg,
|
|
13098
|
+
*args,
|
|
13099
|
+
**kwargs,
|
|
13100
|
+
),
|
|
13101
|
+
)
|
|
13102
|
+
|
|
13103
|
+
|
|
13104
|
+
class LoggerToAsyncLogger(AsyncLogger):
|
|
13105
|
+
def __init__(self, u: Logger) -> None:
|
|
13106
|
+
super().__init__()
|
|
13107
|
+
|
|
13108
|
+
self._u = u
|
|
13109
|
+
|
|
13110
|
+
def get_effective_level(self) -> LogLevel:
|
|
13111
|
+
return self._u.get_effective_level()
|
|
13112
|
+
|
|
13113
|
+
async def _log(
|
|
13114
|
+
self,
|
|
13115
|
+
ctx: CaptureLoggingContext,
|
|
13116
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
13117
|
+
*args: ta.Any,
|
|
13118
|
+
**kwargs: ta.Any,
|
|
13119
|
+
) -> None:
|
|
13120
|
+
return self._u._log( # noqa
|
|
13121
|
+
check.isinstance(ctx, CaptureLoggingContextImpl).inc_stack_offset(),
|
|
13122
|
+
msg,
|
|
13123
|
+
*args,
|
|
13124
|
+
**kwargs,
|
|
13125
|
+
)
|
|
13126
|
+
|
|
13127
|
+
|
|
12459
13128
|
########################################
|
|
12460
13129
|
# ../../../omlish/logs/std/loggers.py
|
|
12461
13130
|
|
|
@@ -12479,7 +13148,12 @@ class StdLogger(Logger):
|
|
|
12479
13148
|
def get_effective_level(self) -> LogLevel:
|
|
12480
13149
|
return self._std.getEffectiveLevel()
|
|
12481
13150
|
|
|
12482
|
-
def _log(
|
|
13151
|
+
def _log(
|
|
13152
|
+
self,
|
|
13153
|
+
ctx: CaptureLoggingContext,
|
|
13154
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
13155
|
+
*args: ta.Any,
|
|
13156
|
+
) -> None:
|
|
12483
13157
|
if not self.is_enabled_for(ctx.must_get_info(LoggingContextInfos.Level).level):
|
|
12484
13158
|
return
|
|
12485
13159
|
|
|
@@ -13122,8 +13796,23 @@ asyncio_subprocesses = AsyncioSubprocesses()
|
|
|
13122
13796
|
##
|
|
13123
13797
|
|
|
13124
13798
|
|
|
13799
|
+
def _get_module_std_logger(mod_globals: ta.Mapping[str, ta.Any]) -> logging.Logger:
|
|
13800
|
+
return logging.getLogger(mod_globals.get('__name__'))
|
|
13801
|
+
|
|
13802
|
+
|
|
13125
13803
|
def get_module_logger(mod_globals: ta.Mapping[str, ta.Any]) -> Logger:
|
|
13126
|
-
return StdLogger(
|
|
13804
|
+
return StdLogger(_get_module_std_logger(mod_globals))
|
|
13805
|
+
|
|
13806
|
+
|
|
13807
|
+
def get_module_async_logger(mod_globals: ta.Mapping[str, ta.Any]) -> AsyncLogger:
|
|
13808
|
+
return LoggerToAsyncLogger(get_module_logger(mod_globals))
|
|
13809
|
+
|
|
13810
|
+
|
|
13811
|
+
def get_module_loggers(mod_globals: ta.Mapping[str, ta.Any]) -> ta.Tuple[Logger, AsyncLogger]:
|
|
13812
|
+
return (
|
|
13813
|
+
log := get_module_logger(mod_globals),
|
|
13814
|
+
LoggerToAsyncLogger(log),
|
|
13815
|
+
)
|
|
13127
13816
|
|
|
13128
13817
|
|
|
13129
13818
|
########################################
|
|
@@ -14951,12 +15640,42 @@ uv run pip
|
|
|
14951
15640
|
uv run --python 3.11.6 pip
|
|
14952
15641
|
uv venv --python 3.11.6 --seed barf
|
|
14953
15642
|
python3 -m venv barf && barf/bin/pip install uv && barf/bin/uv venv --python 3.11.6 --seed barf2
|
|
15643
|
+
uv python find '3.13.10'
|
|
15644
|
+
uv python list --output-format=json
|
|
14954
15645
|
"""
|
|
14955
15646
|
|
|
14956
15647
|
|
|
14957
15648
|
##
|
|
14958
15649
|
|
|
14959
15650
|
|
|
15651
|
+
@dc.dataclass(frozen=True)
|
|
15652
|
+
class UvPythonListOutput:
|
|
15653
|
+
key: str
|
|
15654
|
+
version: str
|
|
15655
|
+
|
|
15656
|
+
@dc.dataclass(frozen=True)
|
|
15657
|
+
class VersionParts:
|
|
15658
|
+
major: int
|
|
15659
|
+
minor: int
|
|
15660
|
+
patch: int
|
|
15661
|
+
|
|
15662
|
+
version_parts: VersionParts
|
|
15663
|
+
|
|
15664
|
+
path: ta.Optional[str]
|
|
15665
|
+
symlink: ta.Optional[str]
|
|
15666
|
+
|
|
15667
|
+
url: str
|
|
15668
|
+
|
|
15669
|
+
os: str # emscripten linux macos
|
|
15670
|
+
variant: str # default freethreaded
|
|
15671
|
+
implementation: str # cpython graalpy pyodide pypy
|
|
15672
|
+
arch: str # aarch64 wasm32 x86_64
|
|
15673
|
+
libc: str # gnu musl none
|
|
15674
|
+
|
|
15675
|
+
|
|
15676
|
+
##
|
|
15677
|
+
|
|
15678
|
+
|
|
14960
15679
|
class UvInterpProvider(InterpProvider):
|
|
14961
15680
|
def __init__(
|
|
14962
15681
|
self,
|
|
@@ -14977,6 +15696,12 @@ class UvInterpProvider(InterpProvider):
|
|
|
14977
15696
|
async def get_installed_version(self, version: InterpVersion) -> Interp:
|
|
14978
15697
|
raise NotImplementedError
|
|
14979
15698
|
|
|
15699
|
+
# async def get_installable_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
|
15700
|
+
# return []
|
|
15701
|
+
|
|
15702
|
+
# async def install_version(self, version: InterpVersion) -> Interp:
|
|
15703
|
+
# raise TypeError
|
|
15704
|
+
|
|
14980
15705
|
|
|
14981
15706
|
########################################
|
|
14982
15707
|
# ../commands/inject.py
|
|
@@ -16826,7 +17551,7 @@ class MainCli(ArgparseCli):
|
|
|
16826
17551
|
|
|
16827
17552
|
|
|
16828
17553
|
def _main() -> None:
|
|
16829
|
-
|
|
17554
|
+
raise SystemExit(asyncio.run(MainCli().async_cli_run()))
|
|
16830
17555
|
|
|
16831
17556
|
|
|
16832
17557
|
if __name__ == '__main__':
|