omlish 0.0.0.dev257__py3-none-any.whl → 0.0.0.dev259__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.
omlish/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev257'
2
- __revision__ = '62df4004126a5530d242ba70bd0dfdc429b20ae1'
1
+ __version__ = '0.0.0.dev259'
2
+ __revision__ = '5fb30c5ff443151db83d45b682f3eaf8d8427cb2'
3
3
 
4
4
 
5
5
  #
@@ -71,4 +71,7 @@ from .utils import ( # noqa
71
71
  first,
72
72
 
73
73
  get_current_task,
74
+
75
+ call_with_task_group,
76
+ run_with_task_group,
74
77
  )
@@ -1,11 +1,13 @@
1
+ import functools
1
2
  import typing as ta
2
3
 
3
- import anyio
4
+ import anyio.abc
4
5
  import sniffio
5
6
 
6
7
  from ... import lang
7
8
 
8
9
 
10
+ P = ta.ParamSpec('P')
9
11
  T = ta.TypeVar('T')
10
12
 
11
13
 
@@ -46,3 +48,26 @@ def get_current_task() -> anyio.TaskInfo | None:
46
48
  return anyio.get_current_task()
47
49
  except sniffio.AsyncLibraryNotFoundError:
48
50
  return None
51
+
52
+
53
+ ##
54
+
55
+
56
+ async def call_with_task_group(
57
+ fn: ta.Callable[ta.Concatenate[anyio.abc.TaskGroup, P], ta.Awaitable[T]],
58
+ *args: ta.Any,
59
+ **kwargs: ta.Any,
60
+ ) -> T:
61
+ async with anyio.create_task_group() as tg:
62
+ return await fn(tg, *args, **kwargs)
63
+
64
+
65
+ def run_with_task_group(
66
+ fn: ta.Callable[ta.Concatenate[anyio.abc.TaskGroup, P], ta.Awaitable[T]],
67
+ *args: ta.Any,
68
+ **kwargs: ta.Any,
69
+ ) -> T:
70
+ return anyio.run(
71
+ functools.partial(call_with_task_group, fn, *args),
72
+ **kwargs,
73
+ )
@@ -0,0 +1,55 @@
1
+ # ruff: noqa: UP006 UP007
2
+ # @omlish-lite
3
+ import typing as ta
4
+
5
+ from ..io.buffers import ReadableListBuffer
6
+
7
+
8
+ ##
9
+
10
+
11
+ class AsyncBufferedReader:
12
+ def __init__(
13
+ self,
14
+ read: ta.Callable[[], ta.Awaitable[bytes]],
15
+ ) -> None:
16
+ super().__init__()
17
+
18
+ self._read = read
19
+
20
+ self._buf = ReadableListBuffer()
21
+
22
+ class Cancelled(Exception): # noqa
23
+ pass
24
+
25
+ async def read_until(
26
+ self,
27
+ delim: bytes,
28
+ *,
29
+ canceller: ta.Optional[ta.Callable[[], bool]] = None,
30
+ ) -> bytes:
31
+ o = 0
32
+ while True:
33
+ if canceller is not None and canceller():
34
+ raise self.Cancelled
35
+ r = self._buf.read_until_(delim, o)
36
+ if isinstance(r, bytes):
37
+ return r
38
+ o = r
39
+ b = await self._read()
40
+ self._buf.feed(b)
41
+
42
+ async def read_exact(
43
+ self,
44
+ sz: int,
45
+ *,
46
+ canceller: ta.Optional[ta.Callable[[], bool]] = None,
47
+ ) -> bytes:
48
+ while True:
49
+ if canceller is not None and canceller():
50
+ raise self.Cancelled
51
+ r = self._buf.read(sz)
52
+ if r is not None:
53
+ return r
54
+ b = await self._read()
55
+ self._buf.feed(b)
omlish/io/buffers.py CHANGED
@@ -182,15 +182,21 @@ class ReadableListBuffer:
182
182
  raise EOFError(f'ReadableListBuffer got {"no" if d is None else len(d)}, expected {sz}')
183
183
  return d
184
184
 
185
- def read_until(self, delim: bytes = b'\n') -> ta.Optional[bytes]:
185
+ def read_until_(self, delim: bytes = b'\n', start_buffer: int = 0) -> ta.Union[bytes, int]:
186
186
  if not (lst := self._lst):
187
- return None
187
+ return 0
188
188
 
189
- for i, d in enumerate(lst):
190
- if (p := d.find(delim)) >= 0:
189
+ i = start_buffer
190
+ while i < len(lst):
191
+ if (p := lst[i].find(delim)) >= 0:
191
192
  return self._chop(i, p + len(delim))
193
+ i += 1
192
194
 
193
- return None
195
+ return i
196
+
197
+ def read_until(self, delim: bytes = b'\n') -> ta.Optional[bytes]:
198
+ r = self.read_until_(delim)
199
+ return r if isinstance(r, bytes) else None
194
200
 
195
201
 
196
202
  class IncrementalWriteBuffer:
omlish/lang/__init__.py CHANGED
@@ -69,7 +69,13 @@ from .clsdct import ( # noqa
69
69
  is_possibly_cls_dct,
70
70
  )
71
71
 
72
- from .cmp import ( # noqa
72
+ from .collections import ( # noqa
73
+ empty_map,
74
+ merge_dicts,
75
+ yield_dict_init,
76
+ )
77
+
78
+ from .comparison import ( # noqa
73
79
  Infinity,
74
80
  InfinityType,
75
81
  NegativeInfinity,
@@ -77,12 +83,6 @@ from .cmp import ( # noqa
77
83
  cmp,
78
84
  )
79
85
 
80
- from .collections import ( # noqa
81
- empty_map,
82
- merge_dicts,
83
- yield_dict_init,
84
- )
85
-
86
86
  from .contextmanagers import ( # noqa
87
87
  AsyncContextManager,
88
88
  ContextManaged,
@@ -117,13 +117,11 @@ def error(id: Id, error: Error) -> Response: # noqa
117
117
  ##
118
118
 
119
119
 
120
- Message: ta.TypeAlias = Request | Response | Error
120
+ Message: ta.TypeAlias = Request | Response
121
121
 
122
122
 
123
123
  def detect_message_type(dct: ta.Mapping[str, ta.Any]) -> type[Message]:
124
124
  if 'method' in dct:
125
125
  return Request
126
- elif 'code' in dct:
127
- return Error
128
126
  else:
129
127
  return Response
@@ -0,0 +1,64 @@
1
+ from .keywords.base import ( # noqa
2
+ Keyword,
3
+ Keywords,
4
+ KnownKeyword,
5
+ )
6
+
7
+ from .keywords.core import ( # noqa
8
+ CoreKeyword,
9
+ Defs,
10
+ Id,
11
+ Ref,
12
+ SchemaKeyword,
13
+ )
14
+
15
+ from .keywords.format import ( # noqa
16
+ Format,
17
+ FormatKeyword,
18
+ )
19
+
20
+ from .keywords.metadata import ( # noqa
21
+ Description,
22
+ MetadataKeyword,
23
+ Title,
24
+ )
25
+
26
+ from .keywords.parse import ( # noqa
27
+ DEFAULT_KEYWORD_SUPERTYPES,
28
+ DEFAULT_KEYWORD_TYPES,
29
+ DEFAULT_KEYWORD_TYPES_BY_TAG,
30
+ DEFAULT_KEYWORD_PARSER,
31
+ KeywordParser,
32
+ build_keyword_types_by_tag,
33
+ parse_keyword,
34
+ parse_keywords,
35
+ )
36
+
37
+ from .keywords.render import ( # noqa
38
+ render_keyword,
39
+ render_keywords,
40
+ )
41
+
42
+ from .keywords.unknown import ( # noqa
43
+ UnknownKeyword,
44
+ )
45
+
46
+ from .keywords.validation import ( # noqa
47
+ ExclusiveMaximum,
48
+ ExclusiveMinimum,
49
+ Items,
50
+ MaxItems,
51
+ Maximum,
52
+ MinItems,
53
+ Minimum,
54
+ Properties,
55
+ Required,
56
+ Type,
57
+ UniqueItems,
58
+ ValidationKeyword,
59
+ )
60
+
61
+ from .types import ( # noqa
62
+ JsonType,
63
+ TYPE_SETS_BY_JSON_TYPE,
64
+ )
@@ -1,48 +0,0 @@
1
- from .base import ( # noqa
2
- Keyword,
3
- Keywords,
4
- )
5
-
6
- from .core import ( # noqa
7
- CoreKeyword,
8
- Id,
9
- Ref,
10
- SchemaKeyword,
11
- )
12
-
13
- from .metadata import ( # noqa
14
- Description,
15
- MetadataKeyword,
16
- Title,
17
- )
18
-
19
- from .parse import ( # noqa
20
- DEFAULT_KEYWORD_SUPERTYPES,
21
- DEFAULT_KEYWORD_TYPES,
22
- DEFAULT_KEYWORD_TYPES_BY_TAG,
23
- DEFAULT_PARSER,
24
- Parser,
25
- build_keyword_types_by_tag,
26
- parse_keyword,
27
- parse_keywords,
28
- )
29
-
30
- from .render import ( # noqa
31
- render_keyword,
32
- render_keywords,
33
- )
34
-
35
- from .validation import ( # noqa
36
- ExclusiveMaximum,
37
- ExclusiveMinimum,
38
- Items,
39
- MaxItems,
40
- Maximum,
41
- MinItems,
42
- Minimum,
43
- Properties,
44
- Required,
45
- Type,
46
- UniqueItems,
47
- ValidationKeyword,
48
- )
@@ -17,14 +17,33 @@ KeywordT = ta.TypeVar('KeywordT', bound='Keyword')
17
17
  class Keyword(lang.Abstract):
18
18
  tag: ta.ClassVar[str]
19
19
 
20
- def __init_subclass__(cls, *, tag: str | None = None, **kwargs: ta.Any) -> None:
20
+
21
+ ##
22
+
23
+
24
+ class KnownKeyword(Keyword, lang.Abstract):
25
+ aliases: ta.ClassVar[frozenset[str]]
26
+
27
+ tag_and_aliases: ta.ClassVar[frozenset[str]]
28
+
29
+ def __init_subclass__(
30
+ cls,
31
+ *,
32
+ tag: str | None = None,
33
+ aliases: ta.Iterable[str] | None = None,
34
+ **kwargs: ta.Any,
35
+ ) -> None:
21
36
  super().__init_subclass__(**kwargs)
22
- check.not_in('tag', dir(cls))
37
+ check.empty(set(dir(cls)) & {'tag', 'aliases', 'tag_and_aliases'})
23
38
  if not lang.is_abstract_class(cls):
24
39
  check.issubclass(cls, lang.Final)
40
+ check.not_isinstance(aliases, str)
25
41
  cls.tag = check.non_empty_str(tag)
42
+ cls.aliases = frozenset(aliases or ())
43
+ cls.tag_and_aliases = frozenset([cls.tag, *cls.aliases])
26
44
  else:
27
- check.none(tag)
45
+ for a in (tag, aliases):
46
+ check.none(a)
28
47
 
29
48
 
30
49
  ##
@@ -1,12 +1,13 @@
1
1
  from .... import lang
2
- from .base import Keyword
2
+ from .base import KnownKeyword
3
3
  from .base import StrKeyword
4
+ from .base import StrToKeywordsKeyword
4
5
 
5
6
 
6
7
  ##
7
8
 
8
9
 
9
- class CoreKeyword(Keyword, lang.Abstract, lang.Sealed):
10
+ class CoreKeyword(KnownKeyword, lang.Abstract, lang.Sealed):
10
11
  pass
11
12
 
12
13
 
@@ -23,3 +24,7 @@ class SchemaKeyword(StrKeyword, CoreKeyword, lang.Final, tag='$schema'):
23
24
 
24
25
  class Ref(StrKeyword, CoreKeyword, lang.Final, tag='$ref'):
25
26
  pass
27
+
28
+
29
+ class Defs(StrToKeywordsKeyword, CoreKeyword, lang.Final, tag='$defs', aliases=['definitions']):
30
+ pass
@@ -0,0 +1,17 @@
1
+ from .... import lang
2
+ from .base import KnownKeyword
3
+ from .base import StrKeyword
4
+
5
+
6
+ ##
7
+
8
+
9
+ class FormatKeyword(KnownKeyword, lang.Abstract, lang.Sealed):
10
+ pass
11
+
12
+
13
+ ##
14
+
15
+
16
+ class Format(StrKeyword, FormatKeyword, lang.Final, tag='format'):
17
+ pass
@@ -1,12 +1,12 @@
1
1
  from .... import lang
2
- from .base import Keyword
2
+ from .base import KnownKeyword
3
3
  from .base import StrKeyword
4
4
 
5
5
 
6
6
  ##
7
7
 
8
8
 
9
- class MetadataKeyword(Keyword, lang.Abstract, lang.Sealed):
9
+ class MetadataKeyword(KnownKeyword, lang.Abstract, lang.Sealed):
10
10
  pass
11
11
 
12
12
 
@@ -1,4 +1,3 @@
1
- import operator
2
1
  import typing as ta
3
2
 
4
3
  from .... import check
@@ -8,12 +7,15 @@ from .base import BooleanKeyword
8
7
  from .base import Keyword
9
8
  from .base import Keywords
10
9
  from .base import KeywordsKeyword
10
+ from .base import KnownKeyword
11
11
  from .base import NumberKeyword
12
12
  from .base import StrKeyword
13
13
  from .base import StrOrStrsKeyword
14
14
  from .base import StrToKeywordsKeyword
15
15
  from .core import CoreKeyword
16
+ from .format import FormatKeyword
16
17
  from .metadata import MetadataKeyword
18
+ from .unknown import UnknownKeyword
17
19
  from .validation import ValidationKeyword
18
20
 
19
21
 
@@ -23,38 +25,49 @@ KeywordT = ta.TypeVar('KeywordT', bound=Keyword)
23
25
  ##
24
26
 
25
27
 
26
- def build_keyword_types_by_tag(keyword_types: ta.Iterable[type[Keyword]]) -> ta.Mapping[str, type[Keyword]]:
27
- return col.make_map_by(operator.attrgetter('tag'), keyword_types, strict=True)
28
+ def build_keyword_types_by_tag(keyword_types: ta.Iterable[type[KnownKeyword]]) -> ta.Mapping[str, type[KnownKeyword]]:
29
+ return col.make_map(((t, kt) for kt in keyword_types for t in kt.tag_and_aliases), strict=True)
28
30
 
29
31
 
30
- DEFAULT_KEYWORD_SUPERTYPES: ta.AbstractSet = frozenset([
32
+ DEFAULT_KEYWORD_SUPERTYPES: ta.AbstractSet[type[KnownKeyword]] = frozenset([
31
33
  CoreKeyword,
34
+ FormatKeyword,
32
35
  MetadataKeyword,
33
36
  ValidationKeyword,
34
37
  ])
35
38
 
36
- DEFAULT_KEYWORD_TYPES: ta.AbstractSet = frozenset(lang.flatten(
39
+ DEFAULT_KEYWORD_TYPES: ta.AbstractSet[type[KnownKeyword]] = frozenset(lang.flatten(
37
40
  lang.deep_subclasses(st, concrete_only=True) for st in DEFAULT_KEYWORD_SUPERTYPES
38
41
  ))
39
42
 
40
- DEFAULT_KEYWORD_TYPES_BY_TAG: ta.Mapping[str, type[Keyword]] = build_keyword_types_by_tag(DEFAULT_KEYWORD_TYPES)
43
+ DEFAULT_KEYWORD_TYPES_BY_TAG: ta.Mapping[str, type[KnownKeyword]] = build_keyword_types_by_tag(DEFAULT_KEYWORD_TYPES)
41
44
 
42
45
 
43
46
  ##
44
47
 
45
48
 
46
- class Parser:
49
+ class KeywordParser:
47
50
  def __init__(
48
51
  self,
49
- keyword_types: ta.Iterable[type[Keyword]] | ta.Mapping[str, type[Keyword]] = DEFAULT_KEYWORD_TYPES_BY_TAG,
52
+ *,
53
+ keyword_types: ta.Union[ # noqa
54
+ ta.Iterable[type[KnownKeyword]],
55
+ ta.Mapping[str, type[KnownKeyword]],
56
+ None,
57
+ ] = None,
58
+ allow_unknown: bool = False,
50
59
  ) -> None:
51
60
  super().__init__()
52
61
 
53
- if isinstance(keyword_types, ta.Mapping):
62
+ if keyword_types is None:
63
+ self._keyword_types_by_tag = DEFAULT_KEYWORD_TYPES_BY_TAG
64
+ elif isinstance(keyword_types, ta.Mapping):
54
65
  self._keyword_types_by_tag = keyword_types
55
66
  else:
56
67
  self._keyword_types_by_tag = build_keyword_types_by_tag(keyword_types)
57
68
 
69
+ self._allow_unknown = allow_unknown
70
+
58
71
  def parse_keyword(self, cls: type[KeywordT], v: ta.Any) -> KeywordT:
59
72
  if issubclass(cls, BooleanKeyword):
60
73
  return cls(check.isinstance(v, bool)) # type: ignore
@@ -76,26 +89,37 @@ class Parser:
76
89
  return cls(ss) # type: ignore
77
90
 
78
91
  elif issubclass(cls, KeywordsKeyword):
79
- return cls(parse_keywords(v)) # type: ignore
92
+ return cls(self.parse_keywords(v)) # type: ignore
80
93
 
81
94
  elif issubclass(cls, StrToKeywordsKeyword):
82
- return cls({k: parse_keywords(mv) for k, mv in v.items()}) # type: ignore
95
+ return cls({k: self.parse_keywords(mv) for k, mv in v.items()}) # type: ignore
83
96
 
84
97
  else:
85
98
  raise TypeError(cls)
86
99
 
87
100
  def parse_keywords(self, dct: ta.Mapping[str, ta.Any]) -> Keywords:
88
101
  lst: list[Keyword] = []
102
+
89
103
  for k, v in dct.items():
90
- cls = self._keyword_types_by_tag[k]
91
- lst.append(self.parse_keyword(cls, v))
104
+ try:
105
+ cls = self._keyword_types_by_tag[k]
106
+
107
+ except KeyError:
108
+ if not self._allow_unknown:
109
+ raise
110
+
111
+ lst.append(UnknownKeyword(k, v))
112
+
113
+ else:
114
+ lst.append(self.parse_keyword(cls, v))
115
+
92
116
  return Keywords(lst)
93
117
 
94
118
 
95
119
  ##
96
120
 
97
121
 
98
- DEFAULT_PARSER = Parser()
122
+ DEFAULT_KEYWORD_PARSER = KeywordParser()
99
123
 
100
- parse_keyword = DEFAULT_PARSER.parse_keyword
101
- parse_keywords = DEFAULT_PARSER.parse_keywords
124
+ parse_keyword = DEFAULT_KEYWORD_PARSER.parse_keyword
125
+ parse_keywords = DEFAULT_KEYWORD_PARSER.parse_keywords
@@ -8,6 +8,10 @@ from .base import NumberKeyword
8
8
  from .base import StrKeyword
9
9
  from .base import StrOrStrsKeyword
10
10
  from .base import StrToKeywordsKeyword
11
+ from .unknown import UnknownKeyword
12
+
13
+
14
+ ##
11
15
 
12
16
 
13
17
  def render_keyword(kw: Keyword) -> dict[str, ta.Any]:
@@ -32,6 +36,9 @@ def render_keyword(kw: Keyword) -> dict[str, ta.Any]:
32
36
  elif isinstance(kw, StrToKeywordsKeyword):
33
37
  return {kw.tag: {k: render_keywords(v) for k, v in kw.m.items()}}
34
38
 
39
+ elif isinstance(kw, UnknownKeyword):
40
+ return {kw.tag: kw.value}
41
+
35
42
  else:
36
43
  raise TypeError(kw)
37
44
 
@@ -0,0 +1,14 @@
1
+ import typing as ta
2
+
3
+ from .... import dataclasses as dc
4
+ from .... import lang
5
+ from .base import Keyword
6
+
7
+
8
+ ##
9
+
10
+
11
+ @dc.dataclass(frozen=True)
12
+ class UnknownKeyword(Keyword, lang.Final):
13
+ tag: str # type: ignore[misc]
14
+ value: ta.Any
@@ -1,7 +1,7 @@
1
1
  from .... import lang
2
2
  from .base import BooleanKeyword
3
- from .base import Keyword
4
3
  from .base import KeywordsKeyword
4
+ from .base import KnownKeyword
5
5
  from .base import NumberKeyword
6
6
  from .base import StrOrStrsKeyword
7
7
  from .base import StrToKeywordsKeyword
@@ -10,7 +10,7 @@ from .base import StrToKeywordsKeyword
10
10
  ##
11
11
 
12
12
 
13
- class ValidationKeyword(Keyword, lang.Abstract, lang.Sealed):
13
+ class ValidationKeyword(KnownKeyword, lang.Abstract, lang.Sealed):
14
14
  pass
15
15
 
16
16
 
@@ -2,6 +2,9 @@ import enum
2
2
  import typing as ta
3
3
 
4
4
 
5
+ ##
6
+
7
+
5
8
  class JsonType(enum.Enum):
6
9
  NULL = enum.auto()
7
10
  BOOLEAN = enum.auto()
@@ -1,5 +1,11 @@
1
- from . import marshal # noqa
2
-
3
1
  from .openapi import ( # noqa
4
2
  Openapi,
5
3
  )
4
+
5
+
6
+ ##
7
+
8
+
9
+ from ...lang.imports import _register_conditional_import # noqa
10
+
11
+ _register_conditional_import('...marshal', '.marshal', __package__)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: omlish
3
- Version: 0.0.0.dev257
3
+ Version: 0.0.0.dev259
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -98,3 +98,4 @@ Requires-Dist: executing~=2.2; extra == "plus"
98
98
  Requires-Dist: orjson~=3.10; extra == "plus"
99
99
  Requires-Dist: pyyaml~=6.0; extra == "plus"
100
100
  Requires-Dist: wrapt~=1.17; extra == "plus"
101
+ Dynamic: license-file
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=x26AIwDzScUvnX-p4xlq6Zc5QYrAo0Vmgf1qHc1KL_M,8253
2
- omlish/__about__.py,sha256=irtXLzobfvt8KMSteKtCL_pI7wHzOQYda3aaJQXQZB8,3380
2
+ omlish/__about__.py,sha256=QWfWomoVrAlTxHpzmKS8W74S6KcEi_KRE_xJsJmoxqo,3380
3
3
  omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
4
4
  omlish/c3.py,sha256=ubu7lHwss5V4UznbejAI0qXhXahrU01MysuHOZI9C4U,8116
5
5
  omlish/cached.py,sha256=MLap_p0rdGoDIMVhXVHm1tsbcWobJF0OanoodV03Ju8,542
@@ -93,16 +93,17 @@ omlish/asyncs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
93
93
  omlish/asyncs/all.py,sha256=uUz9ziKh4_QrgmdhKFMgq6j7mFbiZd3LiogguDCQsGI,587
94
94
  omlish/asyncs/asyncs.py,sha256=x72xDJenumWV5a_myJOdWlaTdBNZPCwJ_u7_6yhZyBk,2034
95
95
  omlish/asyncs/bridge.py,sha256=zVAhbFVDvw3qJjcvOKKY2mI8AwrmcmddKsW9KIzPdLI,9740
96
+ omlish/asyncs/buffers.py,sha256=xQO6EDdLSus88Lg5Cw2wpZsSLXR1g4GCwc_1K1tSwV0,1312
96
97
  omlish/asyncs/flavors.py,sha256=1mNxGNRVmjUHzA13K5ht8vdJv4CLEmzYTQ6BZXr1520,4866
97
98
  omlish/asyncs/trio.py,sha256=fmZ5b_lKdVV8NQ3euCUutWgnkqTFzSnOjvJSA_jvmrE,367
98
99
  omlish/asyncs/trio_asyncio.py,sha256=oqdOHy0slj9PjVxaDf3gJkq9AAgg7wYZbB469jOftVw,1327
99
- omlish/asyncs/anyio/__init__.py,sha256=sX7bciyRquaPeDAz16phkg_Lnw_AbJgUkayy5Aw8o2M,1695
100
+ omlish/asyncs/anyio/__init__.py,sha256=AkwRD3XFWmEzBeHV-eAzwpA4F04bl7xyyapigrxMR8g,1747
100
101
  omlish/asyncs/anyio/backends.py,sha256=jJIymWoiedaEJJm82gvKiJ41EWLQZ-bcyNHpbDpKKi4,1584
101
102
  omlish/asyncs/anyio/futures.py,sha256=Nm1gLerZEnHk-rlsmr0UfK168IWIK6zA8EebZFtoY_E,2052
102
103
  omlish/asyncs/anyio/signals.py,sha256=ySSut5prdnoy0-5Ws5V1M4cC2ON_vY550vU10d2NHk8,893
103
104
  omlish/asyncs/anyio/streams.py,sha256=gNRAcHR0L8OtNioqKFbq0Z_apYAWKHFipZ2MUBp8Vg0,2228
104
105
  omlish/asyncs/anyio/sync.py,sha256=maggE0mH-TxmefX3vfa27DuDEaE5-yQKn84Mj3mOSVU,1569
105
- omlish/asyncs/anyio/utils.py,sha256=BRThj9AVV1CAe4tkSYXQvNBHqJRbEpP4utzu-AImk08,1086
106
+ omlish/asyncs/anyio/utils.py,sha256=X2Rz1DGrCJ0zkt1O5cHoMRaYKTPndBj6dzLhb09mVtE,1672
106
107
  omlish/asyncs/asyncio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
107
108
  omlish/asyncs/asyncio/all.py,sha256=EksCHjRQKobiGrxuDW72IaH53WJMs7rdj_ZDBI3iKcg,315
108
109
  omlish/asyncs/asyncio/asyncio.py,sha256=mDjYNm1cylUhQ8slWXwdPoXasuWfafjzu78GHt2Mdig,2437
@@ -374,7 +375,7 @@ omlish/inject/impl/proxy.py,sha256=1ko0VaKqzu9UG8bIldp9xtUrAVUOFTKWKTjOCqIGr4s,1
374
375
  omlish/inject/impl/scopes.py,sha256=hKnzNieB-fJSFEXDP_QG1mCfIKoVFIfFlf9LiIt5tk4,5920
375
376
  omlish/io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
376
377
  omlish/io/abc.py,sha256=M40QB2udYpCEqmlxCcHv6FlJYJY6ymmJQBlaklYv0U8,1256
377
- omlish/io/buffers.py,sha256=qo1hCqTfKvlbSmddneporqCtW0rZJ_Mv2GrQTI1Hbk0,5636
378
+ omlish/io/buffers.py,sha256=Pu8CZUfiTJO_qq7cuPYAnNIag_7LJfr4ODaICsFZ6IU,5855
378
379
  omlish/io/fileno.py,sha256=QiVuRfqJRqP1aoLS82AVHOo_rt0lijZHfM21s42uaTo,174
379
380
  omlish/io/pyio.py,sha256=q4RBFVpBE5PYjnGPGT-_4pcZb7dFJmLJ4LtI8OoDRQY,95433
380
381
  omlish/io/trampoline.py,sha256=oUKTQg1F5xQS1431Kt7MbK-NZpX509ubcXU-s86xJr8,7171
@@ -406,11 +407,11 @@ omlish/iterators/iterators.py,sha256=iTQQwBE6Wzoy36dnbPIws17zbjE3zNN4KwVw4Fzh-gY
406
407
  omlish/iterators/recipes.py,sha256=53mkexitMhkwXQZbL6DrhpT0WePQ_56uXd5Jaw3DfzI,467
407
408
  omlish/iterators/tools.py,sha256=Pi4ybXytUXVZ3xwK89xpPImQfYYId9p1vIFQvVqVLqA,2551
408
409
  omlish/iterators/unique.py,sha256=0jAX3kwzVfRNhe0Tmh7kVP_Q2WBIn8POo_O-rgFV0rQ,1390
409
- omlish/lang/__init__.py,sha256=ovWbqkbQJNefmYR3VR_NwsRyEOguh62Rw6bimwcTaRI,5057
410
+ omlish/lang/__init__.py,sha256=H-kPgztXCiOneAvYeC1YxN8nMQu_gYBY2hwy8-dxHvs,5064
410
411
  omlish/lang/attrs.py,sha256=fofCKN0X8TMu1yGqHpLpNLih9r9HWl3D3Vn3b6O791w,3891
411
412
  omlish/lang/clsdct.py,sha256=sJYadm-fwzti-gsi98knR5qQUxriBmOqQE_qz3RopNk,1743
412
- omlish/lang/cmp.py,sha256=5vbzWWbqdzDmNKAGL19z6ZfUKe5Ci49e-Oegf9f4BsE,1346
413
413
  omlish/lang/collections.py,sha256=aGi0j6VzVe2nz4l357Y4RD5_XNl8OJbmM5qM6BclrrY,1895
414
+ omlish/lang/comparison.py,sha256=5vbzWWbqdzDmNKAGL19z6ZfUKe5Ci49e-Oegf9f4BsE,1346
414
415
  omlish/lang/contextmanagers.py,sha256=UPH6daYwSP9cH5AfSVsJyEHk1UURMGhVPM5ZRhp_Hvw,7576
415
416
  omlish/lang/datetimes.py,sha256=ehI_DhQRM-bDxAavnp470XcekbbXc4Gdw9y1KpHDJT0,223
416
417
  omlish/lang/descriptors.py,sha256=zBtgO9LjdSTGHNUgiIqswh78WOVoGH6KzS0NbgB1Wls,6572
@@ -621,16 +622,18 @@ omlish/specs/jmespath/visitor.py,sha256=yneRMO4qf3k2Mdcm2cPC0ozRgOaudzlxRVRGatzt
621
622
  omlish/specs/jsonrpc/__init__.py,sha256=QQwr-jkgvwr1ZMlNwl5W1TuHcxx8RuzQVFwWwNhp5sM,515
622
623
  omlish/specs/jsonrpc/errors.py,sha256=-Zgmlo6bV6J8w5f8h9axQgLquIFBHDgIwcpufEH5NsE,707
623
624
  omlish/specs/jsonrpc/marshal.py,sha256=hM1rPZddoha_87qcQtBWkyaZshCXlPoHPJg6J_nBi9k,1915
624
- omlish/specs/jsonrpc/types.py,sha256=Hf6GQHJhqdSUXE0kWw67HhSH_Fu2fuOeS-MYTgEbXwA,2753
625
- omlish/specs/jsonschema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
626
- omlish/specs/jsonschema/types.py,sha256=qoxExgKfrI-UZXdk3qcVZIEyp1WckFbb85_eGInEoAY,467
627
- omlish/specs/jsonschema/keywords/__init__.py,sha256=kZNJCujSpflCOrPNeJT8C1a5sfStn6cwiXXzbu9YPyg,753
628
- omlish/specs/jsonschema/keywords/base.py,sha256=a_LbIxLXiPn7L2EWMWKip-F-zOWsZPtOw5ebtkE5-sA,1923
629
- omlish/specs/jsonschema/keywords/core.py,sha256=mCMve9CfCMvKXgdLzZ9REF1c6PIanwq3iJowbF6W8Q0,378
630
- omlish/specs/jsonschema/keywords/metadata.py,sha256=gN79qqS-YXGn-FrQ9BS4rKvOHYlsUNXkTVhXyvJ50Wk,326
631
- omlish/specs/jsonschema/keywords/parse.py,sha256=z43Rc1R15D9XHj4_DZelWCVBXUc_wQ_jaDu_fWAiuPA,2991
632
- omlish/specs/jsonschema/keywords/render.py,sha256=enGkw1S8Zxfn1IBkKqZTK81yG21MVKk54B8rqiTY30c,1236
633
- omlish/specs/jsonschema/keywords/validation.py,sha256=bVTdmuHdCibY8FZoiKSh41H_xZSXZGZpRlHWHI6kDTI,1332
625
+ omlish/specs/jsonrpc/types.py,sha256=emEiTPWsjsYy0jCC3It1bUEcu9nHp5y7-j73U1D6vl4,2700
626
+ omlish/specs/jsonschema/__init__.py,sha256=qmlpJJlB9TBwvE2qCjRHeecNhEYonpbncXfX0T2L-do,1060
627
+ omlish/specs/jsonschema/types.py,sha256=_H7ma99hD3_Xu42BFGHOXRI5p79tY8WBX8QE36k7lbw,472
628
+ omlish/specs/jsonschema/keywords/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
629
+ omlish/specs/jsonschema/keywords/base.py,sha256=jbLzU5_MeLcVrsbPlF2HPt0X0MldyOQmofZxelNTwP4,2416
630
+ omlish/specs/jsonschema/keywords/core.py,sha256=3Pbi8d-eocEAxEdemNa0ldp5lrLWNmH0Tye-5rglUoU,535
631
+ omlish/specs/jsonschema/keywords/format.py,sha256=9trrxHe38FDx47I8UfvO4PD_IygRlkEyTUJ3XlxDM6Y,244
632
+ omlish/specs/jsonschema/keywords/metadata.py,sha256=IVWQKWT9xi0R07pXc79ErT7RBu5b6Kzg4pWYIITIRbs,336
633
+ omlish/specs/jsonschema/keywords/parse.py,sha256=zWSOhHHzXbj-Yn5owU_w0V5w8yhiW4qqc4c7lMvavk0,3690
634
+ omlish/specs/jsonschema/keywords/render.py,sha256=kHlBwNjSvKtca0IXBP5DWDRW-H6MduO6PZjhkBFRImU,1353
635
+ omlish/specs/jsonschema/keywords/unknown.py,sha256=iYIQlBbLUqISvTvj_Kup4wVDRxcEwmnLTyAAWjlxsck,234
636
+ omlish/specs/jsonschema/keywords/validation.py,sha256=RJdGAsl_FtUmw1Bin_mrJ5qhN06rBC3f_L-rCBYdIOc,1342
634
637
  omlish/specs/jsonschema/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
635
638
  omlish/specs/jsonschema/schemas/draft202012/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
636
639
  omlish/specs/jsonschema/schemas/draft202012/metaschema.json,sha256=Qdp29a-3zgYtJI92JGOpL3ykfk4PkFsiS6av7vkd7Q8,2452
@@ -644,7 +647,7 @@ omlish/specs/jsonschema/schemas/draft202012/vocabularies/format.json,sha256=UOu_
644
647
  omlish/specs/jsonschema/schemas/draft202012/vocabularies/meta-data.json,sha256=j3bW4U9Bubku-TO3CM3FFEyLUmhlGtEZGEhfsXVPHHY,892
645
648
  omlish/specs/jsonschema/schemas/draft202012/vocabularies/unevaluated.json,sha256=Lb-8tzmUtnCwl2SSre4f_7RsIWgnhNL1pMpWH54tDLQ,506
646
649
  omlish/specs/jsonschema/schemas/draft202012/vocabularies/validation.json,sha256=cBCjHlQfMtK-ch4t40jfdcmzaHaj7TBId_wKvaHTelg,2834
647
- omlish/specs/openapi/__init__.py,sha256=zilQhafjvteRDF_TUIRgF293dBC6g-TJChmUb6T9VBQ,77
650
+ omlish/specs/openapi/__init__.py,sha256=mIx7Askk3FNxGE1CDLBQUOOrRGYaqW7cPGVW4_nAFF4,187
648
651
  omlish/specs/openapi/marshal.py,sha256=Z-E2Knm04C81N8AA8cibCVSl2ImhSpHZVc7yAhmPx88,2135
649
652
  omlish/specs/openapi/openapi.py,sha256=y4h04jeB7ORJSVrcy7apaBdpwLjIyscv1Ub5SderH2c,12682
650
653
  omlish/specs/proto/Protobuf3.g4,sha256=chDrovFsuZaHf5W35WZNts3jOa1ssPwvWiJR4yVIgjw,5552
@@ -764,9 +767,9 @@ omlish/text/parts.py,sha256=Q9NvoyEGQKIWgiPD4D_Qc66cWAuyEKE033dT9m7c3Wk,6662
764
767
  omlish/text/random.py,sha256=jNWpqiaKjKyTdMXC-pWAsSC10AAP-cmRRPVhm59ZWLk,194
765
768
  omlish/text/go/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
766
769
  omlish/text/go/quoting.py,sha256=N9EYdnFdEX_A8fOviH-1w4jwV3XOQ7VU2WsoUNubYVY,9137
767
- omlish-0.0.0.dev257.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
768
- omlish-0.0.0.dev257.dist-info/METADATA,sha256=SCBiML7sTPFB9bgHA3gYkm7D8wlrNpOjJZQFCf_s_Zk,4176
769
- omlish-0.0.0.dev257.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
770
- omlish-0.0.0.dev257.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
771
- omlish-0.0.0.dev257.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
772
- omlish-0.0.0.dev257.dist-info/RECORD,,
770
+ omlish-0.0.0.dev259.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
771
+ omlish-0.0.0.dev259.dist-info/METADATA,sha256=_6IPhJ7Wj-ZeElcErhEi86336VzmKQkKraGj9huqv8s,4198
772
+ omlish-0.0.0.dev259.dist-info/WHEEL,sha256=tTnHoFhvKQHCh4jz3yCn0WPTYIy7wXx3CJtJ7SJGV7c,91
773
+ omlish-0.0.0.dev259.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
774
+ omlish-0.0.0.dev259.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
775
+ omlish-0.0.0.dev259.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (76.1.0)
2
+ Generator: setuptools (77.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
File without changes