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.
Files changed (66) hide show
  1. omlish/__about__.py +2 -3
  2. omlish/codecs/registry.py +1 -1
  3. omlish/dataclasses/__init__.py +135 -113
  4. omlish/dataclasses/impl/api/classes/make.py +5 -3
  5. omlish/dataclasses/impl/configs.py +29 -29
  6. omlish/lite/maysyncs.py +1 -0
  7. omlish/manifests/base.py +1 -1
  8. omlish/marshal/__init__.py +98 -57
  9. omlish/marshal/base/__init__.py +0 -0
  10. omlish/marshal/base/contexts.py +75 -0
  11. omlish/marshal/{errors.py → base/errors.py} +1 -1
  12. omlish/marshal/base/options.py +2 -0
  13. omlish/marshal/base/overrides.py +25 -0
  14. omlish/marshal/{registries.py → base/registries.py} +4 -8
  15. omlish/marshal/base/types.py +70 -0
  16. omlish/marshal/{values.py → base/values.py} +1 -13
  17. omlish/marshal/composite/iterables.py +7 -7
  18. omlish/marshal/composite/literals.py +7 -7
  19. omlish/marshal/composite/mappings.py +7 -7
  20. omlish/marshal/composite/maybes.py +7 -7
  21. omlish/marshal/composite/newtypes.py +6 -6
  22. omlish/marshal/composite/optionals.py +7 -7
  23. omlish/marshal/composite/special.py +6 -6
  24. omlish/marshal/composite/wrapped.py +5 -5
  25. omlish/marshal/factories/__init__.py +0 -0
  26. omlish/marshal/factories/func.py +28 -0
  27. omlish/marshal/factories/match.py +34 -0
  28. omlish/marshal/factories/multi.py +55 -0
  29. omlish/marshal/factories/recursive.py +120 -0
  30. omlish/marshal/factories/simple.py +28 -0
  31. omlish/marshal/factories/typecache.py +91 -0
  32. omlish/marshal/factories/typemap.py +65 -0
  33. omlish/marshal/globals.py +7 -7
  34. omlish/marshal/naming.py +1 -1
  35. omlish/marshal/objects/dataclasses.py +7 -7
  36. omlish/marshal/objects/marshal.py +4 -4
  37. omlish/marshal/objects/metadata.py +4 -4
  38. omlish/marshal/objects/namedtuples.py +7 -7
  39. omlish/marshal/objects/unmarshal.py +4 -4
  40. omlish/marshal/polymorphism/marshal.py +4 -4
  41. omlish/marshal/polymorphism/metadata.py +1 -1
  42. omlish/marshal/polymorphism/standard.py +2 -2
  43. omlish/marshal/polymorphism/unions.py +7 -7
  44. omlish/marshal/polymorphism/unmarshal.py +4 -4
  45. omlish/marshal/singular/base64.py +7 -7
  46. omlish/marshal/singular/datetimes.py +7 -7
  47. omlish/marshal/singular/enums.py +7 -7
  48. omlish/marshal/singular/numbers.py +7 -7
  49. omlish/marshal/singular/primitives.py +7 -7
  50. omlish/marshal/singular/uuids.py +7 -7
  51. omlish/marshal/standard.py +8 -8
  52. omlish/marshal/trivial/any.py +7 -7
  53. omlish/marshal/trivial/forbidden.py +7 -7
  54. omlish/marshal/trivial/nop.py +5 -5
  55. omlish/subprocesses/maysyncs.py +7 -96
  56. {omlish-0.0.0.dev413.dist-info → omlish-0.0.0.dev415.dist-info}/METADATA +1 -1
  57. {omlish-0.0.0.dev413.dist-info → omlish-0.0.0.dev415.dist-info}/RECORD +61 -53
  58. omlish/inject/.dataclasses.json +0 -3
  59. omlish/marshal/.dataclasses.json +0 -3
  60. omlish/marshal/base.py +0 -472
  61. omlish/marshal/factories.py +0 -116
  62. omlish/marshal/proxy.py +0 -26
  63. {omlish-0.0.0.dev413.dist-info → omlish-0.0.0.dev415.dist-info}/WHEEL +0 -0
  64. {omlish-0.0.0.dev413.dist-info → omlish-0.0.0.dev415.dist-info}/entry_points.txt +0 -0
  65. {omlish-0.0.0.dev413.dist-info → omlish-0.0.0.dev415.dist-info}/licenses/LICENSE +0 -0
  66. {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)
@@ -1,4 +1,4 @@
1
- from .. import reflect as rfl
1
+ from ... import reflect as rfl
2
2
 
3
3
 
4
4
  ##
@@ -0,0 +1,2 @@
1
+ class Option:
2
+ pass
@@ -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 .. import collections as col
10
- from .. import lang
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._mtx = threading.Lock()
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._mtx:
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
@@ -1,19 +1,7 @@
1
- """
2
- Null
3
- Bool
4
- Int
5
- Float
6
- Number
7
- String
8
- Bytes
9
- Array
10
- Object
11
- Any
12
- """
13
1
  import typing as ta
14
2
 
15
3
 
16
- Value = ta.Union[ # noqa
4
+ Value: ta.TypeAlias = ta.Union[ # noqa
17
5
  None,
18
6
 
19
7
  bool,
@@ -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 Marshaler
15
- from ..base import MarshalerFactoryMatchClass
16
- from ..base import UnmarshalContext
17
- from ..base import Unmarshaler
18
- from ..base import UnmarshalerFactoryMatchClass
19
- from ..values import Value
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 Marshaler
8
- from ..base import SimpleMarshalerFactory
9
- from ..base import SimpleUnmarshalerFactory
10
- from ..base import UnmarshalContext
11
- from ..base import Unmarshaler
12
- from ..values import Value
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 Marshaler
10
- from ..base import MarshalerFactoryMatchClass
11
- from ..base import UnmarshalContext
12
- from ..base import Unmarshaler
13
- from ..base import UnmarshalerFactoryMatchClass
14
- from ..values import Value
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 Marshaler
14
- from ..base import MarshalerFactoryMatchClass
15
- from ..base import UnmarshalContext
16
- from ..base import Unmarshaler
17
- from ..base import UnmarshalerFactoryMatchClass
18
- from ..values import Value
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 Marshaler
5
- from ..base import SimpleMarshalerFactory
6
- from ..base import SimpleUnmarshalerFactory
7
- from ..base import UnmarshalContext
8
- from ..base import Unmarshaler
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 Marshaler
8
- from ..base import SimpleMarshalerFactory
9
- from ..base import SimpleUnmarshalerFactory
10
- from ..base import UnmarshalContext
11
- from ..base import Unmarshaler
12
- from ..values import Value
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 Marshaler
9
- from ..base import MarshalerFactoryMatchClass
10
- from ..base import UnmarshalContext
11
- from ..base import Unmarshaler
12
- from ..base import UnmarshalerFactoryMatchClass
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 Marshaler
6
- from ..base import UnmarshalContext
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