omlish 0.0.0.dev413__py3-none-any.whl → 0.0.0.dev415__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 -3
- omlish/codecs/registry.py +1 -1
- omlish/dataclasses/__init__.py +135 -113
- omlish/dataclasses/impl/api/classes/make.py +5 -3
- omlish/dataclasses/impl/configs.py +29 -29
- omlish/lite/maysyncs.py +1 -0
- omlish/manifests/base.py +1 -1
- omlish/marshal/__init__.py +98 -57
- omlish/marshal/base/__init__.py +0 -0
- omlish/marshal/base/contexts.py +75 -0
- omlish/marshal/{errors.py → base/errors.py} +1 -1
- omlish/marshal/base/options.py +2 -0
- omlish/marshal/base/overrides.py +25 -0
- omlish/marshal/{registries.py → base/registries.py} +4 -8
- omlish/marshal/base/types.py +70 -0
- omlish/marshal/{values.py → base/values.py} +1 -13
- omlish/marshal/composite/iterables.py +7 -7
- omlish/marshal/composite/literals.py +7 -7
- omlish/marshal/composite/mappings.py +7 -7
- omlish/marshal/composite/maybes.py +7 -7
- omlish/marshal/composite/newtypes.py +6 -6
- omlish/marshal/composite/optionals.py +7 -7
- omlish/marshal/composite/special.py +6 -6
- omlish/marshal/composite/wrapped.py +5 -5
- omlish/marshal/factories/__init__.py +0 -0
- omlish/marshal/factories/func.py +28 -0
- omlish/marshal/factories/match.py +34 -0
- omlish/marshal/factories/multi.py +55 -0
- omlish/marshal/factories/recursive.py +120 -0
- omlish/marshal/factories/simple.py +28 -0
- omlish/marshal/factories/typecache.py +91 -0
- omlish/marshal/factories/typemap.py +65 -0
- omlish/marshal/globals.py +7 -7
- omlish/marshal/naming.py +1 -1
- omlish/marshal/objects/dataclasses.py +7 -7
- omlish/marshal/objects/marshal.py +4 -4
- omlish/marshal/objects/metadata.py +4 -4
- omlish/marshal/objects/namedtuples.py +7 -7
- omlish/marshal/objects/unmarshal.py +4 -4
- omlish/marshal/polymorphism/marshal.py +4 -4
- omlish/marshal/polymorphism/metadata.py +1 -1
- omlish/marshal/polymorphism/standard.py +2 -2
- omlish/marshal/polymorphism/unions.py +7 -7
- omlish/marshal/polymorphism/unmarshal.py +4 -4
- omlish/marshal/singular/base64.py +7 -7
- omlish/marshal/singular/datetimes.py +7 -7
- omlish/marshal/singular/enums.py +7 -7
- omlish/marshal/singular/numbers.py +7 -7
- omlish/marshal/singular/primitives.py +7 -7
- omlish/marshal/singular/uuids.py +7 -7
- omlish/marshal/standard.py +8 -8
- omlish/marshal/trivial/any.py +7 -7
- omlish/marshal/trivial/forbidden.py +7 -7
- omlish/marshal/trivial/nop.py +5 -5
- omlish/subprocesses/maysyncs.py +7 -96
- {omlish-0.0.0.dev413.dist-info → omlish-0.0.0.dev415.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev413.dist-info → omlish-0.0.0.dev415.dist-info}/RECORD +61 -53
- omlish/inject/.dataclasses.json +0 -3
- omlish/marshal/.dataclasses.json +0 -3
- omlish/marshal/base.py +0 -472
- omlish/marshal/factories.py +0 -116
- omlish/marshal/proxy.py +0 -26
- {omlish-0.0.0.dev413.dist-info → omlish-0.0.0.dev415.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev413.dist-info → omlish-0.0.0.dev415.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev413.dist-info → omlish-0.0.0.dev415.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev413.dist-info → omlish-0.0.0.dev415.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
from ... import check
|
4
|
+
from ... import collections as col
|
5
|
+
from ... import dataclasses as dc
|
6
|
+
from ... import lang
|
7
|
+
from ... import reflect as rfl
|
8
|
+
from ...funcs import match as mfs
|
9
|
+
from .errors import UnhandledTypeError
|
10
|
+
from .options import Option
|
11
|
+
from .overrides import ReflectOverride
|
12
|
+
from .registries import Registry
|
13
|
+
from .types import Marshaler
|
14
|
+
from .types import MarshalerFactory
|
15
|
+
from .types import Unmarshaler
|
16
|
+
from .types import UnmarshalerFactory
|
17
|
+
from .values import Value
|
18
|
+
|
19
|
+
|
20
|
+
T = ta.TypeVar('T')
|
21
|
+
|
22
|
+
|
23
|
+
##
|
24
|
+
|
25
|
+
|
26
|
+
@dc.dataclass(frozen=True)
|
27
|
+
class BaseContext(lang.Abstract):
|
28
|
+
registry: Registry
|
29
|
+
options: col.TypeMap[Option] = col.TypeMap()
|
30
|
+
|
31
|
+
def _reflect(self, o: ta.Any) -> rfl.Type:
|
32
|
+
def override(o):
|
33
|
+
if (ovr := self.registry.get_of(o, ReflectOverride)):
|
34
|
+
return ovr[-1].rty
|
35
|
+
return None
|
36
|
+
|
37
|
+
return rfl.Reflector(override=override).type(o)
|
38
|
+
|
39
|
+
|
40
|
+
@dc.dataclass(frozen=True)
|
41
|
+
class MarshalContext(BaseContext, lang.Final):
|
42
|
+
factory: MarshalerFactory | None = None
|
43
|
+
|
44
|
+
def make(self, o: ta.Any) -> Marshaler:
|
45
|
+
rty = self._reflect(o)
|
46
|
+
try:
|
47
|
+
return check.not_none(self.factory).make_marshaler(self, rty)
|
48
|
+
except mfs.MatchGuardError:
|
49
|
+
raise UnhandledTypeError(rty) # noqa
|
50
|
+
|
51
|
+
def marshal(self, obj: ta.Any, ty: ta.Any | None = None) -> Value:
|
52
|
+
return self.make(ty if ty is not None else type(obj)).marshal(self, obj)
|
53
|
+
|
54
|
+
|
55
|
+
@dc.dataclass(frozen=True)
|
56
|
+
class UnmarshalContext(BaseContext, lang.Final):
|
57
|
+
factory: UnmarshalerFactory | None = None
|
58
|
+
|
59
|
+
def make(self, o: ta.Any) -> Unmarshaler:
|
60
|
+
rty = self._reflect(o)
|
61
|
+
try:
|
62
|
+
return check.not_none(self.factory).make_unmarshaler(self, rty)
|
63
|
+
except mfs.MatchGuardError:
|
64
|
+
raise UnhandledTypeError(rty) # noqa
|
65
|
+
|
66
|
+
@ta.overload
|
67
|
+
def unmarshal(self, v: Value, ty: type[T]) -> T:
|
68
|
+
...
|
69
|
+
|
70
|
+
@ta.overload
|
71
|
+
def unmarshal(self, v: Value, ty: ta.Any) -> ta.Any:
|
72
|
+
...
|
73
|
+
|
74
|
+
def unmarshal(self, v, ty):
|
75
|
+
return self.make(ty).unmarshal(self, v)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from ... import dataclasses as dc
|
2
|
+
from ... import lang
|
3
|
+
from ... import reflect as rfl
|
4
|
+
from .registries import RegistryItem
|
5
|
+
from .types import Marshaler
|
6
|
+
from .types import MarshalerFactory
|
7
|
+
from .types import Unmarshaler
|
8
|
+
from .types import UnmarshalerFactory
|
9
|
+
|
10
|
+
|
11
|
+
##
|
12
|
+
|
13
|
+
|
14
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
15
|
+
class Override(RegistryItem, lang.Final):
|
16
|
+
marshaler: Marshaler | None = dc.xfield(None, check_type=(Marshaler, None))
|
17
|
+
marshaler_factory: MarshalerFactory | None = None
|
18
|
+
|
19
|
+
unmarshaler: Unmarshaler | None = dc.xfield(None, check_type=(Unmarshaler, None))
|
20
|
+
unmarshaler_factory: UnmarshalerFactory | None = None
|
21
|
+
|
22
|
+
|
23
|
+
@dc.dataclass(frozen=True)
|
24
|
+
class ReflectOverride(RegistryItem, lang.Final):
|
25
|
+
rty: rfl.Type
|
@@ -1,13 +1,9 @@
|
|
1
|
-
"""
|
2
|
-
TODO:
|
3
|
-
- inheritance
|
4
|
-
"""
|
5
1
|
import dataclasses as dc
|
6
2
|
import threading
|
7
3
|
import typing as ta
|
8
4
|
|
9
|
-
from
|
10
|
-
from
|
5
|
+
from ... import collections as col
|
6
|
+
from ... import lang
|
11
7
|
|
12
8
|
|
13
9
|
##
|
@@ -36,7 +32,7 @@ class Registry:
|
|
36
32
|
def __init__(self) -> None:
|
37
33
|
super().__init__()
|
38
34
|
|
39
|
-
self.
|
35
|
+
self._lock = threading.Lock()
|
40
36
|
self._idct: ta.MutableMapping[ta.Any, _KeyRegistryItems] = col.IdentityKeyDict()
|
41
37
|
self._dct: dict[ta.Any, _KeyRegistryItems] = {}
|
42
38
|
|
@@ -46,7 +42,7 @@ class Registry:
|
|
46
42
|
*items: RegistryItem,
|
47
43
|
identity: bool = False,
|
48
44
|
) -> 'Registry':
|
49
|
-
with self.
|
45
|
+
with self._lock:
|
50
46
|
dct: ta.Any = self._idct if identity else self._dct
|
51
47
|
if (sr := dct.get(key)) is None:
|
52
48
|
sr = dct[key] = _KeyRegistryItems(key)
|
@@ -0,0 +1,70 @@
|
|
1
|
+
import abc
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from ... import dataclasses as dc
|
5
|
+
from ... import lang
|
6
|
+
from ... import reflect as rfl
|
7
|
+
from ...funcs import match as mfs
|
8
|
+
from .values import Value
|
9
|
+
|
10
|
+
|
11
|
+
if ta.TYPE_CHECKING:
|
12
|
+
from .contexts import MarshalContext
|
13
|
+
from .contexts import UnmarshalContext
|
14
|
+
|
15
|
+
|
16
|
+
##
|
17
|
+
|
18
|
+
|
19
|
+
class Marshaler(lang.Abstract):
|
20
|
+
@abc.abstractmethod
|
21
|
+
def marshal(self, ctx: 'MarshalContext', o: ta.Any) -> Value:
|
22
|
+
raise NotImplementedError
|
23
|
+
|
24
|
+
|
25
|
+
class Unmarshaler(lang.Abstract):
|
26
|
+
@abc.abstractmethod
|
27
|
+
def unmarshal(self, ctx: 'UnmarshalContext', v: Value) -> ta.Any:
|
28
|
+
raise NotImplementedError
|
29
|
+
|
30
|
+
|
31
|
+
##
|
32
|
+
|
33
|
+
|
34
|
+
MarshalerMaker: ta.TypeAlias = mfs.MatchFn[['MarshalContext', rfl.Type], Marshaler]
|
35
|
+
UnmarshalerMaker: ta.TypeAlias = mfs.MatchFn[['UnmarshalContext', rfl.Type], Unmarshaler]
|
36
|
+
|
37
|
+
|
38
|
+
class MarshalerFactory(lang.Abstract):
|
39
|
+
@property
|
40
|
+
@abc.abstractmethod
|
41
|
+
def make_marshaler(self) -> MarshalerMaker:
|
42
|
+
raise NotImplementedError
|
43
|
+
|
44
|
+
|
45
|
+
class UnmarshalerFactory(lang.Abstract):
|
46
|
+
@property
|
47
|
+
@abc.abstractmethod
|
48
|
+
def make_unmarshaler(self) -> UnmarshalerMaker:
|
49
|
+
raise NotImplementedError
|
50
|
+
|
51
|
+
|
52
|
+
##
|
53
|
+
|
54
|
+
|
55
|
+
@dc.dataclass(frozen=True)
|
56
|
+
class MarshalerFactory_(MarshalerFactory): # noqa
|
57
|
+
fn: MarshalerMaker
|
58
|
+
|
59
|
+
@property
|
60
|
+
def make_marshaler(self) -> MarshalerMaker:
|
61
|
+
return self.fn
|
62
|
+
|
63
|
+
|
64
|
+
@dc.dataclass(frozen=True)
|
65
|
+
class UnmarshalerFactory_(UnmarshalerFactory): # noqa
|
66
|
+
fn: UnmarshalerMaker
|
67
|
+
|
68
|
+
@property
|
69
|
+
def make_unmarshaler(self) -> UnmarshalerMaker:
|
70
|
+
return self.fn
|
@@ -10,13 +10,13 @@ import typing as ta
|
|
10
10
|
from ... import check
|
11
11
|
from ... import reflect as rfl
|
12
12
|
from ...funcs import match as mfs
|
13
|
-
from ..base import MarshalContext
|
14
|
-
from ..base import
|
15
|
-
from ..base import
|
16
|
-
from ..base import
|
17
|
-
from ..base import
|
18
|
-
from ..
|
19
|
-
from ..
|
13
|
+
from ..base.contexts import MarshalContext
|
14
|
+
from ..base.contexts import UnmarshalContext
|
15
|
+
from ..base.types import Marshaler
|
16
|
+
from ..base.types import Unmarshaler
|
17
|
+
from ..base.values import Value
|
18
|
+
from ..factories.match import MarshalerFactoryMatchClass
|
19
|
+
from ..factories.match import UnmarshalerFactoryMatchClass
|
20
20
|
|
21
21
|
|
22
22
|
##
|
@@ -3,13 +3,13 @@ import typing as ta
|
|
3
3
|
|
4
4
|
from ... import check
|
5
5
|
from ... import reflect as rfl
|
6
|
-
from ..base import MarshalContext
|
7
|
-
from ..base import
|
8
|
-
from ..base import
|
9
|
-
from ..base import
|
10
|
-
from ..base import
|
11
|
-
from ..
|
12
|
-
from ..
|
6
|
+
from ..base.contexts import MarshalContext
|
7
|
+
from ..base.contexts import UnmarshalContext
|
8
|
+
from ..base.types import Marshaler
|
9
|
+
from ..base.types import Unmarshaler
|
10
|
+
from ..base.values import Value
|
11
|
+
from ..factories.simple import SimpleMarshalerFactory
|
12
|
+
from ..factories.simple import SimpleUnmarshalerFactory
|
13
13
|
|
14
14
|
|
15
15
|
##
|
@@ -5,13 +5,13 @@ import typing as ta
|
|
5
5
|
from ... import check
|
6
6
|
from ... import reflect as rfl
|
7
7
|
from ...funcs import match as mfs
|
8
|
-
from ..base import MarshalContext
|
9
|
-
from ..base import
|
10
|
-
from ..base import
|
11
|
-
from ..base import
|
12
|
-
from ..base import
|
13
|
-
from ..
|
14
|
-
from ..
|
8
|
+
from ..base.contexts import MarshalContext
|
9
|
+
from ..base.contexts import UnmarshalContext
|
10
|
+
from ..base.types import Marshaler
|
11
|
+
from ..base.types import Unmarshaler
|
12
|
+
from ..base.values import Value
|
13
|
+
from ..factories.match import MarshalerFactoryMatchClass
|
14
|
+
from ..factories.match import UnmarshalerFactoryMatchClass
|
15
15
|
|
16
16
|
|
17
17
|
##
|
@@ -9,13 +9,13 @@ from ... import check
|
|
9
9
|
from ... import lang
|
10
10
|
from ... import reflect as rfl
|
11
11
|
from ...funcs import match as mfs
|
12
|
-
from ..base import MarshalContext
|
13
|
-
from ..base import
|
14
|
-
from ..base import
|
15
|
-
from ..base import
|
16
|
-
from ..base import
|
17
|
-
from ..
|
18
|
-
from ..
|
12
|
+
from ..base.contexts import MarshalContext
|
13
|
+
from ..base.contexts import UnmarshalContext
|
14
|
+
from ..base.types import Marshaler
|
15
|
+
from ..base.types import Unmarshaler
|
16
|
+
from ..base.values import Value
|
17
|
+
from ..factories.match import MarshalerFactoryMatchClass
|
18
|
+
from ..factories.match import UnmarshalerFactoryMatchClass
|
19
19
|
|
20
20
|
|
21
21
|
##
|
@@ -1,11 +1,11 @@
|
|
1
1
|
from ... import check
|
2
2
|
from ... import reflect as rfl
|
3
|
-
from ..base import MarshalContext
|
4
|
-
from ..base import
|
5
|
-
from ..base import
|
6
|
-
from ..base import
|
7
|
-
from ..
|
8
|
-
from ..
|
3
|
+
from ..base.contexts import MarshalContext
|
4
|
+
from ..base.contexts import UnmarshalContext
|
5
|
+
from ..base.types import Marshaler
|
6
|
+
from ..base.types import Unmarshaler
|
7
|
+
from ..factories.simple import SimpleMarshalerFactory
|
8
|
+
from ..factories.simple import SimpleUnmarshalerFactory
|
9
9
|
|
10
10
|
|
11
11
|
##
|
@@ -3,13 +3,13 @@ import typing as ta
|
|
3
3
|
|
4
4
|
from ... import check
|
5
5
|
from ... import reflect as rfl
|
6
|
-
from ..base import MarshalContext
|
7
|
-
from ..base import
|
8
|
-
from ..base import
|
9
|
-
from ..base import
|
10
|
-
from ..base import
|
11
|
-
from ..
|
12
|
-
from ..
|
6
|
+
from ..base.contexts import MarshalContext
|
7
|
+
from ..base.contexts import UnmarshalContext
|
8
|
+
from ..base.types import Marshaler
|
9
|
+
from ..base.types import Unmarshaler
|
10
|
+
from ..base.values import Value
|
11
|
+
from ..factories.simple import SimpleMarshalerFactory
|
12
|
+
from ..factories.simple import SimpleUnmarshalerFactory
|
13
13
|
|
14
14
|
|
15
15
|
##
|
@@ -4,12 +4,12 @@ from ... import check
|
|
4
4
|
from ... import lang
|
5
5
|
from ... import reflect as rfl
|
6
6
|
from ...funcs import match as mfs
|
7
|
-
from ..base import MarshalContext
|
8
|
-
from ..base import
|
9
|
-
from ..base import
|
10
|
-
from ..base import
|
11
|
-
from ..
|
12
|
-
from ..
|
7
|
+
from ..base.contexts import MarshalContext
|
8
|
+
from ..base.contexts import UnmarshalContext
|
9
|
+
from ..base.types import Marshaler
|
10
|
+
from ..base.types import Unmarshaler
|
11
|
+
from ..factories.match import MarshalerFactoryMatchClass
|
12
|
+
from ..factories.match import UnmarshalerFactoryMatchClass
|
13
13
|
from .iterables import DEFAULT_ITERABLE_CONCRETE_TYPES
|
14
14
|
from .iterables import IterableMarshaler
|
15
15
|
from .iterables import IterableUnmarshaler
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import dataclasses as dc
|
2
2
|
import typing as ta
|
3
3
|
|
4
|
-
from ..base import MarshalContext
|
5
|
-
from ..base import
|
6
|
-
from ..base import
|
7
|
-
from ..base import Unmarshaler
|
8
|
-
from ..values import Value
|
4
|
+
from ..base.contexts import MarshalContext
|
5
|
+
from ..base.contexts import UnmarshalContext
|
6
|
+
from ..base.types import Marshaler
|
7
|
+
from ..base.types import Unmarshaler
|
8
|
+
from ..base.values import Value
|
9
9
|
|
10
10
|
|
11
11
|
##
|
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
from ... import dataclasses as dc
|
4
|
+
from ... import lang
|
5
|
+
from ..base.contexts import MarshalContext
|
6
|
+
from ..base.contexts import UnmarshalContext
|
7
|
+
from ..base.types import Marshaler
|
8
|
+
from ..base.types import Unmarshaler
|
9
|
+
from ..base.values import Value
|
10
|
+
|
11
|
+
|
12
|
+
##
|
13
|
+
|
14
|
+
|
15
|
+
@dc.dataclass(frozen=True)
|
16
|
+
class FuncMarshaler(Marshaler, lang.Final):
|
17
|
+
fn: ta.Callable[[MarshalContext, ta.Any], Value]
|
18
|
+
|
19
|
+
def marshal(self, ctx: MarshalContext, o: ta.Any) -> Value:
|
20
|
+
return self.fn(ctx, o)
|
21
|
+
|
22
|
+
|
23
|
+
@dc.dataclass(frozen=True)
|
24
|
+
class FuncUnmarshaler(Unmarshaler, lang.Final):
|
25
|
+
fn: ta.Callable[[UnmarshalContext, Value], ta.Any]
|
26
|
+
|
27
|
+
def unmarshal(self, ctx: UnmarshalContext, v: Value) -> ta.Any:
|
28
|
+
return self.fn(ctx, v)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
from ... import lang
|
2
|
+
from ... import reflect as rfl
|
3
|
+
from ...funcs import match as mfs
|
4
|
+
from ..base.contexts import MarshalContext
|
5
|
+
from ..base.contexts import UnmarshalContext
|
6
|
+
from ..base.types import Marshaler
|
7
|
+
from ..base.types import MarshalerFactory
|
8
|
+
from ..base.types import MarshalerMaker
|
9
|
+
from ..base.types import Unmarshaler
|
10
|
+
from ..base.types import UnmarshalerFactory
|
11
|
+
from ..base.types import UnmarshalerMaker
|
12
|
+
|
13
|
+
|
14
|
+
##
|
15
|
+
|
16
|
+
|
17
|
+
class MarshalerFactoryMatchClass(
|
18
|
+
MarshalerFactory,
|
19
|
+
mfs.MatchFnClass[[MarshalContext, rfl.Type], Marshaler],
|
20
|
+
lang.Abstract,
|
21
|
+
):
|
22
|
+
@property
|
23
|
+
def make_marshaler(self) -> MarshalerMaker:
|
24
|
+
return self # noqa
|
25
|
+
|
26
|
+
|
27
|
+
class UnmarshalerFactoryMatchClass(
|
28
|
+
UnmarshalerFactory,
|
29
|
+
mfs.MatchFnClass[[UnmarshalContext, rfl.Type], Unmarshaler],
|
30
|
+
lang.Abstract,
|
31
|
+
):
|
32
|
+
@property
|
33
|
+
def make_unmarshaler(self) -> UnmarshalerMaker:
|
34
|
+
return self # noqa
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
from ... import reflect as rfl
|
4
|
+
from ...funcs import match as mfs
|
5
|
+
from ..base.contexts import MarshalContext
|
6
|
+
from ..base.contexts import UnmarshalContext
|
7
|
+
from ..base.types import Marshaler
|
8
|
+
from ..base.types import MarshalerFactory
|
9
|
+
from ..base.types import MarshalerMaker
|
10
|
+
from ..base.types import Unmarshaler
|
11
|
+
from ..base.types import UnmarshalerFactory
|
12
|
+
from ..base.types import UnmarshalerMaker
|
13
|
+
|
14
|
+
|
15
|
+
##
|
16
|
+
|
17
|
+
|
18
|
+
class MultiMarshalerFactory(MarshalerFactory):
|
19
|
+
def __init__(
|
20
|
+
self,
|
21
|
+
fs: ta.Iterable[MarshalerFactory],
|
22
|
+
*,
|
23
|
+
strict: bool = False,
|
24
|
+
) -> None:
|
25
|
+
super().__init__()
|
26
|
+
|
27
|
+
self._fs = list(fs)
|
28
|
+
self._mmf: mfs.MultiMatchFn[[MarshalContext, rfl.Type], Marshaler] = mfs.MultiMatchFn(
|
29
|
+
[f.make_marshaler for f in self._fs],
|
30
|
+
strict=strict,
|
31
|
+
)
|
32
|
+
|
33
|
+
@property
|
34
|
+
def make_marshaler(self) -> MarshalerMaker:
|
35
|
+
return self._mmf
|
36
|
+
|
37
|
+
|
38
|
+
class MultiUnmarshalerFactory(UnmarshalerFactory):
|
39
|
+
def __init__(
|
40
|
+
self,
|
41
|
+
fs: ta.Iterable[UnmarshalerFactory],
|
42
|
+
*,
|
43
|
+
strict: bool = False,
|
44
|
+
) -> None:
|
45
|
+
super().__init__()
|
46
|
+
|
47
|
+
self._fs = list(fs)
|
48
|
+
self._mmf: mfs.MultiMatchFn[[UnmarshalContext, rfl.Type], Unmarshaler] = mfs.MultiMatchFn(
|
49
|
+
[f.make_unmarshaler for f in self._fs],
|
50
|
+
strict=strict,
|
51
|
+
)
|
52
|
+
|
53
|
+
@property
|
54
|
+
def make_unmarshaler(self) -> UnmarshalerMaker:
|
55
|
+
return self._mmf
|
@@ -0,0 +1,120 @@
|
|
1
|
+
import typing as ta
|
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.contexts import MarshalContext
|
8
|
+
from ..base.contexts import UnmarshalContext
|
9
|
+
from ..base.types import Marshaler
|
10
|
+
from ..base.types import MarshalerFactory
|
11
|
+
from ..base.types import MarshalerMaker
|
12
|
+
from ..base.types import Unmarshaler
|
13
|
+
from ..base.types import UnmarshalerFactory
|
14
|
+
from ..base.types import UnmarshalerMaker
|
15
|
+
from ..base.values import Value
|
16
|
+
|
17
|
+
|
18
|
+
T = ta.TypeVar('T')
|
19
|
+
R = ta.TypeVar('R')
|
20
|
+
C = ta.TypeVar('C')
|
21
|
+
|
22
|
+
|
23
|
+
##
|
24
|
+
|
25
|
+
|
26
|
+
class _RecursiveTypeFactory(mfs.MatchFn[[C, rfl.Type], R]):
|
27
|
+
def __init__(
|
28
|
+
self,
|
29
|
+
f: mfs.MatchFn[[C, rfl.Type], R],
|
30
|
+
prx: ta.Callable[[], tuple[R, ta.Callable[[R], None]]],
|
31
|
+
) -> None:
|
32
|
+
super().__init__()
|
33
|
+
|
34
|
+
self._f = f
|
35
|
+
self._prx = prx
|
36
|
+
self._dct: dict[rfl.Type, R] = {}
|
37
|
+
|
38
|
+
def guard(self, ctx: C, rty: rfl.Type) -> bool:
|
39
|
+
check.isinstance(rty, rfl.TYPES)
|
40
|
+
return self._f.guard(ctx, rty)
|
41
|
+
|
42
|
+
def fn(self, ctx: C, rty: rfl.Type) -> R:
|
43
|
+
check.isinstance(rty, rfl.TYPES)
|
44
|
+
try:
|
45
|
+
return self._dct[rty]
|
46
|
+
except KeyError:
|
47
|
+
pass
|
48
|
+
p, sp = self._prx()
|
49
|
+
self._dct[rty] = p
|
50
|
+
try:
|
51
|
+
r = self._f(ctx, rty)
|
52
|
+
sp(r)
|
53
|
+
return r
|
54
|
+
finally:
|
55
|
+
del self._dct[rty]
|
56
|
+
|
57
|
+
|
58
|
+
##
|
59
|
+
|
60
|
+
|
61
|
+
class _Proxy(ta.Generic[T]):
|
62
|
+
__obj: T | None = None
|
63
|
+
|
64
|
+
@property
|
65
|
+
def _obj(self) -> T:
|
66
|
+
if self.__obj is None:
|
67
|
+
raise TypeError('recursive proxy not set')
|
68
|
+
return self.__obj
|
69
|
+
|
70
|
+
def _set_obj(self, obj: T) -> None:
|
71
|
+
if self.__obj is not None:
|
72
|
+
raise TypeError('recursive proxy already set')
|
73
|
+
self.__obj = obj
|
74
|
+
|
75
|
+
@classmethod
|
76
|
+
def _new(cls) -> tuple[ta.Any, ta.Callable[[ta.Any], None]]:
|
77
|
+
return (p := cls()), p._set_obj # noqa
|
78
|
+
|
79
|
+
|
80
|
+
##
|
81
|
+
|
82
|
+
|
83
|
+
class _ProxyMarshaler(_Proxy[Marshaler], Marshaler):
|
84
|
+
def marshal(self, ctx: MarshalContext, o: ta.Any) -> Value:
|
85
|
+
return self._obj.marshal(ctx, o)
|
86
|
+
|
87
|
+
|
88
|
+
class RecursiveMarshalerFactory(MarshalerFactory, lang.Final):
|
89
|
+
def __init__(self, f: MarshalerFactory) -> None:
|
90
|
+
super().__init__()
|
91
|
+
|
92
|
+
self._f = f
|
93
|
+
self._rtf: _RecursiveTypeFactory[MarshalContext, Marshaler] = _RecursiveTypeFactory(
|
94
|
+
self._f.make_marshaler, # noqa
|
95
|
+
_ProxyMarshaler._new, # noqa
|
96
|
+
)
|
97
|
+
|
98
|
+
@property
|
99
|
+
def make_marshaler(self) -> MarshalerMaker:
|
100
|
+
return self._rtf
|
101
|
+
|
102
|
+
|
103
|
+
class _ProxyUnmarshaler(_Proxy[Unmarshaler], Unmarshaler):
|
104
|
+
def unmarshal(self, ctx: UnmarshalContext, v: Value) -> ta.Any:
|
105
|
+
return self._obj.unmarshal(ctx, v)
|
106
|
+
|
107
|
+
|
108
|
+
class RecursiveUnmarshalerFactory(UnmarshalerFactory, lang.Final):
|
109
|
+
def __init__(self, f: UnmarshalerFactory) -> None:
|
110
|
+
super().__init__()
|
111
|
+
|
112
|
+
self._f = f
|
113
|
+
self._rtf: _RecursiveTypeFactory[UnmarshalContext, Unmarshaler] = _RecursiveTypeFactory(
|
114
|
+
self._f.make_unmarshaler, # noqa
|
115
|
+
_ProxyUnmarshaler._new, # noqa
|
116
|
+
)
|
117
|
+
|
118
|
+
@property
|
119
|
+
def make_unmarshaler(self) -> UnmarshalerMaker:
|
120
|
+
return self._rtf
|
@@ -0,0 +1,28 @@
|
|
1
|
+
from ... import lang
|
2
|
+
from ..base.types import MarshalerFactory
|
3
|
+
from ..base.types import MarshalerMaker
|
4
|
+
from ..base.types import UnmarshalerFactory
|
5
|
+
from ..base.types import UnmarshalerMaker
|
6
|
+
|
7
|
+
|
8
|
+
##
|
9
|
+
|
10
|
+
|
11
|
+
class SimpleMarshalerFactory(
|
12
|
+
MarshalerFactory,
|
13
|
+
MarshalerMaker,
|
14
|
+
lang.Abstract,
|
15
|
+
):
|
16
|
+
@property
|
17
|
+
def make_marshaler(self) -> MarshalerMaker:
|
18
|
+
return self # noqa
|
19
|
+
|
20
|
+
|
21
|
+
class SimpleUnmarshalerFactory(
|
22
|
+
UnmarshalerFactory,
|
23
|
+
UnmarshalerMaker,
|
24
|
+
lang.Abstract,
|
25
|
+
):
|
26
|
+
@property
|
27
|
+
def make_unmarshaler(self) -> UnmarshalerMaker:
|
28
|
+
return self # noqa
|