omlish 0.0.0.dev419__py3-none-any.whl → 0.0.0.dev421__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 (96) hide show
  1. omlish/__about__.py +2 -2
  2. omlish/asyncs/bluelet/core.py +2 -2
  3. omlish/asyncs/bluelet/events.py +4 -3
  4. omlish/asyncs/bluelet/files.py +2 -2
  5. omlish/asyncs/bluelet/sockets.py +2 -2
  6. omlish/collections/frozen.py +1 -1
  7. omlish/collections/kv/base.py +1 -1
  8. omlish/collections/multimaps.py +1 -1
  9. omlish/collections/persistent/treapmap.py +2 -1
  10. omlish/concurrent/threadlets.py +2 -2
  11. omlish/configs/all.py +39 -32
  12. omlish/configs/formats.py +5 -4
  13. omlish/configs/processing/all.py +32 -26
  14. omlish/configs/processing/flattening.py +2 -1
  15. omlish/configs/processing/rewriting.py +2 -2
  16. omlish/configs/shadow.py +3 -2
  17. omlish/daemons/spawning.py +2 -2
  18. omlish/daemons/targets.py +1 -1
  19. omlish/daemons/waiting.py +2 -1
  20. omlish/dataclasses/impl/generation/base.py +3 -2
  21. omlish/dataclasses/impl/generation/compilation.py +2 -1
  22. omlish/dataclasses/impl/generation/ops.py +2 -2
  23. omlish/dataclasses/impl/generation/processor.py +1 -1
  24. omlish/dataclasses/metaclass/meta.py +1 -0
  25. omlish/dataclasses/tools/static.py +5 -1
  26. omlish/formats/dotenv.py +3 -1
  27. omlish/formats/json/backends/default.py +14 -7
  28. omlish/formats/logfmt.py +111 -0
  29. omlish/formats/yaml.py +1 -1
  30. omlish/funcs/builders.py +2 -1
  31. omlish/funcs/match.py +1 -1
  32. omlish/funcs/pairs.py +41 -23
  33. omlish/funcs/pipes.py +3 -1
  34. omlish/http/asgi.py +2 -1
  35. omlish/http/coro/client/io.py +3 -2
  36. omlish/http/coro/server/server.py +2 -2
  37. omlish/http/handlers.py +2 -1
  38. omlish/http/jwt.py +1 -1
  39. omlish/http/parsing.py +2 -2
  40. omlish/io/compress/base.py +3 -2
  41. omlish/io/coro/readers.py +4 -3
  42. omlish/io/fdio/handlers.py +3 -2
  43. omlish/io/fdio/pollers.py +3 -1
  44. omlish/lang/__init__.py +20 -8
  45. omlish/lang/attrs.py +3 -1
  46. omlish/lang/casing.py +3 -1
  47. omlish/lang/classes/abstract.py +35 -96
  48. omlish/lang/classes/virtual.py +2 -2
  49. omlish/lang/contextmanagers.py +6 -4
  50. omlish/lang/generators.py +2 -2
  51. omlish/lang/iterables.py +6 -6
  52. omlish/lang/objects.py +0 -58
  53. omlish/lang/outcomes.py +3 -1
  54. omlish/lang/typing.py +5 -24
  55. omlish/lite/abstract.py +119 -0
  56. omlish/lite/contextmanagers.py +4 -1
  57. omlish/lite/inject.py +9 -9
  58. omlish/lite/marshal.py +230 -114
  59. omlish/lite/maybes.py +3 -1
  60. omlish/lite/maysync.py +4 -2
  61. omlish/lite/objects.py +81 -0
  62. omlish/lite/reflect.py +0 -15
  63. omlish/lite/timeouts.py +3 -1
  64. omlish/lite/wrappers.py +23 -0
  65. omlish/logs/abc.py +21 -5
  66. omlish/logs/all.py +56 -38
  67. omlish/logs/configs.py +13 -10
  68. omlish/logs/levels.py +4 -0
  69. omlish/logs/protocol.py +77 -39
  70. omlish/marshal/__init__.py +1 -0
  71. omlish/os/atomics.py +3 -2
  72. omlish/os/deathpacts/base.py +4 -2
  73. omlish/os/forkhooks.py +2 -2
  74. omlish/os/pidfiles/pinning.py +2 -1
  75. omlish/reflect/types.py +4 -3
  76. omlish/secrets/crypto.py +1 -1
  77. omlish/sockets/bind.py +2 -1
  78. omlish/sockets/handlers.py +3 -2
  79. omlish/sockets/server/handlers.py +2 -1
  80. omlish/sockets/server/server.py +4 -3
  81. omlish/sql/api/base.py +2 -2
  82. omlish/subprocesses/asyncs.py +2 -1
  83. omlish/subprocesses/base.py +2 -2
  84. omlish/subprocesses/maysync.py +1 -2
  85. omlish/subprocesses/run.py +2 -1
  86. omlish/subprocesses/sync.py +2 -1
  87. omlish/term/coloring.py +3 -1
  88. omlish/testing/pytest/plugins/asyncs/backends/base.py +3 -1
  89. omlish/testing/unittest/loading.py +2 -2
  90. omlish/text/asdl.py +4 -3
  91. {omlish-0.0.0.dev419.dist-info → omlish-0.0.0.dev421.dist-info}/METADATA +1 -1
  92. {omlish-0.0.0.dev419.dist-info → omlish-0.0.0.dev421.dist-info}/RECORD +96 -91
  93. {omlish-0.0.0.dev419.dist-info → omlish-0.0.0.dev421.dist-info}/WHEEL +0 -0
  94. {omlish-0.0.0.dev419.dist-info → omlish-0.0.0.dev421.dist-info}/entry_points.txt +0 -0
  95. {omlish-0.0.0.dev419.dist-info → omlish-0.0.0.dev421.dist-info}/licenses/LICENSE +0 -0
  96. {omlish-0.0.0.dev419.dist-info → omlish-0.0.0.dev421.dist-info}/top_level.txt +0 -0
omlish/lite/reflect.py CHANGED
@@ -91,18 +91,3 @@ def is_literal_type(spec: ta.Any) -> bool:
91
91
 
92
92
  def get_literal_type_args(spec: ta.Any) -> ta.Iterable[ta.Any]:
93
93
  return spec.__args__
94
-
95
-
96
- ##
97
-
98
-
99
- def deep_subclasses(cls: ta.Type[T]) -> ta.Iterator[ta.Type[T]]:
100
- seen = set()
101
- todo = list(reversed(cls.__subclasses__()))
102
- while todo:
103
- cur = todo.pop()
104
- if cur in seen:
105
- continue
106
- seen.add(cur)
107
- yield cur
108
- todo.extend(reversed(cur.__subclasses__()))
omlish/lite/timeouts.py CHANGED
@@ -7,6 +7,8 @@ import abc
7
7
  import time
8
8
  import typing as ta
9
9
 
10
+ from .abstract import Abstract
11
+
10
12
 
11
13
  TimeoutLike = ta.Union['Timeout', ta.Type['Timeout.DEFAULT'], ta.Iterable['TimeoutLike'], float, None] # ta.TypeAlias
12
14
 
@@ -14,7 +16,7 @@ TimeoutLike = ta.Union['Timeout', ta.Type['Timeout.DEFAULT'], ta.Iterable['Timeo
14
16
  ##
15
17
 
16
18
 
17
- class Timeout(abc.ABC):
19
+ class Timeout(Abstract):
18
20
  @property
19
21
  @abc.abstractmethod
20
22
  def can_expire(self) -> bool:
@@ -0,0 +1,23 @@
1
+ # ruff: noqa: UP006
2
+ import functools
3
+ import typing as ta
4
+
5
+
6
+ ##
7
+
8
+
9
+ _ANNOTATION_ATTRS: ta.FrozenSet[str] = frozenset([
10
+ '__annotations__',
11
+
12
+ '__annotate__',
13
+ '__annotate_func__',
14
+
15
+ '__annotations_cache__',
16
+ ])
17
+
18
+ _UPDATE_WRAPPER_ASSIGNMENTS_NO_ANNOTATIONS: ta.Sequence[str] = list(frozenset(functools.WRAPPER_ASSIGNMENTS) - _ANNOTATION_ATTRS) # noqa
19
+
20
+
21
+ def update_wrapper_no_annotations(wrapper, wrapped):
22
+ functools.update_wrapper(wrapper, wrapped, assigned=_UPDATE_WRAPPER_ASSIGNMENTS_NO_ANNOTATIONS)
23
+ return wrapper
omlish/logs/abc.py CHANGED
@@ -1,6 +1,4 @@
1
- # ruff: noqa: A002
2
- # ruff: noqa: N802
3
- # ruff: noqa: N815
1
+ # ruff: noqa: A002 N802 N815
4
2
  import types
5
3
  import typing as ta
6
4
 
@@ -94,6 +92,8 @@ class LogRecord:
94
92
 
95
93
 
96
94
  class Formatter(ta.Protocol):
95
+ """https://docs.python.org/3/library/logging.html#formatter-objects"""
96
+
97
97
  default_time_format: ta.ClassVar[str]
98
98
  default_msec_format: ta.ClassVar[str]
99
99
 
@@ -111,6 +111,8 @@ class Formatter(ta.Protocol):
111
111
 
112
112
 
113
113
  class BufferingFormatter(ta.Protocol):
114
+ """https://docs.python.org/3/library/logging.html#logging.BufferingFormatter"""
115
+
114
116
  def formatHeader(self, records: ta.Sequence[LogRecord]) -> str: ...
115
117
 
116
118
  def formatFooter(self, records: ta.Sequence[LogRecord]) -> str: ...
@@ -122,10 +124,14 @@ class BufferingFormatter(ta.Protocol):
122
124
 
123
125
 
124
126
  class Filter(ta.Protocol):
127
+ """https://docs.python.org/3/library/logging.html#filter-objects"""
128
+
125
129
  def filter(self, record: LogRecord) -> bool: ...
126
130
 
127
131
 
128
132
  class Filterer(ta.Protocol):
133
+ """A base class for loggers and handlers which allows them to share common code."""
134
+
129
135
  def addFilter(self, filter: Filter) -> None: ...
130
136
 
131
137
  def removeFilter(self, filter: Filter) -> None: ...
@@ -136,7 +142,9 @@ class Filterer(ta.Protocol):
136
142
  ##
137
143
 
138
144
 
139
- class Handler(ta.Protocol):
145
+ class Handler(Filterer, ta.Protocol):
146
+ """https://docs.python.org/3/library/logging.html#handler-objects"""
147
+
140
148
  level: Level
141
149
 
142
150
  def get_name(self) -> str: ...
@@ -176,7 +184,9 @@ class Stream(ta.Protocol):
176
184
  def close(self) -> None: ... # OPTIONAL METHOD
177
185
 
178
186
 
179
- class StreamHandler(Handler):
187
+ class StreamHandler(Handler, ta.Protocol):
188
+ """https://docs.python.org/3/library/logging.handlers.html#logging.StreamHandler"""
189
+
180
190
  terminator: ta.ClassVar[str]
181
191
 
182
192
  stream: Stream
@@ -192,6 +202,8 @@ class StreamHandler(Handler):
192
202
 
193
203
 
194
204
  class Manager(ta.Protocol):
205
+ """There is [under normal circumstances] just one Manager instance, which holds the hierarchy of loggers."""
206
+
195
207
  root: 'Logger'
196
208
 
197
209
  disable: Level
@@ -215,6 +227,8 @@ Caller: ta.TypeAlias = tuple[
215
227
 
216
228
 
217
229
  class Logger(Filterer, ta.Protocol):
230
+ """https://docs.python.org/3/library/logging.html#logger-objects"""
231
+
218
232
  name: str
219
233
  level: Level
220
234
  parent: ta.Optional['Logger']
@@ -274,6 +288,8 @@ class Logger(Filterer, ta.Protocol):
274
288
 
275
289
 
276
290
  class LoggerAdapter(ta.Protocol):
291
+ """https://docs.python.org/3/library/logging.html#loggeradapter-objects"""
292
+
277
293
  logger: Logger
278
294
  extra: ta.Mapping[str, ta.Any]
279
295
 
omlish/logs/all.py CHANGED
@@ -1,50 +1,68 @@
1
- from .callers import ( # noqa
2
- LoggingCaller,
3
- )
1
+ # rufF: noqa: I001
2
+ from .. import lang as _lang
4
3
 
5
- from .color import ( # noqa
6
- ColorLogFormatter,
7
- )
8
4
 
9
- from .filters import ( # noqa
10
- TidLogFilter,
11
- )
5
+ with _lang.auto_proxy_init(globals()):
6
+ ##
12
7
 
13
- from .handlers import ( # noqa
14
- ListHandler,
15
- )
8
+ from .callers import ( # noqa
9
+ LoggingCaller,
10
+ )
16
11
 
17
- from .json import ( # noqa
18
- JsonLogFormatter,
19
- )
12
+ from .color import ( # noqa
13
+ ColorLogFormatter,
14
+ )
20
15
 
21
- from .noisy import ( # noqa
22
- silence_noisy_loggers,
23
- )
16
+ from .filters import ( # noqa
17
+ TidLogFilter,
18
+ )
24
19
 
25
- from .protocol import ( # noqa
26
- LogLevel,
20
+ from .handlers import ( # noqa
21
+ ListHandler,
22
+ )
27
23
 
28
- Logging,
29
- NopLogging,
30
- AbstractLogging,
31
- StdlibLogging,
32
- )
24
+ from .json import ( # noqa
25
+ JsonLogFormatter,
26
+ )
33
27
 
34
- from .proxy import ( # noqa
35
- ProxyLogFilterer,
36
- ProxyLogHandler,
37
- )
28
+ from .levels import ( # noqa
29
+ LogLevel,
30
+ )
38
31
 
39
- from .standard import ( # noqa
40
- STANDARD_LOG_FORMAT_PARTS,
41
- StandardLogFormatter,
32
+ from .noisy import ( # noqa
33
+ silence_noisy_loggers,
34
+ )
42
35
 
43
- StandardConfiguredLogHandler,
36
+ from .protocol import ( # noqa
37
+ AnyLogging,
38
+ Logging,
39
+ AsyncLogging,
44
40
 
45
- configure_standard_logging,
46
- )
41
+ AnyAbstractLogging,
42
+ AbstractLogging,
43
+ AbstractAsyncLogging,
47
44
 
48
- from .utils import ( # noqa
49
- error_logging,
50
- )
45
+ AnyNopLogging,
46
+ NopLogging,
47
+ NopAsyncLogging,
48
+
49
+ StdlibLogging,
50
+ )
51
+
52
+ from .proxy import ( # noqa
53
+ ProxyLogFilterer,
54
+ ProxyLogHandler,
55
+ )
56
+
57
+ from .standard import ( # noqa
58
+ STANDARD_LOG_FORMAT_PARTS,
59
+ StandardLogFormatter,
60
+
61
+ StandardConfiguredLogHandler,
62
+
63
+ configure_standard_logging,
64
+ )
65
+
66
+ from .utils import ( # noqa
67
+ error_logging,
68
+ )
omlish/logs/configs.py CHANGED
@@ -1,17 +1,20 @@
1
+ # ruff: noqa: UP006 UP045
2
+ # @omlish-lite
1
3
  """
2
4
  https://docs.python.org/3/howto/logging.html#configuring-logging
5
+ https://docs.python.org/3/library/logging.config.html#logging-config-dictschema
3
6
  """
4
7
  import dataclasses as dc
5
8
  import typing as ta
6
9
 
7
10
 
8
- ##
11
+ FilterConfig = ta.Dict[str, ta.Any] # ta.TypeAlias
12
+ FormatterConfig = ta.Dict[str, ta.Any] # ta.TypeAlias
13
+ HandlerConfig = ta.Dict[str, ta.Any] # ta.TypeAlias
14
+ LoggerConfig = ta.Dict[str, ta.Any] # ta.TypeAlias
9
15
 
10
16
 
11
- FilterConfig: ta.TypeAlias = dict[str, ta.Any]
12
- FormatterConfig: ta.TypeAlias = dict[str, ta.Any]
13
- HandlerConfig: ta.TypeAlias = dict[str, ta.Any]
14
- LoggerConfig: ta.TypeAlias = dict[str, ta.Any]
17
+ ##
15
18
 
16
19
 
17
20
  @dc.dataclass()
@@ -19,8 +22,8 @@ class DictConfig:
19
22
  version: int = 1
20
23
  incremental: bool = False
21
24
  disable_existing_loggers: bool = False
22
- filters: dict[str, FilterConfig] = dc.field(default_factory=dict)
23
- formatters: dict[str, FormatterConfig] = dc.field(default_factory=dict)
24
- handlers: dict[str, HandlerConfig] = dc.field(default_factory=dict)
25
- loggers: dict[str, LoggerConfig] = dc.field(default_factory=dict)
26
- root: LoggerConfig | None = None
25
+ filters: ta.Dict[str, FilterConfig] = dc.field(default_factory=dict)
26
+ formatters: ta.Dict[str, FormatterConfig] = dc.field(default_factory=dict)
27
+ handlers: ta.Dict[str, HandlerConfig] = dc.field(default_factory=dict)
28
+ loggers: ta.Dict[str, LoggerConfig] = dc.field(default_factory=dict)
29
+ root: ta.Optional[LoggerConfig] = None
omlish/logs/levels.py ADDED
@@ -0,0 +1,4 @@
1
+ # @omlish-lite
2
+
3
+
4
+ LogLevel = int # ta.TypeAlias
omlish/logs/protocol.py CHANGED
@@ -6,49 +6,50 @@ import sys
6
6
  import typing as ta
7
7
 
8
8
  from .callers import LoggingCaller
9
+ from .levels import LogLevel
9
10
 
10
11
 
11
- LogLevel = int # ta.TypeAlias
12
+ T = ta.TypeVar('T')
13
+ T_co = ta.TypeVar('T_co', covariant=True)
12
14
 
13
15
 
14
16
  ##
15
17
 
16
18
 
17
- class Logging(ta.Protocol):
18
- def isEnabledFor(self, level: LogLevel) -> bool: # noqa
19
- ...
19
+ class AnyLogging(ta.Protocol[T_co]):
20
+ def isEnabledFor(self, level: LogLevel) -> bool: ... # noqa
20
21
 
21
- def getEffectiveLevel(self) -> LogLevel: # noqa
22
- ...
22
+ def getEffectiveLevel(self) -> LogLevel: ... # noqa
23
23
 
24
24
  #
25
25
 
26
- def debug(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
27
- ...
26
+ def debug(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T_co: ...
28
27
 
29
- def info(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
30
- ...
28
+ def info(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T_co: ...
31
29
 
32
- def warning(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
33
- ...
30
+ def warning(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T_co: ...
34
31
 
35
- def error(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
36
- ...
32
+ def error(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T_co: ...
37
33
 
38
- def exception(self, msg: str, *args: ta.Any, exc_info: bool = True, **kwargs) -> None:
39
- ...
34
+ def exception(self, msg: str, *args: ta.Any, exc_info: bool = True, **kwargs: ta.Any) -> T_co: ...
40
35
 
41
- def critical(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
42
- ...
36
+ def critical(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T_co: ...
43
37
 
44
- def log(self, level: LogLevel, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
45
- ...
38
+ def log(self, level: LogLevel, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T_co: ...
39
+
40
+
41
+ class Logging(AnyLogging[None], ta.Protocol):
42
+ pass
43
+
44
+
45
+ class AsyncLogging(AnyLogging[ta.Awaitable[None]], ta.Protocol):
46
+ pass
46
47
 
47
48
 
48
49
  ##
49
50
 
50
51
 
51
- class AbstractLogging(abc.ABC):
52
+ class AnyAbstractLogging(abc.ABC, ta.Generic[T]):
52
53
  @ta.final
53
54
  def isEnabledFor(self, level: LogLevel) -> bool: # noqa
54
55
  return self.is_enabled_for(level)
@@ -66,29 +67,38 @@ class AbstractLogging(abc.ABC):
66
67
 
67
68
  #
68
69
 
69
- def debug(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
70
- if self.is_enabled_for(logging.DEBUG):
71
- self.log(logging.DEBUG, msg, args, **kwargs)
70
+ def debug(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
71
+ return self.log(logging.DEBUG, msg, *args, **kwargs)
72
72
 
73
- def info(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
74
- if self.is_enabled_for(logging.INFO):
75
- self.log(logging.INFO, msg, args, **kwargs)
73
+ def info(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
74
+ return self.log(logging.INFO, msg, *args, **kwargs)
76
75
 
77
- def warning(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
78
- if self.is_enabled_for(logging.WARNING):
79
- self.log(logging.WARNING, msg, args, **kwargs)
76
+ def warning(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
77
+ return self.log(logging.WARNING, msg, *args, **kwargs)
80
78
 
81
- def error(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
82
- if self.is_enabled_for(logging.ERROR):
83
- self.log(logging.ERROR, msg, args, **kwargs)
79
+ def error(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
80
+ return self.log(logging.ERROR, msg, *args, **kwargs)
84
81
 
85
- def exception(self, msg: str, *args: ta.Any, exc_info: bool = True, **kwargs: ta.Any) -> None:
86
- self.error(msg, *args, exc_info=exc_info, **kwargs)
82
+ def exception(self, msg: str, *args: ta.Any, exc_info: bool = True, **kwargs: ta.Any) -> T:
83
+ return self.error(msg, *args, exc_info=exc_info, **kwargs)
87
84
 
88
- def critical(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
89
- if self.is_enabled_for(logging.CRITICAL):
90
- self.log(logging.CRITICAL, msg, args, **kwargs)
85
+ def critical(self, msg: str, *args: ta.Any, **kwargs: ta.Any) -> T:
86
+ return self.log(logging.CRITICAL, msg, *args, **kwargs)
91
87
 
88
+ @abc.abstractmethod
89
+ def log(
90
+ self,
91
+ level: int,
92
+ msg: str,
93
+ *args: ta.Any,
94
+ exc_info: ta.Any = None,
95
+ extra: ta.Any = None,
96
+ stack_info: bool = False,
97
+ ) -> T:
98
+ raise NotImplementedError
99
+
100
+
101
+ class AbstractLogging(AnyAbstractLogging[None], abc.ABC):
92
102
  def log(self, level: LogLevel, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
93
103
  if not isinstance(level, int):
94
104
  raise TypeError('Level must be an integer.')
@@ -109,17 +119,45 @@ class AbstractLogging(abc.ABC):
109
119
  raise NotImplementedError
110
120
 
111
121
 
122
+ class AbstractAsyncLogging(AnyAbstractLogging[ta.Awaitable[None]], abc.ABC):
123
+ async def log(self, level: LogLevel, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None:
124
+ if not isinstance(level, int):
125
+ raise TypeError('Level must be an integer.')
126
+ if self.is_enabled_for(level):
127
+ await self._log(level, msg, args, **kwargs)
128
+
129
+ @abc.abstractmethod
130
+ def _log(
131
+ self,
132
+ level: int,
133
+ msg: str,
134
+ args: ta.Any,
135
+ *,
136
+ exc_info: ta.Any = None,
137
+ extra: ta.Any = None,
138
+ stack_info: bool = False,
139
+ ) -> ta.Awaitable[None]:
140
+ raise NotImplementedError
141
+
142
+
112
143
  ##
113
144
 
114
145
 
115
- class NopLogging(AbstractLogging):
146
+ class AnyNopLogging(AnyAbstractLogging[T], abc.ABC):
116
147
  def get_effective_level(self) -> LogLevel:
117
148
  return logging.CRITICAL + 1
118
149
 
150
+
151
+ class NopLogging(AnyNopLogging[None], AbstractLogging):
119
152
  def _log(self, *args: ta.Any, **kwargs: ta.Any) -> None:
120
153
  pass
121
154
 
122
155
 
156
+ class NopAsyncLogging(AnyNopLogging[ta.Awaitable[None]], AbstractAsyncLogging):
157
+ async def _log(self, *args: ta.Any, **kwargs: ta.Any) -> None:
158
+ pass
159
+
160
+
123
161
  ##
124
162
 
125
163
 
@@ -9,6 +9,7 @@ TODO:
9
9
  - can't disambiguate from str - can't coexist in bare union
10
10
  - factories being free MatchFns does more harm than good - in practice these are such big guns you want to write a
11
11
  class body if only ceremonially
12
+ - simple lite interop like inj - alt ObjMarshalerManager impl for Context
12
13
 
13
14
  See:
14
15
  - https://github.com/python-attrs/cattrs
omlish/os/atomics.py CHANGED
@@ -6,6 +6,7 @@ import shutil
6
6
  import tempfile
7
7
  import typing as ta
8
8
 
9
+ from ..lite.abstract import Abstract
9
10
  from ..lite.check import check
10
11
  from ..lite.strings import attr_repr
11
12
 
@@ -17,7 +18,7 @@ AtomicPathSwapState = ta.Literal['open', 'committed', 'aborted'] # ta.TypeAlias
17
18
  ##
18
19
 
19
20
 
20
- class AtomicPathSwap(abc.ABC):
21
+ class AtomicPathSwap(Abstract):
21
22
  def __init__(
22
23
  self,
23
24
  kind: AtomicPathSwapKind,
@@ -105,7 +106,7 @@ class AtomicPathSwap(abc.ABC):
105
106
  self.abort()
106
107
 
107
108
 
108
- class AtomicPathSwapping(abc.ABC):
109
+ class AtomicPathSwapping(Abstract):
109
110
  @abc.abstractmethod
110
111
  def begin_atomic_path_swap(
111
112
  self,
@@ -5,11 +5,13 @@ import sys
5
5
  import time
6
6
  import typing as ta
7
7
 
8
+ from ... import lang
9
+
8
10
 
9
11
  ##
10
12
 
11
13
 
12
- class Deathpact(abc.ABC):
14
+ class Deathpact(lang.Abstract):
13
15
  @abc.abstractmethod
14
16
  def poll(self) -> None:
15
17
  raise NotImplementedError
@@ -23,7 +25,7 @@ class NopDeathpact(Deathpact):
23
25
  ##
24
26
 
25
27
 
26
- class BaseDeathpact(Deathpact, abc.ABC):
28
+ class BaseDeathpact(Deathpact, lang.Abstract):
27
29
  def __init__(
28
30
  self,
29
31
  *,
omlish/os/forkhooks.py CHANGED
@@ -1,10 +1,10 @@
1
1
  # ruff: noqa: UP006 UP007 UP045
2
2
  # @omlish-lite
3
- import abc
4
3
  import os
5
4
  import threading
6
5
  import typing as ta
7
6
 
7
+ from ..lite.abstract import Abstract
8
8
  from ..lite.check import check
9
9
 
10
10
 
@@ -145,7 +145,7 @@ class _ForkHookManager:
145
145
  #
146
146
 
147
147
 
148
- class ForkHook(abc.ABC): # noqa
148
+ class ForkHook(Abstract):
149
149
  @ta.final
150
150
  def __new__(cls, *args, **kwargs): # noqa
151
151
  raise TypeError
@@ -27,6 +27,7 @@ import typing as ta
27
27
 
28
28
  from ...diag.lslocks import LslocksCommand
29
29
  from ...diag.lsof import LsofCommand
30
+ from ...lite.abstract import Abstract
30
31
  from ...lite.check import check
31
32
  from ...lite.timeouts import Timeout
32
33
  from ...lite.timeouts import TimeoutLike
@@ -37,7 +38,7 @@ from .pidfile import Pidfile
37
38
  ##
38
39
 
39
40
 
40
- class PidfilePinner(abc.ABC):
41
+ class PidfilePinner(Abstract):
41
42
  def __init__(
42
43
  self,
43
44
  *,
omlish/reflect/types.py CHANGED
@@ -16,12 +16,13 @@ TODO:
16
16
  - cache this shit, esp generic_mro shit
17
17
  - cache __hash__ in Generic/Union
18
18
  """
19
- import abc
20
19
  import dataclasses as dc
21
20
  import threading
22
21
  import types
23
22
  import typing as ta
24
23
 
24
+ from ..lite.abstract import Abstract
25
+
25
26
 
26
27
  _NoneType = types.NoneType # type: ignore
27
28
 
@@ -275,7 +276,7 @@ def get_type_var_bound(obj: ta.Any) -> ta.Any:
275
276
  ##
276
277
 
277
278
 
278
- class TypeInfo(abc.ABC): # noqa
279
+ class TypeInfo(Abstract):
279
280
  pass
280
281
 
281
282
 
@@ -320,7 +321,7 @@ GenericLikeCls = ta.TypeVar('GenericLikeCls')
320
321
 
321
322
 
322
323
  @dc.dataclass(frozen=True)
323
- class GenericLike(TypeInfo, abc.ABC, ta.Generic[GenericLikeCls]):
324
+ class GenericLike(TypeInfo, Abstract, ta.Generic[GenericLikeCls]):
324
325
  cls: GenericLikeCls
325
326
 
326
327
  # args and params are the same length - params maps to the generic origin's params:
omlish/secrets/crypto.py CHANGED
@@ -58,7 +58,7 @@ class DecryptionError(Exception):
58
58
  pass
59
59
 
60
60
 
61
- class Crypto(abc.ABC):
61
+ class Crypto(lang.Abstract):
62
62
  @abc.abstractmethod
63
63
  def generate_key(self) -> bytes:
64
64
  raise NotImplementedError
omlish/sockets/bind.py CHANGED
@@ -15,6 +15,7 @@ import socket as socket_
15
15
  import stat
16
16
  import typing as ta
17
17
 
18
+ from ..lite.abstract import Abstract
18
19
  from ..lite.check import check
19
20
  from ..lite.dataclasses import dataclass_maybe_post_init
20
21
  from .addresses import SocketAddress
@@ -31,7 +32,7 @@ CanSocketBinder = ta.Union['SocketBinder', CanSocketBinderConfig] # ta.TypeAlia
31
32
  ##
32
33
 
33
34
 
34
- class SocketBinder(abc.ABC, ta.Generic[SocketBinderConfigT]):
35
+ class SocketBinder(Abstract, ta.Generic[SocketBinderConfigT]):
35
36
  @dc.dataclass(frozen=True)
36
37
  class Config:
37
38
  listen_backlog: int = 5
@@ -3,8 +3,9 @@
3
3
  import abc
4
4
  import typing as ta
5
5
 
6
+ from ..lite.abstract import Abstract
6
7
  from .addresses import SocketAddress
7
- from .io import SocketIoPair # noqa
8
+ from .io import SocketIoPair
8
9
 
9
10
 
10
11
  SocketHandler = ta.Callable[[SocketAddress, 'SocketIoPair'], None] # ta.TypeAlias
@@ -13,7 +14,7 @@ SocketHandler = ta.Callable[[SocketAddress, 'SocketIoPair'], None] # ta.TypeAli
13
14
  ##
14
15
 
15
16
 
16
- class SocketHandler_(abc.ABC): # noqa
17
+ class SocketHandler_(Abstract): # noqa
17
18
  @abc.abstractmethod
18
19
  def __call__(self, addr: SocketAddress, f: SocketIoPair) -> None:
19
20
  raise NotImplementedError
@@ -7,6 +7,7 @@ import logging
7
7
  import socket
8
8
  import typing as ta
9
9
 
10
+ from ...lite.abstract import Abstract
10
11
  from ..addresses import SocketAndAddress
11
12
  from ..handlers import SocketHandler
12
13
  from ..io import SocketIoPair
@@ -19,7 +20,7 @@ SocketServerHandler = ta.Callable[['SocketAndAddress'], None] # ta.TypeAlias
19
20
  ##
20
21
 
21
22
 
22
- class SocketServerHandler_(abc.ABC): # noqa
23
+ class SocketServerHandler_(Abstract): # noqa
23
24
  @abc.abstractmethod
24
25
  def __call__(self, conn: SocketAndAddress) -> None:
25
26
  raise NotImplementedError