omlish 0.0.0.dev423__py3-none-any.whl → 0.0.0.dev484__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/{.manifests.json → .omlish-manifests.json} +12 -0
- omlish/__about__.py +21 -18
- omlish/argparse/all.py +17 -9
- omlish/argparse/cli.py +16 -3
- omlish/argparse/utils.py +21 -0
- omlish/asyncs/all.py +0 -13
- omlish/asyncs/asyncio/rlock.py +110 -0
- omlish/asyncs/asyncio/subprocesses.py +2 -2
- omlish/asyncs/asyncio/sync.py +43 -0
- omlish/asyncs/asyncio/utils.py +2 -0
- omlish/asyncs/ioproxy/proxy.py +1 -1
- 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/c3.py +4 -1
- 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 +3 -2
- 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/__init__.py +0 -11
- omlish/concurrent/all.py +18 -0
- omlish/concurrent/futures.py +25 -0
- omlish/concurrent/threadlets.py +1 -1
- omlish/configs/processing/flattening.py +1 -1
- omlish/configs/processing/merging.py +8 -6
- omlish/configs/types.py +1 -1
- omlish/daemons/__init__.py +70 -0
- omlish/daemons/daemon.py +2 -2
- omlish/daemons/launching.py +2 -2
- omlish/daemons/reparent.py +2 -3
- omlish/daemons/spawning.py +2 -3
- omlish/dataclasses/__init__.py +5 -5
- omlish/dataclasses/errors.py +1 -1
- omlish/dataclasses/impl/api/classes/decorator.py +3 -0
- omlish/dataclasses/impl/api/classes/make.py +4 -1
- omlish/dataclasses/impl/concerns/doc.py +1 -1
- omlish/dataclasses/impl/concerns/repr.py +15 -2
- omlish/dataclasses/impl/configs.py +97 -36
- 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/processor.py +105 -24
- omlish/dataclasses/impl/processing/base.py +8 -0
- omlish/dataclasses/impl/processing/driving.py +8 -8
- omlish/dataclasses/specs.py +34 -2
- omlish/dataclasses/tools/as_.py +0 -12
- omlish/dataclasses/tools/modifiers.py +5 -0
- omlish/dataclasses/tools/static.py +1 -1
- omlish/diag/_pycharm/runhack.py +1 -1
- 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/procfs.py +4 -4
- omlish/diag/pycharm.py +16 -2
- omlish/diag/pydevd.py +58 -40
- omlish/diag/replserver/console.py +3 -3
- omlish/diag/replserver/server.py +2 -2
- omlish/dispatch/__init__.py +18 -12
- omlish/dispatch/methods.py +50 -140
- omlish/dom/rendering.py +1 -1
- omlish/formats/dotenv.py +8 -8
- omlish/formats/json/stream/__init__.py +18 -3
- omlish/formats/json/stream/building.py +2 -2
- omlish/formats/json/stream/lexing.py +401 -67
- omlish/formats/json/stream/parsing.py +32 -10
- omlish/formats/json/stream/rendering.py +6 -6
- omlish/formats/json/stream/utils.py +132 -30
- omlish/formats/json5/literals.py +7 -4
- omlish/formats/json5/parsing.py +33 -79
- omlish/formats/json5/stream.py +77 -0
- omlish/formats/logfmt.py +8 -2
- omlish/funcs/genmachine.py +2 -2
- omlish/funcs/guard.py +225 -0
- omlish/graphs/dot/rendering.py +1 -1
- omlish/http/all.py +122 -53
- omlish/http/asgi.py +2 -2
- omlish/http/clients/__init__.py +0 -34
- omlish/http/clients/asyncs.py +153 -0
- omlish/http/clients/base.py +63 -122
- omlish/http/clients/coro/sync.py +171 -0
- omlish/http/clients/default.py +209 -30
- omlish/http/clients/executor.py +56 -0
- omlish/http/clients/httpx.py +78 -13
- omlish/http/clients/middleware.py +181 -0
- omlish/http/clients/sync.py +151 -0
- omlish/http/clients/syncasync.py +49 -0
- omlish/http/clients/urllib.py +8 -5
- omlish/http/coro/client/{client.py → connection.py} +43 -37
- omlish/http/coro/client/headers.py +5 -5
- omlish/http/coro/client/response.py +37 -38
- omlish/http/coro/client/status.py +4 -4
- omlish/http/coro/{client/io.py → io.py} +19 -2
- omlish/http/coro/server/fdio.py +10 -9
- omlish/http/coro/server/server.py +14 -41
- omlish/http/coro/server/sockets.py +7 -6
- 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/handlers.py +3 -2
- omlish/http/headers.py +69 -35
- omlish/http/sse.py +1 -1
- omlish/http/urls.py +67 -0
- omlish/inject/__init__.py +173 -126
- omlish/inject/_dataclasses.py +4986 -0
- omlish/inject/binder.py +10 -49
- omlish/inject/elements.py +27 -0
- omlish/inject/{utils.py → helpers/constfn.py} +3 -3
- omlish/inject/{tags.py → helpers/id.py} +2 -2
- omlish/inject/helpers/multis.py +143 -0
- omlish/inject/helpers/wrappers.py +54 -0
- omlish/inject/impl/elements.py +52 -22
- omlish/inject/impl/injector.py +76 -49
- omlish/inject/impl/inspect.py +11 -1
- omlish/inject/impl/maysync.py +43 -0
- omlish/inject/impl/multis.py +10 -7
- omlish/inject/impl/privates.py +8 -8
- omlish/inject/impl/providers.py +23 -34
- omlish/inject/impl/providersmap.py +43 -0
- omlish/inject/impl/proxy.py +0 -2
- omlish/inject/impl/scopes.py +19 -23
- omlish/inject/impl/sync.py +41 -0
- omlish/inject/injector.py +37 -8
- omlish/inject/inspect.py +35 -0
- omlish/inject/listeners.py +4 -4
- omlish/inject/managed.py +54 -18
- omlish/inject/maysync.py +27 -0
- omlish/inject/multis.py +8 -0
- omlish/inject/overrides.py +3 -3
- omlish/inject/privates.py +6 -0
- omlish/inject/providers.py +8 -1
- omlish/inject/scopes.py +40 -12
- omlish/inject/sync.py +49 -0
- omlish/io/buffers.py +119 -1
- omlish/io/readers.py +29 -0
- omlish/iterators/__init__.py +28 -20
- omlish/iterators/transforms.py +204 -0
- omlish/lang/__init__.py +240 -129
- omlish/lang/_asyncs.cc +186 -0
- omlish/lang/asyncs.py +67 -43
- omlish/lang/{attrs.py → attrstorage.py} +15 -15
- omlish/lang/cached/property.py +2 -2
- omlish/lang/casing.py +11 -0
- omlish/lang/classes/bindable.py +2 -3
- omlish/lang/classes/restrict.py +8 -0
- omlish/lang/classes/simple.py +26 -4
- omlish/lang/collections.py +1 -1
- omlish/lang/contextmanagers.py +59 -9
- omlish/lang/functions.py +31 -33
- omlish/lang/imports/_capture.cc +103 -0
- omlish/lang/imports/capture.py +902 -0
- omlish/lang/imports/lazy.py +0 -25
- omlish/lang/imports/proxy.py +559 -0
- omlish/lang/iterables.py +2 -2
- omlish/lang/lazyglobals.py +49 -14
- omlish/lang/maybes.py +2 -1
- omlish/lang/maysync.py +2 -2
- omlish/lang/params.py +17 -0
- omlish/lang/recursion.py +0 -1
- omlish/lang/resources.py +1 -1
- omlish/lang/sequences.py +124 -0
- omlish/lifecycles/contextmanagers.py +1 -2
- omlish/lifecycles/controller.py +1 -2
- omlish/lite/abstract.py +54 -24
- omlish/lite/asyncs.py +146 -0
- omlish/lite/attrops.py +415 -0
- omlish/lite/cached.py +57 -1
- omlish/lite/contextmanagers.py +4 -4
- omlish/lite/dataclasses.py +55 -0
- omlish/lite/inject.py +5 -4
- omlish/lite/marshal.py +1 -0
- omlish/lite/maybes.py +10 -2
- omlish/lite/maysync.py +22 -5
- omlish/lite/pycharm.py +1 -1
- omlish/lite/strings.py +0 -7
- omlish/lite/timing.py +6 -3
- omlish/lite/typing.py +6 -0
- omlish/logs/_amalg.py +8 -0
- omlish/logs/all.py +59 -31
- omlish/logs/base.py +204 -0
- omlish/logs/contexts.py +171 -0
- omlish/logs/formatters.py +13 -0
- omlish/logs/infos.py +377 -0
- omlish/logs/levels.py +97 -0
- omlish/logs/modules.py +13 -0
- omlish/logs/protocols.py +32 -0
- omlish/logs/standard.py +20 -15
- omlish/logs/std/configs.py +29 -0
- omlish/logs/{filters.py → std/filters.py} +1 -1
- omlish/logs/std/formatters.py +25 -0
- omlish/logs/std/handlers.py +19 -0
- omlish/logs/{json.py → std/json.py} +2 -2
- omlish/logs/std/loggers.py +48 -0
- omlish/logs/{proxy.py → std/proxy.py} +3 -3
- omlish/logs/std/records.py +671 -0
- omlish/logs/typed/bindings.py +108 -37
- omlish/logs/typed/types.py +17 -1
- omlish/logs/typed/values.py +2 -2
- omlish/logs/utils.py +60 -4
- omlish/logs/warnings.py +8 -0
- omlish/manifests/loading.py +8 -1
- omlish/marshal/__init__.py +54 -22
- 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/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/math/fixed.py +2 -2
- omlish/metadata.py +23 -1
- omlish/os/atomics.py +2 -2
- omlish/os/forkhooks.py +4 -0
- omlish/os/journald.py +3 -3
- omlish/os/pidfiles/pinning.py +2 -2
- omlish/reflect/ops.py +9 -0
- omlish/reflect/types.py +44 -8
- omlish/secrets/marshal.py +1 -1
- omlish/secrets/secrets.py +6 -3
- omlish/sockets/addresses.py +1 -1
- omlish/sockets/server/handlers.py +2 -2
- omlish/sockets/server/server.py +4 -3
- omlish/sockets/server/ssl.py +2 -2
- 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 +15 -20
- omlish/sql/{tabledefs/alchemy.py → alchemy/tabledefs.py} +2 -2
- omlish/sql/queries/_marshal.py +3 -3
- omlish/sql/queries/params.py +1 -1
- omlish/sql/queries/rendering.py +1 -1
- omlish/sql/tabledefs/_marshal.py +1 -1
- omlish/subprocesses/all.py +135 -0
- omlish/subprocesses/base.py +8 -3
- omlish/subprocesses/editor.py +1 -1
- omlish/sync.py +181 -20
- 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/skips.py +2 -5
- 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 +86 -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/__init__.py +1 -1
- omlish/typedvalues/marshal.py +85 -59
- omlish/typedvalues/values.py +2 -1
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/METADATA +36 -38
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/RECORD +323 -385
- omlish/asyncs/bluelet/LICENSE +0 -6
- omlish/asyncs/bluelet/all.py +0 -67
- omlish/asyncs/bluelet/api.py +0 -23
- omlish/asyncs/bluelet/core.py +0 -178
- omlish/asyncs/bluelet/events.py +0 -79
- omlish/asyncs/bluelet/files.py +0 -80
- omlish/asyncs/bluelet/runner.py +0 -417
- omlish/asyncs/bluelet/sockets.py +0 -216
- omlish/asyncs/bridge.py +0 -359
- omlish/asyncs/utils.py +0 -18
- omlish/dataclasses/impl/generation/mangling.py +0 -18
- omlish/defs.py +0 -216
- omlish/dispatch/_dispatch2.py +0 -69
- omlish/dispatch/_dispatch3.py +0 -108
- omlish/dynamic.py +0 -219
- omlish/formats/json/Json.g4 +0 -77
- omlish/formats/json/_antlr/JsonLexer.py +0 -109
- omlish/formats/json/_antlr/JsonListener.py +0 -61
- omlish/formats/json/_antlr/JsonParser.py +0 -457
- omlish/formats/json/_antlr/JsonVisitor.py +0 -42
- omlish/formats/json5/Json5.g4 +0 -168
- omlish/formats/json5/_antlr/Json5Lexer.py +0 -354
- omlish/formats/json5/_antlr/Json5Listener.py +0 -79
- omlish/formats/json5/_antlr/Json5Parser.py +0 -617
- omlish/formats/json5/_antlr/Json5Visitor.py +0 -52
- omlish/funcs/match.py +0 -227
- omlish/io/trampoline.py +0 -289
- omlish/lang/imports/proxyinit.py +0 -665
- omlish/lite/logs.py +0 -4
- omlish/lite/reprs.py +0 -85
- omlish/logs/abc.py +0 -319
- omlish/logs/callers.py +0 -67
- omlish/logs/color.py +0 -27
- omlish/logs/configs.py +0 -29
- omlish/logs/handlers.py +0 -17
- omlish/logs/protocol.py +0 -218
- omlish/logs/timing.py +0 -58
- omlish/marshal/factories/match.py +0 -34
- omlish/marshal/factories/simple.py +0 -28
- omlish/specs/irc/messages/base.py +0 -49
- omlish/specs/irc/messages/formats.py +0 -92
- omlish/specs/irc/messages/messages.py +0 -774
- omlish/specs/irc/messages/parsing.py +0 -98
- omlish/specs/irc/numerics/formats.py +0 -97
- omlish/specs/irc/numerics/numerics.py +0 -865
- omlish/specs/irc/numerics/types.py +0 -59
- omlish/specs/irc/protocol/LICENSE +0 -11
- omlish/specs/irc/protocol/__init__.py +0 -61
- omlish/specs/irc/protocol/consts.py +0 -6
- omlish/specs/irc/protocol/errors.py +0 -30
- omlish/specs/irc/protocol/message.py +0 -21
- omlish/specs/irc/protocol/nuh.py +0 -55
- omlish/specs/irc/protocol/parsing.py +0 -158
- omlish/specs/irc/protocol/rendering.py +0 -153
- omlish/specs/irc/protocol/tags.py +0 -102
- omlish/specs/irc/protocol/utils.py +0 -30
- omlish/specs/proto/Protobuf3.g4 +0 -396
- omlish/specs/proto/__init__.py +0 -0
- omlish/specs/proto/_antlr/Protobuf3Lexer.py +0 -340
- omlish/specs/proto/_antlr/Protobuf3Listener.py +0 -448
- omlish/specs/proto/_antlr/Protobuf3Parser.py +0 -3909
- omlish/specs/proto/_antlr/Protobuf3Visitor.py +0 -257
- omlish/specs/proto/_antlr/__init__.py +0 -0
- omlish/specs/proto/nodes.py +0 -54
- omlish/specs/proto/parsing.py +0 -97
- omlish/sql/parsing/Minisql.g4 +0 -292
- omlish/sql/parsing/__init__.py +0 -0
- omlish/sql/parsing/_antlr/MinisqlLexer.py +0 -322
- omlish/sql/parsing/_antlr/MinisqlListener.py +0 -511
- omlish/sql/parsing/_antlr/MinisqlParser.py +0 -3763
- omlish/sql/parsing/_antlr/MinisqlVisitor.py +0 -292
- omlish/sql/parsing/_antlr/__init__.py +0 -0
- omlish/sql/parsing/parsing.py +0 -119
- omlish/text/antlr/__init__.py +0 -3
- omlish/text/antlr/_runtime/BufferedTokenStream.py +0 -305
- omlish/text/antlr/_runtime/CommonTokenFactory.py +0 -64
- omlish/text/antlr/_runtime/CommonTokenStream.py +0 -90
- omlish/text/antlr/_runtime/FileStream.py +0 -30
- omlish/text/antlr/_runtime/InputStream.py +0 -90
- omlish/text/antlr/_runtime/IntervalSet.py +0 -183
- omlish/text/antlr/_runtime/LICENSE.txt +0 -28
- omlish/text/antlr/_runtime/LL1Analyzer.py +0 -176
- omlish/text/antlr/_runtime/Lexer.py +0 -332
- omlish/text/antlr/_runtime/ListTokenSource.py +0 -147
- omlish/text/antlr/_runtime/Parser.py +0 -583
- omlish/text/antlr/_runtime/ParserInterpreter.py +0 -173
- omlish/text/antlr/_runtime/ParserRuleContext.py +0 -189
- omlish/text/antlr/_runtime/PredictionContext.py +0 -632
- omlish/text/antlr/_runtime/Recognizer.py +0 -150
- omlish/text/antlr/_runtime/RuleContext.py +0 -230
- omlish/text/antlr/_runtime/StdinStream.py +0 -14
- omlish/text/antlr/_runtime/Token.py +0 -158
- omlish/text/antlr/_runtime/TokenStreamRewriter.py +0 -258
- omlish/text/antlr/_runtime/Utils.py +0 -36
- omlish/text/antlr/_runtime/__init__.py +0 -2
- omlish/text/antlr/_runtime/_all.py +0 -24
- omlish/text/antlr/_runtime/_pygrun.py +0 -174
- omlish/text/antlr/_runtime/atn/ATN.py +0 -135
- omlish/text/antlr/_runtime/atn/ATNConfig.py +0 -162
- omlish/text/antlr/_runtime/atn/ATNConfigSet.py +0 -215
- omlish/text/antlr/_runtime/atn/ATNDeserializationOptions.py +0 -27
- omlish/text/antlr/_runtime/atn/ATNDeserializer.py +0 -449
- omlish/text/antlr/_runtime/atn/ATNSimulator.py +0 -50
- omlish/text/antlr/_runtime/atn/ATNState.py +0 -267
- omlish/text/antlr/_runtime/atn/ATNType.py +0 -20
- omlish/text/antlr/_runtime/atn/LexerATNSimulator.py +0 -573
- omlish/text/antlr/_runtime/atn/LexerAction.py +0 -301
- omlish/text/antlr/_runtime/atn/LexerActionExecutor.py +0 -146
- omlish/text/antlr/_runtime/atn/ParserATNSimulator.py +0 -1664
- omlish/text/antlr/_runtime/atn/PredictionMode.py +0 -502
- omlish/text/antlr/_runtime/atn/SemanticContext.py +0 -333
- omlish/text/antlr/_runtime/atn/Transition.py +0 -271
- omlish/text/antlr/_runtime/atn/__init__.py +0 -4
- omlish/text/antlr/_runtime/dfa/DFA.py +0 -136
- omlish/text/antlr/_runtime/dfa/DFASerializer.py +0 -76
- omlish/text/antlr/_runtime/dfa/DFAState.py +0 -129
- omlish/text/antlr/_runtime/dfa/__init__.py +0 -4
- omlish/text/antlr/_runtime/error/DiagnosticErrorListener.py +0 -111
- omlish/text/antlr/_runtime/error/ErrorListener.py +0 -75
- omlish/text/antlr/_runtime/error/ErrorStrategy.py +0 -712
- omlish/text/antlr/_runtime/error/Errors.py +0 -176
- omlish/text/antlr/_runtime/error/__init__.py +0 -4
- omlish/text/antlr/_runtime/tree/Chunk.py +0 -33
- omlish/text/antlr/_runtime/tree/ParseTreeMatch.py +0 -121
- omlish/text/antlr/_runtime/tree/ParseTreePattern.py +0 -75
- omlish/text/antlr/_runtime/tree/ParseTreePatternMatcher.py +0 -377
- omlish/text/antlr/_runtime/tree/RuleTagToken.py +0 -53
- omlish/text/antlr/_runtime/tree/TokenTagToken.py +0 -50
- omlish/text/antlr/_runtime/tree/Tree.py +0 -194
- omlish/text/antlr/_runtime/tree/Trees.py +0 -114
- omlish/text/antlr/_runtime/tree/__init__.py +0 -2
- omlish/text/antlr/_runtime/xpath/XPath.py +0 -278
- omlish/text/antlr/_runtime/xpath/XPathLexer.py +0 -98
- omlish/text/antlr/_runtime/xpath/__init__.py +0 -4
- omlish/text/antlr/delimit.py +0 -109
- omlish/text/antlr/dot.py +0 -41
- omlish/text/antlr/errors.py +0 -14
- omlish/text/antlr/input.py +0 -96
- omlish/text/antlr/parsing.py +0 -54
- omlish/text/antlr/runtime.py +0 -102
- omlish/text/antlr/utils.py +0 -38
- /omlish/{asyncs/bluelet → cexts}/__init__.py +0 -0
- /omlish/{formats/json/_antlr → diag/cmds}/__init__.py +0 -0
- /omlish/{formats/json5/_antlr → http/clients/coro}/__init__.py +0 -0
- /omlish/{specs/irc → inject/helpers}/__init__.py +0 -0
- /omlish/{specs/irc/messages → logs/std}/__init__.py +0 -0
- /omlish/logs/{noisy.py → std/noisy.py} +0 -0
- /omlish/{specs/irc/numerics → marshal/composite/unions}/__init__.py +0 -0
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/top_level.txt +0 -0
omlish/bootstrap/sys.py
CHANGED
|
@@ -2,14 +2,10 @@
|
|
|
2
2
|
import contextlib
|
|
3
3
|
import dataclasses as dc
|
|
4
4
|
import enum
|
|
5
|
-
import faulthandler
|
|
6
5
|
import gc
|
|
7
6
|
import importlib
|
|
8
7
|
import logging
|
|
9
8
|
import os
|
|
10
|
-
import pwd
|
|
11
|
-
import resource
|
|
12
|
-
import signal
|
|
13
9
|
import sys
|
|
14
10
|
import typing as ta
|
|
15
11
|
|
|
@@ -19,18 +15,17 @@ from .base import ContextBootstrap
|
|
|
19
15
|
from .base import SimpleBootstrap
|
|
20
16
|
|
|
21
17
|
|
|
22
|
-
|
|
18
|
+
with lang.auto_proxy_import(globals()):
|
|
19
|
+
import faulthandler
|
|
20
|
+
import pwd
|
|
21
|
+
import resource
|
|
22
|
+
import signal
|
|
23
|
+
|
|
23
24
|
from .. import libc
|
|
24
25
|
from ..formats import dotenv
|
|
25
26
|
from ..logs import all as logs
|
|
26
27
|
from ..os.pidfiles import pidfile
|
|
27
28
|
|
|
28
|
-
else:
|
|
29
|
-
libc = lang.proxy_import('..libc', __package__)
|
|
30
|
-
logs = lang.proxy_import('..logs', __package__)
|
|
31
|
-
dotenv = lang.proxy_import('..formats.dotenv', __package__)
|
|
32
|
-
pidfile = lang.proxy_import('..os.pidfiles.pidfile', __package__)
|
|
33
|
-
|
|
34
29
|
|
|
35
30
|
##
|
|
36
31
|
|
|
@@ -184,14 +179,16 @@ class FaulthandlerBootstrap(ContextBootstrap['FaulthandlerBootstrap.Config']):
|
|
|
184
179
|
##
|
|
185
180
|
|
|
186
181
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
182
|
+
@lang.cached_function
|
|
183
|
+
def signals_by_name() -> ta.Mapping[str, int]:
|
|
184
|
+
return {
|
|
185
|
+
a[len('SIG'):]: v # noqa
|
|
186
|
+
for a in dir(signal)
|
|
187
|
+
if a.startswith('SIG')
|
|
188
|
+
and not a.startswith('SIG_')
|
|
189
|
+
and a == a.upper()
|
|
190
|
+
and isinstance((v := getattr(signal, a)), int)
|
|
191
|
+
}
|
|
195
192
|
|
|
196
193
|
|
|
197
194
|
class PrctlBootstrap(SimpleBootstrap['PrctlBootstrap.Config']):
|
|
@@ -208,20 +205,22 @@ class PrctlBootstrap(SimpleBootstrap['PrctlBootstrap.Config']):
|
|
|
208
205
|
if isinstance(self._config.deathsig, int):
|
|
209
206
|
sig = self._config.deathsig
|
|
210
207
|
else:
|
|
211
|
-
sig =
|
|
208
|
+
sig = signals_by_name()[self._config.deathsig.upper()]
|
|
212
209
|
libc.prctl(libc.PR_SET_PDEATHSIG, sig, 0, 0, 0, 0)
|
|
213
210
|
|
|
214
211
|
|
|
215
212
|
##
|
|
216
213
|
|
|
217
214
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
215
|
+
@lang.cached_function
|
|
216
|
+
def rlimits_by_name() -> ta.Mapping[str, int]:
|
|
217
|
+
return {
|
|
218
|
+
a[len('RLIMIT_'):]: v # noqa
|
|
219
|
+
for a in dir(resource)
|
|
220
|
+
if a.startswith('RLIMIT_')
|
|
221
|
+
and a == a.upper()
|
|
222
|
+
and isinstance((v := getattr(resource, a)), int)
|
|
223
|
+
}
|
|
225
224
|
|
|
226
225
|
|
|
227
226
|
class RlimitBootstrap(ContextBootstrap['RlimitBootstrap.Config']):
|
|
@@ -240,7 +239,7 @@ class RlimitBootstrap(ContextBootstrap['RlimitBootstrap.Config']):
|
|
|
240
239
|
|
|
241
240
|
prev = {}
|
|
242
241
|
for k, (s, h) in self._config.limits.items():
|
|
243
|
-
i =
|
|
242
|
+
i = rlimits_by_name()[k.upper()]
|
|
244
243
|
prev[i] = resource.getrlimit(i)
|
|
245
244
|
resource.setrlimit(i, (or_infin(s), or_infin(h)))
|
|
246
245
|
|
omlish/c3.py
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
#
|
|
34
34
|
# 8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this
|
|
35
35
|
# License Agreement.
|
|
36
|
+
import abc
|
|
36
37
|
import functools
|
|
37
38
|
import operator
|
|
38
39
|
import typing as ta
|
|
@@ -75,7 +76,9 @@ def merge(seqs: ta.MutableSequence[list[T]]) -> list[T]:
|
|
|
75
76
|
|
|
76
77
|
|
|
77
78
|
def _default_is_abstract(obj: ta.Any) -> bool:
|
|
78
|
-
|
|
79
|
+
# .lite.abstracts.Abstract has '__abstractmethods__' but is not an ABCMeta, and thus for the purposes of c3 mro are
|
|
80
|
+
# not considered 'abstract'. What 'abstract' means in this context is 'can have virtual subclasses'.
|
|
81
|
+
return hasattr(obj, '__abstractmethods__') and isinstance(obj, abc.ABCMeta)
|
|
79
82
|
|
|
80
83
|
|
|
81
84
|
def mro(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#pragma once
|
omlish/collections/__init__.py
CHANGED
|
@@ -6,12 +6,21 @@ from .. import lang as _lang
|
|
|
6
6
|
with _lang.auto_proxy_init(globals()):
|
|
7
7
|
##
|
|
8
8
|
|
|
9
|
+
from .attrregistry import ( # noqa
|
|
10
|
+
AttrRegistry,
|
|
11
|
+
|
|
12
|
+
AttrRegistryCache,
|
|
13
|
+
SimpleAttrRegistryCache,
|
|
14
|
+
)
|
|
15
|
+
|
|
9
16
|
from .bimap import ( # noqa
|
|
10
17
|
BiMap,
|
|
11
18
|
|
|
12
19
|
make_bi_map,
|
|
13
20
|
)
|
|
14
21
|
|
|
22
|
+
from . import cache # noqa
|
|
23
|
+
|
|
15
24
|
from .coerce import ( # noqa
|
|
16
25
|
abs_set,
|
|
17
26
|
abs_set_of,
|
|
@@ -64,9 +73,10 @@ with _lang.auto_proxy_init(globals()):
|
|
|
64
73
|
from . import kv # noqa
|
|
65
74
|
|
|
66
75
|
from .mappings import ( # noqa
|
|
76
|
+
DynamicTypeMap,
|
|
67
77
|
MissingDict,
|
|
68
78
|
TypeMap,
|
|
69
|
-
|
|
79
|
+
dict_factory,
|
|
70
80
|
guarded_map_update,
|
|
71
81
|
multikey_dict,
|
|
72
82
|
)
|
|
@@ -145,6 +155,8 @@ with _lang.auto_proxy_init(globals()):
|
|
|
145
155
|
key_cmp,
|
|
146
156
|
make_map,
|
|
147
157
|
make_map_by,
|
|
158
|
+
map_keys,
|
|
159
|
+
map_values,
|
|
148
160
|
multi_map,
|
|
149
161
|
multi_map_by,
|
|
150
162
|
partition,
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- lock?
|
|
4
|
+
"""
|
|
5
|
+
import dataclasses as dc
|
|
6
|
+
import typing as ta
|
|
7
|
+
import weakref
|
|
8
|
+
|
|
9
|
+
from .. import check
|
|
10
|
+
from .. import lang
|
|
11
|
+
from .mappings import dict_factory
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
T = ta.TypeVar('T')
|
|
15
|
+
K = ta.TypeVar('K')
|
|
16
|
+
V = ta.TypeVar('V')
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class AttrRegistry(ta.Generic[K, V]):
|
|
23
|
+
"""
|
|
24
|
+
MRO-honoring class member registry. There are many ways to do this, and this one is attr name based: a class is
|
|
25
|
+
considered to have objects registered to it based on whether or not they are accessible by a non-shadowed,
|
|
26
|
+
MRO-resolved named attribute on that class.
|
|
27
|
+
|
|
28
|
+
Care must be taken when overriding registered objects from superclasses in subclasses - shadowing the attribute name
|
|
29
|
+
of the superclass member will not automatically register the new member with the same name to the registry - it must
|
|
30
|
+
be explicitly registered itself. This is a feature, allowing for selective de-registration of objects in subclasses
|
|
31
|
+
via name shadowing.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
*,
|
|
37
|
+
requires_override: bool = False,
|
|
38
|
+
is_override: ta.Callable[[ta.Any], bool] | None = None,
|
|
39
|
+
forbid_duplicates: bool = False,
|
|
40
|
+
identity: bool = False,
|
|
41
|
+
weak: bool = False,
|
|
42
|
+
) -> None:
|
|
43
|
+
super().__init__()
|
|
44
|
+
|
|
45
|
+
self._requires_override = requires_override
|
|
46
|
+
self._is_override = is_override
|
|
47
|
+
self._forbid_duplicates = forbid_duplicates
|
|
48
|
+
self._identity = identity
|
|
49
|
+
self._weak = weak
|
|
50
|
+
|
|
51
|
+
self._objs: ta.MutableMapping[K, V] = dict_factory(identity=identity, weak=weak)()
|
|
52
|
+
self._invalidate_callbacks: list[ta.Callable[[], None]] = []
|
|
53
|
+
|
|
54
|
+
def add_invalidate_callback(self, callback: ta.Callable[[], None]) -> None:
|
|
55
|
+
self._invalidate_callbacks.append(callback)
|
|
56
|
+
|
|
57
|
+
@ta.overload
|
|
58
|
+
def register(self, obj: K, val: V) -> None:
|
|
59
|
+
...
|
|
60
|
+
|
|
61
|
+
@ta.overload
|
|
62
|
+
def register(self, val: V) -> ta.Callable[[T], T]:
|
|
63
|
+
...
|
|
64
|
+
|
|
65
|
+
def register(self, *args):
|
|
66
|
+
def inner(obj, val):
|
|
67
|
+
check.not_in(obj, self._objs)
|
|
68
|
+
|
|
69
|
+
self._objs[obj] = val
|
|
70
|
+
|
|
71
|
+
for iv in self._invalidate_callbacks:
|
|
72
|
+
iv()
|
|
73
|
+
|
|
74
|
+
return obj
|
|
75
|
+
|
|
76
|
+
if len(args) == 1:
|
|
77
|
+
return lambda obj: inner(obj, args[0])
|
|
78
|
+
elif len(args) == 2:
|
|
79
|
+
inner = inner(*args)
|
|
80
|
+
return None
|
|
81
|
+
else:
|
|
82
|
+
raise TypeError(args)
|
|
83
|
+
|
|
84
|
+
def _lookup(self, obj: ta.Any) -> lang.Maybe[V]:
|
|
85
|
+
if not self._identity:
|
|
86
|
+
try:
|
|
87
|
+
hash(obj)
|
|
88
|
+
except TypeError:
|
|
89
|
+
return lang.empty()
|
|
90
|
+
|
|
91
|
+
try:
|
|
92
|
+
val = self._objs[obj]
|
|
93
|
+
except KeyError:
|
|
94
|
+
return lang.empty()
|
|
95
|
+
else:
|
|
96
|
+
return lang.just(val)
|
|
97
|
+
|
|
98
|
+
@dc.dataclass()
|
|
99
|
+
class DuplicatesForbiddenError(Exception):
|
|
100
|
+
owner_cls: type
|
|
101
|
+
instance_cls: type
|
|
102
|
+
att: str
|
|
103
|
+
ex_att: str
|
|
104
|
+
|
|
105
|
+
def collect(self, instance_cls: type, owner_cls: type | None = None) -> dict[str, tuple[K, V]]:
|
|
106
|
+
if owner_cls is None:
|
|
107
|
+
owner_cls = instance_cls
|
|
108
|
+
|
|
109
|
+
mro = instance_cls.__mro__[-2::-1]
|
|
110
|
+
try:
|
|
111
|
+
mro_pos = mro.index(owner_cls)
|
|
112
|
+
except ValueError:
|
|
113
|
+
raise TypeError(f'Owner class {owner_cls} not in mro of instance class {instance_cls}') from None
|
|
114
|
+
|
|
115
|
+
mro_dct: dict[str, list[tuple[type, ta.Any]]] = {}
|
|
116
|
+
for cur_cls in mro[:mro_pos + 1]:
|
|
117
|
+
for att, obj in cur_cls.__dict__.items():
|
|
118
|
+
if att not in mro_dct:
|
|
119
|
+
if not self._lookup(obj).present:
|
|
120
|
+
continue
|
|
121
|
+
|
|
122
|
+
try:
|
|
123
|
+
lst = mro_dct[att]
|
|
124
|
+
except KeyError:
|
|
125
|
+
lst = mro_dct[att] = []
|
|
126
|
+
lst.append((cur_cls, obj))
|
|
127
|
+
|
|
128
|
+
#
|
|
129
|
+
|
|
130
|
+
seen: ta.MutableMapping[ta.Any, str] | None = None
|
|
131
|
+
if self._forbid_duplicates:
|
|
132
|
+
seen = dict_factory(identity=self._identity)()
|
|
133
|
+
|
|
134
|
+
out: dict[str, tuple[K, V]] = {}
|
|
135
|
+
for att, lst in mro_dct.items():
|
|
136
|
+
if not lst:
|
|
137
|
+
raise RuntimeError
|
|
138
|
+
_, obj = lst[-1]
|
|
139
|
+
|
|
140
|
+
if len(lst) > 1:
|
|
141
|
+
if self._requires_override and not (self._is_override or lang.is_override)(obj):
|
|
142
|
+
raise lang.RequiresOverrideError(
|
|
143
|
+
att,
|
|
144
|
+
instance_cls,
|
|
145
|
+
lst[-1][0],
|
|
146
|
+
lst[0][0],
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
if not (mv := self._lookup(obj)).present:
|
|
150
|
+
continue
|
|
151
|
+
|
|
152
|
+
if seen is not None:
|
|
153
|
+
try:
|
|
154
|
+
ex_att = seen[obj]
|
|
155
|
+
except KeyError:
|
|
156
|
+
pass
|
|
157
|
+
else:
|
|
158
|
+
raise AttrRegistry.DuplicatesForbiddenError(owner_cls, instance_cls, att, ex_att) # noqa
|
|
159
|
+
seen[obj] = att
|
|
160
|
+
|
|
161
|
+
out[att] = (obj, mv.must())
|
|
162
|
+
|
|
163
|
+
return out
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
##
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class AttrRegistryCache(ta.Generic[K, V, T]):
|
|
170
|
+
def __init__(
|
|
171
|
+
self,
|
|
172
|
+
registry: AttrRegistry[K, V],
|
|
173
|
+
prepare: ta.Callable[[type, dict[str, tuple[K, V]]], T],
|
|
174
|
+
) -> None:
|
|
175
|
+
super().__init__()
|
|
176
|
+
|
|
177
|
+
self._registry = registry
|
|
178
|
+
self._prepare = prepare
|
|
179
|
+
|
|
180
|
+
self._cache: dict[ta.Any, T] = {}
|
|
181
|
+
|
|
182
|
+
def cache_remove(k, self_ref=weakref.ref(self)):
|
|
183
|
+
if (ref_self := self_ref()) is not None:
|
|
184
|
+
cache = ref_self._cache # noqa
|
|
185
|
+
try:
|
|
186
|
+
del cache[k]
|
|
187
|
+
except KeyError:
|
|
188
|
+
pass
|
|
189
|
+
|
|
190
|
+
self._cache_remove = cache_remove
|
|
191
|
+
|
|
192
|
+
registry.add_invalidate_callback(self._cache.clear)
|
|
193
|
+
|
|
194
|
+
def get(self, instance_cls: type) -> T:
|
|
195
|
+
cls_ref = weakref.ref(instance_cls)
|
|
196
|
+
try:
|
|
197
|
+
return self._cache[cls_ref]
|
|
198
|
+
except KeyError:
|
|
199
|
+
pass
|
|
200
|
+
del cls_ref
|
|
201
|
+
|
|
202
|
+
collected = self._registry.collect(instance_cls)
|
|
203
|
+
out = self._prepare(instance_cls, collected)
|
|
204
|
+
self._cache[weakref.ref(instance_cls, self._cache_remove)] = out
|
|
205
|
+
return out
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class SimpleAttrRegistryCache(AttrRegistryCache[K, V, dict[str, tuple[K, V]]], ta.Generic[K, V]):
|
|
209
|
+
def __init__(self, registry: AttrRegistry[K, V]) -> None:
|
|
210
|
+
super().__init__(registry, lambda _, dct: dct)
|
omlish/collections/cache/impl.py
CHANGED
|
@@ -10,12 +10,12 @@ TODO:
|
|
|
10
10
|
import collections
|
|
11
11
|
import contextlib
|
|
12
12
|
import functools
|
|
13
|
-
import logging
|
|
14
13
|
import time
|
|
15
14
|
import typing as ta
|
|
16
15
|
import weakref
|
|
17
16
|
|
|
18
17
|
from ... import lang
|
|
18
|
+
from ...logs import all as logs
|
|
19
19
|
from .types import Cache
|
|
20
20
|
from .types import Eviction
|
|
21
21
|
from .types import OverweightError
|
|
@@ -27,7 +27,7 @@ V = ta.TypeVar('V')
|
|
|
27
27
|
V2 = ta.TypeVar('V2')
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
log =
|
|
30
|
+
log = logs.get_module_logger(globals())
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
##
|
|
@@ -41,6 +41,7 @@ def LRU(cache: 'Cache') -> None: # noqa
|
|
|
41
41
|
cache._kill(cache._root.lru_next) # type: ignore # noqa
|
|
42
42
|
|
|
43
43
|
|
|
44
|
+
# aka FIFO
|
|
44
45
|
def LRI(cache: 'Cache') -> None: # noqa
|
|
45
46
|
cache._kill(cache._root.ins_next) # type: ignore # noqa
|
|
46
47
|
|
omlish/collections/identity.py
CHANGED
omlish/collections/mappings.py
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import typing as ta
|
|
2
2
|
import weakref
|
|
3
3
|
|
|
4
|
+
from .. import lang
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
with lang.auto_proxy_import(globals()):
|
|
8
|
+
from . import identity as _identity
|
|
9
|
+
|
|
4
10
|
|
|
5
11
|
T = ta.TypeVar('T')
|
|
6
12
|
K = ta.TypeVar('K')
|
|
@@ -63,6 +69,9 @@ class TypeMap(ta.Generic[T]):
|
|
|
63
69
|
def __iter__(self) -> ta.Iterator[T]:
|
|
64
70
|
return iter(self._items)
|
|
65
71
|
|
|
72
|
+
def __contains__(self, ty: type[T]) -> bool:
|
|
73
|
+
return ty in self._items
|
|
74
|
+
|
|
66
75
|
def get(self, ty: type[T]) -> T | None:
|
|
67
76
|
return self._dct.get(ty)
|
|
68
77
|
|
|
@@ -138,3 +147,22 @@ class MissingDict(dict[K, V]):
|
|
|
138
147
|
def __missing__(self, key):
|
|
139
148
|
v = self[key] = self._missing_fn(key)
|
|
140
149
|
return v
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
##
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def dict_factory[K, V](
|
|
156
|
+
*,
|
|
157
|
+
identity: bool = False,
|
|
158
|
+
weak: bool = False,
|
|
159
|
+
) -> ta.Callable[..., ta.MutableMapping[K, V]]:
|
|
160
|
+
if identity:
|
|
161
|
+
if weak:
|
|
162
|
+
return _identity.IdentityWeakKeyDictionary
|
|
163
|
+
else:
|
|
164
|
+
return _identity.IdentityKeyDict
|
|
165
|
+
elif weak:
|
|
166
|
+
return weakref.WeakKeyDictionary
|
|
167
|
+
else:
|
|
168
|
+
return dict
|
omlish/collections/trie.py
CHANGED
|
@@ -37,12 +37,16 @@ class Trie(ta.MutableMapping[ta.Sequence[K], V], ta.Generic[K, V]):
|
|
|
37
37
|
def children(self) -> ta.Mapping[K2, 'Trie.Node[K2, V2]']:
|
|
38
38
|
return self._children
|
|
39
39
|
|
|
40
|
-
def __init__(self) -> None:
|
|
40
|
+
def __init__(self, items: ta.Iterable[tuple[ta.Iterable[K], V]] | None = None) -> None:
|
|
41
41
|
super().__init__()
|
|
42
42
|
|
|
43
43
|
self._len = 0
|
|
44
44
|
self._root: Trie.Node[K, V] = Trie.Node()
|
|
45
45
|
|
|
46
|
+
if items is not None:
|
|
47
|
+
for k, v in items:
|
|
48
|
+
self[k] = v
|
|
49
|
+
|
|
46
50
|
@property
|
|
47
51
|
def root(self) -> Node[K, V]:
|
|
48
52
|
return self._root
|
omlish/collections/utils.py
CHANGED
|
@@ -7,7 +7,9 @@ from .identity import IdentitySet
|
|
|
7
7
|
|
|
8
8
|
T = ta.TypeVar('T')
|
|
9
9
|
K = ta.TypeVar('K')
|
|
10
|
+
K2 = ta.TypeVar('K2')
|
|
10
11
|
V = ta.TypeVar('V')
|
|
12
|
+
V2 = ta.TypeVar('V2')
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
##
|
|
@@ -135,6 +137,81 @@ def make_map_by(
|
|
|
135
137
|
##
|
|
136
138
|
|
|
137
139
|
|
|
140
|
+
@ta.overload
|
|
141
|
+
def map_keys(
|
|
142
|
+
fn: ta.Callable[[K], K2],
|
|
143
|
+
dct: ta.Mapping[K, V] | ta.Iterable[tuple[K, V]],
|
|
144
|
+
*,
|
|
145
|
+
identity: ta.Literal[False] = False,
|
|
146
|
+
strict: bool = False,
|
|
147
|
+
) -> dict[K2, V]:
|
|
148
|
+
return {}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
@ta.overload
|
|
152
|
+
def map_keys(
|
|
153
|
+
fn: ta.Callable[[K], K2],
|
|
154
|
+
dct: ta.Mapping[K, V] | ta.Iterable[tuple[K, V]],
|
|
155
|
+
*,
|
|
156
|
+
identity: bool = False,
|
|
157
|
+
strict: bool = False,
|
|
158
|
+
) -> ta.MutableMapping[K2, V]:
|
|
159
|
+
return {}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def map_keys(
|
|
163
|
+
fn,
|
|
164
|
+
dct,
|
|
165
|
+
*,
|
|
166
|
+
identity=False,
|
|
167
|
+
strict=False,
|
|
168
|
+
):
|
|
169
|
+
return make_map(
|
|
170
|
+
((fn(k), v) for k, v in (dct.items() if isinstance(dct, ta.Mapping) else dct)),
|
|
171
|
+
identity=identity,
|
|
172
|
+
strict=strict,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@ta.overload
|
|
177
|
+
def map_values(
|
|
178
|
+
fn: ta.Callable[[V], V2],
|
|
179
|
+
dct: ta.Mapping[K, V] | ta.Iterable[tuple[K, V]],
|
|
180
|
+
*,
|
|
181
|
+
identity: ta.Literal[False] = False,
|
|
182
|
+
strict: bool = False,
|
|
183
|
+
) -> dict[K, V2]:
|
|
184
|
+
return {}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
@ta.overload
|
|
188
|
+
def map_values(
|
|
189
|
+
fn: ta.Callable[[V], V2],
|
|
190
|
+
dct: ta.Mapping[K, V] | ta.Iterable[tuple[K, V]],
|
|
191
|
+
*,
|
|
192
|
+
identity: bool = False,
|
|
193
|
+
strict: bool = False,
|
|
194
|
+
) -> ta.MutableMapping[K2, V]:
|
|
195
|
+
return {}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def map_values(
|
|
199
|
+
fn,
|
|
200
|
+
dct,
|
|
201
|
+
*,
|
|
202
|
+
identity=False,
|
|
203
|
+
strict=False,
|
|
204
|
+
):
|
|
205
|
+
return make_map(
|
|
206
|
+
((k, fn(v)) for k, v in (dct.items() if isinstance(dct, ta.Mapping) else dct)),
|
|
207
|
+
identity=identity,
|
|
208
|
+
strict=strict,
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
##
|
|
213
|
+
|
|
214
|
+
|
|
138
215
|
@ta.overload
|
|
139
216
|
def multi_map(
|
|
140
217
|
kvs: ta.Iterable[tuple[K, V]],
|
omlish/concurrent/__init__.py
CHANGED
omlish/concurrent/all.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from .. import lang as _lang
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
with _lang.auto_proxy_init(globals()):
|
|
5
|
+
##
|
|
6
|
+
|
|
7
|
+
from .executors import ( # noqa
|
|
8
|
+
ImmediateExecutor,
|
|
9
|
+
new_executor,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from .futures import ( # noqa
|
|
13
|
+
FutureError,
|
|
14
|
+
FutureTimeoutError,
|
|
15
|
+
wait_all_futures_or_raise,
|
|
16
|
+
wait_dependent_futures,
|
|
17
|
+
wait_futures,
|
|
18
|
+
)
|
omlish/concurrent/futures.py
CHANGED
|
@@ -48,6 +48,13 @@ def wait_futures(
|
|
|
48
48
|
raise_exceptions: bool = False,
|
|
49
49
|
cancel_on_exception: bool = False,
|
|
50
50
|
) -> bool:
|
|
51
|
+
# TODO:
|
|
52
|
+
# - raise_exceptions 'at_end', ExceptionGroup
|
|
53
|
+
# - more responsive than tick_interval_s - semaphore, add callbacks to each fut to decrement, sleep with a timed
|
|
54
|
+
# wait on sem
|
|
55
|
+
# - cancel_on_timeout
|
|
56
|
+
# - obviate wait_all_futures_or_raise
|
|
57
|
+
|
|
51
58
|
start = time.time()
|
|
52
59
|
|
|
53
60
|
not_done = set(futures)
|
|
@@ -72,6 +79,24 @@ def wait_futures(
|
|
|
72
79
|
return False
|
|
73
80
|
|
|
74
81
|
|
|
82
|
+
def wait_all_futures_or_raise(futures: ta.Sequence[cf.Future]) -> None:
|
|
83
|
+
done, not_done = cf.wait(futures, return_when=cf.ALL_COMPLETED)
|
|
84
|
+
if not_done:
|
|
85
|
+
raise RuntimeError(f'Not all futures finished: {not_done}')
|
|
86
|
+
|
|
87
|
+
excs: list[Exception] = []
|
|
88
|
+
for f in done:
|
|
89
|
+
try:
|
|
90
|
+
f.result()
|
|
91
|
+
except Exception as e: # noqa
|
|
92
|
+
excs.append(e)
|
|
93
|
+
|
|
94
|
+
if len(excs) == 1:
|
|
95
|
+
raise excs[0]
|
|
96
|
+
elif excs:
|
|
97
|
+
raise ExceptionGroup('One or more futures failed', excs)
|
|
98
|
+
|
|
99
|
+
|
|
75
100
|
def wait_dependent_futures(
|
|
76
101
|
executor: cf.Executor,
|
|
77
102
|
dependency_sets_by_fn: ta.Mapping[ta.Callable, ta.AbstractSet[ta.Callable]],
|
omlish/concurrent/threadlets.py
CHANGED
|
@@ -75,7 +75,7 @@ class GreenletThreadlet(Threadlet):
|
|
|
75
75
|
|
|
76
76
|
@property
|
|
77
77
|
def parent(self) -> ta.Optional['GreenletThreadlet']:
|
|
78
|
-
return GreenletThreadlet(self.g.parent)
|
|
78
|
+
return GreenletThreadlet(p) if (p := self.g.parent) is not None else None
|
|
79
79
|
|
|
80
80
|
@property
|
|
81
81
|
def dead(self) -> bool:
|
|
@@ -119,7 +119,7 @@ class ConfigFlattening:
|
|
|
119
119
|
def unflatten(self, flattened: ta.Mapping[str, ta.Any]) -> ta.Mapping[str, ta.Any]:
|
|
120
120
|
root = ConfigFlattening.UnflattenDict()
|
|
121
121
|
|
|
122
|
-
def split_keys(fkey: str) -> ta.
|
|
122
|
+
def split_keys(fkey: str) -> ta.Iterator[ta.Union[str, int]]:
|
|
123
123
|
for part in fkey.split(self._delimiter):
|
|
124
124
|
if self._index_open in part:
|
|
125
125
|
check.state(part.endswith(self._index_close))
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"""
|
|
4
4
|
TODO:
|
|
5
5
|
- smarter merging than just dumb dict-squashing
|
|
6
|
+
- at least sequence merging
|
|
6
7
|
"""
|
|
7
8
|
import typing as ta
|
|
8
9
|
|
|
@@ -19,13 +20,14 @@ def merge_configs(*ms: ConfigMap) -> ConfigMap:
|
|
|
19
20
|
e = o[k]
|
|
20
21
|
except KeyError:
|
|
21
22
|
o[k] = v
|
|
23
|
+
continue
|
|
24
|
+
|
|
25
|
+
if isinstance(e, ta.Mapping) and isinstance(v, ta.Mapping):
|
|
26
|
+
rec(e, v) # noqa
|
|
22
27
|
else:
|
|
23
|
-
if isinstance(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if isinstance(v, ta.Mapping):
|
|
27
|
-
v = dict(v)
|
|
28
|
-
o[k] = v
|
|
28
|
+
if isinstance(v, ta.Mapping):
|
|
29
|
+
v = dict(v)
|
|
30
|
+
o[k] = v
|
|
29
31
|
|
|
30
32
|
o: dict = {}
|
|
31
33
|
for i in ms:
|