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/lang/_asyncs.cc
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// @omlish-cext
|
|
2
|
+
#define PY_SSIZE_T_CLEAN
|
|
3
|
+
#include <Python.h>
|
|
4
|
+
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
#define _MODULE_NAME "_asyncs"
|
|
8
|
+
#define _PACKAGE_NAME "omlish.lang"
|
|
9
|
+
#define _MODULE_FULL_NAME _PACKAGE_NAME "." _MODULE_NAME
|
|
10
|
+
|
|
11
|
+
//
|
|
12
|
+
|
|
13
|
+
typedef struct {
|
|
14
|
+
PyObject *SyncAwaitCoroutineNotTerminatedError;
|
|
15
|
+
PyObject *str_close;
|
|
16
|
+
PyObject *str___await__;
|
|
17
|
+
} module_state;
|
|
18
|
+
|
|
19
|
+
static module_state *
|
|
20
|
+
get_module_state(PyObject *module)
|
|
21
|
+
{
|
|
22
|
+
return (module_state *) PyModule_GetState(module);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//
|
|
26
|
+
|
|
27
|
+
static void
|
|
28
|
+
suppress_close(PyObject *iter, module_state *state)
|
|
29
|
+
{
|
|
30
|
+
PyObject *res = PyObject_CallMethodNoArgs(iter, state->str_close);
|
|
31
|
+
if (!res) {
|
|
32
|
+
PyErr_Clear();
|
|
33
|
+
} else {
|
|
34
|
+
Py_DECREF(res);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static PyObject *
|
|
39
|
+
sync_await(PyObject *module, PyObject *aw)
|
|
40
|
+
{
|
|
41
|
+
module_state *state = get_module_state(module);
|
|
42
|
+
PyObject *await_meth = NULL;
|
|
43
|
+
PyObject *iter = NULL;
|
|
44
|
+
PyObject *result = NULL;
|
|
45
|
+
PySendResult sres;
|
|
46
|
+
|
|
47
|
+
await_meth = PyObject_GetAttr(aw, state->str___await__);
|
|
48
|
+
if (await_meth == NULL) {
|
|
49
|
+
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
|
50
|
+
PyErr_SetString(PyExc_TypeError, "object is not awaitable (no __await__)");
|
|
51
|
+
}
|
|
52
|
+
goto error;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
iter = PyObject_CallNoArgs(await_meth);
|
|
56
|
+
Py_DECREF(await_meth);
|
|
57
|
+
await_meth = NULL;
|
|
58
|
+
|
|
59
|
+
if (iter == NULL) {
|
|
60
|
+
goto error;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!PyIter_Check(iter)) {
|
|
64
|
+
Py_DECREF(iter);
|
|
65
|
+
PyErr_SetString(PyExc_TypeError, "__await__() must return an iterator");
|
|
66
|
+
goto error;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
sres = PyIter_Send(iter, Py_None, &result);
|
|
70
|
+
if (sres == PYGEN_ERROR) {
|
|
71
|
+
Py_DECREF(iter);
|
|
72
|
+
goto error;
|
|
73
|
+
}
|
|
74
|
+
if (sres == PYGEN_NEXT) {
|
|
75
|
+
Py_XDECREF(result);
|
|
76
|
+
suppress_close(iter, state);
|
|
77
|
+
Py_DECREF(iter);
|
|
78
|
+
PyErr_SetString(state->SyncAwaitCoroutineNotTerminatedError, "Not terminated");
|
|
79
|
+
goto error;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
Py_DECREF(iter);
|
|
83
|
+
return result;
|
|
84
|
+
|
|
85
|
+
error:
|
|
86
|
+
return NULL;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
//
|
|
90
|
+
|
|
91
|
+
static PyMethodDef mod_methods[] = {
|
|
92
|
+
{"sync_await", sync_await, METH_O, "sync_await"},
|
|
93
|
+
{NULL, NULL, 0, NULL}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
static int
|
|
97
|
+
module_traverse(PyObject *module, visitproc visit, void *arg)
|
|
98
|
+
{
|
|
99
|
+
module_state *state = get_module_state(module);
|
|
100
|
+
Py_VISIT(state->SyncAwaitCoroutineNotTerminatedError);
|
|
101
|
+
Py_VISIT(state->str_close);
|
|
102
|
+
Py_VISIT(state->str___await__);
|
|
103
|
+
return 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
static int
|
|
107
|
+
module_clear(PyObject *module)
|
|
108
|
+
{
|
|
109
|
+
module_state *state = get_module_state(module);
|
|
110
|
+
Py_CLEAR(state->SyncAwaitCoroutineNotTerminatedError);
|
|
111
|
+
Py_CLEAR(state->str_close);
|
|
112
|
+
Py_CLEAR(state->str___await__);
|
|
113
|
+
return 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
static void
|
|
117
|
+
module_free(void *module)
|
|
118
|
+
{
|
|
119
|
+
module_clear((PyObject *) module);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static int
|
|
123
|
+
module_exec(PyObject *module)
|
|
124
|
+
{
|
|
125
|
+
module_state *state = get_module_state(module);
|
|
126
|
+
|
|
127
|
+
state->str_close = PyUnicode_InternFromString("close");
|
|
128
|
+
if (!state->str_close) {
|
|
129
|
+
return -1;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
state->str___await__ = PyUnicode_InternFromString("__await__");
|
|
133
|
+
if (!state->str___await__) {
|
|
134
|
+
return -1;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
PyObject *asyncs_module = PyImport_ImportModule("omlish.lite.asyncs");
|
|
138
|
+
if (!asyncs_module) {
|
|
139
|
+
return -1;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
state->SyncAwaitCoroutineNotTerminatedError = PyObject_GetAttrString(
|
|
143
|
+
asyncs_module,
|
|
144
|
+
"SyncAwaitCoroutineNotTerminatedError"
|
|
145
|
+
);
|
|
146
|
+
Py_DECREF(asyncs_module);
|
|
147
|
+
|
|
148
|
+
if (!state->SyncAwaitCoroutineNotTerminatedError) {
|
|
149
|
+
return -1;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
//
|
|
156
|
+
|
|
157
|
+
PyDoc_STRVAR(module_doc, _MODULE_NAME);
|
|
158
|
+
|
|
159
|
+
static PyModuleDef_Slot module_slots[] = {
|
|
160
|
+
{Py_mod_exec, (void *) module_exec},
|
|
161
|
+
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
|
|
162
|
+
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
|
|
163
|
+
{0, NULL}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
static PyModuleDef module_def = {
|
|
167
|
+
.m_base = PyModuleDef_HEAD_INIT,
|
|
168
|
+
.m_name = _MODULE_NAME,
|
|
169
|
+
.m_doc = module_doc,
|
|
170
|
+
.m_size = sizeof(module_state),
|
|
171
|
+
.m_methods = mod_methods,
|
|
172
|
+
.m_slots = module_slots,
|
|
173
|
+
.m_traverse = module_traverse,
|
|
174
|
+
.m_clear = module_clear,
|
|
175
|
+
.m_free = module_free,
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
extern "C" {
|
|
179
|
+
|
|
180
|
+
PyMODINIT_FUNC
|
|
181
|
+
PyInit__asyncs(void)
|
|
182
|
+
{
|
|
183
|
+
return PyModuleDef_Init(&module_def);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
}
|
omlish/lang/asyncs.py
CHANGED
|
@@ -1,73 +1,97 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import functools
|
|
1
3
|
import typing as ta
|
|
2
4
|
|
|
5
|
+
from ..lite.abstract import Abstract
|
|
6
|
+
from ..lite.asyncs import sync_await as _sync_await
|
|
7
|
+
from ..lite.maybes import Maybe
|
|
3
8
|
|
|
9
|
+
|
|
10
|
+
O = ta.TypeVar('O')
|
|
11
|
+
I = ta.TypeVar('I')
|
|
12
|
+
R = ta.TypeVar('R')
|
|
4
13
|
T = ta.TypeVar('T')
|
|
14
|
+
P = ta.ParamSpec('P')
|
|
5
15
|
|
|
6
16
|
|
|
7
17
|
##
|
|
8
18
|
|
|
9
19
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"""Simply eagerly reads the full contents of a function call returning an async iterator."""
|
|
20
|
+
def as_async(fn: ta.Callable[P, T], *, wrap: bool = False) -> ta.Callable[P, ta.Awaitable[T]]:
|
|
21
|
+
async def inner(*args, **kwargs):
|
|
22
|
+
return fn(*args, **kwargs)
|
|
14
23
|
|
|
15
|
-
return
|
|
24
|
+
return functools.wraps(fn)(inner) if wrap else inner
|
|
16
25
|
|
|
17
26
|
|
|
18
27
|
##
|
|
19
28
|
|
|
20
29
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
class AsyncGeneratorWithReturn(ta.AsyncGenerator[O, I], Abstract, ta.Generic[O, I, R]):
|
|
31
|
+
@property
|
|
32
|
+
@abc.abstractmethod
|
|
33
|
+
def value(self) -> Maybe[R]:
|
|
34
|
+
raise NotImplementedError
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@ta.final
|
|
38
|
+
class _AsyncGeneratorWithReturn(AsyncGeneratorWithReturn[O, I, R]):
|
|
39
|
+
def __init__(self, ag: ta.AsyncGenerator[O, I]) -> None:
|
|
40
|
+
if isinstance(ag, _AsyncGeneratorWithReturn):
|
|
41
|
+
raise TypeError(ag)
|
|
42
|
+
self._ag = ag
|
|
43
|
+
|
|
44
|
+
def __repr__(self) -> str:
|
|
45
|
+
return f'{self.__class__.__name__}({self._ag!r})'
|
|
46
|
+
|
|
47
|
+
_v: Maybe[R] = Maybe.empty()
|
|
29
48
|
|
|
30
|
-
|
|
49
|
+
@property
|
|
50
|
+
def value(self) -> Maybe[R]:
|
|
51
|
+
return self._v
|
|
31
52
|
|
|
32
|
-
|
|
33
|
-
|
|
53
|
+
def _set_value(self, v: R) -> None:
|
|
54
|
+
if self._v.present:
|
|
55
|
+
raise TypeError('Return value already set')
|
|
56
|
+
self._v = Maybe.just(v)
|
|
34
57
|
|
|
35
|
-
|
|
58
|
+
def __anext__(self):
|
|
59
|
+
return self._ag.__anext__()
|
|
36
60
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
try:
|
|
40
|
-
cr.send(None)
|
|
41
|
-
except StopIteration:
|
|
42
|
-
pass
|
|
61
|
+
def asend(self, value):
|
|
62
|
+
return self._ag.asend(value)
|
|
43
63
|
|
|
44
|
-
|
|
45
|
-
|
|
64
|
+
def athrow(self, typ, val=None, tb=None):
|
|
65
|
+
return self._ag.athrow(typ, val, tb)
|
|
46
66
|
|
|
47
|
-
|
|
48
|
-
|
|
67
|
+
def aclose(self):
|
|
68
|
+
return self._ag.aclose()
|
|
49
69
|
|
|
50
|
-
return ta.cast(T, ret)
|
|
51
70
|
|
|
71
|
+
def async_generator_with_return(
|
|
72
|
+
fn: ta.Callable[ta.Concatenate[ta.Callable[[R], None], P], ta.AsyncGenerator[O, I]],
|
|
73
|
+
) -> ta.Callable[P, AsyncGeneratorWithReturn[O, I, R]]:
|
|
74
|
+
@functools.wraps(fn)
|
|
75
|
+
def inner(*args, **kwargs):
|
|
76
|
+
def set_value(v):
|
|
77
|
+
x._set_value(v) # noqa
|
|
52
78
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"""
|
|
79
|
+
return (x := _AsyncGeneratorWithReturn(fn(set_value, *args, **kwargs))) # type: ignore[var-annotated]
|
|
80
|
+
|
|
81
|
+
return inner
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
##
|
|
60
85
|
|
|
61
|
-
lst: list[T] | None = None
|
|
62
86
|
|
|
63
|
-
|
|
64
|
-
nonlocal lst
|
|
87
|
+
sync_await = _sync_await
|
|
65
88
|
|
|
66
|
-
lst = [v async for v in ai]
|
|
67
89
|
|
|
68
|
-
|
|
90
|
+
try:
|
|
91
|
+
from . import _asyncs as cext # type: ignore
|
|
69
92
|
|
|
70
|
-
|
|
71
|
-
|
|
93
|
+
except ImportError:
|
|
94
|
+
pass
|
|
72
95
|
|
|
73
|
-
|
|
96
|
+
else:
|
|
97
|
+
sync_await = cext.sync_await
|
|
@@ -76,7 +76,7 @@ def set_attr(
|
|
|
76
76
|
##
|
|
77
77
|
|
|
78
78
|
|
|
79
|
-
class
|
|
79
|
+
class AttrStorage(Abstract):
|
|
80
80
|
class NOT_SET: # noqa
|
|
81
81
|
def __new__(cls, *args, **kwargs): # noqa
|
|
82
82
|
raise TypeError
|
|
@@ -97,9 +97,9 @@ class AttrOps(Abstract):
|
|
|
97
97
|
#
|
|
98
98
|
|
|
99
99
|
|
|
100
|
-
class
|
|
101
|
-
def getattr(self, obj: ta.Any, name: str, default: ta.Any =
|
|
102
|
-
if default is
|
|
100
|
+
class StdAttrStorage(AttrStorage):
|
|
101
|
+
def getattr(self, obj: ta.Any, name: str, default: ta.Any = AttrStorage.NOT_SET) -> ta.Any:
|
|
102
|
+
if default is AttrStorage.NOT_SET:
|
|
103
103
|
return getattr(obj, name)
|
|
104
104
|
else:
|
|
105
105
|
return getattr(obj, name, default)
|
|
@@ -111,13 +111,13 @@ class StdAttrOps(AttrOps):
|
|
|
111
111
|
delattr(obj, name)
|
|
112
112
|
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
STD_ATTR_STORAGE = StdAttrStorage()
|
|
115
115
|
|
|
116
116
|
|
|
117
117
|
#
|
|
118
118
|
|
|
119
119
|
|
|
120
|
-
class
|
|
120
|
+
class DictAttrStorage(AttrStorage):
|
|
121
121
|
def __init__(self, dct: ta.MutableMapping[str, ta.Any] | None = None) -> None:
|
|
122
122
|
super().__init__()
|
|
123
123
|
|
|
@@ -125,11 +125,11 @@ class DictAttrOps(AttrOps):
|
|
|
125
125
|
dct = {}
|
|
126
126
|
self._dct = dct
|
|
127
127
|
|
|
128
|
-
def getattr(self, obj: ta.Any, name: str, default: ta.Any =
|
|
128
|
+
def getattr(self, obj: ta.Any, name: str, default: ta.Any = AttrStorage.NOT_SET) -> ta.Any:
|
|
129
129
|
try:
|
|
130
130
|
return self._dct[name]
|
|
131
131
|
except KeyError:
|
|
132
|
-
if default is not
|
|
132
|
+
if default is not AttrStorage.NOT_SET:
|
|
133
133
|
return default
|
|
134
134
|
raise AttributeError(name) from None
|
|
135
135
|
|
|
@@ -205,13 +205,13 @@ def _get_object_transient_dict(obj: ta.Any) -> TransientDict:
|
|
|
205
205
|
return obj.__dict__.setdefault(_TRANSIENT_DICT_ATTR, TransientDict())
|
|
206
206
|
|
|
207
207
|
|
|
208
|
-
class
|
|
209
|
-
def getattr(self, obj: ta.Any, name: str, default: ta.Any =
|
|
208
|
+
class TransientAttrStorage(AttrStorage):
|
|
209
|
+
def getattr(self, obj: ta.Any, name: str, default: ta.Any = AttrStorage.NOT_SET) -> ta.Any:
|
|
210
210
|
td = _get_object_transient_dict(obj)
|
|
211
211
|
try:
|
|
212
212
|
return td[name]
|
|
213
213
|
except KeyError:
|
|
214
|
-
if default is not
|
|
214
|
+
if default is not AttrStorage.NOT_SET:
|
|
215
215
|
return default
|
|
216
216
|
raise AttributeError(name) from None
|
|
217
217
|
|
|
@@ -227,8 +227,8 @@ class TransientAttrOps(AttrOps):
|
|
|
227
227
|
raise AttributeError(name) from None
|
|
228
228
|
|
|
229
229
|
|
|
230
|
-
|
|
230
|
+
TRANSIENT_ATTR_STORAGE = TransientAttrStorage()
|
|
231
231
|
|
|
232
|
-
transient_getattr =
|
|
233
|
-
transient_setattr =
|
|
234
|
-
transient_delattr =
|
|
232
|
+
transient_getattr = TRANSIENT_ATTR_STORAGE.getattr
|
|
233
|
+
transient_setattr = TRANSIENT_ATTR_STORAGE.setattr
|
|
234
|
+
transient_delattr = TRANSIENT_ATTR_STORAGE.delattr
|
omlish/lang/cached/property.py
CHANGED
|
@@ -2,8 +2,8 @@ import abc
|
|
|
2
2
|
import functools
|
|
3
3
|
import typing as ta
|
|
4
4
|
|
|
5
|
-
from ..
|
|
6
|
-
from ..
|
|
5
|
+
from ..attrstorage import transient_getattr
|
|
6
|
+
from ..attrstorage import transient_setattr
|
|
7
7
|
from ..classes.abstract import Abstract
|
|
8
8
|
|
|
9
9
|
|
omlish/lang/casing.py
CHANGED
|
@@ -50,6 +50,13 @@ class StringCasing(Abstract):
|
|
|
50
50
|
|
|
51
51
|
raise NotImplementedError
|
|
52
52
|
|
|
53
|
+
#
|
|
54
|
+
|
|
55
|
+
def to(self, other: 'StringCasing') -> ta.Callable[[str], str]:
|
|
56
|
+
def inner(s: str) -> str:
|
|
57
|
+
return other.join(*self.split(s))
|
|
58
|
+
return inner
|
|
59
|
+
|
|
53
60
|
|
|
54
61
|
#
|
|
55
62
|
|
|
@@ -167,6 +174,10 @@ snake_case = SNAKE_CASE.join
|
|
|
167
174
|
up_snake_case = UP_SNAKE_CASE.join
|
|
168
175
|
|
|
169
176
|
|
|
177
|
+
camel_to_snake = CAMEL_CASE.to(SNAKE_CASE)
|
|
178
|
+
snake_to_camel = SNAKE_CASE.to(CAMEL_CASE)
|
|
179
|
+
|
|
180
|
+
|
|
170
181
|
##
|
|
171
182
|
|
|
172
183
|
|
omlish/lang/classes/bindable.py
CHANGED
|
@@ -7,10 +7,9 @@ T = ta.TypeVar('T')
|
|
|
7
7
|
##
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
@ta.final
|
|
10
11
|
class _ClassOrInstanceMethod:
|
|
11
12
|
def __init__(self, func):
|
|
12
|
-
super().__init__()
|
|
13
|
-
|
|
14
13
|
self.__func__ = func
|
|
15
14
|
|
|
16
15
|
def __get__(self, instance, owner=None):
|
|
@@ -19,7 +18,7 @@ class _ClassOrInstanceMethod:
|
|
|
19
18
|
|
|
20
19
|
class BindableClass(ta.Generic[T]):
|
|
21
20
|
# FIXME: apparently can't have TypeVars in ClassVars, but could stick in a @classmethod (which gets transformed)...
|
|
22
|
-
_bound: ta.ClassVar[type[T] | None] = None
|
|
21
|
+
_bound: ta.ClassVar[type[T] | None] = None
|
|
23
22
|
|
|
24
23
|
def __init__(self, *, _bound):
|
|
25
24
|
super().__init__()
|
omlish/lang/classes/restrict.py
CHANGED
|
@@ -32,6 +32,14 @@ class Final(Abstract):
|
|
|
32
32
|
elif Final in base.__mro__:
|
|
33
33
|
raise FinalTypeError(base)
|
|
34
34
|
|
|
35
|
+
# Per `ta.final`:
|
|
36
|
+
try:
|
|
37
|
+
cls.__final__ = True # type: ignore[attr-defined]
|
|
38
|
+
except (AttributeError, TypeError):
|
|
39
|
+
# Skip the attribute silently if it is not writable. AttributeError happens if the object has __slots__ or
|
|
40
|
+
# a read-only property, TypeError if it's a builtin class.
|
|
41
|
+
pass
|
|
42
|
+
|
|
35
43
|
|
|
36
44
|
##
|
|
37
45
|
|
omlish/lang/classes/simple.py
CHANGED
|
@@ -63,7 +63,6 @@ class Marker(NotInstantiable, metaclass=_MarkerMeta):
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
_SINGLETON_INSTANCE_ATTR = '__singleton_instance__'
|
|
66
|
-
_SINGLETON_LOCK = threading.RLock()
|
|
67
66
|
|
|
68
67
|
|
|
69
68
|
def _set_singleton_instance(inst):
|
|
@@ -85,7 +84,24 @@ def _set_singleton_instance(inst):
|
|
|
85
84
|
return inst
|
|
86
85
|
|
|
87
86
|
|
|
88
|
-
class
|
|
87
|
+
class _AnySingleton:
|
|
88
|
+
def __init__(self) -> None:
|
|
89
|
+
try:
|
|
90
|
+
type(self).__dict__[_SINGLETON_INSTANCE_ATTR]
|
|
91
|
+
except KeyError:
|
|
92
|
+
pass
|
|
93
|
+
else:
|
|
94
|
+
raise TypeError(f'Must not re-instantiate singleton {type(self)}')
|
|
95
|
+
|
|
96
|
+
super().__init__()
|
|
97
|
+
|
|
98
|
+
@ta.final
|
|
99
|
+
def __reduce__(self):
|
|
100
|
+
return (type(self), ())
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class Singleton(_AnySingleton):
|
|
104
|
+
@ta.final
|
|
89
105
|
def __new__(cls):
|
|
90
106
|
return cls.__dict__[_SINGLETON_INSTANCE_ATTR]
|
|
91
107
|
|
|
@@ -95,15 +111,21 @@ class Singleton:
|
|
|
95
111
|
_set_singleton_instance(super().__new__(cls)) # noqa
|
|
96
112
|
|
|
97
113
|
|
|
98
|
-
|
|
114
|
+
_LAZY_SINGLETON_LOCK = threading.RLock()
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class LazySingleton(_AnySingleton):
|
|
118
|
+
@ta.final
|
|
99
119
|
def __new__(cls):
|
|
100
120
|
try:
|
|
101
121
|
return cls.__dict__[_SINGLETON_INSTANCE_ATTR]
|
|
102
122
|
except KeyError:
|
|
103
123
|
pass
|
|
104
|
-
|
|
124
|
+
|
|
125
|
+
with _LAZY_SINGLETON_LOCK:
|
|
105
126
|
try:
|
|
106
127
|
return cls.__dict__[_SINGLETON_INSTANCE_ATTR]
|
|
107
128
|
except KeyError:
|
|
108
129
|
pass
|
|
130
|
+
|
|
109
131
|
return _set_singleton_instance(super().__new__(cls))
|
omlish/lang/collections.py
CHANGED
|
@@ -9,7 +9,7 @@ V = ta.TypeVar('V')
|
|
|
9
9
|
##
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
def yield_dict_init(*args: ta.Any, **kwargs: ta.Any) -> ta.
|
|
12
|
+
def yield_dict_init(*args: ta.Any, **kwargs: ta.Any) -> ta.Iterator[tuple[ta.Any, ta.Any]]:
|
|
13
13
|
if len(args) > 1:
|
|
14
14
|
raise TypeError
|
|
15
15
|
|
omlish/lang/contextmanagers.py
CHANGED
|
@@ -20,6 +20,8 @@ T = ta.TypeVar('T')
|
|
|
20
20
|
K = ta.TypeVar('K')
|
|
21
21
|
V = ta.TypeVar('V')
|
|
22
22
|
|
|
23
|
+
P = ta.ParamSpec('P')
|
|
24
|
+
|
|
23
25
|
|
|
24
26
|
##
|
|
25
27
|
|
|
@@ -165,6 +167,30 @@ def maybe_managing(obj: T) -> ta.Iterator[T]:
|
|
|
165
167
|
yield obj
|
|
166
168
|
|
|
167
169
|
|
|
170
|
+
@contextlib.asynccontextmanager
|
|
171
|
+
async def async_maybe_managing(obj: T) -> ta.AsyncGenerator[T]:
|
|
172
|
+
if isinstance(obj, ta.AsyncContextManager):
|
|
173
|
+
async with obj:
|
|
174
|
+
yield obj
|
|
175
|
+
else:
|
|
176
|
+
yield obj
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@contextlib.asynccontextmanager
|
|
180
|
+
async def async_or_sync_maybe_managing(obj: T) -> ta.AsyncGenerator[T]:
|
|
181
|
+
if isinstance(obj, ta.AsyncContextManager):
|
|
182
|
+
async with obj:
|
|
183
|
+
yield obj
|
|
184
|
+
elif isinstance(obj, ta.ContextManager):
|
|
185
|
+
with obj:
|
|
186
|
+
yield obj
|
|
187
|
+
else:
|
|
188
|
+
yield obj
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
##
|
|
192
|
+
|
|
193
|
+
|
|
168
194
|
@contextlib.contextmanager
|
|
169
195
|
def disposing(obj: T, attr: str = 'dispose') -> ta.Iterator[T]:
|
|
170
196
|
try:
|
|
@@ -194,15 +220,6 @@ def context_var_setting(var: contextvars.ContextVar[T], val: T) -> ta.Iterator[T
|
|
|
194
220
|
##
|
|
195
221
|
|
|
196
222
|
|
|
197
|
-
@contextlib.asynccontextmanager
|
|
198
|
-
async def as_async_context_manager(cm: ta.ContextManager[T]) -> ta.AsyncIterator[T]:
|
|
199
|
-
with cm as v:
|
|
200
|
-
yield v
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
##
|
|
204
|
-
|
|
205
|
-
|
|
206
223
|
ContextWrappable: ta.TypeAlias = ta.ContextManager | str | ta.Callable[..., ta.ContextManager]
|
|
207
224
|
|
|
208
225
|
|
|
@@ -382,3 +399,36 @@ def double_check_setdefault(
|
|
|
382
399
|
v = fn()
|
|
383
400
|
dct[k] = v
|
|
384
401
|
return v
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
##
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
def call_with_exit_stack(
|
|
408
|
+
fn: ta.Callable[ta.Concatenate[contextlib.ExitStack, P], T],
|
|
409
|
+
*args: P.args,
|
|
410
|
+
**kwargs: P.kwargs,
|
|
411
|
+
) -> T:
|
|
412
|
+
with contextlib.ExitStack() as es:
|
|
413
|
+
return fn(es, *args, **kwargs)
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
async def call_with_async_exit_stack(
|
|
417
|
+
fn: ta.Callable[ta.Concatenate[contextlib.AsyncExitStack, P], ta.Awaitable[T]],
|
|
418
|
+
*args: P.args,
|
|
419
|
+
**kwargs: P.kwargs,
|
|
420
|
+
) -> T:
|
|
421
|
+
async with contextlib.AsyncExitStack() as aes:
|
|
422
|
+
return await fn(aes, *args, **kwargs)
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def with_exit_stack(
|
|
426
|
+
fn: ta.Callable[ta.Concatenate[contextlib.ExitStack, P], T],
|
|
427
|
+
) -> ta.Callable[P, T]:
|
|
428
|
+
return functools.partial(call_with_exit_stack, fn)
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def with_async_exit_stack(
|
|
432
|
+
fn: ta.Callable[ta.Concatenate[contextlib.AsyncExitStack, P], ta.Awaitable[T]],
|
|
433
|
+
) -> ta.Callable[P, ta.Awaitable[T]]:
|
|
434
|
+
return functools.partial(call_with_async_exit_stack, fn)
|