omlish 0.0.0.dev219__py3-none-any.whl → 0.0.0.dev220__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 (36) hide show
  1. omlish/__about__.py +2 -2
  2. omlish/antlr/dot.py +13 -6
  3. omlish/dataclasses/__init__.py +1 -0
  4. omlish/dataclasses/impl/api.py +10 -0
  5. omlish/dataclasses/impl/fields.py +8 -1
  6. omlish/dataclasses/impl/init.py +1 -1
  7. omlish/dataclasses/impl/main.py +1 -1
  8. omlish/dataclasses/impl/metaclass.py +112 -29
  9. omlish/dataclasses/impl/overrides.py +53 -0
  10. omlish/dataclasses/impl/params.py +3 -0
  11. omlish/dataclasses/impl/reflect.py +17 -5
  12. omlish/dataclasses/impl/simple.py +0 -42
  13. omlish/http/coro/server.py +58 -38
  14. omlish/http/handlers.py +8 -0
  15. omlish/io/fileno.py +11 -0
  16. omlish/lang/__init__.py +4 -1
  17. omlish/lang/cached.py +0 -1
  18. omlish/lang/classes/__init__.py +3 -1
  19. omlish/lang/classes/abstract.py +14 -1
  20. omlish/lang/classes/restrict.py +5 -5
  21. omlish/lang/classes/virtual.py +0 -1
  22. omlish/lang/clsdct.py +0 -1
  23. omlish/lang/contextmanagers.py +0 -8
  24. omlish/lang/descriptors.py +0 -1
  25. omlish/lang/maybes.py +0 -1
  26. omlish/lang/objects.py +0 -2
  27. omlish/secrets/ssl.py +9 -0
  28. omlish/secrets/tempssl.py +50 -0
  29. omlish/sockets/bind.py +6 -1
  30. omlish/sockets/server/server.py +18 -5
  31. {omlish-0.0.0.dev219.dist-info → omlish-0.0.0.dev220.dist-info}/METADATA +1 -1
  32. {omlish-0.0.0.dev219.dist-info → omlish-0.0.0.dev220.dist-info}/RECORD +36 -32
  33. {omlish-0.0.0.dev219.dist-info → omlish-0.0.0.dev220.dist-info}/LICENSE +0 -0
  34. {omlish-0.0.0.dev219.dist-info → omlish-0.0.0.dev220.dist-info}/WHEEL +0 -0
  35. {omlish-0.0.0.dev219.dist-info → omlish-0.0.0.dev220.dist-info}/entry_points.txt +0 -0
  36. {omlish-0.0.0.dev219.dist-info → omlish-0.0.0.dev220.dist-info}/top_level.txt +0 -0
omlish/http/handlers.py CHANGED
@@ -33,12 +33,20 @@ class HttpHandlerResponse:
33
33
  data: ta.Optional[HttpHandlerResponseData] = None
34
34
  close_connection: ta.Optional[bool] = None
35
35
 
36
+ def close(self) -> None:
37
+ if isinstance(d := self.data, HttpHandlerResponseStreamedData):
38
+ d.close()
39
+
36
40
 
37
41
  @dc.dataclass(frozen=True)
38
42
  class HttpHandlerResponseStreamedData:
39
43
  iter: ta.Iterable[bytes]
40
44
  length: ta.Optional[int] = None
41
45
 
46
+ def close(self) -> None:
47
+ if hasattr(d := self.iter, 'close'):
48
+ d.close() # noqa
49
+
42
50
 
43
51
  class HttpHandlerError(Exception):
44
52
  pass
omlish/io/fileno.py ADDED
@@ -0,0 +1,11 @@
1
+ # ruff: noqa: UP006 UP007
2
+ # @omlish-lite
3
+ import dataclasses as dc
4
+
5
+
6
+ @dc.dataclass(frozen=True)
7
+ class Fileno:
8
+ fd: int
9
+
10
+ def fileno(self) -> int:
11
+ return self.fd
omlish/lang/__init__.py CHANGED
@@ -6,11 +6,12 @@ from .cached import ( # noqa
6
6
 
7
7
  from .classes import ( # noqa
8
8
  Abstract,
9
+ AbstractTypeError,
9
10
  AnySensitive,
10
11
  Callable,
11
12
  Descriptor,
12
13
  Final,
13
- FinalError,
14
+ FinalTypeError,
14
15
  LazySingleton,
15
16
  Marker,
16
17
  Namespace,
@@ -26,6 +27,7 @@ from .classes import ( # noqa
26
27
  SimpleMetaDict,
27
28
  Singleton,
28
29
  Virtual,
30
+ get_abstract_methods,
29
31
  is_abstract,
30
32
  is_abstract_class,
31
33
  is_abstract_method,
@@ -52,6 +54,7 @@ from .cmp import ( # noqa
52
54
 
53
55
  from .contextmanagers import ( # noqa
54
56
  AsyncContextManager,
57
+ AsyncExitStacked,
55
58
  ContextManaged,
56
59
  ContextManager,
57
60
  ContextWrapped,
omlish/lang/cached.py CHANGED
@@ -158,7 +158,6 @@ class _CachedFunction(ta.Generic[T]):
158
158
 
159
159
 
160
160
  class _CachedFunctionDescriptor(_CachedFunction[T]):
161
-
162
161
  def __init__(
163
162
  self,
164
163
  fn: ta.Callable[P, T],
@@ -1,5 +1,7 @@
1
1
  from .abstract import ( # noqa
2
2
  Abstract,
3
+ AbstractTypeError,
4
+ get_abstract_methods,
3
5
  is_abstract,
4
6
  is_abstract_class,
5
7
  is_abstract_method,
@@ -10,7 +12,7 @@ from .abstract import ( # noqa
10
12
  from .restrict import ( # noqa
11
13
  AnySensitive,
12
14
  Final,
13
- FinalError,
15
+ FinalTypeError,
14
16
  NoBool,
15
17
  NotInstantiable,
16
18
  NotPicklable,
@@ -11,6 +11,8 @@ _ABSTRACT_METHODS_ATTR = '__abstractmethods__'
11
11
  _IS_ABSTRACT_METHOD_ATTR = '__isabstractmethod__'
12
12
  _FORCE_ABSTRACT_ATTR = '__forceabstract__'
13
13
 
14
+ _INTERNAL_ABSTRACT_ATTRS = frozenset([_FORCE_ABSTRACT_ATTR])
15
+
14
16
 
15
17
  def make_abstract(obj: T) -> T:
16
18
  if callable(obj):
@@ -27,6 +29,10 @@ def make_abstract(obj: T) -> T:
27
29
  return obj
28
30
 
29
31
 
32
+ class AbstractTypeError(TypeError):
33
+ pass
34
+
35
+
30
36
  class Abstract(abc.ABC): # noqa
31
37
  __slots__ = ()
32
38
 
@@ -50,7 +56,7 @@ class Abstract(abc.ABC): # noqa
50
56
  ams.update(set(getattr(b, _ABSTRACT_METHODS_ATTR, [])) - seen)
51
57
  seen.update(dir(b))
52
58
  if ams:
53
- raise TypeError(
59
+ raise AbstractTypeError(
54
60
  f'Cannot subclass abstract class {cls.__name__} with abstract methods: '
55
61
  f'{", ".join(map(str, sorted(ams)))}',
56
62
  )
@@ -78,6 +84,13 @@ def is_abstract(obj: ta.Any) -> bool:
78
84
  return is_abstract_method(obj) or is_abstract_class(obj)
79
85
 
80
86
 
87
+ def get_abstract_methods(cls: type, *, include_internal: bool = False) -> frozenset[str]:
88
+ ms = frozenset(getattr(cls, _ABSTRACT_METHODS_ATTR))
89
+ if not include_internal:
90
+ ms -= _INTERNAL_ABSTRACT_ATTRS
91
+ return ms
92
+
93
+
81
94
  def unabstract_class(
82
95
  members: ta.Iterable[str | tuple[str, ta.Any]],
83
96
  ): # -> ta.Callable[[type[T]], type[T]]:
@@ -9,7 +9,7 @@ from .abstract import is_abstract
9
9
  ##
10
10
 
11
11
 
12
- class FinalError(TypeError):
12
+ class FinalTypeError(TypeError):
13
13
  def __init__(self, _type: type) -> None:
14
14
  super().__init__()
15
15
 
@@ -28,11 +28,11 @@ class Final(Abstract):
28
28
  abstracts: set[ta.Any] = set()
29
29
  for base in cls.__bases__:
30
30
  if base is Abstract:
31
- raise FinalError(base)
31
+ raise FinalTypeError(base)
32
32
  elif base is Final:
33
33
  continue
34
34
  elif Final in base.__mro__:
35
- raise FinalError(base)
35
+ raise FinalTypeError(base)
36
36
  else:
37
37
  abstracts.update(getattr(base, '__abstractmethods__', []))
38
38
 
@@ -40,9 +40,9 @@ class Final(Abstract):
40
40
  try:
41
41
  v = cls.__dict__[a]
42
42
  except KeyError:
43
- raise FinalError(a) from None
43
+ raise FinalTypeError(a) from None
44
44
  if is_abstract(v):
45
- raise FinalError(a)
45
+ raise FinalTypeError(a)
46
46
 
47
47
 
48
48
  ##
@@ -28,7 +28,6 @@ def _make_not_instantiable():
28
28
 
29
29
 
30
30
  class _VirtualMeta(abc.ABCMeta):
31
-
32
31
  def __new__(mcls, name, bases, namespace):
33
32
  if 'Virtual' not in globals():
34
33
  return super().__new__(mcls, name, bases, namespace)
omlish/lang/clsdct.py CHANGED
@@ -36,7 +36,6 @@ def get_caller_cls_dct(offset: int = 0) -> ta.MutableMapping[str, ta.Any]:
36
36
 
37
37
 
38
38
  class ClassDctFn:
39
-
40
39
  def __init__(self, fn: ta.Callable, offset: int | None = None, *, wrap=True) -> None:
41
40
  super().__init__()
42
41
 
@@ -19,7 +19,6 @@ T = ta.TypeVar('T')
19
19
 
20
20
 
21
21
  class ContextManaged:
22
-
23
22
  def __enter__(self) -> ta.Self:
24
23
  return self
25
24
 
@@ -33,7 +32,6 @@ class ContextManaged:
33
32
 
34
33
 
35
34
  class NopContextManaged(ContextManaged):
36
-
37
35
  def __init_subclass__(cls, **kwargs: ta.Any) -> None:
38
36
  raise TypeError
39
37
 
@@ -42,7 +40,6 @@ NOP_CONTEXT_MANAGED = NopContextManaged()
42
40
 
43
41
 
44
42
  class NopContextManager:
45
-
46
43
  def __init_subclass__(cls, **kwargs: ta.Any) -> None:
47
44
  raise TypeError
48
45
 
@@ -57,7 +54,6 @@ NOP_CONTEXT_MANAGER = NopContextManager()
57
54
 
58
55
 
59
56
  class ContextManager(abc.ABC, ta.Generic[T]):
60
-
61
57
  def __init_subclass__(cls, **kwargs: ta.Any) -> None:
62
58
  super().__init_subclass__(**kwargs)
63
59
 
@@ -87,7 +83,6 @@ class ContextManager(abc.ABC, ta.Generic[T]):
87
83
 
88
84
 
89
85
  class AsyncContextManager(abc.ABC, ta.Generic[T]):
90
-
91
86
  def __init_subclass__(cls, **kwargs: ta.Any) -> None:
92
87
  super().__init_subclass__(**kwargs)
93
88
 
@@ -191,7 +186,6 @@ def attr_setting(obj, attr, val, *, default=None): # noqa
191
186
 
192
187
 
193
188
  class ExitStacked:
194
-
195
189
  @property
196
190
  def _exit_stack(self) -> contextlib.ExitStack:
197
191
  try:
@@ -229,7 +223,6 @@ class ExitStacked:
229
223
 
230
224
 
231
225
  class AsyncExitStacked:
232
-
233
226
  @property
234
227
  def _exit_stack(self) -> contextlib.AsyncExitStack:
235
228
  try:
@@ -276,7 +269,6 @@ ContextWrappable: ta.TypeAlias = ta.ContextManager | str | ta.Callable[..., ta.C
276
269
 
277
270
 
278
271
  class ContextWrapped:
279
-
280
272
  def __init__(self, fn: ta.Callable, cm: str | ContextWrappable) -> None:
281
273
  super().__init__()
282
274
 
@@ -197,7 +197,6 @@ decorator = _decorator
197
197
 
198
198
 
199
199
  class AccessForbiddenError(Exception):
200
-
201
200
  def __init__(self, name: str | None = None, *args: ta.Any, **kwargs: ta.Any) -> None:
202
201
  super().__init__(*((name,) if name is not None else ()), *args, **kwargs) # noqa
203
202
  self.name = name
omlish/lang/maybes.py CHANGED
@@ -11,7 +11,6 @@ class ValueNotPresentException(BaseException):
11
11
 
12
12
 
13
13
  class Maybe(abc.ABC, ta.Generic[T]):
14
-
15
14
  @property
16
15
  @abc.abstractmethod
17
16
  def present(self) -> bool:
omlish/lang/objects.py CHANGED
@@ -140,9 +140,7 @@ def dir_dict(o: ta.Any) -> dict[str, ta.Any]:
140
140
 
141
141
 
142
142
  class SimpleProxy(ta.Generic[T]):
143
-
144
143
  class Descriptor:
145
-
146
144
  def __init__(self, attr: str) -> None:
147
145
  super().__init__()
148
146
  self._attr = attr
omlish/secrets/ssl.py ADDED
@@ -0,0 +1,9 @@
1
+ # @omlish-lite
2
+ # ruff: noqa: UP006 UP007
3
+ import dataclasses as dc
4
+
5
+
6
+ @dc.dataclass(frozen=True)
7
+ class SslCert:
8
+ key_file: str
9
+ cert_file: str
@@ -0,0 +1,50 @@
1
+ # @omlish-lite
2
+ # ruff: noqa: UP006 UP007
3
+ import os.path
4
+ import subprocess
5
+ import tempfile
6
+ import typing as ta
7
+
8
+ from .ssl import SslCert
9
+
10
+
11
+ class TempSslCert(ta.NamedTuple):
12
+ cert: SslCert
13
+ temp_dir: str
14
+
15
+
16
+ def generate_temp_localhost_ssl_cert() -> TempSslCert:
17
+ temp_dir = tempfile.mkdtemp()
18
+
19
+ proc = subprocess.run(
20
+ [
21
+ 'openssl',
22
+ 'req',
23
+ '-x509',
24
+ '-newkey', 'rsa:2048',
25
+
26
+ '-keyout', 'key.pem',
27
+ '-out', 'cert.pem',
28
+
29
+ '-days', '365',
30
+
31
+ '-nodes',
32
+
33
+ '-subj', '/CN=localhost',
34
+ '-addext', 'subjectAltName = DNS:localhost,IP:127.0.0.1',
35
+ ],
36
+ cwd=temp_dir,
37
+ capture_output=True,
38
+ check=False,
39
+ )
40
+
41
+ if proc.returncode:
42
+ raise RuntimeError(f'Failed to generate temp ssl cert: {proc.stderr=}')
43
+
44
+ return TempSslCert(
45
+ SslCert(
46
+ key_file=os.path.join(temp_dir, 'key.pem'),
47
+ cert_file=os.path.join(temp_dir, 'cert.pem'),
48
+ ),
49
+ temp_dir,
50
+ )
omlish/sockets/bind.py CHANGED
@@ -2,7 +2,10 @@
2
2
  # @omlish-lite
3
3
  """
4
4
  TODO:
5
+ - def parse: (<bind>)?:<port>, unix://, fd://
6
+ - unix chown/chgrp
5
7
  - DupSocketBinder
8
+ - udp
6
9
  """
7
10
  import abc
8
11
  import dataclasses as dc
@@ -20,6 +23,7 @@ from omlish.sockets.addresses import SocketAndAddress
20
23
 
21
24
  SocketBinderT = ta.TypeVar('SocketBinderT', bound='SocketBinder')
22
25
  SocketBinderConfigT = ta.TypeVar('SocketBinderConfigT', bound='SocketBinder.Config')
26
+
23
27
  CanSocketBinderConfig = ta.Union['SocketBinder.Config', int, ta.Tuple[str, int], str] # ta.TypeAlias
24
28
  CanSocketBinder = ta.Union['SocketBinder', CanSocketBinderConfig] # ta.TypeAlias
25
29
 
@@ -308,7 +312,8 @@ class UnixSocketBinder(SocketBinder):
308
312
 
309
313
  if self._config.unlink:
310
314
  try:
311
- os.unlink(self._config.file)
315
+ if stat.S_ISSOCK(os.stat(self._config.file).st_mode):
316
+ os.unlink(self._config.file)
312
317
  except FileNotFoundError:
313
318
  pass
314
319
 
@@ -2,10 +2,12 @@
2
2
  # ruff: noqa: UP006 UP007
3
3
  import abc
4
4
  import contextlib
5
+ import logging
5
6
  import selectors
6
7
  import threading
7
8
  import typing as ta
8
9
 
10
+ from ..addresses import SocketAndAddress
9
11
  from ..bind import SocketBinder
10
12
  from ..io import close_socket_immediately
11
13
  from .handlers import SocketServerHandler
@@ -15,12 +17,15 @@ from .handlers import SocketServerHandler
15
17
 
16
18
 
17
19
  class SocketServer(abc.ABC):
20
+ _DEFAULT_LOGGER = logging.getLogger('.'.join([__name__, 'SocketServer']))
21
+
18
22
  def __init__(
19
23
  self,
20
24
  binder: SocketBinder,
21
25
  handler: SocketServerHandler,
22
26
  *,
23
- on_error: ta.Optional[ta.Callable[[BaseException], None]] = None,
27
+ on_error: ta.Optional[ta.Callable[[BaseException, ta.Optional[SocketAndAddress]], None]] = None,
28
+ error_logger: ta.Optional[logging.Logger] = _DEFAULT_LOGGER,
24
29
  poll_interval: float = .5,
25
30
  shutdown_timeout: ta.Optional[float] = None,
26
31
  ) -> None:
@@ -29,6 +34,7 @@ class SocketServer(abc.ABC):
29
34
  self._binder = binder
30
35
  self._handler = handler
31
36
  self._on_error = on_error
37
+ self._error_logger = error_logger
32
38
  self._poll_interval = poll_interval
33
39
  self._shutdown_timeout = shutdown_timeout
34
40
 
@@ -46,6 +52,15 @@ class SocketServer(abc.ABC):
46
52
 
47
53
  #
48
54
 
55
+ def _handle_error(self, exc: BaseException, conn: ta.Optional[SocketAndAddress] = None) -> None:
56
+ if (error_logger := self._error_logger) is not None:
57
+ error_logger.exception('Error in socket server: %r', conn)
58
+
59
+ if (on_error := self._on_error) is not None:
60
+ on_error(exc, conn)
61
+
62
+ #
63
+
49
64
  class SelectorProtocol(ta.Protocol):
50
65
  def register(self, *args, **kwargs) -> None:
51
66
  raise NotImplementedError
@@ -100,8 +115,7 @@ class SocketServer(abc.ABC):
100
115
  conn = self._binder.accept()
101
116
 
102
117
  except OSError as exc:
103
- if (on_error := self._on_error) is not None:
104
- on_error(exc)
118
+ self._handle_error(exc)
105
119
 
106
120
  return
107
121
 
@@ -109,8 +123,7 @@ class SocketServer(abc.ABC):
109
123
  self._handler(conn)
110
124
 
111
125
  except Exception as exc: # noqa
112
- if (on_error := self._on_error) is not None:
113
- on_error(exc)
126
+ self._handle_error(exc, conn)
114
127
 
115
128
  close_socket_immediately(conn.socket)
116
129
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: omlish
3
- Version: 0.0.0.dev219
3
+ Version: 0.0.0.dev220
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=YGmAnUBszmosQQ_7Hh2wwtDiYdYZ4unNKYzOtALuels,7968
2
- omlish/__about__.py,sha256=XK2FqqJrrqiv22AiJ0Zjsv-tVj5fAtCQ0g6QGY3-xtU,3380
2
+ omlish/__about__.py,sha256=4MxdtmyseRyrqsGb-8ZzKRlrqSzhp5cQ5hkCmiaDCZc,3380
3
3
  omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
4
4
  omlish/c3.py,sha256=ubu7lHwss5V4UznbejAI0qXhXahrU01MysuHOZI9C4U,8116
5
5
  omlish/cached.py,sha256=UI-XTFBwA6YXWJJJeBn-WkwBkfzDjLBBaZf4nIJA9y0,510
@@ -15,7 +15,7 @@ omlish/subprocesses.py,sha256=c7arxsQ7JiaNCmK3GKqwRO6BwrvxeK7eez8A4SrvGBo,10199
15
15
  omlish/sync.py,sha256=QJ79kxmIqDP9SeHDoZAf--DpFIhDQe1jACy8H4N0yZI,2928
16
16
  omlish/antlr/__init__.py,sha256=88bMl_28cfSKslgOkMGYXqALgsHz3KC4LFvAVtzj7k8,89
17
17
  omlish/antlr/delimit.py,sha256=3Byvh9_Ip8ftM_SeSEmMbnNo1jrxk-xm8HnHDp_nDaI,3466
18
- omlish/antlr/dot.py,sha256=uH2X7-8xNLYDQNJ30uW8ssv1MLkZSm07GsalcRuunYI,817
18
+ omlish/antlr/dot.py,sha256=W9cgprtAZH6EjUkzWfSbx2XUUYRYLLxFofGWrUp-368,956
19
19
  omlish/antlr/errors.py,sha256=foYz2109WReT1C7qZsIrb4zCAkZg4vM_UiDOAPC0AqQ,308
20
20
  omlish/antlr/input.py,sha256=baeO279AIxR50pymya0eabtnc2A0bSdA5u7jvIGebzA,2090
21
21
  omlish/antlr/parsing.py,sha256=kXxeGb5luiwhSyIcXO2mLLME7IJLF6-0XMuS4UcDbcw,1414
@@ -169,30 +169,31 @@ omlish/configs/processing/matching.py,sha256=R64RxpPB1uX5Ztvvk2dQ2xi_xwlaxkxQgZw
169
169
  omlish/configs/processing/names.py,sha256=weHmaTclzgM9lUn3aBtw-kwZ3mc2N-CZlFg3Kd_UsKo,1093
170
170
  omlish/configs/processing/rewriting.py,sha256=v7PfHtuTn5v_5Y6Au7oMN2Z0nxAMy1iYyO5CXnTvZhs,4226
171
171
  omlish/configs/processing/strings.py,sha256=qFS2oh6z02IaM_q4lTKLdufzkJqAJ6J-Qjrz5S-QJoM,826
172
- omlish/dataclasses/__init__.py,sha256=4LYQCg0kqBNwexcXvK6drjxdi79sMvqa4augNhCBHLU,1543
172
+ omlish/dataclasses/__init__.py,sha256=D7I6ZJjEFeLN2re8oOZ_7JKWiG2plrPnaUFq3iEXYmQ,1553
173
173
  omlish/dataclasses/utils.py,sha256=N2seT8cJtfOv-41D7F3E-q4us-FCTQmnxxPv3dt1OcI,3796
174
174
  omlish/dataclasses/impl/LICENSE,sha256=Oy-B_iHRgcSZxZolbI4ZaEVdZonSaaqFNzv7avQdo78,13936
175
175
  omlish/dataclasses/impl/__init__.py,sha256=zqGBC5gSbjJxaqG_zS1LL1PX-zAfhIua8UqOE4IwO2k,789
176
- omlish/dataclasses/impl/api.py,sha256=p7W519_EnDAWlkOVS-4BpP4SxadWIiUzC3RldSoB28o,6431
176
+ omlish/dataclasses/impl/api.py,sha256=RhU4f50GVdn-dxilia8NA3F7VIm2R5z78pFfpIVXPRQ,6635
177
177
  omlish/dataclasses/impl/as_.py,sha256=CD-t7hkC1EP2F_jvZKIA_cVoDuwZ-Ln_xC4fJumPYX0,2598
178
178
  omlish/dataclasses/impl/copy.py,sha256=Tn8_n6Vohs-w4otbGdubBEvhd3TsSTaM3EfNGdS2LYo,591
179
179
  omlish/dataclasses/impl/descriptors.py,sha256=rEYE1Len99agTQCC25hSPMnM19BgPr0ZChABGi58Fdk,2476
180
180
  omlish/dataclasses/impl/exceptions.py,sha256=-vqxZmfXVflymVuiM553XTlJProse5HEMktTpfdPCIY,1275
181
- omlish/dataclasses/impl/fields.py,sha256=4_5qMz9LlOS6U67cDKQ-oorTtSGGxR77I4hw88soM44,6878
181
+ omlish/dataclasses/impl/fields.py,sha256=8p7Uzvr0C4yBR0NqHzkq--OY2HXFQlGsb1HC3K17-7k,6985
182
182
  omlish/dataclasses/impl/frozen.py,sha256=x87DSM8FIMZ3c_BIUE8NooCkExFjPsabeqIueEP5qKs,2988
183
183
  omlish/dataclasses/impl/hashing.py,sha256=0Gr6XIRkKy4pr-mdHblIlQCy3mBxycjMqJk3oZDw43s,3215
184
- omlish/dataclasses/impl/init.py,sha256=5kYcMDlI6EVeLQ6RCTk1bvYjb-cwg0AYfVE9FPZJlYI,6365
184
+ omlish/dataclasses/impl/init.py,sha256=drt_-697uw2xp0FGj9AYlMbiuSfYRNV3-8JxTPzkP_w,6415
185
185
  omlish/dataclasses/impl/internals.py,sha256=UvZYjrLT1S8ntyxJ_vRPIkPOF00K8HatGAygErgoXTU,2990
186
- omlish/dataclasses/impl/main.py,sha256=Ti0PKbFKraKvfmoPuR-G7nLVNzRC8mvEuXhCuC-M2kc,2574
187
- omlish/dataclasses/impl/metaclass.py,sha256=_iBp9HZvgokKKCbe8GlrcJ9HRrx3DufgzbxJHUy1Axg,3241
186
+ omlish/dataclasses/impl/main.py,sha256=LyWr8IBfoL-bBfweR4OqJgi842REDw20WRYcGSYNfMg,2577
187
+ omlish/dataclasses/impl/metaclass.py,sha256=dOtNkMqAP_QyZUX0rUwY2c-bkFsTHWo6DhnuW6s1dXc,5103
188
188
  omlish/dataclasses/impl/metadata.py,sha256=4veWwTr-aA0KP-Y1cPEeOcXHup9EKJTYNJ0ozIxtzD4,1401
189
189
  omlish/dataclasses/impl/order.py,sha256=zWvWDkSTym8cc7vO1cLHqcBhhjOlucHOCUVJcdh4jt0,1369
190
- omlish/dataclasses/impl/params.py,sha256=MWRL0IhulYP0dycWnK3j-0ej0uTgeE_jIlKFiE9MnI0,2836
190
+ omlish/dataclasses/impl/overrides.py,sha256=g9aCzaDDKyek8-yXRvtAcu1B1nCphWDYr4InHDlgbKk,1732
191
+ omlish/dataclasses/impl/params.py,sha256=9EHn7PxqPVtRPcNDNDCsbcmxvkezWR5LzLLxCua2Vok,2946
191
192
  omlish/dataclasses/impl/processing.py,sha256=DFxyFjL_h3awRyF_5eyTnB8QkuApx7Zc4QFnVoltlao,459
192
- omlish/dataclasses/impl/reflect.py,sha256=-yEkg30fOHmMf5LQbzy6DFuDpQjuljsfV517_a74VAc,5365
193
+ omlish/dataclasses/impl/reflect.py,sha256=1PTxx3ycsWhC3oAV71mW-ZquDRwa2-t9uIaKFO8ab8U,5468
193
194
  omlish/dataclasses/impl/replace.py,sha256=wS9GHX4fIwaPv1JBJzIewdBfXyK3X3V7_t55Da87dYo,1217
194
195
  omlish/dataclasses/impl/repr.py,sha256=oLXBTxqp88NKmz82HrJeGiTEiwK4l5LlXQT9Q0-tX3c,1605
195
- omlish/dataclasses/impl/simple.py,sha256=EovA-GpmQYtB_svItO2byTAWqbKGF4njz0MdQts3QBU,3157
196
+ omlish/dataclasses/impl/simple.py,sha256=tr1WkNuUZ3upyrLBea6RV5Jb_2YsBxisSrGPN_XIlK8,1771
196
197
  omlish/dataclasses/impl/slots.py,sha256=qXRLbtFWUs_2UV1fFUdv53_6fBLKJ_8McjNiP9YQlGM,5264
197
198
  omlish/dataclasses/impl/utils.py,sha256=aER2iL3UAtgS1BdLuEvTr9Tr2wC28wk1kiOeO-jIymw,6138
198
199
  omlish/diag/__init__.py,sha256=4S8v0myJM4Zld6_FV6cPe_nSv0aJb6kXftEit0HkiGE,1141
@@ -301,7 +302,7 @@ omlish/http/consts.py,sha256=7BJ4D1MdIvqBcepkgCfBFHolgTwbOlqsOEiee_IjxOA,2289
301
302
  omlish/http/cookies.py,sha256=uuOYlHR6e2SC3GM41V0aozK10nef9tYg83Scqpn5-HM,6351
302
303
  omlish/http/dates.py,sha256=Otgp8wRxPgNGyzx8LFowu1vC4EKJYARCiAwLFncpfHM,2875
303
304
  omlish/http/encodings.py,sha256=w2WoKajpaZnQH8j-IBvk5ZFL2O2pAU_iBvZnkocaTlw,164
304
- omlish/http/handlers.py,sha256=_MdO62GGKqzCabSSmA9uCMTB41b6sSC0AFJCpPJ9vOU,1232
305
+ omlish/http/handlers.py,sha256=Tv_ApQ0AM_Sls6VDtYn2Wejy6GGEKAsw7X6DM1rcs0M,1461
305
306
  omlish/http/headers.py,sha256=ZMmjrEiYjzo0YTGyK0YsvjdwUazktGqzVVYorY4fd44,5081
306
307
  omlish/http/json.py,sha256=9XwAsl4966Mxrv-1ytyCqhcE6lbBJw-0_tFZzGszgHE,7440
307
308
  omlish/http/jwt.py,sha256=6Rigk1WrJ059DY4jDIKnxjnChWb7aFdermj2AI2DSvk,4346
@@ -314,7 +315,7 @@ omlish/http/versions.py,sha256=wSiOXPiClVjkVgSU_VmxkoD1SUYGaoPbP0U5Aw-Ufg8,409
314
315
  omlish/http/wsgi.py,sha256=czZsVUX-l2YTlMrUjKN49wRoP4rVpS0qpeBn4O5BoMY,948
315
316
  omlish/http/coro/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
316
317
  omlish/http/coro/fdio.py,sha256=ajj_lekRockGwQEw8m_mi6RO9-o6hnC9ITiwtZe3y-s,4017
317
- omlish/http/coro/server.py,sha256=QujEUM2fhfy2GsoKhpHZvFv7SlGVwcU8kwUXEyUgwWk,18791
318
+ omlish/http/coro/server.py,sha256=TgqBTOpniZMqRPoSP3xrAaD-TLSoPsknVr7D22-2zgo,19432
318
319
  omlish/inject/__init__.py,sha256=n0RC9UDGsBQQ39cST39-XJqJPq2M0tnnh9yJubW9azo,1891
319
320
  omlish/inject/binder.py,sha256=DAbc8TZi5w8Mna0TUtq0mT4jeDVA7i7SlBtOFrh2swc,4185
320
321
  omlish/inject/bindings.py,sha256=pLXn2U3kvmAS-68IOG-tr77DbiI-wp9hGyy4lhG6_H8,525
@@ -348,6 +349,7 @@ omlish/inject/impl/scopes.py,sha256=hKnzNieB-fJSFEXDP_QG1mCfIKoVFIfFlf9LiIt5tk4,
348
349
  omlish/io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
349
350
  omlish/io/abc.py,sha256=M40QB2udYpCEqmlxCcHv6FlJYJY6ymmJQBlaklYv0U8,1256
350
351
  omlish/io/buffers.py,sha256=qo1hCqTfKvlbSmddneporqCtW0rZJ_Mv2GrQTI1Hbk0,5636
352
+ omlish/io/fileno.py,sha256=QiVuRfqJRqP1aoLS82AVHOo_rt0lijZHfM21s42uaTo,174
351
353
  omlish/io/pyio.py,sha256=q4RBFVpBE5PYjnGPGT-_4pcZb7dFJmLJ4LtI8OoDRQY,95433
352
354
  omlish/io/trampoline.py,sha256=oUKTQg1F5xQS1431Kt7MbK-NZpX509ubcXU-s86xJr8,7171
353
355
  omlish/io/compress/__init__.py,sha256=fJFPT4ONfqxmsA4jR6qbMt2woIyyEgnc_qOWK9o1kII,247
@@ -378,31 +380,31 @@ omlish/iterators/iterators.py,sha256=ghI4dO6WPyyFOLTIIMaHQ_IOy2xXaFpGPqveZ5YGIBU
378
380
  omlish/iterators/recipes.py,sha256=53mkexitMhkwXQZbL6DrhpT0WePQ_56uXd5Jaw3DfzI,467
379
381
  omlish/iterators/tools.py,sha256=Pi4ybXytUXVZ3xwK89xpPImQfYYId9p1vIFQvVqVLqA,2551
380
382
  omlish/iterators/unique.py,sha256=0jAX3kwzVfRNhe0Tmh7kVP_Q2WBIn8POo_O-rgFV0rQ,1390
381
- omlish/lang/__init__.py,sha256=sY7YSgN772n48qWlR-mwuOOCOwRF5Fh421gZqZWxYlw,4042
382
- omlish/lang/cached.py,sha256=92TvRZQ6sWlm7dNn4hgl7aWKbX0J1XUEo3DRjBpgVQk,7834
383
- omlish/lang/clsdct.py,sha256=AjtIWLlx2E6D5rC97zQ3Lwq2SOMkbg08pdO_AxpzEHI,1744
383
+ omlish/lang/__init__.py,sha256=Jh-Zj9PTDcUTi-OokA8cCqtVTZtJtkOKjUOobE2iqRc,4117
384
+ omlish/lang/cached.py,sha256=tQaqMu1LID0q4NSTk5vPXsgxIBWSFAmjs5AhQoEHoCQ,7833
385
+ omlish/lang/clsdct.py,sha256=sJYadm-fwzti-gsi98knR5qQUxriBmOqQE_qz3RopNk,1743
384
386
  omlish/lang/cmp.py,sha256=5vbzWWbqdzDmNKAGL19z6ZfUKe5Ci49e-Oegf9f4BsE,1346
385
- omlish/lang/contextmanagers.py,sha256=NEwaTLQMfhKawD5x_0HgI2RpeLXbMa5r9NqWqfDnUXI,10408
387
+ omlish/lang/contextmanagers.py,sha256=V-XRwj1Em17Pr92i9mSYeeElQs9pmfM_B4jTF732qIg,10400
386
388
  omlish/lang/datetimes.py,sha256=ehI_DhQRM-bDxAavnp470XcekbbXc4Gdw9y1KpHDJT0,223
387
- omlish/lang/descriptors.py,sha256=RRBbkMgTzg82fFFE4D0muqobpM-ZZaOta6yB1lpX3s8,6617
389
+ omlish/lang/descriptors.py,sha256=njkYDS1gn5p4-3v1jr-s_srauC7tvvt571RjE7Q4LXE,6616
388
390
  omlish/lang/exceptions.py,sha256=qJBo3NU1mOWWm-NhQUHCY5feYXR3arZVyEHinLsmRH4,47
389
391
  omlish/lang/functions.py,sha256=t9nsnWwhsibG0w908VMx-_pRM5tZfruE3faPxrCWTbI,4160
390
392
  omlish/lang/generators.py,sha256=5LX17j-Ej3QXhwBgZvRTm_dq3n9veC4IOUcVmvSu2vU,5243
391
393
  omlish/lang/imports.py,sha256=oGigWiLkLog29mWWYdu7untyX--K1SueFmKzCpXdtug,9612
392
394
  omlish/lang/iterables.py,sha256=HOjcxOwyI5bBApDLsxRAGGhTTmw7fdZl2kEckxRVl-0,1994
393
- omlish/lang/maybes.py,sha256=1RN7chX_x2XvgUwryZRz0W7hAX-be3eEFcFub5vvf6M,3417
394
- omlish/lang/objects.py,sha256=LOC3JvX1g5hPxJ7Sv2TK9kNkAo9c8J-Jw2NmClR_rkA,4576
395
+ omlish/lang/maybes.py,sha256=dAgrUoAhCgyrHRqa73CkaGnpXwGc-o9n-NIThrNXnbU,3416
396
+ omlish/lang/objects.py,sha256=65XsD7UtblRdNe2ID1-brn_QvRkJhBIk5nyZWcQNeqU,4574
395
397
  omlish/lang/resolving.py,sha256=OuN2mDTPNyBUbcrswtvFKtj4xgH4H4WglgqSKv3MTy0,1606
396
398
  omlish/lang/resources.py,sha256=N64KeVE-rYMxqBBRp91qzgVqpOVR2uX7k1WlS_bo5hM,2681
397
399
  omlish/lang/strings.py,sha256=egdv8PxLNG40-5V93agP5j2rBUDIsahCx048zV7uEbU,4690
398
400
  omlish/lang/sys.py,sha256=UoZz_PJYVKLQAKqYxxn-LHz1okK_38I__maZgnXMcxU,406
399
401
  omlish/lang/timeouts.py,sha256=vECdWYhc_IZgcal1Ng1Y42wf2FV3KAx-i8As-MgGHIQ,1186
400
402
  omlish/lang/typing.py,sha256=Zdad9Zv0sa-hIaUXPrzPidT7sDVpRcussAI7D-j-I1c,3296
401
- omlish/lang/classes/__init__.py,sha256=D3dn4FOQu5f50kW4_jLCI_zI0fTtADdYumirRdIqSuU,605
402
- omlish/lang/classes/abstract.py,sha256=19jsUEJUSTkQkXnMvjGbokfq-Z4jXFOd_tT76jSu5I0,3362
403
- omlish/lang/classes/restrict.py,sha256=pSK7ZT_kpwqS6lWRrxwuEe-tt07F0-uZVazgGh-HDco,3921
403
+ omlish/lang/classes/__init__.py,sha256=HY9UD3Tg8_sH59emZUKgP1Kb8-8r0GCw5hUOumxwKlM,658
404
+ omlish/lang/classes/abstract.py,sha256=bIcuAetV_aChhpSURypmjjcqP07xi20uVYPKh1kvQNU,3710
405
+ omlish/lang/classes/restrict.py,sha256=QvM-GqXvO8vpCONkcr0QpgVPfzZmgDo7o8d9kUwOzlo,3941
404
406
  omlish/lang/classes/simple.py,sha256=XQ8b86WvQA0qtSYqlbMOJS7tHgE8sv9onda33uQmbkM,3294
405
- omlish/lang/classes/virtual.py,sha256=W-QJuKsDehOcrydwg6eMN0bFPTYbk3Tz84TSH3blb44,3367
407
+ omlish/lang/classes/virtual.py,sha256=z0MYQD9Q5MkX8DzF325wDB4J9XoYbsB09jZ1omC62To,3366
406
408
  omlish/lifecycles/__init__.py,sha256=1FjYceXs-4fc-S-C9zFYmc2axHs4znnQHcJVHdY7a6E,578
407
409
  omlish/lifecycles/abstract.py,sha256=70CQyZy-c9a2o0ZJxPeUT7eYjWZTBrp2HpUBnrHdAOM,1109
408
410
  omlish/lifecycles/base.py,sha256=ceXrNSzuv7iiTlX96UI1fvsQ70OgOmZl-UisDPyA3NA,1394
@@ -509,15 +511,17 @@ omlish/secrets/openssl.py,sha256=wxA_wIlxtuOUy71ABxAJgavh-UI_taOfm-A0dVlmSwM,621
509
511
  omlish/secrets/pwgen.py,sha256=v-5ztnOTHTAWXLGR-3H6HkMj2nPIZBMbo5xWR3q0rDY,1707
510
512
  omlish/secrets/pwhash.py,sha256=Goktn-swmC6PXqfRBnDrH_Lr42vjckT712UyErPjzkw,4102
511
513
  omlish/secrets/secrets.py,sha256=QNgOmRcIRK2fx49bIbBBM2rYbe6IhhLgk8fKvq8guoI,7963
514
+ omlish/secrets/ssl.py,sha256=TvO1BJeCCBPsOLjO-QH7Q0DC-NS8onfmRxbl4ntOnd8,147
512
515
  omlish/secrets/subprocesses.py,sha256=ffjfbgPbEE_Pwb_87vG4yYR2CGZy3I31mHNCo_0JtHw,1212
516
+ omlish/secrets/tempssl.py,sha256=8yFLb3Q19zVtciFZL7LEeK1LIXaYxvtSaxZX2L13Xx8,1048
513
517
  omlish/sockets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
514
518
  omlish/sockets/addresses.py,sha256=vbVeQBkzI513H4vRv-JS89QtRbr9U8v5zqkm3oODl_s,1869
515
- omlish/sockets/bind.py,sha256=rNX-1VWYR0IlOLo4S0qqfm1PwqfjvSvHiFj7DE2_gIE,7914
519
+ omlish/sockets/bind.py,sha256=TnG5nm0pnuMxRA02TG2W40RbutrPA6tkOJtbZvBjDWU,8063
516
520
  omlish/sockets/handlers.py,sha256=ux2cPzAWV8b-mQ0K08-b7qjVeIT8Js5_-tyVZs0fbwg,406
517
521
  omlish/sockets/io.py,sha256=lfhTkB7NnAIx9kuQhAkwgsEUXY78Mp1_WtYrIQNS_k8,1408
518
522
  omlish/sockets/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
519
523
  omlish/sockets/server/handlers.py,sha256=-5lH2Xg7gnZiPB4t2Asa_Vgblj1ZkHzLvyiC_K4XlNc,3295
520
- omlish/sockets/server/server.py,sha256=kIQ8hHpc9GVefX7sGUrs6bhpJybaagYVwKq5QRT5B4s,4463
524
+ omlish/sockets/server/server.py,sha256=mZmHPkCRPitous56_7FJdAsDLZag2wDqjj-LaYM8_Fg,4943
521
525
  omlish/sockets/server/threading.py,sha256=YmW3Ym_p5j_F4SIH9BgRHIObywjq1HS39j9CGWIcMAY,2856
522
526
  omlish/specs/__init__.py,sha256=zZwF8yXTEkSstYtORkDhVLK-_hWU8WOJCuBpognb_NY,118
523
527
  omlish/specs/jmespath/LICENSE,sha256=IH-ZZlZkS8XMkf_ubNVD1aYHQ2l_wd0tmHtXrCcYpRU,1113
@@ -639,9 +643,9 @@ omlish/text/indent.py,sha256=YjtJEBYWuk8--b9JU_T6q4yxV85_TR7VEVr5ViRCFwk,1336
639
643
  omlish/text/minja.py,sha256=jZC-fp3Xuhx48ppqsf2Sf1pHbC0t8XBB7UpUUoOk2Qw,5751
640
644
  omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
641
645
  omlish/text/random.py,sha256=jNWpqiaKjKyTdMXC-pWAsSC10AAP-cmRRPVhm59ZWLk,194
642
- omlish-0.0.0.dev219.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
643
- omlish-0.0.0.dev219.dist-info/METADATA,sha256=lh7Dpy8tG4NhG-VPo4QWw-EnYsyHj1OY8pnJOIEfQm8,4176
644
- omlish-0.0.0.dev219.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
645
- omlish-0.0.0.dev219.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
646
- omlish-0.0.0.dev219.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
647
- omlish-0.0.0.dev219.dist-info/RECORD,,
646
+ omlish-0.0.0.dev220.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
647
+ omlish-0.0.0.dev220.dist-info/METADATA,sha256=ipY89eJtdtOxzaJVqRlOxyjn-VVMv0fWU7P7qXeJo1Q,4176
648
+ omlish-0.0.0.dev220.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
649
+ omlish-0.0.0.dev220.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
650
+ omlish-0.0.0.dev220.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
651
+ omlish-0.0.0.dev220.dist-info/RECORD,,