omlish 0.0.0.dev336__py3-none-any.whl → 0.0.0.dev338__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 CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev336'
2
- __revision__ = '16b945e9466bbc3af4270b99369d4041260ac765'
1
+ __version__ = '0.0.0.dev338'
2
+ __revision__ = '8d983648c5770796c8addb2cf217a0d7235a9b29'
3
3
 
4
4
 
5
5
  #
@@ -0,0 +1,33 @@
1
+ import collections.abc
2
+
3
+ from ... import check
4
+ from ... import lang
5
+ from ... import reflect as rfl
6
+ from ...funcs import match as mfs
7
+ from ..base import MarshalContext
8
+ from ..base import Marshaler
9
+ from ..base import MarshalerFactoryMatchClass
10
+ from ..base import UnmarshalContext
11
+ from ..base import Unmarshaler
12
+ from ..base import UnmarshalerFactoryMatchClass
13
+ from .iterables import DEFAULT_ITERABLE_CONCRETE_TYPES
14
+ from .iterables import IterableMarshaler
15
+ from .iterables import IterableUnmarshaler
16
+
17
+
18
+ ##
19
+
20
+
21
+ class SequenceNotStrMarshalerFactory(MarshalerFactoryMatchClass):
22
+ @mfs.simple(lambda _, ctx, rty: isinstance(rty, rfl.Protocol) and rty.cls is lang.SequenceNotStr)
23
+ def _build_generic(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
24
+ gty = check.isinstance(rty, rfl.Protocol)
25
+ return IterableMarshaler(ctx.make(check.single(gty.args)))
26
+
27
+
28
+ class SequenceNotStrUnmarshalerFactory(UnmarshalerFactoryMatchClass):
29
+ @mfs.simple(lambda _, ctx, rty: isinstance(rty, rfl.Protocol) and rty.cls is lang.SequenceNotStr)
30
+ def _build_generic(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
31
+ gty = check.isinstance(rty, rfl.Protocol)
32
+ cty = DEFAULT_ITERABLE_CONCRETE_TYPES[collections.abc.Sequence] # type: ignore[type-abstract]
33
+ return IterableUnmarshaler(cty, ctx.make(check.single(gty.args)))
@@ -18,6 +18,8 @@ from .composite.newtypes import NewtypeMarshalerFactory
18
18
  from .composite.newtypes import NewtypeUnmarshalerFactory
19
19
  from .composite.optionals import OptionalMarshalerFactory
20
20
  from .composite.optionals import OptionalUnmarshalerFactory
21
+ from .composite.special import SequenceNotStrMarshalerFactory
22
+ from .composite.special import SequenceNotStrUnmarshalerFactory
21
23
  from .objects.dataclasses import DataclassMarshalerFactory
22
24
  from .objects.dataclasses import DataclassUnmarshalerFactory
23
25
  from .objects.namedtuples import NamedtupleMarshalerFactory
@@ -58,6 +60,7 @@ STANDARD_MARSHALER_FACTORIES: list[MarshalerFactory] = [
58
60
  DATETIME_MARSHALER_FACTORY,
59
61
  MaybeMarshalerFactory(),
60
62
  MappingMarshalerFactory(),
63
+ SequenceNotStrMarshalerFactory(),
61
64
  IterableMarshalerFactory(),
62
65
  ANY_MARSHALER_FACTORY,
63
66
  ]
@@ -91,6 +94,7 @@ STANDARD_UNMARSHALER_FACTORIES: list[UnmarshalerFactory] = [
91
94
  DATETIME_UNMARSHALER_FACTORY,
92
95
  MaybeUnmarshalerFactory(),
93
96
  MappingUnmarshalerFactory(),
97
+ SequenceNotStrUnmarshalerFactory(),
94
98
  IterableUnmarshalerFactory(),
95
99
  ANY_UNMARSHALER_FACTORY,
96
100
  ]
@@ -28,8 +28,10 @@ from .types import ( # noqa
28
28
  Any,
29
29
  DEFAULT_REFLECTOR,
30
30
  Generic,
31
+ GenericLike,
31
32
  Literal,
32
33
  NewType,
34
+ Protocol,
33
35
  ReflectTypeError,
34
36
  Reflector,
35
37
  TYPES,
omlish/reflect/ops.py CHANGED
@@ -1,9 +1,12 @@
1
+ import dataclasses as dc
1
2
  import typing as ta
2
3
 
3
4
  from .types import Annotated
4
5
  from .types import Any
5
6
  from .types import Generic
7
+ from .types import GenericLike
6
8
  from .types import NewType
9
+ from .types import Protocol
7
10
  from .types import Type
8
11
  from .types import Union
9
12
  from .types import get_type_var_bound
@@ -15,13 +18,13 @@ def strip_objs(ty: Type) -> Type:
15
18
  return ty
16
19
 
17
20
  if isinstance(ty, Union):
18
- return Union(frozenset(map(strip_objs, ty.args)))
21
+ return dc.replace(ty, args=frozenset(map(strip_objs, ty.args)))
19
22
 
20
- if isinstance(ty, Generic):
21
- return Generic(ty.cls, tuple(map(strip_objs, ty.args)), ty.params, None)
23
+ if isinstance(ty, GenericLike):
24
+ return dc.replace(ty, args=tuple(map(strip_objs, ty.args)), obj=None)
22
25
 
23
26
  if isinstance(ty, Annotated):
24
- return Annotated(strip_objs(ty.ty), ty.md, None)
27
+ return dc.replace(ty, ty=strip_objs(ty.ty), obj=None)
25
28
 
26
29
  raise TypeError(ty)
27
30
 
@@ -31,10 +34,10 @@ def strip_annotations(ty: Type) -> Type:
31
34
  return ty
32
35
 
33
36
  if isinstance(ty, Union):
34
- return Union(frozenset(map(strip_annotations, ty.args)))
37
+ return dc.replace(ty, args=frozenset(map(strip_annotations, ty.args)))
35
38
 
36
- if isinstance(ty, Generic):
37
- return Generic(ty.cls, tuple(map(strip_annotations, ty.args)), ty.params, ty.obj)
39
+ if isinstance(ty, GenericLike):
40
+ return dc.replace(ty, args=tuple(map(strip_annotations, ty.args)))
38
41
 
39
42
  if isinstance(ty, Annotated):
40
43
  return strip_annotations(ty.ty)
@@ -74,7 +77,7 @@ def get_concrete_type(
74
77
 
75
78
  return None
76
79
 
77
- if isinstance(cur, (Union, Any)):
80
+ if isinstance(cur, (Union, Any, Protocol)):
78
81
  return None
79
82
 
80
83
  raise TypeError(cur)
@@ -89,6 +92,9 @@ def to_annotation(ty: Type) -> ta.Any:
89
92
  if isinstance(ty, Union):
90
93
  return ta.Union[*tuple(to_annotation(e) for e in ty.args)]
91
94
 
95
+ if isinstance(ty, Protocol):
96
+ return ta.Protocol[*ty.params]
97
+
92
98
  if isinstance(ty, (type, ta.TypeVar, NewType)):
93
99
  return ty
94
100
 
omlish/reflect/types.py CHANGED
@@ -3,6 +3,7 @@ TODO:
3
3
  - visitor / transformer
4
4
  - uniform collection isinstance - items() for mappings, iter() for other
5
5
  - also check instance type in isinstance not just items lol
6
+ TODO:
6
7
  - ta.Generic in mro causing trouble - omit? no longer 1:1
7
8
  - cache this shit, esp generic_mro shit
8
9
  - cache __hash__ in Generic/Union
@@ -22,6 +23,7 @@ _AnnotatedAlias = ta._AnnotatedAlias # type: ignore # noqa
22
23
  _CallableGenericAlias = ta._CallableGenericAlias # type: ignore # noqa
23
24
  _GenericAlias = ta._GenericAlias # type: ignore # noqa
24
25
  _LiteralGenericAlias = ta._LiteralGenericAlias # type: ignore # noqa
26
+ _ProtocolMeta = ta._ProtocolMeta # noqa
25
27
  _SpecialGenericAlias = ta._SpecialGenericAlias # type: ignore # noqa
26
28
  _UnionGenericAlias = ta._UnionGenericAlias # type: ignore # noqa
27
29
 
@@ -29,6 +31,16 @@ _UnionGenericAlias = ta._UnionGenericAlias # type: ignore # noqa
29
31
  ##
30
32
 
31
33
 
34
+ _Protocol = getattr(ta, 'Protocol')
35
+ _Generic = getattr(ta, 'Generic')
36
+
37
+ if not isinstance(_Protocol, type) or not issubclass(_Protocol, _Generic):
38
+ raise TypeError(f'typing.Protocol is not a proper typing.Generic subtype')
39
+
40
+
41
+ ##
42
+
43
+
32
44
  @dc.dataclass(frozen=True)
33
45
  class _Special:
34
46
  name: str
@@ -95,6 +107,10 @@ def get_params(obj: ta.Any) -> tuple[ta.TypeVar, ...]:
95
107
  raise TypeError(obj)
96
108
 
97
109
 
110
+ def _is_immediate_protocol(obj: ta.Any) -> bool:
111
+ return isinstance(obj, _ProtocolMeta) and obj.__dict__['_is_protocol']
112
+
113
+
98
114
  def is_union_type(cls: ta.Any) -> bool:
99
115
  if hasattr(ta, 'UnionType'):
100
116
  return ta.get_origin(cls) in {ta.Union, getattr(ta, 'UnionType')}
@@ -163,22 +179,30 @@ class Union(TypeInfo):
163
179
  #
164
180
 
165
181
 
182
+ GenericLikeCls = ta.TypeVar('GenericLikeCls')
183
+
184
+
166
185
  @dc.dataclass(frozen=True)
167
- class Generic(TypeInfo):
168
- cls: type
169
- args: tuple[Type, ...] # map[int, V] = (int, V) | map[T, T] = (T, T)
186
+ class GenericLike(TypeInfo, abc.ABC, ta.Generic[GenericLikeCls]):
187
+ cls: GenericLikeCls
170
188
 
171
- params: tuple[ta.TypeVar, ...] = dc.field(compare=False, repr=False) # map[int, V] = (_0, _1) | map[T, T] = (_0, _1) # noqa
172
- # params2: tuple[ta.TypeVar, ...] # map[int, V] = (V,) | map[T, T] = (T,)
189
+ # args and params are the same length - params maps to the generic origin's params:
190
+ # args : map[int, V] = (int, V) | map[T, T] = (T, T)
191
+ # params : map[int, V] = (_0, _1) | map[T, T] = (_0, _1)
192
+ args: tuple[Type, ...]
193
+ params: tuple[ta.TypeVar, ...] = dc.field(compare=False, repr=False)
173
194
 
174
195
  obj: ta.Any = dc.field(compare=False, repr=False)
175
196
 
176
- # def __post_init__(self) -> None:
177
- # if not isinstance(self.cls, type):
178
- # raise TypeError(self.cls)
197
+ def __post_init__(self) -> None:
198
+ if not isinstance(self.cls, type):
199
+ raise ReflectTypeError(f'GenericLike {self.cls=} must be a type')
200
+ if len(self.args) != len(self.params):
201
+ raise ReflectTypeError(f'GenericLike {self.args=} must be same length as {self.params=}')
179
202
 
180
- def full_eq(self, other: 'Generic') -> bool:
203
+ def full_eq(self, other: 'GenericLike') -> bool:
181
204
  return (
205
+ type(self) is type(other) and
182
206
  self.cls == other.cls and
183
207
  self.args == other.args and
184
208
  self.params == other.params and
@@ -186,6 +210,18 @@ class Generic(TypeInfo):
186
210
  )
187
211
 
188
212
 
213
+ @dc.dataclass(frozen=True)
214
+ class Generic(GenericLike[type]):
215
+ pass
216
+
217
+
218
+ @dc.dataclass(frozen=True)
219
+ class Protocol(GenericLike[ta.Any]):
220
+ # cls will still be a type - it will be the topmost _is_protocol=True class.
221
+ # it may however be ta.Protocol, which *is* a type, but not according to mypy.
222
+ pass
223
+
224
+
189
225
  #
190
226
 
191
227
 
@@ -311,9 +347,13 @@ class Reflector:
311
347
  return None
312
348
 
313
349
  origin = ta.get_origin(obj)
350
+
314
351
  args = ta.get_args(obj)
315
352
 
316
- if oty is _CallableGenericAlias:
353
+ if origin is ta.Protocol:
354
+ params = get_params(obj)
355
+
356
+ elif oty is _CallableGenericAlias:
317
357
  p, r = args
318
358
  if p is Ellipsis or isinstance(p, ta.ParamSpec):
319
359
  raise ReflectTypeError(f'Callable argument not yet supported for {obj=}')
@@ -332,6 +372,27 @@ class Reflector:
332
372
  if len(args) != len(params):
333
373
  raise ReflectTypeError(f'Mismatched {args=} and {params=} for {obj=}')
334
374
 
375
+ if not isinstance(origin, type):
376
+ raise ReflectTypeError(f'Generic origin {origin!r} is not a type')
377
+
378
+ if origin is ta.Protocol:
379
+ if args != params:
380
+ raise ReflectTypeError(f'Protocol argument not yet supported for {args=}, {params=}')
381
+ return Protocol(
382
+ ta.Protocol,
383
+ args,
384
+ params,
385
+ obj,
386
+ )
387
+
388
+ if _is_immediate_protocol(origin):
389
+ return Protocol(
390
+ origin,
391
+ args,
392
+ params,
393
+ obj,
394
+ )
395
+
335
396
  return Generic(
336
397
  origin,
337
398
  tuple(self.type(a) for a in args),
@@ -346,6 +407,15 @@ class Reflector:
346
407
  if check_only:
347
408
  return None
348
409
 
410
+ if _is_immediate_protocol(obj):
411
+ params = get_params(obj)
412
+ return Protocol(
413
+ obj,
414
+ params,
415
+ params,
416
+ obj,
417
+ )
418
+
349
419
  if issubclass(obj, ta.Generic): # type: ignore
350
420
  params = get_params(obj)
351
421
  if params:
@@ -0,0 +1 @@
1
+ from .plugin import SwitchesPlugin # noqa
@@ -5,15 +5,17 @@ TODO:
5
5
  - dynamic switching (skip docker if not running, skip online if not online, ...)
6
6
  """
7
7
  import dataclasses as dc
8
- import enum
9
8
  import typing as ta
10
9
 
11
10
  import pytest
12
11
 
13
- from .... import check
14
- from .... import collections as col
15
- from ....docker import all as docker
16
- from ._registry import register
12
+ from ..... import check
13
+ from ..... import collections as col
14
+ from .._registry import register
15
+ from .switches import SWITCHES
16
+ from .switches import SWITCHES_BY_NAME
17
+ from .switches import Switch
18
+ from .switches import SwitchState
17
19
 
18
20
 
19
21
  Configable: ta.TypeAlias = pytest.FixtureRequest | pytest.Config
@@ -22,80 +24,6 @@ Configable: ta.TypeAlias = pytest.FixtureRequest | pytest.Config
22
24
  ##
23
25
 
24
26
 
25
- class SwitchState(enum.Enum):
26
- ENABLED = enum.auto()
27
- DISABLED = enum.auto()
28
- ONLY = enum.auto()
29
- IF_SINGLE = enum.auto()
30
-
31
-
32
- @dc.dataclass(frozen=True, eq=False)
33
- class Switch:
34
- name: str
35
- _default_state: SwitchState | ta.Callable[[pytest.Session], SwitchState]
36
-
37
- _: dc.KW_ONLY
38
-
39
- add_marks: ta.Sequence[ta.Any] | None = None
40
-
41
- def default_state(self, session: pytest.Session) -> SwitchState:
42
- if isinstance(e := self._default_state, SwitchState):
43
- return e
44
- elif callable(e):
45
- return check.isinstance(e(session), SwitchState)
46
- else:
47
- raise TypeError(e)
48
-
49
- @property
50
- def attr(self) -> str:
51
- return self.name.replace('-', '_')
52
-
53
-
54
- SWITCHES: ta.Sequence[Switch] = [
55
- Switch(
56
- 'name',
57
- lambda _: SwitchState.ENABLED if docker.has_cli() else SwitchState.DISABLED,
58
- ),
59
-
60
- Switch(
61
- 'docker-guest',
62
- lambda _: SwitchState.ENABLED if docker.is_likely_in_docker() else SwitchState.DISABLED,
63
- ),
64
-
65
- Switch(
66
- 'online',
67
- SwitchState.ENABLED,
68
- ),
69
-
70
- Switch(
71
- 'integration',
72
- SwitchState.ENABLED,
73
- ),
74
-
75
- Switch(
76
- 'high-mem',
77
- SwitchState.ENABLED,
78
- add_marks=[
79
- # https://pytest-xdist.readthedocs.io/en/latest/distribution.html
80
- pytest.mark.xdist_group('high-mem'),
81
- pytest.mark.gc_collect_after(),
82
- ],
83
- ),
84
-
85
- Switch(
86
- 'slow',
87
- SwitchState.IF_SINGLE,
88
- ),
89
- ]
90
-
91
-
92
- SWITCHES_BY_NAME: ta.Mapping[str, Switch] = col.make_map_by(lambda sw: sw.name, SWITCHES, strict=True)
93
- SWITCHES_BY_ATTR: ta.Mapping[str, Switch] = col.make_map_by(lambda sw: sw.attr, SWITCHES, strict=True)
94
-
95
-
96
- ##
97
-
98
-
99
27
  SWITCH_STATE_OPT_PREFIXES: ta.Mapping[SwitchState, str] = {
100
28
  SwitchState.ENABLED: '--',
101
29
  SwitchState.DISABLED: '--no-',
@@ -0,0 +1,89 @@
1
+ import dataclasses as dc
2
+ import enum
3
+ import typing as ta
4
+
5
+ import pytest
6
+
7
+ from ..... import check
8
+ from ..... import collections as col
9
+ from .....docker import all as docker
10
+
11
+
12
+ ##
13
+
14
+
15
+ class SwitchState(enum.Enum):
16
+ ENABLED = enum.auto()
17
+ DISABLED = enum.auto()
18
+ ONLY = enum.auto()
19
+ IF_SINGLE = enum.auto()
20
+
21
+
22
+ @dc.dataclass(frozen=True, eq=False)
23
+ class Switch:
24
+ name: str
25
+ _default_state: SwitchState | ta.Callable[[pytest.Session], SwitchState]
26
+
27
+ _: dc.KW_ONLY
28
+
29
+ add_marks: ta.Sequence[ta.Any] | None = None
30
+
31
+ def default_state(self, session: pytest.Session) -> SwitchState:
32
+ if isinstance(e := self._default_state, SwitchState):
33
+ return e
34
+ elif callable(e):
35
+ return check.isinstance(e(session), SwitchState)
36
+ else:
37
+ raise TypeError(e)
38
+
39
+ @property
40
+ def attr(self) -> str:
41
+ return self.name.replace('-', '_')
42
+
43
+
44
+ ##
45
+
46
+
47
+ SWITCHES: ta.Sequence[Switch] = [
48
+ Switch(
49
+ 'name',
50
+ lambda _: SwitchState.ENABLED if docker.has_cli() else SwitchState.DISABLED,
51
+ ),
52
+
53
+ Switch(
54
+ 'docker-guest',
55
+ lambda _: SwitchState.ENABLED if docker.is_likely_in_docker() else SwitchState.DISABLED,
56
+ ),
57
+
58
+ Switch(
59
+ 'online',
60
+ SwitchState.ENABLED,
61
+ ),
62
+
63
+ Switch(
64
+ 'integration',
65
+ SwitchState.ENABLED,
66
+ ),
67
+
68
+ Switch(
69
+ 'high-mem',
70
+ SwitchState.ENABLED,
71
+ add_marks=[
72
+ # https://pytest-xdist.readthedocs.io/en/latest/distribution.html
73
+ pytest.mark.xdist_group('high-mem'),
74
+ pytest.mark.gc_collect_after(),
75
+ ],
76
+ ),
77
+
78
+ Switch(
79
+ 'slow',
80
+ SwitchState.IF_SINGLE,
81
+ ),
82
+ ]
83
+
84
+
85
+ ##
86
+
87
+
88
+ SWITCHES_BY_NAME: ta.Mapping[str, Switch] = col.make_map_by(lambda sw: sw.name, SWITCHES, strict=True)
89
+ SWITCHES_BY_ATTR: ta.Mapping[str, Switch] = col.make_map_by(lambda sw: sw.attr, SWITCHES, strict=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omlish
3
- Version: 0.0.0.dev336
3
+ Version: 0.0.0.dev338
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=orgsRvtpHu8tdhaCvlP9v3P495OJopYYiHKjK68WtWg,8587
2
- omlish/__about__.py,sha256=qfDmcKP6gZ8mkTC4jhOQsbycwdsxLHwhrOxUjvDl13M,3478
2
+ omlish/__about__.py,sha256=p63JDbIzq9Uyt4DamGvFNixWASVUZ_s5JryuZGRCE5I,3478
3
3
  omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
4
4
  omlish/c3.py,sha256=rer-TPOFDU6fYq_AWio_AmA-ckZ8JDY5shIzQ_yXfzA,8414
5
5
  omlish/cached.py,sha256=MLap_p0rdGoDIMVhXVHm1tsbcWobJF0OanoodV03Ju8,542
@@ -496,7 +496,7 @@ omlish/marshal/global_.py,sha256=nTJmC17O8SJNURScIdYqEY72h-dRy6D-SaDSUQCp-cY,152
496
496
  omlish/marshal/naming.py,sha256=7jQ204u_Kpc3-OGr-ctUHSv997DdWYRLh643qLHJhks,852
497
497
  omlish/marshal/proxy.py,sha256=puKJpwPpuDlMOIrKMcLTRLJyMiL6n_Xs-p59AuDEymA,543
498
498
  omlish/marshal/registries.py,sha256=FvC6qXHCizNB2QmU_N3orxW7iqfGYkiUXYYdTRWS6HA,2353
499
- omlish/marshal/standard.py,sha256=TADR75Hd9VSUpuN_Tnu74Bzmvby42P2bzwFwUBC0l-Q,4283
499
+ omlish/marshal/standard.py,sha256=C1AawI1IrSb_mH6xBhZWHnqdjviVpk5-Cm9g-9aY02A,4487
500
500
  omlish/marshal/values.py,sha256=ssHiWdg_L6M17kAn8GiGdPW7UeQOm3RDikWkvwblf5I,263
501
501
  omlish/marshal/composite/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
502
502
  omlish/marshal/composite/iterables.py,sha256=YdkdWNUe_AzdUqiAsr7z3kaDcPeg7Znj3AuQepY_qaA,2647
@@ -505,6 +505,7 @@ omlish/marshal/composite/mappings.py,sha256=HoqUKe4kyCYRdMpQMWW0DLPi0-DEsxt-nk4p
505
505
  omlish/marshal/composite/maybes.py,sha256=NfQ2cIHHIvohTl4iYPYbEvhNVq3L3JCu2GEbt4DM5DA,2216
506
506
  omlish/marshal/composite/newtypes.py,sha256=5-te247TiPYf84oFhf59tqIOOByXj8i9KaHT8gn72fU,878
507
507
  omlish/marshal/composite/optionals.py,sha256=MnecrmrJYjQvYJipIHNCDq78oH09dOjnw5pvaMKqoeU,1537
508
+ omlish/marshal/composite/special.py,sha256=s0PcOmDiQyCjoxcdaGSORTqNoXNp6uuBz_NJs2kHzRM,1350
508
509
  omlish/marshal/composite/wrapped.py,sha256=jOsn3h1vLIqcoSTB-0KObnsdbV8jSVWJYbf7Kg9AUwg,750
509
510
  omlish/marshal/objects/__init__.py,sha256=F4wej8L_tedC8ETYxAnmKfdPR9TjsqIus9Z3nZofYuc,182
510
511
  omlish/marshal/objects/dataclasses.py,sha256=klXXY1zOKh_FYlw6L5ZNPjpXSk0ntUGxSOrm309WoiY,8953
@@ -563,11 +564,11 @@ omlish/os/pidfiles/cli.py,sha256=2SSsP4O3VdpsDIMAkWgWSjh_YNIPzCD9l5LNN2qrIjo,207
563
564
  omlish/os/pidfiles/manager.py,sha256=QphQxIENVVwvBWynLCNU31NwOfLkV43VoTVeYFn2Hac,2351
564
565
  omlish/os/pidfiles/pidfile.py,sha256=9tI5IMVwfPfnni0XMn4x5ptNQgm36n8tLeUNPf50UqU,4394
565
566
  omlish/os/pidfiles/pinning.py,sha256=aQgCmvcAqN0lvI70GcSB2TKVX1G4vwbyN_AOHF3-eKE,6630
566
- omlish/reflect/__init__.py,sha256=64eHbD6zL6Fhp7FfXb8n9ZHywlODjBN3rm1LMvZ081A,822
567
+ omlish/reflect/__init__.py,sha256=9pzXLXXNMHkLhhI79iUr-o0SMOtR6HMUmAEUplZkIdE,853
567
568
  omlish/reflect/inspect.py,sha256=WCo2YpBYauKw6k758FLlZ_H4Q05rgVPs96fEv9w6zHQ,1538
568
- omlish/reflect/ops.py,sha256=9F369zrp6dNJUiGLLrYhb2O-Zss0BhTcpo3dzdLCq-I,2424
569
+ omlish/reflect/ops.py,sha256=RxUc9sFZxYP_f5y-jU2DujFLkzhzx8DsyITShPSpW3U,2614
569
570
  omlish/reflect/subst.py,sha256=jpBgYR1_JyH9fz5b-gmOg7OhFKk7jIxEh7hwtKYKC9Q,3691
570
- omlish/reflect/types.py,sha256=Cn9FYGoiCNt0FS0YLiTTAR12WKcesWMapCrVYcb8IDo,9225
571
+ omlish/reflect/types.py,sha256=C3NsAQFam_9mXhvSUa0H0RnJxhVAzIbY1Z_WHXHcNcs,11213
571
572
  omlish/secrets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
572
573
  omlish/secrets/all.py,sha256=gv_d9SfyMxso30HsrSz9XmIrSZOdl3rLA5MSH0ZXfgM,486
573
574
  omlish/secrets/crypto.py,sha256=9D21lnvPhStwu8arD4ssT0ih0bDG-nlqIRdVgYL40xA,3708
@@ -754,7 +755,6 @@ omlish/testing/pytest/plugins/pydevd.py,sha256=5moE64LrNRV6gKRaeCuONDiwuh-4UFxJP
754
755
  omlish/testing/pytest/plugins/repeat.py,sha256=jiZCI-17042jBvUEbZCxNwqWtr7s3EhTBSeSHh_Uz4E,497
755
756
  omlish/testing/pytest/plugins/skips.py,sha256=eMir_n777Kk2BvOwjQzRROKL4iAMYKSHFwWCHJ-bdPI,1040
756
757
  omlish/testing/pytest/plugins/spacing.py,sha256=tzq-L-exegHe2BImumkYIsVcUwpUUhLJJOuSrsKDuCU,706
757
- omlish/testing/pytest/plugins/switches.py,sha256=z3TKe2NHBOaa_cmarWTRJo519iCNDff4e0XSfHkajHU,7365
758
758
  omlish/testing/pytest/plugins/utils.py,sha256=L5C622UXcA_AUKDcvyh5IMiRfqSGGz0McdhwZWvfMlU,261
759
759
  omlish/testing/pytest/plugins/asyncs/__init__.py,sha256=TTNhFmP_krug1973sq_bpWBTIvg68-1nbuVLSs92Z6k,41
760
760
  omlish/testing/pytest/plugins/asyncs/consts.py,sha256=0NOCkzV43dOu3u97BqYMQ4mPG8JuFncpWibkOZpCqX4,55
@@ -766,6 +766,9 @@ omlish/testing/pytest/plugins/asyncs/backends/asyncio.py,sha256=0b8pmbXNW2qI8qo1
766
766
  omlish/testing/pytest/plugins/asyncs/backends/base.py,sha256=fTZ6R_iKpAp-8DVw8js8rxC_VNqj6onFD4KKBWnmtXk,587
767
767
  omlish/testing/pytest/plugins/asyncs/backends/trio.py,sha256=xty9TR7-Kk6n0cdOqErLilPLLCchJe6zmEyhpypTmKM,3330
768
768
  omlish/testing/pytest/plugins/asyncs/backends/trio_asyncio.py,sha256=VcGVwf4V-1ZFK_70FrFS9b11EU1dOy1ozhhIDXGNSEo,3169
769
+ omlish/testing/pytest/plugins/switches/__init__.py,sha256=KTdm9xe8AYQvNT-IKSGr9O8q_hgRGEqhK3zcto0EbWk,43
770
+ omlish/testing/pytest/plugins/switches/plugin.py,sha256=kHHXpawEgyDMzvcLgfdYBUhcCML2xAo9sdJ6611sm-M,5744
771
+ omlish/testing/pytest/plugins/switches/switches.py,sha256=lj8S9RMwUAW7a93ZqqTjoD4dRVkeGts2sl8Cn-H17hc,1890
769
772
  omlish/text/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
770
773
  omlish/text/asdl.py,sha256=AS3irh-sag5pqyH3beJif78PjCbOaFso1NeKq-HXuTs,16867
771
774
  omlish/text/decoding.py,sha256=sQWGckWzRslRHYKpj1SBeoo6AVqXm5HFlWFRARN1QpM,1286
@@ -858,9 +861,9 @@ omlish/typedvalues/holder.py,sha256=vu-umn-h1nvUqmtV5T9ZfQ_OoOYsERu8PhI2N48Ryns,
858
861
  omlish/typedvalues/marshal.py,sha256=AtBz7Jq-BfW8vwM7HSxSpR85JAXmxK2T0xDblmm1HI0,4956
859
862
  omlish/typedvalues/reflect.py,sha256=PAvKW6T4cW7u--iX80w3HWwZUS3SmIZ2_lQjT65uAyk,1026
860
863
  omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
861
- omlish-0.0.0.dev336.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
862
- omlish-0.0.0.dev336.dist-info/METADATA,sha256=8A6pfMbK7CNFcf8IjZ_MAjSo9qLfSC_Z5s3IuPlUkb4,4416
863
- omlish-0.0.0.dev336.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
864
- omlish-0.0.0.dev336.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
865
- omlish-0.0.0.dev336.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
866
- omlish-0.0.0.dev336.dist-info/RECORD,,
864
+ omlish-0.0.0.dev338.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
865
+ omlish-0.0.0.dev338.dist-info/METADATA,sha256=ZPnPJxCXqfpdEK-ad8rFWYgxjkUBGLj97TEUYcPQ6dc,4416
866
+ omlish-0.0.0.dev338.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
867
+ omlish-0.0.0.dev338.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
868
+ omlish-0.0.0.dev338.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
869
+ omlish-0.0.0.dev338.dist-info/RECORD,,