omlish 0.0.0.dev416__py3-none-any.whl → 0.0.0.dev418__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 (44) hide show
  1. omlish/__about__.py +2 -2
  2. omlish/bootstrap/__init__.py +2 -2
  3. omlish/dataclasses/__init__.py +23 -13
  4. omlish/dataclasses/impl/configs.py +1 -1
  5. omlish/dataclasses/impl/processing/base.py +1 -1
  6. omlish/inject/__init__.py +12 -0
  7. omlish/marshal/__init__.py +229 -202
  8. omlish/marshal/base/configs.py +18 -0
  9. omlish/marshal/base/contexts.py +8 -7
  10. omlish/marshal/base/funcs.py +57 -0
  11. omlish/marshal/base/overrides.py +11 -6
  12. omlish/marshal/base/registries.py +58 -14
  13. omlish/marshal/base/types.py +4 -26
  14. omlish/marshal/factories/invalidate.py +118 -0
  15. omlish/marshal/factories/moduleimport/__init__.py +0 -0
  16. omlish/marshal/factories/moduleimport/configs.py +26 -0
  17. omlish/marshal/factories/moduleimport/factories.py +114 -0
  18. omlish/marshal/factories/typecache.py +24 -4
  19. omlish/marshal/globals.py +28 -13
  20. omlish/marshal/objects/dataclasses.py +29 -4
  21. omlish/marshal/polymorphism/metadata.py +2 -2
  22. omlish/marshal/standard.py +132 -65
  23. omlish/secrets/all.py +0 -9
  24. omlish/secrets/secrets.py +4 -6
  25. omlish/specs/jsonrpc/__init__.py +2 -2
  26. omlish/specs/jsonschema/__init__.py +2 -2
  27. omlish/specs/openapi/__init__.py +2 -2
  28. omlish/sql/queries/__init__.py +4 -2
  29. omlish/sql/tabledefs/__init__.py +2 -2
  30. omlish/text/templating.py +9 -7
  31. omlish/typedvalues/__init__.py +41 -34
  32. {omlish-0.0.0.dev416.dist-info → omlish-0.0.0.dev418.dist-info}/METADATA +1 -1
  33. {omlish-0.0.0.dev416.dist-info → omlish-0.0.0.dev418.dist-info}/RECORD +43 -38
  34. omlish/marshal/factories/func.py +0 -28
  35. /omlish/bootstrap/{marshal.py → _marshal.py} +0 -0
  36. /omlish/specs/jsonrpc/{marshal.py → _marshal.py} +0 -0
  37. /omlish/specs/jsonschema/{marshal.py → _marshal.py} +0 -0
  38. /omlish/specs/openapi/{marshal.py → _marshal.py} +0 -0
  39. /omlish/sql/queries/{marshal.py → _marshal.py} +0 -0
  40. /omlish/sql/tabledefs/{marshal.py → _marshal.py} +0 -0
  41. {omlish-0.0.0.dev416.dist-info → omlish-0.0.0.dev418.dist-info}/WHEEL +0 -0
  42. {omlish-0.0.0.dev416.dist-info → omlish-0.0.0.dev418.dist-info}/entry_points.txt +0 -0
  43. {omlish-0.0.0.dev416.dist-info → omlish-0.0.0.dev418.dist-info}/licenses/LICENSE +0 -0
  44. {omlish-0.0.0.dev416.dist-info → omlish-0.0.0.dev418.dist-info}/top_level.txt +0 -0
@@ -1,9 +1,10 @@
1
+ import dataclasses as dc
1
2
  import typing as ta
2
3
 
3
- from ... import dataclasses as dc
4
+ from ... import check
4
5
  from ... import lang
5
6
  from ... import reflect as rfl
6
- from .registries import RegistryItem
7
+ from .configs import Config
7
8
 
8
9
 
9
10
  if ta.TYPE_CHECKING:
@@ -21,14 +22,18 @@ else:
21
22
 
22
23
 
23
24
  @dc.dataclass(frozen=True, kw_only=True)
24
- class Override(RegistryItem, lang.Final):
25
- marshaler: ta.Optional['Marshaler'] = dc.xfield(None, validate=lambda v: isinstance(v, (_types.Marshaler, type(None)))) # noqa
25
+ class Override(Config, lang.Final):
26
+ marshaler: ta.Optional['Marshaler'] = None
26
27
  marshaler_factory: ta.Optional['MarshalerFactory'] = None
27
28
 
28
- unmarshaler: ta.Optional['Unmarshaler'] = dc.xfield(None, validate=lambda v: isinstance(v, (_types.Unmarshaler, type(None)))) # noqa
29
+ unmarshaler: ta.Optional['Unmarshaler'] = None
29
30
  unmarshaler_factory: ta.Optional['UnmarshalerFactory'] = None
30
31
 
32
+ def __post_init__(self) -> None:
33
+ check.isinstance(self.marshaler, (_types.Marshaler, None))
34
+ check.isinstance(self.unmarshaler, (_types.Unmarshaler, None))
35
+
31
36
 
32
37
  @dc.dataclass(frozen=True)
33
- class ReflectOverride(RegistryItem, lang.Final):
38
+ class ReflectOverride(Config, lang.Final):
34
39
  rty: rfl.Type
@@ -1,3 +1,8 @@
1
+ """
2
+ TODO:
3
+ - col.TypeMap?
4
+ - at least get_any
5
+ """
1
6
  import dataclasses as dc
2
7
  import threading
3
8
  import typing as ta
@@ -14,21 +19,26 @@ class RegistryItem(lang.Abstract):
14
19
 
15
20
 
16
21
  RegistryItemT = ta.TypeVar('RegistryItemT', bound=RegistryItem)
22
+ RegistryItemU = ta.TypeVar('RegistryItemU', bound=RegistryItem)
17
23
 
18
24
 
19
25
  @dc.dataclass(frozen=True)
20
- class _KeyRegistryItems:
26
+ class _KeyRegistryItems(ta.Generic[RegistryItemT]):
21
27
  key: ta.Any
22
- items: list[RegistryItem] = dc.field(default_factory=list)
23
- item_lists_by_ty: dict[type[RegistryItem], list[RegistryItem]] = dc.field(default_factory=dict)
28
+ items: list[RegistryItemT] = dc.field(default_factory=list)
29
+ item_lists_by_ty: dict[type[RegistryItemT], list[RegistryItemT]] = dc.field(default_factory=dict)
24
30
 
25
- def add(self, *items: RegistryItem) -> None:
31
+ def add(self, *items: RegistryItemT) -> None:
26
32
  for i in items:
27
33
  self.items.append(i)
28
34
  self.item_lists_by_ty.setdefault(type(i), []).append(i)
29
35
 
30
36
 
31
- class Registry:
37
+ class RegistrySealedError(Exception):
38
+ pass
39
+
40
+
41
+ class Registry(ta.Generic[RegistryItemT]):
32
42
  def __init__(
33
43
  self,
34
44
  *,
@@ -39,22 +49,54 @@ class Registry:
39
49
  if lock is None:
40
50
  lock = threading.RLock()
41
51
  self._lock = lock
42
- self._idct: ta.MutableMapping[ta.Any, _KeyRegistryItems] = col.IdentityKeyDict()
43
- self._dct: dict[ta.Any, _KeyRegistryItems] = {}
52
+
53
+ self._dct: dict[ta.Any, _KeyRegistryItems[RegistryItemT]] = {}
54
+ self._id_dct: ta.MutableMapping[ta.Any, _KeyRegistryItems[RegistryItemT]] = col.IdentityKeyDict()
55
+
56
+ self._sealed = False
57
+
58
+ #
59
+
60
+ def is_sealed(self) -> bool:
61
+ if self._sealed:
62
+ return True
63
+ with self._lock:
64
+ return self._sealed
65
+
66
+ def seal(self) -> ta.Self:
67
+ if self._sealed:
68
+ raise RegistrySealedError(self)
69
+ with self._lock:
70
+ self._seal()
71
+ return self
72
+
73
+ def _seal(self) -> None:
74
+ if self._sealed:
75
+ raise RegistrySealedError(self)
76
+
77
+ self._sealed = True
78
+
79
+ #
44
80
 
45
81
  def register(
46
82
  self,
47
83
  key: ta.Any,
48
- *items: RegistryItem,
84
+ *items: RegistryItemT,
49
85
  identity: bool = False,
50
- ) -> 'Registry':
86
+ ) -> ta.Self:
51
87
  with self._lock:
52
- dct: ta.Any = self._idct if identity else self._dct
88
+ if self._sealed:
89
+ raise RegistrySealedError(self)
90
+
91
+ dct: ta.Any = self._id_dct if identity else self._dct
53
92
  if (sr := dct.get(key)) is None:
54
93
  sr = dct[key] = _KeyRegistryItems(key)
55
94
  sr.add(*items)
95
+
56
96
  return self
57
97
 
98
+ #
99
+
58
100
  def get(
59
101
  self,
60
102
  key: ta.Any,
@@ -66,7 +108,8 @@ class Registry:
66
108
  *self.get(key, identity=True),
67
109
  *self.get(key, identity=False),
68
110
  )
69
- dct: ta.Any = self._idct if identity else self._dct
111
+
112
+ dct: ta.Any = self._id_dct if identity else self._dct
70
113
  try:
71
114
  return dct[key].items
72
115
  except KeyError:
@@ -75,16 +118,17 @@ class Registry:
75
118
  def get_of(
76
119
  self,
77
120
  key: ta.Any,
78
- item_ty: type[RegistryItemT],
121
+ item_ty: type[RegistryItemU],
79
122
  *,
80
123
  identity: bool | None = None,
81
- ) -> ta.Sequence[RegistryItemT]:
124
+ ) -> ta.Sequence[RegistryItemU]:
82
125
  if identity is None:
83
126
  return (
84
127
  *self.get_of(key, item_ty, identity=True),
85
128
  *self.get_of(key, item_ty, identity=False),
86
129
  )
87
- dct: ta.Any = self._idct if identity else self._dct
130
+
131
+ dct: ta.Any = self._id_dct if identity else self._dct
88
132
  try:
89
133
  sr = dct[key]
90
134
  except KeyError:
@@ -1,13 +1,12 @@
1
1
  import abc
2
2
  import typing as ta
3
3
 
4
- from ... import dataclasses as dc
5
4
  from ... import lang
6
5
  from ... import reflect as rfl
7
6
  from ...funcs import match as mfs
7
+ from .configs import ConfigRegistry
8
8
  from .contexts import MarshalContext
9
9
  from .contexts import UnmarshalContext
10
- from .registries import Registry
11
10
  from .values import Value
12
11
 
13
12
 
@@ -53,30 +52,9 @@ class UnmarshalerFactory(lang.Abstract):
53
52
  ##
54
53
 
55
54
 
56
- @dc.dataclass(frozen=True)
57
- class MarshalerFactory_(MarshalerFactory): # noqa
58
- fn: MarshalerMaker
59
-
60
- @property
61
- def make_marshaler(self) -> MarshalerMaker:
62
- return self.fn
63
-
64
-
65
- @dc.dataclass(frozen=True)
66
- class UnmarshalerFactory_(UnmarshalerFactory): # noqa
67
- fn: UnmarshalerMaker
68
-
69
- @property
70
- def make_unmarshaler(self) -> UnmarshalerMaker:
71
- return self.fn
72
-
73
-
74
- ##
75
-
76
-
77
55
  class Marshaling(lang.Abstract):
78
56
  @abc.abstractmethod
79
- def registry(self) -> Registry:
57
+ def config_registry(self) -> ConfigRegistry:
80
58
  raise NotImplementedError
81
59
 
82
60
  @abc.abstractmethod
@@ -91,14 +69,14 @@ class Marshaling(lang.Abstract):
91
69
 
92
70
  def new_marshal_context(self, **kwargs: ta.Any) -> MarshalContext:
93
71
  return MarshalContext(
94
- self.registry(),
72
+ config_registry=self.config_registry(),
95
73
  factory=self.marshaler_factory(),
96
74
  **kwargs,
97
75
  )
98
76
 
99
77
  def new_unmarshal_context(self, **kwargs: ta.Any) -> UnmarshalContext:
100
78
  return UnmarshalContext(
101
- self.registry(),
79
+ config_registry=self.config_registry(),
102
80
  factory=self.unmarshaler_factory(),
103
81
  **kwargs,
104
82
  )
@@ -0,0 +1,118 @@
1
+ import threading
2
+ import typing as ta
3
+
4
+ from ... import reflect as rfl
5
+ from ...funcs import match as mfs
6
+ from ..base.contexts import BaseContext
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
+
16
+
17
+ R = ta.TypeVar('R')
18
+ ContextT = ta.TypeVar('ContextT', bound=BaseContext)
19
+
20
+
21
+ ##
22
+
23
+
24
+ class _InvalidatableFactory(mfs.MatchFn[[ContextT, rfl.Type], R]):
25
+ def __init__(
26
+ self,
27
+ fn: ta.Callable[[], mfs.MatchFn[[ContextT, rfl.Type], R]],
28
+ check_fn: ta.Callable[[], bool] | None = None,
29
+ ) -> None:
30
+ super().__init__()
31
+
32
+ self._fn = fn
33
+ self._check_fn: ta.Callable[[], bool] | None = check_fn
34
+
35
+ self._lock = threading.RLock()
36
+
37
+ #
38
+
39
+ _f_: mfs.MatchFn[[ContextT, rfl.Type], R] | None = None
40
+
41
+ def _invalidate(self) -> None:
42
+ self._f_ = None
43
+
44
+ def invalidate(self) -> None:
45
+ with self._lock:
46
+ self._invalidate()
47
+
48
+ def _maybe_invalidate(self) -> None:
49
+ if self._check_fn is not None:
50
+ if self._check_fn():
51
+ with self._lock:
52
+ if self._check_fn():
53
+ self._invalidate()
54
+
55
+ def _f(self) -> mfs.MatchFn[[ContextT, rfl.Type], R]:
56
+ self._maybe_invalidate()
57
+
58
+ if (f := self._f_) is None:
59
+ with self._lock:
60
+ if (f := self._f_) is None:
61
+ f = self._f_ = self._fn()
62
+
63
+ return f
64
+
65
+ #
66
+
67
+ def guard(self, ctx: ContextT, rty: rfl.Type) -> bool:
68
+ return self._f().guard(ctx, rty)
69
+
70
+ def fn(self, ctx: ContextT, rty: rfl.Type) -> R:
71
+ return self._f()(ctx, rty)
72
+
73
+
74
+ ##
75
+
76
+
77
+ class InvalidatableMarshalerFactory(MarshalerFactory):
78
+ def __init__(
79
+ self,
80
+ fn: ta.Callable[[], MarshalerFactory],
81
+ check_fn: ta.Callable[[], bool] | None = None,
82
+ ) -> None:
83
+ super().__init__()
84
+
85
+ self._fn = fn
86
+ self._u: _InvalidatableFactory[MarshalContext, Marshaler] = _InvalidatableFactory(
87
+ lambda: fn().make_marshaler,
88
+ check_fn,
89
+ )
90
+
91
+ def invalidate(self) -> None:
92
+ self._u.invalidate()
93
+
94
+ @property
95
+ def make_marshaler(self) -> MarshalerMaker:
96
+ return self._u
97
+
98
+
99
+ class InvalidatableUnmarshalerFactory(UnmarshalerFactory):
100
+ def __init__(
101
+ self,
102
+ fn: ta.Callable[[], UnmarshalerFactory],
103
+ check_fn: ta.Callable[[], bool] | None = None,
104
+ ) -> None:
105
+ super().__init__()
106
+
107
+ self._fn = fn
108
+ self._u: _InvalidatableFactory[UnmarshalContext, Unmarshaler] = _InvalidatableFactory(
109
+ lambda: fn().make_unmarshaler,
110
+ check_fn,
111
+ )
112
+
113
+ def invalidate(self) -> None:
114
+ self._u.invalidate()
115
+
116
+ @property
117
+ def make_unmarshaler(self) -> UnmarshalerMaker:
118
+ return self._u
File without changes
@@ -0,0 +1,26 @@
1
+ import dataclasses as dc
2
+ import importlib
3
+ import sys
4
+
5
+ from .... import lang
6
+ from ...base.configs import Config
7
+
8
+
9
+ ##
10
+
11
+
12
+ @dc.dataclass(frozen=True, eq=False)
13
+ class ModuleImport(Config, lang.Final):
14
+ name: str
15
+ package: str | None = None
16
+
17
+ @lang.cached_function
18
+ def resolve(self) -> str:
19
+ return lang.resolve_import_name(self.name, self.package)
20
+
21
+ def import_if_necessary(self) -> bool:
22
+ if (mn := self.resolve()) in sys.modules:
23
+ return False
24
+
25
+ importlib.import_module(mn)
26
+ return True
@@ -0,0 +1,114 @@
1
+ """
2
+ FIXME:
3
+ - lol support late registration and such, this is broken
4
+ - need to cache in the registry somehow, cannot iterate over all ModuleImports each time
5
+ - probably use something like dataclass driver context items or some such
6
+
7
+ TODO:
8
+ - per-type module imports
9
+ """
10
+ import threading
11
+ import typing as ta
12
+
13
+ from .... import reflect as rfl
14
+ from ....funcs import match as mfs
15
+ from ...base.contexts import BaseContext
16
+ from ...base.contexts import MarshalContext
17
+ from ...base.contexts import UnmarshalContext
18
+ from ...base.types import Marshaler
19
+ from ...base.types import MarshalerFactory
20
+ from ...base.types import MarshalerMaker
21
+ from ...base.types import Unmarshaler
22
+ from ...base.types import UnmarshalerFactory
23
+ from ...base.types import UnmarshalerMaker
24
+ from .configs import ModuleImport
25
+
26
+
27
+ R = ta.TypeVar('R')
28
+ ContextT = ta.TypeVar('ContextT', bound=BaseContext)
29
+
30
+
31
+ ##
32
+
33
+
34
+ class _ModuleImportingFactory(mfs.MatchFn[[ContextT, rfl.Type], R]):
35
+ def __init__(
36
+ self,
37
+ f: mfs.MatchFn[[ContextT, rfl.Type], R],
38
+ callback: ta.Callable[[], None] | None = None,
39
+ ) -> None:
40
+ super().__init__()
41
+
42
+ self._f = f
43
+ self._callback = callback
44
+
45
+ self._lock = threading.RLock()
46
+ self._has_imported = False
47
+
48
+ def _do_import(self, ctx: ContextT) -> None:
49
+ c = 0
50
+ for mi in ctx.config_registry.get_of(None, ModuleImport):
51
+ if mi.import_if_necessary():
52
+ c += 1
53
+
54
+ if c:
55
+ if self._callback is not None:
56
+ self._callback()
57
+
58
+ def _import_if_necessary(self, ctx: ContextT) -> None:
59
+ # FIXME:
60
+ # if not self._has_imported:
61
+ # with self._lock:
62
+ # if not self._has_imported:
63
+ # self._do_import(ctx)
64
+ # self._has_imported = True
65
+ self._do_import(ctx)
66
+
67
+ def guard(self, ctx: ContextT, rty: rfl.Type) -> bool:
68
+ self._import_if_necessary(ctx)
69
+ return self._f.guard(ctx, rty)
70
+
71
+ def fn(self, ctx: ContextT, rty: rfl.Type) -> R:
72
+ self._import_if_necessary(ctx)
73
+ return self._f(ctx, rty)
74
+
75
+
76
+ ##
77
+
78
+
79
+ class ModuleImportingMarshalerFactory(MarshalerFactory):
80
+ def __init__(
81
+ self,
82
+ f: MarshalerFactory,
83
+ callback: ta.Callable[[], None] | None = None,
84
+ ) -> None:
85
+ super().__init__()
86
+
87
+ self._f = f
88
+ self._tcf: _ModuleImportingFactory[MarshalContext, Marshaler] = _ModuleImportingFactory(
89
+ f.make_marshaler,
90
+ callback,
91
+ )
92
+
93
+ @property
94
+ def make_marshaler(self) -> MarshalerMaker:
95
+ return self._tcf
96
+
97
+
98
+ class ModuleImportingUnmarshalerFactory(UnmarshalerFactory):
99
+ def __init__(
100
+ self,
101
+ f: UnmarshalerFactory,
102
+ callback: ta.Callable[[], None] | None = None,
103
+ ) -> None:
104
+ super().__init__()
105
+
106
+ self._f = f
107
+ self._tcf: _ModuleImportingFactory[UnmarshalContext, Unmarshaler] = _ModuleImportingFactory(
108
+ f.make_unmarshaler,
109
+ callback,
110
+ )
111
+
112
+ @property
113
+ def make_unmarshaler(self) -> UnmarshalerMaker:
114
+ return self._tcf
@@ -31,23 +31,43 @@ class _TypeCacheFactory(mfs.MatchFn[[C, rfl.Type], R]):
31
31
 
32
32
  def guard(self, ctx: C, rty: rfl.Type) -> bool:
33
33
  check.isinstance(rty, rfl.TYPES)
34
+
35
+ try:
36
+ return self._dct[rty] is not None
37
+ except KeyError:
38
+ pass
39
+
34
40
  with self._lock:
35
41
  try:
36
42
  e = self._dct[rty]
43
+
37
44
  except KeyError:
38
45
  if self._f.guard(ctx, rty):
39
46
  return True
40
47
  else:
41
48
  self._dct[rty] = None
42
49
  return False
50
+
43
51
  else:
44
52
  return e is not None
45
53
 
46
54
  def fn(self, ctx: C, rty: rfl.Type) -> R:
47
55
  check.isinstance(rty, rfl.TYPES)
56
+
57
+ try:
58
+ e = self._dct[rty]
59
+ except KeyError:
60
+ pass
61
+ else:
62
+ if e is None:
63
+ raise mfs.MatchGuardError(ctx, rty)
64
+ else:
65
+ return e
66
+
48
67
  with self._lock:
49
68
  try:
50
69
  e = self._dct[rty]
70
+
51
71
  except KeyError:
52
72
  try:
53
73
  ret = self._f(ctx, rty)
@@ -57,11 +77,11 @@ class _TypeCacheFactory(mfs.MatchFn[[C, rfl.Type], R]):
57
77
  else:
58
78
  self._dct[rty] = ret
59
79
  return ret
80
+
81
+ if e is None:
82
+ raise mfs.MatchGuardError(ctx, rty)
60
83
  else:
61
- if e is None:
62
- raise mfs.MatchGuardError(ctx, rty)
63
- else:
64
- return e
84
+ return e
65
85
 
66
86
 
67
87
  ##
omlish/marshal/globals.py CHANGED
@@ -2,14 +2,19 @@ import threading
2
2
  import typing as ta
3
3
 
4
4
  from .. import lang
5
- from .base.registries import Registry
6
- from .base.registries import RegistryItem
5
+ from .base.configs import Config
6
+ from .base.configs import ConfigRegistry
7
7
  from .base.types import MarshalerFactory
8
8
  from .base.types import Marshaling
9
9
  from .base.types import UnmarshalerFactory
10
10
  from .base.values import Value
11
- from .standard import new_standard_marshaler_factory
12
- from .standard import new_standard_unmarshaler_factory
11
+ from .factories.moduleimport.configs import ModuleImport
12
+
13
+
14
+ if ta.TYPE_CHECKING:
15
+ from . import standard
16
+ else:
17
+ standard = lang.proxy_import('.standard', __package__)
13
18
 
14
19
 
15
20
  T = ta.TypeVar('T')
@@ -22,23 +27,23 @@ _GLOBAL_LOCK = threading.RLock()
22
27
 
23
28
 
24
29
  @lang.cached_function(lock=_GLOBAL_LOCK)
25
- def global_registry() -> Registry:
26
- return Registry(lock=_GLOBAL_LOCK)
30
+ def global_config_registry() -> ConfigRegistry:
31
+ return ConfigRegistry(lock=_GLOBAL_LOCK)
27
32
 
28
33
 
29
34
  @lang.cached_function(lock=_GLOBAL_LOCK)
30
35
  def global_marshaler_factory() -> MarshalerFactory:
31
- return new_standard_marshaler_factory()
36
+ return standard.new_standard_marshaler_factory()
32
37
 
33
38
 
34
39
  @lang.cached_function(lock=_GLOBAL_LOCK)
35
40
  def global_unmarshaler_factory() -> UnmarshalerFactory:
36
- return new_standard_unmarshaler_factory()
41
+ return standard.new_standard_unmarshaler_factory()
37
42
 
38
43
 
39
44
  class _GlobalMarshaling(Marshaling, lang.Final):
40
- def registry(self) -> Registry:
41
- return global_registry()
45
+ def config_registry(self) -> ConfigRegistry:
46
+ return global_config_registry()
42
47
 
43
48
  def marshaler_factory(self) -> MarshalerFactory:
44
49
  return global_marshaler_factory()
@@ -76,13 +81,23 @@ def unmarshal(v, ty, **kwargs):
76
81
  ##
77
82
 
78
83
 
79
- def register_global(
84
+ def register_global_config(
80
85
  key: ta.Any,
81
- *items: RegistryItem,
86
+ *items: Config,
82
87
  identity: bool = False,
83
88
  ) -> None:
84
- global_registry().register(
89
+ global_config_registry().register(
85
90
  key,
86
91
  *items,
87
92
  identity=identity,
88
93
  )
94
+
95
+
96
+ def register_global_module_import(
97
+ name: str,
98
+ package: str | None = None,
99
+ ) -> None:
100
+ global_config_registry().register(
101
+ None,
102
+ ModuleImport(name, package),
103
+ )
@@ -1,5 +1,6 @@
1
1
  """
2
2
  TODO:
3
+ - clean up yeesh
3
4
  - tangled with objects - Field/ObjectMetadata defined over there but unused
4
5
  """
5
6
  import typing as ta
@@ -158,11 +159,17 @@ def get_dataclass_field_infos(
158
159
  return FieldInfos(ret)
159
160
 
160
161
 
161
- def _make_field_obj(ctx, ty, obj, fac):
162
+ def _make_field_obj(
163
+ ctx,
164
+ ty,
165
+ obj,
166
+ fac,
167
+ fac_attr,
168
+ ):
162
169
  if obj is not None:
163
170
  return obj
164
171
  if fac is not None:
165
- return fac(ctx, ty)
172
+ return getattr(fac, fac_attr)(ctx, ty)
166
173
  return ctx.make(ty)
167
174
 
168
175
 
@@ -210,7 +217,16 @@ class DataclassMarshalerFactory(AbstractDataclassFactory, SimpleMarshalerFactory
210
217
  fis = self._get_field_infos(ty, ctx.options)
211
218
 
212
219
  fields = [
213
- (fi, _make_field_obj(ctx, fi.type, fi.metadata.marshaler, fi.metadata.marshaler_factory))
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
+ ),
229
+ )
214
230
  for fi in fis
215
231
  if fi.name not in dc_md.specials.set
216
232
  ]
@@ -262,7 +278,16 @@ class DataclassUnmarshalerFactory(AbstractDataclassFactory, SimpleUnmarshalerFac
262
278
  ret.extend(e_ns)
263
279
 
264
280
  else:
265
- tup = (fi, _make_field_obj(ctx, fi.type, fi.metadata.unmarshaler, fi.metadata.unmarshaler_factory))
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
+ )
266
291
 
267
292
  for pfx in prefixes:
268
293
  for un in fi.unmarshal_names: