omlish 0.0.0.dev133__py3-none-any.whl → 0.0.0.dev177__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|