nnlogging 0.1.2__py3-none-any.whl → 0.1.4__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 (46) hide show
  1. nnlogging/__init__.py +3 -15
  2. nnlogging/exceptions/__init__.py +15 -0
  3. nnlogging/exceptions/branch_exists.py +29 -0
  4. nnlogging/exceptions/branch_not_found.py +29 -0
  5. nnlogging/exceptions/task_exists.py +31 -0
  6. nnlogging/exceptions/task_not_found.py +29 -0
  7. nnlogging/global_.py +322 -0
  8. nnlogging/options/__init__.py +31 -0
  9. nnlogging/options/branch_config.py +19 -0
  10. nnlogging/options/log_option.py +34 -0
  11. nnlogging/options/logger_config.py +16 -0
  12. nnlogging/options/rich_console.py +44 -0
  13. nnlogging/options/rich_handler.py +47 -0
  14. nnlogging/options/rich_progress.py +62 -0
  15. nnlogging/options/run_config.py +27 -0
  16. nnlogging/options/task_option.py +17 -0
  17. nnlogging/options/track_option.py +19 -0
  18. nnlogging/shell.py +92 -273
  19. nnlogging/shell_funcs/__init__.py +4 -0
  20. nnlogging/shell_funcs/branch_.py +79 -0
  21. nnlogging/{utils/shell_funcs → shell_funcs}/logger_.py +55 -62
  22. nnlogging/shell_funcs/run_.py +84 -0
  23. nnlogging/{utils/shell_funcs → shell_funcs}/task_.py +42 -42
  24. nnlogging/typings/aliases.py +8 -56
  25. nnlogging/typings/exts.py +15 -0
  26. nnlogging/typings/protocols.py +43 -1
  27. nnlogging/utils/factories.py +112 -0
  28. nnlogging/utils/helpers.py +61 -26
  29. {nnlogging-0.1.2.dist-info → nnlogging-0.1.4.dist-info}/METADATA +25 -32
  30. nnlogging-0.1.4.dist-info/RECORD +31 -0
  31. nnlogging/shell_protocol.py +0 -86
  32. nnlogging/typings/__init__.py +0 -41
  33. nnlogging/typings/exceptions.py +0 -10
  34. nnlogging/typings/generics.py +0 -23
  35. nnlogging/utils/__init__.py +0 -83
  36. nnlogging/utils/exception/__init__.py +0 -11
  37. nnlogging/utils/exception/branch_exists.py +0 -49
  38. nnlogging/utils/exception/branch_not_found.py +0 -49
  39. nnlogging/utils/exception/task_exists.py +0 -54
  40. nnlogging/utils/exception/task_not_found.py +0 -49
  41. nnlogging/utils/factory_funcs/rich_.py +0 -154
  42. nnlogging/utils/factory_funcs/shell_.py +0 -192
  43. nnlogging/utils/shell_funcs/branch_.py +0 -164
  44. nnlogging/utils/shell_funcs/run_.py +0 -97
  45. nnlogging-0.1.2.dist-info/RECORD +0 -24
  46. {nnlogging-0.1.2.dist-info → nnlogging-0.1.4.dist-info}/WHEEL +0 -0
nnlogging/__init__.py CHANGED
@@ -1,16 +1,4 @@
1
- """
2
- Package: `nnlogging`
3
- Version: ``0.1.1``
4
- """
1
+ from .global_ import *
2
+ from .shell import Shell
5
3
 
6
- from .shell import (
7
- Shell,
8
- get_global_shell,
9
- replace_global_shell,
10
- )
11
-
12
- __all__ = [
13
- "Shell",
14
- "get_global_shell",
15
- "replace_global_shell",
16
- ]
4
+ __all__ = ["Shell"]
@@ -0,0 +1,15 @@
1
+ from .branch_exists import BranchExistsError, call_branch_exists_error
2
+ from .branch_not_found import BranchNotFoundError, call_branch_not_found_error
3
+ from .task_exists import TaskExistsError, call_task_exists_error
4
+ from .task_not_found import TaskNotFoundError, call_task_not_found_error
5
+
6
+ __all__ = [
7
+ "call_branch_exists_error",
8
+ "call_branch_not_found_error",
9
+ "call_task_exists_error",
10
+ "call_task_not_found_error",
11
+ "BranchExistsError",
12
+ "BranchNotFoundError",
13
+ "TaskExistsError",
14
+ "TaskNotFoundError",
15
+ ]
@@ -0,0 +1,29 @@
1
+ from nnlogging.options import LogOptionDict
2
+ from nnlogging.typings.exts import Unpack
3
+ from nnlogging.typings.protocols import ExceptionProtocol
4
+ from nnlogging.utils.helpers import (
5
+ get_name,
6
+ inc_stacklevel,
7
+ inject_excinfo,
8
+ )
9
+
10
+
11
+ class BranchExistsError(LookupError): ...
12
+
13
+
14
+ def call_branch_exists_error(
15
+ inst: ExceptionProtocol,
16
+ name: str,
17
+ /,
18
+ **kwargs: Unpack[LogOptionDict],
19
+ ):
20
+ e = BranchExistsError(
21
+ f'branch "{name}" already exists in {get_name(inst)}.branches: {inst.branches}'
22
+ )
23
+ inst.exception(
24
+ 'branch "%s" already exists in %s.branches',
25
+ name,
26
+ get_name(inst),
27
+ **inc_stacklevel(inject_excinfo(kwargs, e)),
28
+ )
29
+ return e
@@ -0,0 +1,29 @@
1
+ from nnlogging.options import LogOptionDict
2
+ from nnlogging.typings.exts import Unpack
3
+ from nnlogging.typings.protocols import ExceptionProtocol
4
+ from nnlogging.utils.helpers import (
5
+ get_name,
6
+ inc_stacklevel,
7
+ inject_excinfo,
8
+ )
9
+
10
+
11
+ class BranchNotFoundError(LookupError): ...
12
+
13
+
14
+ def call_branch_not_found_error(
15
+ inst: ExceptionProtocol,
16
+ name: str,
17
+ /,
18
+ **kwargs: Unpack[LogOptionDict],
19
+ ):
20
+ e = BranchNotFoundError(
21
+ f'branch "{name}" not found in {get_name(inst)}.branches: {inst.branches}'
22
+ )
23
+ inst.exception(
24
+ 'branch "%s" not found in %s.branches',
25
+ name,
26
+ get_name(inst),
27
+ **inc_stacklevel(inject_excinfo(kwargs, e)),
28
+ )
29
+ return e
@@ -0,0 +1,31 @@
1
+ from nnlogging.options import LogOptionDict
2
+ from nnlogging.typings.exts import Unpack
3
+ from nnlogging.typings.protocols import ExceptionProtocol
4
+ from nnlogging.utils.helpers import (
5
+ get_name,
6
+ inc_stacklevel,
7
+ inject_excinfo,
8
+ )
9
+
10
+
11
+ class TaskExistsError(LookupError): ...
12
+
13
+
14
+ def call_task_exists_error(
15
+ inst: ExceptionProtocol,
16
+ branch: str,
17
+ name: str,
18
+ /,
19
+ **kwargs: Unpack[LogOptionDict],
20
+ ):
21
+ e = TaskExistsError(
22
+ f'task "{name}" already exists in {get_name(inst)}.branches."{branch}"."tasks": {inst.branches[branch]["tasks"]}'
23
+ )
24
+ inst.exception(
25
+ 'task "%s" already exists in %s.branches."%s"."tasks"',
26
+ name,
27
+ get_name(inst),
28
+ branch,
29
+ **inc_stacklevel(inject_excinfo(kwargs, e)),
30
+ )
31
+ return e
@@ -0,0 +1,29 @@
1
+ from nnlogging.options import LogOptionDict
2
+ from nnlogging.typings.exts import Unpack
3
+ from nnlogging.typings.protocols import ExceptionProtocol
4
+ from nnlogging.utils.helpers import (
5
+ get_name,
6
+ inc_stacklevel,
7
+ inject_excinfo,
8
+ )
9
+
10
+
11
+ class TaskNotFoundError(LookupError): ...
12
+
13
+
14
+ def call_task_not_found_error(
15
+ inst: ExceptionProtocol,
16
+ name: str,
17
+ /,
18
+ **kwargs: Unpack[LogOptionDict],
19
+ ):
20
+ e = TaskNotFoundError(
21
+ f'task "{name}" not found in {get_name(inst)}.branches: {inst.branches}'
22
+ )
23
+ inst.exception(
24
+ 'task "%s" not found in %s.branches',
25
+ name,
26
+ get_name(inst),
27
+ **inc_stacklevel(inject_excinfo(kwargs, e)),
28
+ )
29
+ return e
nnlogging/global_.py ADDED
@@ -0,0 +1,322 @@
1
+ import threading
2
+ from typing import Literal
3
+
4
+ from aim.storage.types import AimObject
5
+
6
+ import nnlogging.shell_funcs as f
7
+ from nnlogging.options import (
8
+ BranchConfigOptionDict,
9
+ LoggerConfigOptionDict,
10
+ LogOptionDict,
11
+ RunConfigOptionDict,
12
+ TaskOptionDict,
13
+ TrackOptionDict,
14
+ )
15
+ from nnlogging.shell import Shell
16
+ from nnlogging.typings.exts import Unpack
17
+ from nnlogging.typings.protocols import Sink
18
+ from nnlogging.utils.helpers import with_lock
19
+
20
+ _global_shell_lock: threading.Lock = threading.Lock()
21
+ _global_shell: Shell = Shell("_global_")
22
+
23
+
24
+ __all__ = [
25
+ "replace_global_shell",
26
+ "logger_configure",
27
+ "run_configure",
28
+ "branch_configure",
29
+ "branch_add",
30
+ "branch_remove",
31
+ "task_add",
32
+ "task_remove",
33
+ "log",
34
+ "debug",
35
+ "info",
36
+ "warn",
37
+ "error",
38
+ "critical",
39
+ "exception",
40
+ "advance",
41
+ "track",
42
+ "add_tag",
43
+ "remove_tag",
44
+ "update_metadata",
45
+ ]
46
+
47
+
48
+ @with_lock(_global_shell_lock)
49
+ def replace_global_shell(shell: Shell):
50
+ global _global_shell, _global_shell_lock
51
+ if _global_shell.logger is not None:
52
+ _global_shell.logger_configure()
53
+ if _global_shell.run is not None:
54
+ _global_shell.run_configure()
55
+ for name in list(_global_shell.branches.keys()):
56
+ _global_shell.branch_remove(name)
57
+ _global_shell = shell
58
+
59
+
60
+ @with_lock(_global_shell_lock)
61
+ def logger_configure(
62
+ **kwargs: Unpack[LoggerConfigOptionDict],
63
+ ):
64
+ global _global_shell
65
+ f.logger_configure(
66
+ _global_shell,
67
+ **kwargs,
68
+ )
69
+
70
+
71
+ @with_lock(_global_shell_lock)
72
+ def run_configure(
73
+ **kwargs: Unpack[RunConfigOptionDict],
74
+ ):
75
+ global _global_shell
76
+ f.run_configure(
77
+ _global_shell,
78
+ **kwargs,
79
+ )
80
+
81
+
82
+ @with_lock(_global_shell_lock)
83
+ def branch_configure(
84
+ **kwargs: Unpack[BranchConfigOptionDict],
85
+ ):
86
+ global _global_shell
87
+ f.branch_configure(
88
+ _global_shell,
89
+ **kwargs,
90
+ )
91
+
92
+
93
+ @with_lock(_global_shell_lock)
94
+ def branch_add(
95
+ name: str,
96
+ /,
97
+ sink: Sink | Literal["stderr", "stdout"] = "stderr",
98
+ **kwargs: Unpack[BranchConfigOptionDict],
99
+ ):
100
+ global _global_shell
101
+ f.branch_add(
102
+ _global_shell,
103
+ name,
104
+ sink=sink,
105
+ **kwargs,
106
+ )
107
+
108
+
109
+ @with_lock(_global_shell_lock)
110
+ def branch_remove(
111
+ name: str,
112
+ /,
113
+ ):
114
+ global _global_shell
115
+ f.branch_remove(
116
+ _global_shell,
117
+ name,
118
+ )
119
+
120
+
121
+ @with_lock(_global_shell_lock)
122
+ def task_add(
123
+ name: str,
124
+ /,
125
+ **kwargs: Unpack[TaskOptionDict],
126
+ ):
127
+ global _global_shell
128
+ f.task_add(
129
+ _global_shell,
130
+ name,
131
+ **kwargs,
132
+ )
133
+
134
+
135
+ @with_lock(_global_shell_lock)
136
+ def task_remove(
137
+ name: str,
138
+ /,
139
+ ):
140
+ global _global_shell
141
+ f.task_remove(
142
+ _global_shell,
143
+ name,
144
+ )
145
+
146
+
147
+ @with_lock(_global_shell_lock)
148
+ def log(
149
+ level: int,
150
+ msg: object,
151
+ *args: object,
152
+ **kwargs: Unpack[LogOptionDict],
153
+ ):
154
+ global _global_shell
155
+ kwargs["stacklevel"] = kwargs.get("stacklevel", 3)
156
+ f.log(
157
+ _global_shell,
158
+ level,
159
+ msg,
160
+ *args,
161
+ **kwargs,
162
+ )
163
+
164
+
165
+ @with_lock(_global_shell_lock)
166
+ def debug(
167
+ msg: object,
168
+ *args: object,
169
+ **kwargs: Unpack[LogOptionDict],
170
+ ):
171
+ global _global_shell
172
+ kwargs["stacklevel"] = kwargs.get("stacklevel", 3)
173
+ f.debug(
174
+ _global_shell,
175
+ msg,
176
+ *args,
177
+ **kwargs,
178
+ )
179
+
180
+
181
+ @with_lock(_global_shell_lock)
182
+ def info(
183
+ msg: object,
184
+ *args: object,
185
+ **kwargs: Unpack[LogOptionDict],
186
+ ):
187
+ global _global_shell
188
+ kwargs["stacklevel"] = kwargs.get("stacklevel", 3)
189
+ f.info(
190
+ _global_shell,
191
+ msg,
192
+ *args,
193
+ **kwargs,
194
+ )
195
+
196
+
197
+ @with_lock(_global_shell_lock)
198
+ def warn(
199
+ msg: object,
200
+ *args: object,
201
+ **kwargs: Unpack[LogOptionDict],
202
+ ):
203
+ global _global_shell
204
+ kwargs["stacklevel"] = kwargs.get("stacklevel", 3)
205
+ f.warn(
206
+ _global_shell,
207
+ msg,
208
+ *args,
209
+ **kwargs,
210
+ )
211
+
212
+
213
+ @with_lock(_global_shell_lock)
214
+ def error(
215
+ msg: object,
216
+ *args: object,
217
+ **kwargs: Unpack[LogOptionDict],
218
+ ):
219
+ global _global_shell
220
+ kwargs["stacklevel"] = kwargs.get("stacklevel", 3)
221
+ f.error(
222
+ _global_shell,
223
+ msg,
224
+ *args,
225
+ **kwargs,
226
+ )
227
+
228
+
229
+ @with_lock(_global_shell_lock)
230
+ def critical(
231
+ msg: object,
232
+ *args: object,
233
+ **kwargs: Unpack[LogOptionDict],
234
+ ):
235
+ global _global_shell
236
+ kwargs["stacklevel"] = kwargs.get("stacklevel", 3)
237
+ f.critical(
238
+ _global_shell,
239
+ msg,
240
+ *args,
241
+ **kwargs,
242
+ )
243
+
244
+
245
+ @with_lock(_global_shell_lock)
246
+ def exception(
247
+ msg: object,
248
+ *args: object,
249
+ **kwargs: Unpack[LogOptionDict],
250
+ ):
251
+ global _global_shell
252
+ kwargs["stacklevel"] = kwargs.get("stacklevel", 3)
253
+ f.exception(
254
+ _global_shell,
255
+ msg,
256
+ *args,
257
+ **kwargs,
258
+ )
259
+
260
+
261
+ @with_lock(_global_shell_lock)
262
+ def advance(
263
+ name: str,
264
+ value: float,
265
+ ):
266
+ global _global_shell
267
+ f.advance(
268
+ _global_shell,
269
+ name,
270
+ value,
271
+ )
272
+
273
+
274
+ @with_lock(_global_shell_lock)
275
+ def track(
276
+ value: object,
277
+ /,
278
+ **kwargs: Unpack[TrackOptionDict],
279
+ ):
280
+ global _global_shell
281
+ f.track(
282
+ _global_shell,
283
+ value,
284
+ **kwargs,
285
+ )
286
+
287
+
288
+ @with_lock(_global_shell_lock)
289
+ def add_tag(
290
+ tag: str,
291
+ /,
292
+ ):
293
+ global _global_shell
294
+ f.add_tag(
295
+ _global_shell,
296
+ tag,
297
+ )
298
+
299
+
300
+ @with_lock(_global_shell_lock)
301
+ def remove_tag(
302
+ tag: str,
303
+ /,
304
+ ):
305
+ global _global_shell
306
+ f.remove_tag(
307
+ _global_shell,
308
+ tag,
309
+ )
310
+
311
+
312
+ @with_lock(_global_shell_lock)
313
+ def update_metadata(
314
+ key: str,
315
+ value: AimObject,
316
+ ):
317
+ global _global_shell
318
+ f.update_metadata(
319
+ _global_shell,
320
+ key,
321
+ value,
322
+ )
@@ -0,0 +1,31 @@
1
+ from .branch_config import BranchConfigOption, BranchConfigOptionDict
2
+ from .log_option import LoggingLogOptionDict, LogOptionDict, RichPrintOptionDict
3
+ from .logger_config import LoggerConfigOption, LoggerConfigOptionDict
4
+ from .rich_console import RichConsoleOption, RichConsoleOptionDict
5
+ from .rich_handler import RichHandlerOption, RichHandlerOptionDict
6
+ from .rich_progress import RichProgressOption, RichProgressOptionDict
7
+ from .run_config import RunConfigOption, RunConfigOptionDict
8
+ from .task_option import TaskOption, TaskOptionDict
9
+ from .track_option import TrackOption, TrackOptionDict
10
+
11
+ __all__ = [
12
+ "RichConsoleOption",
13
+ "RichConsoleOptionDict",
14
+ "RichHandlerOption",
15
+ "RichHandlerOptionDict",
16
+ "RichProgressOption",
17
+ "RichProgressOptionDict",
18
+ "LoggerConfigOption",
19
+ "LoggerConfigOptionDict",
20
+ "RunConfigOption",
21
+ "RunConfigOptionDict",
22
+ "BranchConfigOption",
23
+ "BranchConfigOptionDict",
24
+ "TaskOption",
25
+ "TaskOptionDict",
26
+ "TrackOption",
27
+ "TrackOptionDict",
28
+ "LogOptionDict",
29
+ "RichPrintOptionDict",
30
+ "LoggingLogOptionDict",
31
+ ]
@@ -0,0 +1,19 @@
1
+ from dataclasses import dataclass
2
+
3
+ from .rich_console import RichConsoleOption, RichConsoleOptionDict
4
+ from .rich_handler import RichHandlerOption, RichHandlerOptionDict
5
+ from .rich_progress import RichProgressOption, RichProgressOptionDict
6
+
7
+
8
+ @dataclass(kw_only=True)
9
+ class BranchConfigOption(RichConsoleOption, RichHandlerOption, RichProgressOption):
10
+ def __post_init__(self):
11
+ RichConsoleOption.__post_init__(self)
12
+ RichHandlerOption.__post_init__(self)
13
+
14
+
15
+ class BranchConfigOptionDict(
16
+ RichConsoleOptionDict,
17
+ RichHandlerOptionDict,
18
+ RichProgressOptionDict,
19
+ ): ...
@@ -0,0 +1,34 @@
1
+ from collections.abc import Mapping
2
+ from types import TracebackType
3
+ from typing import TypeAlias, TypedDict
4
+
5
+ from rich.console import (
6
+ JustifyMethod as RichConsoleJustifyMethod,
7
+ OverflowMethod as RichConsoleOverflowMethod,
8
+ )
9
+
10
+ ExcInfoType: TypeAlias = (
11
+ None
12
+ | bool
13
+ | BaseException
14
+ | tuple[None, None, None]
15
+ | tuple[type[BaseException], BaseException, TracebackType | None]
16
+ )
17
+
18
+
19
+ class RichPrintOptionDict(TypedDict, total=False):
20
+ end: str
21
+ justify: RichConsoleJustifyMethod
22
+ no_wrap: bool
23
+ overflow: RichConsoleOverflowMethod
24
+ new_line_start: bool
25
+
26
+
27
+ class LoggingLogOptionDict(TypedDict, total=False):
28
+ exc_info: ExcInfoType
29
+ stack_info: bool
30
+ stacklevel: int
31
+ extra: Mapping[str, object]
32
+
33
+
34
+ class LogOptionDict(LoggingLogOptionDict, RichPrintOptionDict): ...
@@ -0,0 +1,16 @@
1
+ import logging
2
+ from dataclasses import dataclass, field
3
+ from typing import TypedDict
4
+
5
+
6
+ @dataclass(kw_only=True)
7
+ class LoggerConfigOption:
8
+ name: str = field(default="nnlogging")
9
+ level: int | str = field(default=logging.INFO)
10
+ propagate: bool = field(default=False)
11
+
12
+
13
+ class LoggerConfigOptionDict(TypedDict, total=False):
14
+ name: str
15
+ level: int | str
16
+ propagate: bool
@@ -0,0 +1,44 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import Literal, TypedDict
3
+
4
+ from rich.highlighter import (
5
+ Highlighter as RichHighlighter,
6
+ NullHighlighter as RichNullHighlighter,
7
+ )
8
+ from rich.theme import Theme as RichTheme
9
+
10
+
11
+ @dataclass(kw_only=True)
12
+ class RichConsoleOption:
13
+ width: int | None = field(default=None)
14
+ height: int | None = field(default=None)
15
+ markup: bool = field(default=True)
16
+ emoji: bool = field(default=True)
17
+ color_system: Literal["auto", "standard", "truecolor"] | None = field(
18
+ default="auto"
19
+ )
20
+ theme: RichTheme | None = field(default=None)
21
+ highlighter: RichHighlighter = field(default_factory=RichNullHighlighter)
22
+ soft_wrap: bool = field(default=False)
23
+ force_terminal: bool | None = field(default=None)
24
+ force_jupyter: bool | None = field(default=None)
25
+ force_interactive: bool | None = field(default=None)
26
+
27
+ highlight: bool = field(init=False)
28
+
29
+ def __post_init__(self):
30
+ self.highlight = not isinstance(self.highlighter, RichNullHighlighter)
31
+
32
+
33
+ class RichConsoleOptionDict(TypedDict, total=False):
34
+ width: int | None
35
+ height: int | None
36
+ markup: bool
37
+ emoji: bool
38
+ color_system: Literal["auto", "standard", "truecolor"] | None
39
+ theme: RichTheme | None
40
+ highlighter: RichHighlighter
41
+ soft_wrap: bool
42
+ force_terminal: bool | None
43
+ force_jupyter: bool | None
44
+ force_interactive: bool | None
@@ -0,0 +1,47 @@
1
+ import logging
2
+ from dataclasses import dataclass, field
3
+ from logging import Formatter as LoggingFormatter
4
+ from typing import TypedDict
5
+
6
+ from rich.highlighter import (
7
+ Highlighter as RichHighlighter,
8
+ NullHighlighter as RichNullHighlighter,
9
+ )
10
+
11
+ from nnlogging.typings.aliases import FormatTimeCallable
12
+
13
+
14
+ @dataclass(kw_only=True)
15
+ class RichHandlerOption:
16
+ level: str | int = field(default=logging.NOTSET)
17
+ show_level: bool = field(default=True)
18
+ show_time: bool = field(default=True)
19
+ show_path: bool = field(default=True)
20
+ log_time_format: str | FormatTimeCallable = field(default="[%x %X]")
21
+ omit_repeated_times: bool = field(default=True)
22
+ markup: bool = field(default=True)
23
+ highlighter: RichHighlighter = field(default_factory=RichNullHighlighter)
24
+ rich_tracebacks: bool = field(default=True)
25
+ tracebacks_extra_lines: int = field(default=0)
26
+ tracebacks_max_frames: int = field(default=1)
27
+ tracebacks_show_locals: bool = field(default=False)
28
+ locals_max_length: int = field(default=10)
29
+ log_message_format: str | LoggingFormatter = field(default="%(message)s")
30
+
31
+ def __post_init__(self):
32
+ if isinstance(self.log_message_format, str):
33
+ self.log_message_format = LoggingFormatter(self.log_message_format)
34
+
35
+
36
+ class RichHandlerOptionDict(TypedDict, total=False):
37
+ level: str | int
38
+ show_level: bool
39
+ show_time: bool
40
+ show_path: bool
41
+ log_time_format: str | FormatTimeCallable
42
+ omit_repeated_times: bool
43
+ markup: bool
44
+ highlighter: RichHighlighter
45
+ rich_tracebacks: bool
46
+ tracebacks_show_locals: bool
47
+ log_message_format: str | LoggingFormatter