omlish 0.0.0.dev227__py3-none-any.whl → 0.0.0.dev229__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 +3 -3
- omlish/diag/lsof.py +4 -5
- omlish/diag/ps.py +9 -0
- omlish/lite/timeouts.py +1 -1
- omlish/marshal/__init__.py +39 -24
- omlish/marshal/composite/__init__.py +0 -0
- omlish/marshal/{iterables.py → composite/iterables.py} +10 -10
- omlish/marshal/{literals.py → composite/literals.py} +9 -9
- omlish/marshal/{mappings.py → composite/mappings.py} +10 -10
- omlish/marshal/{maybes.py → composite/maybes.py} +11 -11
- omlish/marshal/{newtypes.py → composite/newtypes.py} +8 -8
- omlish/marshal/{optionals.py → composite/optionals.py} +9 -9
- omlish/marshal/objects/__init__.py +7 -0
- omlish/marshal/{dataclasses.py → objects/dataclasses.py} +24 -24
- omlish/marshal/{helpers.py → objects/helpers.py} +6 -3
- omlish/marshal/objects/marshal.py +108 -0
- omlish/marshal/objects/metadata.py +124 -0
- omlish/marshal/{namedtuples.py → objects/namedtuples.py} +16 -16
- omlish/marshal/objects/unmarshal.py +141 -0
- omlish/marshal/polymorphism/__init__.py +7 -0
- omlish/marshal/polymorphism/marshal.py +66 -0
- omlish/marshal/polymorphism/metadata.py +140 -0
- omlish/marshal/{unions.py → polymorphism/unions.py} +18 -18
- omlish/marshal/polymorphism/unmarshal.py +73 -0
- omlish/marshal/singular/__init__.py +0 -0
- omlish/marshal/{any.py → singular/any.py} +8 -8
- omlish/marshal/{base64.py → singular/base64.py} +9 -9
- omlish/marshal/{datetimes.py → singular/datetimes.py} +9 -9
- omlish/marshal/{enums.py → singular/enums.py} +9 -9
- omlish/marshal/{numbers.py → singular/numbers.py} +8 -8
- omlish/marshal/{primitives.py → singular/primitives.py} +8 -8
- omlish/marshal/{uuids.py → singular/uuids.py} +8 -8
- omlish/marshal/standard.py +32 -32
- omlish/os/death.py +72 -4
- omlish/os/fcntl.py +11 -12
- omlish/os/files.py +18 -3
- omlish/os/forkhooks.py +215 -0
- omlish/os/pidfiles/pinning.py +4 -0
- omlish/sockets/bind.py +4 -4
- {omlish-0.0.0.dev227.dist-info → omlish-0.0.0.dev229.dist-info}/METADATA +3 -3
- {omlish-0.0.0.dev227.dist-info → omlish-0.0.0.dev229.dist-info}/RECORD +45 -36
- omlish/marshal/objects.py +0 -317
- omlish/marshal/polymorphism.py +0 -267
- {omlish-0.0.0.dev227.dist-info → omlish-0.0.0.dev229.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev227.dist-info → omlish-0.0.0.dev229.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev227.dist-info → omlish-0.0.0.dev229.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev227.dist-info → omlish-0.0.0.dev229.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
__version__ = '0.0.0.
|
2
|
-
__revision__ = '
|
1
|
+
__version__ = '0.0.0.dev229'
|
2
|
+
__revision__ = '646f2d8caaef32d279a6ebcfd121449752fbae93'
|
3
3
|
|
4
4
|
|
5
5
|
#
|
@@ -79,7 +79,7 @@ class Project(ProjectBase):
|
|
79
79
|
],
|
80
80
|
|
81
81
|
'secrets': [
|
82
|
-
'cryptography ~=
|
82
|
+
'cryptography ~= 44.0',
|
83
83
|
],
|
84
84
|
|
85
85
|
'sqlalchemy': [
|
omlish/diag/lsof.py
CHANGED
@@ -2,9 +2,6 @@
|
|
2
2
|
# @omlish-lite
|
3
3
|
"""
|
4
4
|
https://man7.org/linux/man-pages/man8/lsof.8.html
|
5
|
-
|
6
|
-
Included in the process set are fields that identify the command, the process group IDentification (PGID) number, the
|
7
|
-
task (thread) ID (TID), and the user ID (UID) number or login name.
|
8
5
|
"""
|
9
6
|
import dataclasses as dc
|
10
7
|
import enum
|
@@ -215,8 +212,7 @@ LsofItem._DEFAULT_PREFIXES = ''.join(LsofItem._FIELDS_BY_PREFIX) # noqa
|
|
215
212
|
|
216
213
|
|
217
214
|
@dc.dataclass(frozen=True)
|
218
|
-
class
|
219
|
-
LsofCommand(SubprocessRunnable[ta.List[LsofItem]]):
|
215
|
+
class LsofCommand(SubprocessRunnable[ta.List[LsofItem]]):
|
220
216
|
pid: ta.Optional[int] = None
|
221
217
|
file: ta.Optional[str] = None
|
222
218
|
|
@@ -242,6 +238,9 @@ class \
|
|
242
238
|
return LsofItem.from_prefix_lines(lines)
|
243
239
|
|
244
240
|
|
241
|
+
##
|
242
|
+
|
243
|
+
|
245
244
|
if __name__ == '__main__':
|
246
245
|
def _main() -> None:
|
247
246
|
argparse = __import__('argparse')
|
omlish/diag/ps.py
CHANGED
@@ -12,6 +12,9 @@ from ..subprocesses.run import SubprocessRunOutput
|
|
12
12
|
from ..subprocesses.sync import subprocesses
|
13
13
|
|
14
14
|
|
15
|
+
##
|
16
|
+
|
17
|
+
|
15
18
|
@dc.dataclass(frozen=True)
|
16
19
|
class PsItem:
|
17
20
|
pid: int
|
@@ -43,6 +46,9 @@ class PsCommand(SubprocessRunnable):
|
|
43
46
|
)
|
44
47
|
|
45
48
|
|
49
|
+
##
|
50
|
+
|
51
|
+
|
46
52
|
def get_ps_item(pid: int, timeout: ta.Optional[Timeout] = None) -> PsItem:
|
47
53
|
return PsCommand(pid).run(subprocesses, timeout=timeout)
|
48
54
|
|
@@ -59,6 +65,9 @@ def get_ps_lineage(pid: int, timeout: ta.Optional[Timeout] = None) -> ta.List[Ps
|
|
59
65
|
return ret
|
60
66
|
|
61
67
|
|
68
|
+
##
|
69
|
+
|
70
|
+
|
62
71
|
if __name__ == '__main__':
|
63
72
|
def _main() -> None:
|
64
73
|
print(get_ps_lineage(os.getpid()))
|
omlish/lite/timeouts.py
CHANGED
omlish/marshal/__init__.py
CHANGED
@@ -42,14 +42,11 @@ from .forbidden import ( # noqa
|
|
42
42
|
from .global_ import ( # noqa
|
43
43
|
GLOBAL_REGISTRY,
|
44
44
|
|
45
|
+
global_marshaler_factory,
|
45
46
|
marshal,
|
46
|
-
unmarshal,
|
47
|
-
)
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
update_fields_metadata,
|
52
|
-
update_object_metadata,
|
48
|
+
global_unmarshaler_factory,
|
49
|
+
unmarshal,
|
53
50
|
)
|
54
51
|
|
55
52
|
from .naming import ( # noqa
|
@@ -62,31 +59,59 @@ from .nop import ( # noqa
|
|
62
59
|
NopMarshalerUnmarshaler,
|
63
60
|
)
|
64
61
|
|
65
|
-
from .objects import ( # noqa
|
62
|
+
from .objects.helpers import ( # noqa
|
63
|
+
update_field_metadata,
|
64
|
+
update_fields_metadata,
|
65
|
+
update_object_metadata,
|
66
|
+
)
|
67
|
+
|
68
|
+
from .objects.marshal import ( # noqa
|
69
|
+
ObjectMarshaler,
|
70
|
+
SimpleObjectMarshalerFactory,
|
71
|
+
)
|
72
|
+
|
73
|
+
from .objects.metadata import ( # noqa
|
66
74
|
FieldInfo,
|
67
75
|
FieldInfos,
|
68
76
|
FieldMetadata,
|
69
77
|
FieldOptions,
|
70
|
-
ObjectMarshaler,
|
71
78
|
ObjectMetadata,
|
72
79
|
ObjectSpecials,
|
80
|
+
)
|
81
|
+
|
82
|
+
from .objects.unmarshal import ( # noqa
|
73
83
|
ObjectUnmarshaler,
|
74
|
-
SimpleObjectMarshalerFactory,
|
75
84
|
SimpleObjectUnmarshalerFactory,
|
76
85
|
)
|
77
86
|
|
78
|
-
from .polymorphism import ( # noqa
|
87
|
+
from .polymorphism.marshal import ( # noqa
|
88
|
+
PolymorphismMarshalerFactory,
|
89
|
+
make_polymorphism_marshaler,
|
90
|
+
)
|
91
|
+
|
92
|
+
from .polymorphism.metadata import ( # noqa
|
79
93
|
Impl,
|
80
94
|
Impls,
|
81
95
|
Polymorphism,
|
82
|
-
|
96
|
+
polymorphism_from_subclasses,
|
97
|
+
)
|
98
|
+
|
99
|
+
from .polymorphism.unions import ( # noqa
|
100
|
+
PRIMITIVE_UNION_TYPES,
|
101
|
+
PolymorphismUnionMarshalerFactory,
|
102
|
+
PolymorphismUnionUnmarshalerFactory,
|
103
|
+
PrimitiveUnionMarshaler,
|
104
|
+
PrimitiveUnionMarshalerFactory,
|
105
|
+
PrimitiveUnionUnmarshaler,
|
106
|
+
PrimitiveUnionUnmarshalerFactory,
|
107
|
+
)
|
108
|
+
|
109
|
+
from .polymorphism.unmarshal import ( # noqa
|
83
110
|
PolymorphismUnmarshalerFactory,
|
84
|
-
make_polymorphism_marshaler,
|
85
111
|
make_polymorphism_unmarshaler,
|
86
|
-
polymorphism_from_subclasses,
|
87
112
|
)
|
88
113
|
|
89
|
-
from .primitives import ( # noqa
|
114
|
+
from .singular.primitives import ( # noqa
|
90
115
|
PRIMITIVE_TYPES,
|
91
116
|
)
|
92
117
|
|
@@ -102,16 +127,6 @@ from .standard import ( # noqa
|
|
102
127
|
new_standard_unmarshaler_factory,
|
103
128
|
)
|
104
129
|
|
105
|
-
from .unions import ( # noqa
|
106
|
-
PRIMITIVE_UNION_TYPES,
|
107
|
-
PolymorphismUnionMarshalerFactory,
|
108
|
-
PolymorphismUnionUnmarshalerFactory,
|
109
|
-
PrimitiveUnionMarshaler,
|
110
|
-
PrimitiveUnionMarshalerFactory,
|
111
|
-
PrimitiveUnionUnmarshaler,
|
112
|
-
PrimitiveUnionUnmarshalerFactory,
|
113
|
-
)
|
114
|
-
|
115
130
|
from .values import ( # noqa
|
116
131
|
Value,
|
117
132
|
)
|
File without changes
|
@@ -7,16 +7,16 @@ import dataclasses as dc
|
|
7
7
|
import functools
|
8
8
|
import typing as ta
|
9
9
|
|
10
|
-
from
|
11
|
-
from
|
12
|
-
from
|
13
|
-
from
|
14
|
-
from
|
15
|
-
from
|
16
|
-
from
|
17
|
-
from
|
18
|
-
from
|
19
|
-
from
|
10
|
+
from ... import check
|
11
|
+
from ... import reflect as rfl
|
12
|
+
from ...funcs import match as mfs
|
13
|
+
from ..base import MarshalContext
|
14
|
+
from ..base import Marshaler
|
15
|
+
from ..base import MarshalerFactoryMatchClass
|
16
|
+
from ..base import UnmarshalContext
|
17
|
+
from ..base import Unmarshaler
|
18
|
+
from ..base import UnmarshalerFactoryMatchClass
|
19
|
+
from ..values import Value
|
20
20
|
|
21
21
|
|
22
22
|
DEFAULT_ITERABLE_CONCRETE_TYPES: dict[type[collections.abc.Iterable], type[collections.abc.Iterable]] = {
|
@@ -1,15 +1,15 @@
|
|
1
1
|
import dataclasses as dc
|
2
2
|
import typing as ta
|
3
3
|
|
4
|
-
from
|
5
|
-
from
|
6
|
-
from
|
7
|
-
from
|
8
|
-
from
|
9
|
-
from
|
10
|
-
from
|
11
|
-
from
|
12
|
-
from
|
4
|
+
from ... import check
|
5
|
+
from ... import reflect as rfl
|
6
|
+
from ..base import MarshalContext
|
7
|
+
from ..base import Marshaler
|
8
|
+
from ..base import MarshalerFactory
|
9
|
+
from ..base import UnmarshalContext
|
10
|
+
from ..base import Unmarshaler
|
11
|
+
from ..base import UnmarshalerFactory
|
12
|
+
from ..values import Value
|
13
13
|
|
14
14
|
|
15
15
|
@dc.dataclass(frozen=True)
|
@@ -2,16 +2,16 @@ import collections.abc
|
|
2
2
|
import dataclasses as dc
|
3
3
|
import typing as ta
|
4
4
|
|
5
|
-
from
|
6
|
-
from
|
7
|
-
from
|
8
|
-
from
|
9
|
-
from
|
10
|
-
from
|
11
|
-
from
|
12
|
-
from
|
13
|
-
from
|
14
|
-
from
|
5
|
+
from ... import check
|
6
|
+
from ... import reflect as rfl
|
7
|
+
from ...funcs import match as mfs
|
8
|
+
from ..base import MarshalContext
|
9
|
+
from ..base import Marshaler
|
10
|
+
from ..base import MarshalerFactoryMatchClass
|
11
|
+
from ..base import UnmarshalContext
|
12
|
+
from ..base import Unmarshaler
|
13
|
+
from ..base import UnmarshalerFactoryMatchClass
|
14
|
+
from ..values import Value
|
15
15
|
|
16
16
|
|
17
17
|
DEFAULT_MAPPING_CONCRETE_TYPES: dict[type[collections.abc.Mapping], type[collections.abc.Mapping]] = {
|
@@ -5,17 +5,17 @@ TODO:
|
|
5
5
|
import dataclasses as dc
|
6
6
|
import typing as ta
|
7
7
|
|
8
|
-
from
|
9
|
-
from
|
10
|
-
from
|
11
|
-
from
|
12
|
-
from
|
13
|
-
from
|
14
|
-
from
|
15
|
-
from
|
16
|
-
from
|
17
|
-
from
|
18
|
-
from
|
8
|
+
from ... import check
|
9
|
+
from ... import lang
|
10
|
+
from ... import reflect as rfl
|
11
|
+
from ...funcs import match as mfs
|
12
|
+
from ..base import MarshalContext
|
13
|
+
from ..base import Marshaler
|
14
|
+
from ..base import MarshalerFactoryMatchClass
|
15
|
+
from ..base import UnmarshalContext
|
16
|
+
from ..base import Unmarshaler
|
17
|
+
from ..base import UnmarshalerFactoryMatchClass
|
18
|
+
from ..values import Value
|
19
19
|
|
20
20
|
|
21
21
|
@dc.dataclass(frozen=True)
|
@@ -1,11 +1,11 @@
|
|
1
|
-
from
|
2
|
-
from
|
3
|
-
from
|
4
|
-
from
|
5
|
-
from
|
6
|
-
from
|
7
|
-
from
|
8
|
-
from
|
1
|
+
from ... import check
|
2
|
+
from ... import reflect as rfl
|
3
|
+
from ..base import MarshalContext
|
4
|
+
from ..base import Marshaler
|
5
|
+
from ..base import MarshalerFactory
|
6
|
+
from ..base import UnmarshalContext
|
7
|
+
from ..base import Unmarshaler
|
8
|
+
from ..base import UnmarshalerFactory
|
9
9
|
|
10
10
|
|
11
11
|
class NewtypeMarshalerFactory(MarshalerFactory):
|
@@ -1,15 +1,15 @@
|
|
1
1
|
import dataclasses as dc
|
2
2
|
import typing as ta
|
3
3
|
|
4
|
-
from
|
5
|
-
from
|
6
|
-
from
|
7
|
-
from
|
8
|
-
from
|
9
|
-
from
|
10
|
-
from
|
11
|
-
from
|
12
|
-
from
|
4
|
+
from ... import check
|
5
|
+
from ... import reflect as rfl
|
6
|
+
from ..base import MarshalContext
|
7
|
+
from ..base import Marshaler
|
8
|
+
from ..base import MarshalerFactory
|
9
|
+
from ..base import UnmarshalContext
|
10
|
+
from ..base import Unmarshaler
|
11
|
+
from ..base import UnmarshalerFactory
|
12
|
+
from ..values import Value
|
13
13
|
|
14
14
|
|
15
15
|
@dc.dataclass(frozen=True)
|
@@ -4,30 +4,30 @@ TODO:
|
|
4
4
|
"""
|
5
5
|
import typing as ta
|
6
6
|
|
7
|
-
from
|
8
|
-
from
|
9
|
-
from
|
10
|
-
from
|
11
|
-
from
|
12
|
-
from
|
13
|
-
from
|
14
|
-
from
|
15
|
-
from
|
16
|
-
from
|
17
|
-
from
|
18
|
-
from
|
19
|
-
from
|
20
|
-
from
|
21
|
-
from
|
22
|
-
from .
|
23
|
-
from .
|
24
|
-
from .
|
25
|
-
from .
|
26
|
-
from .
|
27
|
-
from .
|
28
|
-
from .
|
29
|
-
from .
|
30
|
-
from .
|
7
|
+
from ... import check
|
8
|
+
from ... import collections as col
|
9
|
+
from ... import dataclasses as dc
|
10
|
+
from ... import lang
|
11
|
+
from ... import reflect as rfl
|
12
|
+
from ...lite import marshal as lm
|
13
|
+
from ..base import MarshalContext
|
14
|
+
from ..base import Marshaler
|
15
|
+
from ..base import MarshalerFactory
|
16
|
+
from ..base import Option
|
17
|
+
from ..base import UnmarshalContext
|
18
|
+
from ..base import Unmarshaler
|
19
|
+
from ..base import UnmarshalerFactory
|
20
|
+
from ..naming import Naming
|
21
|
+
from ..naming import translate_name
|
22
|
+
from .marshal import ObjectMarshaler
|
23
|
+
from .metadata import DEFAULT_FIELD_OPTIONS
|
24
|
+
from .metadata import FIELD_OPTIONS_KWARGS
|
25
|
+
from .metadata import FieldInfo
|
26
|
+
from .metadata import FieldInfos
|
27
|
+
from .metadata import FieldMetadata
|
28
|
+
from .metadata import FieldOptions
|
29
|
+
from .metadata import ObjectMetadata
|
30
|
+
from .unmarshal import ObjectUnmarshaler
|
31
31
|
|
32
32
|
|
33
33
|
##
|
@@ -1,13 +1,16 @@
|
|
1
1
|
import typing as ta
|
2
2
|
|
3
|
-
from
|
4
|
-
from .
|
5
|
-
from .
|
3
|
+
from ... import dataclasses as dc
|
4
|
+
from .metadata import FieldMetadata
|
5
|
+
from .metadata import ObjectMetadata
|
6
6
|
|
7
7
|
|
8
8
|
T = ta.TypeVar('T')
|
9
9
|
|
10
10
|
|
11
|
+
##
|
12
|
+
|
13
|
+
|
11
14
|
def update_field_metadata(**kwargs: ta.Any) -> dc.field_modifier:
|
12
15
|
@dc.field_modifier
|
13
16
|
def inner(f: dc.Field) -> dc.Field:
|
@@ -0,0 +1,108 @@
|
|
1
|
+
import collections.abc
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from ... import check
|
5
|
+
from ... import dataclasses as dc
|
6
|
+
from ... import reflect as rfl
|
7
|
+
from ..base import MarshalContext
|
8
|
+
from ..base import Marshaler
|
9
|
+
from ..base import MarshalerFactory
|
10
|
+
from ..values import Value
|
11
|
+
from .metadata import FieldInfo
|
12
|
+
from .metadata import FieldInfos
|
13
|
+
from .metadata import ObjectSpecials
|
14
|
+
|
15
|
+
|
16
|
+
##
|
17
|
+
|
18
|
+
|
19
|
+
@dc.dataclass(frozen=True)
|
20
|
+
class ObjectMarshaler(Marshaler):
|
21
|
+
fields: ta.Sequence[tuple[FieldInfo, Marshaler]]
|
22
|
+
|
23
|
+
_: dc.KW_ONLY
|
24
|
+
|
25
|
+
specials: ObjectSpecials = ObjectSpecials()
|
26
|
+
|
27
|
+
attr_getter: ta.Callable[[ta.Any, str], ta.Any] | None = None
|
28
|
+
|
29
|
+
@classmethod
|
30
|
+
def make(
|
31
|
+
cls,
|
32
|
+
ctx: MarshalContext,
|
33
|
+
fis: FieldInfos,
|
34
|
+
**kwargs: ta.Any,
|
35
|
+
) -> Marshaler:
|
36
|
+
fields = [
|
37
|
+
(fi, ctx.make(fi.type))
|
38
|
+
for fi in fis
|
39
|
+
]
|
40
|
+
|
41
|
+
return cls(
|
42
|
+
fields,
|
43
|
+
**kwargs,
|
44
|
+
)
|
45
|
+
|
46
|
+
#
|
47
|
+
|
48
|
+
def marshal(self, ctx: MarshalContext, o: ta.Any) -> Value:
|
49
|
+
if (attr_getter := self.attr_getter) is None:
|
50
|
+
attr_getter = getattr
|
51
|
+
|
52
|
+
ret: dict[str, ta.Any] = {}
|
53
|
+
for fi, m in self.fields:
|
54
|
+
v = attr_getter(o, fi.name)
|
55
|
+
|
56
|
+
if fi.options.omit_if is not None and fi.options.omit_if(v):
|
57
|
+
continue
|
58
|
+
|
59
|
+
if fi.name in self.specials.set:
|
60
|
+
continue
|
61
|
+
|
62
|
+
mn = fi.marshal_name
|
63
|
+
if mn is None:
|
64
|
+
continue
|
65
|
+
|
66
|
+
mv = m.marshal(ctx, v)
|
67
|
+
|
68
|
+
if fi.options.embed:
|
69
|
+
for ek, ev in check.isinstance(mv, collections.abc.Mapping).items():
|
70
|
+
ret[mn + check.non_empty_str(ek)] = ev
|
71
|
+
|
72
|
+
else:
|
73
|
+
ret[mn] = mv
|
74
|
+
|
75
|
+
if self.specials.unknown is not None:
|
76
|
+
if (ukf := attr_getter(o, self.specials.unknown)):
|
77
|
+
if (dks := set(ret) & set(ukf)):
|
78
|
+
raise KeyError(f'Unknown field keys duplicate fields: {dks!r}')
|
79
|
+
|
80
|
+
ret.update(ukf) # FIXME: marshal?
|
81
|
+
|
82
|
+
return ret
|
83
|
+
|
84
|
+
|
85
|
+
##
|
86
|
+
|
87
|
+
|
88
|
+
@dc.dataclass(frozen=True)
|
89
|
+
class SimpleObjectMarshalerFactory(MarshalerFactory):
|
90
|
+
dct: ta.Mapping[type, ta.Sequence[FieldInfo]]
|
91
|
+
|
92
|
+
_: dc.KW_ONLY
|
93
|
+
|
94
|
+
specials: ObjectSpecials = ObjectSpecials()
|
95
|
+
|
96
|
+
def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
|
97
|
+
return isinstance(rty, type) and rty in self.dct
|
98
|
+
|
99
|
+
def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
|
100
|
+
ty = check.isinstance(rty, type)
|
101
|
+
|
102
|
+
fis = FieldInfos(self.dct[ty])
|
103
|
+
|
104
|
+
return ObjectMarshaler.make(
|
105
|
+
ctx,
|
106
|
+
fis,
|
107
|
+
specials=self.specials,
|
108
|
+
)
|
@@ -0,0 +1,124 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
from ... import cached
|
4
|
+
from ... import collections as col
|
5
|
+
from ... import dataclasses as dc
|
6
|
+
from ... import lang
|
7
|
+
from ..base import Marshaler
|
8
|
+
from ..base import MarshalerFactory
|
9
|
+
from ..base import Unmarshaler
|
10
|
+
from ..base import UnmarshalerFactory
|
11
|
+
from ..naming import Naming
|
12
|
+
|
13
|
+
|
14
|
+
##
|
15
|
+
|
16
|
+
|
17
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
18
|
+
class FieldOptions:
|
19
|
+
omit_if: ta.Callable[[ta.Any], bool] | None = None
|
20
|
+
|
21
|
+
default: lang.Maybe[ta.Any] = dc.xfield(default=lang.empty(), check_type=lang.Maybe)
|
22
|
+
|
23
|
+
embed: bool = False
|
24
|
+
|
25
|
+
no_marshal: bool = False
|
26
|
+
no_unmarshal: bool = False
|
27
|
+
|
28
|
+
|
29
|
+
DEFAULT_FIELD_OPTIONS = FieldOptions()
|
30
|
+
FIELD_OPTIONS_KWARGS: frozenset[str] = frozenset(dc.fields_dict(FieldOptions).keys())
|
31
|
+
|
32
|
+
|
33
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
34
|
+
class FieldMetadata:
|
35
|
+
name: str | None = None
|
36
|
+
alts: ta.Iterable[str] | None = None
|
37
|
+
|
38
|
+
options: FieldOptions = DEFAULT_FIELD_OPTIONS
|
39
|
+
|
40
|
+
marshaler: Marshaler | None = dc.xfield(None, check_type=(Marshaler, None))
|
41
|
+
marshaler_factory: MarshalerFactory | None = None
|
42
|
+
|
43
|
+
unmarshaler: Unmarshaler | None = dc.xfield(None, check_type=(Unmarshaler, None))
|
44
|
+
unmarshaler_factory: UnmarshalerFactory | None = None
|
45
|
+
|
46
|
+
def update(self, **kwargs: ta.Any) -> 'FieldMetadata':
|
47
|
+
okw = {k: v for k, v in kwargs.items() if k in FIELD_OPTIONS_KWARGS}
|
48
|
+
mkw = {k: v for k, v in kwargs.items() if k not in FIELD_OPTIONS_KWARGS}
|
49
|
+
return dc.replace(
|
50
|
+
self,
|
51
|
+
**(dict(options=dc.replace(self.options, **okw)) if okw else {}),
|
52
|
+
**mkw,
|
53
|
+
)
|
54
|
+
|
55
|
+
|
56
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
57
|
+
class ObjectMetadata:
|
58
|
+
field_naming: Naming | None = None
|
59
|
+
|
60
|
+
unknown_field: str | None = None
|
61
|
+
source_field: str | None = None
|
62
|
+
|
63
|
+
@cached.property
|
64
|
+
def specials(self) -> 'ObjectSpecials':
|
65
|
+
return ObjectSpecials(
|
66
|
+
unknown=self.unknown_field,
|
67
|
+
source=self.source_field,
|
68
|
+
)
|
69
|
+
|
70
|
+
field_defaults: FieldMetadata = FieldMetadata()
|
71
|
+
|
72
|
+
ignore_unknown: bool = False
|
73
|
+
|
74
|
+
|
75
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
76
|
+
class ObjectSpecials:
|
77
|
+
unknown: str | None = None
|
78
|
+
source: str | None = None
|
79
|
+
|
80
|
+
@cached.property
|
81
|
+
def set(self) -> frozenset[str]:
|
82
|
+
return frozenset(v for v in dc.asdict(self).values() if v is not None)
|
83
|
+
|
84
|
+
|
85
|
+
##
|
86
|
+
|
87
|
+
|
88
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
89
|
+
class FieldInfo:
|
90
|
+
name: str
|
91
|
+
type: ta.Any
|
92
|
+
|
93
|
+
marshal_name: str | None
|
94
|
+
unmarshal_names: ta.Sequence[str]
|
95
|
+
|
96
|
+
metadata: FieldMetadata = FieldMetadata()
|
97
|
+
|
98
|
+
options: FieldOptions = FieldOptions()
|
99
|
+
|
100
|
+
|
101
|
+
@dc.dataclass(frozen=True)
|
102
|
+
class FieldInfos:
|
103
|
+
lst: ta.Sequence[FieldInfo]
|
104
|
+
|
105
|
+
def __iter__(self) -> ta.Iterator[FieldInfo]:
|
106
|
+
return iter(self.lst)
|
107
|
+
|
108
|
+
def __len__(self) -> int:
|
109
|
+
return len(self.lst)
|
110
|
+
|
111
|
+
@cached.property
|
112
|
+
@dc.init
|
113
|
+
def by_name(self) -> ta.Mapping[str, FieldInfo]:
|
114
|
+
return col.make_map(((fi.name, fi) for fi in self), strict=True)
|
115
|
+
|
116
|
+
@cached.property
|
117
|
+
@dc.init
|
118
|
+
def by_marshal_name(self) -> ta.Mapping[str, FieldInfo]:
|
119
|
+
return col.make_map(((fi.marshal_name, fi) for fi in self if fi.marshal_name is not None), strict=True)
|
120
|
+
|
121
|
+
@cached.property
|
122
|
+
@dc.init
|
123
|
+
def by_unmarshal_name(self) -> ta.Mapping[str, FieldInfo]:
|
124
|
+
return col.make_map(((n, fi) for fi in self for n in fi.unmarshal_names), strict=True)
|