omlish 0.0.0.dev454__py3-none-any.whl → 0.0.0.dev456__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 +2 -2
- omlish/lang/__init__.py +7 -1
- omlish/lang/functions.py +2 -2
- omlish/lang/iterables.py +0 -8
- omlish/lang/sequences.py +124 -0
- omlish/marshal/__init__.py +6 -0
- omlish/marshal/base/configs.py +12 -0
- omlish/marshal/base/contexts.py +32 -16
- omlish/marshal/base/funcs.py +4 -12
- omlish/marshal/base/options.py +8 -0
- omlish/marshal/base/registries.py +32 -4
- omlish/marshal/base/types.py +27 -13
- omlish/marshal/composite/iterables.py +10 -8
- omlish/marshal/composite/literals.py +6 -4
- omlish/marshal/composite/mappings.py +10 -8
- omlish/marshal/composite/maybes.py +10 -8
- omlish/marshal/composite/newtypes.py +6 -6
- omlish/marshal/composite/optionals.py +6 -4
- omlish/marshal/composite/special.py +6 -6
- omlish/marshal/composite/unions/literals.py +6 -4
- omlish/marshal/composite/unions/primitives.py +6 -4
- omlish/marshal/factories/invalidate.py +4 -4
- omlish/marshal/factories/method.py +4 -6
- omlish/marshal/factories/moduleimport/factories.py +6 -6
- omlish/marshal/factories/multi.py +4 -4
- omlish/marshal/factories/recursive.py +4 -2
- omlish/marshal/factories/typecache.py +4 -9
- omlish/marshal/factories/typemap.py +4 -4
- omlish/marshal/objects/dataclasses.py +30 -16
- omlish/marshal/objects/marshal.py +4 -3
- omlish/marshal/objects/namedtuples.py +6 -6
- omlish/marshal/objects/unmarshal.py +4 -3
- omlish/marshal/polymorphism/marshal.py +4 -3
- omlish/marshal/polymorphism/unions.py +7 -7
- omlish/marshal/polymorphism/unmarshal.py +4 -3
- omlish/marshal/singular/enums.py +4 -2
- omlish/marshal/trivial/any.py +1 -1
- omlish/marshal/trivial/forbidden.py +4 -4
- omlish/specs/jsonrpc/_marshal.py +4 -4
- omlish/specs/openapi/_marshal.py +16 -10
- omlish/typedvalues/marshal.py +14 -14
- {omlish-0.0.0.dev454.dist-info → omlish-0.0.0.dev456.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev454.dist-info → omlish-0.0.0.dev456.dist-info}/RECORD +47 -47
- omlish/funcs/match.py +0 -229
- {omlish-0.0.0.dev454.dist-info → omlish-0.0.0.dev456.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev454.dist-info → omlish-0.0.0.dev456.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev454.dist-info → omlish-0.0.0.dev456.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev454.dist-info → omlish-0.0.0.dev456.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
omlish/lang/__init__.py
CHANGED
@@ -334,7 +334,6 @@ with _auto_proxy_init(globals(), update_exports=True):
|
|
334
334
|
ilen,
|
335
335
|
take,
|
336
336
|
consume,
|
337
|
-
iterfrom,
|
338
337
|
peek,
|
339
338
|
chunk,
|
340
339
|
interleave,
|
@@ -454,6 +453,13 @@ with _auto_proxy_init(globals(), update_exports=True):
|
|
454
453
|
get_relative_resources,
|
455
454
|
)
|
456
455
|
|
456
|
+
from .sequences import ( # noqa
|
457
|
+
iterslice,
|
458
|
+
iterrange,
|
459
|
+
|
460
|
+
SeqView,
|
461
|
+
)
|
462
|
+
|
457
463
|
from .strings import ( # noqa
|
458
464
|
prefix_delimited,
|
459
465
|
prefix_lines,
|
omlish/lang/functions.py
CHANGED
@@ -59,11 +59,11 @@ def recurse(fn: ta.Callable[..., T], *args, **kwargs) -> T:
|
|
59
59
|
##
|
60
60
|
|
61
61
|
|
62
|
-
def raise_(o: BaseException) -> ta.NoReturn:
|
62
|
+
def raise_(o: BaseException | type[BaseException]) -> ta.NoReturn:
|
63
63
|
raise o
|
64
64
|
|
65
65
|
|
66
|
-
def raising(o: BaseException) -> ta.Callable[..., ta.NoReturn]:
|
66
|
+
def raising(o: BaseException | type[BaseException]) -> ta.Callable[..., ta.NoReturn]:
|
67
67
|
def inner(*args, **kwargs):
|
68
68
|
raise o
|
69
69
|
|
omlish/lang/iterables.py
CHANGED
@@ -26,14 +26,6 @@ def consume(it: ta.Iterable[ta.Any]) -> None:
|
|
26
26
|
collections.deque(it, maxlen=0)
|
27
27
|
|
28
28
|
|
29
|
-
def iterfrom(seq: ta.Sequence[T], start: int = 0, stop: int | None = None) -> ta.Iterator[T]:
|
30
|
-
if start < 0:
|
31
|
-
start += len(seq)
|
32
|
-
if stop is None:
|
33
|
-
stop = len(seq)
|
34
|
-
return map(seq.__getitem__, range(start, stop))
|
35
|
-
|
36
|
-
|
37
29
|
def peek(vs: ta.Iterable[T]) -> tuple[T, ta.Iterator[T]]:
|
38
30
|
it = iter(vs)
|
39
31
|
v = next(it)
|
omlish/lang/sequences.py
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
"""
|
2
|
+
TODO:
|
3
|
+
- StrView, BytesView - in lieu of hkt lol
|
4
|
+
- cext? even necessary?
|
5
|
+
- __eq__, cmp, __hash__
|
6
|
+
- __buffer__
|
7
|
+
- optimize `slice(None)`, keep as SeqView but fast path ops
|
8
|
+
- shorter repr if __len__ > some threshold
|
9
|
+
- use materialize()?
|
10
|
+
"""
|
11
|
+
import typing as ta
|
12
|
+
|
13
|
+
|
14
|
+
T = ta.TypeVar('T')
|
15
|
+
|
16
|
+
|
17
|
+
##
|
18
|
+
|
19
|
+
|
20
|
+
def iterslice(
|
21
|
+
seq: ta.Sequence[T],
|
22
|
+
slc: slice,
|
23
|
+
) -> ta.Iterator[T]:
|
24
|
+
return map(seq.__getitem__, range(*slc.indices(len(seq))))
|
25
|
+
|
26
|
+
|
27
|
+
def iterrange(
|
28
|
+
seq: ta.Sequence[T],
|
29
|
+
start: int | None = None,
|
30
|
+
stop: int | None = None,
|
31
|
+
step: int | None = None,
|
32
|
+
) -> ta.Iterator[T]:
|
33
|
+
return iterslice(seq, slice(start, stop, step))
|
34
|
+
|
35
|
+
|
36
|
+
##
|
37
|
+
|
38
|
+
|
39
|
+
@ta.final
|
40
|
+
class SeqView(ta.Sequence[T]):
|
41
|
+
def __init__(self, data: ta.Sequence[T], slice_: slice = slice(None)) -> None:
|
42
|
+
if data.__class__ is SeqView:
|
43
|
+
self._data = data._data # type: ignore[attr-defined] # noqa
|
44
|
+
self._range = data._range[slice_] # type: ignore[attr-defined] # noqa
|
45
|
+
else:
|
46
|
+
self._data = data
|
47
|
+
self._range = range(*slice_.indices(len(data)))
|
48
|
+
|
49
|
+
def __init_subclass__(cls, **kwargs):
|
50
|
+
raise TypeError
|
51
|
+
|
52
|
+
_data: ta.Sequence[T]
|
53
|
+
_range: range
|
54
|
+
|
55
|
+
@classmethod
|
56
|
+
def _from_range(cls, base: ta.Sequence[T], rng: range) -> 'SeqView[T]':
|
57
|
+
self = object.__new__(cls)
|
58
|
+
self._data = base
|
59
|
+
self._range = rng
|
60
|
+
return self
|
61
|
+
|
62
|
+
def __repr__(self) -> str:
|
63
|
+
return f'{self.__class__.__name__}({self._data!r}, {self.slice!r})'
|
64
|
+
|
65
|
+
#
|
66
|
+
|
67
|
+
def __len__(self) -> int:
|
68
|
+
return len(self._range)
|
69
|
+
|
70
|
+
def __getitem__(self, key: int | slice) -> ta.Union[T, 'SeqView[T]']: # type: ignore[override]
|
71
|
+
if isinstance(key, slice):
|
72
|
+
nr = self._range[key]
|
73
|
+
return SeqView._from_range(self._data, nr)
|
74
|
+
return self._data[self._range[key]]
|
75
|
+
|
76
|
+
def __iter__(self) -> ta.Iterator[T]:
|
77
|
+
return map(self._data.__getitem__, self._range)
|
78
|
+
|
79
|
+
def __reversed__(self) -> ta.Iterator[T]:
|
80
|
+
return map(self._data.__getitem__, reversed(self._range))
|
81
|
+
|
82
|
+
def count(self, value: ta.Any) -> int:
|
83
|
+
c = 0
|
84
|
+
for i in self._range:
|
85
|
+
if self._data[i] == value:
|
86
|
+
c += 1
|
87
|
+
return c
|
88
|
+
|
89
|
+
def index(self, value: ta.Any, start: int = 0, stop: int | None = None) -> int:
|
90
|
+
sub = self._range[slice(start, stop, 1)]
|
91
|
+
for off, i in enumerate(sub):
|
92
|
+
if self._data[i] == value:
|
93
|
+
return off
|
94
|
+
raise ValueError(f'{value!r} is not in view')
|
95
|
+
|
96
|
+
#
|
97
|
+
|
98
|
+
@property
|
99
|
+
def data(self) -> ta.Sequence[T]:
|
100
|
+
return self._data
|
101
|
+
|
102
|
+
_slice: slice
|
103
|
+
|
104
|
+
@property
|
105
|
+
def slice(self) -> slice:
|
106
|
+
try:
|
107
|
+
return self._slice
|
108
|
+
except AttributeError:
|
109
|
+
pass
|
110
|
+
|
111
|
+
step = self._range.step
|
112
|
+
start = self._range.start
|
113
|
+
if len(self._range) == 0:
|
114
|
+
stop = start
|
115
|
+
else:
|
116
|
+
last = start + (len(self._range) - 1) * step
|
117
|
+
stop = last + (1 if step > 0 else -1)
|
118
|
+
slc = slice(start, stop, step)
|
119
|
+
|
120
|
+
self._slice = slc
|
121
|
+
return slc
|
122
|
+
|
123
|
+
def materialize(self) -> ta.Sequence[T]:
|
124
|
+
return self._data[self.slice]
|
omlish/marshal/__init__.py
CHANGED
@@ -49,11 +49,17 @@ with _lang.auto_proxy_init(globals()):
|
|
49
49
|
|
50
50
|
from .base.configs import ( # noqa
|
51
51
|
Config,
|
52
|
+
Configs,
|
53
|
+
|
52
54
|
ConfigRegistry,
|
53
55
|
)
|
54
56
|
|
55
57
|
from .base.contexts import ( # noqa
|
56
58
|
BaseContext,
|
59
|
+
|
60
|
+
MarshalFactoryContext,
|
61
|
+
UnmarshalFactoryContext,
|
62
|
+
|
57
63
|
MarshalContext,
|
58
64
|
UnmarshalContext,
|
59
65
|
)
|
omlish/marshal/base/configs.py
CHANGED
@@ -3,6 +3,10 @@ import typing as ta
|
|
3
3
|
from ... import lang
|
4
4
|
from .registries import Registry
|
5
5
|
from .registries import RegistryItem
|
6
|
+
from .registries import RegistryView
|
7
|
+
|
8
|
+
|
9
|
+
ConfigT = ta.TypeVar('ConfigT', bound='Config')
|
6
10
|
|
7
11
|
|
8
12
|
##
|
@@ -12,7 +16,15 @@ class Config(RegistryItem, lang.Abstract):
|
|
12
16
|
pass
|
13
17
|
|
14
18
|
|
19
|
+
Configs: ta.TypeAlias = RegistryView[Config]
|
20
|
+
|
21
|
+
|
22
|
+
##
|
23
|
+
|
24
|
+
|
15
25
|
ConfigRegistry: ta.TypeAlias = Registry[Config]
|
16
26
|
|
27
|
+
lang.static_check_issubclass[Configs](ConfigRegistry)
|
28
|
+
|
17
29
|
|
18
30
|
EMPTY_CONFIG_REGISTRY = ConfigRegistry().seal()
|
omlish/marshal/base/contexts.py
CHANGED
@@ -6,7 +6,7 @@ from ... import collections as col
|
|
6
6
|
from ... import lang
|
7
7
|
from ... import reflect as rfl
|
8
8
|
from .configs import EMPTY_CONFIG_REGISTRY
|
9
|
-
from .configs import
|
9
|
+
from .configs import Configs
|
10
10
|
from .errors import UnhandledTypeError
|
11
11
|
from .options import Option
|
12
12
|
from .overrides import ReflectOverride
|
@@ -27,45 +27,61 @@ T = ta.TypeVar('T')
|
|
27
27
|
|
28
28
|
|
29
29
|
@dc.dataclass(frozen=True, kw_only=True)
|
30
|
-
class BaseContext(lang.Abstract):
|
31
|
-
|
30
|
+
class BaseContext(lang.Abstract, lang.Sealed):
|
31
|
+
configs: Configs = EMPTY_CONFIG_REGISTRY
|
32
32
|
options: col.TypeMap[Option] = col.TypeMap()
|
33
33
|
|
34
34
|
def _reflect(self, o: ta.Any) -> rfl.Type:
|
35
35
|
def override(o):
|
36
|
-
if (ovr := self.
|
36
|
+
if (ovr := self.configs.get_of(o, ReflectOverride)):
|
37
37
|
return ovr[-1].rty
|
38
38
|
return None
|
39
39
|
|
40
40
|
return rfl.Reflector(override=override).type(o)
|
41
41
|
|
42
42
|
|
43
|
+
#
|
44
|
+
|
45
|
+
|
43
46
|
@dc.dataclass(frozen=True, kw_only=True)
|
44
|
-
class
|
45
|
-
|
47
|
+
class MarshalFactoryContext(BaseContext, lang.Final):
|
48
|
+
marshaler_factory: ta.Optional['MarshalerFactory'] = None
|
46
49
|
|
47
|
-
def
|
50
|
+
def make_marshaler(self, o: ta.Any) -> 'Marshaler':
|
48
51
|
rty = self._reflect(o)
|
49
|
-
fac = check.not_none(self.
|
52
|
+
fac = check.not_none(self.marshaler_factory)
|
50
53
|
if (mfn := fac.make_marshaler(self, rty)) is None:
|
51
54
|
raise UnhandledTypeError(rty) # noqa
|
52
55
|
return mfn()
|
53
56
|
|
54
|
-
def marshal(self, obj: ta.Any, ty: ta.Any | None = None) -> 'Value':
|
55
|
-
return self.make(ty if ty is not None else type(obj)).marshal(self, obj)
|
56
|
-
|
57
57
|
|
58
58
|
@dc.dataclass(frozen=True, kw_only=True)
|
59
|
-
class
|
60
|
-
|
59
|
+
class UnmarshalFactoryContext(BaseContext, lang.Final):
|
60
|
+
unmarshaler_factory: ta.Optional['UnmarshalerFactory'] = None
|
61
61
|
|
62
|
-
def
|
62
|
+
def make_unmarshaler(self, o: ta.Any) -> 'Unmarshaler':
|
63
63
|
rty = self._reflect(o)
|
64
|
-
fac = check.not_none(self.
|
64
|
+
fac = check.not_none(self.unmarshaler_factory)
|
65
65
|
if (mfn := fac.make_unmarshaler(self, rty)) is None:
|
66
66
|
raise UnhandledTypeError(rty) # noqa
|
67
67
|
return mfn()
|
68
68
|
|
69
|
+
|
70
|
+
#
|
71
|
+
|
72
|
+
|
73
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
74
|
+
class MarshalContext(BaseContext, lang.Final):
|
75
|
+
marshal_factory_context: MarshalFactoryContext
|
76
|
+
|
77
|
+
def marshal(self, obj: ta.Any, ty: ta.Any | None = None) -> 'Value':
|
78
|
+
return self.marshal_factory_context.make_marshaler(ty if ty is not None else type(obj)).marshal(self, obj)
|
79
|
+
|
80
|
+
|
81
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
82
|
+
class UnmarshalContext(BaseContext, lang.Final):
|
83
|
+
unmarshal_factory_context: UnmarshalFactoryContext
|
84
|
+
|
69
85
|
@ta.overload
|
70
86
|
def unmarshal(self, v: 'Value', ty: type[T]) -> T:
|
71
87
|
...
|
@@ -75,4 +91,4 @@ class UnmarshalContext(BaseContext, lang.Final):
|
|
75
91
|
...
|
76
92
|
|
77
93
|
def unmarshal(self, v, ty):
|
78
|
-
return self.
|
94
|
+
return self.unmarshal_factory_context.make_unmarshaler(ty).unmarshal(self, v)
|
omlish/marshal/base/funcs.py
CHANGED
@@ -3,9 +3,10 @@ import typing as ta
|
|
3
3
|
|
4
4
|
from ... import lang
|
5
5
|
from ... import reflect as rfl
|
6
|
-
from ...funcs import guard as gfs
|
7
6
|
from .contexts import MarshalContext
|
7
|
+
from .contexts import MarshalFactoryContext
|
8
8
|
from .contexts import UnmarshalContext
|
9
|
+
from .contexts import UnmarshalFactoryContext
|
9
10
|
from .types import Marshaler
|
10
11
|
from .types import MarshalerFactory
|
11
12
|
from .types import MarshalerMaker
|
@@ -41,7 +42,7 @@ class FuncUnmarshaler(Unmarshaler, lang.Final):
|
|
41
42
|
class FuncMarshalerFactory(MarshalerFactory): # noqa
|
42
43
|
gf: MarshalerMaker
|
43
44
|
|
44
|
-
def make_marshaler(self, ctx:
|
45
|
+
def make_marshaler(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
|
45
46
|
return self.gf(ctx, rty)
|
46
47
|
|
47
48
|
|
@@ -49,14 +50,5 @@ class FuncMarshalerFactory(MarshalerFactory): # noqa
|
|
49
50
|
class FuncUnmarshalerFactory(UnmarshalerFactory): # noqa
|
50
51
|
gf: UnmarshalerMaker
|
51
52
|
|
52
|
-
def make_unmarshaler(self, ctx:
|
53
|
+
def make_unmarshaler(self, ctx: UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
|
53
54
|
return self.gf(ctx, rty)
|
54
|
-
|
55
|
-
|
56
|
-
##
|
57
|
-
|
58
|
-
|
59
|
-
class GuardMethodMarshalerFactory(MarshalerFactory):
|
60
|
-
@gfs.method(instance_cache=True)
|
61
|
-
def make_marshaler(self, ctx: MarshalContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
|
62
|
-
raise NotImplementedError
|
omlish/marshal/base/options.py
CHANGED
@@ -3,6 +3,7 @@ TODO:
|
|
3
3
|
- col.TypeMap?
|
4
4
|
- at least get_any
|
5
5
|
"""
|
6
|
+
import abc
|
6
7
|
import dataclasses as dc
|
7
8
|
import threading
|
8
9
|
import typing as ta
|
@@ -21,11 +22,38 @@ RegistryItemT = ta.TypeVar('RegistryItemT', bound=RegistryItem)
|
|
21
22
|
RegistryItemU = ta.TypeVar('RegistryItemU', bound=RegistryItem)
|
22
23
|
|
23
24
|
|
25
|
+
##
|
26
|
+
|
27
|
+
|
28
|
+
class RegistryView(lang.Abstract, ta.Generic[RegistryItemT]):
|
29
|
+
@abc.abstractmethod
|
30
|
+
def get(
|
31
|
+
self,
|
32
|
+
key: ta.Any,
|
33
|
+
*,
|
34
|
+
identity: bool | None = None,
|
35
|
+
) -> ta.Sequence[RegistryItemT]:
|
36
|
+
...
|
37
|
+
|
38
|
+
@abc.abstractmethod
|
39
|
+
def get_of(
|
40
|
+
self,
|
41
|
+
key: ta.Any,
|
42
|
+
item_ty: type[RegistryItemU],
|
43
|
+
*,
|
44
|
+
identity: bool | None = None,
|
45
|
+
) -> ta.Sequence[RegistryItemU]:
|
46
|
+
...
|
47
|
+
|
48
|
+
|
49
|
+
##
|
50
|
+
|
51
|
+
|
24
52
|
class RegistrySealedError(Exception):
|
25
53
|
pass
|
26
54
|
|
27
55
|
|
28
|
-
class Registry(
|
56
|
+
class Registry(RegistryView[RegistryItemT]):
|
29
57
|
def __init__(
|
30
58
|
self,
|
31
59
|
*,
|
@@ -203,8 +231,8 @@ class Registry(ta.Generic[RegistryItemT]):
|
|
203
231
|
key: ta.Any,
|
204
232
|
*,
|
205
233
|
identity: bool | None = None,
|
206
|
-
) -> ta.Sequence[
|
207
|
-
return self._state.get(key, identity=identity)
|
234
|
+
) -> ta.Sequence[RegistryItemT]:
|
235
|
+
return self._state.get(key, identity=identity) # type: ignore [return-value]
|
208
236
|
|
209
237
|
def get_of(
|
210
238
|
self,
|
@@ -213,4 +241,4 @@ class Registry(ta.Generic[RegistryItemT]):
|
|
213
241
|
*,
|
214
242
|
identity: bool | None = None,
|
215
243
|
) -> ta.Sequence[RegistryItemU]:
|
216
|
-
return self._state.get_of(key, item_ty, identity=identity) # type: ignore[return-value]
|
244
|
+
return self._state.get_of(key, item_ty, identity=identity) # type: ignore [return-value]
|
omlish/marshal/base/types.py
CHANGED
@@ -6,7 +6,9 @@ from ... import reflect as rfl
|
|
6
6
|
from ...funcs import guard as gfs
|
7
7
|
from .configs import ConfigRegistry
|
8
8
|
from .contexts import MarshalContext
|
9
|
+
from .contexts import MarshalFactoryContext
|
9
10
|
from .contexts import UnmarshalContext
|
11
|
+
from .contexts import UnmarshalFactoryContext
|
10
12
|
from .values import Value
|
11
13
|
|
12
14
|
|
@@ -31,19 +33,19 @@ class Unmarshaler(lang.Abstract):
|
|
31
33
|
##
|
32
34
|
|
33
35
|
|
34
|
-
MarshalerMaker: ta.TypeAlias = gfs.GuardFn[[
|
35
|
-
UnmarshalerMaker: ta.TypeAlias = gfs.GuardFn[[
|
36
|
+
MarshalerMaker: ta.TypeAlias = gfs.GuardFn[[MarshalFactoryContext, rfl.Type], Marshaler]
|
37
|
+
UnmarshalerMaker: ta.TypeAlias = gfs.GuardFn[[UnmarshalFactoryContext, rfl.Type], Unmarshaler]
|
36
38
|
|
37
39
|
|
38
40
|
class MarshalerFactory(lang.Abstract):
|
39
41
|
@abc.abstractmethod
|
40
|
-
def make_marshaler(self, ctx:
|
42
|
+
def make_marshaler(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
|
41
43
|
raise NotImplementedError
|
42
44
|
|
43
45
|
|
44
46
|
class UnmarshalerFactory(lang.Abstract):
|
45
47
|
@abc.abstractmethod
|
46
|
-
def make_unmarshaler(self, ctx:
|
48
|
+
def make_unmarshaler(self, ctx: UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
|
47
49
|
raise NotImplementedError
|
48
50
|
|
49
51
|
|
@@ -63,20 +65,32 @@ class Marshaling(lang.Abstract):
|
|
63
65
|
def unmarshaler_factory(self) -> UnmarshalerFactory:
|
64
66
|
raise NotImplementedError
|
65
67
|
|
66
|
-
|
68
|
+
##
|
69
|
+
|
70
|
+
def new_marshal_factory_context(self) -> MarshalFactoryContext:
|
71
|
+
return MarshalFactoryContext(
|
72
|
+
configs=self.config_registry(),
|
73
|
+
marshaler_factory=self.marshaler_factory(),
|
74
|
+
)
|
75
|
+
|
76
|
+
def new_unmarshal_factory_context(self) -> UnmarshalFactoryContext:
|
77
|
+
return UnmarshalFactoryContext(
|
78
|
+
configs=self.config_registry(),
|
79
|
+
unmarshaler_factory=self.unmarshaler_factory(),
|
80
|
+
)
|
81
|
+
|
82
|
+
##
|
67
83
|
|
68
|
-
def new_marshal_context(self
|
84
|
+
def new_marshal_context(self) -> MarshalContext:
|
69
85
|
return MarshalContext(
|
70
|
-
|
71
|
-
|
72
|
-
**kwargs,
|
86
|
+
configs=self.config_registry(),
|
87
|
+
marshal_factory_context=self.new_marshal_factory_context(),
|
73
88
|
)
|
74
89
|
|
75
|
-
def new_unmarshal_context(self
|
90
|
+
def new_unmarshal_context(self) -> UnmarshalContext:
|
76
91
|
return UnmarshalContext(
|
77
|
-
|
78
|
-
|
79
|
-
**kwargs,
|
92
|
+
configs=self.config_registry(),
|
93
|
+
unmarshal_factory_context=self.new_unmarshal_factory_context(),
|
80
94
|
)
|
81
95
|
|
82
96
|
#
|
@@ -10,7 +10,9 @@ import typing as ta
|
|
10
10
|
from ... import check
|
11
11
|
from ... import reflect as rfl
|
12
12
|
from ..base.contexts import MarshalContext
|
13
|
+
from ..base.contexts import MarshalFactoryContext
|
13
14
|
from ..base.contexts import UnmarshalContext
|
15
|
+
from ..base.contexts import UnmarshalFactoryContext
|
14
16
|
from ..base.types import Marshaler
|
15
17
|
from ..base.types import Unmarshaler
|
16
18
|
from ..base.values import Value
|
@@ -41,16 +43,16 @@ class IterableMarshaler(Marshaler):
|
|
41
43
|
|
42
44
|
class IterableMarshalerFactory(MarshalerFactoryMethodClass):
|
43
45
|
@MarshalerFactoryMethodClass.make_marshaler.register
|
44
|
-
def _make_generic(self, ctx:
|
46
|
+
def _make_generic(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
|
45
47
|
if not (isinstance(rty, rfl.Generic) and issubclass(rty.cls, collections.abc.Iterable)):
|
46
48
|
return None
|
47
|
-
return lambda: IterableMarshaler(ctx.
|
49
|
+
return lambda: IterableMarshaler(ctx.make_marshaler(check.single(rty.args)))
|
48
50
|
|
49
51
|
@MarshalerFactoryMethodClass.make_marshaler.register
|
50
|
-
def _make_concrete(self, ctx:
|
52
|
+
def _make_concrete(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
|
51
53
|
if not (isinstance(rty, type) and issubclass(rty, collections.abc.Iterable)):
|
52
54
|
return None
|
53
|
-
return lambda: IterableMarshaler(ctx.
|
55
|
+
return lambda: IterableMarshaler(ctx.make_marshaler(ta.Any))
|
54
56
|
|
55
57
|
|
56
58
|
#
|
@@ -67,14 +69,14 @@ class IterableUnmarshaler(Unmarshaler):
|
|
67
69
|
|
68
70
|
class IterableUnmarshalerFactory(UnmarshalerFactoryMethodClass):
|
69
71
|
@UnmarshalerFactoryMethodClass.make_unmarshaler.register
|
70
|
-
def _make_generic(self, ctx:
|
72
|
+
def _make_generic(self, ctx: UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
|
71
73
|
if not (isinstance(rty, rfl.Generic) and issubclass(rty.cls, collections.abc.Iterable)):
|
72
74
|
return None
|
73
75
|
cty = DEFAULT_ITERABLE_CONCRETE_TYPES.get(rty.cls, rty.cls) # noqa
|
74
|
-
return lambda: IterableUnmarshaler(cty, ctx.
|
76
|
+
return lambda: IterableUnmarshaler(cty, ctx.make_unmarshaler(check.single(rty.args))) # noqa
|
75
77
|
|
76
78
|
@UnmarshalerFactoryMethodClass.make_unmarshaler.register
|
77
|
-
def _make_concrete(self, ctx:
|
79
|
+
def _make_concrete(self, ctx: UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
|
78
80
|
if not (isinstance(rty, type) and issubclass(rty, collections.abc.Iterable)):
|
79
81
|
return None
|
80
|
-
return lambda: IterableUnmarshaler(check.isinstance(rty, type), ctx.
|
82
|
+
return lambda: IterableUnmarshaler(check.isinstance(rty, type), ctx.make_unmarshaler(ta.Any))
|
@@ -8,7 +8,9 @@ import typing as ta
|
|
8
8
|
from ... import check
|
9
9
|
from ... import reflect as rfl
|
10
10
|
from ..base.contexts import MarshalContext
|
11
|
+
from ..base.contexts import MarshalFactoryContext
|
11
12
|
from ..base.contexts import UnmarshalContext
|
13
|
+
from ..base.contexts import UnmarshalFactoryContext
|
12
14
|
from ..base.types import Marshaler
|
13
15
|
from ..base.types import MarshalerFactory
|
14
16
|
from ..base.types import Unmarshaler
|
@@ -29,11 +31,11 @@ class LiteralMarshaler(Marshaler):
|
|
29
31
|
|
30
32
|
|
31
33
|
class LiteralMarshalerFactory(MarshalerFactory):
|
32
|
-
def make_marshaler(self, ctx:
|
34
|
+
def make_marshaler(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
|
33
35
|
if not (isinstance(rty, rfl.Literal) and len(set(map(type, rty.args))) == 1):
|
34
36
|
return None
|
35
37
|
ety = check.single(set(map(type, rty.args)))
|
36
|
-
return lambda: LiteralMarshaler(ctx.
|
38
|
+
return lambda: LiteralMarshaler(ctx.make_marshaler(ety), frozenset(rty.args))
|
37
39
|
|
38
40
|
|
39
41
|
@dc.dataclass(frozen=True)
|
@@ -46,8 +48,8 @@ class LiteralUnmarshaler(Unmarshaler):
|
|
46
48
|
|
47
49
|
|
48
50
|
class LiteralUnmarshalerFactory(UnmarshalerFactory):
|
49
|
-
def make_unmarshaler(self, ctx:
|
51
|
+
def make_unmarshaler(self, ctx: UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
|
50
52
|
if not (isinstance(rty, rfl.Literal) and len(set(map(type, rty.args))) == 1):
|
51
53
|
return None
|
52
54
|
ety = check.single(set(map(type, rty.args)))
|
53
|
-
return lambda: LiteralUnmarshaler(ctx.
|
55
|
+
return lambda: LiteralUnmarshaler(ctx.make_unmarshaler(ety), frozenset(rty.args))
|
@@ -5,7 +5,9 @@ import typing as ta
|
|
5
5
|
from ... import check
|
6
6
|
from ... import reflect as rfl
|
7
7
|
from ..base.contexts import MarshalContext
|
8
|
+
from ..base.contexts import MarshalFactoryContext
|
8
9
|
from ..base.contexts import UnmarshalContext
|
10
|
+
from ..base.contexts import UnmarshalFactoryContext
|
9
11
|
from ..base.types import Marshaler
|
10
12
|
from ..base.types import Unmarshaler
|
11
13
|
from ..base.values import Value
|
@@ -39,17 +41,17 @@ class MappingMarshaler(Marshaler):
|
|
39
41
|
|
40
42
|
class MappingMarshalerFactory(MarshalerFactoryMethodClass):
|
41
43
|
@MarshalerFactoryMethodClass.make_marshaler.register
|
42
|
-
def
|
44
|
+
def _make_generic(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
|
43
45
|
if not (isinstance(rty, rfl.Generic) and issubclass(rty.cls, collections.abc.Mapping)):
|
44
46
|
return None
|
45
47
|
kt, vt = rty.args
|
46
|
-
return lambda: MappingMarshaler(ctx.
|
48
|
+
return lambda: MappingMarshaler(ctx.make_marshaler(kt), ctx.make_marshaler(vt))
|
47
49
|
|
48
50
|
@MarshalerFactoryMethodClass.make_marshaler.register
|
49
|
-
def
|
51
|
+
def _make_concrete(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
|
50
52
|
if not (isinstance(rty, type) and issubclass(rty, collections.abc.Mapping)):
|
51
53
|
return None
|
52
|
-
return lambda: MappingMarshaler(a := ctx.
|
54
|
+
return lambda: MappingMarshaler(a := ctx.make_marshaler(ta.Any), a)
|
53
55
|
|
54
56
|
|
55
57
|
#
|
@@ -70,15 +72,15 @@ class MappingUnmarshaler(Unmarshaler):
|
|
70
72
|
|
71
73
|
class MappingUnmarshalerFactory(UnmarshalerFactoryMethodClass):
|
72
74
|
@UnmarshalerFactoryMethodClass.make_unmarshaler.register
|
73
|
-
def
|
75
|
+
def _make_generic(self, ctx: UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
|
74
76
|
if not (isinstance(rty, rfl.Generic) and issubclass(rty.cls, collections.abc.Mapping)):
|
75
77
|
return None
|
76
78
|
cty = DEFAULT_MAPPING_CONCRETE_TYPES.get(rty.cls, rty.cls) # noqa
|
77
79
|
kt, vt = rty.args
|
78
|
-
return lambda: MappingUnmarshaler(cty, ctx.
|
80
|
+
return lambda: MappingUnmarshaler(cty, ctx.make_unmarshaler(kt), ctx.make_unmarshaler(vt))
|
79
81
|
|
80
82
|
@UnmarshalerFactoryMethodClass.make_unmarshaler.register
|
81
|
-
def
|
83
|
+
def _make_concrete(self, ctx: UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
|
82
84
|
if not (isinstance(rty, type) and issubclass(rty, collections.abc.Mapping)):
|
83
85
|
return None
|
84
|
-
return lambda: MappingUnmarshaler(check.isinstance(rty, type), a := ctx.
|
86
|
+
return lambda: MappingUnmarshaler(check.isinstance(rty, type), a := ctx.make_unmarshaler(ta.Any), a)
|