omlish 0.0.0.dev415__py3-none-any.whl → 0.0.0.dev417__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- omlish/__about__.py +2 -2
- omlish/bootstrap/__init__.py +2 -2
- omlish/dataclasses/__init__.py +28 -14
- omlish/dataclasses/impl/processing/base.py +1 -1
- omlish/lang/__init__.py +486 -473
- omlish/lang/imports/proxyinit.py +161 -48
- omlish/lang/maybes.py +8 -0
- omlish/marshal/__init__.py +224 -203
- omlish/marshal/base/configs.py +18 -0
- omlish/marshal/base/contexts.py +23 -19
- omlish/marshal/base/overrides.py +26 -12
- omlish/marshal/base/registries.py +66 -16
- omlish/marshal/base/types.py +60 -8
- omlish/marshal/factories/invalidate.py +118 -0
- omlish/marshal/factories/moduleimport/__init__.py +0 -0
- omlish/marshal/factories/moduleimport/configs.py +26 -0
- omlish/marshal/factories/moduleimport/factories.py +114 -0
- omlish/marshal/factories/typecache.py +24 -4
- omlish/marshal/globals.py +52 -27
- omlish/marshal/polymorphism/metadata.py +2 -2
- omlish/marshal/standard.py +132 -65
- omlish/reflect/__init__.py +57 -47
- omlish/reflect/types.py +144 -15
- omlish/secrets/all.py +0 -9
- omlish/secrets/secrets.py +4 -6
- omlish/specs/jsonrpc/__init__.py +2 -2
- omlish/specs/jsonschema/__init__.py +2 -2
- omlish/specs/openapi/__init__.py +2 -2
- omlish/sql/queries/__init__.py +4 -2
- omlish/sql/tabledefs/__init__.py +2 -2
- omlish/typedvalues/__init__.py +2 -2
- {omlish-0.0.0.dev415.dist-info → omlish-0.0.0.dev417.dist-info}/METADATA +14 -9
- {omlish-0.0.0.dev415.dist-info → omlish-0.0.0.dev417.dist-info}/RECORD +43 -37
- /omlish/bootstrap/{marshal.py → _marshal.py} +0 -0
- /omlish/specs/jsonrpc/{marshal.py → _marshal.py} +0 -0
- /omlish/specs/jsonschema/{marshal.py → _marshal.py} +0 -0
- /omlish/specs/openapi/{marshal.py → _marshal.py} +0 -0
- /omlish/sql/queries/{marshal.py → _marshal.py} +0 -0
- /omlish/sql/tabledefs/{marshal.py → _marshal.py} +0 -0
- {omlish-0.0.0.dev415.dist-info → omlish-0.0.0.dev417.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev415.dist-info → omlish-0.0.0.dev417.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev415.dist-info → omlish-0.0.0.dev417.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev415.dist-info → omlish-0.0.0.dev417.dist-info}/top_level.txt +0 -0
@@ -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,41 +19,84 @@ 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[
|
23
|
-
item_lists_by_ty: dict[type[
|
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:
|
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
|
32
|
-
|
37
|
+
class RegistrySealedError(Exception):
|
38
|
+
pass
|
39
|
+
|
40
|
+
|
41
|
+
class Registry(ta.Generic[RegistryItemT]):
|
42
|
+
def __init__(
|
43
|
+
self,
|
44
|
+
*,
|
45
|
+
lock: ta.Optional[threading.RLock] = None, # noqa
|
46
|
+
) -> None:
|
33
47
|
super().__init__()
|
34
48
|
|
35
|
-
|
36
|
-
|
37
|
-
self.
|
49
|
+
if lock is None:
|
50
|
+
lock = threading.RLock()
|
51
|
+
self._lock = lock
|
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
|
+
#
|
38
80
|
|
39
81
|
def register(
|
40
82
|
self,
|
41
83
|
key: ta.Any,
|
42
|
-
*items:
|
84
|
+
*items: RegistryItemT,
|
43
85
|
identity: bool = False,
|
44
|
-
) ->
|
86
|
+
) -> ta.Self:
|
45
87
|
with self._lock:
|
46
|
-
|
88
|
+
if self._sealed:
|
89
|
+
raise RegistrySealedError(self)
|
90
|
+
|
91
|
+
dct: ta.Any = self._id_dct if identity else self._dct
|
47
92
|
if (sr := dct.get(key)) is None:
|
48
93
|
sr = dct[key] = _KeyRegistryItems(key)
|
49
94
|
sr.add(*items)
|
95
|
+
|
50
96
|
return self
|
51
97
|
|
98
|
+
#
|
99
|
+
|
52
100
|
def get(
|
53
101
|
self,
|
54
102
|
key: ta.Any,
|
@@ -60,7 +108,8 @@ class Registry:
|
|
60
108
|
*self.get(key, identity=True),
|
61
109
|
*self.get(key, identity=False),
|
62
110
|
)
|
63
|
-
|
111
|
+
|
112
|
+
dct: ta.Any = self._id_dct if identity else self._dct
|
64
113
|
try:
|
65
114
|
return dct[key].items
|
66
115
|
except KeyError:
|
@@ -69,16 +118,17 @@ class Registry:
|
|
69
118
|
def get_of(
|
70
119
|
self,
|
71
120
|
key: ta.Any,
|
72
|
-
item_ty: type[
|
121
|
+
item_ty: type[RegistryItemU],
|
73
122
|
*,
|
74
123
|
identity: bool | None = None,
|
75
|
-
) -> ta.Sequence[
|
124
|
+
) -> ta.Sequence[RegistryItemU]:
|
76
125
|
if identity is None:
|
77
126
|
return (
|
78
127
|
*self.get_of(key, item_ty, identity=True),
|
79
128
|
*self.get_of(key, item_ty, identity=False),
|
80
129
|
)
|
81
|
-
|
130
|
+
|
131
|
+
dct: ta.Any = self._id_dct if identity else self._dct
|
82
132
|
try:
|
83
133
|
sr = dct[key]
|
84
134
|
except KeyError:
|
omlish/marshal/base/types.py
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
import abc
|
2
|
+
import dataclasses as dc
|
2
3
|
import typing as ta
|
3
4
|
|
4
|
-
from ... import dataclasses as dc
|
5
5
|
from ... import lang
|
6
6
|
from ... import reflect as rfl
|
7
7
|
from ...funcs import match as mfs
|
8
|
+
from .configs import ConfigRegistry
|
9
|
+
from .contexts import MarshalContext
|
10
|
+
from .contexts import UnmarshalContext
|
8
11
|
from .values import Value
|
9
12
|
|
10
13
|
|
11
|
-
|
12
|
-
from .contexts import MarshalContext
|
13
|
-
from .contexts import UnmarshalContext
|
14
|
+
T = ta.TypeVar('T')
|
14
15
|
|
15
16
|
|
16
17
|
##
|
@@ -18,21 +19,21 @@ if ta.TYPE_CHECKING:
|
|
18
19
|
|
19
20
|
class Marshaler(lang.Abstract):
|
20
21
|
@abc.abstractmethod
|
21
|
-
def marshal(self, ctx:
|
22
|
+
def marshal(self, ctx: MarshalContext, o: ta.Any) -> Value:
|
22
23
|
raise NotImplementedError
|
23
24
|
|
24
25
|
|
25
26
|
class Unmarshaler(lang.Abstract):
|
26
27
|
@abc.abstractmethod
|
27
|
-
def unmarshal(self, ctx:
|
28
|
+
def unmarshal(self, ctx: UnmarshalContext, v: Value) -> ta.Any:
|
28
29
|
raise NotImplementedError
|
29
30
|
|
30
31
|
|
31
32
|
##
|
32
33
|
|
33
34
|
|
34
|
-
MarshalerMaker: ta.TypeAlias = mfs.MatchFn[[
|
35
|
-
UnmarshalerMaker: ta.TypeAlias = mfs.MatchFn[[
|
35
|
+
MarshalerMaker: ta.TypeAlias = mfs.MatchFn[[MarshalContext, rfl.Type], Marshaler]
|
36
|
+
UnmarshalerMaker: ta.TypeAlias = mfs.MatchFn[[UnmarshalContext, rfl.Type], Unmarshaler]
|
36
37
|
|
37
38
|
|
38
39
|
class MarshalerFactory(lang.Abstract):
|
@@ -68,3 +69,54 @@ class UnmarshalerFactory_(UnmarshalerFactory): # noqa
|
|
68
69
|
@property
|
69
70
|
def make_unmarshaler(self) -> UnmarshalerMaker:
|
70
71
|
return self.fn
|
72
|
+
|
73
|
+
|
74
|
+
##
|
75
|
+
|
76
|
+
|
77
|
+
class Marshaling(lang.Abstract):
|
78
|
+
@abc.abstractmethod
|
79
|
+
def config_registry(self) -> ConfigRegistry:
|
80
|
+
raise NotImplementedError
|
81
|
+
|
82
|
+
@abc.abstractmethod
|
83
|
+
def marshaler_factory(self) -> MarshalerFactory:
|
84
|
+
raise NotImplementedError
|
85
|
+
|
86
|
+
@abc.abstractmethod
|
87
|
+
def unmarshaler_factory(self) -> UnmarshalerFactory:
|
88
|
+
raise NotImplementedError
|
89
|
+
|
90
|
+
#
|
91
|
+
|
92
|
+
def new_marshal_context(self, **kwargs: ta.Any) -> MarshalContext:
|
93
|
+
return MarshalContext(
|
94
|
+
config_registry=self.config_registry(),
|
95
|
+
factory=self.marshaler_factory(),
|
96
|
+
**kwargs,
|
97
|
+
)
|
98
|
+
|
99
|
+
def new_unmarshal_context(self, **kwargs: ta.Any) -> UnmarshalContext:
|
100
|
+
return UnmarshalContext(
|
101
|
+
config_registry=self.config_registry(),
|
102
|
+
factory=self.unmarshaler_factory(),
|
103
|
+
**kwargs,
|
104
|
+
)
|
105
|
+
|
106
|
+
#
|
107
|
+
|
108
|
+
@ta.final
|
109
|
+
def marshal(self, obj: ta.Any, ty: ta.Any | None = None, **kwargs: ta.Any) -> Value:
|
110
|
+
return self.new_marshal_context(**kwargs).marshal(obj, ty)
|
111
|
+
|
112
|
+
@ta.overload
|
113
|
+
def unmarshal(self, v: Value, ty: type[T], **kwargs: ta.Any) -> T:
|
114
|
+
...
|
115
|
+
|
116
|
+
@ta.overload
|
117
|
+
def unmarshal(self, v: Value, ty: ta.Any, **kwargs: ta.Any) -> ta.Any:
|
118
|
+
...
|
119
|
+
|
120
|
+
@ta.final
|
121
|
+
def unmarshal(self, v, ty, **kwargs):
|
122
|
+
return self.new_unmarshal_context(**kwargs).unmarshal(v, ty)
|
@@ -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
|
-
|
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
@@ -1,15 +1,20 @@
|
|
1
|
+
import threading
|
1
2
|
import typing as ta
|
2
3
|
|
3
4
|
from .. import lang
|
4
|
-
from .base.
|
5
|
-
from .base.
|
6
|
-
from .base.registries import Registry
|
7
|
-
from .base.registries import RegistryItem
|
5
|
+
from .base.configs import Config
|
6
|
+
from .base.configs import ConfigRegistry
|
8
7
|
from .base.types import MarshalerFactory
|
8
|
+
from .base.types import Marshaling
|
9
9
|
from .base.types import UnmarshalerFactory
|
10
10
|
from .base.values import Value
|
11
|
-
from .
|
12
|
-
|
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')
|
@@ -18,31 +23,45 @@ T = ta.TypeVar('T')
|
|
18
23
|
##
|
19
24
|
|
20
25
|
|
21
|
-
|
26
|
+
_GLOBAL_LOCK = threading.RLock()
|
22
27
|
|
23
28
|
|
24
|
-
|
29
|
+
@lang.cached_function(lock=_GLOBAL_LOCK)
|
30
|
+
def global_config_registry() -> ConfigRegistry:
|
31
|
+
return ConfigRegistry(lock=_GLOBAL_LOCK)
|
25
32
|
|
26
33
|
|
27
|
-
@lang.cached_function(lock=
|
34
|
+
@lang.cached_function(lock=_GLOBAL_LOCK)
|
28
35
|
def global_marshaler_factory() -> MarshalerFactory:
|
29
|
-
return new_standard_marshaler_factory()
|
36
|
+
return standard.new_standard_marshaler_factory()
|
30
37
|
|
31
38
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
39
|
+
@lang.cached_function(lock=_GLOBAL_LOCK)
|
40
|
+
def global_unmarshaler_factory() -> UnmarshalerFactory:
|
41
|
+
return standard.new_standard_unmarshaler_factory()
|
42
|
+
|
43
|
+
|
44
|
+
class _GlobalMarshaling(Marshaling, lang.Final):
|
45
|
+
def config_registry(self) -> ConfigRegistry:
|
46
|
+
return global_config_registry()
|
47
|
+
|
48
|
+
def marshaler_factory(self) -> MarshalerFactory:
|
49
|
+
return global_marshaler_factory()
|
50
|
+
|
51
|
+
def unmarshaler_factory(self) -> UnmarshalerFactory:
|
52
|
+
return global_unmarshaler_factory()
|
53
|
+
|
54
|
+
|
55
|
+
@lang.cached_function(lock=_GLOBAL_LOCK)
|
56
|
+
def global_marshaling() -> Marshaling:
|
57
|
+
return _GlobalMarshaling()
|
38
58
|
|
39
59
|
|
40
60
|
##
|
41
61
|
|
42
62
|
|
43
|
-
|
44
|
-
|
45
|
-
return new_standard_unmarshaler_factory()
|
63
|
+
def marshal(obj: ta.Any, ty: ta.Any | None = None, **kwargs: ta.Any) -> Value:
|
64
|
+
return global_marshaling().marshal(obj, ty, **kwargs)
|
46
65
|
|
47
66
|
|
48
67
|
@ta.overload
|
@@ -56,23 +75,29 @@ def unmarshal(v: Value, ty: ta.Any, **kwargs: ta.Any) -> ta.Any:
|
|
56
75
|
|
57
76
|
|
58
77
|
def unmarshal(v, ty, **kwargs):
|
59
|
-
return
|
60
|
-
GLOBAL_REGISTRY,
|
61
|
-
factory=global_unmarshaler_factory(),
|
62
|
-
**kwargs,
|
63
|
-
).unmarshal(v, ty)
|
78
|
+
return global_marshaling().unmarshal(v, ty, **kwargs)
|
64
79
|
|
65
80
|
|
66
81
|
##
|
67
82
|
|
68
83
|
|
69
|
-
def
|
84
|
+
def register_global_config(
|
70
85
|
key: ta.Any,
|
71
|
-
*items:
|
86
|
+
*items: Config,
|
72
87
|
identity: bool = False,
|
73
88
|
) -> None:
|
74
|
-
|
89
|
+
global_config_registry().register(
|
75
90
|
key,
|
76
91
|
*items,
|
77
92
|
identity=identity,
|
78
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
|
+
)
|
@@ -2,7 +2,7 @@ import dataclasses as dc
|
|
2
2
|
import typing as ta
|
3
3
|
|
4
4
|
from ... import lang
|
5
|
-
from ..base.
|
5
|
+
from ..base.configs import Config
|
6
6
|
from ..naming import Naming
|
7
7
|
from ..naming import translate_name
|
8
8
|
|
@@ -10,7 +10,7 @@ from ..naming import translate_name
|
|
10
10
|
##
|
11
11
|
|
12
12
|
|
13
|
-
class TypeTagging(
|
13
|
+
class TypeTagging(Config, lang.Abstract, lang.Sealed):
|
14
14
|
pass
|
15
15
|
|
16
16
|
|