omdev 0.0.0.dev440__py3-none-any.whl → 0.0.0.dev495__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of omdev might be problematic. Click here for more details.
- omdev/.omlish-manifests.json +18 -30
- omdev/README.md +51 -0
- omdev/__about__.py +11 -7
- omdev/amalg/gen/gen.py +49 -6
- omdev/amalg/gen/imports.py +1 -1
- omdev/amalg/gen/manifests.py +1 -1
- omdev/amalg/gen/resources.py +1 -1
- omdev/amalg/gen/srcfiles.py +13 -3
- omdev/amalg/gen/strip.py +1 -1
- omdev/amalg/gen/types.py +1 -1
- omdev/amalg/gen/typing.py +1 -1
- omdev/amalg/info.py +32 -0
- omdev/cache/data/actions.py +1 -1
- omdev/cache/data/specs.py +1 -1
- omdev/cexts/_boilerplate.cc +2 -3
- omdev/cexts/cmake.py +4 -1
- omdev/ci/cli.py +2 -3
- omdev/cli/clicli.py +37 -7
- omdev/cmdlog/cli.py +1 -2
- omdev/dataclasses/_dumping.py +1960 -0
- omdev/dataclasses/_template.py +22 -0
- omdev/dataclasses/cli.py +7 -2
- omdev/dataclasses/codegen.py +340 -60
- omdev/dataclasses/dumping.py +200 -0
- omdev/interp/cli.py +1 -1
- omdev/interp/types.py +3 -2
- omdev/interp/uv/provider.py +37 -0
- omdev/interp/venvs.py +1 -0
- omdev/irc/messages/base.py +50 -0
- omdev/irc/messages/formats.py +92 -0
- omdev/irc/messages/messages.py +775 -0
- omdev/irc/messages/parsing.py +99 -0
- omdev/irc/numerics/__init__.py +0 -0
- omdev/irc/numerics/formats.py +97 -0
- omdev/irc/numerics/numerics.py +865 -0
- omdev/irc/numerics/types.py +59 -0
- omdev/irc/protocol/LICENSE +11 -0
- omdev/irc/protocol/__init__.py +61 -0
- omdev/irc/protocol/consts.py +6 -0
- omdev/irc/protocol/errors.py +30 -0
- omdev/irc/protocol/message.py +21 -0
- omdev/irc/protocol/nuh.py +55 -0
- omdev/irc/protocol/parsing.py +158 -0
- omdev/irc/protocol/rendering.py +153 -0
- omdev/irc/protocol/tags.py +102 -0
- omdev/irc/protocol/utils.py +30 -0
- omdev/manifests/_dumping.py +125 -25
- omdev/manifests/main.py +1 -1
- omdev/markdown/__init__.py +0 -0
- omdev/markdown/incparse.py +116 -0
- omdev/markdown/tokens.py +51 -0
- omdev/packaging/marshal.py +8 -8
- omdev/packaging/requires.py +6 -6
- omdev/packaging/revisions.py +1 -1
- omdev/packaging/specifiers.py +2 -1
- omdev/packaging/versions.py +4 -4
- omdev/packaging/wheelfile.py +2 -0
- omdev/precheck/blanklines.py +66 -0
- omdev/precheck/caches.py +1 -1
- omdev/precheck/imports.py +14 -1
- omdev/precheck/main.py +4 -3
- omdev/precheck/unicode.py +39 -15
- omdev/py/asts/__init__.py +0 -0
- omdev/py/asts/parents.py +28 -0
- omdev/py/asts/toplevel.py +123 -0
- omdev/py/asts/visitors.py +18 -0
- omdev/py/attrdocs.py +1 -1
- omdev/py/bracepy.py +12 -4
- omdev/py/reprs.py +32 -0
- omdev/py/srcheaders.py +1 -1
- omdev/py/tokens/__init__.py +0 -0
- omdev/py/tools/mkrelimp.py +1 -1
- omdev/py/tools/pipdepup.py +686 -0
- omdev/pyproject/cli.py +1 -1
- omdev/pyproject/pkg.py +190 -45
- omdev/pyproject/reqs.py +31 -9
- omdev/pyproject/tools/__init__.py +0 -0
- omdev/pyproject/tools/aboutdeps.py +60 -0
- omdev/pyproject/venvs.py +8 -1
- omdev/rs/__init__.py +0 -0
- omdev/scripts/ci.py +752 -98
- omdev/scripts/interp.py +232 -39
- omdev/scripts/lib/inject.py +74 -27
- omdev/scripts/lib/logs.py +187 -43
- omdev/scripts/lib/marshal.py +67 -25
- omdev/scripts/pyproject.py +1369 -143
- omdev/tools/git/cli.py +10 -0
- omdev/tools/json/formats.py +2 -0
- omdev/tools/json/processing.py +5 -2
- omdev/tools/jsonview/cli.py +49 -65
- omdev/tools/jsonview/resources/jsonview.html.j2 +43 -0
- omdev/tools/pawk/README.md +195 -0
- omdev/tools/pawk/pawk.py +2 -2
- omdev/tools/pip.py +8 -0
- omdev/tui/__init__.py +0 -0
- omdev/tui/apps/__init__.py +0 -0
- omdev/tui/apps/edit/__init__.py +0 -0
- omdev/tui/apps/edit/main.py +167 -0
- omdev/tui/apps/irc/__init__.py +0 -0
- omdev/tui/apps/irc/__main__.py +4 -0
- omdev/tui/apps/irc/app.py +286 -0
- omdev/tui/apps/irc/client.py +187 -0
- omdev/tui/apps/irc/commands.py +175 -0
- omdev/tui/apps/irc/main.py +26 -0
- omdev/tui/apps/markdown/__init__.py +0 -0
- omdev/tui/apps/markdown/__main__.py +11 -0
- omdev/{ptk → tui/apps}/markdown/cli.py +5 -7
- omdev/tui/rich/__init__.py +46 -0
- omdev/tui/rich/console2.py +20 -0
- omdev/tui/rich/markdown2.py +186 -0
- omdev/tui/textual/__init__.py +265 -0
- omdev/tui/textual/app2.py +16 -0
- omdev/tui/textual/autocomplete/LICENSE +21 -0
- omdev/tui/textual/autocomplete/__init__.py +33 -0
- omdev/tui/textual/autocomplete/matching.py +226 -0
- omdev/tui/textual/autocomplete/paths.py +202 -0
- omdev/tui/textual/autocomplete/widget.py +612 -0
- omdev/tui/textual/debug/__init__.py +10 -0
- omdev/tui/textual/debug/dominfo.py +151 -0
- omdev/tui/textual/debug/screen.py +24 -0
- omdev/tui/textual/devtools.py +187 -0
- omdev/tui/textual/drivers2.py +55 -0
- omdev/tui/textual/logging2.py +20 -0
- omdev/tui/textual/types.py +45 -0
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev495.dist-info}/METADATA +15 -9
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev495.dist-info}/RECORD +135 -80
- omdev/ptk/__init__.py +0 -103
- omdev/ptk/apps/ncdu.py +0 -167
- omdev/ptk/confirm.py +0 -60
- omdev/ptk/markdown/LICENSE +0 -22
- omdev/ptk/markdown/__init__.py +0 -10
- omdev/ptk/markdown/__main__.py +0 -11
- omdev/ptk/markdown/border.py +0 -94
- omdev/ptk/markdown/markdown.py +0 -390
- omdev/ptk/markdown/parser.py +0 -42
- omdev/ptk/markdown/styles.py +0 -29
- omdev/ptk/markdown/tags.py +0 -299
- omdev/ptk/markdown/utils.py +0 -366
- omdev/pyproject/cexts.py +0 -110
- /omdev/{ptk/apps → irc}/__init__.py +0 -0
- /omdev/{tokens → irc/messages}/__init__.py +0 -0
- /omdev/{tokens → py/tokens}/all.py +0 -0
- /omdev/{tokens → py/tokens}/tokenizert.py +0 -0
- /omdev/{tokens → py/tokens}/utils.py +0 -0
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev495.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev495.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev495.dist-info}/licenses/LICENSE +0 -0
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev495.dist-info}/top_level.txt +0 -0
omdev/scripts/lib/logs.py
CHANGED
|
@@ -30,9 +30,33 @@ if sys.version_info < (3, 8):
|
|
|
30
30
|
raise OSError(f'Requires python (3, 8), got {sys.version_info} from {sys.executable}') # noqa
|
|
31
31
|
|
|
32
32
|
|
|
33
|
+
def __omlish_amalg__(): # noqa
|
|
34
|
+
return dict(
|
|
35
|
+
src_files=[
|
|
36
|
+
dict(path='../lite/abstract.py', sha1='a2fc3f3697fa8de5247761e9d554e70176f37aac'),
|
|
37
|
+
dict(path='../lite/json.py', sha1='57eeddc4d23a17931e00284ffa5cb6e3ce089486'),
|
|
38
|
+
dict(path='levels.py', sha1='91405563d082a5eba874da82aac89d83ce7b6152'),
|
|
39
|
+
dict(path='std/filters.py', sha1='f36aab646d84d31e295b33aaaaa6f8b67ff38b3d'),
|
|
40
|
+
dict(path='std/proxy.py', sha1='3e7301a2aa351127f9c85f61b2f85dcc3f15aafb'),
|
|
41
|
+
dict(path='warnings.py', sha1='c4eb694b24773351107fcc058f3620f1dbfb6799'),
|
|
42
|
+
dict(path='infos.py', sha1='4dd104bd468a8c438601dd0bbda619b47d2f1620'),
|
|
43
|
+
dict(path='std/json.py', sha1='2a75553131e4d5331bb0cedde42aa183f403fc3b'),
|
|
44
|
+
dict(path='contexts.py', sha1='1000a6d5ddfb642865ca532e34b1d50759781cf0'),
|
|
45
|
+
dict(path='std/standard.py', sha1='5c97c1b9f7ead58d6127d047b873398f708f288d'),
|
|
46
|
+
dict(path='base.py', sha1='8d06faee05fead6b1dd98c9035a5b042af4aebb1'),
|
|
47
|
+
dict(path='std/records.py', sha1='8bbf6ef9eccb3a012c6ca416ddf3969450fd8fc9'),
|
|
48
|
+
dict(path='std/loggers.py', sha1='a569179445d6a8a942b5dcfad1d1f77702868803'),
|
|
49
|
+
dict(path='_amalg.py', sha1='ae5189de25ab155651a5b2f21dd0baf6eb4f3916'),
|
|
50
|
+
],
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
33
54
|
########################################
|
|
34
55
|
|
|
35
56
|
|
|
57
|
+
# ../lite/abstract.py
|
|
58
|
+
T = ta.TypeVar('T')
|
|
59
|
+
|
|
36
60
|
# levels.py
|
|
37
61
|
LogLevel = int # ta.TypeAlias
|
|
38
62
|
|
|
@@ -46,9 +70,6 @@ LoggingContextInfo = ta.Any # ta.TypeAlias
|
|
|
46
70
|
# contexts.py
|
|
47
71
|
LoggingContextInfoT = ta.TypeVar('LoggingContextInfoT', bound=LoggingContextInfo)
|
|
48
72
|
|
|
49
|
-
# base.py
|
|
50
|
-
T = ta.TypeVar('T')
|
|
51
|
-
|
|
52
73
|
|
|
53
74
|
########################################
|
|
54
75
|
# ../../lite/abstract.py
|
|
@@ -65,25 +86,49 @@ def is_abstract_method(obj: ta.Any) -> bool:
|
|
|
65
86
|
return bool(getattr(obj, _IS_ABSTRACT_METHOD_ATTR, False))
|
|
66
87
|
|
|
67
88
|
|
|
68
|
-
def
|
|
89
|
+
def compute_abstract_methods(cls: type) -> ta.FrozenSet[str]:
|
|
90
|
+
# ~> https://github.com/python/cpython/blob/f3476c6507381ca860eec0989f53647b13517423/Modules/_abc.c#L358
|
|
91
|
+
|
|
92
|
+
# Stage 1: direct abstract methods
|
|
93
|
+
|
|
94
|
+
abstracts = {
|
|
95
|
+
a
|
|
96
|
+
# Get items as a list to avoid mutation issues during iteration
|
|
97
|
+
for a, v in list(cls.__dict__.items())
|
|
98
|
+
if is_abstract_method(v)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# Stage 2: inherited abstract methods
|
|
102
|
+
|
|
103
|
+
for base in cls.__bases__:
|
|
104
|
+
# Get __abstractmethods__ from base if it exists
|
|
105
|
+
if (base_abstracts := getattr(base, _ABSTRACT_METHODS_ATTR, None)) is None:
|
|
106
|
+
continue
|
|
107
|
+
|
|
108
|
+
# Iterate over abstract methods in base
|
|
109
|
+
for key in base_abstracts:
|
|
110
|
+
# Check if this class has an attribute with this name
|
|
111
|
+
try:
|
|
112
|
+
value = getattr(cls, key)
|
|
113
|
+
except AttributeError:
|
|
114
|
+
# Attribute not found in this class, skip
|
|
115
|
+
continue
|
|
116
|
+
|
|
117
|
+
# Check if it's still abstract
|
|
118
|
+
if is_abstract_method(value):
|
|
119
|
+
abstracts.add(key)
|
|
120
|
+
|
|
121
|
+
return frozenset(abstracts)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def update_abstracts(cls: ta.Type[T], *, force: bool = False) -> ta.Type[T]:
|
|
69
125
|
if not force and not hasattr(cls, _ABSTRACT_METHODS_ATTR):
|
|
70
126
|
# Per stdlib: We check for __abstractmethods__ here because cls might by a C implementation or a python
|
|
71
127
|
# implementation (especially during testing), and we want to handle both cases.
|
|
72
128
|
return cls
|
|
73
129
|
|
|
74
|
-
abstracts
|
|
75
|
-
|
|
76
|
-
for scls in cls.__bases__:
|
|
77
|
-
for name in getattr(scls, _ABSTRACT_METHODS_ATTR, ()):
|
|
78
|
-
value = getattr(cls, name, None)
|
|
79
|
-
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
|
80
|
-
abstracts.add(name)
|
|
81
|
-
|
|
82
|
-
for name, value in cls.__dict__.items():
|
|
83
|
-
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
|
84
|
-
abstracts.add(name)
|
|
85
|
-
|
|
86
|
-
setattr(cls, _ABSTRACT_METHODS_ATTR, frozenset(abstracts))
|
|
130
|
+
abstracts = compute_abstract_methods(cls)
|
|
131
|
+
setattr(cls, _ABSTRACT_METHODS_ATTR, abstracts)
|
|
87
132
|
return cls
|
|
88
133
|
|
|
89
134
|
|
|
@@ -137,23 +182,26 @@ class Abstract:
|
|
|
137
182
|
super().__init_subclass__(**kwargs)
|
|
138
183
|
|
|
139
184
|
if not (Abstract in cls.__bases__ or abc.ABC in cls.__bases__):
|
|
140
|
-
ams
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
185
|
+
if ams := compute_abstract_methods(cls):
|
|
186
|
+
amd = {
|
|
187
|
+
a: mcls
|
|
188
|
+
for mcls in cls.__mro__[::-1]
|
|
189
|
+
for a in ams
|
|
190
|
+
if a in mcls.__dict__
|
|
191
|
+
}
|
|
146
192
|
|
|
147
|
-
if ams:
|
|
148
193
|
raise AbstractTypeError(
|
|
149
194
|
f'Cannot subclass abstract class {cls.__name__} with abstract methods: ' +
|
|
150
195
|
', '.join(sorted([
|
|
151
196
|
'.'.join([
|
|
152
|
-
*([
|
|
153
|
-
|
|
197
|
+
*([
|
|
198
|
+
*([m] if (m := getattr(c, '__module__')) else []),
|
|
199
|
+
getattr(c, '__qualname__', getattr(c, '__name__')),
|
|
200
|
+
] if c is not None else '?'),
|
|
154
201
|
a,
|
|
155
202
|
])
|
|
156
|
-
for a
|
|
203
|
+
for a in ams
|
|
204
|
+
for c in [amd.get(a)]
|
|
157
205
|
])),
|
|
158
206
|
)
|
|
159
207
|
|
|
@@ -954,6 +1002,9 @@ class CaptureLoggingContextImpl(CaptureLoggingContext):
|
|
|
954
1002
|
self._infos[type(info)] = info
|
|
955
1003
|
return self
|
|
956
1004
|
|
|
1005
|
+
def get_infos(self) -> ta.Mapping[ta.Type[LoggingContextInfo], LoggingContextInfo]:
|
|
1006
|
+
return self._infos
|
|
1007
|
+
|
|
957
1008
|
def get_info(self, ty: ta.Type[LoggingContextInfoT]) -> ta.Optional[LoggingContextInfoT]:
|
|
958
1009
|
return self._infos.get(ty)
|
|
959
1010
|
|
|
@@ -976,7 +1027,7 @@ class CaptureLoggingContextImpl(CaptureLoggingContext):
|
|
|
976
1027
|
_stack_offset: int
|
|
977
1028
|
_stack_info: bool
|
|
978
1029
|
|
|
979
|
-
def inc_stack_offset(self, ofs: int = 1) -> '
|
|
1030
|
+
def inc_stack_offset(self, ofs: int = 1) -> 'CaptureLoggingContextImpl':
|
|
980
1031
|
if hasattr(self, '_stack_offset'):
|
|
981
1032
|
self._stack_offset += ofs
|
|
982
1033
|
return self
|
|
@@ -1008,10 +1059,9 @@ class CaptureLoggingContextImpl(CaptureLoggingContext):
|
|
|
1008
1059
|
|
|
1009
1060
|
|
|
1010
1061
|
########################################
|
|
1011
|
-
# ../standard.py
|
|
1062
|
+
# ../std/standard.py
|
|
1012
1063
|
"""
|
|
1013
1064
|
TODO:
|
|
1014
|
-
- !! move to std !!
|
|
1015
1065
|
- structured
|
|
1016
1066
|
- prefixed
|
|
1017
1067
|
- debug
|
|
@@ -1161,6 +1211,11 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
1161
1211
|
|
|
1162
1212
|
##
|
|
1163
1213
|
|
|
1214
|
+
# This will be 1 for [Sync]Logger and 0 for AsyncLogger - in sync loggers these methods remain present on the stack,
|
|
1215
|
+
# in async loggers they return a coroutine to be awaited and thus aren't actually present when said coroutine is
|
|
1216
|
+
# awaited.
|
|
1217
|
+
_level_proxy_method_stack_offset: int
|
|
1218
|
+
|
|
1164
1219
|
@ta.overload
|
|
1165
1220
|
def log(self, level: LogLevel, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
|
|
1166
1221
|
...
|
|
@@ -1175,7 +1230,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
1175
1230
|
|
|
1176
1231
|
@ta.final
|
|
1177
1232
|
def log(self, level: LogLevel, *args, **kwargs):
|
|
1178
|
-
return self._log(
|
|
1233
|
+
return self._log(
|
|
1234
|
+
CaptureLoggingContextImpl(
|
|
1235
|
+
level,
|
|
1236
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
1237
|
+
),
|
|
1238
|
+
*args,
|
|
1239
|
+
**kwargs,
|
|
1240
|
+
)
|
|
1179
1241
|
|
|
1180
1242
|
#
|
|
1181
1243
|
|
|
@@ -1193,7 +1255,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
1193
1255
|
|
|
1194
1256
|
@ta.final
|
|
1195
1257
|
def debug(self, *args, **kwargs):
|
|
1196
|
-
return self._log(
|
|
1258
|
+
return self._log(
|
|
1259
|
+
CaptureLoggingContextImpl(
|
|
1260
|
+
NamedLogLevel.DEBUG,
|
|
1261
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
1262
|
+
),
|
|
1263
|
+
*args,
|
|
1264
|
+
**kwargs,
|
|
1265
|
+
)
|
|
1197
1266
|
|
|
1198
1267
|
#
|
|
1199
1268
|
|
|
@@ -1211,7 +1280,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
1211
1280
|
|
|
1212
1281
|
@ta.final
|
|
1213
1282
|
def info(self, *args, **kwargs):
|
|
1214
|
-
return self._log(
|
|
1283
|
+
return self._log(
|
|
1284
|
+
CaptureLoggingContextImpl(
|
|
1285
|
+
NamedLogLevel.INFO,
|
|
1286
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
1287
|
+
),
|
|
1288
|
+
*args,
|
|
1289
|
+
**kwargs,
|
|
1290
|
+
)
|
|
1215
1291
|
|
|
1216
1292
|
#
|
|
1217
1293
|
|
|
@@ -1229,7 +1305,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
1229
1305
|
|
|
1230
1306
|
@ta.final
|
|
1231
1307
|
def warning(self, *args, **kwargs):
|
|
1232
|
-
return self._log(
|
|
1308
|
+
return self._log(
|
|
1309
|
+
CaptureLoggingContextImpl(
|
|
1310
|
+
NamedLogLevel.WARNING,
|
|
1311
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
1312
|
+
),
|
|
1313
|
+
*args,
|
|
1314
|
+
**kwargs,
|
|
1315
|
+
)
|
|
1233
1316
|
|
|
1234
1317
|
#
|
|
1235
1318
|
|
|
@@ -1247,7 +1330,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
1247
1330
|
|
|
1248
1331
|
@ta.final
|
|
1249
1332
|
def error(self, *args, **kwargs):
|
|
1250
|
-
return self._log(
|
|
1333
|
+
return self._log(
|
|
1334
|
+
CaptureLoggingContextImpl(
|
|
1335
|
+
NamedLogLevel.ERROR,
|
|
1336
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
1337
|
+
),
|
|
1338
|
+
*args,
|
|
1339
|
+
**kwargs,
|
|
1340
|
+
)
|
|
1251
1341
|
|
|
1252
1342
|
#
|
|
1253
1343
|
|
|
@@ -1265,7 +1355,15 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
1265
1355
|
|
|
1266
1356
|
@ta.final
|
|
1267
1357
|
def exception(self, *args, exc_info: LoggingExcInfoArg = True, **kwargs):
|
|
1268
|
-
return self._log(
|
|
1358
|
+
return self._log(
|
|
1359
|
+
CaptureLoggingContextImpl(
|
|
1360
|
+
NamedLogLevel.ERROR,
|
|
1361
|
+
exc_info=exc_info,
|
|
1362
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
1363
|
+
),
|
|
1364
|
+
*args,
|
|
1365
|
+
**kwargs,
|
|
1366
|
+
)
|
|
1269
1367
|
|
|
1270
1368
|
#
|
|
1271
1369
|
|
|
@@ -1283,24 +1381,53 @@ class AnyLogger(Abstract, ta.Generic[T]):
|
|
|
1283
1381
|
|
|
1284
1382
|
@ta.final
|
|
1285
1383
|
def critical(self, *args, **kwargs):
|
|
1286
|
-
return self._log(
|
|
1384
|
+
return self._log(
|
|
1385
|
+
CaptureLoggingContextImpl(
|
|
1386
|
+
NamedLogLevel.CRITICAL,
|
|
1387
|
+
stack_offset=self._level_proxy_method_stack_offset,
|
|
1388
|
+
),
|
|
1389
|
+
*args,
|
|
1390
|
+
**kwargs,
|
|
1391
|
+
)
|
|
1287
1392
|
|
|
1288
1393
|
##
|
|
1289
1394
|
|
|
1290
1395
|
@abc.abstractmethod
|
|
1291
|
-
def _log(
|
|
1396
|
+
def _log(
|
|
1397
|
+
self,
|
|
1398
|
+
ctx: CaptureLoggingContext,
|
|
1399
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
1400
|
+
*args: ta.Any,
|
|
1401
|
+
**kwargs: ta.Any,
|
|
1402
|
+
) -> T:
|
|
1292
1403
|
raise NotImplementedError
|
|
1293
1404
|
|
|
1294
1405
|
|
|
1295
1406
|
class Logger(AnyLogger[None], Abstract):
|
|
1407
|
+
_level_proxy_method_stack_offset: int = 1
|
|
1408
|
+
|
|
1296
1409
|
@abc.abstractmethod
|
|
1297
|
-
def _log(
|
|
1410
|
+
def _log(
|
|
1411
|
+
self,
|
|
1412
|
+
ctx: CaptureLoggingContext,
|
|
1413
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
1414
|
+
*args: ta.Any,
|
|
1415
|
+
**kwargs: ta.Any,
|
|
1416
|
+
) -> None:
|
|
1298
1417
|
raise NotImplementedError
|
|
1299
1418
|
|
|
1300
1419
|
|
|
1301
1420
|
class AsyncLogger(AnyLogger[ta.Awaitable[None]], Abstract):
|
|
1421
|
+
_level_proxy_method_stack_offset: int = 0
|
|
1422
|
+
|
|
1302
1423
|
@abc.abstractmethod
|
|
1303
|
-
def _log(
|
|
1424
|
+
def _log(
|
|
1425
|
+
self,
|
|
1426
|
+
ctx: CaptureLoggingContext,
|
|
1427
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
1428
|
+
*args: ta.Any,
|
|
1429
|
+
**kwargs: ta.Any,
|
|
1430
|
+
) -> ta.Awaitable[None]:
|
|
1304
1431
|
raise NotImplementedError
|
|
1305
1432
|
|
|
1306
1433
|
|
|
@@ -1315,13 +1442,25 @@ class AnyNopLogger(AnyLogger[T], Abstract):
|
|
|
1315
1442
|
|
|
1316
1443
|
@ta.final
|
|
1317
1444
|
class NopLogger(AnyNopLogger[None], Logger):
|
|
1318
|
-
def _log(
|
|
1445
|
+
def _log(
|
|
1446
|
+
self,
|
|
1447
|
+
ctx: CaptureLoggingContext,
|
|
1448
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
1449
|
+
*args: ta.Any,
|
|
1450
|
+
**kwargs: ta.Any,
|
|
1451
|
+
) -> None:
|
|
1319
1452
|
pass
|
|
1320
1453
|
|
|
1321
1454
|
|
|
1322
1455
|
@ta.final
|
|
1323
1456
|
class AsyncNopLogger(AnyNopLogger[ta.Awaitable[None]], AsyncLogger):
|
|
1324
|
-
async def _log(
|
|
1457
|
+
async def _log(
|
|
1458
|
+
self,
|
|
1459
|
+
ctx: CaptureLoggingContext,
|
|
1460
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
1461
|
+
*args: ta.Any,
|
|
1462
|
+
**kwargs: ta.Any,
|
|
1463
|
+
) -> None:
|
|
1325
1464
|
pass
|
|
1326
1465
|
|
|
1327
1466
|
|
|
@@ -2006,7 +2145,12 @@ class StdLogger(Logger):
|
|
|
2006
2145
|
def get_effective_level(self) -> LogLevel:
|
|
2007
2146
|
return self._std.getEffectiveLevel()
|
|
2008
2147
|
|
|
2009
|
-
def _log(
|
|
2148
|
+
def _log(
|
|
2149
|
+
self,
|
|
2150
|
+
ctx: CaptureLoggingContext,
|
|
2151
|
+
msg: ta.Union[str, tuple, LoggingMsgFn],
|
|
2152
|
+
*args: ta.Any,
|
|
2153
|
+
) -> None:
|
|
2010
2154
|
if not self.is_enabled_for(ctx.must_get_info(LoggingContextInfos.Level).level):
|
|
2011
2155
|
return
|
|
2012
2156
|
|
omdev/scripts/lib/marshal.py
CHANGED
|
@@ -37,11 +37,26 @@ if sys.version_info < (3, 8):
|
|
|
37
37
|
raise OSError(f'Requires python (3, 8), got {sys.version_info} from {sys.executable}') # noqa
|
|
38
38
|
|
|
39
39
|
|
|
40
|
+
def __omlish_amalg__(): # noqa
|
|
41
|
+
return dict(
|
|
42
|
+
src_files=[
|
|
43
|
+
dict(path='abstract.py', sha1='a2fc3f3697fa8de5247761e9d554e70176f37aac'),
|
|
44
|
+
dict(path='check.py', sha1='bb6b6b63333699b84462951a854d99ae83195b94'),
|
|
45
|
+
dict(path='objects.py', sha1='9566bbf3530fd71fcc56321485216b592fae21e9'),
|
|
46
|
+
dict(path='reflect.py', sha1='c4fec44bf144e9d93293c996af06f6c65fc5e63d'),
|
|
47
|
+
dict(path='strings.py', sha1='89831ecbc34ad80e118a865eceb390ed399dc4d6'),
|
|
48
|
+
dict(path='marshal.py', sha1='96348f5f2a26dc27d842d33cc3927e9da163436b'),
|
|
49
|
+
],
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
40
53
|
########################################
|
|
41
54
|
|
|
42
55
|
|
|
43
|
-
#
|
|
56
|
+
# abstract.py
|
|
44
57
|
T = ta.TypeVar('T')
|
|
58
|
+
|
|
59
|
+
# check.py
|
|
45
60
|
SizedT = ta.TypeVar('SizedT', bound=ta.Sized)
|
|
46
61
|
CheckMessage = ta.Union[str, ta.Callable[..., ta.Optional[str]], None] # ta.TypeAlias
|
|
47
62
|
CheckLateConfigureFn = ta.Callable[['Checks'], None] # ta.TypeAlias
|
|
@@ -65,25 +80,49 @@ def is_abstract_method(obj: ta.Any) -> bool:
|
|
|
65
80
|
return bool(getattr(obj, _IS_ABSTRACT_METHOD_ATTR, False))
|
|
66
81
|
|
|
67
82
|
|
|
68
|
-
def
|
|
83
|
+
def compute_abstract_methods(cls: type) -> ta.FrozenSet[str]:
|
|
84
|
+
# ~> https://github.com/python/cpython/blob/f3476c6507381ca860eec0989f53647b13517423/Modules/_abc.c#L358
|
|
85
|
+
|
|
86
|
+
# Stage 1: direct abstract methods
|
|
87
|
+
|
|
88
|
+
abstracts = {
|
|
89
|
+
a
|
|
90
|
+
# Get items as a list to avoid mutation issues during iteration
|
|
91
|
+
for a, v in list(cls.__dict__.items())
|
|
92
|
+
if is_abstract_method(v)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
# Stage 2: inherited abstract methods
|
|
96
|
+
|
|
97
|
+
for base in cls.__bases__:
|
|
98
|
+
# Get __abstractmethods__ from base if it exists
|
|
99
|
+
if (base_abstracts := getattr(base, _ABSTRACT_METHODS_ATTR, None)) is None:
|
|
100
|
+
continue
|
|
101
|
+
|
|
102
|
+
# Iterate over abstract methods in base
|
|
103
|
+
for key in base_abstracts:
|
|
104
|
+
# Check if this class has an attribute with this name
|
|
105
|
+
try:
|
|
106
|
+
value = getattr(cls, key)
|
|
107
|
+
except AttributeError:
|
|
108
|
+
# Attribute not found in this class, skip
|
|
109
|
+
continue
|
|
110
|
+
|
|
111
|
+
# Check if it's still abstract
|
|
112
|
+
if is_abstract_method(value):
|
|
113
|
+
abstracts.add(key)
|
|
114
|
+
|
|
115
|
+
return frozenset(abstracts)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def update_abstracts(cls: ta.Type[T], *, force: bool = False) -> ta.Type[T]:
|
|
69
119
|
if not force and not hasattr(cls, _ABSTRACT_METHODS_ATTR):
|
|
70
120
|
# Per stdlib: We check for __abstractmethods__ here because cls might by a C implementation or a python
|
|
71
121
|
# implementation (especially during testing), and we want to handle both cases.
|
|
72
122
|
return cls
|
|
73
123
|
|
|
74
|
-
abstracts
|
|
75
|
-
|
|
76
|
-
for scls in cls.__bases__:
|
|
77
|
-
for name in getattr(scls, _ABSTRACT_METHODS_ATTR, ()):
|
|
78
|
-
value = getattr(cls, name, None)
|
|
79
|
-
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
|
80
|
-
abstracts.add(name)
|
|
81
|
-
|
|
82
|
-
for name, value in cls.__dict__.items():
|
|
83
|
-
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
|
84
|
-
abstracts.add(name)
|
|
85
|
-
|
|
86
|
-
setattr(cls, _ABSTRACT_METHODS_ATTR, frozenset(abstracts))
|
|
124
|
+
abstracts = compute_abstract_methods(cls)
|
|
125
|
+
setattr(cls, _ABSTRACT_METHODS_ATTR, abstracts)
|
|
87
126
|
return cls
|
|
88
127
|
|
|
89
128
|
|
|
@@ -137,23 +176,26 @@ class Abstract:
|
|
|
137
176
|
super().__init_subclass__(**kwargs)
|
|
138
177
|
|
|
139
178
|
if not (Abstract in cls.__bases__ or abc.ABC in cls.__bases__):
|
|
140
|
-
ams
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
179
|
+
if ams := compute_abstract_methods(cls):
|
|
180
|
+
amd = {
|
|
181
|
+
a: mcls
|
|
182
|
+
for mcls in cls.__mro__[::-1]
|
|
183
|
+
for a in ams
|
|
184
|
+
if a in mcls.__dict__
|
|
185
|
+
}
|
|
146
186
|
|
|
147
|
-
if ams:
|
|
148
187
|
raise AbstractTypeError(
|
|
149
188
|
f'Cannot subclass abstract class {cls.__name__} with abstract methods: ' +
|
|
150
189
|
', '.join(sorted([
|
|
151
190
|
'.'.join([
|
|
152
|
-
*([
|
|
153
|
-
|
|
191
|
+
*([
|
|
192
|
+
*([m] if (m := getattr(c, '__module__')) else []),
|
|
193
|
+
getattr(c, '__qualname__', getattr(c, '__name__')),
|
|
194
|
+
] if c is not None else '?'),
|
|
154
195
|
a,
|
|
155
196
|
])
|
|
156
|
-
for a
|
|
197
|
+
for a in ams
|
|
198
|
+
for c in [amd.get(a)]
|
|
157
199
|
])),
|
|
158
200
|
)
|
|
159
201
|
|