omlish 0.0.0.dev133__py3-none-any.whl → 0.0.0.dev177__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/.manifests.json +265 -7
- omlish/__about__.py +5 -3
- omlish/antlr/_runtime/__init__.py +0 -22
- omlish/antlr/_runtime/_all.py +24 -0
- omlish/antlr/_runtime/atn/ParserATNSimulator.py +1 -1
- omlish/antlr/_runtime/dfa/DFASerializer.py +1 -1
- omlish/antlr/_runtime/error/DiagnosticErrorListener.py +2 -1
- omlish/antlr/_runtime/xpath/XPath.py +7 -1
- omlish/antlr/_runtime/xpath/XPathLexer.py +1 -1
- omlish/antlr/delimit.py +106 -0
- omlish/antlr/dot.py +31 -0
- omlish/antlr/errors.py +11 -0
- omlish/antlr/input.py +96 -0
- omlish/antlr/parsing.py +19 -0
- omlish/antlr/runtime.py +102 -0
- omlish/antlr/utils.py +38 -0
- omlish/argparse/all.py +45 -0
- omlish/{argparse.py → argparse/cli.py} +112 -107
- omlish/asyncs/__init__.py +0 -35
- omlish/asyncs/all.py +35 -0
- omlish/asyncs/asyncio/all.py +7 -0
- omlish/asyncs/asyncio/channels.py +40 -0
- omlish/asyncs/asyncio/streams.py +45 -0
- omlish/asyncs/asyncio/subprocesses.py +238 -0
- omlish/asyncs/asyncio/timeouts.py +16 -0
- omlish/asyncs/bluelet/LICENSE +6 -0
- omlish/asyncs/bluelet/all.py +67 -0
- omlish/asyncs/bluelet/api.py +23 -0
- omlish/asyncs/bluelet/core.py +178 -0
- omlish/asyncs/bluelet/events.py +78 -0
- omlish/asyncs/bluelet/files.py +80 -0
- omlish/asyncs/bluelet/runner.py +416 -0
- omlish/asyncs/bluelet/sockets.py +214 -0
- omlish/bootstrap/sys.py +3 -3
- omlish/cached.py +2 -2
- omlish/check.py +49 -460
- omlish/codecs/__init__.py +72 -0
- omlish/codecs/base.py +106 -0
- omlish/codecs/bytes.py +119 -0
- omlish/codecs/chain.py +23 -0
- omlish/codecs/funcs.py +39 -0
- omlish/codecs/registry.py +139 -0
- omlish/codecs/standard.py +4 -0
- omlish/codecs/text.py +217 -0
- omlish/collections/cache/impl.py +50 -57
- omlish/collections/coerce.py +1 -0
- omlish/collections/mappings.py +1 -1
- omlish/configs/flattening.py +1 -1
- omlish/defs.py +1 -1
- omlish/diag/_pycharm/runhack.py +8 -2
- omlish/diag/procfs.py +8 -8
- omlish/docker/__init__.py +0 -36
- omlish/docker/all.py +31 -0
- omlish/docker/consts.py +4 -0
- omlish/{lite/docker.py → docker/detect.py} +18 -0
- omlish/docker/{helpers.py → timebomb.py} +0 -21
- omlish/formats/cbor.py +31 -0
- omlish/formats/cloudpickle.py +31 -0
- omlish/formats/codecs.py +93 -0
- omlish/formats/json/codecs.py +29 -0
- omlish/formats/json/delimted.py +4 -0
- omlish/formats/json/stream/errors.py +2 -0
- omlish/formats/json/stream/lex.py +12 -6
- omlish/formats/json/stream/parse.py +38 -22
- omlish/formats/json5.py +31 -0
- omlish/formats/pickle.py +31 -0
- omlish/formats/repr.py +25 -0
- omlish/formats/toml.py +17 -0
- omlish/formats/yaml.py +25 -0
- omlish/funcs/__init__.py +0 -0
- omlish/{genmachine.py → funcs/genmachine.py} +5 -4
- omlish/{matchfns.py → funcs/match.py} +1 -1
- omlish/funcs/pairs.py +215 -0
- omlish/http/__init__.py +0 -48
- omlish/http/all.py +48 -0
- omlish/http/coro/__init__.py +0 -0
- omlish/{lite/fdio/corohttp.py → http/coro/fdio.py} +21 -19
- omlish/{lite/http/coroserver.py → http/coro/server.py} +20 -21
- omlish/{lite/http → http}/handlers.py +3 -2
- omlish/{lite/http → http}/parsing.py +1 -0
- omlish/http/sessions.py +1 -1
- omlish/{lite/http → http}/versions.py +1 -0
- omlish/inject/managed.py +2 -2
- omlish/io/__init__.py +0 -3
- omlish/{lite/io.py → io/buffers.py} +8 -9
- omlish/io/compress/__init__.py +9 -0
- omlish/io/compress/abc.py +104 -0
- omlish/io/compress/adapters.py +148 -0
- omlish/io/compress/base.py +24 -0
- omlish/io/compress/brotli.py +47 -0
- omlish/io/compress/bz2.py +61 -0
- omlish/io/compress/codecs.py +78 -0
- omlish/io/compress/gzip.py +350 -0
- omlish/io/compress/lz4.py +91 -0
- omlish/io/compress/lzma.py +81 -0
- omlish/io/compress/snappy.py +34 -0
- omlish/io/compress/zlib.py +74 -0
- omlish/io/compress/zstd.py +44 -0
- omlish/io/fdio/__init__.py +1 -0
- omlish/{lite → io}/fdio/handlers.py +5 -5
- omlish/{lite → io}/fdio/kqueue.py +8 -8
- omlish/{lite → io}/fdio/manager.py +7 -7
- omlish/{lite → io}/fdio/pollers.py +13 -13
- omlish/io/generators/__init__.py +56 -0
- omlish/io/generators/consts.py +1 -0
- omlish/io/generators/direct.py +13 -0
- omlish/io/generators/readers.py +189 -0
- omlish/io/generators/stepped.py +191 -0
- omlish/io/pyio.py +5 -2
- omlish/iterators/__init__.py +24 -0
- omlish/iterators/iterators.py +132 -0
- omlish/iterators/recipes.py +18 -0
- omlish/iterators/tools.py +96 -0
- omlish/iterators/unique.py +67 -0
- omlish/lang/__init__.py +13 -1
- omlish/lang/functions.py +11 -2
- omlish/lang/generators.py +243 -0
- omlish/lang/iterables.py +46 -49
- omlish/lang/maybes.py +4 -4
- omlish/lite/cached.py +39 -6
- omlish/lite/check.py +438 -75
- omlish/lite/contextmanagers.py +17 -4
- omlish/lite/dataclasses.py +42 -0
- omlish/lite/inject.py +28 -45
- omlish/lite/logs.py +0 -270
- omlish/lite/marshal.py +309 -144
- omlish/lite/pycharm.py +47 -0
- omlish/lite/reflect.py +33 -0
- omlish/lite/resources.py +8 -0
- omlish/lite/runtime.py +4 -4
- omlish/lite/shlex.py +12 -0
- omlish/lite/socketserver.py +2 -2
- omlish/lite/strings.py +31 -0
- omlish/logs/__init__.py +0 -32
- omlish/logs/{_abc.py → abc.py} +0 -1
- omlish/logs/all.py +37 -0
- omlish/logs/{formatters.py → color.py} +1 -2
- omlish/logs/configs.py +7 -38
- omlish/logs/filters.py +10 -0
- omlish/logs/handlers.py +4 -1
- omlish/logs/json.py +56 -0
- omlish/logs/proxy.py +99 -0
- omlish/logs/standard.py +128 -0
- omlish/logs/utils.py +2 -2
- omlish/manifests/__init__.py +2 -0
- omlish/manifests/load.py +209 -0
- omlish/manifests/types.py +17 -0
- omlish/marshal/base.py +1 -1
- omlish/marshal/factories.py +1 -1
- omlish/marshal/forbidden.py +1 -1
- omlish/marshal/iterables.py +1 -1
- omlish/marshal/literals.py +50 -0
- omlish/marshal/mappings.py +1 -1
- omlish/marshal/maybes.py +1 -1
- omlish/marshal/standard.py +5 -1
- omlish/marshal/unions.py +1 -1
- omlish/os/__init__.py +0 -0
- omlish/os/atomics.py +205 -0
- omlish/os/deathsig.py +23 -0
- omlish/{os.py → os/files.py} +0 -9
- omlish/{lite → os}/journald.py +2 -1
- omlish/os/linux.py +484 -0
- omlish/os/paths.py +36 -0
- omlish/{lite → os}/pidfile.py +1 -0
- omlish/os/sizes.py +9 -0
- omlish/reflect/__init__.py +3 -0
- omlish/reflect/subst.py +2 -1
- omlish/reflect/types.py +126 -44
- omlish/secrets/pwhash.py +1 -1
- omlish/secrets/subprocesses.py +3 -1
- omlish/specs/jsonrpc/marshal.py +1 -1
- omlish/specs/openapi/marshal.py +1 -1
- omlish/sql/alchemy/asyncs.py +1 -1
- omlish/sql/queries/__init__.py +9 -1
- omlish/sql/queries/building.py +3 -0
- omlish/sql/queries/exprs.py +10 -27
- omlish/sql/queries/idents.py +48 -10
- omlish/sql/queries/names.py +80 -13
- omlish/sql/queries/params.py +64 -0
- omlish/sql/queries/rendering.py +1 -1
- omlish/subprocesses.py +340 -0
- omlish/term.py +29 -14
- omlish/testing/pytest/marks.py +2 -2
- omlish/testing/pytest/plugins/asyncs.py +6 -1
- omlish/testing/pytest/plugins/logging.py +1 -1
- omlish/testing/pytest/plugins/switches.py +1 -1
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/METADATA +7 -5
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/RECORD +200 -117
- omlish/fnpairs.py +0 -496
- omlish/formats/json/cli/__main__.py +0 -11
- omlish/formats/json/cli/cli.py +0 -298
- omlish/formats/json/cli/formats.py +0 -71
- omlish/formats/json/cli/io.py +0 -74
- omlish/formats/json/cli/parsing.py +0 -82
- omlish/formats/json/cli/processing.py +0 -48
- omlish/formats/json/cli/rendering.py +0 -92
- omlish/iterators.py +0 -300
- omlish/lite/subprocesses.py +0 -130
- /omlish/{formats/json/cli → argparse}/__init__.py +0 -0
- /omlish/{lite/fdio → asyncs/asyncio}/__init__.py +0 -0
- /omlish/asyncs/{asyncio.py → asyncio/asyncio.py} +0 -0
- /omlish/{lite/http → asyncs/bluelet}/__init__.py +0 -0
- /omlish/collections/{_abc.py → abc.py} +0 -0
- /omlish/{fnpipes.py → funcs/pipes.py} +0 -0
- /omlish/io/{_abc.py → abc.py} +0 -0
- /omlish/sql/{_abc.py → abc.py} +0 -0
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/top_level.txt +0 -0
omlish/lite/marshal.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
"""
|
2
2
|
TODO:
|
3
3
|
- pickle stdlib objs? have to pin to 3.8 pickle protocol, will be cross-version
|
4
|
-
-
|
4
|
+
- literals
|
5
5
|
"""
|
6
6
|
# ruff: noqa: UP006 UP007
|
7
7
|
import abc
|
@@ -13,17 +13,22 @@ import decimal
|
|
13
13
|
import enum
|
14
14
|
import fractions
|
15
15
|
import functools
|
16
|
+
import inspect
|
16
17
|
import threading
|
17
18
|
import typing as ta
|
18
19
|
import uuid
|
19
20
|
import weakref # noqa
|
20
21
|
|
21
|
-
from .check import
|
22
|
-
from .check import check_not_none
|
22
|
+
from .check import check
|
23
23
|
from .reflect import deep_subclasses
|
24
|
+
from .reflect import get_literal_type_args
|
25
|
+
from .reflect import get_new_type_supertype
|
24
26
|
from .reflect import get_optional_alias_arg
|
25
27
|
from .reflect import is_generic_alias
|
28
|
+
from .reflect import is_literal_type
|
29
|
+
from .reflect import is_new_type
|
26
30
|
from .reflect import is_union_alias
|
31
|
+
from .strings import snake_case
|
27
32
|
|
28
33
|
|
29
34
|
T = ta.TypeVar('T')
|
@@ -32,21 +37,27 @@ T = ta.TypeVar('T')
|
|
32
37
|
##
|
33
38
|
|
34
39
|
|
40
|
+
@dc.dataclass(frozen=True)
|
41
|
+
class ObjMarshalOptions:
|
42
|
+
raw_bytes: bool = False
|
43
|
+
non_strict_fields: bool = False
|
44
|
+
|
45
|
+
|
35
46
|
class ObjMarshaler(abc.ABC):
|
36
47
|
@abc.abstractmethod
|
37
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
48
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
38
49
|
raise NotImplementedError
|
39
50
|
|
40
51
|
@abc.abstractmethod
|
41
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
52
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
42
53
|
raise NotImplementedError
|
43
54
|
|
44
55
|
|
45
56
|
class NopObjMarshaler(ObjMarshaler):
|
46
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
57
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
47
58
|
return o
|
48
59
|
|
49
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
60
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
50
61
|
return o
|
51
62
|
|
52
63
|
|
@@ -54,29 +65,29 @@ class NopObjMarshaler(ObjMarshaler):
|
|
54
65
|
class ProxyObjMarshaler(ObjMarshaler):
|
55
66
|
m: ta.Optional[ObjMarshaler] = None
|
56
67
|
|
57
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
58
|
-
return
|
68
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
69
|
+
return check.not_none(self.m).marshal(o, ctx)
|
59
70
|
|
60
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
61
|
-
return
|
71
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
72
|
+
return check.not_none(self.m).unmarshal(o, ctx)
|
62
73
|
|
63
74
|
|
64
75
|
@dc.dataclass(frozen=True)
|
65
76
|
class CastObjMarshaler(ObjMarshaler):
|
66
77
|
ty: type
|
67
78
|
|
68
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
79
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
69
80
|
return o
|
70
81
|
|
71
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
82
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
72
83
|
return self.ty(o)
|
73
84
|
|
74
85
|
|
75
86
|
class DynamicObjMarshaler(ObjMarshaler):
|
76
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
77
|
-
return marshal_obj(o)
|
87
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
88
|
+
return ctx.manager.marshal_obj(o, opts=ctx.options)
|
78
89
|
|
79
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
90
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
80
91
|
return o
|
81
92
|
|
82
93
|
|
@@ -84,21 +95,36 @@ class DynamicObjMarshaler(ObjMarshaler):
|
|
84
95
|
class Base64ObjMarshaler(ObjMarshaler):
|
85
96
|
ty: type
|
86
97
|
|
87
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
98
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
88
99
|
return base64.b64encode(o).decode('ascii')
|
89
100
|
|
90
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
101
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
91
102
|
return self.ty(base64.b64decode(o))
|
92
103
|
|
93
104
|
|
105
|
+
@dc.dataclass(frozen=True)
|
106
|
+
class BytesSwitchedObjMarshaler(ObjMarshaler):
|
107
|
+
m: ObjMarshaler
|
108
|
+
|
109
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
110
|
+
if ctx.options.raw_bytes:
|
111
|
+
return o
|
112
|
+
return self.m.marshal(o, ctx)
|
113
|
+
|
114
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
115
|
+
if ctx.options.raw_bytes:
|
116
|
+
return o
|
117
|
+
return self.m.unmarshal(o, ctx)
|
118
|
+
|
119
|
+
|
94
120
|
@dc.dataclass(frozen=True)
|
95
121
|
class EnumObjMarshaler(ObjMarshaler):
|
96
122
|
ty: type
|
97
123
|
|
98
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
124
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
99
125
|
return o.name
|
100
126
|
|
101
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
127
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
102
128
|
return self.ty.__members__[o] # type: ignore
|
103
129
|
|
104
130
|
|
@@ -106,15 +132,27 @@ class EnumObjMarshaler(ObjMarshaler):
|
|
106
132
|
class OptionalObjMarshaler(ObjMarshaler):
|
107
133
|
item: ObjMarshaler
|
108
134
|
|
109
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
135
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
110
136
|
if o is None:
|
111
137
|
return None
|
112
|
-
return self.item.marshal(o)
|
138
|
+
return self.item.marshal(o, ctx)
|
113
139
|
|
114
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
140
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
115
141
|
if o is None:
|
116
142
|
return None
|
117
|
-
return self.item.unmarshal(o)
|
143
|
+
return self.item.unmarshal(o, ctx)
|
144
|
+
|
145
|
+
|
146
|
+
@dc.dataclass(frozen=True)
|
147
|
+
class LiteralObjMarshaler(ObjMarshaler):
|
148
|
+
item: ObjMarshaler
|
149
|
+
vs: frozenset
|
150
|
+
|
151
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
152
|
+
return self.item.marshal(check.in_(o, self.vs), ctx)
|
153
|
+
|
154
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
155
|
+
return check.in_(self.item.unmarshal(o, ctx), self.vs)
|
118
156
|
|
119
157
|
|
120
158
|
@dc.dataclass(frozen=True)
|
@@ -123,11 +161,11 @@ class MappingObjMarshaler(ObjMarshaler):
|
|
123
161
|
km: ObjMarshaler
|
124
162
|
vm: ObjMarshaler
|
125
163
|
|
126
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
127
|
-
return {self.km.marshal(k): self.vm.marshal(v) for k, v in o.items()}
|
164
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
165
|
+
return {self.km.marshal(k, ctx): self.vm.marshal(v, ctx) for k, v in o.items()}
|
128
166
|
|
129
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
130
|
-
return self.ty((self.km.unmarshal(k), self.vm.unmarshal(v)) for k, v in o.items())
|
167
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
168
|
+
return self.ty((self.km.unmarshal(k, ctx), self.vm.unmarshal(v, ctx)) for k, v in o.items())
|
131
169
|
|
132
170
|
|
133
171
|
@dc.dataclass(frozen=True)
|
@@ -135,24 +173,43 @@ class IterableObjMarshaler(ObjMarshaler):
|
|
135
173
|
ty: type
|
136
174
|
item: ObjMarshaler
|
137
175
|
|
138
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
139
|
-
return [self.item.marshal(e) for e in o]
|
176
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
177
|
+
return [self.item.marshal(e, ctx) for e in o]
|
140
178
|
|
141
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
142
|
-
return self.ty(self.item.unmarshal(e) for e in o)
|
179
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
180
|
+
return self.ty(self.item.unmarshal(e, ctx) for e in o)
|
143
181
|
|
144
182
|
|
145
183
|
@dc.dataclass(frozen=True)
|
146
|
-
class
|
184
|
+
class FieldsObjMarshaler(ObjMarshaler):
|
147
185
|
ty: type
|
148
186
|
fs: ta.Mapping[str, ObjMarshaler]
|
149
|
-
|
187
|
+
non_strict: bool = False
|
150
188
|
|
151
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
152
|
-
return {
|
189
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
190
|
+
return {
|
191
|
+
k: m.marshal(getattr(o, k), ctx)
|
192
|
+
for k, m in self.fs.items()
|
193
|
+
}
|
153
194
|
|
154
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
155
|
-
return self.ty(**{
|
195
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
196
|
+
return self.ty(**{
|
197
|
+
k: self.fs[k].unmarshal(v, ctx)
|
198
|
+
for k, v in o.items()
|
199
|
+
if not (self.non_strict or ctx.options.non_strict_fields) or k in self.fs
|
200
|
+
})
|
201
|
+
|
202
|
+
|
203
|
+
@dc.dataclass(frozen=True)
|
204
|
+
class SingleFieldObjMarshaler(ObjMarshaler):
|
205
|
+
ty: type
|
206
|
+
fld: str
|
207
|
+
|
208
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
209
|
+
return getattr(o, self.fld)
|
210
|
+
|
211
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
212
|
+
return self.ty(**{self.fld: o})
|
156
213
|
|
157
214
|
|
158
215
|
@dc.dataclass(frozen=True)
|
@@ -165,50 +222,57 @@ class PolymorphicObjMarshaler(ObjMarshaler):
|
|
165
222
|
impls_by_ty: ta.Mapping[type, Impl]
|
166
223
|
impls_by_tag: ta.Mapping[str, Impl]
|
167
224
|
|
168
|
-
|
225
|
+
@classmethod
|
226
|
+
def of(cls, impls: ta.Iterable[Impl]) -> 'PolymorphicObjMarshaler':
|
227
|
+
return cls(
|
228
|
+
{i.ty: i for i in impls},
|
229
|
+
{i.tag: i for i in impls},
|
230
|
+
)
|
231
|
+
|
232
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
169
233
|
impl = self.impls_by_ty[type(o)]
|
170
|
-
return {impl.tag: impl.m.marshal(o)}
|
234
|
+
return {impl.tag: impl.m.marshal(o, ctx)}
|
171
235
|
|
172
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
236
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
173
237
|
[(t, v)] = o.items()
|
174
238
|
impl = self.impls_by_tag[t]
|
175
|
-
return impl.m.unmarshal(v)
|
239
|
+
return impl.m.unmarshal(v, ctx)
|
176
240
|
|
177
241
|
|
178
242
|
@dc.dataclass(frozen=True)
|
179
243
|
class DatetimeObjMarshaler(ObjMarshaler):
|
180
244
|
ty: type
|
181
245
|
|
182
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
246
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
183
247
|
return o.isoformat()
|
184
248
|
|
185
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
249
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
186
250
|
return self.ty.fromisoformat(o) # type: ignore
|
187
251
|
|
188
252
|
|
189
253
|
class DecimalObjMarshaler(ObjMarshaler):
|
190
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
191
|
-
return str(
|
254
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
255
|
+
return str(check.isinstance(o, decimal.Decimal))
|
192
256
|
|
193
|
-
def unmarshal(self, v: ta.Any) -> ta.Any:
|
194
|
-
return decimal.Decimal(
|
257
|
+
def unmarshal(self, v: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
258
|
+
return decimal.Decimal(check.isinstance(v, str))
|
195
259
|
|
196
260
|
|
197
261
|
class FractionObjMarshaler(ObjMarshaler):
|
198
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
199
|
-
fr =
|
262
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
263
|
+
fr = check.isinstance(o, fractions.Fraction)
|
200
264
|
return [fr.numerator, fr.denominator]
|
201
265
|
|
202
|
-
def unmarshal(self, v: ta.Any) -> ta.Any:
|
203
|
-
num, denom =
|
266
|
+
def unmarshal(self, v: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
267
|
+
num, denom = check.isinstance(v, list)
|
204
268
|
return fractions.Fraction(num, denom)
|
205
269
|
|
206
270
|
|
207
271
|
class UuidObjMarshaler(ObjMarshaler):
|
208
|
-
def marshal(self, o: ta.Any) -> ta.Any:
|
272
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
209
273
|
return str(o)
|
210
274
|
|
211
|
-
def unmarshal(self, o: ta.Any) -> ta.Any:
|
275
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
212
276
|
return uuid.UUID(o)
|
213
277
|
|
214
278
|
|
@@ -218,11 +282,11 @@ class UuidObjMarshaler(ObjMarshaler):
|
|
218
282
|
_DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
|
219
283
|
**{t: NopObjMarshaler() for t in (type(None),)},
|
220
284
|
**{t: CastObjMarshaler(t) for t in (int, float, str, bool)},
|
221
|
-
**{t: Base64ObjMarshaler(t) for t in (bytes, bytearray)},
|
285
|
+
**{t: BytesSwitchedObjMarshaler(Base64ObjMarshaler(t)) for t in (bytes, bytearray)},
|
222
286
|
**{t: IterableObjMarshaler(t, DynamicObjMarshaler()) for t in (list, tuple, set, frozenset)},
|
223
287
|
**{t: MappingObjMarshaler(t, DynamicObjMarshaler(), DynamicObjMarshaler()) for t in (dict,)},
|
224
288
|
|
225
|
-
|
289
|
+
**{t: DynamicObjMarshaler() for t in (ta.Any, object)},
|
226
290
|
|
227
291
|
**{t: DatetimeObjMarshaler(t) for t in (datetime.date, datetime.time, datetime.datetime)},
|
228
292
|
decimal.Decimal: DecimalObjMarshaler(),
|
@@ -244,121 +308,222 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
|
|
244
308
|
}
|
245
309
|
|
246
310
|
|
247
|
-
|
248
|
-
ty: ta.Any,
|
249
|
-
rec: ta.Callable[[ta.Any], ObjMarshaler],
|
250
|
-
*,
|
251
|
-
nonstrict_dataclasses: bool = False,
|
252
|
-
) -> ObjMarshaler:
|
253
|
-
if isinstance(ty, type):
|
254
|
-
if abc.ABC in ty.__bases__:
|
255
|
-
impls = [ # type: ignore
|
256
|
-
PolymorphicObjMarshaler.Impl(
|
257
|
-
ity,
|
258
|
-
ity.__qualname__,
|
259
|
-
rec(ity),
|
260
|
-
)
|
261
|
-
for ity in deep_subclasses(ty)
|
262
|
-
if abc.ABC not in ity.__bases__
|
263
|
-
]
|
264
|
-
return PolymorphicObjMarshaler(
|
265
|
-
{i.ty: i for i in impls},
|
266
|
-
{i.tag: i for i in impls},
|
267
|
-
)
|
268
|
-
|
269
|
-
if issubclass(ty, enum.Enum):
|
270
|
-
return EnumObjMarshaler(ty)
|
271
|
-
|
272
|
-
if dc.is_dataclass(ty):
|
273
|
-
return DataclassObjMarshaler(
|
274
|
-
ty,
|
275
|
-
{f.name: rec(f.type) for f in dc.fields(ty)},
|
276
|
-
nonstrict=nonstrict_dataclasses,
|
277
|
-
)
|
311
|
+
##
|
278
312
|
|
279
|
-
if is_generic_alias(ty):
|
280
|
-
try:
|
281
|
-
mt = _OBJ_MARSHALER_GENERIC_MAPPING_TYPES[ta.get_origin(ty)]
|
282
|
-
except KeyError:
|
283
|
-
pass
|
284
|
-
else:
|
285
|
-
k, v = ta.get_args(ty)
|
286
|
-
return MappingObjMarshaler(mt, rec(k), rec(v))
|
287
313
|
|
288
|
-
|
289
|
-
st = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES[ta.get_origin(ty)]
|
290
|
-
except KeyError:
|
291
|
-
pass
|
292
|
-
else:
|
293
|
-
[e] = ta.get_args(ty)
|
294
|
-
return IterableObjMarshaler(st, rec(e))
|
314
|
+
_REGISTERED_OBJ_MARSHALERS_BY_TYPE: ta.MutableMapping[type, ObjMarshaler] = weakref.WeakKeyDictionary()
|
295
315
|
|
296
|
-
if is_union_alias(ty):
|
297
|
-
return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
|
298
316
|
|
299
|
-
|
317
|
+
def register_type_obj_marshaler(ty: type, om: ObjMarshaler) -> None:
|
318
|
+
_REGISTERED_OBJ_MARSHALERS_BY_TYPE[ty] = om
|
300
319
|
|
301
320
|
|
302
321
|
##
|
303
322
|
|
304
323
|
|
305
|
-
|
324
|
+
class ObjMarshalerManager:
|
325
|
+
def __init__(
|
326
|
+
self,
|
327
|
+
*,
|
328
|
+
default_options: ObjMarshalOptions = ObjMarshalOptions(),
|
329
|
+
|
330
|
+
default_obj_marshalers: ta.Dict[ta.Any, ObjMarshaler] = _DEFAULT_OBJ_MARSHALERS, # noqa
|
331
|
+
generic_mapping_types: ta.Dict[ta.Any, type] = _OBJ_MARSHALER_GENERIC_MAPPING_TYPES, # noqa
|
332
|
+
generic_iterable_types: ta.Dict[ta.Any, type] = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES, # noqa
|
333
|
+
|
334
|
+
registered_obj_marshalers: ta.Mapping[type, ObjMarshaler] = _REGISTERED_OBJ_MARSHALERS_BY_TYPE,
|
335
|
+
) -> None:
|
336
|
+
super().__init__()
|
337
|
+
|
338
|
+
self._default_options = default_options
|
339
|
+
|
340
|
+
self._obj_marshalers = dict(default_obj_marshalers)
|
341
|
+
self._generic_mapping_types = generic_mapping_types
|
342
|
+
self._generic_iterable_types = generic_iterable_types
|
343
|
+
self._registered_obj_marshalers = registered_obj_marshalers
|
344
|
+
|
345
|
+
self._lock = threading.RLock()
|
346
|
+
self._marshalers: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
|
347
|
+
self._proxies: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
|
348
|
+
|
349
|
+
#
|
350
|
+
|
351
|
+
def make_obj_marshaler(
|
352
|
+
self,
|
353
|
+
ty: ta.Any,
|
354
|
+
rec: ta.Callable[[ta.Any], ObjMarshaler],
|
355
|
+
*,
|
356
|
+
non_strict_fields: bool = False,
|
357
|
+
) -> ObjMarshaler:
|
358
|
+
if isinstance(ty, type):
|
359
|
+
if (reg := self._registered_obj_marshalers.get(ty)) is not None:
|
360
|
+
return reg
|
361
|
+
|
362
|
+
if abc.ABC in ty.__bases__:
|
363
|
+
impls = [ity for ity in deep_subclasses(ty) if abc.ABC not in ity.__bases__] # type: ignore
|
364
|
+
if all(ity.__qualname__.endswith(ty.__name__) for ity in impls):
|
365
|
+
ins = {ity: snake_case(ity.__qualname__[:-len(ty.__name__)]) for ity in impls}
|
366
|
+
else:
|
367
|
+
ins = {ity: ity.__qualname__ for ity in impls}
|
368
|
+
return PolymorphicObjMarshaler.of([
|
369
|
+
PolymorphicObjMarshaler.Impl(
|
370
|
+
ity,
|
371
|
+
itn,
|
372
|
+
rec(ity),
|
373
|
+
)
|
374
|
+
for ity, itn in ins.items()
|
375
|
+
])
|
376
|
+
|
377
|
+
if issubclass(ty, enum.Enum):
|
378
|
+
return EnumObjMarshaler(ty)
|
379
|
+
|
380
|
+
if dc.is_dataclass(ty):
|
381
|
+
return FieldsObjMarshaler(
|
382
|
+
ty,
|
383
|
+
{f.name: rec(f.type) for f in dc.fields(ty)},
|
384
|
+
non_strict=non_strict_fields,
|
385
|
+
)
|
306
386
|
|
307
|
-
|
387
|
+
if issubclass(ty, tuple) and hasattr(ty, '_fields'):
|
388
|
+
return FieldsObjMarshaler(
|
389
|
+
ty,
|
390
|
+
{p.name: rec(p.annotation) for p in inspect.signature(ty).parameters.values()},
|
391
|
+
non_strict=non_strict_fields,
|
392
|
+
)
|
308
393
|
|
309
|
-
|
394
|
+
if is_new_type(ty):
|
395
|
+
return rec(get_new_type_supertype(ty))
|
310
396
|
|
397
|
+
if is_literal_type(ty):
|
398
|
+
lvs = frozenset(get_literal_type_args(ty))
|
399
|
+
lty = check.single(set(map(type, lvs)))
|
400
|
+
return LiteralObjMarshaler(rec(lty), lvs)
|
311
401
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
402
|
+
if is_generic_alias(ty):
|
403
|
+
try:
|
404
|
+
mt = self._generic_mapping_types[ta.get_origin(ty)]
|
405
|
+
except KeyError:
|
406
|
+
pass
|
407
|
+
else:
|
408
|
+
k, v = ta.get_args(ty)
|
409
|
+
return MappingObjMarshaler(mt, rec(k), rec(v))
|
317
410
|
|
411
|
+
try:
|
412
|
+
st = self._generic_iterable_types[ta.get_origin(ty)]
|
413
|
+
except KeyError:
|
414
|
+
pass
|
415
|
+
else:
|
416
|
+
[e] = ta.get_args(ty)
|
417
|
+
return IterableObjMarshaler(st, rec(e))
|
418
|
+
|
419
|
+
if is_union_alias(ty):
|
420
|
+
return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
|
421
|
+
|
422
|
+
raise TypeError(ty)
|
423
|
+
|
424
|
+
#
|
425
|
+
|
426
|
+
def set_obj_marshaler(
|
427
|
+
self,
|
428
|
+
ty: ta.Any,
|
429
|
+
m: ObjMarshaler,
|
430
|
+
*,
|
431
|
+
override: bool = False,
|
432
|
+
) -> None:
|
433
|
+
with self._lock:
|
434
|
+
if not override and ty in self._obj_marshalers:
|
435
|
+
raise KeyError(ty)
|
436
|
+
self._obj_marshalers[ty] = m
|
437
|
+
|
438
|
+
def get_obj_marshaler(
|
439
|
+
self,
|
440
|
+
ty: ta.Any,
|
441
|
+
*,
|
442
|
+
no_cache: bool = False,
|
443
|
+
**kwargs: ta.Any,
|
444
|
+
) -> ObjMarshaler:
|
445
|
+
with self._lock:
|
446
|
+
if not no_cache:
|
447
|
+
try:
|
448
|
+
return self._obj_marshalers[ty]
|
449
|
+
except KeyError:
|
450
|
+
pass
|
318
451
|
|
319
|
-
def get_obj_marshaler(
|
320
|
-
ty: ta.Any,
|
321
|
-
*,
|
322
|
-
no_cache: bool = False,
|
323
|
-
**kwargs: ta.Any,
|
324
|
-
) -> ObjMarshaler:
|
325
|
-
with _OBJ_MARSHALERS_LOCK:
|
326
|
-
if not no_cache:
|
327
452
|
try:
|
328
|
-
return
|
453
|
+
return self._proxies[ty]
|
329
454
|
except KeyError:
|
330
455
|
pass
|
331
456
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
457
|
+
rec = functools.partial(
|
458
|
+
self.get_obj_marshaler,
|
459
|
+
no_cache=no_cache,
|
460
|
+
**kwargs,
|
461
|
+
)
|
462
|
+
|
463
|
+
p = ProxyObjMarshaler()
|
464
|
+
self._proxies[ty] = p
|
465
|
+
try:
|
466
|
+
m = self.make_obj_marshaler(ty, rec, **kwargs)
|
467
|
+
finally:
|
468
|
+
del self._proxies[ty]
|
469
|
+
p.m = m
|
470
|
+
|
471
|
+
if not no_cache:
|
472
|
+
self._obj_marshalers[ty] = m
|
473
|
+
return m
|
474
|
+
|
475
|
+
#
|
336
476
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
477
|
+
def _make_context(self, opts: ta.Optional[ObjMarshalOptions]) -> 'ObjMarshalContext':
|
478
|
+
return ObjMarshalContext(
|
479
|
+
options=opts or self._default_options,
|
480
|
+
manager=self,
|
341
481
|
)
|
342
482
|
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
483
|
+
def marshal_obj(
|
484
|
+
self,
|
485
|
+
o: ta.Any,
|
486
|
+
ty: ta.Any = None,
|
487
|
+
opts: ta.Optional[ObjMarshalOptions] = None,
|
488
|
+
) -> ta.Any:
|
489
|
+
m = self.get_obj_marshaler(ty if ty is not None else type(o))
|
490
|
+
return m.marshal(o, self._make_context(opts))
|
491
|
+
|
492
|
+
def unmarshal_obj(
|
493
|
+
self,
|
494
|
+
o: ta.Any,
|
495
|
+
ty: ta.Union[ta.Type[T], ta.Any],
|
496
|
+
opts: ta.Optional[ObjMarshalOptions] = None,
|
497
|
+
) -> T:
|
498
|
+
m = self.get_obj_marshaler(ty)
|
499
|
+
return m.unmarshal(o, self._make_context(opts))
|
500
|
+
|
501
|
+
def roundtrip_obj(
|
502
|
+
self,
|
503
|
+
o: ta.Any,
|
504
|
+
ty: ta.Any = None,
|
505
|
+
opts: ta.Optional[ObjMarshalOptions] = None,
|
506
|
+
) -> ta.Any:
|
507
|
+
if ty is None:
|
508
|
+
ty = type(o)
|
509
|
+
m: ta.Any = self.marshal_obj(o, ty, opts)
|
510
|
+
u: ta.Any = self.unmarshal_obj(m, ty, opts)
|
511
|
+
return u
|
350
512
|
|
351
|
-
|
352
|
-
|
353
|
-
|
513
|
+
|
514
|
+
@dc.dataclass(frozen=True)
|
515
|
+
class ObjMarshalContext:
|
516
|
+
options: ObjMarshalOptions
|
517
|
+
manager: ObjMarshalerManager
|
354
518
|
|
355
519
|
|
356
520
|
##
|
357
521
|
|
358
522
|
|
359
|
-
|
360
|
-
return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
|
523
|
+
OBJ_MARSHALER_MANAGER = ObjMarshalerManager()
|
361
524
|
|
525
|
+
set_obj_marshaler = OBJ_MARSHALER_MANAGER.set_obj_marshaler
|
526
|
+
get_obj_marshaler = OBJ_MARSHALER_MANAGER.get_obj_marshaler
|
362
527
|
|
363
|
-
|
364
|
-
|
528
|
+
marshal_obj = OBJ_MARSHALER_MANAGER.marshal_obj
|
529
|
+
unmarshal_obj = OBJ_MARSHALER_MANAGER.unmarshal_obj
|
omlish/lite/pycharm.py
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
import dataclasses as dc
|
3
|
+
import typing as ta
|
4
|
+
|
5
|
+
|
6
|
+
DEFAULT_PYCHARM_VERSION = '242.23726.102'
|
7
|
+
|
8
|
+
|
9
|
+
@dc.dataclass(frozen=True)
|
10
|
+
class PycharmRemoteDebug:
|
11
|
+
port: int
|
12
|
+
host: ta.Optional[str] = 'localhost'
|
13
|
+
install_version: ta.Optional[str] = DEFAULT_PYCHARM_VERSION
|
14
|
+
|
15
|
+
|
16
|
+
def pycharm_debug_connect(prd: PycharmRemoteDebug) -> None:
|
17
|
+
if prd.install_version is not None:
|
18
|
+
import subprocess
|
19
|
+
import sys
|
20
|
+
subprocess.check_call([
|
21
|
+
sys.executable,
|
22
|
+
'-mpip',
|
23
|
+
'install',
|
24
|
+
f'pydevd-pycharm~={prd.install_version}',
|
25
|
+
])
|
26
|
+
|
27
|
+
pydevd_pycharm = __import__('pydevd_pycharm') # noqa
|
28
|
+
pydevd_pycharm.settrace(
|
29
|
+
prd.host,
|
30
|
+
port=prd.port,
|
31
|
+
stdoutToServer=True,
|
32
|
+
stderrToServer=True,
|
33
|
+
)
|
34
|
+
|
35
|
+
|
36
|
+
def pycharm_debug_preamble(prd: PycharmRemoteDebug) -> str:
|
37
|
+
import inspect
|
38
|
+
import textwrap
|
39
|
+
return textwrap.dedent(f"""
|
40
|
+
{inspect.getsource(pycharm_debug_connect)}
|
41
|
+
|
42
|
+
pycharm_debug_connect(PycharmRemoteDebug(
|
43
|
+
{prd.port!r},
|
44
|
+
host={prd.host!r},
|
45
|
+
install_version={prd.install_version!r},
|
46
|
+
))
|
47
|
+
""")
|