omlish 0.0.0.dev6__py3-none-any.whl → 0.0.0.dev8__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.
- omlish/__about__.py +109 -5
- omlish/__init__.py +0 -8
- omlish/asyncs/__init__.py +0 -9
- omlish/asyncs/anyio.py +40 -0
- omlish/bootstrap.py +737 -0
- omlish/check.py +1 -1
- omlish/collections/__init__.py +4 -0
- omlish/collections/exceptions.py +2 -0
- omlish/collections/utils.py +38 -9
- omlish/configs/strings.py +2 -0
- omlish/dataclasses/__init__.py +7 -0
- omlish/dataclasses/impl/descriptors.py +95 -0
- omlish/dataclasses/impl/reflect.py +1 -1
- omlish/dataclasses/utils.py +23 -0
- omlish/{lang/datetimes.py → datetimes.py} +8 -4
- omlish/diag/procfs.py +1 -1
- omlish/diag/threads.py +131 -48
- omlish/docker.py +16 -1
- omlish/fnpairs.py +0 -4
- omlish/{serde → formats}/dotenv.py +3 -0
- omlish/{serde → formats}/yaml.py +2 -2
- omlish/graphs/trees.py +1 -1
- omlish/http/consts.py +6 -0
- omlish/http/sessions.py +2 -2
- omlish/inject/__init__.py +4 -0
- omlish/inject/binder.py +3 -3
- omlish/inject/elements.py +1 -1
- omlish/inject/impl/injector.py +57 -27
- omlish/inject/impl/origins.py +2 -0
- omlish/inject/origins.py +3 -0
- omlish/inject/utils.py +18 -0
- omlish/iterators.py +69 -2
- omlish/lang/__init__.py +16 -7
- omlish/lang/classes/restrict.py +10 -0
- omlish/lang/contextmanagers.py +1 -1
- omlish/lang/descriptors.py +3 -3
- omlish/lang/imports.py +67 -0
- omlish/lang/iterables.py +40 -0
- omlish/lang/maybes.py +3 -0
- omlish/lang/objects.py +38 -0
- omlish/lang/strings.py +25 -0
- omlish/lang/sys.py +9 -0
- omlish/lang/typing.py +37 -0
- omlish/lite/__init__.py +1 -0
- omlish/lite/cached.py +18 -0
- omlish/lite/check.py +29 -0
- omlish/lite/contextmanagers.py +18 -0
- omlish/lite/json.py +30 -0
- omlish/lite/logs.py +121 -0
- omlish/lite/marshal.py +318 -0
- omlish/lite/reflect.py +49 -0
- omlish/lite/runtime.py +18 -0
- omlish/lite/secrets.py +19 -0
- omlish/lite/strings.py +25 -0
- omlish/lite/subprocesses.py +112 -0
- omlish/logs/__init__.py +13 -9
- omlish/logs/configs.py +17 -22
- omlish/logs/formatters.py +3 -48
- omlish/marshal/__init__.py +28 -0
- omlish/marshal/any.py +5 -5
- omlish/marshal/base.py +27 -11
- omlish/marshal/base64.py +24 -9
- omlish/marshal/dataclasses.py +34 -28
- omlish/marshal/datetimes.py +74 -18
- omlish/marshal/enums.py +14 -8
- omlish/marshal/exceptions.py +11 -1
- omlish/marshal/factories.py +59 -74
- omlish/marshal/forbidden.py +35 -0
- omlish/marshal/global_.py +11 -4
- omlish/marshal/iterables.py +21 -24
- omlish/marshal/mappings.py +23 -26
- omlish/marshal/numbers.py +51 -0
- omlish/marshal/optionals.py +11 -12
- omlish/marshal/polymorphism.py +86 -21
- omlish/marshal/primitives.py +4 -5
- omlish/marshal/standard.py +13 -8
- omlish/marshal/uuids.py +4 -5
- omlish/matchfns.py +218 -0
- omlish/os.py +64 -0
- omlish/reflect/__init__.py +39 -0
- omlish/reflect/isinstance.py +38 -0
- omlish/reflect/ops.py +84 -0
- omlish/reflect/subst.py +110 -0
- omlish/reflect/types.py +275 -0
- omlish/secrets/__init__.py +18 -2
- omlish/secrets/crypto.py +132 -0
- omlish/secrets/marshal.py +36 -7
- omlish/secrets/openssl.py +207 -0
- omlish/secrets/secrets.py +260 -8
- omlish/secrets/subprocesses.py +42 -0
- omlish/sql/dbs.py +6 -5
- omlish/sql/exprs.py +12 -0
- omlish/sql/secrets.py +10 -0
- omlish/term.py +1 -1
- omlish/testing/pytest/plugins/switches.py +54 -19
- omlish/text/glyphsplit.py +5 -0
- omlish-0.0.0.dev8.dist-info/METADATA +50 -0
- {omlish-0.0.0.dev6.dist-info → omlish-0.0.0.dev8.dist-info}/RECORD +105 -78
- {omlish-0.0.0.dev6.dist-info → omlish-0.0.0.dev8.dist-info}/WHEEL +1 -1
- omlish/logs/filters.py +0 -11
- omlish/reflect.py +0 -470
- omlish-0.0.0.dev6.dist-info/METADATA +0 -34
- /omlish/{asyncs/futures.py → concurrent.py} +0 -0
- /omlish/{serde → formats}/__init__.py +0 -0
- /omlish/{serde → formats}/json.py +0 -0
- /omlish/{serde → formats}/props.py +0 -0
- {omlish-0.0.0.dev6.dist-info → omlish-0.0.0.dev8.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev6.dist-info → omlish-0.0.0.dev8.dist-info}/top_level.txt +0 -0
omlish/reflect.py
DELETED
|
@@ -1,470 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
TODO:
|
|
3
|
-
- visitor / transformer
|
|
4
|
-
- uniform collection isinstance - items() for mappings, iter() for other
|
|
5
|
-
- also check instance type in isinstance not just items lol
|
|
6
|
-
- ta.Generic in mro causing trouble - omit? no longer 1:1
|
|
7
|
-
- cache this shit, esp generic_mro shit
|
|
8
|
-
- cache __hash__ in Generic/Union
|
|
9
|
-
"""
|
|
10
|
-
import collections.abc
|
|
11
|
-
import dataclasses as dc
|
|
12
|
-
import types
|
|
13
|
-
import typing as ta
|
|
14
|
-
|
|
15
|
-
from . import c3
|
|
16
|
-
from . import lang
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if ta.TYPE_CHECKING:
|
|
20
|
-
from .collections import cache
|
|
21
|
-
else:
|
|
22
|
-
cache = lang.proxy_import('.collections.cache', __package__)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
_NoneType = types.NoneType # type: ignore
|
|
26
|
-
|
|
27
|
-
_NONE_TYPE_FROZENSET: frozenset['Type'] = frozenset([_NoneType])
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
_GenericAlias = ta._GenericAlias # type: ignore # noqa
|
|
31
|
-
_CallableGenericAlias = ta._CallableGenericAlias # type: ignore # noqa
|
|
32
|
-
_SpecialGenericAlias = ta._SpecialGenericAlias # type: ignore # noqa
|
|
33
|
-
_UnionGenericAlias = ta._UnionGenericAlias # type: ignore # noqa
|
|
34
|
-
_AnnotatedAlias = ta._AnnotatedAlias # type: ignore # noqa
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
##
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
class _Special(ta.NamedTuple):
|
|
41
|
-
name: str
|
|
42
|
-
alias: _SpecialGenericAlias # type: ignore
|
|
43
|
-
origin: type
|
|
44
|
-
nparams: int
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
_KNOWN_SPECIALS = [
|
|
48
|
-
_Special(
|
|
49
|
-
v._name, # noqa
|
|
50
|
-
v,
|
|
51
|
-
v.__origin__,
|
|
52
|
-
v._nparams, # noqa
|
|
53
|
-
)
|
|
54
|
-
for v in ta.__dict__.values()
|
|
55
|
-
if isinstance(v, _SpecialGenericAlias)
|
|
56
|
-
]
|
|
57
|
-
|
|
58
|
-
_KNOWN_SPECIALS_BY_NAME = {s.name: s for s in _KNOWN_SPECIALS}
|
|
59
|
-
_KNOWN_SPECIALS_BY_ALIAS = {s.alias: s for s in _KNOWN_SPECIALS}
|
|
60
|
-
_KNOWN_SPECIALS_BY_ORIGIN = {s.origin: s for s in _KNOWN_SPECIALS}
|
|
61
|
-
|
|
62
|
-
_MAX_KNOWN_SPECIAL_TYPE_VARS = 16
|
|
63
|
-
|
|
64
|
-
_KNOWN_SPECIAL_TYPE_VARS = tuple(
|
|
65
|
-
ta.TypeVar(f'_{i}') # noqa
|
|
66
|
-
for i in range(_MAX_KNOWN_SPECIAL_TYPE_VARS)
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
##
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def get_params(obj: ta.Any) -> tuple[ta.TypeVar, ...]:
|
|
74
|
-
if isinstance(obj, type):
|
|
75
|
-
if issubclass(obj, ta.Generic): # type: ignore
|
|
76
|
-
return obj.__dict__.get('__parameters__', ()) # noqa
|
|
77
|
-
|
|
78
|
-
if (ks := _KNOWN_SPECIALS_BY_ORIGIN.get(obj)) is not None:
|
|
79
|
-
return _KNOWN_SPECIAL_TYPE_VARS[:ks.nparams]
|
|
80
|
-
|
|
81
|
-
oty = type(obj)
|
|
82
|
-
|
|
83
|
-
if (
|
|
84
|
-
oty is _GenericAlias or
|
|
85
|
-
oty is ta.GenericAlias # type: ignore # noqa
|
|
86
|
-
):
|
|
87
|
-
return obj.__dict__.get('__parameters__', ()) # noqa
|
|
88
|
-
|
|
89
|
-
if oty is _CallableGenericAlias:
|
|
90
|
-
raise NotImplementedError('get_params not yet implemented for typing.Callable')
|
|
91
|
-
|
|
92
|
-
raise TypeError(obj)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def is_union_type(cls: ta.Any) -> bool:
|
|
96
|
-
if hasattr(ta, 'UnionType'):
|
|
97
|
-
return ta.get_origin(cls) in {ta.Union, getattr(ta, 'UnionType')}
|
|
98
|
-
|
|
99
|
-
else:
|
|
100
|
-
return ta.get_origin(cls) in {ta.Union}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
def get_orig_class(obj: ta.Any) -> ta.Any:
|
|
104
|
-
return obj.__orig_class__ # noqa
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
##
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
Type = ta.Union[
|
|
111
|
-
type,
|
|
112
|
-
ta.TypeVar,
|
|
113
|
-
'Union',
|
|
114
|
-
'Generic',
|
|
115
|
-
'NewType',
|
|
116
|
-
'Annotated',
|
|
117
|
-
]
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
class Union(ta.NamedTuple):
|
|
121
|
-
args: frozenset[Type]
|
|
122
|
-
|
|
123
|
-
@property
|
|
124
|
-
def is_optional(self) -> bool:
|
|
125
|
-
return _NoneType in self.args
|
|
126
|
-
|
|
127
|
-
def without_none(self) -> Type:
|
|
128
|
-
if _NoneType not in self.args:
|
|
129
|
-
return self
|
|
130
|
-
rem = self.args - _NONE_TYPE_FROZENSET
|
|
131
|
-
if len(rem) == 1:
|
|
132
|
-
return next(iter(rem))
|
|
133
|
-
return Union(rem)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
@dc.dataclass(frozen=True)
|
|
137
|
-
class Generic:
|
|
138
|
-
cls: type
|
|
139
|
-
args: tuple[Type, ...] # map[int, V] = (int, V) | map[T, T] = (T, T)
|
|
140
|
-
|
|
141
|
-
params: tuple[ta.TypeVar, ...] = dc.field(compare=False, repr=False) # map[int, V] = (_0, _1) | map[T, T] = (_0, _1) # noqa
|
|
142
|
-
# params2: tuple[ta.TypeVar, ...] # map[int, V] = (V,) | map[T, T] = (T,)
|
|
143
|
-
|
|
144
|
-
obj: ta.Any = dc.field(compare=False, repr=False)
|
|
145
|
-
|
|
146
|
-
# def __post_init__(self) -> None:
|
|
147
|
-
# if not isinstance(self.cls, type):
|
|
148
|
-
# raise TypeError(self.cls)
|
|
149
|
-
|
|
150
|
-
def full_eq(self, other: 'Generic') -> bool:
|
|
151
|
-
return (
|
|
152
|
-
self.cls == other.cls and
|
|
153
|
-
self.args == other.args and
|
|
154
|
-
self.params == other.params and
|
|
155
|
-
self.obj == other.obj
|
|
156
|
-
)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
class NewType(ta.NamedTuple):
|
|
160
|
-
obj: ta.Any
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
@dc.dataclass(frozen=True)
|
|
164
|
-
class Annotated:
|
|
165
|
-
ty: Type
|
|
166
|
-
md: ta.Sequence[ta.Any]
|
|
167
|
-
|
|
168
|
-
obj: ta.Any = dc.field(compare=False, repr=False)
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
TYPES: tuple[type, ...] = (
|
|
172
|
-
type,
|
|
173
|
-
ta.TypeVar,
|
|
174
|
-
Union,
|
|
175
|
-
Generic,
|
|
176
|
-
NewType,
|
|
177
|
-
Annotated,
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
##
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
def is_type(obj: ta.Any) -> bool:
|
|
185
|
-
if isinstance(obj, (Union, Generic, ta.TypeVar, NewType)): # noqa
|
|
186
|
-
return True
|
|
187
|
-
|
|
188
|
-
oty = type(obj)
|
|
189
|
-
|
|
190
|
-
return (
|
|
191
|
-
oty is _UnionGenericAlias or oty is types.UnionType or # noqa
|
|
192
|
-
|
|
193
|
-
isinstance(obj, ta.NewType) or # noqa
|
|
194
|
-
|
|
195
|
-
(
|
|
196
|
-
oty is _GenericAlias or
|
|
197
|
-
oty is ta.GenericAlias or # type: ignore # noqa
|
|
198
|
-
oty is _CallableGenericAlias
|
|
199
|
-
) or
|
|
200
|
-
|
|
201
|
-
isinstance(obj, type) or
|
|
202
|
-
|
|
203
|
-
isinstance(obj, _SpecialGenericAlias)
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
def type_(obj: ta.Any) -> Type:
|
|
208
|
-
if isinstance(obj, (Union, Generic, ta.TypeVar, NewType)): # noqa
|
|
209
|
-
return obj
|
|
210
|
-
|
|
211
|
-
oty = type(obj)
|
|
212
|
-
|
|
213
|
-
if oty is _UnionGenericAlias or oty is types.UnionType:
|
|
214
|
-
return Union(frozenset(type_(a) for a in ta.get_args(obj)))
|
|
215
|
-
|
|
216
|
-
if isinstance(obj, ta.NewType): # noqa
|
|
217
|
-
return NewType(obj)
|
|
218
|
-
|
|
219
|
-
if (
|
|
220
|
-
oty is _GenericAlias or
|
|
221
|
-
oty is ta.GenericAlias or # type: ignore # noqa
|
|
222
|
-
oty is _CallableGenericAlias
|
|
223
|
-
):
|
|
224
|
-
origin = ta.get_origin(obj)
|
|
225
|
-
args = ta.get_args(obj)
|
|
226
|
-
if oty is _CallableGenericAlias:
|
|
227
|
-
p, r = args
|
|
228
|
-
if p is Ellipsis or isinstance(p, ta.ParamSpec):
|
|
229
|
-
raise TypeError(f'Callable argument not yet supported for {obj=}')
|
|
230
|
-
args = (*p, r)
|
|
231
|
-
params = _KNOWN_SPECIAL_TYPE_VARS[:len(args)]
|
|
232
|
-
elif origin is ta.Generic:
|
|
233
|
-
params = args
|
|
234
|
-
else:
|
|
235
|
-
params = get_params(origin)
|
|
236
|
-
if len(args) != len(params):
|
|
237
|
-
raise TypeError(f'Mismatched {args=} and {params=} for {obj=}')
|
|
238
|
-
return Generic(
|
|
239
|
-
origin,
|
|
240
|
-
tuple(type_(a) for a in args),
|
|
241
|
-
params,
|
|
242
|
-
obj,
|
|
243
|
-
)
|
|
244
|
-
|
|
245
|
-
if isinstance(obj, type):
|
|
246
|
-
if issubclass(obj, ta.Generic): # type: ignore
|
|
247
|
-
params = get_params(obj)
|
|
248
|
-
return Generic(
|
|
249
|
-
obj,
|
|
250
|
-
params,
|
|
251
|
-
params,
|
|
252
|
-
obj,
|
|
253
|
-
)
|
|
254
|
-
return obj
|
|
255
|
-
|
|
256
|
-
if isinstance(obj, _SpecialGenericAlias):
|
|
257
|
-
if (ks := _KNOWN_SPECIALS_BY_ALIAS.get(obj)) is not None:
|
|
258
|
-
params = _KNOWN_SPECIAL_TYPE_VARS[:ks.nparams]
|
|
259
|
-
return Generic(
|
|
260
|
-
ks.origin,
|
|
261
|
-
params,
|
|
262
|
-
params,
|
|
263
|
-
obj,
|
|
264
|
-
)
|
|
265
|
-
|
|
266
|
-
if isinstance(obj, _AnnotatedAlias):
|
|
267
|
-
o = ta.get_args(obj)[0]
|
|
268
|
-
return Annotated(type_(o), md=obj.__metadata__, obj=obj)
|
|
269
|
-
|
|
270
|
-
raise TypeError(obj)
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
##
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
def strip_objs(ty: Type) -> Type:
|
|
277
|
-
if isinstance(ty, (type, ta.TypeVar, NewType)):
|
|
278
|
-
return ty
|
|
279
|
-
|
|
280
|
-
if isinstance(ty, Union):
|
|
281
|
-
return Union(frozenset(map(strip_objs, ty.args)))
|
|
282
|
-
|
|
283
|
-
if isinstance(ty, Generic):
|
|
284
|
-
return Generic(ty.cls, tuple(map(strip_objs, ty.args)), ty.params, None)
|
|
285
|
-
|
|
286
|
-
if isinstance(ty, Annotated):
|
|
287
|
-
return Annotated(strip_objs(ty.ty), ty.md, None)
|
|
288
|
-
|
|
289
|
-
raise TypeError(ty)
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
def strip_annotations(ty: Type) -> Type:
|
|
293
|
-
if isinstance(ty, (type, ta.TypeVar, NewType)):
|
|
294
|
-
return ty
|
|
295
|
-
|
|
296
|
-
if isinstance(ty, Union):
|
|
297
|
-
return Union(frozenset(map(strip_annotations, ty.args)))
|
|
298
|
-
|
|
299
|
-
if isinstance(ty, Generic):
|
|
300
|
-
return Generic(ty.cls, tuple(map(strip_annotations, ty.args)), ty.params, ty.obj)
|
|
301
|
-
|
|
302
|
-
if isinstance(ty, Annotated):
|
|
303
|
-
return strip_annotations(ty.ty)
|
|
304
|
-
|
|
305
|
-
raise TypeError(ty)
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
def types_equivalent(l: Type, r: Type) -> bool:
|
|
309
|
-
if isinstance(l, Generic) and isinstance(r, Generic):
|
|
310
|
-
return l.cls == r.cls and l.args == r.args
|
|
311
|
-
|
|
312
|
-
return l == r
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
def get_underlying(nt: NewType) -> Type:
|
|
316
|
-
return type_(nt.obj.__supertype__) # noqa
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
def get_concrete_type(ty: Type) -> type | None:
|
|
320
|
-
if isinstance(ty, type):
|
|
321
|
-
return ty
|
|
322
|
-
|
|
323
|
-
if isinstance(ty, Generic):
|
|
324
|
-
return ty.cls
|
|
325
|
-
|
|
326
|
-
if isinstance(ty, NewType):
|
|
327
|
-
return get_concrete_type(get_underlying(ty))
|
|
328
|
-
|
|
329
|
-
if isinstance(ty, (Union, ta.TypeVar)):
|
|
330
|
-
return None
|
|
331
|
-
|
|
332
|
-
raise TypeError(ty)
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
def get_type_var_replacements(ty: Type) -> ta.Mapping[ta.TypeVar, Type]:
|
|
336
|
-
if isinstance(ty, Generic):
|
|
337
|
-
return dict(zip(ty.params, ty.args))
|
|
338
|
-
|
|
339
|
-
return {}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
def to_annotation(ty: Type) -> ta.Any:
|
|
343
|
-
if isinstance(ty, Generic):
|
|
344
|
-
return ty.obj if ty.obj is not None else ty.cls
|
|
345
|
-
|
|
346
|
-
if isinstance(ty, Union):
|
|
347
|
-
return ta.Union[*tuple(to_annotation(e) for e in ty.args)]
|
|
348
|
-
|
|
349
|
-
if isinstance(ty, (type, ta.TypeVar, NewType)):
|
|
350
|
-
return ty
|
|
351
|
-
|
|
352
|
-
raise TypeError(ty)
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
def replace_type_vars(
|
|
356
|
-
ty: Type,
|
|
357
|
-
rpl: ta.Mapping[ta.TypeVar, Type],
|
|
358
|
-
*,
|
|
359
|
-
update_aliases: bool = False,
|
|
360
|
-
) -> Type:
|
|
361
|
-
def rec(cur):
|
|
362
|
-
if isinstance(cur, type):
|
|
363
|
-
return cur
|
|
364
|
-
|
|
365
|
-
if isinstance(cur, NewType):
|
|
366
|
-
return cur
|
|
367
|
-
|
|
368
|
-
if isinstance(cur, Generic):
|
|
369
|
-
args = tuple(rec(a) for a in cur.args)
|
|
370
|
-
if update_aliases:
|
|
371
|
-
obj = cur.obj
|
|
372
|
-
if (ops := get_params(obj)):
|
|
373
|
-
nargs = [to_annotation(rpl[p]) for p in ops]
|
|
374
|
-
if ta.get_origin(obj) is ta.Generic:
|
|
375
|
-
# FIXME: None? filter_typing_generic in get_generic_bases?
|
|
376
|
-
pass
|
|
377
|
-
else:
|
|
378
|
-
obj = cur.obj[*nargs]
|
|
379
|
-
else:
|
|
380
|
-
obj = None
|
|
381
|
-
return dc.replace(cur, args=args, obj=obj)
|
|
382
|
-
|
|
383
|
-
if isinstance(cur, Union):
|
|
384
|
-
return Union(frozenset(rec(e) for e in cur.args))
|
|
385
|
-
|
|
386
|
-
if isinstance(cur, ta.TypeVar):
|
|
387
|
-
return rpl[cur]
|
|
388
|
-
|
|
389
|
-
raise TypeError(cur)
|
|
390
|
-
|
|
391
|
-
return rec(ty)
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
class GenericSubstitution:
|
|
395
|
-
def __init__(
|
|
396
|
-
self,
|
|
397
|
-
*,
|
|
398
|
-
update_aliases: bool = False,
|
|
399
|
-
cache_size: int = 0, # FIXME: ta.Generic isn't weakrefable..
|
|
400
|
-
) -> None:
|
|
401
|
-
super().__init__()
|
|
402
|
-
|
|
403
|
-
self._update_aliases = update_aliases
|
|
404
|
-
|
|
405
|
-
if cache_size > 0:
|
|
406
|
-
self.get_generic_bases = cache.cache(weak_keys=True, max_size=cache_size)(self.get_generic_bases) # type: ignore # noqa
|
|
407
|
-
self.generic_mro = cache.cache(weak_keys=True, max_size=cache_size)(self.generic_mro) # type: ignore
|
|
408
|
-
|
|
409
|
-
def get_generic_bases(self, ty: Type) -> tuple[Type, ...]:
|
|
410
|
-
if (cty := get_concrete_type(ty)) is not None:
|
|
411
|
-
rpl = get_type_var_replacements(ty)
|
|
412
|
-
ret: list[Type] = []
|
|
413
|
-
for b in types.get_original_bases(cty):
|
|
414
|
-
bty = type_(b)
|
|
415
|
-
if isinstance(bty, Generic) and isinstance(b, type):
|
|
416
|
-
# FIXME: throws away relative types, but can't use original vars as they're class-contextual
|
|
417
|
-
bty = type_(b[*((ta.Any,) * len(bty.params))]) # type: ignore
|
|
418
|
-
rty = replace_type_vars(bty, rpl, update_aliases=self._update_aliases)
|
|
419
|
-
ret.append(rty)
|
|
420
|
-
return tuple(ret)
|
|
421
|
-
return ()
|
|
422
|
-
|
|
423
|
-
def generic_mro(self, obj: ta.Any) -> list[Type]:
|
|
424
|
-
mro = c3.mro(
|
|
425
|
-
type_(obj),
|
|
426
|
-
get_bases=lambda t: self.get_generic_bases(t),
|
|
427
|
-
is_subclass=lambda l, r: issubclass(get_concrete_type(l), get_concrete_type(r)), # type: ignore
|
|
428
|
-
)
|
|
429
|
-
return [ty for ty in mro if get_concrete_type(ty) is not ta.Generic]
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
DEFAULT_GENERIC_SUBSTITUTION = GenericSubstitution()
|
|
433
|
-
|
|
434
|
-
get_generic_bases = DEFAULT_GENERIC_SUBSTITUTION.get_generic_bases
|
|
435
|
-
generic_mro = DEFAULT_GENERIC_SUBSTITUTION.generic_mro
|
|
436
|
-
|
|
437
|
-
ALIAS_UPDATING_GENERIC_SUBSTITUTION = GenericSubstitution(update_aliases=True)
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
##
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
KNOWN_GENERICS: ta.AbstractSet[type] = frozenset([
|
|
444
|
-
collections.abc.Mapping,
|
|
445
|
-
collections.abc.Sequence,
|
|
446
|
-
collections.abc.Set,
|
|
447
|
-
])
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
def isinstance_of(rfl: Type) -> ta.Callable[[ta.Any], bool]:
|
|
451
|
-
if isinstance(rfl, type):
|
|
452
|
-
return lambda o: isinstance(o, rfl)
|
|
453
|
-
|
|
454
|
-
if isinstance(rfl, NewType):
|
|
455
|
-
return isinstance_of(get_underlying(rfl))
|
|
456
|
-
|
|
457
|
-
if isinstance(rfl, Union):
|
|
458
|
-
fns = [isinstance_of(a) for a in rfl.args]
|
|
459
|
-
return lambda o: any(fn(o) for fn in fns)
|
|
460
|
-
|
|
461
|
-
if isinstance(rfl, Generic):
|
|
462
|
-
if rfl.cls in (collections.abc.Sequence, collections.abc.Set):
|
|
463
|
-
[efn] = map(isinstance_of, rfl.args)
|
|
464
|
-
return lambda o: isinstance(o, rfl.cls) and all(efn(e) for e in o) # type: ignore
|
|
465
|
-
|
|
466
|
-
if rfl.cls == collections.abc.Mapping:
|
|
467
|
-
kfn, vfn = map(isinstance_of, rfl.args)
|
|
468
|
-
return lambda o: isinstance(o, rfl.cls) and all(kfn(k) and vfn(v) for k, v in o.items()) # type: ignore
|
|
469
|
-
|
|
470
|
-
raise TypeError(rfl)
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: omlish
|
|
3
|
-
Version: 0.0.0.dev6
|
|
4
|
-
Summary: omlish
|
|
5
|
-
Author: wrmsr
|
|
6
|
-
License: BSD-3-Clause
|
|
7
|
-
Project-URL: source, https://github.com/wrmsr/omlish
|
|
8
|
-
Classifier: License :: OSI Approved :: BSD License
|
|
9
|
-
Classifier: Development Status :: 2 - Pre-Alpha
|
|
10
|
-
Classifier: Intended Audience :: Developers
|
|
11
|
-
Classifier: Operating System :: OS Independent
|
|
12
|
-
Requires-Python: >=3.12
|
|
13
|
-
License-File: LICENSE
|
|
14
|
-
Provides-Extra: async
|
|
15
|
-
Requires-Dist: anyio ; extra == 'async'
|
|
16
|
-
Provides-Extra: http
|
|
17
|
-
Requires-Dist: httpx ; extra == 'http'
|
|
18
|
-
Provides-Extra: server
|
|
19
|
-
Requires-Dist: h11 ; extra == 'server'
|
|
20
|
-
Requires-Dist: h2 ; extra == 'server'
|
|
21
|
-
Requires-Dist: priority ; extra == 'server'
|
|
22
|
-
Requires-Dist: wsproto ; extra == 'server'
|
|
23
|
-
Provides-Extra: sql
|
|
24
|
-
Requires-Dist: sqlalchemy ; extra == 'sql'
|
|
25
|
-
Provides-Extra: test
|
|
26
|
-
Requires-Dist: pytest ; extra == 'test'
|
|
27
|
-
Provides-Extra: trio
|
|
28
|
-
Requires-Dist: trio ; extra == 'trio'
|
|
29
|
-
Requires-Dist: trio-asyncio ; extra == 'trio'
|
|
30
|
-
Provides-Extra: wrapt
|
|
31
|
-
Requires-Dist: wrapt ; extra == 'wrapt'
|
|
32
|
-
Provides-Extra: yaml
|
|
33
|
-
Requires-Dist: pyyaml ; extra == 'yaml'
|
|
34
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|