omlish 0.0.0.dev5__py3-none-any.whl → 0.0.0.dev7__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.
Potentially problematic release.
This version of omlish might be problematic. Click here for more details.
- omlish/__about__.py +109 -5
- omlish/__init__.py +0 -8
- omlish/asyncs/__init__.py +9 -9
- omlish/asyncs/anyio.py +123 -19
- omlish/asyncs/asyncio.py +23 -0
- omlish/asyncs/asyncs.py +9 -6
- omlish/asyncs/bridge.py +316 -0
- omlish/asyncs/trio_asyncio.py +7 -3
- omlish/bootstrap.py +737 -0
- omlish/check.py +1 -1
- omlish/collections/__init__.py +5 -0
- omlish/collections/exceptions.py +2 -0
- omlish/collections/identity.py +7 -0
- omlish/collections/utils.py +38 -9
- omlish/configs/strings.py +96 -0
- omlish/dataclasses/__init__.py +16 -0
- omlish/dataclasses/impl/copy.py +30 -0
- omlish/dataclasses/impl/descriptors.py +95 -0
- omlish/dataclasses/impl/exceptions.py +6 -0
- omlish/dataclasses/impl/fields.py +24 -25
- omlish/dataclasses/impl/init.py +4 -2
- omlish/dataclasses/impl/main.py +2 -0
- omlish/dataclasses/impl/reflect.py +1 -1
- omlish/dataclasses/utils.py +67 -0
- omlish/{lang/datetimes.py → datetimes.py} +8 -4
- omlish/diag/__init__.py +4 -0
- omlish/diag/procfs.py +2 -2
- omlish/{testing → diag}/pydevd.py +35 -0
- omlish/diag/threads.py +131 -48
- omlish/dispatch/_dispatch2.py +65 -0
- omlish/dispatch/_dispatch3.py +104 -0
- omlish/docker.py +16 -1
- omlish/fnpairs.py +11 -4
- omlish/formats/__init__.py +0 -0
- omlish/{configs → formats}/dotenv.py +15 -24
- omlish/{json.py → formats/json.py} +2 -1
- omlish/formats/yaml.py +223 -0
- omlish/graphs/trees.py +1 -1
- omlish/http/asgi.py +2 -1
- omlish/http/collections.py +15 -0
- omlish/http/consts.py +22 -1
- omlish/http/sessions.py +10 -3
- omlish/inject/__init__.py +49 -17
- omlish/inject/binder.py +185 -5
- omlish/inject/bindings.py +3 -36
- omlish/inject/eagers.py +2 -8
- omlish/inject/elements.py +31 -10
- omlish/inject/exceptions.py +1 -1
- omlish/inject/impl/elements.py +37 -12
- omlish/inject/impl/injector.py +72 -25
- omlish/inject/impl/inspect.py +33 -5
- omlish/inject/impl/origins.py +77 -0
- omlish/inject/impl/{private.py → privates.py} +2 -2
- omlish/inject/impl/scopes.py +6 -2
- omlish/inject/injector.py +8 -4
- omlish/inject/inspect.py +18 -0
- omlish/inject/keys.py +8 -14
- omlish/inject/listeners.py +26 -0
- omlish/inject/managed.py +76 -10
- omlish/inject/multis.py +68 -18
- omlish/inject/origins.py +30 -0
- omlish/inject/overrides.py +5 -4
- omlish/inject/{private.py → privates.py} +6 -10
- omlish/inject/providers.py +12 -85
- omlish/inject/scopes.py +13 -6
- omlish/inject/types.py +3 -1
- omlish/inject/utils.py +18 -0
- omlish/iterators.py +69 -2
- omlish/lang/__init__.py +24 -9
- omlish/lang/cached.py +2 -2
- omlish/lang/classes/restrict.py +12 -1
- omlish/lang/classes/simple.py +18 -8
- omlish/lang/contextmanagers.py +13 -4
- omlish/lang/descriptors.py +132 -1
- omlish/lang/functions.py +8 -28
- omlish/lang/imports.py +67 -0
- omlish/lang/iterables.py +60 -1
- omlish/lang/maybes.py +3 -0
- omlish/lang/objects.py +38 -0
- omlish/lang/strings.py +25 -0
- omlish/lang/sys.py +9 -0
- omlish/lang/typing.py +42 -0
- omlish/lifecycles/__init__.py +34 -0
- omlish/lifecycles/abstract.py +43 -0
- omlish/lifecycles/base.py +51 -0
- omlish/lifecycles/contextmanagers.py +74 -0
- omlish/lifecycles/controller.py +116 -0
- omlish/lifecycles/manager.py +161 -0
- omlish/lifecycles/states.py +43 -0
- omlish/lifecycles/transitions.py +64 -0
- omlish/lite/__init__.py +1 -0
- omlish/lite/cached.py +18 -0
- omlish/lite/check.py +29 -0
- omlish/lite/contextmanagers.py +18 -0
- omlish/lite/json.py +30 -0
- omlish/lite/logs.py +52 -0
- omlish/lite/marshal.py +316 -0
- omlish/lite/reflect.py +49 -0
- omlish/lite/runtime.py +18 -0
- omlish/lite/secrets.py +19 -0
- omlish/lite/strings.py +25 -0
- omlish/lite/subprocesses.py +112 -0
- omlish/logs/configs.py +15 -2
- omlish/logs/formatters.py +7 -2
- omlish/marshal/__init__.py +32 -0
- omlish/marshal/any.py +5 -5
- omlish/marshal/base.py +27 -11
- omlish/marshal/base64.py +24 -9
- omlish/marshal/dataclasses.py +34 -28
- omlish/marshal/datetimes.py +74 -18
- omlish/marshal/enums.py +14 -8
- omlish/marshal/exceptions.py +11 -1
- omlish/marshal/factories.py +59 -74
- omlish/marshal/forbidden.py +35 -0
- omlish/marshal/global_.py +11 -4
- omlish/marshal/iterables.py +21 -24
- omlish/marshal/mappings.py +23 -26
- omlish/marshal/naming.py +4 -0
- omlish/marshal/numbers.py +51 -0
- omlish/marshal/objects.py +1 -0
- omlish/marshal/optionals.py +11 -12
- omlish/marshal/polymorphism.py +86 -21
- omlish/marshal/primitives.py +4 -5
- omlish/marshal/standard.py +13 -8
- omlish/marshal/uuids.py +4 -5
- omlish/matchfns.py +218 -0
- omlish/os.py +64 -0
- omlish/reflect/__init__.py +39 -0
- omlish/reflect/isinstance.py +38 -0
- omlish/reflect/ops.py +84 -0
- omlish/reflect/subst.py +110 -0
- omlish/reflect/types.py +275 -0
- omlish/secrets/__init__.py +23 -0
- omlish/secrets/crypto.py +132 -0
- omlish/secrets/marshal.py +70 -0
- omlish/secrets/openssl.py +207 -0
- omlish/secrets/passwords.py +120 -0
- omlish/secrets/secrets.py +299 -0
- omlish/secrets/subprocesses.py +42 -0
- omlish/sql/dbs.py +7 -6
- omlish/sql/duckdb.py +136 -0
- omlish/sql/exprs.py +12 -0
- omlish/sql/secrets.py +10 -0
- omlish/sql/sqlean.py +17 -0
- omlish/term.py +2 -2
- omlish/testing/pytest/__init__.py +3 -2
- omlish/testing/pytest/inject/harness.py +3 -3
- omlish/testing/pytest/marks.py +4 -7
- omlish/testing/pytest/plugins/__init__.py +1 -0
- omlish/testing/pytest/plugins/asyncs.py +136 -0
- omlish/testing/pytest/plugins/pydevd.py +1 -1
- omlish/testing/pytest/plugins/switches.py +54 -19
- omlish/text/glyphsplit.py +97 -0
- omlish-0.0.0.dev7.dist-info/METADATA +50 -0
- omlish-0.0.0.dev7.dist-info/RECORD +268 -0
- {omlish-0.0.0.dev5.dist-info → omlish-0.0.0.dev7.dist-info}/WHEEL +1 -1
- omlish/reflect.py +0 -355
- omlish-0.0.0.dev5.dist-info/METADATA +0 -34
- omlish-0.0.0.dev5.dist-info/RECORD +0 -212
- /omlish/{asyncs/futures.py → concurrent.py} +0 -0
- /omlish/{configs → formats}/props.py +0 -0
- {omlish-0.0.0.dev5.dist-info → omlish-0.0.0.dev7.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev5.dist-info → omlish-0.0.0.dev7.dist-info}/top_level.txt +0 -0
omlish/marshal/iterables.py
CHANGED
|
@@ -4,13 +4,14 @@ import functools
|
|
|
4
4
|
import typing as ta
|
|
5
5
|
|
|
6
6
|
from .. import check
|
|
7
|
+
from .. import matchfns as mfs
|
|
7
8
|
from .. import reflect as rfl
|
|
8
9
|
from .base import MarshalContext
|
|
9
10
|
from .base import Marshaler
|
|
10
|
-
from .base import
|
|
11
|
+
from .base import MarshalerFactoryMatchClass
|
|
11
12
|
from .base import UnmarshalContext
|
|
12
13
|
from .base import Unmarshaler
|
|
13
|
-
from .base import
|
|
14
|
+
from .base import UnmarshalerFactoryMatchClass
|
|
14
15
|
from .values import Value
|
|
15
16
|
|
|
16
17
|
|
|
@@ -22,17 +23,15 @@ class IterableMarshaler(Marshaler):
|
|
|
22
23
|
return list(map(functools.partial(self.e.marshal, ctx), o))
|
|
23
24
|
|
|
24
25
|
|
|
25
|
-
class IterableMarshalerFactory(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return IterableMarshaler(e)
|
|
35
|
-
return None
|
|
26
|
+
class IterableMarshalerFactory(MarshalerFactoryMatchClass):
|
|
27
|
+
@mfs.simple(lambda _, ctx, rty: isinstance(rty, rfl.Generic) and issubclass(rty.cls, collections.abc.Iterable))
|
|
28
|
+
def _build_generic(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
|
|
29
|
+
gty = check.isinstance(rty, rfl.Generic)
|
|
30
|
+
return IterableMarshaler(ctx.make(check.single(gty.args)))
|
|
31
|
+
|
|
32
|
+
@mfs.simple(lambda _, ctx, rty: isinstance(rty, type) and issubclass(rty, collections.abc.Iterable))
|
|
33
|
+
def _build_concrete(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
|
|
34
|
+
return IterableMarshaler(ctx.make(ta.Any))
|
|
36
35
|
|
|
37
36
|
|
|
38
37
|
@dc.dataclass(frozen=True)
|
|
@@ -44,14 +43,12 @@ class IterableUnmarshaler(Unmarshaler):
|
|
|
44
43
|
return self.ctor(map(functools.partial(self.e.unmarshal, ctx), check.isinstance(v, collections.abc.Iterable)))
|
|
45
44
|
|
|
46
45
|
|
|
47
|
-
class IterableUnmarshalerFactory(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return IterableUnmarshaler(rty, e) # noqa
|
|
57
|
-
return None
|
|
46
|
+
class IterableUnmarshalerFactory(UnmarshalerFactoryMatchClass):
|
|
47
|
+
@mfs.simple(lambda _, ctx, rty: isinstance(rty, rfl.Generic) and issubclass(rty.cls, collections.abc.Iterable))
|
|
48
|
+
def _build_generic(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
|
|
49
|
+
gty = check.isinstance(rty, rfl.Generic)
|
|
50
|
+
return IterableUnmarshaler(gty.cls, ctx.make(check.single(gty.args)))
|
|
51
|
+
|
|
52
|
+
@mfs.simple(lambda _, ctx, rty: isinstance(rty, type) and issubclass(rty, collections.abc.Iterable))
|
|
53
|
+
def _build_concrete(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
|
|
54
|
+
return IterableUnmarshaler(check.isinstance(rty, type), ctx.make(ta.Any))
|
omlish/marshal/mappings.py
CHANGED
|
@@ -3,13 +3,14 @@ import dataclasses as dc
|
|
|
3
3
|
import typing as ta
|
|
4
4
|
|
|
5
5
|
from .. import check
|
|
6
|
+
from .. import matchfns as mfs
|
|
6
7
|
from .. import reflect as rfl
|
|
7
8
|
from .base import MarshalContext
|
|
8
9
|
from .base import Marshaler
|
|
9
|
-
from .base import
|
|
10
|
+
from .base import MarshalerFactoryMatchClass
|
|
10
11
|
from .base import UnmarshalContext
|
|
11
12
|
from .base import Unmarshaler
|
|
12
|
-
from .base import
|
|
13
|
+
from .base import UnmarshalerFactoryMatchClass
|
|
13
14
|
from .values import Value
|
|
14
15
|
|
|
15
16
|
|
|
@@ -25,18 +26,16 @@ class MappingMarshaler(Marshaler):
|
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
|
|
28
|
-
class MappingMarshalerFactory(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return MappingMarshaler(e, e)
|
|
39
|
-
return None
|
|
29
|
+
class MappingMarshalerFactory(MarshalerFactoryMatchClass):
|
|
30
|
+
@mfs.simple(lambda _, ctx, rty: isinstance(rty, rfl.Generic) and issubclass(rty.cls, collections.abc.Mapping))
|
|
31
|
+
def _build_generic(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
|
|
32
|
+
gty = check.isinstance(rty, rfl.Generic)
|
|
33
|
+
kt, vt = gty.args
|
|
34
|
+
return MappingMarshaler(ctx.make(kt), ctx.make(vt))
|
|
35
|
+
|
|
36
|
+
@mfs.simple(lambda _, ctx, rty: isinstance(rty, type) and issubclass(rty, collections.abc.Mapping))
|
|
37
|
+
def _build_concrete(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
|
|
38
|
+
return MappingMarshaler(a := ctx.make(ta.Any), a)
|
|
40
39
|
|
|
41
40
|
|
|
42
41
|
@dc.dataclass(frozen=True)
|
|
@@ -52,15 +51,13 @@ class MappingUnmarshaler(Unmarshaler):
|
|
|
52
51
|
return self.ctor(dct)
|
|
53
52
|
|
|
54
53
|
|
|
55
|
-
class MappingUnmarshalerFactory(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return MappingUnmarshaler(rty, e, e)
|
|
66
|
-
return None
|
|
54
|
+
class MappingUnmarshalerFactory(UnmarshalerFactoryMatchClass):
|
|
55
|
+
@mfs.simple(lambda _, ctx, rty: isinstance(rty, rfl.Generic) and issubclass(rty.cls, collections.abc.Mapping))
|
|
56
|
+
def _build_generic(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
|
|
57
|
+
gty = check.isinstance(rty, rfl.Generic)
|
|
58
|
+
kt, vt = gty.args
|
|
59
|
+
return MappingUnmarshaler(gty.cls, ctx.make(kt), ctx.make(vt))
|
|
60
|
+
|
|
61
|
+
@mfs.simple(lambda _, ctx, rty: isinstance(rty, type) and issubclass(rty, collections.abc.Mapping))
|
|
62
|
+
def _build_concrete(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
|
|
63
|
+
return MappingUnmarshaler(check.isinstance(rty, type), a := ctx.make(ta.Any), a)
|
omlish/marshal/naming.py
CHANGED
|
@@ -7,6 +7,7 @@ from .base import Option
|
|
|
7
7
|
class Naming(Option, enum.Enum):
|
|
8
8
|
SNAKE = 'snake'
|
|
9
9
|
CAMEL = 'camel'
|
|
10
|
+
LOW_CAMEL = 'low_camel'
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def translate_name(n: str, e: Naming) -> str:
|
|
@@ -14,4 +15,7 @@ def translate_name(n: str, e: Naming) -> str:
|
|
|
14
15
|
return lang.snake_case(n)
|
|
15
16
|
if e is Naming.CAMEL:
|
|
16
17
|
return lang.camel_case(n)
|
|
18
|
+
if e is Naming.LOW_CAMEL:
|
|
19
|
+
r = lang.camel_case(n)
|
|
20
|
+
return (r[0].lower() + r[1:]) if r else r
|
|
17
21
|
raise ValueError(e)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import decimal
|
|
2
|
+
import fractions
|
|
3
|
+
import typing as ta
|
|
4
|
+
|
|
5
|
+
from .. import check
|
|
6
|
+
from .base import MarshalContext
|
|
7
|
+
from .base import Marshaler
|
|
8
|
+
from .base import TypeMapMarshalerFactory
|
|
9
|
+
from .base import TypeMapUnmarshalerFactory
|
|
10
|
+
from .base import UnmarshalContext
|
|
11
|
+
from .base import Unmarshaler
|
|
12
|
+
from .values import Value
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ComplexMarshalerUnmarshaler(Marshaler, Unmarshaler):
|
|
16
|
+
def marshal(self, ctx: MarshalContext, o: complex) -> Value:
|
|
17
|
+
return [o.real, o.imag]
|
|
18
|
+
|
|
19
|
+
def unmarshal(self, ctx: UnmarshalContext, v: Value) -> ta.Any:
|
|
20
|
+
real, imag = check.isinstance(v, list)
|
|
21
|
+
return complex(real, imag) # type: ignore
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class DecimalMarshalerUnmarshaler(Marshaler, Unmarshaler):
|
|
25
|
+
def marshal(self, ctx: MarshalContext, o: decimal.Decimal) -> Value:
|
|
26
|
+
return str(o)
|
|
27
|
+
|
|
28
|
+
def unmarshal(self, ctx: UnmarshalContext, v: Value) -> ta.Any:
|
|
29
|
+
return decimal.Decimal(check.isinstance(v, str))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class FractionMarshalerUnmarshaler(Marshaler, Unmarshaler):
|
|
33
|
+
def marshal(self, ctx: MarshalContext, o: fractions.Fraction) -> Value:
|
|
34
|
+
return [o.numerator, o.denominator]
|
|
35
|
+
|
|
36
|
+
def unmarshal(self, ctx: UnmarshalContext, v: Value) -> ta.Any:
|
|
37
|
+
num, denom = check.isinstance(v, list)
|
|
38
|
+
return fractions.Fraction(num, denom) # type: ignore
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
NUMBERS_MARSHALER_FACTORY = TypeMapMarshalerFactory({
|
|
42
|
+
complex: ComplexMarshalerUnmarshaler(),
|
|
43
|
+
decimal.Decimal: DecimalMarshalerUnmarshaler(),
|
|
44
|
+
fractions.Fraction: FractionMarshalerUnmarshaler(),
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
NUMBERS_UNMARSHALER_FACTORY = TypeMapUnmarshalerFactory({
|
|
48
|
+
complex: ComplexMarshalerUnmarshaler(),
|
|
49
|
+
decimal.Decimal: DecimalMarshalerUnmarshaler(),
|
|
50
|
+
fractions.Fraction: FractionMarshalerUnmarshaler(),
|
|
51
|
+
})
|
omlish/marshal/objects.py
CHANGED
omlish/marshal/optionals.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import dataclasses as dc
|
|
2
2
|
import typing as ta
|
|
3
3
|
|
|
4
|
+
from .. import check
|
|
4
5
|
from .. import reflect as rfl
|
|
5
6
|
from .base import MarshalContext
|
|
6
7
|
from .base import Marshaler
|
|
@@ -22,12 +23,11 @@ class OptionalMarshaler(Marshaler):
|
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
class OptionalMarshalerFactory(MarshalerFactory):
|
|
25
|
-
def
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return None
|
|
26
|
+
def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
|
|
27
|
+
return isinstance(rty, rfl.Union) and rty.is_optional
|
|
28
|
+
|
|
29
|
+
def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
|
|
30
|
+
return OptionalMarshaler(ctx.make(check.isinstance(rty, rfl.Union).without_none()))
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
@dc.dataclass(frozen=True)
|
|
@@ -41,9 +41,8 @@ class OptionalUnmarshaler(Unmarshaler):
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
class OptionalUnmarshalerFactory(UnmarshalerFactory):
|
|
44
|
-
def
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return None
|
|
44
|
+
def guard(self, ctx: UnmarshalContext, rty: rfl.Type) -> bool:
|
|
45
|
+
return isinstance(rty, rfl.Union) and rty.is_optional
|
|
46
|
+
|
|
47
|
+
def fn(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
|
|
48
|
+
return OptionalUnmarshaler(ctx.make(check.isinstance(rty, rfl.Union).without_none()))
|
omlish/marshal/polymorphism.py
CHANGED
|
@@ -19,12 +19,29 @@ from .base import Unmarshaler
|
|
|
19
19
|
from .base import UnmarshalerFactory
|
|
20
20
|
from .naming import Naming
|
|
21
21
|
from .naming import translate_name
|
|
22
|
+
from .registries import RegistryItem
|
|
22
23
|
from .values import Value
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
##
|
|
26
27
|
|
|
27
28
|
|
|
29
|
+
class TypeTagging(RegistryItem, lang.Abstract, lang.Sealed):
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class WrapperTypeTagging(TypeTagging, lang.Final):
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dc.dataclass(frozen=True)
|
|
38
|
+
class FieldTypeTagging(TypeTagging, lang.Final):
|
|
39
|
+
field: str
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
##
|
|
43
|
+
|
|
44
|
+
|
|
28
45
|
@dc.dataclass(frozen=True)
|
|
29
46
|
class Impl:
|
|
30
47
|
ty: type
|
|
@@ -33,7 +50,11 @@ class Impl:
|
|
|
33
50
|
|
|
34
51
|
|
|
35
52
|
class Polymorphism:
|
|
36
|
-
def __init__(
|
|
53
|
+
def __init__(
|
|
54
|
+
self,
|
|
55
|
+
ty: type,
|
|
56
|
+
impls: ta.Iterable[Impl],
|
|
57
|
+
) -> None:
|
|
37
58
|
super().__init__()
|
|
38
59
|
self._ty = ty
|
|
39
60
|
self._impls = list(impls)
|
|
@@ -72,7 +93,11 @@ class Polymorphism:
|
|
|
72
93
|
return self._by_tag
|
|
73
94
|
|
|
74
95
|
|
|
75
|
-
def polymorphism_from_subclasses(
|
|
96
|
+
def polymorphism_from_subclasses(
|
|
97
|
+
ty: type,
|
|
98
|
+
*,
|
|
99
|
+
naming: Naming | None = None,
|
|
100
|
+
) -> Polymorphism:
|
|
76
101
|
dct: dict[str, Impl] = {}
|
|
77
102
|
seen: set[type] = set()
|
|
78
103
|
todo: list[type] = [ty]
|
|
@@ -97,7 +122,7 @@ def polymorphism_from_subclasses(ty: type, *, naming: Naming | None = None) -> P
|
|
|
97
122
|
|
|
98
123
|
|
|
99
124
|
@dc.dataclass(frozen=True)
|
|
100
|
-
class
|
|
125
|
+
class WrapperPolymorphismMarshaler(Marshaler):
|
|
101
126
|
m: ta.Mapping[type, tuple[str, Marshaler]]
|
|
102
127
|
|
|
103
128
|
def marshal(self, ctx: MarshalContext, o: ta.Any | None) -> Value:
|
|
@@ -105,24 +130,43 @@ class PolymorphismMarshaler(Marshaler):
|
|
|
105
130
|
return {tag: m.marshal(ctx, o)}
|
|
106
131
|
|
|
107
132
|
|
|
133
|
+
@dc.dataclass(frozen=True)
|
|
134
|
+
class FieldPolymorphismMarshaler(Marshaler):
|
|
135
|
+
m: ta.Mapping[type, tuple[str, Marshaler]]
|
|
136
|
+
tf: str
|
|
137
|
+
|
|
138
|
+
def marshal(self, ctx: MarshalContext, o: ta.Any | None) -> Value:
|
|
139
|
+
tag, m = self.m[type(o)]
|
|
140
|
+
return {self.tf: tag, **m.marshal(ctx, o)} # type: ignore
|
|
141
|
+
|
|
142
|
+
|
|
108
143
|
@dc.dataclass(frozen=True)
|
|
109
144
|
class PolymorphismMarshalerFactory(MarshalerFactory):
|
|
110
145
|
p: Polymorphism
|
|
146
|
+
tt: TypeTagging = WrapperTypeTagging()
|
|
111
147
|
|
|
112
|
-
def
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
148
|
+
def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
|
|
149
|
+
return rty is self.p.ty
|
|
150
|
+
|
|
151
|
+
def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
|
|
152
|
+
check.is_(rty, self.p.ty)
|
|
153
|
+
m = {
|
|
154
|
+
i.ty: (i.tag, ctx.make(i.ty))
|
|
155
|
+
for i in self.p.impls
|
|
156
|
+
}
|
|
157
|
+
if isinstance(self.tt, WrapperTypeTagging):
|
|
158
|
+
return WrapperPolymorphismMarshaler(m)
|
|
159
|
+
elif isinstance(self.tt, FieldTypeTagging):
|
|
160
|
+
return FieldPolymorphismMarshaler(m, self.tt.field)
|
|
161
|
+
else:
|
|
162
|
+
raise TypeError(self.tt)
|
|
119
163
|
|
|
120
164
|
|
|
121
165
|
##
|
|
122
166
|
|
|
123
167
|
|
|
124
168
|
@dc.dataclass(frozen=True)
|
|
125
|
-
class
|
|
169
|
+
class WrapperPolymorphismUnmarshaler(Unmarshaler):
|
|
126
170
|
m: ta.Mapping[str, Unmarshaler]
|
|
127
171
|
|
|
128
172
|
def unmarshal(self, ctx: UnmarshalContext, v: Value) -> ta.Any | None:
|
|
@@ -132,16 +176,37 @@ class PolymorphismUnmarshaler(Unmarshaler):
|
|
|
132
176
|
return u.unmarshal(ctx, iv) # type: ignore
|
|
133
177
|
|
|
134
178
|
|
|
179
|
+
@dc.dataclass(frozen=True)
|
|
180
|
+
class FieldPolymorphismUnmarshaler(Unmarshaler):
|
|
181
|
+
m: ta.Mapping[str, Unmarshaler]
|
|
182
|
+
tf: str
|
|
183
|
+
|
|
184
|
+
def unmarshal(self, ctx: UnmarshalContext, v: Value) -> ta.Any | None:
|
|
185
|
+
ma = dict(check.isinstance(v, collections.abc.Mapping))
|
|
186
|
+
tag = ma.pop(self.tf) # type: ignore
|
|
187
|
+
u = self.m[tag] # type: ignore
|
|
188
|
+
return u.unmarshal(ctx, ma)
|
|
189
|
+
|
|
190
|
+
|
|
135
191
|
@dc.dataclass(frozen=True)
|
|
136
192
|
class PolymorphismUnmarshalerFactory(UnmarshalerFactory):
|
|
137
193
|
p: Polymorphism
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
194
|
+
tt: TypeTagging = WrapperTypeTagging()
|
|
195
|
+
|
|
196
|
+
def guard(self, ctx: UnmarshalContext, rty: rfl.Type) -> bool:
|
|
197
|
+
return rty is self.p.ty
|
|
198
|
+
|
|
199
|
+
def fn(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
|
|
200
|
+
check.is_(rty, self.p.ty)
|
|
201
|
+
m = {
|
|
202
|
+
t: u
|
|
203
|
+
for i in self.p.impls
|
|
204
|
+
for u in [ctx.make(i.ty)]
|
|
205
|
+
for t in [i.tag, *i.alts]
|
|
206
|
+
}
|
|
207
|
+
if isinstance(self.tt, WrapperTypeTagging):
|
|
208
|
+
return WrapperPolymorphismUnmarshaler(m)
|
|
209
|
+
elif isinstance(self.tt, FieldTypeTagging):
|
|
210
|
+
return FieldPolymorphismUnmarshaler(m, self.tt.field)
|
|
211
|
+
else:
|
|
212
|
+
raise TypeError(self.tt)
|
omlish/marshal/primitives.py
CHANGED
|
@@ -2,11 +2,10 @@ import typing as ta
|
|
|
2
2
|
|
|
3
3
|
from .base import MarshalContext
|
|
4
4
|
from .base import Marshaler
|
|
5
|
-
from .base import
|
|
5
|
+
from .base import TypeMapMarshalerFactory
|
|
6
|
+
from .base import TypeMapUnmarshalerFactory
|
|
6
7
|
from .base import UnmarshalContext
|
|
7
8
|
from .base import Unmarshaler
|
|
8
|
-
from .base import UnmarshalerFactory
|
|
9
|
-
from .factories import TypeMapFactory
|
|
10
9
|
from .values import Value
|
|
11
10
|
|
|
12
11
|
|
|
@@ -34,10 +33,10 @@ class PrimitiveMarshalerUnmarshaler(Marshaler, Unmarshaler):
|
|
|
34
33
|
|
|
35
34
|
PRIMITIVE_MARSHALER_UNMARSHALER = PrimitiveMarshalerUnmarshaler()
|
|
36
35
|
|
|
37
|
-
PRIMITIVE_MARSHALER_FACTORY
|
|
36
|
+
PRIMITIVE_MARSHALER_FACTORY = TypeMapMarshalerFactory({ # noqa
|
|
38
37
|
t: PRIMITIVE_MARSHALER_UNMARSHALER for t in PRIMITIVE_TYPES
|
|
39
38
|
})
|
|
40
39
|
|
|
41
|
-
PRIMITIVE_UNMARSHALER_FACTORY
|
|
40
|
+
PRIMITIVE_UNMARSHALER_FACTORY = TypeMapUnmarshalerFactory({ # noqa
|
|
42
41
|
t: PRIMITIVE_MARSHALER_UNMARSHALER for t in PRIMITIVE_TYPES
|
|
43
42
|
})
|
omlish/marshal/standard.py
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
from .. import matchfns as mfs
|
|
1
2
|
from .any import ANY_MARSHALER_FACTORY
|
|
2
3
|
from .any import ANY_UNMARSHALER_FACTORY
|
|
3
4
|
from .base import MarshalerFactory
|
|
4
5
|
from .base import RecursiveMarshalerFactory
|
|
5
6
|
from .base import RecursiveUnmarshalerFactory
|
|
7
|
+
from .base import TypeCacheMarshalerFactory
|
|
8
|
+
from .base import TypeCacheUnmarshalerFactory
|
|
6
9
|
from .base import UnmarshalerFactory
|
|
7
10
|
from .base64 import BASE64_MARSHALER_FACTORY
|
|
8
11
|
from .base64 import BASE64_UNMARSHALER_FACTORY
|
|
@@ -12,12 +15,12 @@ from .datetimes import DATETIME_MARSHALER_FACTORY
|
|
|
12
15
|
from .datetimes import DATETIME_UNMARSHALER_FACTORY
|
|
13
16
|
from .enums import EnumMarshalerFactory
|
|
14
17
|
from .enums import EnumUnmarshalerFactory
|
|
15
|
-
from .factories import CompositeFactory
|
|
16
|
-
from .factories import TypeCacheFactory
|
|
17
18
|
from .iterables import IterableMarshalerFactory
|
|
18
19
|
from .iterables import IterableUnmarshalerFactory
|
|
19
20
|
from .mappings import MappingMarshalerFactory
|
|
20
21
|
from .mappings import MappingUnmarshalerFactory
|
|
22
|
+
from .numbers import NUMBERS_MARSHALER_FACTORY
|
|
23
|
+
from .numbers import NUMBERS_UNMARSHALER_FACTORY
|
|
21
24
|
from .optionals import OptionalMarshalerFactory
|
|
22
25
|
from .optionals import OptionalUnmarshalerFactory
|
|
23
26
|
from .primitives import PRIMITIVE_MARSHALER_FACTORY
|
|
@@ -34,6 +37,7 @@ STANDARD_MARSHALER_FACTORIES: list[MarshalerFactory] = [
|
|
|
34
37
|
OptionalMarshalerFactory(),
|
|
35
38
|
DataclassMarshalerFactory(),
|
|
36
39
|
EnumMarshalerFactory(),
|
|
40
|
+
NUMBERS_MARSHALER_FACTORY,
|
|
37
41
|
UUID_MARSHALER_FACTORY,
|
|
38
42
|
BASE64_MARSHALER_FACTORY,
|
|
39
43
|
DATETIME_MARSHALER_FACTORY,
|
|
@@ -44,10 +48,10 @@ STANDARD_MARSHALER_FACTORIES: list[MarshalerFactory] = [
|
|
|
44
48
|
|
|
45
49
|
|
|
46
50
|
def new_standard_marshaler_factory() -> MarshalerFactory:
|
|
47
|
-
return
|
|
51
|
+
return TypeCacheMarshalerFactory(
|
|
48
52
|
RecursiveMarshalerFactory(
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
mfs.MultiMatchFn(
|
|
54
|
+
list(STANDARD_MARSHALER_FACTORIES),
|
|
51
55
|
),
|
|
52
56
|
),
|
|
53
57
|
)
|
|
@@ -61,6 +65,7 @@ STANDARD_UNMARSHALER_FACTORIES: list[UnmarshalerFactory] = [
|
|
|
61
65
|
OptionalUnmarshalerFactory(),
|
|
62
66
|
DataclassUnmarshalerFactory(),
|
|
63
67
|
EnumUnmarshalerFactory(),
|
|
68
|
+
NUMBERS_UNMARSHALER_FACTORY,
|
|
64
69
|
UUID_UNMARSHALER_FACTORY,
|
|
65
70
|
BASE64_UNMARSHALER_FACTORY,
|
|
66
71
|
DATETIME_UNMARSHALER_FACTORY,
|
|
@@ -71,10 +76,10 @@ STANDARD_UNMARSHALER_FACTORIES: list[UnmarshalerFactory] = [
|
|
|
71
76
|
|
|
72
77
|
|
|
73
78
|
def new_standard_unmarshaler_factory() -> UnmarshalerFactory:
|
|
74
|
-
return
|
|
79
|
+
return TypeCacheUnmarshalerFactory(
|
|
75
80
|
RecursiveUnmarshalerFactory(
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
mfs.MultiMatchFn(
|
|
82
|
+
list(STANDARD_UNMARSHALER_FACTORIES),
|
|
78
83
|
),
|
|
79
84
|
),
|
|
80
85
|
)
|
omlish/marshal/uuids.py
CHANGED
|
@@ -4,11 +4,10 @@ import uuid
|
|
|
4
4
|
from .. import check
|
|
5
5
|
from .base import MarshalContext
|
|
6
6
|
from .base import Marshaler
|
|
7
|
-
from .base import
|
|
7
|
+
from .base import TypeMapMarshalerFactory
|
|
8
|
+
from .base import TypeMapUnmarshalerFactory
|
|
8
9
|
from .base import UnmarshalContext
|
|
9
10
|
from .base import Unmarshaler
|
|
10
|
-
from .base import UnmarshalerFactory
|
|
11
|
-
from .factories import TypeMapFactory
|
|
12
11
|
from .values import Value
|
|
13
12
|
|
|
14
13
|
|
|
@@ -25,5 +24,5 @@ class UuidMarshalerUnmarshaler(Marshaler, Unmarshaler):
|
|
|
25
24
|
|
|
26
25
|
UUID_MARSHALER_UNMARSHALER = UuidMarshalerUnmarshaler()
|
|
27
26
|
|
|
28
|
-
UUID_MARSHALER_FACTORY
|
|
29
|
-
UUID_UNMARSHALER_FACTORY
|
|
27
|
+
UUID_MARSHALER_FACTORY = TypeMapMarshalerFactory({uuid.UUID: UUID_MARSHALER_UNMARSHALER})
|
|
28
|
+
UUID_UNMARSHALER_FACTORY = TypeMapUnmarshalerFactory({uuid.UUID: UUID_MARSHALER_UNMARSHALER})
|