omlish 0.0.0.dev3__tar.gz → 0.0.0.dev4__tar.gz
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-0.0.0.dev3/omlish.egg-info → omlish-0.0.0.dev4}/PKG-INFO +4 -1
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/__about__.py +1 -1
- omlish-0.0.0.dev4/omlish/__init__.py +8 -0
- omlish-0.0.0.dev4/omlish/asyncs/__init__.py +38 -0
- omlish-0.0.0.dev4/omlish/asyncs/flavors.py +201 -0
- omlish-0.0.0.dev4/omlish/asyncs/trio_asyncio.py +41 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dynamic.py +2 -2
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/fnpairs.py +111 -22
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/elements.py +13 -1
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/injector.py +7 -5
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/scopes.py +3 -2
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/json.py +136 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/__init__.py +4 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/classes/restrict.py +1 -1
- omlish-0.0.0.dev4/omlish/lang/sys.py +7 -0
- omlish-0.0.0.dev4/omlish/sql/__init__.py +9 -0
- omlish-0.0.0.dev4/omlish/sql/asyncs.py +148 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pydevd.py +2 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4/omlish.egg-info}/PKG-INFO +4 -1
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish.egg-info/SOURCES.txt +4 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish.egg-info/requires.txt +4 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/pyproject.toml +8 -5
- omlish-0.0.0.dev3/omlish/asyncs/__init__.py +0 -17
- omlish-0.0.0.dev3/omlish/sql/__init__.py +0 -0
- omlish-0.0.0.dev3/omlish/text/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/LICENSE +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/MANIFEST.in +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/README.md +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/argparse.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/asyncs/anyio.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/asyncs/asyncio.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/asyncs/asyncs.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/asyncs/futures.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/asyncs/trio.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/c3.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/cached.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/check.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/_abc.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/_io_abc.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/cache/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/cache/descriptor.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/cache/impl.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/cache/types.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/coerce.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/frozen.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/identity.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/indexed.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/mappings.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/ordered.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/persistent.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/skiplist.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/sorted.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/treap.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/treapmap.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/unmodifiable.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/utils.py +0 -0
- {omlish-0.0.0.dev3/omlish → omlish-0.0.0.dev4/omlish/configs}/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/configs/flattening.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/configs/props.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/api.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/as_.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/exceptions.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/fields.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/frozen.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/hashing.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/init.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/internals.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/main.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/metaclass.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/metadata.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/order.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/params.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/processing.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/reflect.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/replace.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/repr.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/simple.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/slots.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/utils.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/defs.py +0 -0
- {omlish-0.0.0.dev3/omlish/configs → omlish-0.0.0.dev4/omlish/diag}/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/diag/procfs.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/diag/ps.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/diag/replserver/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/diag/replserver/__main__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/diag/replserver/console.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/diag/replserver/server.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dispatch/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dispatch/dispatch.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dispatch/functions.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dispatch/methods.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/docker.py +0 -0
- {omlish-0.0.0.dev3/omlish/diag → omlish-0.0.0.dev4/omlish/graphs}/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/graphs/dot/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/graphs/dot/items.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/graphs/dot/rendering.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/graphs/dot/utils.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/graphs/trees.py +0 -0
- {omlish-0.0.0.dev3/omlish/graphs → omlish-0.0.0.dev4/omlish/http}/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/http/consts.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/http/wsgi.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/binder.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/bindings.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/eagers.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/elements.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/exceptions.py +0 -0
- {omlish-0.0.0.dev3/omlish/http → omlish-0.0.0.dev4/omlish/inject/impl}/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/bindings.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/inspect.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/private.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/providers.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/injector.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/inspect.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/keys.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/managed.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/overrides.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/private.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/providers.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/proxy.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/scopes.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/types.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/iterators.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/cached.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/classes/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/classes/abstract.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/classes/simple.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/classes/virtual.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/clsdct.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/cmp.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/contextmanagers.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/datetimes.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/descriptors.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/exceptions.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/functions.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/imports.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/iterables.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/maybes.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/objects.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/resolving.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/strings.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/timeouts.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/typing.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/libc.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/logs/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/logs/_abc.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/logs/configs.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/logs/filters.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/logs/formatters.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/logs/utils.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/any.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/base.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/base64.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/dataclasses.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/datetimes.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/enums.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/exceptions.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/factories.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/global_.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/iterables.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/mappings.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/naming.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/objects.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/optionals.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/polymorphism.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/primitives.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/registries.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/standard.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/utils.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/uuids.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/values.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/math.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/os.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/reflect.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/runmodule.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/sql/_abc.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/sql/dbs.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/stats.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/term.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/helpers.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/inject/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/inject/harness.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/_registry.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/logging.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/pydevd.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/repeat.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/skips.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/spacing.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/switches.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/testing.py +0 -0
- {omlish-0.0.0.dev3/omlish/inject/impl → omlish-0.0.0.dev4/omlish/text}/__init__.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/text/delimit.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/text/indent.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/text/parts.py +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish.egg-info/dependency_links.txt +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish.egg-info/top_level.txt +0 -0
- {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: omlish
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev4
|
|
4
4
|
Summary: omlish
|
|
5
5
|
Author: wrmsr
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -13,6 +13,9 @@ Requires-Python: >=3.12
|
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Provides-Extra: async
|
|
15
15
|
Requires-Dist: anyio; extra == "async"
|
|
16
|
+
Provides-Extra: trio
|
|
17
|
+
Requires-Dist: trio; extra == "trio"
|
|
18
|
+
Requires-Dist: trio-asyncio; extra == "trio"
|
|
16
19
|
Provides-Extra: http
|
|
17
20
|
Requires-Dist: httpx; extra == "http"
|
|
18
21
|
Provides-Extra: sql
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from .asyncs import ( # noqa
|
|
2
|
+
SyncableIterable,
|
|
3
|
+
async_list,
|
|
4
|
+
sync_await,
|
|
5
|
+
sync_list,
|
|
6
|
+
syncable_iterable,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
from .flavors import ( # noqa
|
|
10
|
+
ContextManagerAdapter,
|
|
11
|
+
Flavor,
|
|
12
|
+
adapt,
|
|
13
|
+
adapt_context,
|
|
14
|
+
from_anyio,
|
|
15
|
+
from_anyio_context,
|
|
16
|
+
from_asyncio,
|
|
17
|
+
from_asyncio_context,
|
|
18
|
+
from_trio,
|
|
19
|
+
from_trio_context,
|
|
20
|
+
get_flavor,
|
|
21
|
+
mark_anyio,
|
|
22
|
+
mark_asyncio,
|
|
23
|
+
mark_flavor,
|
|
24
|
+
mark_trio,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
from .futures import ( # noqa
|
|
28
|
+
FutureError,
|
|
29
|
+
FutureTimeoutError,
|
|
30
|
+
ImmediateExecutor,
|
|
31
|
+
new_thread_or_immediate_executor,
|
|
32
|
+
wait_dependent_futures,
|
|
33
|
+
wait_futures,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
from .trio_asyncio import ( # noqa
|
|
37
|
+
with_trio_asyncio_loop,
|
|
38
|
+
)
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- 'get current'? -> sniffio..
|
|
4
|
+
- mark whole class / module?
|
|
5
|
+
- sync/greenlet bridge
|
|
6
|
+
"""
|
|
7
|
+
import abc
|
|
8
|
+
import dataclasses as dc
|
|
9
|
+
import enum
|
|
10
|
+
import typing as ta
|
|
11
|
+
|
|
12
|
+
from .. import lang
|
|
13
|
+
from .trio_asyncio import check_trio_asyncio
|
|
14
|
+
|
|
15
|
+
if ta.TYPE_CHECKING:
|
|
16
|
+
import sniffio
|
|
17
|
+
import trio_asyncio
|
|
18
|
+
else:
|
|
19
|
+
sniffio = lang.proxy_import('sniffio')
|
|
20
|
+
trio_asyncio = lang.proxy_import('trio_asyncio')
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
T = ta.TypeVar('T')
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
##
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
_FLAVOR_ATTR = '__async_flavor__'
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class _MISSING(lang.Marker):
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class Flavor(enum.Enum):
|
|
37
|
+
ASYNCIO = enum.auto()
|
|
38
|
+
TRIO = enum.auto()
|
|
39
|
+
ANYIO = enum.auto()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def mark_flavor(f: Flavor):
|
|
43
|
+
if not isinstance(f, Flavor):
|
|
44
|
+
raise TypeError(f)
|
|
45
|
+
|
|
46
|
+
def inner(fn):
|
|
47
|
+
setattr(fn, _FLAVOR_ATTR, f)
|
|
48
|
+
return fn
|
|
49
|
+
|
|
50
|
+
return inner
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
mark_asyncio = mark_flavor(Flavor.ASYNCIO)
|
|
54
|
+
mark_anyio = mark_flavor(Flavor.ANYIO)
|
|
55
|
+
mark_trio = mark_flavor(Flavor.TRIO)
|
|
56
|
+
|
|
57
|
+
PACKAGE_FLAVORS: ta.MutableMapping[str, Flavor] = {
|
|
58
|
+
'anyio': Flavor.ANYIO,
|
|
59
|
+
'asyncio': Flavor.ASYNCIO,
|
|
60
|
+
'trio': Flavor.TRIO,
|
|
61
|
+
|
|
62
|
+
'sqlalchemy.ext.asyncio': Flavor.ASYNCIO,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
_MODULE_FLAVOR_CACHE: dict[str, Flavor | None] = {}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _get_module_flavor(p: str) -> Flavor | None:
|
|
69
|
+
try:
|
|
70
|
+
return _MODULE_FLAVOR_CACHE[p]
|
|
71
|
+
except KeyError:
|
|
72
|
+
pass
|
|
73
|
+
pf: Flavor | None = None
|
|
74
|
+
for cp, cf in PACKAGE_FLAVORS.items():
|
|
75
|
+
if p.startswith(cp) and (len(cp) == len(p) or p[len(cp)] == '.'):
|
|
76
|
+
pf = cf
|
|
77
|
+
break
|
|
78
|
+
_MODULE_FLAVOR_CACHE[p] = pf
|
|
79
|
+
return pf
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def get_flavor(obj: ta.Any, default: ta.Union[Flavor, type[_MISSING], None] = _MISSING) -> Flavor:
|
|
83
|
+
u = lang.unwrap_func(obj)
|
|
84
|
+
|
|
85
|
+
try:
|
|
86
|
+
return getattr(u, _FLAVOR_ATTR)
|
|
87
|
+
except AttributeError:
|
|
88
|
+
pass
|
|
89
|
+
|
|
90
|
+
if (mn := getattr(u, '__module__', None)) is not None:
|
|
91
|
+
if (pf := _get_module_flavor(mn)):
|
|
92
|
+
return pf
|
|
93
|
+
|
|
94
|
+
if default is not _MISSING:
|
|
95
|
+
return default # type: ignore
|
|
96
|
+
|
|
97
|
+
raise TypeError(f'not marked with flavor: {obj}')
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
##
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class Adapter(lang.Abstract):
|
|
104
|
+
_FROM_METHODS_BY_FLAVOR: ta.ClassVar[ta.Mapping[Flavor, str]] = {
|
|
105
|
+
Flavor.ANYIO: 'from_anyio',
|
|
106
|
+
Flavor.ASYNCIO: 'from_asyncio',
|
|
107
|
+
Flavor.TRIO: 'from_trio',
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
def adapt(self, fn, fl=None):
|
|
111
|
+
if fl is None:
|
|
112
|
+
fl = get_flavor(fn)
|
|
113
|
+
return getattr(self, self._FROM_METHODS_BY_FLAVOR[fl])(fn)
|
|
114
|
+
|
|
115
|
+
#
|
|
116
|
+
|
|
117
|
+
def from_anyio(self, fn):
|
|
118
|
+
return fn
|
|
119
|
+
|
|
120
|
+
@abc.abstractmethod
|
|
121
|
+
def from_asyncio(self, fn):
|
|
122
|
+
raise NotImplementedError
|
|
123
|
+
|
|
124
|
+
@abc.abstractmethod
|
|
125
|
+
def from_trio(self, fn):
|
|
126
|
+
raise NotImplementedError
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class AsyncioAdapter(Adapter):
|
|
130
|
+
def from_asyncio(self, fn):
|
|
131
|
+
return fn
|
|
132
|
+
|
|
133
|
+
def from_trio(self, fn):
|
|
134
|
+
check_trio_asyncio()
|
|
135
|
+
return trio_asyncio.trio_as_aio(fn)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class TrioAdapter(Adapter):
|
|
139
|
+
def from_asyncio(self, fn):
|
|
140
|
+
check_trio_asyncio()
|
|
141
|
+
return trio_asyncio.aio_as_trio(fn)
|
|
142
|
+
|
|
143
|
+
def from_trio(self, fn):
|
|
144
|
+
return fn
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
_ADAPTERS_BY_BACKEND: ta.Mapping[str, Adapter] = {
|
|
148
|
+
'asyncio': AsyncioAdapter(),
|
|
149
|
+
'trio': TrioAdapter(),
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def get_adapter() -> Adapter:
|
|
154
|
+
return _ADAPTERS_BY_BACKEND[sniffio.current_async_library()]
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def adapt(fn, fl=None):
|
|
158
|
+
return get_adapter().adapt(fn, fl)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def from_anyio(fn):
|
|
162
|
+
return get_adapter().from_anyio(fn)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def from_asyncio(fn):
|
|
166
|
+
return get_adapter().from_asyncio(fn)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def from_trio(fn):
|
|
170
|
+
return get_adapter().from_trio(fn)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
##
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@dc.dataclass(frozen=True)
|
|
177
|
+
class ContextManagerAdapter(ta.Generic[T]):
|
|
178
|
+
obj: ta.AsyncContextManager[T]
|
|
179
|
+
adapt: ta.Callable[[ta.Callable], ta.Callable]
|
|
180
|
+
|
|
181
|
+
async def __aenter__(self, *args: ta.Any, **kwargs: ta.Any) -> T:
|
|
182
|
+
return await self.adapt(self.obj.__aenter__)(*args, **kwargs)
|
|
183
|
+
|
|
184
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
185
|
+
return await self.adapt(self.obj.__aexit__)(exc_type, exc_val, exc_tb)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def adapt_context(obj):
|
|
189
|
+
return ContextManagerAdapter(obj, get_adapter().adapt)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def from_anyio_context(obj):
|
|
193
|
+
return ContextManagerAdapter(obj, get_adapter().from_anyio)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def from_asyncio_context(obj):
|
|
197
|
+
return ContextManagerAdapter(obj, get_adapter().from_asyncio)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def from_trio_context(obj):
|
|
201
|
+
return ContextManagerAdapter(obj, get_adapter().from_trio)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
import typing as ta
|
|
3
|
+
|
|
4
|
+
from .. import lang
|
|
5
|
+
|
|
6
|
+
if ta.TYPE_CHECKING:
|
|
7
|
+
import asyncio
|
|
8
|
+
import sniffio
|
|
9
|
+
import trio_asyncio
|
|
10
|
+
else:
|
|
11
|
+
asyncio = lang.proxy_import('asyncio')
|
|
12
|
+
sniffio = lang.proxy_import('sniffio')
|
|
13
|
+
trio_asyncio = lang.proxy_import('trio_asyncio')
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def check_trio_asyncio() -> None:
|
|
17
|
+
if trio_asyncio.current_loop.get() is None:
|
|
18
|
+
raise RuntimeError('trio_asyncio loop not running')
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def with_trio_asyncio_loop(fn, *, wait=False):
|
|
22
|
+
@functools.wraps(fn)
|
|
23
|
+
async def inner(*args, **kwargs):
|
|
24
|
+
if trio_asyncio.current_loop.get() is not None:
|
|
25
|
+
await fn(*args, **kwargs)
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
if sniffio.current_async_library() != 'trio':
|
|
29
|
+
raise RuntimeError('trio loop not running')
|
|
30
|
+
|
|
31
|
+
loop: asyncio.BaseEventLoop
|
|
32
|
+
async with trio_asyncio.open_loop() as loop:
|
|
33
|
+
try:
|
|
34
|
+
await fn(*args, **kwargs)
|
|
35
|
+
finally:
|
|
36
|
+
if wait:
|
|
37
|
+
# FIXME: lol
|
|
38
|
+
while asyncio.all_tasks(loop):
|
|
39
|
+
await asyncio.sleep(.2)
|
|
40
|
+
|
|
41
|
+
return inner
|
|
@@ -49,7 +49,7 @@ class Var(ta.Generic[T]):
|
|
|
49
49
|
|
|
50
50
|
def __init__(
|
|
51
51
|
self,
|
|
52
|
-
default: type[MISSING] | T = MISSING,
|
|
52
|
+
default: type[MISSING] | T = MISSING,
|
|
53
53
|
*,
|
|
54
54
|
new: ta.Callable[[], T] | type[MISSING] = MISSING,
|
|
55
55
|
validate: ta.Callable[[T], None] | None = None,
|
|
@@ -138,7 +138,7 @@ class Var(ta.Generic[T]):
|
|
|
138
138
|
frame = frame.f_back
|
|
139
139
|
|
|
140
140
|
if self._new is not MISSING:
|
|
141
|
-
yield self._new()
|
|
141
|
+
yield self._new() # type: ignore
|
|
142
142
|
|
|
143
143
|
def __iter__(self) -> ta.Iterator[T]:
|
|
144
144
|
return self.values
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- objects
|
|
4
|
+
- csv
|
|
5
|
+
- csvloader
|
|
6
|
+
- cbor
|
|
7
|
+
- cloudpickle
|
|
8
|
+
- alt json backends
|
|
9
|
+
- compression
|
|
10
|
+
- snappy
|
|
11
|
+
- lz4
|
|
12
|
+
- wrapped (wait for usecase)
|
|
13
|
+
"""
|
|
1
14
|
import abc
|
|
2
15
|
import codecs
|
|
3
16
|
import dataclasses as dc
|
|
@@ -6,32 +19,41 @@ import typing as ta
|
|
|
6
19
|
from . import lang
|
|
7
20
|
|
|
8
21
|
if ta.TYPE_CHECKING:
|
|
9
|
-
import
|
|
22
|
+
import bz2 as _bz2
|
|
23
|
+
import cloudpickle as _cloudpickle
|
|
10
24
|
import gzip as _gzip
|
|
11
25
|
import json as _json
|
|
26
|
+
import lz4.frame as _lz4_frame
|
|
12
27
|
import lzma as _lzma
|
|
13
28
|
import pickle as _pickle
|
|
29
|
+
import snappy as _snappy
|
|
14
30
|
import struct as _struct
|
|
15
31
|
import tomllib as _tomllib
|
|
32
|
+
import yaml as _yaml
|
|
33
|
+
import zstd as _zstd
|
|
16
34
|
|
|
17
35
|
else:
|
|
18
|
-
|
|
36
|
+
_bz2 = lang.proxy_import('bz2')
|
|
37
|
+
_cloudpickle = lang.proxy_import('cloudpickle')
|
|
19
38
|
_gzip = lang.proxy_import('gzip')
|
|
20
39
|
_json = lang.proxy_import('json')
|
|
40
|
+
_lz4_frame = lang.proxy_import('lz4.frame')
|
|
21
41
|
_lzma = lang.proxy_import('lzma')
|
|
22
42
|
_pickle = lang.proxy_import('pickle')
|
|
43
|
+
_snappy = lang.proxy_import('snappy')
|
|
23
44
|
_struct = lang.proxy_import('struct')
|
|
24
45
|
_tomllib = lang.proxy_import('tomllib')
|
|
25
|
-
|
|
26
|
-
_zstd = lang.proxy_import('zstd')
|
|
27
|
-
_yaml = lang.proxy_import('yaml')
|
|
46
|
+
_yaml = lang.proxy_import('yaml')
|
|
47
|
+
_zstd = lang.proxy_import('zstd')
|
|
28
48
|
|
|
29
49
|
|
|
30
50
|
##
|
|
31
51
|
|
|
32
52
|
|
|
33
53
|
F = ta.TypeVar('F')
|
|
54
|
+
F2 = ta.TypeVar('F2')
|
|
34
55
|
T = ta.TypeVar('T')
|
|
56
|
+
T2 = ta.TypeVar('T2')
|
|
35
57
|
U = ta.TypeVar('U')
|
|
36
58
|
|
|
37
59
|
|
|
@@ -44,6 +66,11 @@ class FnPair(ta.Generic[F, T], abc.ABC):
|
|
|
44
66
|
def backward(self, t: T) -> F:
|
|
45
67
|
raise NotImplementedError
|
|
46
68
|
|
|
69
|
+
##
|
|
70
|
+
|
|
71
|
+
def __call__(self, f: F) -> T:
|
|
72
|
+
return self.forward(f)
|
|
73
|
+
|
|
47
74
|
def invert(self) -> 'FnPair[T, F]':
|
|
48
75
|
if isinstance(self, Inverted):
|
|
49
76
|
return self.fp
|
|
@@ -76,6 +103,8 @@ Simple.__abstractmethods__ = frozenset() # noqa
|
|
|
76
103
|
|
|
77
104
|
of = Simple
|
|
78
105
|
|
|
106
|
+
NOP: FnPair[ta.Any, ta.Any] = of(lang.identity, lang.identity)
|
|
107
|
+
|
|
79
108
|
|
|
80
109
|
##
|
|
81
110
|
|
|
@@ -91,9 +120,6 @@ class Inverted(FnPair[F, T]):
|
|
|
91
120
|
return self.fp.forward(t)
|
|
92
121
|
|
|
93
122
|
|
|
94
|
-
##
|
|
95
|
-
|
|
96
|
-
|
|
97
123
|
@dc.dataclass(frozen=True)
|
|
98
124
|
class Composite(FnPair[F, T]):
|
|
99
125
|
children: ta.Sequence[FnPair]
|
|
@@ -109,6 +135,14 @@ class Composite(FnPair[F, T]):
|
|
|
109
135
|
return ta.cast(F, t)
|
|
110
136
|
|
|
111
137
|
|
|
138
|
+
def compose(*ps: FnPair) -> FnPair:
|
|
139
|
+
if not ps:
|
|
140
|
+
return NOP
|
|
141
|
+
if len(ps) == 1:
|
|
142
|
+
return ps[0]
|
|
143
|
+
return Composite(ps)
|
|
144
|
+
|
|
145
|
+
|
|
112
146
|
##
|
|
113
147
|
|
|
114
148
|
|
|
@@ -177,6 +211,10 @@ def _register_extension(*ss):
|
|
|
177
211
|
return inner
|
|
178
212
|
|
|
179
213
|
|
|
214
|
+
def get_for_extension(ext: str) -> FnPair:
|
|
215
|
+
return compose(*[_EXTENSION_REGISTRY[p]() for p in ext.split('.')])
|
|
216
|
+
|
|
217
|
+
|
|
180
218
|
##
|
|
181
219
|
|
|
182
220
|
|
|
@@ -184,28 +222,28 @@ class Compression(FnPair[bytes, bytes], abc.ABC):
|
|
|
184
222
|
pass
|
|
185
223
|
|
|
186
224
|
|
|
187
|
-
@_register_extension('
|
|
225
|
+
@_register_extension('bz2')
|
|
188
226
|
@dc.dataclass(frozen=True)
|
|
189
|
-
class
|
|
227
|
+
class Bz2(Compression):
|
|
190
228
|
compresslevel: int = 9
|
|
191
229
|
|
|
192
230
|
def forward(self, f: bytes) -> bytes:
|
|
193
|
-
return
|
|
231
|
+
return _bz2.compress(f, compresslevel=self.compresslevel)
|
|
194
232
|
|
|
195
233
|
def backward(self, t: bytes) -> bytes:
|
|
196
|
-
return
|
|
234
|
+
return _bz2.decompress(t)
|
|
197
235
|
|
|
198
236
|
|
|
199
|
-
@_register_extension('
|
|
237
|
+
@_register_extension('gz')
|
|
200
238
|
@dc.dataclass(frozen=True)
|
|
201
|
-
class
|
|
239
|
+
class Gzip(Compression):
|
|
202
240
|
compresslevel: int = 9
|
|
203
241
|
|
|
204
242
|
def forward(self, f: bytes) -> bytes:
|
|
205
|
-
return
|
|
243
|
+
return _gzip.compress(f, compresslevel=self.compresslevel)
|
|
206
244
|
|
|
207
245
|
def backward(self, t: bytes) -> bytes:
|
|
208
|
-
return
|
|
246
|
+
return _gzip.decompress(t)
|
|
209
247
|
|
|
210
248
|
|
|
211
249
|
@_register_extension('lzma')
|
|
@@ -220,6 +258,27 @@ class Lzma(Compression):
|
|
|
220
258
|
#
|
|
221
259
|
|
|
222
260
|
|
|
261
|
+
@_register_extension('lz4')
|
|
262
|
+
@dc.dataclass(frozen=True)
|
|
263
|
+
class Lz4(Compression):
|
|
264
|
+
compression_level: int = 0
|
|
265
|
+
|
|
266
|
+
def forward(self, f: bytes) -> bytes:
|
|
267
|
+
return _lz4_frame.compress(f, compression_level=self.compression_level)
|
|
268
|
+
|
|
269
|
+
def backward(self, t: bytes) -> bytes:
|
|
270
|
+
return _lz4_frame.decompress(t)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
@_register_extension('snappy')
|
|
274
|
+
class Snappy(Compression):
|
|
275
|
+
def forward(self, f: bytes) -> bytes:
|
|
276
|
+
return _snappy.compress(f)
|
|
277
|
+
|
|
278
|
+
def backward(self, t: bytes) -> bytes:
|
|
279
|
+
return _snappy.decompress(t)
|
|
280
|
+
|
|
281
|
+
|
|
223
282
|
@_register_extension('zstd')
|
|
224
283
|
class Zstd(Compression):
|
|
225
284
|
def forward(self, f: bytes) -> bytes:
|
|
@@ -243,9 +302,27 @@ class Struct(FnPair[tuple, bytes]):
|
|
|
243
302
|
return _struct.unpack(self.fmt, t)
|
|
244
303
|
|
|
245
304
|
|
|
305
|
+
##
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
class Object(FnPair[ta.Any, T], lang.Abstract): # noqa
|
|
309
|
+
pass
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
class ObjectStr(Object[str], lang.Abstract): # noqa
|
|
313
|
+
pass
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
class ObjectBytes(Object[bytes], lang.Abstract): # noqa
|
|
317
|
+
pass
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
#
|
|
321
|
+
|
|
322
|
+
|
|
246
323
|
@_register_extension('pkl')
|
|
247
324
|
@dc.dataclass(frozen=True)
|
|
248
|
-
class Pickle(
|
|
325
|
+
class Pickle(ObjectBytes):
|
|
249
326
|
protocol: int | None = None
|
|
250
327
|
|
|
251
328
|
def forward(self, f: ta.Any) -> bytes:
|
|
@@ -257,7 +334,7 @@ class Pickle(FnPair[ta.Any, bytes]):
|
|
|
257
334
|
|
|
258
335
|
@_register_extension('json')
|
|
259
336
|
@dc.dataclass(frozen=True)
|
|
260
|
-
class Json(
|
|
337
|
+
class Json(ObjectStr):
|
|
261
338
|
indent: int | str | None = dc.field(default=None, kw_only=True)
|
|
262
339
|
separators: tuple[str, str] | None = dc.field(default=None, kw_only=True)
|
|
263
340
|
|
|
@@ -283,7 +360,7 @@ class JsonLines(FnPair[ta.Sequence[ta.Any], str]):
|
|
|
283
360
|
|
|
284
361
|
|
|
285
362
|
@_register_extension('toml')
|
|
286
|
-
class Toml(
|
|
363
|
+
class Toml(ObjectStr):
|
|
287
364
|
def forward(self, f: ta.Any) -> str:
|
|
288
365
|
raise NotImplementedError
|
|
289
366
|
|
|
@@ -294,8 +371,20 @@ class Toml(FnPair[ta.Any, str]):
|
|
|
294
371
|
#
|
|
295
372
|
|
|
296
373
|
|
|
374
|
+
@_register_extension('cpkl')
|
|
375
|
+
@dc.dataclass(frozen=True)
|
|
376
|
+
class Cloudpickle(ObjectBytes):
|
|
377
|
+
protocol: int | None = None
|
|
378
|
+
|
|
379
|
+
def forward(self, f: ta.Any) -> bytes:
|
|
380
|
+
return _cloudpickle.dumps(f, protocol=self.protocol)
|
|
381
|
+
|
|
382
|
+
def backward(self, t: bytes) -> ta.Any:
|
|
383
|
+
return _cloudpickle.loads(t)
|
|
384
|
+
|
|
385
|
+
|
|
297
386
|
@_register_extension('yml', 'yaml')
|
|
298
|
-
class Yaml(
|
|
387
|
+
class Yaml(ObjectStr):
|
|
299
388
|
def forward(self, f: ta.Any) -> str:
|
|
300
389
|
return _yaml.dump(f)
|
|
301
390
|
|
|
@@ -303,9 +392,9 @@ class Yaml(FnPair[ta.Any, str]):
|
|
|
303
392
|
return _yaml.safe_load(t)
|
|
304
393
|
|
|
305
394
|
|
|
306
|
-
class
|
|
395
|
+
class YamlUnsafe(ObjectStr):
|
|
307
396
|
def forward(self, f: ta.Any) -> str:
|
|
308
397
|
return _yaml.dump(f)
|
|
309
398
|
|
|
310
399
|
def backward(self, t: str) -> ta.Any:
|
|
311
|
-
return _yaml.
|
|
400
|
+
return _yaml.load(t, _yaml.FullLoader)
|
|
@@ -14,7 +14,7 @@ Element Types:
|
|
|
14
14
|
- Overrides
|
|
15
15
|
- Expose
|
|
16
16
|
- Private
|
|
17
|
-
-
|
|
17
|
+
- ScopeBinding
|
|
18
18
|
"""
|
|
19
19
|
import typing as ta
|
|
20
20
|
|
|
@@ -31,6 +31,7 @@ from ..overrides import Overrides
|
|
|
31
31
|
from ..private import Expose
|
|
32
32
|
from ..private import Private
|
|
33
33
|
from ..scopes import ScopeBinding
|
|
34
|
+
from ..types import Scope
|
|
34
35
|
from .bindings import BindingImpl
|
|
35
36
|
from .providers import MultiProviderImpl
|
|
36
37
|
from .providers import make_provider_impl
|
|
@@ -152,3 +153,14 @@ class ElementCollection(lang.Final):
|
|
|
152
153
|
@lang.cached_function
|
|
153
154
|
def binding_impl_map(self) -> ta.Mapping[Key, BindingImpl]:
|
|
154
155
|
return self._build_binding_impl_map(self.element_multimap())
|
|
156
|
+
|
|
157
|
+
##
|
|
158
|
+
|
|
159
|
+
@lang.cached_function
|
|
160
|
+
def eager_keys_by_scope(self) -> ta.Mapping[Scope, ta.Sequence[Key]]:
|
|
161
|
+
bim = self.binding_impl_map()
|
|
162
|
+
ret: dict[Scope, list[Key]] = {}
|
|
163
|
+
for e in self.elements_of_type(Eager):
|
|
164
|
+
bi = bim[e.key]
|
|
165
|
+
ret.setdefault(bi.scope, []).append(e.key)
|
|
166
|
+
return ret
|
|
@@ -7,6 +7,8 @@ TODO:
|
|
|
7
7
|
- config is probably shared with ElementCollection... but not 'bound', must be shared everywhere
|
|
8
8
|
- InjectorRoot object?
|
|
9
9
|
- ** eagers in any scope, on scope init/open
|
|
10
|
+
- injection listeners
|
|
11
|
+
- unions - raise on ambiguous - usecase: sql.AsyncEngineLike
|
|
10
12
|
"""
|
|
11
13
|
import contextlib
|
|
12
14
|
import typing as ta
|
|
@@ -14,7 +16,6 @@ import weakref
|
|
|
14
16
|
|
|
15
17
|
from ... import check
|
|
16
18
|
from ... import lang
|
|
17
|
-
from ..eagers import Eager
|
|
18
19
|
from ..elements import Elements
|
|
19
20
|
from ..exceptions import CyclicDependencyError
|
|
20
21
|
from ..exceptions import UnboundKeyError
|
|
@@ -52,6 +53,7 @@ class InjectorImpl(Injector, lang.Final):
|
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
self._bim = ec.binding_impl_map()
|
|
56
|
+
self._ekbs = ec.eager_keys_by_scope()
|
|
55
57
|
|
|
56
58
|
self._cs: weakref.WeakSet[InjectorImpl] | None = None
|
|
57
59
|
self._root: InjectorImpl = p._root if p is not None else self # noqa
|
|
@@ -66,13 +68,13 @@ class InjectorImpl(Injector, lang.Final):
|
|
|
66
68
|
s: make_scope_impl(s) for s in ss
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
self._instantiate_eagers()
|
|
71
|
+
self._instantiate_eagers(Unscoped())
|
|
70
72
|
|
|
71
73
|
_root: 'InjectorImpl'
|
|
72
74
|
|
|
73
|
-
def _instantiate_eagers(self) -> None:
|
|
74
|
-
for
|
|
75
|
-
self.provide(
|
|
75
|
+
def _instantiate_eagers(self, sc: Scope) -> None:
|
|
76
|
+
for k in self._ekbs.get(sc, ()):
|
|
77
|
+
self.provide(k)
|
|
76
78
|
|
|
77
79
|
def get_scope_impl(self, sc: Scope) -> ScopeImpl:
|
|
78
80
|
return self._scopes[sc]
|
|
@@ -141,8 +141,8 @@ class SeededScopeImpl(ScopeImpl):
|
|
|
141
141
|
def __init__(self, ss: SeededScope, i: Injector) -> None:
|
|
142
142
|
super().__init__()
|
|
143
143
|
self._ss = check.isinstance(ss, SeededScope)
|
|
144
|
-
|
|
145
|
-
self._ssi = check.isinstance(
|
|
144
|
+
self._ii = check.isinstance(i, injector_.InjectorImpl)
|
|
145
|
+
self._ssi = check.isinstance(self._ii.get_scope_impl(self._ss), SeededScopeImpl)
|
|
146
146
|
|
|
147
147
|
@contextlib.contextmanager
|
|
148
148
|
def __call__(self, seeds: ta.Mapping[Key, ta.Any]) -> ta.Generator[None, None, None]:
|
|
@@ -150,6 +150,7 @@ class SeededScopeImpl(ScopeImpl):
|
|
|
150
150
|
if self._ssi._st is not None: # noqa
|
|
151
151
|
raise ScopeAlreadyOpenError(self._ss)
|
|
152
152
|
self._ssi._st = SeededScopeImpl.State(dict(seeds)) # noqa
|
|
153
|
+
self._ii._instantiate_eagers(self._ss) # noqa
|
|
153
154
|
yield
|
|
154
155
|
finally:
|
|
155
156
|
if self._ssi._st is None: # noqa
|