omlish 0.0.0.dev25__tar.gz → 0.0.0.dev26__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.
- {omlish-0.0.0.dev25/omlish.egg-info → omlish-0.0.0.dev26}/PKG-INFO +1 -1
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/__about__.py +6 -2
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/bootstrap/diag.py +25 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/bootstrap/harness.py +3 -2
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/check.py +1 -1
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/__init__.py +1 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/utils.py +7 -2
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/__init__.py +4 -4
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/api.py +5 -3
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/exceptions.py +2 -2
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/fields.py +7 -4
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/init.py +8 -8
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/metadata.py +3 -3
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/params.py +4 -3
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/diag/replserver/server.py +17 -2
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/docker.py +74 -6
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/formats/yaml.py +10 -0
- omlish-0.0.0.dev26/omlish/graphs/dot/__init__.py +31 -0
- omlish-0.0.0.dev26/omlish/graphs/dot/make.py +16 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/graphs/dot/rendering.py +9 -8
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/http/cookies.py +2 -1
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/impl/scopes.py +2 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/keys.py +1 -1
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/multis.py +4 -4
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/providers.py +1 -1
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/__init__.py +8 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/classes/__init__.py +3 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/classes/restrict.py +25 -4
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/classes/simple.py +0 -4
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/classes/virtual.py +6 -4
- omlish-0.0.0.dev26/omlish/lang/datetimes.py +9 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lite/logs.py +30 -25
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lite/secrets.py +3 -1
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/logs/configs.py +2 -2
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/dataclasses.py +1 -1
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/secrets/secrets.py +1 -1
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/stats.py +1 -1
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26/omlish.egg-info}/PKG-INFO +1 -1
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish.egg-info/SOURCES.txt +2 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/pyproject.toml +1 -1
- omlish-0.0.0.dev25/omlish/graphs/dot/__init__.py +0 -19
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/LICENSE +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/MANIFEST.in +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/README.rst +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/_manifests.json +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/argparse.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/asyncs/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/asyncs/anyio.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/asyncs/asyncio.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/asyncs/asyncs.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/asyncs/bridge.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/asyncs/flavors.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/asyncs/trio.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/asyncs/trio_asyncio.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/bootstrap/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/bootstrap/__main__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/bootstrap/base.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/bootstrap/main.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/bootstrap/marshal.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/bootstrap/sys.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/c3.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/cached.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/_abc.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/_io_abc.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/cache/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/cache/descriptor.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/cache/impl.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/cache/types.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/coerce.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/exceptions.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/frozen.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/identity.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/indexed.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/mappings.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/ordered.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/persistent.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/skiplist.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/sorted.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/treap.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/treapmap.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/collections/unmodifiable.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/concurrent/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/concurrent/executors.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/concurrent/futures.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/concurrent/threadlets.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/configs/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/configs/classes.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/configs/flattening.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/configs/strings.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/LICENSE +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/as_.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/copy.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/descriptors.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/frozen.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/hashing.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/internals.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/main.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/metaclass.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/order.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/processing.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/reflect.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/replace.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/repr.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/simple.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/slots.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/impl/utils.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dataclasses/utils.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/datetimes.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/defs.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/diag/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/diag/asts.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/diag/procfs.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/diag/procstats.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/diag/ps.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/diag/pycharm.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/diag/pydevd.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/diag/replserver/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/diag/replserver/__main__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/diag/replserver/console.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/diag/threads.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dispatch/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dispatch/_dispatch2.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dispatch/_dispatch3.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dispatch/dispatch.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dispatch/functions.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dispatch/methods.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/dynamic.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/fnpairs.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/formats/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/formats/dotenv.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/formats/json.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/formats/props.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/genmachine.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/graphs/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/graphs/dags.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/graphs/domination.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/graphs/dot/items.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/graphs/dot/utils.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/graphs/trees.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/http/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/http/asgi.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/http/collections.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/http/consts.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/http/dates.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/http/encodings.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/http/json.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/http/sessions.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/http/wsgi.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/binder.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/bindings.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/eagers.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/elements.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/exceptions.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/impl/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/impl/bindings.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/impl/elements.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/impl/injector.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/impl/inspect.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/impl/multis.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/impl/origins.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/impl/privates.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/impl/providers.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/impl/proxy.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/injector.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/inspect.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/listeners.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/managed.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/origins.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/overrides.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/privates.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/scopes.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/types.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/inject/utils.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/iterators.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/cached.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/classes/abstract.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/clsdct.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/cmp.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/contextmanagers.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/descriptors.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/exceptions.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/functions.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/imports.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/iterables.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/maybes.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/objects.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/resolving.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/resources.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/strings.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/sys.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/timeouts.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lang/typing.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/libc.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lifecycles/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lifecycles/abstract.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lifecycles/base.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lifecycles/contextmanagers.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lifecycles/controller.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lifecycles/manager.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lifecycles/states.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lifecycles/transitions.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lite/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lite/cached.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lite/check.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lite/contextmanagers.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lite/json.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lite/marshal.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lite/reflect.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lite/runtime.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lite/strings.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/lite/subprocesses.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/logs/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/logs/_abc.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/logs/formatters.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/logs/handlers.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/logs/noisy.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/logs/utils.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/any.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/base.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/base64.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/datetimes.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/enums.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/exceptions.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/factories.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/forbidden.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/global_.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/helpers.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/iterables.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/mappings.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/maybes.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/naming.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/numbers.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/objects.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/optionals.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/polymorphism.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/primitives.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/registries.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/standard.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/unions.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/utils.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/uuids.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/marshal/values.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/matchfns.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/math.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/multiprocessing.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/os.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/reflect/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/reflect/isinstance.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/reflect/ops.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/reflect/subst.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/reflect/types.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/runmodule.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/secrets/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/secrets/crypto.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/secrets/marshal.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/secrets/openssl.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/secrets/passwords.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/secrets/subprocesses.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/keywords/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/keywords/base.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/keywords/core.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/keywords/metadata.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/keywords/parse.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/keywords/render.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/keywords/validation.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/schemas/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/schemas/draft202012/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/schemas/draft202012/metaschema.json +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/applicator.json +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/content.json +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/core.json +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/format-annotation.json +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/format-assertion.json +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/format.json +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/meta-data.json +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/unevaluated.json +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/validation.json +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/specs/jsonschema/types.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/sql/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/sql/_abc.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/sql/asyncs.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/sql/dbs.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/sql/duckdb.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/sql/exprs.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/sql/qualifiedname.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/sql/secrets.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/sql/sqlean.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/sync.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/term.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/helpers.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/inject/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/inject/harness.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/marks.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/plugins/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/plugins/_registry.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/plugins/asyncs.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/plugins/depskip.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/plugins/logging.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/plugins/managermarks.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/plugins/pydevd.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/plugins/repeat.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/plugins/skips.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/plugins/spacing.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/plugins/switches.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/pytest/plugins/utils.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/testing/testing.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/text/__init__.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/text/delimit.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/text/glyphsplit.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/text/indent.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish/text/parts.py +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish.egg-info/dependency_links.txt +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish.egg-info/requires.txt +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/omlish.egg-info/top_level.txt +0 -0
- {omlish-0.0.0.dev25 → omlish-0.0.0.dev26}/setup.cfg +0 -0
@@ -1,5 +1,5 @@
|
|
1
|
-
__version__ = '0.0.0.
|
2
|
-
__revision__ = '
|
1
|
+
__version__ = '0.0.0.dev26'
|
2
|
+
__revision__ = 'd3cb2e43eac2aa63dc4606aa371faa78ec0daf1a'
|
3
3
|
|
4
4
|
|
5
5
|
#
|
@@ -41,7 +41,9 @@ class Project(ProjectBase):
|
|
41
41
|
|
42
42
|
'compression': [
|
43
43
|
'lz4 ~= 4.0',
|
44
|
+
|
44
45
|
'python-snappy ~= 0.7; python_version < "3.13"',
|
46
|
+
|
45
47
|
'zstd ~= 1.5',
|
46
48
|
],
|
47
49
|
|
@@ -69,6 +71,7 @@ class Project(ProjectBase):
|
|
69
71
|
|
70
72
|
'misc': [
|
71
73
|
'jinja2 ~= 3.1',
|
74
|
+
|
72
75
|
'wrapt ~= 1.14',
|
73
76
|
],
|
74
77
|
|
@@ -81,6 +84,7 @@ class Project(ProjectBase):
|
|
81
84
|
|
82
85
|
'pg8000 ~= 1.31',
|
83
86
|
# 'psycopg2 ~= 2.9',
|
87
|
+
# 'psycopg ~= 3.2',
|
84
88
|
|
85
89
|
'pymysql ~= 1.1',
|
86
90
|
# 'mysql-connector-python ~= 9.0',
|
@@ -3,6 +3,7 @@ import contextlib
|
|
3
3
|
import dataclasses as dc
|
4
4
|
import signal
|
5
5
|
import sys
|
6
|
+
import threading
|
6
7
|
import typing as ta
|
7
8
|
|
8
9
|
from .. import check
|
@@ -17,6 +18,7 @@ if ta.TYPE_CHECKING:
|
|
17
18
|
import pstats
|
18
19
|
|
19
20
|
from ..diag import pycharm as diagpc
|
21
|
+
from ..diag import replserver as diagrs
|
20
22
|
from ..diag import threads as diagt
|
21
23
|
|
22
24
|
else:
|
@@ -24,6 +26,7 @@ else:
|
|
24
26
|
pstats = lang.proxy_import('pstats')
|
25
27
|
|
26
28
|
diagpc = lang.proxy_import('..diag.pycharm', __package__)
|
29
|
+
diagrs = lang.proxy_import('..diag.replserver', __package__)
|
27
30
|
diagt = lang.proxy_import('..diag.threads', __package__)
|
28
31
|
|
29
32
|
|
@@ -175,3 +178,25 @@ class PycharmBootstrap(SimpleBootstrap['PycharmBootstrap.Config']):
|
|
175
178
|
self._config.debug_port,
|
176
179
|
version=self._config.version,
|
177
180
|
)
|
181
|
+
|
182
|
+
|
183
|
+
##
|
184
|
+
|
185
|
+
|
186
|
+
class ReplServerBootstrap(ContextBootstrap['ReplServerBootstrap.Config']):
|
187
|
+
@dc.dataclass(frozen=True)
|
188
|
+
class Config(Bootstrap.Config):
|
189
|
+
path: str | None = None
|
190
|
+
|
191
|
+
@contextlib.contextmanager
|
192
|
+
def enter(self) -> ta.Iterator[None]:
|
193
|
+
if self._config.path is None:
|
194
|
+
return
|
195
|
+
|
196
|
+
with diagrs.ReplServer(diagrs.ReplServer.Config(
|
197
|
+
path=self._config.path,
|
198
|
+
)) as rs:
|
199
|
+
thread = threading.Thread(target=rs.run, name='replserver')
|
200
|
+
thread.start()
|
201
|
+
|
202
|
+
yield
|
@@ -6,6 +6,7 @@ TODO:
|
|
6
6
|
- multiprocess profiling - afterfork, suffix with pid
|
7
7
|
|
8
8
|
TODO diag:
|
9
|
+
- tracemalloc
|
9
10
|
- yappi
|
10
11
|
- stackscope
|
11
12
|
- https://github.com/pythonspeed/filprofiler
|
@@ -13,10 +14,10 @@ TODO diag:
|
|
13
14
|
- https://pypi.org/project/memory-profiler/
|
14
15
|
- https://pypi.org/project/Pympler/
|
15
16
|
|
17
|
+
|
16
18
|
TODO new items:
|
17
|
-
- pydevd connect-back
|
18
19
|
- debugging / pdb
|
19
|
-
|
20
|
+
- https://github.com/inducer/pudb
|
20
21
|
- packaging fixups
|
21
22
|
- daemonize ( https://github.com/thesharp/daemonize/blob/master/daemonize.py )
|
22
23
|
"""
|
@@ -332,7 +332,7 @@ def single(obj: ta.Iterable[T], message: Message = None) -> T:
|
|
332
332
|
return value
|
333
333
|
|
334
334
|
|
335
|
-
def
|
335
|
+
def opt_single(obj: ta.Iterable[T], message: Message = None) -> T | None:
|
336
336
|
it = iter(obj)
|
337
337
|
try:
|
338
338
|
value = next(it)
|
@@ -39,7 +39,12 @@ def toposort(data: ta.Mapping[T, ta.AbstractSet[T]]) -> ta.Iterator[set[T]]:
|
|
39
39
|
##
|
40
40
|
|
41
41
|
|
42
|
-
|
42
|
+
class PartitionResult(ta.NamedTuple, ta.Generic[T]):
|
43
|
+
t: list[T]
|
44
|
+
f: list[T]
|
45
|
+
|
46
|
+
|
47
|
+
def partition(items: ta.Iterable[T], pred: ta.Callable[[T], bool]) -> PartitionResult[T]:
|
43
48
|
t: list[T] = []
|
44
49
|
f: list[T] = []
|
45
50
|
for e in items:
|
@@ -47,7 +52,7 @@ def partition(items: ta.Iterable[T], pred: ta.Callable[[T], bool]) -> tuple[list
|
|
47
52
|
t.append(e)
|
48
53
|
else:
|
49
54
|
f.append(e)
|
50
|
-
return t, f
|
55
|
+
return PartitionResult(t, f)
|
51
56
|
|
52
57
|
|
53
58
|
def unique(
|
@@ -59,8 +59,8 @@ globals()['make_dataclass'] = xmake_dataclass
|
|
59
59
|
|
60
60
|
|
61
61
|
from .impl.exceptions import ( # noqa
|
62
|
-
|
63
|
-
|
62
|
+
FieldValidationError,
|
63
|
+
ValidationError,
|
64
64
|
)
|
65
65
|
|
66
66
|
from .impl.metaclass import ( # noqa
|
@@ -76,8 +76,8 @@ from .impl.metadata import ( # noqa
|
|
76
76
|
UserMetadata,
|
77
77
|
metadata,
|
78
78
|
|
79
|
-
|
80
|
-
|
79
|
+
Validate,
|
80
|
+
validate,
|
81
81
|
|
82
82
|
Init,
|
83
83
|
init,
|
@@ -30,8 +30,9 @@ def field( # noqa
|
|
30
30
|
metadata=None,
|
31
31
|
kw_only=MISSING,
|
32
32
|
|
33
|
-
|
34
|
-
|
33
|
+
derive: ta.Callable[..., ta.Any] | None = None,
|
34
|
+
coerce: bool | ta.Callable[[ta.Any], ta.Any] | None = None,
|
35
|
+
validate: ta.Callable[[ta.Any], bool] | None = None,
|
35
36
|
check_type: bool | None = None,
|
36
37
|
override: bool = False,
|
37
38
|
repr_fn: ta.Callable[[ta.Any], str | None] | None = None,
|
@@ -40,8 +41,9 @@ def field( # noqa
|
|
40
41
|
raise ValueError('cannot specify both default and default_factory')
|
41
42
|
|
42
43
|
fx = FieldExtras(
|
44
|
+
derive=derive,
|
43
45
|
coerce=coerce,
|
44
|
-
|
46
|
+
validate=validate,
|
45
47
|
check_type=check_type,
|
46
48
|
override=override,
|
47
49
|
repr_fn=repr_fn,
|
@@ -175,15 +175,18 @@ def field_init(
|
|
175
175
|
else:
|
176
176
|
pass
|
177
177
|
|
178
|
+
if fx.derive is not None:
|
179
|
+
raise NotImplementedError
|
180
|
+
|
178
181
|
if fx.coerce is not None:
|
179
182
|
cn = f'__dataclass_coerce__{f.name}__'
|
180
183
|
locals[cn] = fx.coerce
|
181
184
|
lines.append(f'{value} = {cn}({value})')
|
182
185
|
|
183
|
-
if fx.
|
184
|
-
cn = f'
|
185
|
-
locals[cn] = fx.
|
186
|
-
lines.append(f'if not {cn}({value}): raise
|
186
|
+
if fx.validate is not None:
|
187
|
+
cn = f'__dataclass_validate__{f.name}__'
|
188
|
+
locals[cn] = fx.validate
|
189
|
+
lines.append(f'if not {cn}({value}): raise __dataclass_FieldValidationError__({f.name})')
|
187
190
|
|
188
191
|
if fx.check_type:
|
189
192
|
cn = f'__dataclass_check_type__{f.name}__'
|
@@ -3,16 +3,16 @@ import inspect
|
|
3
3
|
import typing as ta
|
4
4
|
|
5
5
|
from ... import lang
|
6
|
-
from .exceptions import
|
7
|
-
from .exceptions import
|
6
|
+
from .exceptions import FieldValidationError
|
7
|
+
from .exceptions import ValidationError
|
8
8
|
from .fields import field_init
|
9
9
|
from .fields import field_type
|
10
10
|
from .fields import has_default
|
11
11
|
from .internals import HAS_DEFAULT_FACTORY
|
12
12
|
from .internals import POST_INIT_NAME
|
13
13
|
from .internals import FieldType
|
14
|
-
from .metadata import Check
|
15
14
|
from .metadata import Init
|
15
|
+
from .metadata import Validate
|
16
16
|
from .processing import Processor
|
17
17
|
from .reflect import ClassInfo
|
18
18
|
from .utils import Namespace
|
@@ -100,8 +100,8 @@ class InitBuilder:
|
|
100
100
|
'__dataclass_builtins_object__': object,
|
101
101
|
'__dataclass_builtins_isinstance__': isinstance,
|
102
102
|
'__dataclass_builtins_TypeError__': TypeError,
|
103
|
-
'
|
104
|
-
'
|
103
|
+
'__dataclass_ValidationError__': ValidationError,
|
104
|
+
'__dataclass_FieldValidationError__': FieldValidationError,
|
105
105
|
})
|
106
106
|
|
107
107
|
body_lines: list[str] = []
|
@@ -121,14 +121,14 @@ class InitBuilder:
|
|
121
121
|
params_str = ','.join(f.name for f in ifs.all if field_type(f) is FieldType.INIT)
|
122
122
|
body_lines.append(f'{self._self_name}.{POST_INIT_NAME}({params_str})')
|
123
123
|
|
124
|
-
for i, fn in enumerate(self._info.merged_metadata.get(
|
124
|
+
for i, fn in enumerate(self._info.merged_metadata.get(Validate, [])):
|
125
125
|
if isinstance(fn, staticmethod):
|
126
126
|
fn = fn.__func__
|
127
|
-
cn = f'
|
127
|
+
cn = f'__dataclass_validate_{i}__'
|
128
128
|
locals[cn] = fn
|
129
129
|
csig = inspect.signature(fn)
|
130
130
|
cas = ', '.join(p.name for p in csig.parameters.values())
|
131
|
-
body_lines.append(f'if not {cn}({cas}): raise
|
131
|
+
body_lines.append(f'if not {cn}({cas}): raise __dataclass_ValidationError__')
|
132
132
|
|
133
133
|
inits = self._info.merged_metadata.get(Init, [])
|
134
134
|
mro_dct = lang.build_mro_dict(self._info.cls)
|
@@ -54,12 +54,12 @@ def metadata(cls_dct, *args) -> None:
|
|
54
54
|
|
55
55
|
|
56
56
|
@_class_merged
|
57
|
-
class
|
57
|
+
class Validate(lang.Marker):
|
58
58
|
pass
|
59
59
|
|
60
60
|
|
61
|
-
def
|
62
|
-
_append_cls_md(
|
61
|
+
def validate(fn: ta.Callable[..., bool] | staticmethod) -> None:
|
62
|
+
_append_cls_md(Validate, fn)
|
63
63
|
|
64
64
|
|
65
65
|
##
|
@@ -40,10 +40,11 @@ from .metadata import METADATA_ATTR
|
|
40
40
|
##
|
41
41
|
|
42
42
|
|
43
|
-
@dc.dataclass(frozen=True)
|
43
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
44
44
|
class FieldExtras(lang.Final):
|
45
|
+
derive: ta.Callable[..., ta.Any] | None = None
|
45
46
|
coerce: bool | ta.Callable[[ta.Any], ta.Any] | None = None
|
46
|
-
|
47
|
+
validate: ta.Callable[[ta.Any], bool] | None = None
|
47
48
|
check_type: bool | None = None
|
48
49
|
override: bool = False
|
49
50
|
repr_fn: ta.Callable[[ta.Any], str | None] | None = None
|
@@ -79,7 +80,7 @@ def get_params(obj: ta.Any) -> Params:
|
|
79
80
|
##
|
80
81
|
|
81
82
|
|
82
|
-
@dc.dataclass(frozen=True)
|
83
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
83
84
|
class ParamsExtras(lang.Final):
|
84
85
|
reorder: bool = False
|
85
86
|
cache_hash: bool = False
|
@@ -1,8 +1,13 @@
|
|
1
1
|
"""
|
2
|
+
FIXME:
|
3
|
+
- lol shutdown deadlocks
|
4
|
+
- whole thing is just gross is this its own thread or what
|
5
|
+
|
2
6
|
TODO:
|
3
7
|
- !!! ANYIO !!!
|
4
8
|
- optional paramiko ssh-server
|
5
9
|
- optional ipython embed
|
10
|
+
- https://github.com/python/cpython/tree/56470004e58911b146c016fc9fec4461b8f69454/Lib/_pyrepl
|
6
11
|
|
7
12
|
lookit:
|
8
13
|
- https://github.com/vxgmichel/aioconsole/blob/e55f4b0601da3b3a40a88c965526d35ab38b5841/aioconsole/server.py
|
@@ -38,7 +43,7 @@ class ReplServer:
|
|
38
43
|
@dc.dataclass(frozen=True)
|
39
44
|
class Config:
|
40
45
|
path: str
|
41
|
-
file_mode: int | None =
|
46
|
+
file_mode: int | None = 0o660
|
42
47
|
poll_interval: float = 0.5
|
43
48
|
exit_timeout: float = 10.0
|
44
49
|
|
@@ -80,7 +85,17 @@ class ReplServer:
|
|
80
85
|
|
81
86
|
self._socket = sock.socket(sock.AF_UNIX, sock.SOCK_STREAM)
|
82
87
|
self._socket.settimeout(self._config.poll_interval)
|
83
|
-
|
88
|
+
|
89
|
+
if self._config.file_mode is not None:
|
90
|
+
prev_umask = os.umask(~self._config.file_mode)
|
91
|
+
else:
|
92
|
+
prev_umask = None
|
93
|
+
try:
|
94
|
+
self._socket.bind(self._config.path)
|
95
|
+
finally:
|
96
|
+
if prev_umask is not None:
|
97
|
+
os.umask(prev_umask)
|
98
|
+
|
84
99
|
with contextlib.closing(self._socket):
|
85
100
|
self._socket.listen(1)
|
86
101
|
|
@@ -7,12 +7,6 @@ TODO:
|
|
7
7
|
- https://stackoverflow.com/questions/55386202/how-can-i-use-the-docker-registry-api-to-pull-information-about-a-container-get
|
8
8
|
- https://ops.tips/blog/inspecting-docker-image-without-pull/
|
9
9
|
|
10
|
-
repo=library/nginx
|
11
|
-
token=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${repo}:pull" | jq -r '.token')
|
12
|
-
curl -H "Authorization: Bearer $token" -s "https://registry-1.docker.io/v2/${repo}/tags/list" | jq
|
13
|
-
api="application/vnd.docker.distribution.manifest.v2+json"
|
14
|
-
apil="application/vnd.docker.distribution.manifest.list.v2+json"
|
15
|
-
curl -H "Accept: ${api}" -H "Accept: ${apil}" -H "Authorization: Bearer $token" -s "https://registry-1.docker.io/v2/${repo}/manifests/latest" | jq .
|
16
10
|
""" # noqa
|
17
11
|
import datetime
|
18
12
|
import os
|
@@ -21,6 +15,7 @@ import shlex
|
|
21
15
|
import subprocess
|
22
16
|
import sys
|
23
17
|
import typing as ta
|
18
|
+
import urllib.request
|
24
19
|
|
25
20
|
from . import check
|
26
21
|
from . import dataclasses as dc
|
@@ -191,3 +186,76 @@ DOCKER_HOST_PLATFORM_KEY = 'DOCKER_HOST_PLATFORM'
|
|
191
186
|
|
192
187
|
def get_docker_host_platform() -> str | None:
|
193
188
|
return os.environ.get(DOCKER_HOST_PLATFORM_KEY)
|
189
|
+
|
190
|
+
|
191
|
+
##
|
192
|
+
|
193
|
+
|
194
|
+
@dc.dataclass(frozen=True)
|
195
|
+
class HubRepoInfo:
|
196
|
+
repo: str
|
197
|
+
tags: ta.Mapping[str, ta.Any]
|
198
|
+
latest_manifests: ta.Mapping[str, ta.Any]
|
199
|
+
|
200
|
+
|
201
|
+
def get_hub_repo_info(
|
202
|
+
repo: str,
|
203
|
+
*,
|
204
|
+
auth_url: str = 'https://auth.docker.io/',
|
205
|
+
api_url: str = 'https://registry-1.docker.io/v2/',
|
206
|
+
) -> HubRepoInfo:
|
207
|
+
"""
|
208
|
+
https://stackoverflow.com/a/39376254
|
209
|
+
|
210
|
+
==
|
211
|
+
|
212
|
+
repo=library/nginx
|
213
|
+
token=$(
|
214
|
+
curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${repo}:pull" \
|
215
|
+
| jq -r '.token' \
|
216
|
+
)
|
217
|
+
curl -H "Authorization: Bearer $token" -s "https://registry-1.docker.io/v2/${repo}/tags/list" | jq
|
218
|
+
curl \
|
219
|
+
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
|
220
|
+
-H "Accept: application/vnd.docker.distribution.manifest.list.v2+json" \
|
221
|
+
-H "Authorization: Bearer $token" \
|
222
|
+
-s "https://registry-1.docker.io/v2/${repo}/manifests/latest" \
|
223
|
+
| jq .
|
224
|
+
"""
|
225
|
+
|
226
|
+
auth_url = auth_url.rstrip('/')
|
227
|
+
api_url = api_url.rstrip('/')
|
228
|
+
|
229
|
+
#
|
230
|
+
|
231
|
+
def req_json(url: str, **kwargs: ta.Any) -> ta.Any:
|
232
|
+
with urllib.request.urlopen(urllib.request.Request(url, **kwargs)) as resp: # noqa
|
233
|
+
return json.loads(resp.read().decode('utf-8'))
|
234
|
+
|
235
|
+
#
|
236
|
+
|
237
|
+
token_dct = req_json(f'{auth_url}/token?service=registry.docker.io&scope=repository:{repo}:pull')
|
238
|
+
token = token_dct['token']
|
239
|
+
|
240
|
+
req_hdrs = {'Authorization': f'Bearer {token}'}
|
241
|
+
|
242
|
+
#
|
243
|
+
|
244
|
+
tags_dct = req_json(
|
245
|
+
f'{api_url}/{repo}/tags/list',
|
246
|
+
headers=req_hdrs,
|
247
|
+
)
|
248
|
+
|
249
|
+
latest_mani_dct = req_json(
|
250
|
+
f'{api_url}/{repo}/manifests/latest',
|
251
|
+
headers={
|
252
|
+
**req_hdrs,
|
253
|
+
'Accept': 'application/vnd.docker.distribution.manifest.v2+json',
|
254
|
+
},
|
255
|
+
)
|
256
|
+
|
257
|
+
return HubRepoInfo(
|
258
|
+
repo,
|
259
|
+
tags_dct,
|
260
|
+
latest_mani_dct,
|
261
|
+
)
|
@@ -5,6 +5,7 @@ TODO:
|
|
5
5
|
- goal: perfect rewrites (comments, whitespace)
|
6
6
|
- or at least comments
|
7
7
|
- rename 'objects'? codecs/serde interplay still unresolved
|
8
|
+
- look ma, a monad
|
8
9
|
"""
|
9
10
|
import datetime
|
10
11
|
import types
|
@@ -26,6 +27,9 @@ else:
|
|
26
27
|
T = ta.TypeVar('T')
|
27
28
|
|
28
29
|
|
30
|
+
##
|
31
|
+
|
32
|
+
|
29
33
|
@dc.dataclass(frozen=True)
|
30
34
|
class NodeWrapped(lang.Final, ta.Generic[T]):
|
31
35
|
value: T
|
@@ -124,6 +128,9 @@ class NodeWrappingConstructorMixin:
|
|
124
128
|
return self.__construct_yaml_pairs(node, super().construct_yaml_pairs) # type: ignore # noqa
|
125
129
|
|
126
130
|
|
131
|
+
##
|
132
|
+
|
133
|
+
|
127
134
|
class _cached_class_property: # noqa
|
128
135
|
def __init__(self, fn):
|
129
136
|
super().__init__()
|
@@ -204,6 +211,9 @@ class WrappedLoaders(lang.Namespace):
|
|
204
211
|
return cls.CUnsafe(*args, **kwargs)
|
205
212
|
|
206
213
|
|
214
|
+
##
|
215
|
+
|
216
|
+
|
207
217
|
def load(stream, Loader): # noqa
|
208
218
|
with lang.disposing(Loader(stream)) as loader:
|
209
219
|
return loader.get_single_data()
|
@@ -0,0 +1,31 @@
|
|
1
|
+
from .items import ( # noqa
|
2
|
+
Attrs,
|
3
|
+
Cell,
|
4
|
+
Edge,
|
5
|
+
Graph,
|
6
|
+
Id,
|
7
|
+
Item,
|
8
|
+
Node,
|
9
|
+
Raw,
|
10
|
+
RawStmt,
|
11
|
+
Row,
|
12
|
+
Stmt,
|
13
|
+
Table,
|
14
|
+
Text,
|
15
|
+
)
|
16
|
+
|
17
|
+
from .make import ( # noqa
|
18
|
+
make_simple,
|
19
|
+
)
|
20
|
+
|
21
|
+
from .rendering import ( # noqa
|
22
|
+
Renderer,
|
23
|
+
open_dot,
|
24
|
+
render,
|
25
|
+
)
|
26
|
+
|
27
|
+
from .utils import ( # noqa
|
28
|
+
Color,
|
29
|
+
escape,
|
30
|
+
gen_rainbow,
|
31
|
+
)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
from ... import lang
|
4
|
+
from .items import Edge
|
5
|
+
from .items import Graph
|
6
|
+
from .items import Node
|
7
|
+
|
8
|
+
|
9
|
+
T = ta.TypeVar('T')
|
10
|
+
|
11
|
+
|
12
|
+
def make_simple(graph: ta.Mapping[T, ta.Iterable[T]]) -> Graph:
|
13
|
+
return Graph([
|
14
|
+
*[Node(n) for n in {*graph, *lang.flatten(graph.values())}],
|
15
|
+
*[Edge(k, v) for k, vs in graph.items() for v in vs],
|
16
|
+
])
|
@@ -120,6 +120,7 @@ def open_dot(
|
|
120
120
|
*,
|
121
121
|
timeout_s: float = 1.,
|
122
122
|
sleep_s: float = 0.,
|
123
|
+
delete: bool = False,
|
123
124
|
) -> None:
|
124
125
|
stdout, _ = subprocess.Popen(
|
125
126
|
['dot', '-Tpdf'],
|
@@ -132,16 +133,16 @@ def open_dot(
|
|
132
133
|
|
133
134
|
with tempfile.NamedTemporaryFile(
|
134
135
|
suffix='.pdf',
|
135
|
-
delete=
|
136
|
+
delete=delete,
|
136
137
|
) as pdf:
|
137
138
|
pdf.file.write(stdout)
|
138
139
|
pdf.file.flush()
|
139
140
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
141
|
+
_, _ = subprocess.Popen(
|
142
|
+
['open', pdf.name],
|
143
|
+
).communicate(
|
144
|
+
timeout=timeout_s,
|
145
|
+
)
|
145
146
|
|
146
|
-
|
147
|
-
|
147
|
+
if sleep_s > 0.:
|
148
|
+
time.sleep(sleep_s)
|
@@ -29,6 +29,7 @@ import typing as ta
|
|
29
29
|
import urllib.parse
|
30
30
|
|
31
31
|
from .. import collections as col
|
32
|
+
from .. import lang
|
32
33
|
from .dates import http_date
|
33
34
|
|
34
35
|
|
@@ -140,7 +141,7 @@ def dump_cookie(
|
|
140
141
|
if not isinstance(expires, str):
|
141
142
|
expires = http_date(expires)
|
142
143
|
elif max_age is not None and sync_expires:
|
143
|
-
expires = http_date(
|
144
|
+
expires = http_date(lang.utcnow().timestamp() + max_age)
|
144
145
|
|
145
146
|
if samesite is not None:
|
146
147
|
samesite = samesite.title()
|
@@ -32,14 +32,14 @@ def _check_set_multi_key(mk: Key) -> bool:
|
|
32
32
|
@dc.dataclass(frozen=True)
|
33
33
|
@dc.extra_params(cache_hash=True)
|
34
34
|
class SetBinding(Element, lang.Final):
|
35
|
-
multi_key: Key = dc.xfield(
|
35
|
+
multi_key: Key = dc.xfield(validate=_check_set_multi_key)
|
36
36
|
dst: Key = dc.xfield(coerce=check.of_isinstance(Key))
|
37
37
|
|
38
38
|
|
39
39
|
@dc.dataclass(frozen=True)
|
40
40
|
@dc.extra_params(cache_hash=True)
|
41
41
|
class SetProvider(Provider):
|
42
|
-
multi_key: Key = dc.xfield(
|
42
|
+
multi_key: Key = dc.xfield(validate=_check_set_multi_key)
|
43
43
|
|
44
44
|
|
45
45
|
##
|
@@ -52,7 +52,7 @@ def _check_map_multi_key(mk: Key) -> bool:
|
|
52
52
|
@dc.dataclass(frozen=True)
|
53
53
|
@dc.extra_params(cache_hash=True)
|
54
54
|
class MapBinding(Element, lang.Final):
|
55
|
-
multi_key: Key = dc.xfield(
|
55
|
+
multi_key: Key = dc.xfield(validate=_check_map_multi_key)
|
56
56
|
map_key: ta.Any = dc.xfield()
|
57
57
|
dst: Key = dc.xfield(coerce=check.of_isinstance(Key))
|
58
58
|
|
@@ -60,7 +60,7 @@ class MapBinding(Element, lang.Final):
|
|
60
60
|
@dc.dataclass(frozen=True)
|
61
61
|
@dc.extra_params(cache_hash=True)
|
62
62
|
class MapProvider(Provider):
|
63
|
-
multi_key: Key = dc.xfield(
|
63
|
+
multi_key: Key = dc.xfield(validate=_check_map_multi_key)
|
64
64
|
|
65
65
|
|
66
66
|
##
|