omlish 0.0.0.dev447__py3-none-any.whl → 0.0.0.dev493__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/.omlish-manifests.json +12 -0
- omlish/README.md +199 -0
- omlish/__about__.py +21 -16
- omlish/argparse/all.py +17 -9
- omlish/argparse/cli.py +16 -3
- omlish/argparse/utils.py +21 -0
- omlish/asyncs/asyncio/rlock.py +110 -0
- omlish/asyncs/asyncio/sync.py +43 -0
- omlish/asyncs/asyncio/utils.py +2 -0
- omlish/asyncs/sync.py +25 -0
- omlish/bootstrap/_marshal.py +1 -1
- omlish/bootstrap/diag.py +12 -21
- omlish/bootstrap/main.py +2 -5
- omlish/bootstrap/sys.py +27 -28
- omlish/cexts/__init__.py +0 -0
- omlish/cexts/include/omlish/omlish.hh +1 -0
- omlish/collections/__init__.py +13 -1
- omlish/collections/attrregistry.py +210 -0
- omlish/collections/cache/impl.py +1 -0
- omlish/collections/identity.py +1 -0
- omlish/collections/mappings.py +28 -0
- omlish/collections/trie.py +5 -1
- omlish/collections/utils.py +77 -0
- omlish/concurrent/all.py +2 -1
- omlish/concurrent/futures.py +25 -0
- omlish/concurrent/threadlets.py +1 -1
- omlish/daemons/reparent.py +2 -3
- omlish/daemons/spawning.py +2 -3
- omlish/dataclasses/__init__.py +2 -0
- omlish/dataclasses/impl/api/classes/decorator.py +3 -0
- omlish/dataclasses/impl/api/classes/make.py +3 -0
- omlish/dataclasses/impl/concerns/repr.py +15 -2
- omlish/dataclasses/impl/configs.py +97 -37
- omlish/dataclasses/impl/generation/compilation.py +21 -19
- omlish/dataclasses/impl/generation/globals.py +1 -0
- omlish/dataclasses/impl/generation/ops.py +1 -0
- omlish/dataclasses/impl/generation/plans.py +2 -17
- omlish/dataclasses/impl/generation/processor.py +106 -25
- omlish/dataclasses/impl/processing/base.py +8 -0
- omlish/dataclasses/impl/processing/driving.py +19 -7
- omlish/dataclasses/specs.py +1 -0
- omlish/dataclasses/tools/modifiers.py +5 -0
- omlish/diag/_pycharm/runhack.py +1 -1
- omlish/diag/cmds/__init__.py +0 -0
- omlish/diag/{lslocks.py → cmds/lslocks.py} +6 -6
- omlish/diag/{lsof.py → cmds/lsof.py} +6 -6
- omlish/diag/{ps.py → cmds/ps.py} +6 -6
- omlish/diag/pycharm.py +16 -2
- omlish/diag/pydevd.py +58 -40
- omlish/diag/replserver/console.py +1 -1
- omlish/dispatch/__init__.py +18 -12
- omlish/dispatch/methods.py +50 -140
- omlish/dom/rendering.py +1 -1
- omlish/formats/dotenv.py +1 -1
- omlish/formats/json/stream/__init__.py +13 -0
- omlish/funcs/guard.py +225 -0
- omlish/graphs/dot/rendering.py +1 -1
- omlish/http/all.py +44 -4
- omlish/http/clients/asyncs.py +33 -27
- omlish/http/clients/base.py +17 -1
- omlish/http/clients/coro/__init__.py +0 -0
- omlish/http/clients/coro/sync.py +171 -0
- omlish/http/clients/default.py +208 -29
- omlish/http/clients/executor.py +56 -0
- omlish/http/clients/httpx.py +72 -11
- omlish/http/clients/middleware.py +181 -0
- omlish/http/clients/sync.py +33 -27
- omlish/http/clients/syncasync.py +49 -0
- omlish/http/clients/urllib.py +6 -3
- omlish/http/coro/client/connection.py +15 -6
- omlish/http/coro/io.py +2 -0
- omlish/http/flasky/__init__.py +40 -0
- omlish/http/flasky/_compat.py +2 -0
- omlish/http/flasky/api.py +82 -0
- omlish/http/flasky/app.py +203 -0
- omlish/http/flasky/cvs.py +59 -0
- omlish/http/flasky/requests.py +20 -0
- omlish/http/flasky/responses.py +23 -0
- omlish/http/flasky/routes.py +23 -0
- omlish/http/flasky/types.py +15 -0
- omlish/http/urls.py +67 -0
- omlish/inject/__init__.py +57 -29
- omlish/inject/_dataclasses.py +5148 -0
- omlish/inject/binder.py +11 -52
- omlish/inject/eagers.py +2 -0
- omlish/inject/elements.py +27 -0
- omlish/inject/helpers/__init__.py +0 -0
- omlish/inject/{utils.py → helpers/constfn.py} +3 -3
- omlish/inject/{tags.py → helpers/id.py} +2 -2
- omlish/inject/helpers/late.py +76 -0
- omlish/inject/{managed.py → helpers/managed.py} +10 -10
- omlish/inject/helpers/multis.py +143 -0
- omlish/inject/helpers/wrappers.py +54 -0
- omlish/inject/impl/elements.py +54 -21
- omlish/inject/impl/injector.py +29 -25
- omlish/inject/impl/inspect.py +10 -1
- omlish/inject/impl/maysync.py +3 -4
- omlish/inject/impl/multis.py +3 -0
- omlish/inject/impl/sync.py +3 -4
- omlish/inject/injector.py +31 -2
- omlish/inject/inspect.py +35 -0
- omlish/inject/maysync.py +2 -4
- omlish/inject/multis.py +8 -0
- omlish/inject/overrides.py +3 -3
- omlish/inject/privates.py +6 -0
- omlish/inject/providers.py +3 -2
- omlish/inject/sync.py +5 -4
- omlish/io/buffers.py +118 -0
- omlish/io/readers.py +29 -0
- omlish/iterators/transforms.py +2 -2
- omlish/lang/__init__.py +180 -97
- omlish/lang/_asyncs.cc +186 -0
- omlish/lang/asyncs.py +17 -0
- omlish/lang/casing.py +11 -0
- omlish/lang/contextmanagers.py +28 -4
- omlish/lang/functions.py +31 -22
- omlish/lang/imports/_capture.cc +11 -9
- omlish/lang/imports/capture.py +363 -170
- omlish/lang/imports/proxy.py +455 -152
- omlish/lang/lazyglobals.py +22 -9
- omlish/lang/params.py +17 -0
- omlish/lang/recursion.py +0 -1
- omlish/lang/sequences.py +124 -0
- omlish/lifecycles/README.md +30 -0
- omlish/lifecycles/__init__.py +87 -13
- omlish/lifecycles/_dataclasses.py +1388 -0
- omlish/lifecycles/base.py +178 -64
- omlish/lifecycles/contextmanagers.py +113 -4
- omlish/lifecycles/controller.py +150 -87
- omlish/lifecycles/injection.py +143 -0
- omlish/lifecycles/listeners.py +56 -0
- omlish/lifecycles/managed.py +142 -0
- omlish/lifecycles/manager.py +218 -93
- omlish/lifecycles/states.py +2 -0
- omlish/lifecycles/transitions.py +3 -0
- omlish/lifecycles/unwrap.py +57 -0
- omlish/lite/abstract.py +54 -24
- omlish/lite/asyncs.py +2 -2
- omlish/lite/attrops.py +2 -0
- omlish/lite/contextmanagers.py +4 -4
- omlish/lite/dataclasses.py +44 -0
- omlish/lite/maybes.py +8 -0
- omlish/lite/maysync.py +1 -5
- omlish/lite/pycharm.py +1 -1
- omlish/lite/typing.py +24 -0
- omlish/logs/_amalg.py +1 -1
- omlish/logs/all.py +25 -11
- omlish/logs/asyncs.py +73 -0
- omlish/logs/base.py +101 -12
- omlish/logs/contexts.py +4 -1
- omlish/logs/lists.py +125 -0
- omlish/logs/modules.py +19 -1
- omlish/logs/std/loggers.py +6 -1
- omlish/logs/std/noisy.py +11 -9
- omlish/logs/{standard.py → std/standard.py} +3 -4
- omlish/logs/utils.py +17 -2
- omlish/manifests/loading.py +2 -1
- omlish/marshal/__init__.py +33 -13
- omlish/marshal/_dataclasses.py +2774 -0
- omlish/marshal/base/configs.py +12 -0
- omlish/marshal/base/contexts.py +36 -21
- omlish/marshal/base/funcs.py +8 -11
- omlish/marshal/base/options.py +8 -0
- omlish/marshal/base/registries.py +146 -44
- omlish/marshal/base/types.py +40 -16
- omlish/marshal/composite/iterables.py +33 -20
- omlish/marshal/composite/literals.py +20 -18
- omlish/marshal/composite/mappings.py +36 -23
- omlish/marshal/composite/maybes.py +29 -19
- omlish/marshal/composite/newtypes.py +16 -16
- omlish/marshal/composite/optionals.py +14 -14
- omlish/marshal/composite/special.py +15 -15
- omlish/marshal/composite/unions/__init__.py +0 -0
- omlish/marshal/composite/unions/literals.py +93 -0
- omlish/marshal/composite/unions/primitives.py +103 -0
- omlish/marshal/factories/invalidate.py +18 -68
- omlish/marshal/factories/method.py +26 -0
- omlish/marshal/factories/moduleimport/factories.py +22 -65
- omlish/marshal/factories/multi.py +13 -25
- omlish/marshal/factories/recursive.py +42 -56
- omlish/marshal/factories/typecache.py +29 -74
- omlish/marshal/factories/typemap.py +42 -43
- omlish/marshal/objects/dataclasses.py +129 -106
- omlish/marshal/objects/marshal.py +18 -14
- omlish/marshal/objects/namedtuples.py +48 -42
- omlish/marshal/objects/unmarshal.py +19 -15
- omlish/marshal/polymorphism/marshal.py +9 -11
- omlish/marshal/polymorphism/metadata.py +16 -5
- omlish/marshal/polymorphism/standard.py +13 -1
- omlish/marshal/polymorphism/unions.py +15 -105
- omlish/marshal/polymorphism/unmarshal.py +9 -10
- omlish/marshal/singular/enums.py +14 -18
- omlish/marshal/standard.py +10 -6
- omlish/marshal/trivial/any.py +1 -1
- omlish/marshal/trivial/forbidden.py +21 -26
- omlish/metadata.py +23 -1
- omlish/os/forkhooks.py +4 -0
- omlish/os/pidfiles/pinning.py +2 -2
- omlish/reflect/__init__.py +43 -26
- omlish/reflect/ops.py +10 -1
- omlish/reflect/types.py +1 -0
- omlish/secrets/marshal.py +1 -1
- omlish/specs/jmespath/__init__.py +12 -3
- omlish/specs/jmespath/_dataclasses.py +2893 -0
- omlish/specs/jmespath/ast.py +1 -1
- omlish/specs/jsonrpc/__init__.py +13 -0
- omlish/specs/jsonrpc/_marshal.py +32 -23
- omlish/specs/jsonrpc/conns.py +10 -7
- omlish/specs/jsonschema/_marshal.py +1 -1
- omlish/specs/jsonschema/keywords/__init__.py +7 -0
- omlish/specs/jsonschema/keywords/_dataclasses.py +1644 -0
- omlish/specs/openapi/_marshal.py +31 -22
- omlish/sql/__init__.py +24 -5
- omlish/sql/{tabledefs/alchemy.py → alchemy/tabledefs.py} +2 -2
- omlish/sql/api/dbapi.py +1 -1
- omlish/sql/dbapi/__init__.py +15 -0
- omlish/sql/{dbapi.py → dbapi/drivers.py} +2 -2
- omlish/sql/queries/__init__.py +3 -0
- omlish/sql/queries/_marshal.py +2 -2
- omlish/sql/queries/rendering.py +1 -1
- omlish/sql/tabledefs/_marshal.py +1 -1
- omlish/subprocesses/base.py +4 -0
- omlish/subprocesses/editor.py +1 -1
- omlish/sync.py +155 -21
- omlish/term/alt.py +60 -0
- omlish/term/confirm.py +8 -8
- omlish/term/pager.py +235 -0
- omlish/term/terminfo.py +935 -0
- omlish/term/termstate.py +67 -0
- omlish/term/vt100/terminal.py +0 -3
- omlish/testing/pytest/plugins/asyncs/fixtures.py +4 -1
- omlish/testing/pytest/plugins/asyncs/plugin.py +2 -0
- omlish/testing/pytest/plugins/skips.py +2 -1
- omlish/testing/unittest/main.py +3 -3
- omlish/text/docwrap/__init__.py +3 -0
- omlish/text/docwrap/__main__.py +11 -0
- omlish/text/docwrap/api.py +83 -0
- omlish/text/docwrap/cli.py +91 -0
- omlish/text/docwrap/groups.py +84 -0
- omlish/text/docwrap/lists.py +167 -0
- omlish/text/docwrap/parts.py +146 -0
- omlish/text/docwrap/reflowing.py +106 -0
- omlish/text/docwrap/rendering.py +151 -0
- omlish/text/docwrap/utils.py +11 -0
- omlish/text/docwrap/wrapping.py +59 -0
- omlish/text/filecache.py +2 -2
- omlish/text/lorem.py +6 -0
- omlish/text/parts.py +2 -2
- omlish/text/textwrap.py +51 -0
- omlish/typedvalues/marshal.py +85 -59
- omlish/typedvalues/values.py +2 -1
- {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev493.dist-info}/METADATA +36 -32
- {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev493.dist-info}/RECORD +260 -199
- omlish/dataclasses/impl/generation/mangling.py +0 -18
- omlish/funcs/match.py +0 -227
- omlish/lifecycles/abstract.py +0 -86
- omlish/marshal/factories/match.py +0 -34
- omlish/marshal/factories/simple.py +0 -28
- /omlish/inject/{impl → helpers}/proxy.py +0 -0
- /omlish/inject/impl/{providers2.py → providersmap.py} +0 -0
- /omlish/sql/{abc.py → dbapi/abc.py} +0 -0
- {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev493.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev493.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev493.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev493.dist-info}/top_level.txt +0 -0
|
@@ -11,13 +11,14 @@ from ... import dataclasses as dc
|
|
|
11
11
|
from ... import lang
|
|
12
12
|
from ... import reflect as rfl
|
|
13
13
|
from ...lite import marshal as lm
|
|
14
|
-
from ..base.contexts import
|
|
15
|
-
from ..base.contexts import
|
|
14
|
+
from ..base.contexts import MarshalFactoryContext
|
|
15
|
+
from ..base.contexts import UnmarshalFactoryContext
|
|
16
|
+
from ..base.errors import UnhandledTypeError
|
|
16
17
|
from ..base.options import Option
|
|
17
18
|
from ..base.types import Marshaler
|
|
19
|
+
from ..base.types import MarshalerFactory
|
|
18
20
|
from ..base.types import Unmarshaler
|
|
19
|
-
from ..
|
|
20
|
-
from ..factories.simple import SimpleUnmarshalerFactory
|
|
21
|
+
from ..base.types import UnmarshalerFactory
|
|
21
22
|
from ..naming import Naming
|
|
22
23
|
from ..naming import translate_name
|
|
23
24
|
from .marshal import ObjectMarshaler
|
|
@@ -159,19 +160,37 @@ def get_dataclass_field_infos(
|
|
|
159
160
|
return FieldInfos(ret)
|
|
160
161
|
|
|
161
162
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
163
|
+
##
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _make_field_marshal_obj(
|
|
167
|
+
ctx: MarshalFactoryContext,
|
|
168
|
+
ty: ta.Any,
|
|
169
|
+
obj: Marshaler | None,
|
|
170
|
+
fac: MarshalerFactory | None,
|
|
168
171
|
):
|
|
169
172
|
if obj is not None:
|
|
170
173
|
return obj
|
|
171
174
|
if fac is not None:
|
|
172
|
-
|
|
173
|
-
|
|
175
|
+
if (m := fac.make_marshaler(ctx, ty)) is None:
|
|
176
|
+
raise UnhandledTypeError(ty)
|
|
177
|
+
return m()
|
|
178
|
+
return ctx.make_marshaler(ty)
|
|
179
|
+
|
|
174
180
|
|
|
181
|
+
def _make_field_unmarshal_obj(
|
|
182
|
+
ctx: UnmarshalFactoryContext,
|
|
183
|
+
ty: ta.Any,
|
|
184
|
+
obj: Unmarshaler | None,
|
|
185
|
+
fac: UnmarshalerFactory | None,
|
|
186
|
+
):
|
|
187
|
+
if obj is not None:
|
|
188
|
+
return obj
|
|
189
|
+
if fac is not None:
|
|
190
|
+
if (m := fac.make_unmarshaler(ctx, ty)) is None:
|
|
191
|
+
raise UnhandledTypeError(ty)
|
|
192
|
+
return m()
|
|
193
|
+
return ctx.make_unmarshaler(ty)
|
|
175
194
|
|
|
176
195
|
##
|
|
177
196
|
|
|
@@ -200,119 +219,123 @@ def _type_or_generic_base(rty: rfl.Type) -> type | None:
|
|
|
200
219
|
return None
|
|
201
220
|
|
|
202
221
|
|
|
203
|
-
class DataclassMarshalerFactory(AbstractDataclassFactory,
|
|
204
|
-
def
|
|
205
|
-
|
|
222
|
+
class DataclassMarshalerFactory(AbstractDataclassFactory, MarshalerFactory):
|
|
223
|
+
def make_marshaler(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
|
|
224
|
+
if not (
|
|
206
225
|
(ty := _type_or_generic_base(rty)) is not None and
|
|
207
226
|
dc.is_dataclass(ty) and
|
|
208
227
|
not lang.is_abstract_class(ty)
|
|
209
|
-
)
|
|
228
|
+
):
|
|
229
|
+
return None
|
|
230
|
+
|
|
231
|
+
def inner() -> Marshaler:
|
|
232
|
+
ty = check.isinstance(_type_or_generic_base(rty), type)
|
|
233
|
+
check.state(dc.is_dataclass(ty))
|
|
234
|
+
check.state(not lang.is_abstract_class(ty))
|
|
235
|
+
|
|
236
|
+
dc_md = self._get_metadata(ty)
|
|
237
|
+
fis = self._get_field_infos(ty, ctx.options)
|
|
238
|
+
|
|
239
|
+
fields = [
|
|
240
|
+
(
|
|
241
|
+
fi,
|
|
242
|
+
_make_field_marshal_obj(
|
|
243
|
+
ctx,
|
|
244
|
+
fi.type,
|
|
245
|
+
fi.metadata.marshaler,
|
|
246
|
+
fi.metadata.marshaler_factory,
|
|
247
|
+
),
|
|
248
|
+
)
|
|
249
|
+
for fi in fis
|
|
250
|
+
if fi.name not in dc_md.specials.set
|
|
251
|
+
]
|
|
210
252
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
check.state(not lang.is_abstract_class(ty))
|
|
215
|
-
|
|
216
|
-
dc_md = self._get_metadata(ty)
|
|
217
|
-
fis = self._get_field_infos(ty, ctx.options)
|
|
218
|
-
|
|
219
|
-
fields = [
|
|
220
|
-
(
|
|
221
|
-
fi,
|
|
222
|
-
_make_field_obj(
|
|
223
|
-
ctx,
|
|
224
|
-
fi.type,
|
|
225
|
-
fi.metadata.marshaler,
|
|
226
|
-
fi.metadata.marshaler_factory,
|
|
227
|
-
'make_marshaler',
|
|
228
|
-
),
|
|
253
|
+
return ObjectMarshaler(
|
|
254
|
+
fields,
|
|
255
|
+
specials=dc_md.specials,
|
|
229
256
|
)
|
|
230
|
-
for fi in fis
|
|
231
|
-
if fi.name not in dc_md.specials.set
|
|
232
|
-
]
|
|
233
257
|
|
|
234
|
-
return
|
|
235
|
-
fields,
|
|
236
|
-
specials=dc_md.specials,
|
|
237
|
-
)
|
|
258
|
+
return inner
|
|
238
259
|
|
|
239
260
|
|
|
240
261
|
##
|
|
241
262
|
|
|
242
263
|
|
|
243
|
-
class DataclassUnmarshalerFactory(AbstractDataclassFactory,
|
|
244
|
-
def
|
|
245
|
-
|
|
264
|
+
class DataclassUnmarshalerFactory(AbstractDataclassFactory, UnmarshalerFactory):
|
|
265
|
+
def make_unmarshaler(self, ctx: UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
|
|
266
|
+
if not (
|
|
246
267
|
(ty := _type_or_generic_base(rty)) is not None and
|
|
247
268
|
dc.is_dataclass(ty) and
|
|
248
269
|
not lang.is_abstract_class(ty)
|
|
249
|
-
)
|
|
270
|
+
):
|
|
271
|
+
return None
|
|
250
272
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
273
|
+
def inner() -> Unmarshaler:
|
|
274
|
+
ty = check.isinstance(_type_or_generic_base(rty), type)
|
|
275
|
+
check.state(dc.is_dataclass(ty))
|
|
276
|
+
check.state(not lang.is_abstract_class(ty))
|
|
255
277
|
|
|
256
|
-
|
|
257
|
-
|
|
278
|
+
dc_md = self._get_metadata(ty)
|
|
279
|
+
fis = self._get_field_infos(ty, ctx.options)
|
|
258
280
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
281
|
+
d: dict[str, tuple[FieldInfo, Unmarshaler]] = {}
|
|
282
|
+
defaults: dict[str, ta.Any] = {}
|
|
283
|
+
embeds: dict[str, type] = {}
|
|
284
|
+
embeds_by_unmarshal_name: dict[str, tuple[str, str]] = {}
|
|
263
285
|
|
|
264
|
-
|
|
265
|
-
|
|
286
|
+
def add_field(fi: FieldInfo, *, prefixes: ta.Iterable[str] = ('',)) -> ta.Iterable[str]:
|
|
287
|
+
ret: list[str] = []
|
|
266
288
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
289
|
+
if fi.options.embed:
|
|
290
|
+
e_ty = check.isinstance(fi.type, type)
|
|
291
|
+
check.state(dc.is_dataclass(e_ty))
|
|
292
|
+
e_dc_md = get_dataclass_metadata(e_ty)
|
|
293
|
+
if e_dc_md.specials.set:
|
|
294
|
+
raise Exception(f'Embedded fields cannot have specials: {e_ty}')
|
|
273
295
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
296
|
+
embeds[fi.name] = e_ty
|
|
297
|
+
for e_fi in self._get_field_infos(e_ty, ctx.options):
|
|
298
|
+
e_ns = add_field(e_fi, prefixes=[p + ep for p in prefixes for ep in fi.unmarshal_names])
|
|
299
|
+
embeds_by_unmarshal_name.update({e_f: (fi.name, e_fi.name) for e_f in e_ns})
|
|
300
|
+
ret.extend(e_ns)
|
|
279
301
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
)
|
|
290
|
-
)
|
|
302
|
+
else:
|
|
303
|
+
tup = (
|
|
304
|
+
fi,
|
|
305
|
+
_make_field_unmarshal_obj(
|
|
306
|
+
ctx,
|
|
307
|
+
fi.type,
|
|
308
|
+
fi.metadata.unmarshaler,
|
|
309
|
+
fi.metadata.unmarshaler_factory,
|
|
310
|
+
),
|
|
311
|
+
)
|
|
291
312
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
313
|
+
for pfx in prefixes:
|
|
314
|
+
for un in fi.unmarshal_names:
|
|
315
|
+
un = pfx + un
|
|
316
|
+
if un in d:
|
|
317
|
+
raise KeyError(f'Duplicate fields for name {un!r}: {fi.name!r}, {d[un][0].name!r}')
|
|
318
|
+
d[un] = tup
|
|
319
|
+
ret.append(un)
|
|
320
|
+
|
|
321
|
+
if fi.options.default.present:
|
|
322
|
+
defaults[fi.name] = fi.options.default.must()
|
|
323
|
+
|
|
324
|
+
return ret
|
|
325
|
+
|
|
326
|
+
for fi in fis:
|
|
327
|
+
if fi.name in dc_md.specials.set:
|
|
328
|
+
continue
|
|
329
|
+
add_field(fi)
|
|
330
|
+
|
|
331
|
+
return ObjectUnmarshaler(
|
|
332
|
+
ty,
|
|
333
|
+
d,
|
|
334
|
+
specials=dc_md.specials,
|
|
335
|
+
defaults=defaults,
|
|
336
|
+
embeds=embeds,
|
|
337
|
+
embeds_by_unmarshal_name=embeds_by_unmarshal_name,
|
|
338
|
+
ignore_unknown=dc_md.ignore_unknown,
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
return inner
|
|
@@ -5,9 +5,10 @@ from ... import check
|
|
|
5
5
|
from ... import dataclasses as dc
|
|
6
6
|
from ... import reflect as rfl
|
|
7
7
|
from ..base.contexts import MarshalContext
|
|
8
|
+
from ..base.contexts import MarshalFactoryContext
|
|
8
9
|
from ..base.types import Marshaler
|
|
10
|
+
from ..base.types import MarshalerFactory
|
|
9
11
|
from ..base.values import Value
|
|
10
|
-
from ..factories.simple import SimpleMarshalerFactory
|
|
11
12
|
from .metadata import FieldInfo
|
|
12
13
|
from .metadata import FieldInfos
|
|
13
14
|
from .metadata import ObjectSpecials
|
|
@@ -29,12 +30,12 @@ class ObjectMarshaler(Marshaler):
|
|
|
29
30
|
@classmethod
|
|
30
31
|
def make(
|
|
31
32
|
cls,
|
|
32
|
-
ctx:
|
|
33
|
+
ctx: MarshalFactoryContext,
|
|
33
34
|
fis: FieldInfos,
|
|
34
35
|
**kwargs: ta.Any,
|
|
35
36
|
) -> Marshaler:
|
|
36
37
|
fields = [
|
|
37
|
-
(fi, ctx.
|
|
38
|
+
(fi, ctx.make_marshaler(fi.type))
|
|
38
39
|
for fi in fis
|
|
39
40
|
]
|
|
40
41
|
|
|
@@ -86,23 +87,26 @@ class ObjectMarshaler(Marshaler):
|
|
|
86
87
|
|
|
87
88
|
|
|
88
89
|
@dc.dataclass(frozen=True)
|
|
89
|
-
class SimpleObjectMarshalerFactory(
|
|
90
|
+
class SimpleObjectMarshalerFactory(MarshalerFactory):
|
|
90
91
|
dct: ta.Mapping[type, ta.Sequence[FieldInfo]]
|
|
91
92
|
|
|
92
93
|
_: dc.KW_ONLY
|
|
93
94
|
|
|
94
95
|
specials: ObjectSpecials = ObjectSpecials()
|
|
95
96
|
|
|
96
|
-
def
|
|
97
|
-
|
|
97
|
+
def make_marshaler(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
|
|
98
|
+
if not (isinstance(rty, type) and rty in self.dct):
|
|
99
|
+
return None
|
|
98
100
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
+
def inner() -> Marshaler:
|
|
102
|
+
ty = check.isinstance(rty, type)
|
|
101
103
|
|
|
102
|
-
|
|
104
|
+
fis = FieldInfos(self.dct[ty])
|
|
103
105
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
return ObjectMarshaler.make(
|
|
107
|
+
ctx,
|
|
108
|
+
fis,
|
|
109
|
+
specials=self.specials,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
return inner
|
|
@@ -5,13 +5,13 @@ from ... import check
|
|
|
5
5
|
from ... import collections as col
|
|
6
6
|
from ... import lang
|
|
7
7
|
from ... import reflect as rfl
|
|
8
|
-
from ..base.contexts import
|
|
9
|
-
from ..base.contexts import
|
|
8
|
+
from ..base.contexts import MarshalFactoryContext
|
|
9
|
+
from ..base.contexts import UnmarshalFactoryContext
|
|
10
10
|
from ..base.options import Option
|
|
11
11
|
from ..base.types import Marshaler
|
|
12
|
+
from ..base.types import MarshalerFactory
|
|
12
13
|
from ..base.types import Unmarshaler
|
|
13
|
-
from ..
|
|
14
|
-
from ..factories.simple import SimpleUnmarshalerFactory
|
|
14
|
+
from ..base.types import UnmarshalerFactory
|
|
15
15
|
from .marshal import ObjectMarshaler
|
|
16
16
|
from .metadata import FieldInfo
|
|
17
17
|
from .metadata import FieldInfos
|
|
@@ -55,57 +55,63 @@ def get_namedtuple_field_infos(
|
|
|
55
55
|
##
|
|
56
56
|
|
|
57
57
|
|
|
58
|
-
class NamedtupleMarshalerFactory(
|
|
59
|
-
def
|
|
60
|
-
|
|
58
|
+
class NamedtupleMarshalerFactory(MarshalerFactory):
|
|
59
|
+
def make_marshaler(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
|
|
60
|
+
if not _is_namedtuple(rty):
|
|
61
|
+
return None
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
def inner() -> Marshaler:
|
|
64
|
+
check.state(_is_namedtuple(rty))
|
|
65
|
+
ty = check.isinstance(rty, type)
|
|
66
|
+
check.state(not lang.is_abstract_class(ty))
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
fis = get_namedtuple_field_infos(ty, ctx.options)
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
fields = [
|
|
71
|
+
(fi, ctx.make_marshaler(fi.type))
|
|
72
|
+
for fi in fis
|
|
73
|
+
]
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
return ObjectMarshaler(
|
|
76
|
+
fields,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
return inner
|
|
77
80
|
|
|
78
81
|
|
|
79
82
|
##
|
|
80
83
|
|
|
81
84
|
|
|
82
|
-
class NamedtupleUnmarshalerFactory(
|
|
83
|
-
def
|
|
84
|
-
|
|
85
|
+
class NamedtupleUnmarshalerFactory(UnmarshalerFactory):
|
|
86
|
+
def make_unmarshaler(self, ctx: UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
|
|
87
|
+
if not _is_namedtuple(rty):
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
def inner() -> Unmarshaler:
|
|
91
|
+
check.state(_is_namedtuple(rty))
|
|
92
|
+
ty = check.isinstance(rty, type)
|
|
93
|
+
check.state(not lang.is_abstract_class(ty))
|
|
85
94
|
|
|
86
|
-
|
|
87
|
-
check.state(_is_namedtuple(rty))
|
|
88
|
-
ty = check.isinstance(rty, type)
|
|
89
|
-
check.state(not lang.is_abstract_class(ty))
|
|
95
|
+
fis = get_namedtuple_field_infos(ty, ctx.options)
|
|
90
96
|
|
|
91
|
-
|
|
97
|
+
d: dict[str, tuple[FieldInfo, Unmarshaler]] = {}
|
|
98
|
+
defaults: dict[str, ta.Any] = {}
|
|
92
99
|
|
|
93
|
-
|
|
94
|
-
|
|
100
|
+
for fi in fis:
|
|
101
|
+
tup = (fi, ctx.make_unmarshaler(fi.type))
|
|
95
102
|
|
|
96
|
-
|
|
97
|
-
|
|
103
|
+
for un in fi.unmarshal_names:
|
|
104
|
+
if un in d:
|
|
105
|
+
raise KeyError(f'Duplicate fields for name {un!r}: {fi.name!r}, {d[un][0].name!r}')
|
|
106
|
+
d[un] = tup
|
|
98
107
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
raise KeyError(f'Duplicate fields for name {un!r}: {fi.name!r}, {d[un][0].name!r}')
|
|
102
|
-
d[un] = tup
|
|
108
|
+
if fi.options.default.present:
|
|
109
|
+
defaults[fi.name] = fi.options.default.must()
|
|
103
110
|
|
|
104
|
-
|
|
105
|
-
|
|
111
|
+
return ObjectUnmarshaler(
|
|
112
|
+
ty,
|
|
113
|
+
d,
|
|
114
|
+
defaults=defaults,
|
|
115
|
+
)
|
|
106
116
|
|
|
107
|
-
return
|
|
108
|
-
ty,
|
|
109
|
-
d,
|
|
110
|
-
defaults=defaults,
|
|
111
|
-
)
|
|
117
|
+
return inner
|
|
@@ -5,9 +5,10 @@ from ... import check
|
|
|
5
5
|
from ... import dataclasses as dc
|
|
6
6
|
from ... import reflect as rfl
|
|
7
7
|
from ..base.contexts import UnmarshalContext
|
|
8
|
+
from ..base.contexts import UnmarshalFactoryContext
|
|
8
9
|
from ..base.types import Unmarshaler
|
|
10
|
+
from ..base.types import UnmarshalerFactory
|
|
9
11
|
from ..base.values import Value
|
|
10
|
-
from ..factories.simple import SimpleUnmarshalerFactory
|
|
11
12
|
from .metadata import FieldInfo
|
|
12
13
|
from .metadata import FieldInfos
|
|
13
14
|
from .metadata import ObjectSpecials
|
|
@@ -35,13 +36,13 @@ class ObjectUnmarshaler(Unmarshaler):
|
|
|
35
36
|
@classmethod
|
|
36
37
|
def make(
|
|
37
38
|
cls,
|
|
38
|
-
ctx:
|
|
39
|
+
ctx: UnmarshalFactoryContext,
|
|
39
40
|
factory: ta.Callable,
|
|
40
41
|
fis: FieldInfos,
|
|
41
42
|
**kwargs: ta.Any,
|
|
42
43
|
) -> Unmarshaler:
|
|
43
44
|
fields_by_unmarshal_name = {
|
|
44
|
-
n: (fi, ctx.
|
|
45
|
+
n: (fi, ctx.make_unmarshaler(fi.type))
|
|
45
46
|
for fi in fis
|
|
46
47
|
for n in fi.unmarshal_names
|
|
47
48
|
}
|
|
@@ -118,24 +119,27 @@ class ObjectUnmarshaler(Unmarshaler):
|
|
|
118
119
|
|
|
119
120
|
|
|
120
121
|
@dc.dataclass(frozen=True)
|
|
121
|
-
class SimpleObjectUnmarshalerFactory(
|
|
122
|
+
class SimpleObjectUnmarshalerFactory(UnmarshalerFactory):
|
|
122
123
|
dct: ta.Mapping[type, ta.Sequence[FieldInfo]]
|
|
123
124
|
|
|
124
125
|
_: dc.KW_ONLY
|
|
125
126
|
|
|
126
127
|
specials: ObjectSpecials = ObjectSpecials()
|
|
127
128
|
|
|
128
|
-
def
|
|
129
|
-
|
|
129
|
+
def make_unmarshaler(self, ctx: UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
|
|
130
|
+
if not (isinstance(rty, type) and rty in self.dct):
|
|
131
|
+
return None
|
|
130
132
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
+
def inner() -> Unmarshaler:
|
|
134
|
+
ty = check.isinstance(rty, type)
|
|
133
135
|
|
|
134
|
-
|
|
136
|
+
fis = FieldInfos(self.dct[ty])
|
|
135
137
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
return ObjectUnmarshaler.make(
|
|
139
|
+
ctx,
|
|
140
|
+
ty,
|
|
141
|
+
fis,
|
|
142
|
+
specials=self.specials,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
return inner
|
|
@@ -2,13 +2,13 @@ import abc
|
|
|
2
2
|
import dataclasses as dc
|
|
3
3
|
import typing as ta
|
|
4
4
|
|
|
5
|
-
from ... import check
|
|
6
5
|
from ... import lang
|
|
7
6
|
from ... import reflect as rfl
|
|
8
7
|
from ..base.contexts import MarshalContext
|
|
8
|
+
from ..base.contexts import MarshalFactoryContext
|
|
9
9
|
from ..base.types import Marshaler
|
|
10
|
+
from ..base.types import MarshalerFactory
|
|
10
11
|
from ..base.values import Value
|
|
11
|
-
from ..factories.simple import SimpleMarshalerFactory
|
|
12
12
|
from .metadata import FieldTypeTagging
|
|
13
13
|
from .metadata import Impls
|
|
14
14
|
from .metadata import Polymorphism
|
|
@@ -53,10 +53,10 @@ class FieldPolymorphismMarshaler(PolymorphismMarshaler):
|
|
|
53
53
|
def make_polymorphism_marshaler(
|
|
54
54
|
impls: Impls,
|
|
55
55
|
tt: TypeTagging,
|
|
56
|
-
ctx:
|
|
56
|
+
ctx: MarshalFactoryContext,
|
|
57
57
|
) -> Marshaler:
|
|
58
58
|
m = {
|
|
59
|
-
i.ty: (i.tag, ctx.
|
|
59
|
+
i.ty: (i.tag, ctx.make_marshaler(i.ty))
|
|
60
60
|
for i in impls
|
|
61
61
|
}
|
|
62
62
|
if isinstance(tt, WrapperTypeTagging):
|
|
@@ -68,13 +68,11 @@ def make_polymorphism_marshaler(
|
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
@dc.dataclass(frozen=True)
|
|
71
|
-
class PolymorphismMarshalerFactory(
|
|
71
|
+
class PolymorphismMarshalerFactory(MarshalerFactory):
|
|
72
72
|
p: Polymorphism
|
|
73
73
|
tt: TypeTagging = WrapperTypeTagging()
|
|
74
74
|
|
|
75
|
-
def
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
check.is_(rty, self.p.ty)
|
|
80
|
-
return make_polymorphism_marshaler(self.p.impls, self.tt, ctx)
|
|
75
|
+
def make_marshaler(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
|
|
76
|
+
if rty is not self.p.ty:
|
|
77
|
+
return None
|
|
78
|
+
return lambda: make_polymorphism_marshaler(self.p.impls, self.tt, ctx)
|
|
@@ -107,23 +107,34 @@ class Polymorphism:
|
|
|
107
107
|
return self._impls
|
|
108
108
|
|
|
109
109
|
|
|
110
|
+
class AutoStripSuffix(lang.Marker):
|
|
111
|
+
pass
|
|
112
|
+
|
|
113
|
+
|
|
110
114
|
def polymorphism_from_impls(
|
|
111
115
|
ty: type,
|
|
112
116
|
impls: ta.Iterable[type],
|
|
113
117
|
*,
|
|
114
118
|
naming: Naming | None = None,
|
|
115
|
-
strip_suffix: bool |
|
|
119
|
+
strip_suffix: bool | type[AutoStripSuffix] | str = False,
|
|
116
120
|
) -> Polymorphism:
|
|
117
121
|
impls = set(impls)
|
|
118
122
|
|
|
119
|
-
|
|
123
|
+
ssx: str | None
|
|
124
|
+
if strip_suffix is AutoStripSuffix:
|
|
120
125
|
strip_suffix = all(c.__name__.endswith(ty.__name__) for c in impls)
|
|
126
|
+
if isinstance(strip_suffix, bool):
|
|
127
|
+
ssx = ty.__name__ if strip_suffix else None
|
|
128
|
+
elif isinstance(strip_suffix, str):
|
|
129
|
+
ssx = strip_suffix
|
|
130
|
+
else:
|
|
131
|
+
raise TypeError(strip_suffix)
|
|
121
132
|
|
|
122
133
|
dct: dict[str, Impl] = {}
|
|
123
134
|
for cur in impls:
|
|
124
135
|
name = cur.__name__
|
|
125
|
-
if
|
|
126
|
-
name = lang.strip_suffix(name,
|
|
136
|
+
if ssx is not None:
|
|
137
|
+
name = lang.strip_suffix(name, ssx)
|
|
127
138
|
if naming is not None:
|
|
128
139
|
name = translate_name(name, naming)
|
|
129
140
|
if name in dct:
|
|
@@ -141,7 +152,7 @@ def polymorphism_from_subclasses(
|
|
|
141
152
|
ty: type,
|
|
142
153
|
*,
|
|
143
154
|
naming: Naming | None = None,
|
|
144
|
-
strip_suffix: bool |
|
|
155
|
+
strip_suffix: bool | type[AutoStripSuffix] | str = False,
|
|
145
156
|
) -> Polymorphism:
|
|
146
157
|
return polymorphism_from_impls(
|
|
147
158
|
ty,
|
|
@@ -6,6 +6,8 @@ from .marshal import PolymorphismMarshalerFactory
|
|
|
6
6
|
from .metadata import Polymorphism
|
|
7
7
|
from .metadata import TypeTagging
|
|
8
8
|
from .metadata import WrapperTypeTagging
|
|
9
|
+
from .unions import PolymorphismUnionMarshalerFactory
|
|
10
|
+
from .unions import PolymorphismUnionUnmarshalerFactory
|
|
9
11
|
from .unmarshal import PolymorphismUnmarshalerFactory
|
|
10
12
|
|
|
11
13
|
|
|
@@ -15,8 +17,18 @@ from .unmarshal import PolymorphismUnmarshalerFactory
|
|
|
15
17
|
def standard_polymorphism_factories(
|
|
16
18
|
poly: Polymorphism,
|
|
17
19
|
tt: TypeTagging = WrapperTypeTagging(),
|
|
20
|
+
*,
|
|
21
|
+
unions: bool | ta.Literal['partial'] = False,
|
|
18
22
|
) -> ta.Sequence[MarshalerFactory | UnmarshalerFactory]:
|
|
19
|
-
|
|
23
|
+
out: list[MarshalerFactory | UnmarshalerFactory] = [
|
|
20
24
|
PolymorphismMarshalerFactory(poly, tt),
|
|
21
25
|
PolymorphismUnmarshalerFactory(poly, tt),
|
|
22
26
|
]
|
|
27
|
+
|
|
28
|
+
if unions:
|
|
29
|
+
out.extend([
|
|
30
|
+
PolymorphismUnionMarshalerFactory(poly.impls, tt, allow_partial=unions == 'partial'),
|
|
31
|
+
PolymorphismUnionUnmarshalerFactory(poly.impls, tt, allow_partial=unions == 'partial'),
|
|
32
|
+
])
|
|
33
|
+
|
|
34
|
+
return out
|