omlish 0.0.0.dev219__py3-none-any.whl → 0.0.0.dev220__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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,,