omlish 0.0.0.dev133__py3-none-any.whl → 0.0.0.dev177__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.
- omlish/.manifests.json +265 -7
- omlish/__about__.py +5 -3
- omlish/antlr/_runtime/__init__.py +0 -22
- omlish/antlr/_runtime/_all.py +24 -0
- omlish/antlr/_runtime/atn/ParserATNSimulator.py +1 -1
- omlish/antlr/_runtime/dfa/DFASerializer.py +1 -1
- omlish/antlr/_runtime/error/DiagnosticErrorListener.py +2 -1
- omlish/antlr/_runtime/xpath/XPath.py +7 -1
- omlish/antlr/_runtime/xpath/XPathLexer.py +1 -1
- omlish/antlr/delimit.py +106 -0
- omlish/antlr/dot.py +31 -0
- omlish/antlr/errors.py +11 -0
- omlish/antlr/input.py +96 -0
- omlish/antlr/parsing.py +19 -0
- omlish/antlr/runtime.py +102 -0
- omlish/antlr/utils.py +38 -0
- omlish/argparse/all.py +45 -0
- omlish/{argparse.py → argparse/cli.py} +112 -107
- omlish/asyncs/__init__.py +0 -35
- omlish/asyncs/all.py +35 -0
- omlish/asyncs/asyncio/all.py +7 -0
- omlish/asyncs/asyncio/channels.py +40 -0
- omlish/asyncs/asyncio/streams.py +45 -0
- omlish/asyncs/asyncio/subprocesses.py +238 -0
- omlish/asyncs/asyncio/timeouts.py +16 -0
- omlish/asyncs/bluelet/LICENSE +6 -0
- omlish/asyncs/bluelet/all.py +67 -0
- omlish/asyncs/bluelet/api.py +23 -0
- omlish/asyncs/bluelet/core.py +178 -0
- omlish/asyncs/bluelet/events.py +78 -0
- omlish/asyncs/bluelet/files.py +80 -0
- omlish/asyncs/bluelet/runner.py +416 -0
- omlish/asyncs/bluelet/sockets.py +214 -0
- omlish/bootstrap/sys.py +3 -3
- omlish/cached.py +2 -2
- omlish/check.py +49 -460
- omlish/codecs/__init__.py +72 -0
- omlish/codecs/base.py +106 -0
- omlish/codecs/bytes.py +119 -0
- omlish/codecs/chain.py +23 -0
- omlish/codecs/funcs.py +39 -0
- omlish/codecs/registry.py +139 -0
- omlish/codecs/standard.py +4 -0
- omlish/codecs/text.py +217 -0
- omlish/collections/cache/impl.py +50 -57
- omlish/collections/coerce.py +1 -0
- omlish/collections/mappings.py +1 -1
- omlish/configs/flattening.py +1 -1
- omlish/defs.py +1 -1
- omlish/diag/_pycharm/runhack.py +8 -2
- omlish/diag/procfs.py +8 -8
- omlish/docker/__init__.py +0 -36
- omlish/docker/all.py +31 -0
- omlish/docker/consts.py +4 -0
- omlish/{lite/docker.py → docker/detect.py} +18 -0
- omlish/docker/{helpers.py → timebomb.py} +0 -21
- omlish/formats/cbor.py +31 -0
- omlish/formats/cloudpickle.py +31 -0
- omlish/formats/codecs.py +93 -0
- omlish/formats/json/codecs.py +29 -0
- omlish/formats/json/delimted.py +4 -0
- omlish/formats/json/stream/errors.py +2 -0
- omlish/formats/json/stream/lex.py +12 -6
- omlish/formats/json/stream/parse.py +38 -22
- omlish/formats/json5.py +31 -0
- omlish/formats/pickle.py +31 -0
- omlish/formats/repr.py +25 -0
- omlish/formats/toml.py +17 -0
- omlish/formats/yaml.py +25 -0
- omlish/funcs/__init__.py +0 -0
- omlish/{genmachine.py → funcs/genmachine.py} +5 -4
- omlish/{matchfns.py → funcs/match.py} +1 -1
- omlish/funcs/pairs.py +215 -0
- omlish/http/__init__.py +0 -48
- omlish/http/all.py +48 -0
- omlish/http/coro/__init__.py +0 -0
- omlish/{lite/fdio/corohttp.py → http/coro/fdio.py} +21 -19
- omlish/{lite/http/coroserver.py → http/coro/server.py} +20 -21
- omlish/{lite/http → http}/handlers.py +3 -2
- omlish/{lite/http → http}/parsing.py +1 -0
- omlish/http/sessions.py +1 -1
- omlish/{lite/http → http}/versions.py +1 -0
- omlish/inject/managed.py +2 -2
- omlish/io/__init__.py +0 -3
- omlish/{lite/io.py → io/buffers.py} +8 -9
- omlish/io/compress/__init__.py +9 -0
- omlish/io/compress/abc.py +104 -0
- omlish/io/compress/adapters.py +148 -0
- omlish/io/compress/base.py +24 -0
- omlish/io/compress/brotli.py +47 -0
- omlish/io/compress/bz2.py +61 -0
- omlish/io/compress/codecs.py +78 -0
- omlish/io/compress/gzip.py +350 -0
- omlish/io/compress/lz4.py +91 -0
- omlish/io/compress/lzma.py +81 -0
- omlish/io/compress/snappy.py +34 -0
- omlish/io/compress/zlib.py +74 -0
- omlish/io/compress/zstd.py +44 -0
- omlish/io/fdio/__init__.py +1 -0
- omlish/{lite → io}/fdio/handlers.py +5 -5
- omlish/{lite → io}/fdio/kqueue.py +8 -8
- omlish/{lite → io}/fdio/manager.py +7 -7
- omlish/{lite → io}/fdio/pollers.py +13 -13
- omlish/io/generators/__init__.py +56 -0
- omlish/io/generators/consts.py +1 -0
- omlish/io/generators/direct.py +13 -0
- omlish/io/generators/readers.py +189 -0
- omlish/io/generators/stepped.py +191 -0
- omlish/io/pyio.py +5 -2
- omlish/iterators/__init__.py +24 -0
- omlish/iterators/iterators.py +132 -0
- omlish/iterators/recipes.py +18 -0
- omlish/iterators/tools.py +96 -0
- omlish/iterators/unique.py +67 -0
- omlish/lang/__init__.py +13 -1
- omlish/lang/functions.py +11 -2
- omlish/lang/generators.py +243 -0
- omlish/lang/iterables.py +46 -49
- omlish/lang/maybes.py +4 -4
- omlish/lite/cached.py +39 -6
- omlish/lite/check.py +438 -75
- omlish/lite/contextmanagers.py +17 -4
- omlish/lite/dataclasses.py +42 -0
- omlish/lite/inject.py +28 -45
- omlish/lite/logs.py +0 -270
- omlish/lite/marshal.py +309 -144
- omlish/lite/pycharm.py +47 -0
- omlish/lite/reflect.py +33 -0
- omlish/lite/resources.py +8 -0
- omlish/lite/runtime.py +4 -4
- omlish/lite/shlex.py +12 -0
- omlish/lite/socketserver.py +2 -2
- omlish/lite/strings.py +31 -0
- omlish/logs/__init__.py +0 -32
- omlish/logs/{_abc.py → abc.py} +0 -1
- omlish/logs/all.py +37 -0
- omlish/logs/{formatters.py → color.py} +1 -2
- omlish/logs/configs.py +7 -38
- omlish/logs/filters.py +10 -0
- omlish/logs/handlers.py +4 -1
- omlish/logs/json.py +56 -0
- omlish/logs/proxy.py +99 -0
- omlish/logs/standard.py +128 -0
- omlish/logs/utils.py +2 -2
- omlish/manifests/__init__.py +2 -0
- omlish/manifests/load.py +209 -0
- omlish/manifests/types.py +17 -0
- omlish/marshal/base.py +1 -1
- omlish/marshal/factories.py +1 -1
- omlish/marshal/forbidden.py +1 -1
- omlish/marshal/iterables.py +1 -1
- omlish/marshal/literals.py +50 -0
- omlish/marshal/mappings.py +1 -1
- omlish/marshal/maybes.py +1 -1
- omlish/marshal/standard.py +5 -1
- omlish/marshal/unions.py +1 -1
- omlish/os/__init__.py +0 -0
- omlish/os/atomics.py +205 -0
- omlish/os/deathsig.py +23 -0
- omlish/{os.py → os/files.py} +0 -9
- omlish/{lite → os}/journald.py +2 -1
- omlish/os/linux.py +484 -0
- omlish/os/paths.py +36 -0
- omlish/{lite → os}/pidfile.py +1 -0
- omlish/os/sizes.py +9 -0
- omlish/reflect/__init__.py +3 -0
- omlish/reflect/subst.py +2 -1
- omlish/reflect/types.py +126 -44
- omlish/secrets/pwhash.py +1 -1
- omlish/secrets/subprocesses.py +3 -1
- omlish/specs/jsonrpc/marshal.py +1 -1
- omlish/specs/openapi/marshal.py +1 -1
- omlish/sql/alchemy/asyncs.py +1 -1
- omlish/sql/queries/__init__.py +9 -1
- omlish/sql/queries/building.py +3 -0
- omlish/sql/queries/exprs.py +10 -27
- omlish/sql/queries/idents.py +48 -10
- omlish/sql/queries/names.py +80 -13
- omlish/sql/queries/params.py +64 -0
- omlish/sql/queries/rendering.py +1 -1
- omlish/subprocesses.py +340 -0
- omlish/term.py +29 -14
- omlish/testing/pytest/marks.py +2 -2
- omlish/testing/pytest/plugins/asyncs.py +6 -1
- omlish/testing/pytest/plugins/logging.py +1 -1
- omlish/testing/pytest/plugins/switches.py +1 -1
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/METADATA +7 -5
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/RECORD +200 -117
- omlish/fnpairs.py +0 -496
- omlish/formats/json/cli/__main__.py +0 -11
- omlish/formats/json/cli/cli.py +0 -298
- omlish/formats/json/cli/formats.py +0 -71
- omlish/formats/json/cli/io.py +0 -74
- omlish/formats/json/cli/parsing.py +0 -82
- omlish/formats/json/cli/processing.py +0 -48
- omlish/formats/json/cli/rendering.py +0 -92
- omlish/iterators.py +0 -300
- omlish/lite/subprocesses.py +0 -130
- /omlish/{formats/json/cli → argparse}/__init__.py +0 -0
- /omlish/{lite/fdio → asyncs/asyncio}/__init__.py +0 -0
- /omlish/asyncs/{asyncio.py → asyncio/asyncio.py} +0 -0
- /omlish/{lite/http → asyncs/bluelet}/__init__.py +0 -0
- /omlish/collections/{_abc.py → abc.py} +0 -0
- /omlish/{fnpipes.py → funcs/pipes.py} +0 -0
- /omlish/io/{_abc.py → abc.py} +0 -0
- /omlish/sql/{_abc.py → abc.py} +0 -0
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/top_level.txt +0 -0
omlish/lite/inject.py
CHANGED
@@ -8,11 +8,7 @@ import types
|
|
8
8
|
import typing as ta
|
9
9
|
import weakref
|
10
10
|
|
11
|
-
from .check import
|
12
|
-
from .check import check_isinstance
|
13
|
-
from .check import check_not_in
|
14
|
-
from .check import check_not_isinstance
|
15
|
-
from .check import check_not_none
|
11
|
+
from .check import check
|
16
12
|
from .maybes import Maybe
|
17
13
|
from .reflect import get_optional_alias_arg
|
18
14
|
from .reflect import is_new_type
|
@@ -170,7 +166,7 @@ class FnInjectorProvider(InjectorProvider):
|
|
170
166
|
fn: ta.Any
|
171
167
|
|
172
168
|
def __post_init__(self) -> None:
|
173
|
-
|
169
|
+
check.not_isinstance(self.fn, type)
|
174
170
|
|
175
171
|
def provider_fn(self) -> InjectorProviderFn:
|
176
172
|
def pfn(i: Injector) -> ta.Any:
|
@@ -184,7 +180,7 @@ class CtorInjectorProvider(InjectorProvider):
|
|
184
180
|
cls_: type
|
185
181
|
|
186
182
|
def __post_init__(self) -> None:
|
187
|
-
|
183
|
+
check.isinstance(self.cls_, type)
|
188
184
|
|
189
185
|
def provider_fn(self) -> InjectorProviderFn:
|
190
186
|
def pfn(i: Injector) -> ta.Any:
|
@@ -206,7 +202,7 @@ class SingletonInjectorProvider(InjectorProvider):
|
|
206
202
|
p: InjectorProvider
|
207
203
|
|
208
204
|
def __post_init__(self) -> None:
|
209
|
-
|
205
|
+
check.isinstance(self.p, InjectorProvider)
|
210
206
|
|
211
207
|
def provider_fn(self) -> InjectorProviderFn:
|
212
208
|
v = not_set = object()
|
@@ -226,7 +222,7 @@ class LinkInjectorProvider(InjectorProvider):
|
|
226
222
|
k: InjectorKey
|
227
223
|
|
228
224
|
def __post_init__(self) -> None:
|
229
|
-
|
225
|
+
check.isinstance(self.k, InjectorKey)
|
230
226
|
|
231
227
|
def provider_fn(self) -> InjectorProviderFn:
|
232
228
|
def pfn(i: Injector) -> ta.Any:
|
@@ -423,7 +419,7 @@ def build_injection_kwargs_target(
|
|
423
419
|
|
424
420
|
skip_names: ta.Set[str] = set()
|
425
421
|
if skip_kwargs is not None:
|
426
|
-
skip_names.update(
|
422
|
+
skip_names.update(check.not_isinstance(skip_kwargs, str))
|
427
423
|
|
428
424
|
seen: ta.Set[InjectorKey] = set()
|
429
425
|
kws: ta.List[InjectionKwarg] = []
|
@@ -484,8 +480,8 @@ class _Injector(Injector):
|
|
484
480
|
def __init__(self, bs: InjectorBindings, p: ta.Optional[Injector] = None) -> None:
|
485
481
|
super().__init__()
|
486
482
|
|
487
|
-
self._bs =
|
488
|
-
self._p: ta.Optional[Injector] =
|
483
|
+
self._bs = check.isinstance(bs, InjectorBindings)
|
484
|
+
self._p: ta.Optional[Injector] = check.isinstance(p, (Injector, type(None)))
|
489
485
|
|
490
486
|
self._pfm = {k: v.provider_fn() for k, v in build_injector_provider_map(bs).items()}
|
491
487
|
|
@@ -516,8 +512,8 @@ class _Injector(Injector):
|
|
516
512
|
return Maybe.empty()
|
517
513
|
|
518
514
|
def handle_provision(self, key: InjectorKey, mv: Maybe) -> Maybe:
|
519
|
-
|
520
|
-
|
515
|
+
check.in_(key, self._seen_keys)
|
516
|
+
check.not_in(key, self._provisions)
|
521
517
|
self._provisions[key] = mv
|
522
518
|
return mv
|
523
519
|
|
@@ -614,7 +610,7 @@ class InjectorBinder:
|
|
614
610
|
def __new__(cls, *args, **kwargs): # noqa
|
615
611
|
raise TypeError
|
616
612
|
|
617
|
-
_FN_TYPES: ta.Tuple[type, ...] = (
|
613
|
+
_FN_TYPES: ta.ClassVar[ta.Tuple[type, ...]] = (
|
618
614
|
types.FunctionType,
|
619
615
|
types.MethodType,
|
620
616
|
|
@@ -631,12 +627,12 @@ class InjectorBinder:
|
|
631
627
|
|
632
628
|
@classmethod
|
633
629
|
def bind_as_fn(cls, icls: ta.Type[T]) -> ta.Type[T]:
|
634
|
-
|
630
|
+
check.isinstance(icls, type)
|
635
631
|
if icls not in cls._FN_TYPES:
|
636
632
|
cls._FN_TYPES = (*cls._FN_TYPES, icls)
|
637
633
|
return icls
|
638
634
|
|
639
|
-
_BANNED_BIND_TYPES: ta.Tuple[type, ...] = (
|
635
|
+
_BANNED_BIND_TYPES: ta.ClassVar[ta.Tuple[type, ...]] = (
|
640
636
|
InjectorProvider,
|
641
637
|
)
|
642
638
|
|
@@ -688,7 +684,7 @@ class InjectorBinder:
|
|
688
684
|
to_fn = obj
|
689
685
|
if key is None:
|
690
686
|
insp = _injection_inspect(obj)
|
691
|
-
key_cls: ta.Any = check_valid_injector_key_cls(
|
687
|
+
key_cls: ta.Any = check_valid_injector_key_cls(check.not_none(insp.type_hints.get('return')))
|
692
688
|
key = InjectorKey(key_cls)
|
693
689
|
else:
|
694
690
|
if to_const is not None:
|
@@ -815,45 +811,35 @@ def bind_injector_eager_key(key: ta.Any) -> InjectorBinding:
|
|
815
811
|
##
|
816
812
|
|
817
813
|
|
818
|
-
class
|
819
|
-
def __new__(cls, *args, **kwargs): # noqa
|
820
|
-
raise TypeError
|
821
|
-
|
814
|
+
class InjectionApi:
|
822
815
|
# keys
|
823
816
|
|
824
|
-
|
825
|
-
def as_key(cls, o: ta.Any) -> InjectorKey:
|
817
|
+
def as_key(self, o: ta.Any) -> InjectorKey:
|
826
818
|
return as_injector_key(o)
|
827
819
|
|
828
|
-
|
829
|
-
def array(cls, o: ta.Any) -> InjectorKey:
|
820
|
+
def array(self, o: ta.Any) -> InjectorKey:
|
830
821
|
return dc.replace(as_injector_key(o), array=True)
|
831
822
|
|
832
|
-
|
833
|
-
def tag(cls, o: ta.Any, t: ta.Any) -> InjectorKey:
|
823
|
+
def tag(self, o: ta.Any, t: ta.Any) -> InjectorKey:
|
834
824
|
return dc.replace(as_injector_key(o), tag=t)
|
835
825
|
|
836
826
|
# bindings
|
837
827
|
|
838
|
-
|
839
|
-
def as_bindings(cls, *args: InjectorBindingOrBindings) -> InjectorBindings:
|
828
|
+
def as_bindings(self, *args: InjectorBindingOrBindings) -> InjectorBindings:
|
840
829
|
return as_injector_bindings(*args)
|
841
830
|
|
842
|
-
|
843
|
-
def override(cls, p: InjectorBindings, *args: InjectorBindingOrBindings) -> InjectorBindings:
|
831
|
+
def override(self, p: InjectorBindings, *args: InjectorBindingOrBindings) -> InjectorBindings:
|
844
832
|
return injector_override(p, *args)
|
845
833
|
|
846
834
|
# injector
|
847
835
|
|
848
|
-
|
849
|
-
def create_injector(cls, *args: InjectorBindingOrBindings, parent: ta.Optional[Injector] = None) -> Injector:
|
836
|
+
def create_injector(self, *args: InjectorBindingOrBindings, parent: ta.Optional[Injector] = None) -> Injector:
|
850
837
|
return _Injector(as_injector_bindings(*args), parent)
|
851
838
|
|
852
839
|
# binder
|
853
840
|
|
854
|
-
@classmethod
|
855
841
|
def bind(
|
856
|
-
|
842
|
+
self,
|
857
843
|
obj: ta.Any,
|
858
844
|
*,
|
859
845
|
key: ta.Any = None,
|
@@ -888,32 +874,29 @@ class Injection:
|
|
888
874
|
|
889
875
|
# helpers
|
890
876
|
|
891
|
-
@classmethod
|
892
877
|
def bind_factory(
|
893
|
-
|
878
|
+
self,
|
894
879
|
fn: ta.Callable[..., T],
|
895
880
|
cls_: U,
|
896
881
|
ann: ta.Any = None,
|
897
882
|
) -> InjectorBindingOrBindings:
|
898
|
-
return
|
883
|
+
return self.bind(make_injector_factory(fn, cls_, ann))
|
899
884
|
|
900
|
-
@classmethod
|
901
885
|
def bind_array(
|
902
|
-
|
886
|
+
self,
|
903
887
|
obj: ta.Any = None,
|
904
888
|
*,
|
905
889
|
tag: ta.Any = None,
|
906
890
|
) -> InjectorBindingOrBindings:
|
907
891
|
return bind_injector_array(obj, tag=tag)
|
908
892
|
|
909
|
-
@classmethod
|
910
893
|
def bind_array_type(
|
911
|
-
|
894
|
+
self,
|
912
895
|
ele: ta.Union[InjectorKey, InjectorKeyCls],
|
913
896
|
cls_: U,
|
914
897
|
ann: ta.Any = None,
|
915
898
|
) -> InjectorBindingOrBindings:
|
916
|
-
return
|
899
|
+
return self.bind(make_injector_array_type(ele, cls_, ann))
|
917
900
|
|
918
901
|
|
919
|
-
inj =
|
902
|
+
inj = InjectionApi()
|
omlish/lite/logs.py
CHANGED
@@ -1,274 +1,4 @@
|
|
1
|
-
"""
|
2
|
-
TODO:
|
3
|
-
- translate json keys
|
4
|
-
- debug
|
5
|
-
"""
|
6
|
-
# ruff: noqa: UP006 UP007 N802
|
7
|
-
import contextlib
|
8
|
-
import datetime
|
9
1
|
import logging
|
10
|
-
import threading
|
11
|
-
import typing as ta
|
12
|
-
|
13
|
-
from .json import json_dumps_compact
|
14
2
|
|
15
3
|
|
16
4
|
log = logging.getLogger(__name__)
|
17
|
-
|
18
|
-
|
19
|
-
##
|
20
|
-
|
21
|
-
|
22
|
-
class TidLogFilter(logging.Filter):
|
23
|
-
|
24
|
-
def filter(self, record):
|
25
|
-
record.tid = threading.get_native_id()
|
26
|
-
return True
|
27
|
-
|
28
|
-
|
29
|
-
##
|
30
|
-
|
31
|
-
|
32
|
-
class JsonLogFormatter(logging.Formatter):
|
33
|
-
|
34
|
-
KEYS: ta.Mapping[str, bool] = {
|
35
|
-
'name': False,
|
36
|
-
'msg': False,
|
37
|
-
'args': False,
|
38
|
-
'levelname': False,
|
39
|
-
'levelno': False,
|
40
|
-
'pathname': False,
|
41
|
-
'filename': False,
|
42
|
-
'module': False,
|
43
|
-
'exc_info': True,
|
44
|
-
'exc_text': True,
|
45
|
-
'stack_info': True,
|
46
|
-
'lineno': False,
|
47
|
-
'funcName': False,
|
48
|
-
'created': False,
|
49
|
-
'msecs': False,
|
50
|
-
'relativeCreated': False,
|
51
|
-
'thread': False,
|
52
|
-
'threadName': False,
|
53
|
-
'processName': False,
|
54
|
-
'process': False,
|
55
|
-
}
|
56
|
-
|
57
|
-
def format(self, record: logging.LogRecord) -> str:
|
58
|
-
dct = {
|
59
|
-
k: v
|
60
|
-
for k, o in self.KEYS.items()
|
61
|
-
for v in [getattr(record, k)]
|
62
|
-
if not (o and v is None)
|
63
|
-
}
|
64
|
-
return json_dumps_compact(dct)
|
65
|
-
|
66
|
-
|
67
|
-
##
|
68
|
-
|
69
|
-
|
70
|
-
STANDARD_LOG_FORMAT_PARTS = [
|
71
|
-
('asctime', '%(asctime)-15s'),
|
72
|
-
('process', 'pid=%(process)-6s'),
|
73
|
-
('thread', 'tid=%(thread)x'),
|
74
|
-
('levelname', '%(levelname)s'),
|
75
|
-
('name', '%(name)s'),
|
76
|
-
('separator', '::'),
|
77
|
-
('message', '%(message)s'),
|
78
|
-
]
|
79
|
-
|
80
|
-
|
81
|
-
class StandardLogFormatter(logging.Formatter):
|
82
|
-
|
83
|
-
@staticmethod
|
84
|
-
def build_log_format(parts: ta.Iterable[ta.Tuple[str, str]]) -> str:
|
85
|
-
return ' '.join(v for k, v in parts)
|
86
|
-
|
87
|
-
converter = datetime.datetime.fromtimestamp # type: ignore
|
88
|
-
|
89
|
-
def formatTime(self, record, datefmt=None):
|
90
|
-
ct = self.converter(record.created) # type: ignore
|
91
|
-
if datefmt:
|
92
|
-
return ct.strftime(datefmt) # noqa
|
93
|
-
else:
|
94
|
-
t = ct.strftime('%Y-%m-%d %H:%M:%S')
|
95
|
-
return '%s.%03d' % (t, record.msecs) # noqa
|
96
|
-
|
97
|
-
|
98
|
-
##
|
99
|
-
|
100
|
-
|
101
|
-
class ProxyLogFilterer(logging.Filterer):
|
102
|
-
def __init__(self, underlying: logging.Filterer) -> None: # noqa
|
103
|
-
self._underlying = underlying
|
104
|
-
|
105
|
-
@property
|
106
|
-
def underlying(self) -> logging.Filterer:
|
107
|
-
return self._underlying
|
108
|
-
|
109
|
-
@property
|
110
|
-
def filters(self):
|
111
|
-
return self._underlying.filters
|
112
|
-
|
113
|
-
@filters.setter
|
114
|
-
def filters(self, filters):
|
115
|
-
self._underlying.filters = filters
|
116
|
-
|
117
|
-
def addFilter(self, filter): # noqa
|
118
|
-
self._underlying.addFilter(filter)
|
119
|
-
|
120
|
-
def removeFilter(self, filter): # noqa
|
121
|
-
self._underlying.removeFilter(filter)
|
122
|
-
|
123
|
-
def filter(self, record):
|
124
|
-
return self._underlying.filter(record)
|
125
|
-
|
126
|
-
|
127
|
-
class ProxyLogHandler(ProxyLogFilterer, logging.Handler):
|
128
|
-
def __init__(self, underlying: logging.Handler) -> None: # noqa
|
129
|
-
ProxyLogFilterer.__init__(self, underlying)
|
130
|
-
|
131
|
-
_underlying: logging.Handler
|
132
|
-
|
133
|
-
@property
|
134
|
-
def underlying(self) -> logging.Handler:
|
135
|
-
return self._underlying
|
136
|
-
|
137
|
-
def get_name(self):
|
138
|
-
return self._underlying.get_name()
|
139
|
-
|
140
|
-
def set_name(self, name):
|
141
|
-
self._underlying.set_name(name)
|
142
|
-
|
143
|
-
@property
|
144
|
-
def name(self):
|
145
|
-
return self._underlying.name
|
146
|
-
|
147
|
-
@property
|
148
|
-
def level(self):
|
149
|
-
return self._underlying.level
|
150
|
-
|
151
|
-
@level.setter
|
152
|
-
def level(self, level):
|
153
|
-
self._underlying.level = level
|
154
|
-
|
155
|
-
@property
|
156
|
-
def formatter(self):
|
157
|
-
return self._underlying.formatter
|
158
|
-
|
159
|
-
@formatter.setter
|
160
|
-
def formatter(self, formatter):
|
161
|
-
self._underlying.formatter = formatter
|
162
|
-
|
163
|
-
def createLock(self):
|
164
|
-
self._underlying.createLock()
|
165
|
-
|
166
|
-
def acquire(self):
|
167
|
-
self._underlying.acquire()
|
168
|
-
|
169
|
-
def release(self):
|
170
|
-
self._underlying.release()
|
171
|
-
|
172
|
-
def setLevel(self, level):
|
173
|
-
self._underlying.setLevel(level)
|
174
|
-
|
175
|
-
def format(self, record):
|
176
|
-
return self._underlying.format(record)
|
177
|
-
|
178
|
-
def emit(self, record):
|
179
|
-
self._underlying.emit(record)
|
180
|
-
|
181
|
-
def handle(self, record):
|
182
|
-
return self._underlying.handle(record)
|
183
|
-
|
184
|
-
def setFormatter(self, fmt):
|
185
|
-
self._underlying.setFormatter(fmt)
|
186
|
-
|
187
|
-
def flush(self):
|
188
|
-
self._underlying.flush()
|
189
|
-
|
190
|
-
def close(self):
|
191
|
-
self._underlying.close()
|
192
|
-
|
193
|
-
def handleError(self, record):
|
194
|
-
self._underlying.handleError(record)
|
195
|
-
|
196
|
-
|
197
|
-
##
|
198
|
-
|
199
|
-
|
200
|
-
class StandardLogHandler(ProxyLogHandler):
|
201
|
-
pass
|
202
|
-
|
203
|
-
|
204
|
-
##
|
205
|
-
|
206
|
-
|
207
|
-
@contextlib.contextmanager
|
208
|
-
def _locking_logging_module_lock() -> ta.Iterator[None]:
|
209
|
-
if hasattr(logging, '_acquireLock'):
|
210
|
-
logging._acquireLock() # noqa
|
211
|
-
try:
|
212
|
-
yield
|
213
|
-
finally:
|
214
|
-
logging._releaseLock() # type: ignore # noqa
|
215
|
-
|
216
|
-
elif hasattr(logging, '_lock'):
|
217
|
-
# https://github.com/python/cpython/commit/74723e11109a320e628898817ab449b3dad9ee96
|
218
|
-
with logging._lock: # noqa
|
219
|
-
yield
|
220
|
-
|
221
|
-
else:
|
222
|
-
raise Exception("Can't find lock in logging module")
|
223
|
-
|
224
|
-
|
225
|
-
def configure_standard_logging(
|
226
|
-
level: ta.Union[int, str] = logging.INFO,
|
227
|
-
*,
|
228
|
-
json: bool = False,
|
229
|
-
target: ta.Optional[logging.Logger] = None,
|
230
|
-
force: bool = False,
|
231
|
-
handler_factory: ta.Optional[ta.Callable[[], logging.Handler]] = None,
|
232
|
-
) -> ta.Optional[StandardLogHandler]:
|
233
|
-
with _locking_logging_module_lock():
|
234
|
-
if target is None:
|
235
|
-
target = logging.root
|
236
|
-
|
237
|
-
#
|
238
|
-
|
239
|
-
if not force:
|
240
|
-
if any(isinstance(h, StandardLogHandler) for h in list(target.handlers)):
|
241
|
-
return None
|
242
|
-
|
243
|
-
#
|
244
|
-
|
245
|
-
if handler_factory is not None:
|
246
|
-
handler = handler_factory()
|
247
|
-
else:
|
248
|
-
handler = logging.StreamHandler()
|
249
|
-
|
250
|
-
#
|
251
|
-
|
252
|
-
formatter: logging.Formatter
|
253
|
-
if json:
|
254
|
-
formatter = JsonLogFormatter()
|
255
|
-
else:
|
256
|
-
formatter = StandardLogFormatter(StandardLogFormatter.build_log_format(STANDARD_LOG_FORMAT_PARTS))
|
257
|
-
handler.setFormatter(formatter)
|
258
|
-
|
259
|
-
#
|
260
|
-
|
261
|
-
handler.addFilter(TidLogFilter())
|
262
|
-
|
263
|
-
#
|
264
|
-
|
265
|
-
target.addHandler(handler)
|
266
|
-
|
267
|
-
#
|
268
|
-
|
269
|
-
if level is not None:
|
270
|
-
target.setLevel(level)
|
271
|
-
|
272
|
-
#
|
273
|
-
|
274
|
-
return StandardLogHandler(handler)
|