omlish 0.0.0.dev430__py3-none-any.whl → 0.0.0.dev432__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.
@@ -7,7 +7,7 @@ import threading
7
7
  import time
8
8
  import typing as ta
9
9
 
10
- from ...logs.callers import LoggingCaller
10
+ from ...logs.infos import LoggingContextInfos
11
11
  from ...logs.levels import LogLevel
12
12
  from .types import ABSENT_TYPED_LOGGER_VALUE
13
13
  from .types import AbsentTypedLoggerValue
@@ -57,7 +57,7 @@ class StandardTypedLoggerValues:
57
57
 
58
58
  #
59
59
 
60
- class Caller(TypedLoggerValue[LoggingCaller]):
60
+ class Caller(TypedLoggerValue[LoggingContextInfos.Caller]):
61
61
  pass
62
62
 
63
63
  #
omlish/math/fixed.py CHANGED
@@ -70,8 +70,8 @@ class FixedWidthInt(int, lang.Abstract):
70
70
 
71
71
  #
72
72
 
73
- def __init_subclass__(cls) -> None:
74
- super().__init_subclass__()
73
+ def __init_subclass__(cls, **kwargs: ta.Any) -> None:
74
+ super().__init_subclass__(**kwargs)
75
75
 
76
76
  if lang.is_abstract_class(cls):
77
77
  return
omlish/secrets/secrets.py CHANGED
@@ -8,6 +8,9 @@ TODO:
8
8
  - time of retrieval
9
9
  - logs accesses
10
10
  - types? ssh / url / pw / basicauthtoken / tls / str
11
+ - read-once?
12
+ - NotSecret[T]
13
+ - tainting / MarkupSafe
11
14
  """
12
15
  import abc
13
16
  import collections
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omlish
3
- Version: 0.0.0.dev430
3
+ Version: 0.0.0.dev432
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License-Expression: BSD-3-Clause
@@ -1,5 +1,5 @@
1
1
  omlish/.omlish-manifests.json,sha256=FLw7xkPiSXuImZgqSP8BwrEib2R1doSzUPLUkc-QUIA,8410
2
- omlish/__about__.py,sha256=hWUhAjMnMNft0GDUanNG2JIkoAwrhNLC_ZTd5BzHw0A,3575
2
+ omlish/__about__.py,sha256=3-_QYxv_HRPE-514v1MBZ6PctnESC50f34-uw3VRp7U,3575
3
3
  omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
4
4
  omlish/c3.py,sha256=ZNIMl1kwg3qdei4DiUrJPQe5M81S1e76N-GuNSwLBAE,8683
5
5
  omlish/cached.py,sha256=MLap_p0rdGoDIMVhXVHm1tsbcWobJF0OanoodV03Ju8,542
@@ -55,7 +55,7 @@ omlish/asyncs/ioproxy/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0R
55
55
  omlish/asyncs/ioproxy/all.py,sha256=_0mg0OjNKbnpGPSQZ-ftXYhKSpt-Po4Rlu2kam7v3XQ,1003
56
56
  omlish/asyncs/ioproxy/io.py,sha256=XMVPk5_q7b-1YYf2YxO2duSKzEWpuhY5X_leI3QWsHY,5123
57
57
  omlish/asyncs/ioproxy/proxier.py,sha256=dYXiVkDJVCzasMP4eMNSvSO1eNsd6CIRTtLyoa8YzNc,4492
58
- omlish/asyncs/ioproxy/proxy.py,sha256=s9bnjVPkTVtW5dh_vcpKNwbzEhA2zZZKF-U1BWZ5LPo,3911
58
+ omlish/asyncs/ioproxy/proxy.py,sha256=TmWNQb7iOKyEk8ZOG2gZuk0RhziymwypWblZQ5u2QSM,3919
59
59
  omlish/asyncs/ioproxy/typing.py,sha256=ZM-9HRO4dpy-RqomSkyRha9s901ckL30bwjACi2TJ8s,2475
60
60
  omlish/bootstrap/__init__.py,sha256=svuRMcY-rqA31fLnHpTRRAs1uN63MXIeGcKK3NoKhL0,691
61
61
  omlish/bootstrap/__main__.py,sha256=GKhsZdPdJtzE4qnjt34-EvL07nLJVZD-d8nxfGl7EEI,188
@@ -105,7 +105,7 @@ omlish/collections/persistent/treapmap.py,sha256=O4rh3x6p6tQ0EC2wiz80ZzGNb37-mQR
105
105
  omlish/collections/sorted/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
106
  omlish/collections/sorted/skiplist.py,sha256=bcTO1hZvV5EnYxBZ3YBhdewXP_2aCTZra7tJ0pA7jjo,6194
107
107
  omlish/collections/sorted/sorted.py,sha256=sWMRdwdiKmByeWY0nwOq_nxLL5_sjHYfJVu95xmaxc8,3969
108
- omlish/concurrent/__init__.py,sha256=9p-s8MvBEYDqHIoYU3OYoe-Nni22QdkW7nhZGEukJTM,197
108
+ omlish/concurrent/__init__.py,sha256=OCr6LUTXq95sG97dsFvSrFm-V0vy1vDjUf5pO5PzGrY,315
109
109
  omlish/concurrent/executors.py,sha256=j2V8f4UW3sJJG_qn7ldi1R2yY2QmUQA3UCuNQvLj1Wk,1285
110
110
  omlish/concurrent/futures.py,sha256=870tx8ELI8THvMnTrQoYIlEFKO9hM4KUrlehckJqKBU,4238
111
111
  omlish/concurrent/threadlets.py,sha256=Z1pCSWt7U8VBMhPFNzd850BfbDMiGQxhYCC7X7KjYyU,2435
@@ -301,7 +301,7 @@ omlish/formats/toml/writer.py,sha256=9NT8sRy3I9KubxFx56Qbislvrdtbd23rEuBT-GSdUYA
301
301
  omlish/funcs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
302
302
  omlish/funcs/builders.py,sha256=ZSBQS2xqriXp5x0t074EEZvuTmMp4Yue2YGBoTLAioo,4044
303
303
  omlish/funcs/genmachine.py,sha256=YRRW5FwhUgtGhi482tdlZbgz0aLGXtLB4Y0gOZGcP2w,2578
304
- omlish/funcs/match.py,sha256=8OTTnJf4kL9rWeCIDAOv6_JEeC-wrezjaTkl4qhMQ7s,6205
304
+ omlish/funcs/match.py,sha256=AD0sQs_GIRq--fIQzL5gFYzlvXHplIljvlx7hbhNSEk,6213
305
305
  omlish/funcs/pairs.py,sha256=XhYTJdqooAJKeoGZmEaiKYeFRq5-Dj2_y92IdBl_C20,4371
306
306
  omlish/funcs/pipes.py,sha256=E1dQZMBmgT2qautG1vEqy5v3QBsO2Nzryv33j4YAngA,2520
307
307
  omlish/graphs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -457,7 +457,7 @@ omlish/lang/classes/virtual.py,sha256=J4y-uiv1RaP2rfFeptXqQ1a4MRek0TMlAFFraO_lzh
457
457
  omlish/lang/imports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
458
458
  omlish/lang/imports/conditional.py,sha256=R-E47QD95mMonPImWlrde3rnJrFKCCkYz71c94W05sc,1006
459
459
  omlish/lang/imports/lazy.py,sha256=Fhtb5tSAttff6G2pZdF8bh__GZlqJWHaMKtA8KubuX4,1479
460
- omlish/lang/imports/proxyinit.py,sha256=Mw3_Or0x8Gz0YrMBIdyfdALnqNi4HXgv6ZZQDPMWL_o,19629
460
+ omlish/lang/imports/proxyinit.py,sha256=VrCnc4XNfwiJU18GNc3tFGxHSx5QxgyAfqyuJiCH66Y,19721
461
461
  omlish/lang/imports/resolving.py,sha256=DeRarn35Fryg5JhVhy8wbiC9lvr58AnllI9B_reswUE,2085
462
462
  omlish/lang/imports/traversal.py,sha256=pbFQIa880NGjSfcLsno2vE_G41_CLwDHb-7gWg2J3BI,2855
463
463
  omlish/lifecycles/__init__.py,sha256=zOuvV4pErPwxcKUSgshmME2Duw9GrjwckpNmW3FPKng,810
@@ -497,32 +497,32 @@ omlish/lite/types.py,sha256=QM9whf55r7TmmQBRApIWSlyVKsl1p_jcut_YheyZMFY,146
497
497
  omlish/lite/typing.py,sha256=m2CyJTz2OVOCPRvp-0UuEx7oleZgXqs3rYXijE0bTsA,1280
498
498
  omlish/lite/wrappers.py,sha256=d00Ls2kFHuogKd5wEBaU65VNCN10YXIZtiwu1mbMpmA,530
499
499
  omlish/logs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
500
- omlish/logs/all.py,sha256=_sU_2waB8FR9GuVrdxGLI145nGepd8c2LAHf2J4dbz4,1777
501
- omlish/logs/base.py,sha256=VHPjSJjQzIRCe5nqgkmNORYclDJZayGucMy_WhITO1c,6650
502
- omlish/logs/callers.py,sha256=F3VbeQJniw6RyfbeGBcxMGL3aeO5mgPizmJ8pa2RW88,2091
503
- omlish/logs/contexts.py,sha256=dC84Wa__j0leSJw5SzP-ygsflfzIiqvmRnv9meD-Q_U,7523
504
- omlish/logs/infos.py,sha256=38bPi7v7vHawNlLp7Q7X6JS-q5s-JrwlDi08FY4xoy4,2621
500
+ omlish/logs/all.py,sha256=GqST35bRnHgpGmQXvtHih7kLaw5DcFgB32uxPGAsgSI,1717
501
+ omlish/logs/base.py,sha256=Z1hfwYS2LgMJxFIyHiOvYa2meu2MH3kQDkhaWRNzt0M,5698
502
+ omlish/logs/contexts.py,sha256=bTja5uA2V2VMoPnPrBxRfzUDgD0giRA0RVbtwrp3Xv4,4797
503
+ omlish/logs/formatters.py,sha256=g8oGfP_ok0nrW9opIIh5LqcQTmdufWFGO-9pRKX4m3Q,242
504
+ omlish/logs/infos.py,sha256=Nr2SbyI978vP5BTiVZsXUBdy2k0CUiwggcW-wewJHmo,11560
505
505
  omlish/logs/levels.py,sha256=Eze-k_LPgFzbNMnG10F2bRKfL3veQpIxiegvN5rGeWM,2909
506
506
  omlish/logs/modules.py,sha256=wZ_PNCYhAaEdnGE5k0JvChcqn9nhtEpmwuH74Bwn5gg,266
507
507
  omlish/logs/protocols.py,sha256=e_zizD3pQdYlU6bg3xGB3_ARUTcoHUfar_uLjCo-SPw,961
508
- omlish/logs/standard.py,sha256=ppho-wDecGxUiRXOdCIlblmrQhqXZ0oQOGayy8N53XY,3237
509
- omlish/logs/times.py,sha256=WUy92cUxMtttnj0PZryIxbLqEdWiiAVDUboRxqe2pYw,2594
508
+ omlish/logs/standard.py,sha256=btp0YOUb3AsANG0D1rqGK-z25O4HN7p1PJj9ecJ80WI,3323
510
509
  omlish/logs/utils.py,sha256=fKvP342qBmE8wwTgUQ8Tf0-ATVhCm90UYBQt2pk0044,1883
511
510
  omlish/logs/warnings.py,sha256=xyhDgiPy1p8Kp5D9sb_NZiBnQ26SUppaHqC27dtQzok,67
512
511
  omlish/logs/std/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
513
512
  omlish/logs/std/configs.py,sha256=aDQahqBJXJpmQBaxXVK5S2xi_I_nrLLcCLTq6Q2K6EQ,1037
514
513
  omlish/logs/std/filters.py,sha256=Z8tHOvBRiP-OYm2z5cwY-lYXRimNgferEARMwvwx5Pw,380
514
+ omlish/logs/std/formatters.py,sha256=mORjx6kPQ-nYvek0Lyg1PZh0vtSYr6Vk-UJtRNW9_8k,645
515
515
  omlish/logs/std/handlers.py,sha256=uTWOT6oayBUEftKmJ8yo89ZP4plv5eQ8Lbcmt-IGl8c,469
516
516
  omlish/logs/std/json.py,sha256=QJ5lywLsRsPyVno2nk2kOw-Z1z3bfrDiZzqcRUdWUMY,1382
517
- omlish/logs/std/loggers.py,sha256=nJieUZ2iPO8iVYc72QDUBKLPhGw7yPd_RzR18zKUSck,1106
517
+ omlish/logs/std/loggers.py,sha256=hJIEC5BGaDOxgikTYKJ_qA_moS4CcHLMDAVKFDDKdHo,1144
518
518
  omlish/logs/std/noisy.py,sha256=hWpbseerZqlHdEPEajDTSmcRhx8LmmNAxz_7GBZAO9s,353
519
519
  omlish/logs/std/proxy.py,sha256=9MVV5kbj9nwl3KZGtrYCIb5XTpv33f33zZ7P_B58fX0,2394
520
- omlish/logs/std/records.py,sha256=muJA3KKjGm5mgsHXtOyrpaEZu553M-UviNgNvXdISXY,10718
520
+ omlish/logs/std/records.py,sha256=NbprlkTQV8Y89nP2c27m3nE0OY3SWmQHCl-o_rQfs50,25476
521
521
  omlish/logs/typed/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
522
522
  omlish/logs/typed/bindings.py,sha256=H_B-3LTGFlBIWYDJ8rei1VMfInE8KrBwRo3bJ_BgFj8,18184
523
523
  omlish/logs/typed/contexts.py,sha256=MU1RqHtmYbnxoLfLhMZbTbRd-WfYEyeVo7_3VnG3rY0,4027
524
524
  omlish/logs/typed/types.py,sha256=DQKDT2v4bG1Cgv_LrhvTIHWBAIODs9b8E5jNI4jTRpU,14442
525
- omlish/logs/typed/values.py,sha256=w8ukpJZ3lx_st7Mj7riP2squzGmMaz7OuUxw_NZCZsY,3261
525
+ omlish/logs/typed/values.py,sha256=s8x-P6tYq-BrhoA98Z5tfi70Tl1hHhcxOd1qao_h6ps,3278
526
526
  omlish/manifests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
527
527
  omlish/manifests/base.py,sha256=wW-De-pU3cef-0vGsgo-ypftDwc3tCBxhRAzPtrdark,918
528
528
  omlish/manifests/globals.py,sha256=kVqQ-fT4kc7xWzLHoI731GviitFPv2v2yqw-p7t7Exs,2628
@@ -590,7 +590,7 @@ omlish/marshal/trivial/nop.py,sha256=PDXT0B9RR-ghG6ExuK9BH2J-nHEnoTYGNdVaNAyRzSk
590
590
  omlish/math/__init__.py,sha256=bcdEEM3l4YNPJvTY_gD-7ARa5HEBNFTfvkVDTTzaNOQ,1531
591
591
  omlish/math/bits.py,sha256=pcTuWxNXXfG-CtTITNNbW3YConAkCeU8PLNcglCc43E,533
592
592
  omlish/math/c.py,sha256=JUHHZfVUUE4sb-6_LxJksbcLOLi9za0LdPs4dky5Ba8,308
593
- omlish/math/fixed.py,sha256=pplyqqD6BxZWS9UEc8MHLsiMwx0-D1GLTeB8EL6yxHs,7419
593
+ omlish/math/fixed.py,sha256=IqNEbI6gBWVCVFXAj2e2O8CN4VqJfIAYb0QIaQ7gpTg,7445
594
594
  omlish/math/floats.py,sha256=xbuGQccA3wC0DoTDqR4awgrzfwoOEYQLdQmFgw7c6-w,332
595
595
  omlish/math/histogram.py,sha256=gDYJG9Cq2sZEjae0cFOb-ADzwNY_xKSnF73Tyd34EPQ,3859
596
596
  omlish/math/stats.py,sha256=HxWJhZD5vdPcCAZ2HO9jYz798EPl2JtyEbXLoJdlRjE,6225
@@ -634,7 +634,7 @@ omlish/secrets/marshal.py,sha256=u90n1OfRfdpH1T2F0xK_pAPH1ENYL6acFt6XdVd3KvI,198
634
634
  omlish/secrets/openssl.py,sha256=4zp1KZ1EVRNaBS0VIokTqnamy3ZeeC1XN2wSXx4lEcM,6215
635
635
  omlish/secrets/pwgen.py,sha256=Z5i1qMKK4idOZvWai5dXkI59gX7pYzFFlFYAj7qEmqA,1706
636
636
  omlish/secrets/pwhash.py,sha256=Jctv3QzcMvVPXJsWA3w3LDUlzmyUDGEWG9sLiJz1xaw,4107
637
- omlish/secrets/secrets.py,sha256=wf_X7IA7HXSEcSPCSt97KuHgYCjDzVhKfDS17rrZUVk,8053
637
+ omlish/secrets/secrets.py,sha256=oZZokPsEvqwcNr--0LwZY8IeYx2JMrGN8Ps9dwBGl7M,8108
638
638
  omlish/secrets/ssl.py,sha256=HnH5MS31X9Uid7Iw1CWqviaVwMLF1Ha8RxZiiE-_iF8,158
639
639
  omlish/secrets/subprocesses.py,sha256=ZdShw4jrGDdyQW8mRMgl106-9qpCEq2J6w_x7ruz1wk,1217
640
640
  omlish/secrets/tempssl.py,sha256=KbNKGwiKw95Ly2b1OtNL2jhPa25aO0t_tvyNB5trUcU,1885
@@ -892,9 +892,9 @@ omlish/typedvalues/marshal.py,sha256=AtBz7Jq-BfW8vwM7HSxSpR85JAXmxK2T0xDblmm1HI0
892
892
  omlish/typedvalues/of_.py,sha256=UXkxSj504WI2UrFlqdZJbu2hyDwBhL7XVrc2qdR02GQ,1309
893
893
  omlish/typedvalues/reflect.py,sha256=PAvKW6T4cW7u--iX80w3HWwZUS3SmIZ2_lQjT65uAyk,1026
894
894
  omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
895
- omlish-0.0.0.dev430.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
896
- omlish-0.0.0.dev430.dist-info/METADATA,sha256=iD6ksXPqkEoUuKrQg-U2gFrrtB3eCj9jzyhlaHtfGgs,19243
897
- omlish-0.0.0.dev430.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
898
- omlish-0.0.0.dev430.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
899
- omlish-0.0.0.dev430.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
900
- omlish-0.0.0.dev430.dist-info/RECORD,,
895
+ omlish-0.0.0.dev432.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
896
+ omlish-0.0.0.dev432.dist-info/METADATA,sha256=bfGoM5Z4MjOp8DULPuEbClTLTNoyTilZ3sKRe-c5SRk,19243
897
+ omlish-0.0.0.dev432.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
898
+ omlish-0.0.0.dev432.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
899
+ omlish-0.0.0.dev432.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
900
+ omlish-0.0.0.dev432.dist-info/RECORD,,
omlish/logs/callers.py DELETED
@@ -1,75 +0,0 @@
1
- # ruff: noqa: UP006 UP007 UP045
2
- # @omlish-lite
3
- import io
4
- import os.path
5
- import sys
6
- import traceback
7
- import types
8
- import typing as ta
9
-
10
- from .infos import logging_context_info
11
-
12
-
13
- ##
14
-
15
-
16
- @logging_context_info
17
- @ta.final
18
- class LoggingCaller(ta.NamedTuple):
19
- file_path: str
20
- line_no: int
21
- name: str
22
- stack_info: ta.Optional[str]
23
-
24
- @classmethod
25
- def is_internal_frame(cls, frame: types.FrameType) -> bool:
26
- file_path = os.path.normcase(frame.f_code.co_filename)
27
-
28
- # Yes, really.
29
- # https://github.com/python/cpython/blob/e709361fc87d0d9ab9c58033a0a7f2fef0ad43d2/Lib/logging/__init__.py#L204
30
- # https://github.com/python/cpython/commit/5ca6d7469be53960843df39bb900e9c3359f127f
31
- if 'importlib' in file_path and '_bootstrap' in file_path:
32
- return True
33
-
34
- return False
35
-
36
- @classmethod
37
- def find_frame(cls, ofs: int = 0) -> ta.Optional[types.FrameType]:
38
- f: ta.Optional[types.FrameType] = sys._getframe(2 + ofs) # noqa
39
-
40
- while f is not None:
41
- # NOTE: We don't check __file__ like stdlib since we may be running amalgamated - we rely on careful, manual
42
- # stack_offset management.
43
- if hasattr(f, 'f_code'):
44
- return f
45
-
46
- f = f.f_back
47
-
48
- return None
49
-
50
- @classmethod
51
- def find(
52
- cls,
53
- ofs: int = 0,
54
- *,
55
- stack_info: bool = False,
56
- ) -> ta.Optional['LoggingCaller']:
57
- if (f := cls.find_frame(ofs + 1)) is None:
58
- return None
59
-
60
- # https://github.com/python/cpython/blob/08e9794517063c8cd92c48714071b1d3c60b71bd/Lib/logging/__init__.py#L1616-L1623 # noqa
61
- sinfo = None
62
- if stack_info:
63
- sio = io.StringIO()
64
- traceback.print_stack(f, file=sio)
65
- sinfo = sio.getvalue()
66
- sio.close()
67
- if sinfo[-1] == '\n':
68
- sinfo = sinfo[:-1]
69
-
70
- return cls(
71
- file_path=f.f_code.co_filename,
72
- line_no=f.f_lineno or 0,
73
- name=f.f_code.co_name,
74
- stack_info=sinfo,
75
- )
omlish/logs/times.py DELETED
@@ -1,89 +0,0 @@
1
- # ruff: noqa: UP045
2
- # @omlish-lite
3
- import logging
4
- import time
5
- import typing as ta
6
-
7
- from .infos import logging_context_info
8
- from .warnings import LoggingSetupWarning
9
-
10
-
11
- ##
12
-
13
-
14
- @logging_context_info
15
- @ta.final
16
- class LoggingTimeFields(ta.NamedTuple):
17
- """Maps directly to stdlib `logging.LogRecord` fields, and must be kept in sync with it."""
18
-
19
- created: float
20
- msecs: float
21
- relative_created: float
22
-
23
- @classmethod
24
- def get_std_start_time_ns(cls) -> int:
25
- x: ta.Any = logging._startTime # type: ignore[attr-defined] # noqa
26
-
27
- # Before 3.13.0b1 this will be `time.time()`, a float of seconds. After that, it will be `time.time_ns()`, an
28
- # int.
29
- #
30
- # See:
31
- # - https://github.com/python/cpython/commit/1316692e8c7c1e1f3b6639e51804f9db5ed892ea
32
- #
33
- if isinstance(x, float):
34
- return int(x * 1e9)
35
- else:
36
- return x
37
-
38
- @classmethod
39
- def build(
40
- cls,
41
- time_ns: int,
42
- *,
43
- start_time_ns: ta.Optional[int] = None,
44
- ) -> 'LoggingTimeFields':
45
- # https://github.com/python/cpython/commit/1316692e8c7c1e1f3b6639e51804f9db5ed892ea
46
- created = time_ns / 1e9 # ns to float seconds
47
-
48
- # Get the number of whole milliseconds (0-999) in the fractional part of seconds.
49
- # Eg: 1_677_903_920_999_998_503 ns --> 999_998_503 ns--> 999 ms
50
- # Convert to float by adding 0.0 for historical reasons. See gh-89047
51
- msecs = (time_ns % 1_000_000_000) // 1_000_000 + 0.0
52
-
53
- # https://github.com/python/cpython/commit/1500a23f33f5a6d052ff1ef6383d9839928b8ff1
54
- if msecs == 999.0 and int(created) != time_ns // 1_000_000_000:
55
- # ns -> sec conversion can round up, e.g:
56
- # 1_677_903_920_999_999_900 ns --> 1_677_903_921.0 sec
57
- msecs = 0.0
58
-
59
- if start_time_ns is None:
60
- start_time_ns = cls.get_std_start_time_ns()
61
- relative_created = (time_ns - start_time_ns) / 1e6
62
-
63
- return cls(
64
- created=created,
65
- msecs=msecs,
66
- relative_created=relative_created,
67
- )
68
-
69
-
70
- ##
71
-
72
-
73
- class UnexpectedLoggingStartTimeWarning(LoggingSetupWarning):
74
- pass
75
-
76
-
77
- def _check_logging_start_time() -> None:
78
- if (x := LoggingTimeFields.get_std_start_time_ns()) < (t := time.time()):
79
- import warnings # noqa
80
-
81
- warnings.warn(
82
- f'Unexpected logging start time detected: '
83
- f'get_std_start_time_ns={x}, '
84
- f'time.time()={t}',
85
- UnexpectedLoggingStartTimeWarning,
86
- )
87
-
88
-
89
- _check_logging_start_time()