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.
Files changed (210) hide show
  1. omlish/.manifests.json +265 -7
  2. omlish/__about__.py +5 -3
  3. omlish/antlr/_runtime/__init__.py +0 -22
  4. omlish/antlr/_runtime/_all.py +24 -0
  5. omlish/antlr/_runtime/atn/ParserATNSimulator.py +1 -1
  6. omlish/antlr/_runtime/dfa/DFASerializer.py +1 -1
  7. omlish/antlr/_runtime/error/DiagnosticErrorListener.py +2 -1
  8. omlish/antlr/_runtime/xpath/XPath.py +7 -1
  9. omlish/antlr/_runtime/xpath/XPathLexer.py +1 -1
  10. omlish/antlr/delimit.py +106 -0
  11. omlish/antlr/dot.py +31 -0
  12. omlish/antlr/errors.py +11 -0
  13. omlish/antlr/input.py +96 -0
  14. omlish/antlr/parsing.py +19 -0
  15. omlish/antlr/runtime.py +102 -0
  16. omlish/antlr/utils.py +38 -0
  17. omlish/argparse/all.py +45 -0
  18. omlish/{argparse.py → argparse/cli.py} +112 -107
  19. omlish/asyncs/__init__.py +0 -35
  20. omlish/asyncs/all.py +35 -0
  21. omlish/asyncs/asyncio/all.py +7 -0
  22. omlish/asyncs/asyncio/channels.py +40 -0
  23. omlish/asyncs/asyncio/streams.py +45 -0
  24. omlish/asyncs/asyncio/subprocesses.py +238 -0
  25. omlish/asyncs/asyncio/timeouts.py +16 -0
  26. omlish/asyncs/bluelet/LICENSE +6 -0
  27. omlish/asyncs/bluelet/all.py +67 -0
  28. omlish/asyncs/bluelet/api.py +23 -0
  29. omlish/asyncs/bluelet/core.py +178 -0
  30. omlish/asyncs/bluelet/events.py +78 -0
  31. omlish/asyncs/bluelet/files.py +80 -0
  32. omlish/asyncs/bluelet/runner.py +416 -0
  33. omlish/asyncs/bluelet/sockets.py +214 -0
  34. omlish/bootstrap/sys.py +3 -3
  35. omlish/cached.py +2 -2
  36. omlish/check.py +49 -460
  37. omlish/codecs/__init__.py +72 -0
  38. omlish/codecs/base.py +106 -0
  39. omlish/codecs/bytes.py +119 -0
  40. omlish/codecs/chain.py +23 -0
  41. omlish/codecs/funcs.py +39 -0
  42. omlish/codecs/registry.py +139 -0
  43. omlish/codecs/standard.py +4 -0
  44. omlish/codecs/text.py +217 -0
  45. omlish/collections/cache/impl.py +50 -57
  46. omlish/collections/coerce.py +1 -0
  47. omlish/collections/mappings.py +1 -1
  48. omlish/configs/flattening.py +1 -1
  49. omlish/defs.py +1 -1
  50. omlish/diag/_pycharm/runhack.py +8 -2
  51. omlish/diag/procfs.py +8 -8
  52. omlish/docker/__init__.py +0 -36
  53. omlish/docker/all.py +31 -0
  54. omlish/docker/consts.py +4 -0
  55. omlish/{lite/docker.py → docker/detect.py} +18 -0
  56. omlish/docker/{helpers.py → timebomb.py} +0 -21
  57. omlish/formats/cbor.py +31 -0
  58. omlish/formats/cloudpickle.py +31 -0
  59. omlish/formats/codecs.py +93 -0
  60. omlish/formats/json/codecs.py +29 -0
  61. omlish/formats/json/delimted.py +4 -0
  62. omlish/formats/json/stream/errors.py +2 -0
  63. omlish/formats/json/stream/lex.py +12 -6
  64. omlish/formats/json/stream/parse.py +38 -22
  65. omlish/formats/json5.py +31 -0
  66. omlish/formats/pickle.py +31 -0
  67. omlish/formats/repr.py +25 -0
  68. omlish/formats/toml.py +17 -0
  69. omlish/formats/yaml.py +25 -0
  70. omlish/funcs/__init__.py +0 -0
  71. omlish/{genmachine.py → funcs/genmachine.py} +5 -4
  72. omlish/{matchfns.py → funcs/match.py} +1 -1
  73. omlish/funcs/pairs.py +215 -0
  74. omlish/http/__init__.py +0 -48
  75. omlish/http/all.py +48 -0
  76. omlish/http/coro/__init__.py +0 -0
  77. omlish/{lite/fdio/corohttp.py → http/coro/fdio.py} +21 -19
  78. omlish/{lite/http/coroserver.py → http/coro/server.py} +20 -21
  79. omlish/{lite/http → http}/handlers.py +3 -2
  80. omlish/{lite/http → http}/parsing.py +1 -0
  81. omlish/http/sessions.py +1 -1
  82. omlish/{lite/http → http}/versions.py +1 -0
  83. omlish/inject/managed.py +2 -2
  84. omlish/io/__init__.py +0 -3
  85. omlish/{lite/io.py → io/buffers.py} +8 -9
  86. omlish/io/compress/__init__.py +9 -0
  87. omlish/io/compress/abc.py +104 -0
  88. omlish/io/compress/adapters.py +148 -0
  89. omlish/io/compress/base.py +24 -0
  90. omlish/io/compress/brotli.py +47 -0
  91. omlish/io/compress/bz2.py +61 -0
  92. omlish/io/compress/codecs.py +78 -0
  93. omlish/io/compress/gzip.py +350 -0
  94. omlish/io/compress/lz4.py +91 -0
  95. omlish/io/compress/lzma.py +81 -0
  96. omlish/io/compress/snappy.py +34 -0
  97. omlish/io/compress/zlib.py +74 -0
  98. omlish/io/compress/zstd.py +44 -0
  99. omlish/io/fdio/__init__.py +1 -0
  100. omlish/{lite → io}/fdio/handlers.py +5 -5
  101. omlish/{lite → io}/fdio/kqueue.py +8 -8
  102. omlish/{lite → io}/fdio/manager.py +7 -7
  103. omlish/{lite → io}/fdio/pollers.py +13 -13
  104. omlish/io/generators/__init__.py +56 -0
  105. omlish/io/generators/consts.py +1 -0
  106. omlish/io/generators/direct.py +13 -0
  107. omlish/io/generators/readers.py +189 -0
  108. omlish/io/generators/stepped.py +191 -0
  109. omlish/io/pyio.py +5 -2
  110. omlish/iterators/__init__.py +24 -0
  111. omlish/iterators/iterators.py +132 -0
  112. omlish/iterators/recipes.py +18 -0
  113. omlish/iterators/tools.py +96 -0
  114. omlish/iterators/unique.py +67 -0
  115. omlish/lang/__init__.py +13 -1
  116. omlish/lang/functions.py +11 -2
  117. omlish/lang/generators.py +243 -0
  118. omlish/lang/iterables.py +46 -49
  119. omlish/lang/maybes.py +4 -4
  120. omlish/lite/cached.py +39 -6
  121. omlish/lite/check.py +438 -75
  122. omlish/lite/contextmanagers.py +17 -4
  123. omlish/lite/dataclasses.py +42 -0
  124. omlish/lite/inject.py +28 -45
  125. omlish/lite/logs.py +0 -270
  126. omlish/lite/marshal.py +309 -144
  127. omlish/lite/pycharm.py +47 -0
  128. omlish/lite/reflect.py +33 -0
  129. omlish/lite/resources.py +8 -0
  130. omlish/lite/runtime.py +4 -4
  131. omlish/lite/shlex.py +12 -0
  132. omlish/lite/socketserver.py +2 -2
  133. omlish/lite/strings.py +31 -0
  134. omlish/logs/__init__.py +0 -32
  135. omlish/logs/{_abc.py → abc.py} +0 -1
  136. omlish/logs/all.py +37 -0
  137. omlish/logs/{formatters.py → color.py} +1 -2
  138. omlish/logs/configs.py +7 -38
  139. omlish/logs/filters.py +10 -0
  140. omlish/logs/handlers.py +4 -1
  141. omlish/logs/json.py +56 -0
  142. omlish/logs/proxy.py +99 -0
  143. omlish/logs/standard.py +128 -0
  144. omlish/logs/utils.py +2 -2
  145. omlish/manifests/__init__.py +2 -0
  146. omlish/manifests/load.py +209 -0
  147. omlish/manifests/types.py +17 -0
  148. omlish/marshal/base.py +1 -1
  149. omlish/marshal/factories.py +1 -1
  150. omlish/marshal/forbidden.py +1 -1
  151. omlish/marshal/iterables.py +1 -1
  152. omlish/marshal/literals.py +50 -0
  153. omlish/marshal/mappings.py +1 -1
  154. omlish/marshal/maybes.py +1 -1
  155. omlish/marshal/standard.py +5 -1
  156. omlish/marshal/unions.py +1 -1
  157. omlish/os/__init__.py +0 -0
  158. omlish/os/atomics.py +205 -0
  159. omlish/os/deathsig.py +23 -0
  160. omlish/{os.py → os/files.py} +0 -9
  161. omlish/{lite → os}/journald.py +2 -1
  162. omlish/os/linux.py +484 -0
  163. omlish/os/paths.py +36 -0
  164. omlish/{lite → os}/pidfile.py +1 -0
  165. omlish/os/sizes.py +9 -0
  166. omlish/reflect/__init__.py +3 -0
  167. omlish/reflect/subst.py +2 -1
  168. omlish/reflect/types.py +126 -44
  169. omlish/secrets/pwhash.py +1 -1
  170. omlish/secrets/subprocesses.py +3 -1
  171. omlish/specs/jsonrpc/marshal.py +1 -1
  172. omlish/specs/openapi/marshal.py +1 -1
  173. omlish/sql/alchemy/asyncs.py +1 -1
  174. omlish/sql/queries/__init__.py +9 -1
  175. omlish/sql/queries/building.py +3 -0
  176. omlish/sql/queries/exprs.py +10 -27
  177. omlish/sql/queries/idents.py +48 -10
  178. omlish/sql/queries/names.py +80 -13
  179. omlish/sql/queries/params.py +64 -0
  180. omlish/sql/queries/rendering.py +1 -1
  181. omlish/subprocesses.py +340 -0
  182. omlish/term.py +29 -14
  183. omlish/testing/pytest/marks.py +2 -2
  184. omlish/testing/pytest/plugins/asyncs.py +6 -1
  185. omlish/testing/pytest/plugins/logging.py +1 -1
  186. omlish/testing/pytest/plugins/switches.py +1 -1
  187. {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/METADATA +7 -5
  188. {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/RECORD +200 -117
  189. omlish/fnpairs.py +0 -496
  190. omlish/formats/json/cli/__main__.py +0 -11
  191. omlish/formats/json/cli/cli.py +0 -298
  192. omlish/formats/json/cli/formats.py +0 -71
  193. omlish/formats/json/cli/io.py +0 -74
  194. omlish/formats/json/cli/parsing.py +0 -82
  195. omlish/formats/json/cli/processing.py +0 -48
  196. omlish/formats/json/cli/rendering.py +0 -92
  197. omlish/iterators.py +0 -300
  198. omlish/lite/subprocesses.py +0 -130
  199. /omlish/{formats/json/cli → argparse}/__init__.py +0 -0
  200. /omlish/{lite/fdio → asyncs/asyncio}/__init__.py +0 -0
  201. /omlish/asyncs/{asyncio.py → asyncio/asyncio.py} +0 -0
  202. /omlish/{lite/http → asyncs/bluelet}/__init__.py +0 -0
  203. /omlish/collections/{_abc.py → abc.py} +0 -0
  204. /omlish/{fnpipes.py → funcs/pipes.py} +0 -0
  205. /omlish/io/{_abc.py → abc.py} +0 -0
  206. /omlish/sql/{_abc.py → abc.py} +0 -0
  207. {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/LICENSE +0 -0
  208. {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/WHEEL +0 -0
  209. {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/entry_points.txt +0 -0
  210. {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 check_in
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
- check_not_isinstance(self.fn, type)
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
- check_isinstance(self.cls_, type)
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
- check_isinstance(self.p, InjectorProvider)
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
- check_isinstance(self.k, InjectorKey)
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(check_not_isinstance(skip_kwargs, str))
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 = check_isinstance(bs, InjectorBindings)
488
- self._p: ta.Optional[Injector] = check_isinstance(p, (Injector, type(None)))
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
- check_in(key, self._seen_keys)
520
- check_not_in(key, self._provisions)
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
- check_isinstance(icls, type)
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(check_not_none(insp.type_hints.get('return')))
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 Injection:
819
- def __new__(cls, *args, **kwargs): # noqa
820
- raise TypeError
821
-
814
+ class InjectionApi:
822
815
  # keys
823
816
 
824
- @classmethod
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
- @classmethod
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
- @classmethod
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
- @classmethod
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
- @classmethod
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
- @classmethod
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
- cls,
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
- cls,
878
+ self,
894
879
  fn: ta.Callable[..., T],
895
880
  cls_: U,
896
881
  ann: ta.Any = None,
897
882
  ) -> InjectorBindingOrBindings:
898
- return cls.bind(make_injector_factory(fn, cls_, ann))
883
+ return self.bind(make_injector_factory(fn, cls_, ann))
899
884
 
900
- @classmethod
901
885
  def bind_array(
902
- cls,
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
- cls,
894
+ self,
912
895
  ele: ta.Union[InjectorKey, InjectorKeyCls],
913
896
  cls_: U,
914
897
  ann: ta.Any = None,
915
898
  ) -> InjectorBindingOrBindings:
916
- return cls.bind(make_injector_array_type(ele, cls_, ann))
899
+ return self.bind(make_injector_array_type(ele, cls_, ann))
917
900
 
918
901
 
919
- inj = Injection
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)