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/maybes.py
CHANGED
omlish/lang/maysync.py
CHANGED
|
@@ -3,7 +3,7 @@ import typing as ta
|
|
|
3
3
|
from ..lite.maysync import MaysyncFn
|
|
4
4
|
from ..lite.maysync import MaysyncGeneratorFn
|
|
5
5
|
from ..lite.maysync import make_maysync as _make_maysync
|
|
6
|
-
from .
|
|
6
|
+
from .asyncs import as_async
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
T = ta.TypeVar('T')
|
|
@@ -68,5 +68,5 @@ def make_maysync_from_sync(
|
|
|
68
68
|
) -> ta.Callable[P, ta.Awaitable[T]]:
|
|
69
69
|
return _make_maysync(
|
|
70
70
|
s,
|
|
71
|
-
a if a is not None else as_async(s),
|
|
71
|
+
a if a is not None else as_async(s, wrap=True),
|
|
72
72
|
)
|
omlish/lang/params.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
TODO:
|
|
3
3
|
- check validity
|
|
4
|
+
- signature vs getfullargspec - diff unwrapping + 'self' handling
|
|
4
5
|
"""
|
|
5
6
|
import dataclasses as dc
|
|
6
7
|
import enum
|
|
@@ -16,6 +17,13 @@ from .classes.restrict import Sealed
|
|
|
16
17
|
T = ta.TypeVar('T')
|
|
17
18
|
|
|
18
19
|
|
|
20
|
+
CanParamSpec: ta.TypeAlias = ta.Union[
|
|
21
|
+
'ParamSpec',
|
|
22
|
+
inspect.Signature,
|
|
23
|
+
ta.Callable,
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
|
|
19
27
|
##
|
|
20
28
|
|
|
21
29
|
|
|
@@ -101,6 +109,15 @@ class ParamSpec(ta.Sequence[Param], Final):
|
|
|
101
109
|
|
|
102
110
|
#
|
|
103
111
|
|
|
112
|
+
@classmethod
|
|
113
|
+
def of(cls, obj: CanParamSpec) -> 'ParamSpec':
|
|
114
|
+
if isinstance(obj, ParamSpec):
|
|
115
|
+
return obj
|
|
116
|
+
elif isinstance(obj, inspect.Signature):
|
|
117
|
+
return cls.of_signature(obj)
|
|
118
|
+
else:
|
|
119
|
+
return cls.inspect(obj)
|
|
120
|
+
|
|
104
121
|
@classmethod
|
|
105
122
|
def of_signature(
|
|
106
123
|
cls,
|
omlish/lang/recursion.py
CHANGED
omlish/lang/resources.py
CHANGED
omlish/lang/sequences.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- StrView, BytesView - in lieu of hkt lol
|
|
4
|
+
- cext? even necessary?
|
|
5
|
+
- __eq__, cmp, __hash__
|
|
6
|
+
- __buffer__
|
|
7
|
+
- optimize `slice(None)`, keep as SeqView but fast path ops
|
|
8
|
+
- shorter repr if __len__ > some threshold
|
|
9
|
+
- use materialize()?
|
|
10
|
+
"""
|
|
11
|
+
import typing as ta
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
T = ta.TypeVar('T')
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
##
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def iterslice(
|
|
21
|
+
seq: ta.Sequence[T],
|
|
22
|
+
slc: slice,
|
|
23
|
+
) -> ta.Iterator[T]:
|
|
24
|
+
return map(seq.__getitem__, range(*slc.indices(len(seq))))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def iterrange(
|
|
28
|
+
seq: ta.Sequence[T],
|
|
29
|
+
start: int | None = None,
|
|
30
|
+
stop: int | None = None,
|
|
31
|
+
step: int | None = None,
|
|
32
|
+
) -> ta.Iterator[T]:
|
|
33
|
+
return iterslice(seq, slice(start, stop, step))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@ta.final
|
|
40
|
+
class SeqView(ta.Sequence[T]):
|
|
41
|
+
def __init__(self, data: ta.Sequence[T], slice_: slice = slice(None)) -> None:
|
|
42
|
+
if data.__class__ is SeqView:
|
|
43
|
+
self._data = data._data # type: ignore[attr-defined] # noqa
|
|
44
|
+
self._range = data._range[slice_] # type: ignore[attr-defined] # noqa
|
|
45
|
+
else:
|
|
46
|
+
self._data = data
|
|
47
|
+
self._range = range(*slice_.indices(len(data)))
|
|
48
|
+
|
|
49
|
+
def __init_subclass__(cls, **kwargs):
|
|
50
|
+
raise TypeError
|
|
51
|
+
|
|
52
|
+
_data: ta.Sequence[T]
|
|
53
|
+
_range: range
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def _from_range(cls, base: ta.Sequence[T], rng: range) -> 'SeqView[T]':
|
|
57
|
+
self = object.__new__(cls)
|
|
58
|
+
self._data = base
|
|
59
|
+
self._range = rng
|
|
60
|
+
return self
|
|
61
|
+
|
|
62
|
+
def __repr__(self) -> str:
|
|
63
|
+
return f'{self.__class__.__name__}({self._data!r}, {self.slice!r})'
|
|
64
|
+
|
|
65
|
+
#
|
|
66
|
+
|
|
67
|
+
def __len__(self) -> int:
|
|
68
|
+
return len(self._range)
|
|
69
|
+
|
|
70
|
+
def __getitem__(self, key: int | slice) -> ta.Union[T, 'SeqView[T]']: # type: ignore[override]
|
|
71
|
+
if isinstance(key, slice):
|
|
72
|
+
nr = self._range[key]
|
|
73
|
+
return SeqView._from_range(self._data, nr)
|
|
74
|
+
return self._data[self._range[key]]
|
|
75
|
+
|
|
76
|
+
def __iter__(self) -> ta.Iterator[T]:
|
|
77
|
+
return map(self._data.__getitem__, self._range)
|
|
78
|
+
|
|
79
|
+
def __reversed__(self) -> ta.Iterator[T]:
|
|
80
|
+
return map(self._data.__getitem__, reversed(self._range))
|
|
81
|
+
|
|
82
|
+
def count(self, value: ta.Any) -> int:
|
|
83
|
+
c = 0
|
|
84
|
+
for i in self._range:
|
|
85
|
+
if self._data[i] == value:
|
|
86
|
+
c += 1
|
|
87
|
+
return c
|
|
88
|
+
|
|
89
|
+
def index(self, value: ta.Any, start: int = 0, stop: int | None = None) -> int:
|
|
90
|
+
sub = self._range[slice(start, stop, 1)]
|
|
91
|
+
for off, i in enumerate(sub):
|
|
92
|
+
if self._data[i] == value:
|
|
93
|
+
return off
|
|
94
|
+
raise ValueError(f'{value!r} is not in view')
|
|
95
|
+
|
|
96
|
+
#
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def data(self) -> ta.Sequence[T]:
|
|
100
|
+
return self._data
|
|
101
|
+
|
|
102
|
+
_slice: slice
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def slice(self) -> slice:
|
|
106
|
+
try:
|
|
107
|
+
return self._slice
|
|
108
|
+
except AttributeError:
|
|
109
|
+
pass
|
|
110
|
+
|
|
111
|
+
step = self._range.step
|
|
112
|
+
start = self._range.start
|
|
113
|
+
if len(self._range) == 0:
|
|
114
|
+
stop = start
|
|
115
|
+
else:
|
|
116
|
+
last = start + (len(self._range) - 1) * step
|
|
117
|
+
stop = last + (1 if step > 0 else -1)
|
|
118
|
+
slc = slice(start, stop, step)
|
|
119
|
+
|
|
120
|
+
self._slice = slc
|
|
121
|
+
return slc
|
|
122
|
+
|
|
123
|
+
def materialize(self) -> ta.Sequence[T]:
|
|
124
|
+
return self._data[self.slice]
|
|
@@ -2,7 +2,6 @@ import types
|
|
|
2
2
|
import typing as ta
|
|
3
3
|
|
|
4
4
|
from .. import dataclasses as dc
|
|
5
|
-
from .. import defs
|
|
6
5
|
from .. import lang
|
|
7
6
|
from .base import Lifecycle
|
|
8
7
|
from .controller import LifecycleController
|
|
@@ -37,7 +36,7 @@ class LifecycleContextManager(ta.Generic[LifecycleT]):
|
|
|
37
36
|
self._lifecycle = lifecycle
|
|
38
37
|
self._controller = lifecycle if isinstance(lifecycle, LifecycleController) else LifecycleController(lifecycle)
|
|
39
38
|
|
|
40
|
-
|
|
39
|
+
__repr__ = lang.attr_ops(lambda o: (o.lifecycle, o.state)).repr
|
|
41
40
|
|
|
42
41
|
@property
|
|
43
42
|
def lifecycle(self) -> LifecycleT:
|
omlish/lifecycles/controller.py
CHANGED
|
@@ -2,7 +2,6 @@ import abc
|
|
|
2
2
|
import typing as ta
|
|
3
3
|
|
|
4
4
|
from .. import check
|
|
5
|
-
from .. import defs
|
|
6
5
|
from .. import lang
|
|
7
6
|
from .base import AnyLifecycle # noqa
|
|
8
7
|
from .base import Lifecycle # noqa
|
|
@@ -48,7 +47,7 @@ class AnyLifecycleController(AnyLifecycle[R], lang.Abstract, ta.Generic[AnyLifec
|
|
|
48
47
|
self._state = LifecycleStates.NEW
|
|
49
48
|
self._listeners: list[AnyLifecycleListener[AnyLifecycleT, R]] = []
|
|
50
49
|
|
|
51
|
-
|
|
50
|
+
__repr__ = lang.attr_ops(lambda o: (o.lifecycle, o.state)).repr
|
|
52
51
|
|
|
53
52
|
@property
|
|
54
53
|
def lifecycle(self) -> AnyLifecycleT:
|
omlish/lite/abstract.py
CHANGED
|
@@ -3,6 +3,9 @@ import abc
|
|
|
3
3
|
import typing as ta
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
T = ta.TypeVar('T')
|
|
7
|
+
|
|
8
|
+
|
|
6
9
|
##
|
|
7
10
|
|
|
8
11
|
|
|
@@ -14,25 +17,49 @@ def is_abstract_method(obj: ta.Any) -> bool:
|
|
|
14
17
|
return bool(getattr(obj, _IS_ABSTRACT_METHOD_ATTR, False))
|
|
15
18
|
|
|
16
19
|
|
|
17
|
-
def
|
|
20
|
+
def compute_abstract_methods(cls: type) -> ta.FrozenSet[str]:
|
|
21
|
+
# ~> https://github.com/python/cpython/blob/f3476c6507381ca860eec0989f53647b13517423/Modules/_abc.c#L358
|
|
22
|
+
|
|
23
|
+
# Stage 1: direct abstract methods
|
|
24
|
+
|
|
25
|
+
abstracts = {
|
|
26
|
+
a
|
|
27
|
+
# Get items as a list to avoid mutation issues during iteration
|
|
28
|
+
for a, v in list(cls.__dict__.items())
|
|
29
|
+
if is_abstract_method(v)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Stage 2: inherited abstract methods
|
|
33
|
+
|
|
34
|
+
for base in cls.__bases__:
|
|
35
|
+
# Get __abstractmethods__ from base if it exists
|
|
36
|
+
if (base_abstracts := getattr(base, _ABSTRACT_METHODS_ATTR, None)) is None:
|
|
37
|
+
continue
|
|
38
|
+
|
|
39
|
+
# Iterate over abstract methods in base
|
|
40
|
+
for key in base_abstracts:
|
|
41
|
+
# Check if this class has an attribute with this name
|
|
42
|
+
try:
|
|
43
|
+
value = getattr(cls, key)
|
|
44
|
+
except AttributeError:
|
|
45
|
+
# Attribute not found in this class, skip
|
|
46
|
+
continue
|
|
47
|
+
|
|
48
|
+
# Check if it's still abstract
|
|
49
|
+
if is_abstract_method(value):
|
|
50
|
+
abstracts.add(key)
|
|
51
|
+
|
|
52
|
+
return frozenset(abstracts)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def update_abstracts(cls: ta.Type[T], *, force: bool = False) -> ta.Type[T]:
|
|
18
56
|
if not force and not hasattr(cls, _ABSTRACT_METHODS_ATTR):
|
|
19
57
|
# Per stdlib: We check for __abstractmethods__ here because cls might by a C implementation or a python
|
|
20
58
|
# implementation (especially during testing), and we want to handle both cases.
|
|
21
59
|
return cls
|
|
22
60
|
|
|
23
|
-
abstracts
|
|
24
|
-
|
|
25
|
-
for scls in cls.__bases__:
|
|
26
|
-
for name in getattr(scls, _ABSTRACT_METHODS_ATTR, ()):
|
|
27
|
-
value = getattr(cls, name, None)
|
|
28
|
-
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
|
29
|
-
abstracts.add(name)
|
|
30
|
-
|
|
31
|
-
for name, value in cls.__dict__.items():
|
|
32
|
-
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
|
33
|
-
abstracts.add(name)
|
|
34
|
-
|
|
35
|
-
setattr(cls, _ABSTRACT_METHODS_ATTR, frozenset(abstracts))
|
|
61
|
+
abstracts = compute_abstract_methods(cls)
|
|
62
|
+
setattr(cls, _ABSTRACT_METHODS_ATTR, abstracts)
|
|
36
63
|
return cls
|
|
37
64
|
|
|
38
65
|
|
|
@@ -86,23 +113,26 @@ class Abstract:
|
|
|
86
113
|
super().__init_subclass__(**kwargs)
|
|
87
114
|
|
|
88
115
|
if not (Abstract in cls.__bases__ or abc.ABC in cls.__bases__):
|
|
89
|
-
ams
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
116
|
+
if ams := compute_abstract_methods(cls):
|
|
117
|
+
amd = {
|
|
118
|
+
a: mcls
|
|
119
|
+
for mcls in cls.__mro__[::-1]
|
|
120
|
+
for a in ams
|
|
121
|
+
if a in mcls.__dict__
|
|
122
|
+
}
|
|
95
123
|
|
|
96
|
-
if ams:
|
|
97
124
|
raise AbstractTypeError(
|
|
98
125
|
f'Cannot subclass abstract class {cls.__name__} with abstract methods: ' +
|
|
99
126
|
', '.join(sorted([
|
|
100
127
|
'.'.join([
|
|
101
|
-
*([
|
|
102
|
-
|
|
128
|
+
*([
|
|
129
|
+
*([m] if (m := getattr(c, '__module__')) else []),
|
|
130
|
+
getattr(c, '__qualname__', getattr(c, '__name__')),
|
|
131
|
+
] if c is not None else '?'),
|
|
103
132
|
a,
|
|
104
133
|
])
|
|
105
|
-
for a
|
|
134
|
+
for a in ams
|
|
135
|
+
for c in [amd.get(a)]
|
|
106
136
|
])),
|
|
107
137
|
)
|
|
108
138
|
|
omlish/lite/asyncs.py
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# ruff: noqa: UP006 UP045
|
|
2
|
+
import functools
|
|
3
|
+
import typing as ta
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
T = ta.TypeVar('T')
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def opt_await(aw: ta.Optional[ta.Awaitable[T]]) -> ta.Optional[T]:
|
|
13
|
+
return (await aw if aw is not None else None)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
async def async_list(ai: ta.AsyncIterable[T]) -> ta.List[T]:
|
|
17
|
+
return [v async for v in ai]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
async def async_enumerate(ai: ta.AsyncIterable[T]) -> ta.AsyncIterable[ta.Tuple[int, T]]:
|
|
21
|
+
i = 0
|
|
22
|
+
async for e in ai:
|
|
23
|
+
yield (i, e)
|
|
24
|
+
i += 1
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def as_async(fn: ta.Callable[..., T], *, wrap: bool = False) -> ta.Callable[..., ta.Awaitable[T]]:
|
|
31
|
+
async def inner(*args, **kwargs):
|
|
32
|
+
return fn(*args, **kwargs)
|
|
33
|
+
|
|
34
|
+
return functools.wraps(fn)(inner) if wrap else inner
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class SyncAwaitCoroutineNotTerminatedError(Exception):
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def sync_await(aw: ta.Awaitable[T]) -> T:
|
|
45
|
+
"""
|
|
46
|
+
Allows for the synchronous execution of async functions which will never actually *externally* await anything. These
|
|
47
|
+
functions are allowed to await any number of other functions - including contextmanagers and generators - so long as
|
|
48
|
+
nothing ever actually 'leaks' out of the function, presumably to an event loop.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
ret = missing = object()
|
|
52
|
+
|
|
53
|
+
async def thunk():
|
|
54
|
+
nonlocal ret
|
|
55
|
+
|
|
56
|
+
ret = await aw
|
|
57
|
+
|
|
58
|
+
cr = thunk()
|
|
59
|
+
try:
|
|
60
|
+
try:
|
|
61
|
+
cr.send(None)
|
|
62
|
+
except StopIteration:
|
|
63
|
+
pass
|
|
64
|
+
|
|
65
|
+
if ret is missing or cr.cr_await is not None or cr.cr_running:
|
|
66
|
+
raise SyncAwaitCoroutineNotTerminatedError('Not terminated')
|
|
67
|
+
|
|
68
|
+
finally:
|
|
69
|
+
cr.close()
|
|
70
|
+
|
|
71
|
+
return ta.cast(T, ret)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
#
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def sync_aiter(ai: ta.AsyncIterator[T]) -> ta.Iterator[T]:
|
|
78
|
+
while True:
|
|
79
|
+
try:
|
|
80
|
+
o = sync_await(ai.__anext__())
|
|
81
|
+
except StopAsyncIteration:
|
|
82
|
+
break
|
|
83
|
+
yield o
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def sync_async_list(ai: ta.AsyncIterable[T]) -> ta.List[T]:
|
|
87
|
+
"""
|
|
88
|
+
Uses `sync_await` to synchronously read the full contents of a function call returning an async iterator, given that
|
|
89
|
+
the function never externally awaits anything.
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
lst: ta.Optional[ta.List[T]] = None
|
|
93
|
+
|
|
94
|
+
async def inner():
|
|
95
|
+
nonlocal lst
|
|
96
|
+
|
|
97
|
+
lst = [v async for v in ai]
|
|
98
|
+
|
|
99
|
+
sync_await(inner())
|
|
100
|
+
|
|
101
|
+
if not isinstance(lst, list):
|
|
102
|
+
raise TypeError(lst)
|
|
103
|
+
|
|
104
|
+
return lst
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
#
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@ta.final
|
|
111
|
+
class SyncAwaitContextManager(ta.Generic[T]):
|
|
112
|
+
def __init__(self, acm: ta.AsyncContextManager[T]) -> None:
|
|
113
|
+
self._acm = acm
|
|
114
|
+
|
|
115
|
+
def __repr__(self) -> str:
|
|
116
|
+
return f'{self.__class__.__name__}({self._acm!r})'
|
|
117
|
+
|
|
118
|
+
def __enter__(self) -> T:
|
|
119
|
+
return sync_await(self._acm.__aenter__())
|
|
120
|
+
|
|
121
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
122
|
+
return sync_await(self._acm.__aexit__(exc_type, exc_val, exc_tb))
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
sync_async_with = SyncAwaitContextManager
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
##
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
@ta.final
|
|
132
|
+
class SyncToAsyncContextManager(ta.Generic[T]):
|
|
133
|
+
def __init__(self, cm: ta.ContextManager[T]) -> None:
|
|
134
|
+
self._cm = cm
|
|
135
|
+
|
|
136
|
+
def __repr__(self) -> str:
|
|
137
|
+
return f'{self.__class__.__name__}({self._cm!r})'
|
|
138
|
+
|
|
139
|
+
async def __aenter__(self) -> T:
|
|
140
|
+
return self._cm.__enter__()
|
|
141
|
+
|
|
142
|
+
async def __aexit__(self, exc_type, exc_value, traceback, /):
|
|
143
|
+
return self._cm.__exit__(exc_type, exc_value, traceback)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
as_async_context_manager = SyncToAsyncContextManager
|