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/lite/attrops.py
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
# ruff: noqa: UP006 UP007 UP045
|
|
2
|
+
# @omlish-lite
|
|
3
|
+
"""
|
|
4
|
+
TODO:
|
|
5
|
+
- dotted paths!
|
|
6
|
+
- per-attr repr transform / filter
|
|
7
|
+
- __ne__ ? cases where it still matters
|
|
8
|
+
- ordering ?
|
|
9
|
+
- repr_filter: ta.Union[ta.Callable[[ta.Any], ta.Optional[str]], ta.Literal['not_none', 'truthy']]] ?
|
|
10
|
+
- unify repr/repr_fn/repr_filter
|
|
11
|
+
"""
|
|
12
|
+
import types # noqa
|
|
13
|
+
import typing as ta
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
T = ta.TypeVar('T')
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@ta.final
|
|
23
|
+
class AttrOps(ta.Generic[T]):
|
|
24
|
+
@ta.final
|
|
25
|
+
class Attr:
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
name: str,
|
|
29
|
+
*,
|
|
30
|
+
display: ta.Optional[str] = None,
|
|
31
|
+
|
|
32
|
+
repr: bool = True, # noqa
|
|
33
|
+
repr_fn: ta.Optional[ta.Callable[[ta.Any], ta.Optional[str]]] = None,
|
|
34
|
+
|
|
35
|
+
hash: bool = True, # noqa
|
|
36
|
+
eq: bool = True,
|
|
37
|
+
) -> None:
|
|
38
|
+
if '.' in name:
|
|
39
|
+
raise NotImplementedError('Dotted paths not yet supported')
|
|
40
|
+
if not name.isidentifier() or name.startswith('__'):
|
|
41
|
+
raise AttributeError(f'Invalid attr: {name!r}')
|
|
42
|
+
self._name = name
|
|
43
|
+
|
|
44
|
+
if display is None:
|
|
45
|
+
display = name[1:] if name.startswith('_') and len(name) > 1 else name
|
|
46
|
+
self._display = display
|
|
47
|
+
|
|
48
|
+
self._repr = repr
|
|
49
|
+
self._repr_fn = repr_fn
|
|
50
|
+
|
|
51
|
+
self._hash = hash
|
|
52
|
+
self._eq = eq
|
|
53
|
+
|
|
54
|
+
@classmethod
|
|
55
|
+
def of(
|
|
56
|
+
cls,
|
|
57
|
+
o: ta.Union[
|
|
58
|
+
'AttrOps.Attr',
|
|
59
|
+
str,
|
|
60
|
+
ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
|
|
61
|
+
ta.Mapping[str, ta.Any],
|
|
62
|
+
],
|
|
63
|
+
) -> 'AttrOps.Attr':
|
|
64
|
+
if isinstance(o, AttrOps.Attr):
|
|
65
|
+
return o
|
|
66
|
+
elif isinstance(o, str):
|
|
67
|
+
return cls(o)
|
|
68
|
+
elif isinstance(o, tuple):
|
|
69
|
+
name, x = o
|
|
70
|
+
kw: ta.Mapping[str, ta.Any]
|
|
71
|
+
if isinstance(x, str):
|
|
72
|
+
kw = dict(display=x)
|
|
73
|
+
elif isinstance(x, ta.Mapping):
|
|
74
|
+
kw = x
|
|
75
|
+
else:
|
|
76
|
+
raise TypeError(x)
|
|
77
|
+
return cls(name, **kw)
|
|
78
|
+
elif isinstance(o, ta.Mapping):
|
|
79
|
+
return cls(**o)
|
|
80
|
+
else:
|
|
81
|
+
raise TypeError(o)
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def name(self) -> str:
|
|
85
|
+
return self._name
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def display(self) -> str:
|
|
89
|
+
return self._display
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def hash(self) -> bool:
|
|
93
|
+
return self._hash
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def eq(self) -> bool:
|
|
97
|
+
return self._eq
|
|
98
|
+
|
|
99
|
+
@staticmethod
|
|
100
|
+
def opt_repr(o: ta.Any) -> ta.Optional[str]:
|
|
101
|
+
return repr(o) if o is not None else None
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def truthy_repr(o: ta.Any) -> ta.Optional[str]:
|
|
105
|
+
return repr(o) if o else None
|
|
106
|
+
|
|
107
|
+
#
|
|
108
|
+
|
|
109
|
+
@ta.overload
|
|
110
|
+
def __init__(
|
|
111
|
+
self,
|
|
112
|
+
*attrs: ta.Sequence[ta.Union[
|
|
113
|
+
str,
|
|
114
|
+
ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
|
|
115
|
+
ta.Mapping[str, ta.Any],
|
|
116
|
+
Attr,
|
|
117
|
+
]],
|
|
118
|
+
|
|
119
|
+
with_module: bool = False,
|
|
120
|
+
use_qualname: bool = False,
|
|
121
|
+
with_id: bool = False,
|
|
122
|
+
terse: bool = False,
|
|
123
|
+
repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
|
|
124
|
+
recursive: bool = False,
|
|
125
|
+
|
|
126
|
+
cache_hash: ta.Union[bool, str] = False,
|
|
127
|
+
subtypes_eq: bool = False,
|
|
128
|
+
) -> None:
|
|
129
|
+
...
|
|
130
|
+
|
|
131
|
+
@ta.overload
|
|
132
|
+
def __init__(
|
|
133
|
+
self,
|
|
134
|
+
attrs_fn: ta.Callable[[T], ta.Tuple[ta.Union[
|
|
135
|
+
ta.Any,
|
|
136
|
+
ta.Tuple[ta.Any, ta.Union[str, ta.Mapping[str, ta.Any]]],
|
|
137
|
+
Attr,
|
|
138
|
+
], ...]],
|
|
139
|
+
/,
|
|
140
|
+
*,
|
|
141
|
+
|
|
142
|
+
with_module: bool = False,
|
|
143
|
+
use_qualname: bool = False,
|
|
144
|
+
with_id: bool = False,
|
|
145
|
+
terse: bool = False,
|
|
146
|
+
repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
|
|
147
|
+
recursive: bool = False,
|
|
148
|
+
|
|
149
|
+
cache_hash: ta.Union[bool, str] = False,
|
|
150
|
+
subtypes_eq: bool = False,
|
|
151
|
+
) -> None:
|
|
152
|
+
...
|
|
153
|
+
|
|
154
|
+
def __init__(
|
|
155
|
+
self,
|
|
156
|
+
*args,
|
|
157
|
+
|
|
158
|
+
with_module=False,
|
|
159
|
+
use_qualname=False,
|
|
160
|
+
with_id=False,
|
|
161
|
+
terse=False,
|
|
162
|
+
repr_filter=None,
|
|
163
|
+
recursive=False,
|
|
164
|
+
|
|
165
|
+
cache_hash=False,
|
|
166
|
+
subtypes_eq=False,
|
|
167
|
+
) -> None:
|
|
168
|
+
if args and len(args) == 1 and callable(args[0]):
|
|
169
|
+
self._attrs: ta.Sequence[AttrOps.Attr] = self._capture_attrs(args[0])
|
|
170
|
+
else:
|
|
171
|
+
self._attrs = list(map(AttrOps.Attr.of, args))
|
|
172
|
+
|
|
173
|
+
self._with_module: bool = with_module
|
|
174
|
+
self._use_qualname: bool = use_qualname
|
|
175
|
+
self._with_id: bool = with_id
|
|
176
|
+
self._terse: bool = terse
|
|
177
|
+
self._repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = repr_filter
|
|
178
|
+
self._recursive: bool = recursive
|
|
179
|
+
|
|
180
|
+
self._cache_hash: ta.Union[bool, str] = cache_hash
|
|
181
|
+
self._subtypes_eq: bool = subtypes_eq
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def attrs(self) -> ta.Sequence[Attr]:
|
|
185
|
+
return self._attrs
|
|
186
|
+
|
|
187
|
+
#
|
|
188
|
+
|
|
189
|
+
@ta.final
|
|
190
|
+
class _AttrCapturer:
|
|
191
|
+
def __init__(self, fn):
|
|
192
|
+
self.__fn = fn
|
|
193
|
+
|
|
194
|
+
def __getattr__(self, attr):
|
|
195
|
+
return self.__fn(self, attr)
|
|
196
|
+
|
|
197
|
+
@classmethod
|
|
198
|
+
def _capture_attrs(cls, fn: ta.Callable) -> ta.Sequence[Attr]:
|
|
199
|
+
def access(parent, attr):
|
|
200
|
+
dct[(ret := cls._AttrCapturer(access))] = (parent, attr)
|
|
201
|
+
return ret
|
|
202
|
+
|
|
203
|
+
dct: dict = {}
|
|
204
|
+
raw = fn(root := cls._AttrCapturer(access))
|
|
205
|
+
|
|
206
|
+
def rec(cap): # noqa
|
|
207
|
+
if cap is root:
|
|
208
|
+
return
|
|
209
|
+
parent, attr = dct[cap]
|
|
210
|
+
yield from rec(parent)
|
|
211
|
+
yield attr
|
|
212
|
+
|
|
213
|
+
attrs: ta.List[AttrOps.Attr] = []
|
|
214
|
+
for o in raw:
|
|
215
|
+
if isinstance(o, (AttrOps.Attr, ta.Mapping)):
|
|
216
|
+
attrs.append(AttrOps.Attr.of(o))
|
|
217
|
+
continue
|
|
218
|
+
|
|
219
|
+
kw: ta.Mapping[str, ta.Any]
|
|
220
|
+
if isinstance(o, tuple):
|
|
221
|
+
cap, x = o
|
|
222
|
+
if isinstance(x, str):
|
|
223
|
+
kw = dict(display=x)
|
|
224
|
+
elif isinstance(x, ta.Mapping):
|
|
225
|
+
kw = x
|
|
226
|
+
else:
|
|
227
|
+
raise TypeError(x)
|
|
228
|
+
else:
|
|
229
|
+
cap, kw = o, {}
|
|
230
|
+
|
|
231
|
+
path = tuple(rec(cap))
|
|
232
|
+
|
|
233
|
+
attrs.append(AttrOps.Attr(
|
|
234
|
+
'.'.join(path),
|
|
235
|
+
**kw,
|
|
236
|
+
))
|
|
237
|
+
|
|
238
|
+
return attrs
|
|
239
|
+
|
|
240
|
+
#
|
|
241
|
+
|
|
242
|
+
_repr: ta.Callable[[T], str]
|
|
243
|
+
|
|
244
|
+
@property
|
|
245
|
+
def repr(self) -> ta.Callable[[T], str]:
|
|
246
|
+
try:
|
|
247
|
+
return self._repr
|
|
248
|
+
except AttributeError:
|
|
249
|
+
pass
|
|
250
|
+
|
|
251
|
+
def _repr(o: T) -> str:
|
|
252
|
+
vs: ta.List[str] = []
|
|
253
|
+
for a in self._attrs:
|
|
254
|
+
if not a._repr: # noqa
|
|
255
|
+
continue
|
|
256
|
+
v = getattr(o, a._name) # noqa
|
|
257
|
+
if self._repr_filter is not None and not self._repr_filter(v):
|
|
258
|
+
continue
|
|
259
|
+
if (rfn := a._repr_fn) is None: # noqa
|
|
260
|
+
rfn = repr
|
|
261
|
+
if (vr := rfn(v)) is None:
|
|
262
|
+
continue
|
|
263
|
+
if self._terse:
|
|
264
|
+
vs.append(vr)
|
|
265
|
+
else:
|
|
266
|
+
vs.append(f'{a._display}={vr}') # noqa
|
|
267
|
+
|
|
268
|
+
return (
|
|
269
|
+
f'{o.__class__.__module__ + "." if self._with_module else ""}'
|
|
270
|
+
f'{o.__class__.__qualname__ if self._use_qualname else o.__class__.__name__}'
|
|
271
|
+
f'{("@" + hex(id(o))[2:]) if self._with_id else ""}' # noqa
|
|
272
|
+
f'({", ".join(vs)})'
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
if self._recursive:
|
|
276
|
+
_repr = self._reprlib().recursive_repr()(_repr)
|
|
277
|
+
|
|
278
|
+
self._repr = _repr
|
|
279
|
+
return _repr
|
|
280
|
+
|
|
281
|
+
_reprlib_: ta.ClassVar[ta.Any]
|
|
282
|
+
|
|
283
|
+
@classmethod
|
|
284
|
+
def _reprlib(cls) -> ta.Any:
|
|
285
|
+
try:
|
|
286
|
+
return cls._reprlib_
|
|
287
|
+
except AttributeError:
|
|
288
|
+
pass
|
|
289
|
+
|
|
290
|
+
import reprlib # noqa
|
|
291
|
+
|
|
292
|
+
cls._reprlib_ = reprlib
|
|
293
|
+
return reprlib
|
|
294
|
+
|
|
295
|
+
#
|
|
296
|
+
|
|
297
|
+
_DEFAULT_CACHED_HASH_ATTR: ta.ClassVar[str] = '__cached_hash__'
|
|
298
|
+
|
|
299
|
+
_hash: ta.Callable[[T], int]
|
|
300
|
+
|
|
301
|
+
@property
|
|
302
|
+
def hash(self) -> ta.Callable[[T], int]:
|
|
303
|
+
try:
|
|
304
|
+
return self._hash
|
|
305
|
+
except AttributeError:
|
|
306
|
+
pass
|
|
307
|
+
|
|
308
|
+
def _calc_hash(o: T) -> int:
|
|
309
|
+
return hash(tuple(
|
|
310
|
+
getattr(o, a._name) # noqa
|
|
311
|
+
for a in self._attrs
|
|
312
|
+
if a._hash # noqa
|
|
313
|
+
))
|
|
314
|
+
|
|
315
|
+
if (ch := self._cache_hash) is not False:
|
|
316
|
+
if ch is True:
|
|
317
|
+
cha = self._DEFAULT_CACHED_HASH_ATTR
|
|
318
|
+
elif isinstance(ch, str):
|
|
319
|
+
cha = ch
|
|
320
|
+
else:
|
|
321
|
+
raise TypeError(ch)
|
|
322
|
+
|
|
323
|
+
def _cached_hash(o: T) -> int:
|
|
324
|
+
try:
|
|
325
|
+
return object.__getattribute__(o, cha)
|
|
326
|
+
except AttributeError:
|
|
327
|
+
object.__setattr__(o, cha, h := _calc_hash(o))
|
|
328
|
+
return h
|
|
329
|
+
|
|
330
|
+
_hash = _cached_hash
|
|
331
|
+
|
|
332
|
+
else:
|
|
333
|
+
_hash = _calc_hash
|
|
334
|
+
|
|
335
|
+
self._hash = _hash
|
|
336
|
+
return _hash
|
|
337
|
+
|
|
338
|
+
#
|
|
339
|
+
|
|
340
|
+
_eq: ta.Callable[[T, ta.Any], ta.Union[bool, 'types.NotImplementedType']]
|
|
341
|
+
|
|
342
|
+
@property
|
|
343
|
+
def eq(self) -> ta.Callable[[T, ta.Any], ta.Union[bool, 'types.NotImplementedType']]:
|
|
344
|
+
try:
|
|
345
|
+
return self._eq
|
|
346
|
+
except AttributeError:
|
|
347
|
+
pass
|
|
348
|
+
|
|
349
|
+
def _eq(o: T, x: ta.Any) -> 'ta.Union[bool, types.NotImplementedType]':
|
|
350
|
+
if self._subtypes_eq:
|
|
351
|
+
if not isinstance(x, type(o)):
|
|
352
|
+
return NotImplemented
|
|
353
|
+
else:
|
|
354
|
+
if type(x) is not type(o):
|
|
355
|
+
return NotImplemented
|
|
356
|
+
|
|
357
|
+
return all(
|
|
358
|
+
getattr(o, a._name) == getattr(x, a._name) # noqa
|
|
359
|
+
for a in self._attrs
|
|
360
|
+
if a._eq # noqa
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
self._eq = _eq
|
|
364
|
+
return _eq
|
|
365
|
+
|
|
366
|
+
@property
|
|
367
|
+
def hash_eq(self) -> ta.Tuple[
|
|
368
|
+
ta.Callable[[T], int],
|
|
369
|
+
ta.Callable[[T, ta.Any], ta.Union[bool, 'types.NotImplementedType']],
|
|
370
|
+
]:
|
|
371
|
+
return (self.hash, self.eq)
|
|
372
|
+
|
|
373
|
+
#
|
|
374
|
+
|
|
375
|
+
@property
|
|
376
|
+
def repr_hash_eq(self) -> ta.Tuple[
|
|
377
|
+
ta.Callable[[T], str],
|
|
378
|
+
ta.Callable[[T], int],
|
|
379
|
+
ta.Callable[[T, ta.Any], ta.Union[bool, 'types.NotImplementedType']],
|
|
380
|
+
]:
|
|
381
|
+
return (self.repr, self.hash, self.eq)
|
|
382
|
+
|
|
383
|
+
#
|
|
384
|
+
|
|
385
|
+
class NOT_SET: # noqa
|
|
386
|
+
def __new__(cls, *args, **kwargs): # noqa
|
|
387
|
+
raise TypeError
|
|
388
|
+
|
|
389
|
+
def install(
|
|
390
|
+
self,
|
|
391
|
+
locals_dct: ta.MutableMapping[str, ta.Any],
|
|
392
|
+
*,
|
|
393
|
+
repr: ta.Union[bool, ta.Type[NOT_SET]] = NOT_SET, # noqa
|
|
394
|
+
hash: ta.Union[bool, ta.Type[NOT_SET]] = NOT_SET, # noqa
|
|
395
|
+
eq: ta.Union[bool, ta.Type[NOT_SET]] = NOT_SET,
|
|
396
|
+
) -> 'AttrOps[T]':
|
|
397
|
+
if all(a is self.NOT_SET for a in (repr, hash, eq)):
|
|
398
|
+
repr = hash = eq = True # noqa
|
|
399
|
+
if repr:
|
|
400
|
+
locals_dct.update(__repr__=self.repr)
|
|
401
|
+
if hash:
|
|
402
|
+
locals_dct.update(__hash__=self.hash)
|
|
403
|
+
if eq:
|
|
404
|
+
locals_dct.update(__eq__=self.eq)
|
|
405
|
+
return self
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
attr_ops = AttrOps[ta.Any]
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
##
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
def attr_repr(obj: ta.Any, *attrs: str, **kwargs: ta.Any) -> str:
|
|
415
|
+
return AttrOps(*attrs, **kwargs).repr(obj)
|
omlish/lite/cached.py
CHANGED
|
@@ -21,7 +21,7 @@ class _AbstractCachedNullary:
|
|
|
21
21
|
def __call__(self, *args, **kwargs): # noqa
|
|
22
22
|
raise TypeError
|
|
23
23
|
|
|
24
|
-
def __get__(self, instance, owner): # noqa
|
|
24
|
+
def __get__(self, instance, owner=None): # noqa
|
|
25
25
|
bound = instance.__dict__[self._fn.__name__] = self.__class__(self._fn.__get__(instance, owner))
|
|
26
26
|
return bound
|
|
27
27
|
|
|
@@ -58,3 +58,59 @@ class _AsyncCachedNullary(_AbstractCachedNullary):
|
|
|
58
58
|
|
|
59
59
|
def async_cached_nullary(fn): # ta.Callable[..., T]) -> ta.Callable[..., T]:
|
|
60
60
|
return _AsyncCachedNullary(fn)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
##
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
cached_property = functools.cached_property
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class _cached_property: # noqa
|
|
70
|
+
"""Backported to pick up https://github.com/python/cpython/commit/056dfc71dce15f81887f0bd6da09d6099d71f979 ."""
|
|
71
|
+
|
|
72
|
+
def __init__(self, func):
|
|
73
|
+
self.func = func
|
|
74
|
+
self.attrname = None # noqa
|
|
75
|
+
self.__doc__ = func.__doc__
|
|
76
|
+
self.__module__ = func.__module__
|
|
77
|
+
|
|
78
|
+
_NOT_FOUND = object()
|
|
79
|
+
|
|
80
|
+
def __set_name__(self, owner, name):
|
|
81
|
+
if self.attrname is None:
|
|
82
|
+
self.attrname = name # noqa
|
|
83
|
+
elif name != self.attrname:
|
|
84
|
+
raise TypeError(
|
|
85
|
+
f'Cannot assign the same cached_property to two different names ({self.attrname!r} and {name!r}).',
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
def __get__(self, instance, owner=None):
|
|
89
|
+
if instance is None:
|
|
90
|
+
return self
|
|
91
|
+
if self.attrname is None:
|
|
92
|
+
raise TypeError('Cannot use cached_property instance without calling __set_name__ on it.')
|
|
93
|
+
|
|
94
|
+
try:
|
|
95
|
+
cache = instance.__dict__
|
|
96
|
+
except AttributeError: # not all objects have __dict__ (e.g. class defines slots)
|
|
97
|
+
raise TypeError(
|
|
98
|
+
f"No '__dict__' attribute on {type(instance).__name__!r} instance to cache {self.attrname!r} property.",
|
|
99
|
+
) from None
|
|
100
|
+
|
|
101
|
+
val = cache.get(self.attrname, self._NOT_FOUND)
|
|
102
|
+
|
|
103
|
+
if val is self._NOT_FOUND:
|
|
104
|
+
val = self.func(instance)
|
|
105
|
+
try:
|
|
106
|
+
cache[self.attrname] = val
|
|
107
|
+
except TypeError:
|
|
108
|
+
raise TypeError(
|
|
109
|
+
f"The '__dict__' attribute on {type(instance).__name__!r} instance does not support item "
|
|
110
|
+
f"assignment for caching {self.attrname!r} property.",
|
|
111
|
+
) from None
|
|
112
|
+
|
|
113
|
+
return val
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
globals()['cached_property'] = _cached_property
|
omlish/lite/contextmanagers.py
CHANGED
|
@@ -54,7 +54,7 @@ class ExitStacked:
|
|
|
54
54
|
es.__enter__()
|
|
55
55
|
try:
|
|
56
56
|
self._enter_contexts()
|
|
57
|
-
except
|
|
57
|
+
except BaseException: # noqa
|
|
58
58
|
es.__exit__(*sys.exc_info())
|
|
59
59
|
raise
|
|
60
60
|
return self
|
|
@@ -65,7 +65,7 @@ class ExitStacked:
|
|
|
65
65
|
return None
|
|
66
66
|
try:
|
|
67
67
|
self._exit_contexts()
|
|
68
|
-
except
|
|
68
|
+
except BaseException: # noqa
|
|
69
69
|
es.__exit__(*sys.exc_info())
|
|
70
70
|
raise
|
|
71
71
|
return es.__exit__(exc_type, exc_val, exc_tb)
|
|
@@ -113,7 +113,7 @@ class AsyncExitStacked:
|
|
|
113
113
|
await es.__aenter__()
|
|
114
114
|
try:
|
|
115
115
|
await self._async_enter_contexts()
|
|
116
|
-
except
|
|
116
|
+
except BaseException: # noqa
|
|
117
117
|
await es.__aexit__(*sys.exc_info())
|
|
118
118
|
raise
|
|
119
119
|
return self
|
|
@@ -124,7 +124,7 @@ class AsyncExitStacked:
|
|
|
124
124
|
return None
|
|
125
125
|
try:
|
|
126
126
|
await self._async_exit_contexts()
|
|
127
|
-
except
|
|
127
|
+
except BaseException: # noqa
|
|
128
128
|
await es.__aexit__(*sys.exc_info())
|
|
129
129
|
raise
|
|
130
130
|
return await es.__aexit__(exc_type, exc_val, exc_tb)
|
omlish/lite/dataclasses.py
CHANGED
|
@@ -7,6 +7,17 @@ import typing as ta
|
|
|
7
7
|
##
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
def dataclass_shallow_astuple(o: ta.Any) -> ta.Tuple[ta.Any, ...]:
|
|
11
|
+
return tuple(getattr(o, f.name) for f in dc.fields(o))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def dataclass_shallow_asdict(o: ta.Any) -> ta.Dict[str, ta.Any]:
|
|
15
|
+
return {f.name: getattr(o, f.name) for f in dc.fields(o)}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
##
|
|
19
|
+
|
|
20
|
+
|
|
10
21
|
def is_immediate_dataclass(cls: type) -> bool:
|
|
11
22
|
if not isinstance(cls, type):
|
|
12
23
|
raise TypeError(cls)
|
|
@@ -89,6 +100,36 @@ def dataclass_repr_omit_falsey(obj: ta.Any) -> str:
|
|
|
89
100
|
##
|
|
90
101
|
|
|
91
102
|
|
|
103
|
+
def dataclass_descriptor_method(*bind_attrs: str, bind_owner: bool = False) -> ta.Callable:
|
|
104
|
+
if not bind_attrs:
|
|
105
|
+
def __get__(self, instance, owner=None): # noqa
|
|
106
|
+
return self
|
|
107
|
+
|
|
108
|
+
elif bind_owner:
|
|
109
|
+
def __get__(self, instance, owner=None): # noqa
|
|
110
|
+
# Guaranteed to return a new instance even with no attrs
|
|
111
|
+
return dc.replace(self, **{
|
|
112
|
+
a: v.__get__(instance, owner) if (v := getattr(self, a)) is not None else None
|
|
113
|
+
for a in bind_attrs
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
else:
|
|
117
|
+
def __get__(self, instance, owner=None): # noqa
|
|
118
|
+
if instance is None:
|
|
119
|
+
return self
|
|
120
|
+
|
|
121
|
+
# Guaranteed to return a new instance even with no attrs
|
|
122
|
+
return dc.replace(self, **{
|
|
123
|
+
a: v.__get__(instance, owner) if (v := getattr(self, a)) is not None else None
|
|
124
|
+
for a in bind_attrs
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
return __get__
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
##
|
|
131
|
+
|
|
132
|
+
|
|
92
133
|
def dataclass_kw_only_init():
|
|
93
134
|
def inner(cls):
|
|
94
135
|
if not isinstance(cls, type) and dc.is_dataclass(cls):
|
|
@@ -150,3 +191,17 @@ def dataclass_kw_only_init():
|
|
|
150
191
|
return cls
|
|
151
192
|
|
|
152
193
|
return inner
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
##
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
@dc.dataclass()
|
|
200
|
+
class DataclassFieldRequiredError(Exception):
|
|
201
|
+
name: str
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def dataclass_field_required(name: str) -> ta.Callable[[], ta.Any]:
|
|
205
|
+
def inner() -> ta.NoReturn:
|
|
206
|
+
raise DataclassFieldRequiredError(name)
|
|
207
|
+
return inner
|
omlish/lite/inject.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# ruff: noqa: UP006 UP007 UP043 UP045
|
|
2
|
+
# @omlish-amalg ../../omdev/scripts/lib/inject.py
|
|
2
3
|
import abc
|
|
3
4
|
import contextlib
|
|
4
5
|
import contextvars
|
|
@@ -21,12 +22,12 @@ T = ta.TypeVar('T')
|
|
|
21
22
|
U = ta.TypeVar('U')
|
|
22
23
|
|
|
23
24
|
|
|
24
|
-
InjectorKeyCls = ta.Union[type, ta.NewType]
|
|
25
|
+
InjectorKeyCls = ta.Union[type, ta.NewType] # ta.TypeAlias
|
|
25
26
|
|
|
26
|
-
InjectorProviderFn = ta.Callable[['Injector'], ta.Any]
|
|
27
|
-
InjectorProviderFnMap = ta.Mapping['InjectorKey', 'InjectorProviderFn']
|
|
27
|
+
InjectorProviderFn = ta.Callable[['Injector'], ta.Any] # ta.TypeAlias
|
|
28
|
+
InjectorProviderFnMap = ta.Mapping['InjectorKey', 'InjectorProviderFn'] # ta.TypeAlias
|
|
28
29
|
|
|
29
|
-
InjectorBindingOrBindings = ta.Union['InjectorBinding', 'InjectorBindings']
|
|
30
|
+
InjectorBindingOrBindings = ta.Union['InjectorBinding', 'InjectorBindings'] # ta.TypeAlias
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
###
|
omlish/lite/marshal.py
CHANGED
omlish/lite/maybes.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# ruff: noqa: UP007 UP045
|
|
2
2
|
import abc
|
|
3
3
|
import functools
|
|
4
|
+
import operator
|
|
4
5
|
import typing as ta
|
|
5
6
|
|
|
6
7
|
from .abstract import Abstract
|
|
@@ -148,12 +149,11 @@ class _Maybe(Maybe[T], Abstract):
|
|
|
148
149
|
return op and not sp
|
|
149
150
|
|
|
150
151
|
|
|
152
|
+
@ta.final
|
|
151
153
|
class _JustMaybe(_Maybe[T]):
|
|
152
154
|
__slots__ = ('_v', '_hash')
|
|
153
155
|
|
|
154
156
|
def __init__(self, v: T) -> None:
|
|
155
|
-
super().__init__()
|
|
156
|
-
|
|
157
157
|
self._v = v
|
|
158
158
|
|
|
159
159
|
@property
|
|
@@ -185,6 +185,7 @@ class _JustMaybe(_Maybe[T]):
|
|
|
185
185
|
)
|
|
186
186
|
|
|
187
187
|
|
|
188
|
+
@ta.final
|
|
188
189
|
class _EmptyMaybe(_Maybe[T]):
|
|
189
190
|
__slots__ = ()
|
|
190
191
|
|
|
@@ -208,3 +209,10 @@ class _EmptyMaybe(_Maybe[T]):
|
|
|
208
209
|
|
|
209
210
|
|
|
210
211
|
Maybe._empty = _EmptyMaybe() # noqa
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
##
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
setattr(Maybe, 'just', _JustMaybe) # noqa
|
|
218
|
+
setattr(Maybe, 'empty', functools.partial(operator.attrgetter('_empty'), Maybe))
|
omlish/lite/maysync.py
CHANGED
|
@@ -25,6 +25,7 @@ Internally, it's not really correct to say that there is 'no event loop' in the
|
|
|
25
25
|
===
|
|
26
26
|
|
|
27
27
|
TODO:
|
|
28
|
+
- ! impl iterators not just generators !
|
|
28
29
|
- __del__
|
|
29
30
|
- (test) maysync context managers
|
|
30
31
|
- CancelledError
|
|
@@ -33,11 +34,6 @@ TODO:
|
|
|
33
34
|
- works down to 3.8
|
|
34
35
|
- make_maysync_from_sync can run with asyncio.run_in_thread
|
|
35
36
|
- make_maysync_from_async can run with asyncio.run_soon
|
|
36
|
-
|
|
37
|
-
TODO OVERHAUL:
|
|
38
|
-
- no more sync/async context, just one Context, and it means sync
|
|
39
|
-
- make FpMaywaitable *not reusable*
|
|
40
|
-
- `cannot reuse already awaited coroutine`
|
|
41
37
|
"""
|
|
42
38
|
import abc
|
|
43
39
|
import inspect
|
|
@@ -523,6 +519,27 @@ def run_maysync(m):
|
|
|
523
519
|
##
|
|
524
520
|
|
|
525
521
|
|
|
522
|
+
@ta.final
|
|
523
|
+
class RunMaysyncContextManager(ta.Generic[T]):
|
|
524
|
+
def __init__(self, acm: ta.AsyncContextManager[T]) -> None:
|
|
525
|
+
self._acm = acm
|
|
526
|
+
|
|
527
|
+
def __repr__(self) -> str:
|
|
528
|
+
return f'{self.__class__.__name__}({self._acm!r})'
|
|
529
|
+
|
|
530
|
+
def __enter__(self) -> T:
|
|
531
|
+
return run_maysync(self._acm.__aenter__())
|
|
532
|
+
|
|
533
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
534
|
+
return run_maysync(self._acm.__aexit__(exc_type, exc_val, exc_tb))
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
run_maysync_context_manager = RunMaysyncContextManager
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
##
|
|
541
|
+
|
|
542
|
+
|
|
526
543
|
_MAYSYNC_MARK_ATTR = '__maysync__'
|
|
527
544
|
|
|
528
545
|
|