omdev 0.0.0.dev486__py3-none-any.whl → 0.0.0.dev506__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 omdev might be problematic. Click here for more details.

Files changed (50) hide show
  1. omdev/.omlish-manifests.json +2 -2
  2. omdev/README.md +51 -0
  3. omdev/__about__.py +4 -2
  4. omdev/ci/cli.py +1 -1
  5. omdev/cli/clicli.py +37 -7
  6. omdev/dataclasses/cli.py +1 -1
  7. omdev/interp/cli.py +1 -1
  8. omdev/interp/types.py +3 -2
  9. omdev/interp/uv/provider.py +36 -0
  10. omdev/manifests/main.py +1 -1
  11. omdev/markdown/incparse.py +392 -0
  12. omdev/packaging/revisions.py +1 -1
  13. omdev/py/tools/pipdepup.py +150 -93
  14. omdev/pyproject/cli.py +2 -36
  15. omdev/pyproject/configs.py +1 -1
  16. omdev/pyproject/pkg.py +1 -1
  17. omdev/pyproject/reqs.py +8 -7
  18. omdev/pyproject/tools/aboutdeps.py +5 -0
  19. omdev/pyproject/tools/pyversions.py +47 -0
  20. omdev/pyproject/versions.py +40 -0
  21. omdev/scripts/ci.py +369 -26
  22. omdev/scripts/interp.py +51 -9
  23. omdev/scripts/lib/inject.py +8 -1
  24. omdev/scripts/lib/logs.py +117 -21
  25. omdev/scripts/pyproject.py +479 -76
  26. omdev/tools/git/cli.py +43 -13
  27. omdev/tools/json/formats.py +2 -0
  28. omdev/tools/jsonview/cli.py +19 -61
  29. omdev/tools/jsonview/resources/jsonview.html.j2 +43 -0
  30. omdev/tools/pawk/README.md +195 -0
  31. omdev/tools/sqlrepl.py +189 -78
  32. omdev/tui/apps/edit/main.py +5 -1
  33. omdev/tui/apps/irc/app.py +28 -20
  34. omdev/tui/apps/irc/commands.py +1 -1
  35. omdev/tui/rich/__init__.py +12 -0
  36. omdev/tui/rich/markdown2.py +219 -18
  37. omdev/tui/textual/__init__.py +41 -2
  38. omdev/tui/textual/app2.py +6 -1
  39. omdev/tui/textual/debug/__init__.py +10 -0
  40. omdev/tui/textual/debug/dominfo.py +151 -0
  41. omdev/tui/textual/debug/screen.py +24 -0
  42. omdev/tui/textual/devtools.py +187 -0
  43. omdev/tui/textual/logging2.py +20 -0
  44. omdev/tui/textual/types.py +45 -0
  45. {omdev-0.0.0.dev486.dist-info → omdev-0.0.0.dev506.dist-info}/METADATA +10 -6
  46. {omdev-0.0.0.dev486.dist-info → omdev-0.0.0.dev506.dist-info}/RECORD +50 -39
  47. {omdev-0.0.0.dev486.dist-info → omdev-0.0.0.dev506.dist-info}/WHEEL +0 -0
  48. {omdev-0.0.0.dev486.dist-info → omdev-0.0.0.dev506.dist-info}/entry_points.txt +0 -0
  49. {omdev-0.0.0.dev486.dist-info → omdev-0.0.0.dev506.dist-info}/licenses/LICENSE +0 -0
  50. {omdev-0.0.0.dev486.dist-info → omdev-0.0.0.dev506.dist-info}/top_level.txt +0 -0
omdev/scripts/ci.py CHANGED
@@ -97,6 +97,7 @@ def __omlish_amalg__(): # noqa
97
97
  dict(path='../../omlish/http/urllib.py', sha1='25431c5bdc7dd5cbecfcb8c0bdffaabf8c1691b9'),
98
98
  dict(path='../../omlish/http/versions.py', sha1='197685ffbb62a457a0e8d4047a9df26aebd7dae4'),
99
99
  dict(path='../../omlish/lite/abstract.py', sha1='a2fc3f3697fa8de5247761e9d554e70176f37aac'),
100
+ dict(path='../../omlish/lite/asyncs.py', sha1='b3f2251c56617ce548abf9c333ac996b63edb23e'),
100
101
  dict(path='../../omlish/lite/cached.py', sha1='0c33cf961ac8f0727284303c7a30c5ea98f714f2'),
101
102
  dict(path='../../omlish/lite/check.py', sha1='bb6b6b63333699b84462951a854d99ae83195b94'),
102
103
  dict(path='../../omlish/lite/contextmanagers.py', sha1='993f5ed96d3410f739a20363f55670d5e5267fa3'),
@@ -124,7 +125,7 @@ def __omlish_amalg__(): # noqa
124
125
  dict(path='../../omlish/http/coro/io.py', sha1='2cdf6529c37a37cc0c1db2e02032157cf906d5d6'),
125
126
  dict(path='../../omlish/http/parsing.py', sha1='3fea28dc6341908ba7c8fad42bf7bbe711f21b82'),
126
127
  dict(path='../../omlish/lite/marshal.py', sha1='96348f5f2a26dc27d842d33cc3927e9da163436b'),
127
- dict(path='../../omlish/lite/maybes.py', sha1='bdf5136654ccd14b6a072588cad228925bdfbabd'),
128
+ dict(path='../../omlish/lite/maybes.py', sha1='04d2fcbea17028a5e6b8e7a7fb742375495ed233'),
128
129
  dict(path='../../omlish/lite/runtime.py', sha1='2e752a27ae2bf89b1bb79b4a2da522a3ec360c70'),
129
130
  dict(path='../../omlish/lite/timeouts.py', sha1='a0f673033a6943f242e35848d78a41892b9c62a1'),
130
131
  dict(path='../../omlish/logs/infos.py', sha1='4dd104bd468a8c438601dd0bbda619b47d2f1620'),
@@ -142,9 +143,9 @@ def __omlish_amalg__(): # noqa
142
143
  dict(path='../../omlish/asyncs/asyncio/timeouts.py', sha1='4d31b02b3c39b8f2fa7e94db36552fde6942e36a'),
143
144
  dict(path='../../omlish/http/handlers.py', sha1='40629060bac22ea5e94b720b57001861a4ec9031'),
144
145
  dict(path='../../omlish/lite/inject.py', sha1='6f097e3170019a34ff6834d36fcc9cbeed3a7ab4'),
145
- dict(path='../../omlish/logs/contexts.py', sha1='7456964ade9ac66460e9ade4e242dbdc24b39501'),
146
- dict(path='../../omlish/logs/standard.py', sha1='818b674f7d15012f25b79f52f6e8e7368b633038'),
147
- dict(path='../../omlish/logs/utils.py', sha1='8430cddbb7de34afb2793ab8a0cc6fbee47fef2c'),
146
+ dict(path='../../omlish/logs/contexts.py', sha1='1000a6d5ddfb642865ca532e34b1d50759781cf0'),
147
+ dict(path='../../omlish/logs/std/standard.py', sha1='5c97c1b9f7ead58d6127d047b873398f708f288d'),
148
+ dict(path='../../omlish/logs/utils.py', sha1='39599f5e9d9911a06eac6e0d7e5116fdc69b1263'),
148
149
  dict(path='../../omlish/sockets/server/handlers.py', sha1='6f9adca9fa04774a28a488a4e2a11bb4492c71d0'),
149
150
  dict(path='../../omlish/subprocesses/run.py', sha1='8200e48f0c49d164df3503cd0143038d0c4d30aa'),
150
151
  dict(path='../../omlish/subprocesses/wrap.py', sha1='8a9b7d2255481fae15c05f5624b0cdc0766f4b3f'),
@@ -153,7 +154,7 @@ def __omlish_amalg__(): # noqa
153
154
  dict(path='../oci/media.py', sha1='a20324c5b0661c9a9a7679406d019ab3ba4acd98'),
154
155
  dict(path='../oci/pack/packing.py', sha1='7585c3dea6b8a62b6ca63fe78968497db915ea57'),
155
156
  dict(path='../../omlish/http/coro/server/server.py', sha1='c0a980afa8346dbc20570acddb2b3b579bfc1ce0'),
156
- dict(path='../../omlish/logs/base.py', sha1='a376460b11b9dc0555fd4ead5437af62c2109a4b'),
157
+ dict(path='../../omlish/logs/base.py', sha1='8d06faee05fead6b1dd98c9035a5b042af4aebb1'),
157
158
  dict(path='../../omlish/logs/std/records.py', sha1='8bbf6ef9eccb3a012c6ca416ddf3969450fd8fc9'),
158
159
  dict(path='../../omlish/secrets/tempssl.py', sha1='360d4cd98483357bcf013e156dafd92fd37ed220'),
159
160
  dict(path='../../omlish/sockets/server/server.py', sha1='a93a74f6beb38d69e0fb9047c932f2a95aa37eca'),
@@ -165,7 +166,8 @@ def __omlish_amalg__(): # noqa
165
166
  dict(path='../oci/building.py', sha1='b4fea06c03ba02d3ecfc6d10d955dc76f263846a'),
166
167
  dict(path='../oci/loading.py', sha1='64d806ffad8d24087ccc29f759f672e6d795bee2'),
167
168
  dict(path='../../omlish/http/coro/server/sockets.py', sha1='40ef4aa43f94f1a1a2a431a012cb961f25905ff4'),
168
- dict(path='../../omlish/logs/std/loggers.py', sha1='daa35bdc4adea5006e442688017f0de3392579b7'),
169
+ dict(path='../../omlish/logs/asyncs.py', sha1='ab11b70033d9f2e9a4e70254185aa1c6130c6077'),
170
+ dict(path='../../omlish/logs/std/loggers.py', sha1='a569179445d6a8a942b5dcfad1d1f77702868803'),
169
171
  dict(path='../../omlish/subprocesses/asyncs.py', sha1='bba44d524c24c6ac73168aee6343488414e5bf48'),
170
172
  dict(path='../../omlish/subprocesses/sync.py', sha1='8434919eba4da67825773d56918fdc0cb2f1883b'),
171
173
  dict(path='requirements.py', sha1='c370a65958a00412e00608a0e1f12795e276aee1'),
@@ -173,7 +175,7 @@ def __omlish_amalg__(): # noqa
173
175
  dict(path='../oci/dataserver.py', sha1='dd147b56282b054cef264556a0ff3b3d1719bcee'),
174
176
  dict(path='../../omlish/asyncs/asyncio/subprocesses.py', sha1='b6b5f9ae3fd0b9c83593bad2e04a08f726e5904d'),
175
177
  dict(path='../../omlish/http/coro/server/simple.py', sha1='2332079fe29993123c68d7dbc266b47cd44cd6a6'),
176
- dict(path='../../omlish/logs/modules.py', sha1='99e73cde6872fd5eda6af3dbf0fc9322bdeb641a'),
178
+ dict(path='../../omlish/logs/modules.py', sha1='dd7d5f8e63fe8829dfb49460f3929ab64b68ee14'),
177
179
  dict(path='cache.py', sha1='9353e5c3b73bed47258680fd15ac49417113f0ca'),
178
180
  dict(path='compose.py', sha1='d2bec1385701979c7ff9913456b72d8c7b31f70b'),
179
181
  dict(path='docker/cmds.py', sha1='5528c384f68f9003732bfaf6be302e84747909dd'),
@@ -195,7 +197,7 @@ def __omlish_amalg__(): # noqa
195
197
  dict(path='github/cli.py', sha1='6d14b0eb4ca5f606ad2821b63b9707ce57f50406'),
196
198
  dict(path='github/inject.py', sha1='99c0dd7c55767e7c49f70b7edac25da67f718b2e'),
197
199
  dict(path='inject.py', sha1='e86b16d79a113a4f387e68ed0db1d067bcada93a'),
198
- dict(path='cli.py', sha1='49bcd482bd814ba436237099b4bdb62f77d6c054'),
200
+ dict(path='cli.py', sha1='92948cf3ec76fd9ceb25762aadbf497354adce6d'),
199
201
  ],
200
202
  )
201
203
 
@@ -759,6 +761,150 @@ class Abstract:
759
761
  update_abstracts(cls, force=True)
760
762
 
761
763
 
764
+ ########################################
765
+ # ../../../omlish/lite/asyncs.py
766
+
767
+
768
+ ##
769
+
770
+
771
+ async def opt_await(aw: ta.Optional[ta.Awaitable[T]]) -> ta.Optional[T]:
772
+ return (await aw if aw is not None else None)
773
+
774
+
775
+ async def async_list(ai: ta.AsyncIterable[T]) -> ta.List[T]:
776
+ return [v async for v in ai]
777
+
778
+
779
+ async def async_enumerate(ai: ta.AsyncIterable[T]) -> ta.AsyncIterable[ta.Tuple[int, T]]:
780
+ i = 0
781
+ async for e in ai:
782
+ yield (i, e)
783
+ i += 1
784
+
785
+
786
+ ##
787
+
788
+
789
+ def as_async(fn: ta.Callable[..., T], *, wrap: bool = False) -> ta.Callable[..., ta.Awaitable[T]]:
790
+ async def inner(*args, **kwargs):
791
+ return fn(*args, **kwargs)
792
+
793
+ return functools.wraps(fn)(inner) if wrap else inner
794
+
795
+
796
+ ##
797
+
798
+
799
+ class SyncAwaitCoroutineNotTerminatedError(Exception):
800
+ pass
801
+
802
+
803
+ def sync_await(aw: ta.Awaitable[T]) -> T:
804
+ """
805
+ Allows for the synchronous execution of async functions which will never actually *externally* await anything. These
806
+ functions are allowed to await any number of other functions - including contextmanagers and generators - so long as
807
+ nothing ever actually 'leaks' out of the function, presumably to an event loop.
808
+ """
809
+
810
+ ret = missing = object()
811
+
812
+ async def thunk():
813
+ nonlocal ret
814
+
815
+ ret = await aw
816
+
817
+ cr = thunk()
818
+ try:
819
+ try:
820
+ cr.send(None)
821
+ except StopIteration:
822
+ pass
823
+
824
+ if ret is missing or cr.cr_await is not None or cr.cr_running:
825
+ raise SyncAwaitCoroutineNotTerminatedError('Not terminated')
826
+
827
+ finally:
828
+ cr.close()
829
+
830
+ return ta.cast(T, ret)
831
+
832
+
833
+ #
834
+
835
+
836
+ def sync_aiter(ai: ta.AsyncIterator[T]) -> ta.Iterator[T]:
837
+ while True:
838
+ try:
839
+ o = sync_await(ai.__anext__())
840
+ except StopAsyncIteration:
841
+ break
842
+ yield o
843
+
844
+
845
+ def sync_async_list(ai: ta.AsyncIterable[T]) -> ta.List[T]:
846
+ """
847
+ Uses `sync_await` to synchronously read the full contents of a function call returning an async iterator, given that
848
+ the function never externally awaits anything.
849
+ """
850
+
851
+ lst: ta.Optional[ta.List[T]] = None
852
+
853
+ async def inner():
854
+ nonlocal lst
855
+
856
+ lst = [v async for v in ai]
857
+
858
+ sync_await(inner())
859
+
860
+ if not isinstance(lst, list):
861
+ raise TypeError(lst)
862
+
863
+ return lst
864
+
865
+
866
+ #
867
+
868
+
869
+ @ta.final
870
+ class SyncAwaitContextManager(ta.Generic[T]):
871
+ def __init__(self, acm: ta.AsyncContextManager[T]) -> None:
872
+ self._acm = acm
873
+
874
+ def __repr__(self) -> str:
875
+ return f'{self.__class__.__name__}({self._acm!r})'
876
+
877
+ def __enter__(self) -> T:
878
+ return sync_await(self._acm.__aenter__())
879
+
880
+ def __exit__(self, exc_type, exc_val, exc_tb):
881
+ return sync_await(self._acm.__aexit__(exc_type, exc_val, exc_tb))
882
+
883
+
884
+ sync_async_with = SyncAwaitContextManager
885
+
886
+
887
+ ##
888
+
889
+
890
+ @ta.final
891
+ class SyncToAsyncContextManager(ta.Generic[T]):
892
+ def __init__(self, cm: ta.ContextManager[T]) -> None:
893
+ self._cm = cm
894
+
895
+ def __repr__(self) -> str:
896
+ return f'{self.__class__.__name__}({self._cm!r})'
897
+
898
+ async def __aenter__(self) -> T:
899
+ return self._cm.__enter__()
900
+
901
+ async def __aexit__(self, exc_type, exc_value, traceback, /):
902
+ return self._cm.__exit__(exc_type, exc_value, traceback)
903
+
904
+
905
+ as_async_context_manager = SyncToAsyncContextManager
906
+
907
+
762
908
  ########################################
763
909
  # ../../../omlish/lite/cached.py
764
910
 
@@ -4869,6 +5015,13 @@ class Maybe(ta.Generic[T]):
4869
5015
  else:
4870
5016
  return other
4871
5017
 
5018
+ @ta.final
5019
+ def or_none(self) -> ta.Optional[T]:
5020
+ if self.present:
5021
+ return self.must()
5022
+ else:
5023
+ return None
5024
+
4872
5025
  @ta.final
4873
5026
  def or_else_get(self, supplier: ta.Callable[[], ta.Union[T, U]]) -> ta.Union[T, U]:
4874
5027
  if self.present:
@@ -8081,6 +8234,9 @@ class CaptureLoggingContextImpl(CaptureLoggingContext):
8081
8234
  self._infos[type(info)] = info
8082
8235
  return self
8083
8236
 
8237
+ def get_infos(self) -> ta.Mapping[ta.Type[LoggingContextInfo], LoggingContextInfo]:
8238
+ return self._infos
8239
+
8084
8240
  def get_info(self, ty: ta.Type[LoggingContextInfoT]) -> ta.Optional[LoggingContextInfoT]:
8085
8241
  return self._infos.get(ty)
8086
8242
 
@@ -8103,7 +8259,7 @@ class CaptureLoggingContextImpl(CaptureLoggingContext):
8103
8259
  _stack_offset: int
8104
8260
  _stack_info: bool
8105
8261
 
8106
- def inc_stack_offset(self, ofs: int = 1) -> 'CaptureLoggingContext':
8262
+ def inc_stack_offset(self, ofs: int = 1) -> 'CaptureLoggingContextImpl':
8107
8263
  if hasattr(self, '_stack_offset'):
8108
8264
  self._stack_offset += ofs
8109
8265
  return self
@@ -8135,10 +8291,9 @@ class CaptureLoggingContextImpl(CaptureLoggingContext):
8135
8291
 
8136
8292
 
8137
8293
  ########################################
8138
- # ../../../omlish/logs/standard.py
8294
+ # ../../../omlish/logs/std/standard.py
8139
8295
  """
8140
8296
  TODO:
8141
- - !! move to std !!
8142
8297
  - structured
8143
8298
  - prefixed
8144
8299
  - debug
@@ -8274,7 +8429,7 @@ def exception_logging(log): # noqa
8274
8429
  def inner(*args, **kwargs):
8275
8430
  try:
8276
8431
  return fn(*args, **kwargs)
8277
- except Exception:
8432
+ except Exception as e: # noqa
8278
8433
  log.exception('Error in %r', fn)
8279
8434
  raise
8280
8435
 
@@ -8283,6 +8438,21 @@ def exception_logging(log): # noqa
8283
8438
  return outer
8284
8439
 
8285
8440
 
8441
+ def async_exception_logging(alog): # noqa
8442
+ def outer(fn):
8443
+ @functools.wraps(fn)
8444
+ async def inner(*args, **kwargs):
8445
+ try:
8446
+ return await fn(*args, **kwargs)
8447
+ except Exception as e: # noqa
8448
+ await alog.exception('Error in %r', fn)
8449
+ raise
8450
+
8451
+ return inner
8452
+
8453
+ return outer
8454
+
8455
+
8286
8456
  ##
8287
8457
 
8288
8458
 
@@ -9799,6 +9969,11 @@ class AnyLogger(Abstract, ta.Generic[T]):
9799
9969
 
9800
9970
  ##
9801
9971
 
9972
+ # This will be 1 for [Sync]Logger and 0 for AsyncLogger - in sync loggers these methods remain present on the stack,
9973
+ # in async loggers they return a coroutine to be awaited and thus aren't actually present when said coroutine is
9974
+ # awaited.
9975
+ _level_proxy_method_stack_offset: int
9976
+
9802
9977
  @ta.overload
9803
9978
  def log(self, level: LogLevel, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
9804
9979
  ...
@@ -9813,7 +9988,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
9813
9988
 
9814
9989
  @ta.final
9815
9990
  def log(self, level: LogLevel, *args, **kwargs):
9816
- return self._log(CaptureLoggingContextImpl(level, stack_offset=1), *args, **kwargs)
9991
+ return self._log(
9992
+ CaptureLoggingContextImpl(
9993
+ level,
9994
+ stack_offset=self._level_proxy_method_stack_offset,
9995
+ ),
9996
+ *args,
9997
+ **kwargs,
9998
+ )
9817
9999
 
9818
10000
  #
9819
10001
 
@@ -9831,7 +10013,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
9831
10013
 
9832
10014
  @ta.final
9833
10015
  def debug(self, *args, **kwargs):
9834
- return self._log(CaptureLoggingContextImpl(NamedLogLevel.DEBUG, stack_offset=1), *args, **kwargs)
10016
+ return self._log(
10017
+ CaptureLoggingContextImpl(
10018
+ NamedLogLevel.DEBUG,
10019
+ stack_offset=self._level_proxy_method_stack_offset,
10020
+ ),
10021
+ *args,
10022
+ **kwargs,
10023
+ )
9835
10024
 
9836
10025
  #
9837
10026
 
@@ -9849,7 +10038,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
9849
10038
 
9850
10039
  @ta.final
9851
10040
  def info(self, *args, **kwargs):
9852
- return self._log(CaptureLoggingContextImpl(NamedLogLevel.INFO, stack_offset=1), *args, **kwargs)
10041
+ return self._log(
10042
+ CaptureLoggingContextImpl(
10043
+ NamedLogLevel.INFO,
10044
+ stack_offset=self._level_proxy_method_stack_offset,
10045
+ ),
10046
+ *args,
10047
+ **kwargs,
10048
+ )
9853
10049
 
9854
10050
  #
9855
10051
 
@@ -9867,7 +10063,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
9867
10063
 
9868
10064
  @ta.final
9869
10065
  def warning(self, *args, **kwargs):
9870
- return self._log(CaptureLoggingContextImpl(NamedLogLevel.WARNING, stack_offset=1), *args, **kwargs)
10066
+ return self._log(
10067
+ CaptureLoggingContextImpl(
10068
+ NamedLogLevel.WARNING,
10069
+ stack_offset=self._level_proxy_method_stack_offset,
10070
+ ),
10071
+ *args,
10072
+ **kwargs,
10073
+ )
9871
10074
 
9872
10075
  #
9873
10076
 
@@ -9885,7 +10088,14 @@ class AnyLogger(Abstract, ta.Generic[T]):
9885
10088
 
9886
10089
  @ta.final
9887
10090
  def error(self, *args, **kwargs):
9888
- return self._log(CaptureLoggingContextImpl(NamedLogLevel.ERROR, stack_offset=1), *args, **kwargs)
10091
+ return self._log(
10092
+ CaptureLoggingContextImpl(
10093
+ NamedLogLevel.ERROR,
10094
+ stack_offset=self._level_proxy_method_stack_offset,
10095
+ ),
10096
+ *args,
10097
+ **kwargs,
10098
+ )
9889
10099
 
9890
10100
  #
9891
10101
 
@@ -9903,7 +10113,15 @@ class AnyLogger(Abstract, ta.Generic[T]):
9903
10113
 
9904
10114
  @ta.final
9905
10115
  def exception(self, *args, exc_info: LoggingExcInfoArg = True, **kwargs):
9906
- return self._log(CaptureLoggingContextImpl(NamedLogLevel.ERROR, exc_info=exc_info, stack_offset=1), *args, **kwargs) # noqa
10116
+ return self._log(
10117
+ CaptureLoggingContextImpl(
10118
+ NamedLogLevel.ERROR,
10119
+ exc_info=exc_info,
10120
+ stack_offset=self._level_proxy_method_stack_offset,
10121
+ ),
10122
+ *args,
10123
+ **kwargs,
10124
+ )
9907
10125
 
9908
10126
  #
9909
10127
 
@@ -9921,24 +10139,53 @@ class AnyLogger(Abstract, ta.Generic[T]):
9921
10139
 
9922
10140
  @ta.final
9923
10141
  def critical(self, *args, **kwargs):
9924
- return self._log(CaptureLoggingContextImpl(NamedLogLevel.CRITICAL, stack_offset=1), *args, **kwargs)
10142
+ return self._log(
10143
+ CaptureLoggingContextImpl(
10144
+ NamedLogLevel.CRITICAL,
10145
+ stack_offset=self._level_proxy_method_stack_offset,
10146
+ ),
10147
+ *args,
10148
+ **kwargs,
10149
+ )
9925
10150
 
9926
10151
  ##
9927
10152
 
9928
10153
  @abc.abstractmethod
9929
- def _log(self, ctx: CaptureLoggingContext, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any, **kwargs: ta.Any) -> T: # noqa
10154
+ def _log(
10155
+ self,
10156
+ ctx: CaptureLoggingContext,
10157
+ msg: ta.Union[str, tuple, LoggingMsgFn],
10158
+ *args: ta.Any,
10159
+ **kwargs: ta.Any,
10160
+ ) -> T:
9930
10161
  raise NotImplementedError
9931
10162
 
9932
10163
 
9933
10164
  class Logger(AnyLogger[None], Abstract):
10165
+ _level_proxy_method_stack_offset: int = 1
10166
+
9934
10167
  @abc.abstractmethod
9935
- def _log(self, ctx: CaptureLoggingContext, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any, **kwargs: ta.Any) -> None: # noqa
10168
+ def _log(
10169
+ self,
10170
+ ctx: CaptureLoggingContext,
10171
+ msg: ta.Union[str, tuple, LoggingMsgFn],
10172
+ *args: ta.Any,
10173
+ **kwargs: ta.Any,
10174
+ ) -> None:
9936
10175
  raise NotImplementedError
9937
10176
 
9938
10177
 
9939
10178
  class AsyncLogger(AnyLogger[ta.Awaitable[None]], Abstract):
10179
+ _level_proxy_method_stack_offset: int = 0
10180
+
9940
10181
  @abc.abstractmethod
9941
- def _log(self, ctx: CaptureLoggingContext, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any, **kwargs: ta.Any) -> ta.Awaitable[None]: # noqa
10182
+ def _log(
10183
+ self,
10184
+ ctx: CaptureLoggingContext,
10185
+ msg: ta.Union[str, tuple, LoggingMsgFn],
10186
+ *args: ta.Any,
10187
+ **kwargs: ta.Any,
10188
+ ) -> ta.Awaitable[None]:
9942
10189
  raise NotImplementedError
9943
10190
 
9944
10191
 
@@ -9953,13 +10200,25 @@ class AnyNopLogger(AnyLogger[T], Abstract):
9953
10200
 
9954
10201
  @ta.final
9955
10202
  class NopLogger(AnyNopLogger[None], Logger):
9956
- def _log(self, ctx: CaptureLoggingContext, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any, **kwargs: ta.Any) -> None: # noqa
10203
+ def _log(
10204
+ self,
10205
+ ctx: CaptureLoggingContext,
10206
+ msg: ta.Union[str, tuple, LoggingMsgFn],
10207
+ *args: ta.Any,
10208
+ **kwargs: ta.Any,
10209
+ ) -> None:
9957
10210
  pass
9958
10211
 
9959
10212
 
9960
10213
  @ta.final
9961
10214
  class AsyncNopLogger(AnyNopLogger[ta.Awaitable[None]], AsyncLogger):
9962
- async def _log(self, ctx: CaptureLoggingContext, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any, **kwargs: ta.Any) -> None: # noqa
10215
+ async def _log(
10216
+ self,
10217
+ ctx: CaptureLoggingContext,
10218
+ msg: ta.Union[str, tuple, LoggingMsgFn],
10219
+ *args: ta.Any,
10220
+ **kwargs: ta.Any,
10221
+ ) -> None:
9963
10222
  pass
9964
10223
 
9965
10224
 
@@ -11818,6 +12077,70 @@ class CoroHttpServerSocketHandler(SocketHandler_):
11818
12077
  return check.isinstance(e.value, CoroHttpServer.CoroHandleResult)
11819
12078
 
11820
12079
 
12080
+ ########################################
12081
+ # ../../../omlish/logs/asyncs.py
12082
+
12083
+
12084
+ ##
12085
+
12086
+
12087
+ class AsyncLoggerToLogger(Logger):
12088
+ def __init__(self, u: AsyncLogger) -> None:
12089
+ super().__init__()
12090
+
12091
+ self._u = u
12092
+
12093
+ def get_effective_level(self) -> LogLevel:
12094
+ return self._u.get_effective_level()
12095
+
12096
+ def _log(
12097
+ self,
12098
+ ctx: CaptureLoggingContext,
12099
+ msg: ta.Union[str, tuple, LoggingMsgFn],
12100
+ *args: ta.Any,
12101
+ **kwargs: ta.Any,
12102
+ ) -> None:
12103
+ # Nope out early to avoid sync_await if possible - don't bother in the LoggerToAsyncLogger.
12104
+ if not self.is_enabled_for(ctx.must_get_info(LoggingContextInfos.Level).level):
12105
+ return
12106
+
12107
+ # Note: we hardcode the stack offset of sync_await (which is 2 - sync_await + sync_await.thunk). In non-lite
12108
+ # code, lang.sync_await uses a cext if present to avoid being on the py stack, which would obviously complicate
12109
+ # this, but this is lite code so we will always have the non-c version.
12110
+ sync_await(
12111
+ self._u._log( # noqa
12112
+ check.isinstance(ctx, CaptureLoggingContextImpl).inc_stack_offset(3),
12113
+ msg,
12114
+ *args,
12115
+ **kwargs,
12116
+ ),
12117
+ )
12118
+
12119
+
12120
+ class LoggerToAsyncLogger(AsyncLogger):
12121
+ def __init__(self, u: Logger) -> None:
12122
+ super().__init__()
12123
+
12124
+ self._u = u
12125
+
12126
+ def get_effective_level(self) -> LogLevel:
12127
+ return self._u.get_effective_level()
12128
+
12129
+ async def _log(
12130
+ self,
12131
+ ctx: CaptureLoggingContext,
12132
+ msg: ta.Union[str, tuple, LoggingMsgFn],
12133
+ *args: ta.Any,
12134
+ **kwargs: ta.Any,
12135
+ ) -> None:
12136
+ return self._u._log( # noqa
12137
+ check.isinstance(ctx, CaptureLoggingContextImpl).inc_stack_offset(),
12138
+ msg,
12139
+ *args,
12140
+ **kwargs,
12141
+ )
12142
+
12143
+
11821
12144
  ########################################
11822
12145
  # ../../../omlish/logs/std/loggers.py
11823
12146
 
@@ -11841,7 +12164,12 @@ class StdLogger(Logger):
11841
12164
  def get_effective_level(self) -> LogLevel:
11842
12165
  return self._std.getEffectiveLevel()
11843
12166
 
11844
- def _log(self, ctx: CaptureLoggingContext, msg: ta.Union[str, tuple, LoggingMsgFn], *args: ta.Any) -> None:
12167
+ def _log(
12168
+ self,
12169
+ ctx: CaptureLoggingContext,
12170
+ msg: ta.Union[str, tuple, LoggingMsgFn],
12171
+ *args: ta.Any,
12172
+ ) -> None:
11845
12173
  if not self.is_enabled_for(ctx.must_get_info(LoggingContextInfos.Level).level):
11846
12174
  return
11847
12175
 
@@ -12592,8 +12920,23 @@ def make_simple_http_server(
12592
12920
  ##
12593
12921
 
12594
12922
 
12923
+ def _get_module_std_logger(mod_globals: ta.Mapping[str, ta.Any]) -> logging.Logger:
12924
+ return logging.getLogger(mod_globals.get('__name__'))
12925
+
12926
+
12595
12927
  def get_module_logger(mod_globals: ta.Mapping[str, ta.Any]) -> Logger:
12596
- return StdLogger(logging.getLogger(mod_globals.get('__name__'))) # noqa
12928
+ return StdLogger(_get_module_std_logger(mod_globals))
12929
+
12930
+
12931
+ def get_module_async_logger(mod_globals: ta.Mapping[str, ta.Any]) -> AsyncLogger:
12932
+ return LoggerToAsyncLogger(get_module_logger(mod_globals))
12933
+
12934
+
12935
+ def get_module_loggers(mod_globals: ta.Mapping[str, ta.Any]) -> ta.Tuple[Logger, AsyncLogger]:
12936
+ return (
12937
+ log := get_module_logger(mod_globals),
12938
+ LoggerToAsyncLogger(log),
12939
+ )
12597
12940
 
12598
12941
 
12599
12942
  ########################################