omlish 0.0.0.dev227__py3-none-any.whl → 0.0.0.dev229__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|