omlish 0.0.0.dev453__py3-none-any.whl → 0.0.0.dev454__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 (52) hide show
  1. omlish/__about__.py +2 -2
  2. omlish/collections/identity.py +1 -0
  3. omlish/dataclasses/__init__.py +2 -0
  4. omlish/funcs/guard.py +27 -16
  5. omlish/lang/__init__.py +1 -0
  6. omlish/lang/iterables.py +8 -0
  7. omlish/lite/attrops.py +2 -0
  8. omlish/lite/dataclasses.py +30 -0
  9. omlish/marshal/__init__.py +12 -11
  10. omlish/marshal/base/contexts.py +4 -7
  11. omlish/marshal/base/funcs.py +16 -11
  12. omlish/marshal/base/types.py +17 -7
  13. omlish/marshal/composite/iterables.py +31 -20
  14. omlish/marshal/composite/literals.py +14 -18
  15. omlish/marshal/composite/mappings.py +34 -23
  16. omlish/marshal/composite/maybes.py +27 -19
  17. omlish/marshal/composite/newtypes.py +14 -14
  18. omlish/marshal/composite/optionals.py +12 -14
  19. omlish/marshal/composite/special.py +13 -13
  20. omlish/marshal/composite/unions/__init__.py +0 -0
  21. omlish/marshal/composite/unions/literals.py +91 -0
  22. omlish/marshal/composite/unions/primitives.py +101 -0
  23. omlish/marshal/factories/invalidate.py +16 -66
  24. omlish/marshal/factories/method.py +28 -0
  25. omlish/marshal/factories/moduleimport/factories.py +13 -54
  26. omlish/marshal/factories/multi.py +11 -23
  27. omlish/marshal/factories/recursive.py +40 -56
  28. omlish/marshal/factories/typecache.py +23 -75
  29. omlish/marshal/factories/typemap.py +40 -41
  30. omlish/marshal/objects/dataclasses.py +106 -97
  31. omlish/marshal/objects/marshal.py +15 -12
  32. omlish/marshal/objects/namedtuples.py +46 -40
  33. omlish/marshal/objects/unmarshal.py +16 -13
  34. omlish/marshal/polymorphism/marshal.py +6 -9
  35. omlish/marshal/polymorphism/unions.py +15 -9
  36. omlish/marshal/polymorphism/unmarshal.py +6 -8
  37. omlish/marshal/singular/enums.py +12 -18
  38. omlish/marshal/standard.py +8 -8
  39. omlish/marshal/trivial/forbidden.py +19 -24
  40. omlish/os/forkhooks.py +4 -0
  41. omlish/specs/jsonrpc/_marshal.py +33 -24
  42. omlish/specs/openapi/_marshal.py +20 -17
  43. omlish/typedvalues/marshal.py +81 -55
  44. {omlish-0.0.0.dev453.dist-info → omlish-0.0.0.dev454.dist-info}/METADATA +1 -1
  45. {omlish-0.0.0.dev453.dist-info → omlish-0.0.0.dev454.dist-info}/RECORD +49 -48
  46. omlish/marshal/composite/unions.py +0 -213
  47. omlish/marshal/factories/match.py +0 -34
  48. omlish/marshal/factories/simple.py +0 -28
  49. {omlish-0.0.0.dev453.dist-info → omlish-0.0.0.dev454.dist-info}/WHEEL +0 -0
  50. {omlish-0.0.0.dev453.dist-info → omlish-0.0.0.dev454.dist-info}/entry_points.txt +0 -0
  51. {omlish-0.0.0.dev453.dist-info → omlish-0.0.0.dev454.dist-info}/licenses/LICENSE +0 -0
  52. {omlish-0.0.0.dev453.dist-info → omlish-0.0.0.dev454.dist-info}/top_level.txt +0 -0
@@ -13,11 +13,12 @@ from ... import reflect as rfl
13
13
  from ...lite import marshal as lm
14
14
  from ..base.contexts import MarshalContext
15
15
  from ..base.contexts import UnmarshalContext
16
+ from ..base.errors import UnhandledTypeError
16
17
  from ..base.options import Option
17
18
  from ..base.types import Marshaler
19
+ from ..base.types import MarshalerFactory
18
20
  from ..base.types import Unmarshaler
19
- from ..factories.simple import SimpleMarshalerFactory
20
- from ..factories.simple import SimpleUnmarshalerFactory
21
+ from ..base.types import UnmarshalerFactory
21
22
  from ..naming import Naming
22
23
  from ..naming import translate_name
23
24
  from .marshal import ObjectMarshaler
@@ -169,7 +170,9 @@ def _make_field_obj(
169
170
  if obj is not None:
170
171
  return obj
171
172
  if fac is not None:
172
- return getattr(fac, fac_attr)(ctx, ty)
173
+ if (m := getattr(fac, fac_attr)(ctx, ty)) is None:
174
+ raise UnhandledTypeError(ty)
175
+ return m()
173
176
  return ctx.make(ty)
174
177
 
175
178
 
@@ -200,119 +203,125 @@ def _type_or_generic_base(rty: rfl.Type) -> type | None:
200
203
  return None
201
204
 
202
205
 
203
- class DataclassMarshalerFactory(AbstractDataclassFactory, SimpleMarshalerFactory):
204
- def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
205
- return (
206
+ class DataclassMarshalerFactory(AbstractDataclassFactory, MarshalerFactory):
207
+ def make_marshaler(self, ctx: MarshalContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
208
+ if not (
206
209
  (ty := _type_or_generic_base(rty)) is not None and
207
210
  dc.is_dataclass(ty) and
208
211
  not lang.is_abstract_class(ty)
209
- )
212
+ ):
213
+ return None
214
+
215
+ def inner() -> Marshaler:
216
+ ty = check.isinstance(_type_or_generic_base(rty), type)
217
+ check.state(dc.is_dataclass(ty))
218
+ check.state(not lang.is_abstract_class(ty))
219
+
220
+ dc_md = self._get_metadata(ty)
221
+ fis = self._get_field_infos(ty, ctx.options)
210
222
 
211
- def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
212
- ty = check.isinstance(_type_or_generic_base(rty), type)
213
- check.state(dc.is_dataclass(ty))
214
- check.state(not lang.is_abstract_class(ty))
215
-
216
- dc_md = self._get_metadata(ty)
217
- fis = self._get_field_infos(ty, ctx.options)
218
-
219
- fields = [
220
- (
221
- fi,
222
- _make_field_obj(
223
- ctx,
224
- fi.type,
225
- fi.metadata.marshaler,
226
- fi.metadata.marshaler_factory,
227
- 'make_marshaler',
228
- ),
223
+ fields = [
224
+ (
225
+ fi,
226
+ _make_field_obj(
227
+ ctx,
228
+ fi.type,
229
+ fi.metadata.marshaler,
230
+ fi.metadata.marshaler_factory,
231
+ 'make_marshaler',
232
+ ),
233
+ )
234
+ for fi in fis
235
+ if fi.name not in dc_md.specials.set
236
+ ]
237
+
238
+ return ObjectMarshaler(
239
+ fields,
240
+ specials=dc_md.specials,
229
241
  )
230
- for fi in fis
231
- if fi.name not in dc_md.specials.set
232
- ]
233
242
 
234
- return ObjectMarshaler(
235
- fields,
236
- specials=dc_md.specials,
237
- )
243
+ return inner
238
244
 
239
245
 
240
246
  ##
241
247
 
242
248
 
243
- class DataclassUnmarshalerFactory(AbstractDataclassFactory, SimpleUnmarshalerFactory):
244
- def guard(self, ctx: UnmarshalContext, rty: rfl.Type) -> bool:
245
- return (
249
+ class DataclassUnmarshalerFactory(AbstractDataclassFactory, UnmarshalerFactory):
250
+ def make_unmarshaler(self, ctx: UnmarshalContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
251
+ if not (
246
252
  (ty := _type_or_generic_base(rty)) is not None and
247
253
  dc.is_dataclass(ty) and
248
254
  not lang.is_abstract_class(ty)
249
- )
255
+ ):
256
+ return None
250
257
 
251
- def fn(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
252
- ty = check.isinstance(_type_or_generic_base(rty), type)
253
- check.state(dc.is_dataclass(ty))
254
- check.state(not lang.is_abstract_class(ty))
258
+ def inner() -> Unmarshaler:
259
+ ty = check.isinstance(_type_or_generic_base(rty), type)
260
+ check.state(dc.is_dataclass(ty))
261
+ check.state(not lang.is_abstract_class(ty))
255
262
 
256
- dc_md = self._get_metadata(ty)
257
- fis = self._get_field_infos(ty, ctx.options)
263
+ dc_md = self._get_metadata(ty)
264
+ fis = self._get_field_infos(ty, ctx.options)
258
265
 
259
- d: dict[str, tuple[FieldInfo, Unmarshaler]] = {}
260
- defaults: dict[str, ta.Any] = {}
261
- embeds: dict[str, type] = {}
262
- embeds_by_unmarshal_name: dict[str, tuple[str, str]] = {}
266
+ d: dict[str, tuple[FieldInfo, Unmarshaler]] = {}
267
+ defaults: dict[str, ta.Any] = {}
268
+ embeds: dict[str, type] = {}
269
+ embeds_by_unmarshal_name: dict[str, tuple[str, str]] = {}
263
270
 
264
- def add_field(fi: FieldInfo, *, prefixes: ta.Iterable[str] = ('',)) -> ta.Iterable[str]:
265
- ret: list[str] = []
271
+ def add_field(fi: FieldInfo, *, prefixes: ta.Iterable[str] = ('',)) -> ta.Iterable[str]:
272
+ ret: list[str] = []
266
273
 
267
- if fi.options.embed:
268
- e_ty = check.isinstance(fi.type, type)
269
- check.state(dc.is_dataclass(e_ty))
270
- e_dc_md = get_dataclass_metadata(e_ty)
271
- if e_dc_md.specials.set:
272
- raise Exception(f'Embedded fields cannot have specials: {e_ty}')
274
+ if fi.options.embed:
275
+ e_ty = check.isinstance(fi.type, type)
276
+ check.state(dc.is_dataclass(e_ty))
277
+ e_dc_md = get_dataclass_metadata(e_ty)
278
+ if e_dc_md.specials.set:
279
+ raise Exception(f'Embedded fields cannot have specials: {e_ty}')
273
280
 
274
- embeds[fi.name] = e_ty
275
- for e_fi in self._get_field_infos(e_ty, ctx.options):
276
- e_ns = add_field(e_fi, prefixes=[p + ep for p in prefixes for ep in fi.unmarshal_names])
277
- embeds_by_unmarshal_name.update({e_f: (fi.name, e_fi.name) for e_f in e_ns})
278
- ret.extend(e_ns)
281
+ embeds[fi.name] = e_ty
282
+ for e_fi in self._get_field_infos(e_ty, ctx.options):
283
+ e_ns = add_field(e_fi, prefixes=[p + ep for p in prefixes for ep in fi.unmarshal_names])
284
+ embeds_by_unmarshal_name.update({e_f: (fi.name, e_fi.name) for e_f in e_ns})
285
+ ret.extend(e_ns)
279
286
 
280
- else:
281
- tup = (
282
- fi,
283
- _make_field_obj(
284
- ctx,
285
- fi.type,
286
- fi.metadata.unmarshaler,
287
- fi.metadata.unmarshaler_factory,
288
- 'make_unmarshaler',
289
- ),
290
- )
287
+ else:
288
+ tup = (
289
+ fi,
290
+ _make_field_obj(
291
+ ctx,
292
+ fi.type,
293
+ fi.metadata.unmarshaler,
294
+ fi.metadata.unmarshaler_factory,
295
+ 'make_unmarshaler',
296
+ ),
297
+ )
291
298
 
292
- for pfx in prefixes:
293
- for un in fi.unmarshal_names:
294
- un = pfx + un
295
- if un in d:
296
- raise KeyError(f'Duplicate fields for name {un!r}: {fi.name!r}, {d[un][0].name!r}')
297
- d[un] = tup
298
- ret.append(un)
299
-
300
- if fi.options.default.present:
301
- defaults[fi.name] = fi.options.default.must()
302
-
303
- return ret
304
-
305
- for fi in fis:
306
- if fi.name in dc_md.specials.set:
307
- continue
308
- add_field(fi)
309
-
310
- return ObjectUnmarshaler(
311
- ty,
312
- d,
313
- specials=dc_md.specials,
314
- defaults=defaults,
315
- embeds=embeds,
316
- embeds_by_unmarshal_name=embeds_by_unmarshal_name,
317
- ignore_unknown=dc_md.ignore_unknown,
318
- )
299
+ for pfx in prefixes:
300
+ for un in fi.unmarshal_names:
301
+ un = pfx + un
302
+ if un in d:
303
+ raise KeyError(f'Duplicate fields for name {un!r}: {fi.name!r}, {d[un][0].name!r}')
304
+ d[un] = tup
305
+ ret.append(un)
306
+
307
+ if fi.options.default.present:
308
+ defaults[fi.name] = fi.options.default.must()
309
+
310
+ return ret
311
+
312
+ for fi in fis:
313
+ if fi.name in dc_md.specials.set:
314
+ continue
315
+ add_field(fi)
316
+
317
+ return ObjectUnmarshaler(
318
+ ty,
319
+ d,
320
+ specials=dc_md.specials,
321
+ defaults=defaults,
322
+ embeds=embeds,
323
+ embeds_by_unmarshal_name=embeds_by_unmarshal_name,
324
+ ignore_unknown=dc_md.ignore_unknown,
325
+ )
326
+
327
+ return inner
@@ -6,8 +6,8 @@ from ... import dataclasses as dc
6
6
  from ... import reflect as rfl
7
7
  from ..base.contexts import MarshalContext
8
8
  from ..base.types import Marshaler
9
+ from ..base.types import MarshalerFactory
9
10
  from ..base.values import Value
10
- from ..factories.simple import SimpleMarshalerFactory
11
11
  from .metadata import FieldInfo
12
12
  from .metadata import FieldInfos
13
13
  from .metadata import ObjectSpecials
@@ -86,23 +86,26 @@ class ObjectMarshaler(Marshaler):
86
86
 
87
87
 
88
88
  @dc.dataclass(frozen=True)
89
- class SimpleObjectMarshalerFactory(SimpleMarshalerFactory):
89
+ class SimpleObjectMarshalerFactory(MarshalerFactory):
90
90
  dct: ta.Mapping[type, ta.Sequence[FieldInfo]]
91
91
 
92
92
  _: dc.KW_ONLY
93
93
 
94
94
  specials: ObjectSpecials = ObjectSpecials()
95
95
 
96
- def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
97
- return isinstance(rty, type) and rty in self.dct
96
+ def make_marshaler(self, ctx: MarshalContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
97
+ if not (isinstance(rty, type) and rty in self.dct):
98
+ return None
98
99
 
99
- def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
100
- ty = check.isinstance(rty, type)
100
+ def inner() -> Marshaler:
101
+ ty = check.isinstance(rty, type)
101
102
 
102
- fis = FieldInfos(self.dct[ty])
103
+ fis = FieldInfos(self.dct[ty])
103
104
 
104
- return ObjectMarshaler.make(
105
- ctx,
106
- fis,
107
- specials=self.specials,
108
- )
105
+ return ObjectMarshaler.make(
106
+ ctx,
107
+ fis,
108
+ specials=self.specials,
109
+ )
110
+
111
+ return inner
@@ -9,9 +9,9 @@ from ..base.contexts import MarshalContext
9
9
  from ..base.contexts import UnmarshalContext
10
10
  from ..base.options import Option
11
11
  from ..base.types import Marshaler
12
+ from ..base.types import MarshalerFactory
12
13
  from ..base.types import Unmarshaler
13
- from ..factories.simple import SimpleMarshalerFactory
14
- from ..factories.simple import SimpleUnmarshalerFactory
14
+ from ..base.types import UnmarshalerFactory
15
15
  from .marshal import ObjectMarshaler
16
16
  from .metadata import FieldInfo
17
17
  from .metadata import FieldInfos
@@ -55,57 +55,63 @@ def get_namedtuple_field_infos(
55
55
  ##
56
56
 
57
57
 
58
- class NamedtupleMarshalerFactory(SimpleMarshalerFactory):
59
- def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
60
- return _is_namedtuple(rty)
58
+ class NamedtupleMarshalerFactory(MarshalerFactory):
59
+ def make_marshaler(self, ctx: MarshalContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
60
+ if not _is_namedtuple(rty):
61
+ return None
61
62
 
62
- def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
63
- check.state(_is_namedtuple(rty))
64
- ty = check.isinstance(rty, type)
65
- check.state(not lang.is_abstract_class(ty))
63
+ def inner() -> Marshaler:
64
+ check.state(_is_namedtuple(rty))
65
+ ty = check.isinstance(rty, type)
66
+ check.state(not lang.is_abstract_class(ty))
66
67
 
67
- fis = get_namedtuple_field_infos(ty, ctx.options)
68
+ fis = get_namedtuple_field_infos(ty, ctx.options)
68
69
 
69
- fields = [
70
- (fi, ctx.make(fi.type))
71
- for fi in fis
72
- ]
70
+ fields = [
71
+ (fi, ctx.make(fi.type))
72
+ for fi in fis
73
+ ]
73
74
 
74
- return ObjectMarshaler(
75
- fields,
76
- )
75
+ return ObjectMarshaler(
76
+ fields,
77
+ )
78
+
79
+ return inner
77
80
 
78
81
 
79
82
  ##
80
83
 
81
84
 
82
- class NamedtupleUnmarshalerFactory(SimpleUnmarshalerFactory):
83
- def guard(self, ctx: UnmarshalContext, rty: rfl.Type) -> bool:
84
- return _is_namedtuple(rty)
85
+ class NamedtupleUnmarshalerFactory(UnmarshalerFactory):
86
+ def make_unmarshaler(self, ctx: UnmarshalContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
87
+ if not _is_namedtuple(rty):
88
+ return None
89
+
90
+ def inner() -> Unmarshaler:
91
+ check.state(_is_namedtuple(rty))
92
+ ty = check.isinstance(rty, type)
93
+ check.state(not lang.is_abstract_class(ty))
85
94
 
86
- def fn(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
87
- check.state(_is_namedtuple(rty))
88
- ty = check.isinstance(rty, type)
89
- check.state(not lang.is_abstract_class(ty))
95
+ fis = get_namedtuple_field_infos(ty, ctx.options)
90
96
 
91
- fis = get_namedtuple_field_infos(ty, ctx.options)
97
+ d: dict[str, tuple[FieldInfo, Unmarshaler]] = {}
98
+ defaults: dict[str, ta.Any] = {}
92
99
 
93
- d: dict[str, tuple[FieldInfo, Unmarshaler]] = {}
94
- defaults: dict[str, ta.Any] = {}
100
+ for fi in fis:
101
+ tup = (fi, ctx.make(fi.type))
95
102
 
96
- for fi in fis:
97
- tup = (fi, ctx.make(fi.type))
103
+ for un in fi.unmarshal_names:
104
+ if un in d:
105
+ raise KeyError(f'Duplicate fields for name {un!r}: {fi.name!r}, {d[un][0].name!r}')
106
+ d[un] = tup
98
107
 
99
- for un in fi.unmarshal_names:
100
- if un in d:
101
- raise KeyError(f'Duplicate fields for name {un!r}: {fi.name!r}, {d[un][0].name!r}')
102
- d[un] = tup
108
+ if fi.options.default.present:
109
+ defaults[fi.name] = fi.options.default.must()
103
110
 
104
- if fi.options.default.present:
105
- defaults[fi.name] = fi.options.default.must()
111
+ return ObjectUnmarshaler(
112
+ ty,
113
+ d,
114
+ defaults=defaults,
115
+ )
106
116
 
107
- return ObjectUnmarshaler(
108
- ty,
109
- d,
110
- defaults=defaults,
111
- )
117
+ return inner
@@ -6,8 +6,8 @@ from ... import dataclasses as dc
6
6
  from ... import reflect as rfl
7
7
  from ..base.contexts import UnmarshalContext
8
8
  from ..base.types import Unmarshaler
9
+ from ..base.types import UnmarshalerFactory
9
10
  from ..base.values import Value
10
- from ..factories.simple import SimpleUnmarshalerFactory
11
11
  from .metadata import FieldInfo
12
12
  from .metadata import FieldInfos
13
13
  from .metadata import ObjectSpecials
@@ -118,24 +118,27 @@ class ObjectUnmarshaler(Unmarshaler):
118
118
 
119
119
 
120
120
  @dc.dataclass(frozen=True)
121
- class SimpleObjectUnmarshalerFactory(SimpleUnmarshalerFactory):
121
+ class SimpleObjectUnmarshalerFactory(UnmarshalerFactory):
122
122
  dct: ta.Mapping[type, ta.Sequence[FieldInfo]]
123
123
 
124
124
  _: dc.KW_ONLY
125
125
 
126
126
  specials: ObjectSpecials = ObjectSpecials()
127
127
 
128
- def guard(self, ctx: UnmarshalContext, rty: rfl.Type) -> bool:
129
- return isinstance(rty, type) and rty in self.dct
128
+ def make_unmarshaler(self, ctx: UnmarshalContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
129
+ if not (isinstance(rty, type) and rty in self.dct):
130
+ return None
130
131
 
131
- def fn(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
132
- ty = check.isinstance(rty, type)
132
+ def inner() -> Unmarshaler:
133
+ ty = check.isinstance(rty, type)
133
134
 
134
- fis = FieldInfos(self.dct[ty])
135
+ fis = FieldInfos(self.dct[ty])
135
136
 
136
- return ObjectUnmarshaler.make(
137
- ctx,
138
- ty,
139
- fis,
140
- specials=self.specials,
141
- )
137
+ return ObjectUnmarshaler.make(
138
+ ctx,
139
+ ty,
140
+ fis,
141
+ specials=self.specials,
142
+ )
143
+
144
+ return inner
@@ -2,13 +2,12 @@ import abc
2
2
  import dataclasses as dc
3
3
  import typing as ta
4
4
 
5
- from ... import check
6
5
  from ... import lang
7
6
  from ... import reflect as rfl
8
7
  from ..base.contexts import MarshalContext
9
8
  from ..base.types import Marshaler
9
+ from ..base.types import MarshalerFactory
10
10
  from ..base.values import Value
11
- from ..factories.simple import SimpleMarshalerFactory
12
11
  from .metadata import FieldTypeTagging
13
12
  from .metadata import Impls
14
13
  from .metadata import Polymorphism
@@ -68,13 +67,11 @@ def make_polymorphism_marshaler(
68
67
 
69
68
 
70
69
  @dc.dataclass(frozen=True)
71
- class PolymorphismMarshalerFactory(SimpleMarshalerFactory):
70
+ class PolymorphismMarshalerFactory(MarshalerFactory):
72
71
  p: Polymorphism
73
72
  tt: TypeTagging = WrapperTypeTagging()
74
73
 
75
- def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
76
- return rty is self.p.ty
77
-
78
- def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
79
- check.is_(rty, self.p.ty)
80
- return make_polymorphism_marshaler(self.p.impls, self.tt, ctx)
74
+ def make_marshaler(self, ctx: MarshalContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
75
+ if rty is not self.p.ty:
76
+ return None
77
+ return lambda: make_polymorphism_marshaler(self.p.impls, self.tt, ctx)
@@ -1,3 +1,5 @@
1
+ import typing as ta
2
+
1
3
  from ... import cached
2
4
  from ... import check
3
5
  from ... import dataclasses as dc
@@ -6,9 +8,9 @@ from ... import reflect as rfl
6
8
  from ..base.contexts import MarshalContext
7
9
  from ..base.contexts import UnmarshalContext
8
10
  from ..base.types import Marshaler
11
+ from ..base.types import MarshalerFactory
9
12
  from ..base.types import Unmarshaler
10
- from ..factories.simple import SimpleMarshalerFactory
11
- from ..factories.simple import SimpleUnmarshalerFactory
13
+ from ..base.types import UnmarshalerFactory
12
14
  from .marshal import make_polymorphism_marshaler
13
15
  from .metadata import Impls
14
16
  from .metadata import TypeTagging
@@ -30,7 +32,7 @@ class _BasePolymorphismUnionFactory(lang.Abstract):
30
32
  def rtys(self) -> frozenset[rfl.Type]:
31
33
  return frozenset(i.ty for i in self.impls)
32
34
 
33
- def guard(self, ctx: MarshalContext | UnmarshalContext, rty: rfl.Type) -> bool:
35
+ def _guard(self, ctx: MarshalContext | UnmarshalContext, rty: rfl.Type) -> bool:
34
36
  if not isinstance(rty, rfl.Union):
35
37
  return False
36
38
  if self.allow_partial:
@@ -44,12 +46,16 @@ class _BasePolymorphismUnionFactory(lang.Abstract):
44
46
 
45
47
 
46
48
  @dc.dataclass(frozen=True)
47
- class PolymorphismUnionMarshalerFactory(_BasePolymorphismUnionFactory, SimpleMarshalerFactory):
48
- def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
49
- return make_polymorphism_marshaler(self.get_impls(rty), self.tt, ctx)
49
+ class PolymorphismUnionMarshalerFactory(_BasePolymorphismUnionFactory, MarshalerFactory):
50
+ def make_marshaler(self, ctx: MarshalContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
51
+ if not self._guard(ctx, rty):
52
+ return None
53
+ return lambda: make_polymorphism_marshaler(self.get_impls(rty), self.tt, ctx)
50
54
 
51
55
 
52
56
  @dc.dataclass(frozen=True)
53
- class PolymorphismUnionUnmarshalerFactory(_BasePolymorphismUnionFactory, SimpleUnmarshalerFactory):
54
- def fn(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
55
- return make_polymorphism_unmarshaler(self.get_impls(rty), self.tt, ctx)
57
+ class PolymorphismUnionUnmarshalerFactory(_BasePolymorphismUnionFactory, UnmarshalerFactory):
58
+ def make_unmarshaler(self, ctx: UnmarshalContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
59
+ if not self._guard(ctx, rty):
60
+ return None
61
+ return lambda: make_polymorphism_unmarshaler(self.get_impls(rty), self.tt, ctx)
@@ -8,8 +8,8 @@ from ... import lang
8
8
  from ... import reflect as rfl
9
9
  from ..base.contexts import UnmarshalContext
10
10
  from ..base.types import Unmarshaler
11
+ from ..base.types import UnmarshalerFactory
11
12
  from ..base.values import Value
12
- from ..factories.simple import SimpleUnmarshalerFactory
13
13
  from .metadata import FieldTypeTagging
14
14
  from .metadata import Impls
15
15
  from .metadata import Polymorphism
@@ -75,13 +75,11 @@ def make_polymorphism_unmarshaler(
75
75
 
76
76
 
77
77
  @dc.dataclass(frozen=True)
78
- class PolymorphismUnmarshalerFactory(SimpleUnmarshalerFactory):
78
+ class PolymorphismUnmarshalerFactory(UnmarshalerFactory):
79
79
  p: Polymorphism
80
80
  tt: TypeTagging = WrapperTypeTagging()
81
81
 
82
- def guard(self, ctx: UnmarshalContext, rty: rfl.Type) -> bool:
83
- return rty is self.p.ty
84
-
85
- def fn(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
86
- check.is_(rty, self.p.ty)
87
- return make_polymorphism_unmarshaler(self.p.impls, self.tt, ctx)
82
+ def make_unmarshaler(self, ctx: UnmarshalContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
83
+ if rty is not self.p.ty:
84
+ return None
85
+ return lambda: make_polymorphism_unmarshaler(self.p.impls, self.tt, ctx)
@@ -7,10 +7,10 @@ from ... import reflect as rfl
7
7
  from ..base.contexts import MarshalContext
8
8
  from ..base.contexts import UnmarshalContext
9
9
  from ..base.types import Marshaler
10
+ from ..base.types import MarshalerFactory
10
11
  from ..base.types import Unmarshaler
12
+ from ..base.types import UnmarshalerFactory
11
13
  from ..base.values import Value
12
- from ..factories.simple import SimpleMarshalerFactory
13
- from ..factories.simple import SimpleUnmarshalerFactory
14
14
 
15
15
 
16
16
  ##
@@ -24,14 +24,11 @@ class EnumMarshaler(Marshaler):
24
24
  return o.name
25
25
 
26
26
 
27
- class EnumMarshalerFactory(SimpleMarshalerFactory):
28
- def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
29
- return isinstance(rty, type) and issubclass(rty, enum.Enum)
30
-
31
- def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
32
- ty = check.isinstance(rty, type)
33
- check.state(issubclass(ty, enum.Enum))
34
- return EnumMarshaler(ty) # noqa
27
+ class EnumMarshalerFactory(MarshalerFactory):
28
+ def make_marshaler(self, ctx: MarshalContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
29
+ if not (isinstance(rty, type) and issubclass(rty, enum.Enum)):
30
+ return None
31
+ return lambda: EnumMarshaler(rty) # noqa
35
32
 
36
33
 
37
34
  @dc.dataclass(frozen=True)
@@ -42,11 +39,8 @@ class EnumUnmarshaler(Unmarshaler):
42
39
  return self.ty[check.isinstance(v, str)]
43
40
 
44
41
 
45
- class EnumUnmarshalerFactory(SimpleUnmarshalerFactory):
46
- def guard(self, ctx: UnmarshalContext, rty: rfl.Type) -> bool:
47
- return isinstance(rty, type) and issubclass(rty, enum.Enum)
48
-
49
- def fn(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
50
- ty = check.isinstance(rty, type)
51
- check.state(issubclass(ty, enum.Enum))
52
- return EnumUnmarshaler(ty)
42
+ class EnumUnmarshalerFactory(UnmarshalerFactory):
43
+ def make_unmarshaler(self, ctx: UnmarshalContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
44
+ if not (isinstance(rty, type) and issubclass(rty, enum.Enum)):
45
+ return None
46
+ return lambda: EnumUnmarshaler(rty) # noqa