omlish 0.0.0.dev315__py3-none-any.whl → 0.0.0.dev316__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.dev315'
2
- __revision__ = '9f4bb119f0561532694288dd8bb808ce67ebb43d'
1
+ __version__ = '0.0.0.dev316'
2
+ __revision__ = 'c32f4122c29baf0486a328e8d6e54beb8c47b3fc'
3
3
 
4
4
 
5
5
  #
@@ -1,6 +1,9 @@
1
1
  import json
2
2
 
3
3
 
4
+ ##
5
+
6
+
4
7
  detect_encoding = json.detect_encoding
5
8
 
6
9
 
@@ -15,6 +15,7 @@
15
15
  # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
16
  # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17
17
  # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18
+ # https://github.com/simplejson/simplejson/blob/6932004966ab70ef47250a2b3152acd8c904e6b5/simplejson/encoder.py
18
19
  # https://github.com/simplejson/simplejson/blob/6932004966ab70ef47250a2b3152acd8c904e6b5/simplejson/scanner.py
19
20
  import json
20
21
  import re
@@ -25,6 +26,75 @@ import typing as ta
25
26
  ##
26
27
 
27
28
 
29
+ _ESCAPE_PAT = re.compile(r'[\x00-\x1f\\"]')
30
+ _ESCAPE_ASCII_PAT = re.compile(r'([\\"]|[^\ -~])')
31
+
32
+ _ESCAPE_DCT = {
33
+ **{
34
+ chr(i): f'\\u{i:04x}'
35
+ for i in range(0x20)
36
+ },
37
+ '\\': '\\\\',
38
+ '"': '\\"',
39
+ '\b': '\\b',
40
+ '\f': '\\f',
41
+ '\n': '\\n',
42
+ '\r': '\\r',
43
+ '\t': '\\t',
44
+ }
45
+
46
+
47
+ def _convert_to_string(s: str | bytes) -> str:
48
+ if isinstance(s, bytes):
49
+ return str(s, 'utf-8')
50
+
51
+ elif type(s) is not str:
52
+ # Convert a str subclass instance to exact str. Raise a TypeError otherwise.
53
+ return str.__str__(s)
54
+
55
+ else:
56
+ return s
57
+
58
+
59
+ def encode_string(s: str | bytes, q: str = '"') -> str:
60
+ """Return a JSON representation of a Python string"""
61
+
62
+ s = _convert_to_string(s)
63
+
64
+ def replace(m):
65
+ return _ESCAPE_DCT[m.group(0)]
66
+
67
+ return q + _ESCAPE_PAT.sub(replace, s) + q
68
+
69
+
70
+ def encode_string_ascii(s: str | bytes, q: str = '"') -> str:
71
+ """Return an ASCII-only JSON representation of a Python string"""
72
+
73
+ s = _convert_to_string(s)
74
+
75
+ def replace(m):
76
+ s = m.group(0)
77
+
78
+ try:
79
+ return _ESCAPE_DCT[s]
80
+
81
+ except KeyError:
82
+ n = ord(s)
83
+ if n < 0x10000:
84
+ return f'\\u{n:04x}'
85
+
86
+ # surrogate pair
87
+ n -= 0x10000
88
+ s1 = 0xD800 | ((n >> 10) & 0x3FF)
89
+ s2 = 0xDC00 | (n & 0x3FF)
90
+ return f'\\u{s1:04x}\\u{s2:04x}'
91
+
92
+ return q + str(_ESCAPE_ASCII_PAT.sub(replace, s)) + q
93
+
94
+
95
+ ##
96
+
97
+
28
98
  _FOUR_DIGIT_HEX_PAT = re.compile(r'^[0-9a-fA-F]{4}$')
29
99
 
30
100
 
@@ -86,7 +156,7 @@ def parse_string(
86
156
  prev_end = end
87
157
  end = chunk.end()
88
158
  content, terminator = chunk.groups()
89
- # Content is contains zero or more unescaped string characters
159
+ # Content contains zero or more unescaped string characters
90
160
  if content:
91
161
  chunks.append(content)
92
162
 
@@ -12,12 +12,13 @@ from .types import Scalar
12
12
 
13
13
  I = ta.TypeVar('I')
14
14
 
15
- MULTILINE_SEPARATORS = consts.Separators(',', ': ')
16
-
17
15
 
18
16
  ##
19
17
 
20
18
 
19
+ MULTILINE_SEPARATORS = consts.Separators(',', ': ')
20
+
21
+
21
22
  class AbstractJsonRenderer(lang.Abstract, ta.Generic[I]):
22
23
  class State(enum.Enum):
23
24
  VALUE = enum.auto()
@@ -56,8 +56,7 @@ import abc
56
56
  import dataclasses as dc
57
57
  import email.utils
58
58
  import html
59
- import http.client
60
- import http.server
59
+ import http
61
60
  import io
62
61
  import textwrap
63
62
  import time
omlish/lang/__init__.py CHANGED
@@ -225,13 +225,6 @@ from .iterables import ( # noqa
225
225
  take,
226
226
  )
227
227
 
228
- from .maybes import ( # noqa
229
- Maybe,
230
- empty,
231
- just,
232
- maybe,
233
- )
234
-
235
228
  from .objects import ( # noqa
236
229
  Identity,
237
230
  SimpleProxy,
@@ -341,6 +334,13 @@ from ..lite.imports import ( # noqa
341
334
  import_module_attr,
342
335
  )
343
336
 
337
+ from ..lite.maybes import ( # noqa
338
+ Maybe,
339
+ )
340
+
341
+ empty = Maybe.empty
342
+ just = Maybe.just
343
+
344
344
  from ..lite.reprs import ( # noqa
345
345
  AttrRepr,
346
346
  attr_repr,
omlish/lang/generators.py CHANGED
@@ -2,10 +2,8 @@ import abc
2
2
  import functools
3
3
  import typing as ta
4
4
 
5
+ from ..lite.maybes import Maybe
5
6
  from .classes.restrict import Abstract
6
- from .maybes import Maybe
7
- from .maybes import empty
8
- from .maybes import just
9
7
 
10
8
 
11
9
  T = ta.TypeVar('T')
@@ -203,7 +201,7 @@ class GeneratorMappedIterator(ta.Generic[O, I, R]):
203
201
 
204
202
  self._g = g
205
203
  self._it = it
206
- self._value: Maybe[R] = empty()
204
+ self._value: Maybe[R] = Maybe.empty()
207
205
 
208
206
  @property
209
207
  def g(self) -> ta.Generator[O, I, R]:
@@ -225,7 +223,7 @@ class GeneratorMappedIterator(ta.Generic[O, I, R]):
225
223
  try:
226
224
  o = self._g.send(i)
227
225
  except StopIteration as e:
228
- self._value = just(e.value)
226
+ self._value = Maybe.just(e.value)
229
227
  raise StopIteration from e
230
228
  return o
231
229
 
omlish/lang/params.py CHANGED
@@ -7,12 +7,10 @@ import enum
7
7
  import inspect
8
8
  import typing as ta
9
9
 
10
+ from ..lite.maybes import Maybe
10
11
  from .classes.abstract import Abstract
11
12
  from .classes.restrict import Final
12
13
  from .classes.restrict import Sealed
13
- from .maybes import Maybe
14
- from .maybes import empty
15
- from .maybes import just
16
14
 
17
15
 
18
16
  T = ta.TypeVar('T')
@@ -25,7 +23,7 @@ T = ta.TypeVar('T')
25
23
  class Param(Sealed, Abstract):
26
24
  name: str
27
25
 
28
- annotation: Maybe = empty()
26
+ annotation: Maybe = Maybe.empty()
29
27
 
30
28
  prefix: ta.ClassVar[str] = ''
31
29
 
@@ -57,7 +55,7 @@ class KwargsParam(VarParam, Final):
57
55
 
58
56
  @dc.dataclass(frozen=True, unsafe_hash=True)
59
57
  class ValParam(Param):
60
- default: Maybe = empty()
58
+ default: Maybe = Maybe.empty()
61
59
 
62
60
 
63
61
  @dc.dataclass(frozen=True, unsafe_hash=True)
@@ -83,9 +81,9 @@ class ParamSeparator(enum.Enum):
83
81
 
84
82
  def _inspect_empty_to_maybe(o: T) -> Maybe[T]:
85
83
  if o is inspect.Parameter.empty:
86
- return empty()
84
+ return Maybe.empty()
87
85
  else:
88
- return just(o)
86
+ return Maybe.just(o)
89
87
 
90
88
 
91
89
  class ParamSpec(ta.Sequence[Param], Final):
@@ -119,8 +117,8 @@ class ParamSpec(ta.Sequence[Param], Final):
119
117
  if i < offset:
120
118
  continue
121
119
 
122
- ann = _inspect_empty_to_maybe(ip.annotation) if not strip_annotations else empty()
123
- dfl = _inspect_empty_to_maybe(ip.default) if not strip_defaults else empty()
120
+ ann = _inspect_empty_to_maybe(ip.annotation) if not strip_annotations else Maybe.empty()
121
+ dfl = _inspect_empty_to_maybe(ip.default) if not strip_defaults else Maybe.empty()
124
122
 
125
123
  if ip.kind == inspect.Parameter.POSITIONAL_ONLY:
126
124
  ps.append(PosOnlyParam(ip.name, ann, dfl))
omlish/lite/maybes.py CHANGED
@@ -1,15 +1,23 @@
1
+ # ruff: noqa: UP007
1
2
  import abc
2
3
  import functools
3
4
  import typing as ta
4
5
 
5
6
 
6
7
  T = ta.TypeVar('T')
8
+ U = ta.TypeVar('U')
7
9
 
8
10
 
9
11
  ##
10
12
 
11
13
 
14
+ @functools.total_ordering
12
15
  class Maybe(ta.Generic[T]):
16
+ class ValueNotPresentError(BaseException):
17
+ pass
18
+
19
+ #
20
+
13
21
  @property
14
22
  @abc.abstractmethod
15
23
  def present(self) -> bool:
@@ -19,9 +27,102 @@ class Maybe(ta.Generic[T]):
19
27
  def must(self) -> T:
20
28
  raise NotImplementedError
21
29
 
30
+ #
31
+
32
+ @abc.abstractmethod
33
+ def __repr__(self) -> str:
34
+ raise NotImplementedError
35
+
36
+ @abc.abstractmethod
37
+ def __hash__(self) -> int:
38
+ raise NotImplementedError
39
+
40
+ @abc.abstractmethod
41
+ def __eq__(self, other) -> bool:
42
+ raise NotImplementedError
43
+
44
+ @abc.abstractmethod
45
+ def __lt__(self, other) -> bool:
46
+ raise NotImplementedError
47
+
48
+ #
49
+
50
+ @ta.final
51
+ def __ne__(self, other):
52
+ return not (self == other)
53
+
54
+ @ta.final
55
+ def __iter__(self) -> ta.Iterator[T]:
56
+ if self.present:
57
+ yield self.must()
58
+
59
+ @ta.final
60
+ def __bool__(self) -> ta.NoReturn:
61
+ raise TypeError
62
+
63
+ #
64
+
65
+ @ta.final
66
+ def if_present(self, consumer: ta.Callable[[T], None]) -> None:
67
+ if self.present:
68
+ consumer(self.must())
69
+
70
+ @ta.final
71
+ def filter(self, predicate: ta.Callable[[T], bool]) -> 'Maybe[T]':
72
+ if self.present and predicate(self.must()):
73
+ return self
74
+ else:
75
+ return Maybe.empty()
76
+
77
+ @ta.final
78
+ def map(self, mapper: ta.Callable[[T], U]) -> 'Maybe[U]':
79
+ if self.present:
80
+ return Maybe.just(mapper(self.must()))
81
+ else:
82
+ return Maybe.empty()
83
+
84
+ @ta.final
85
+ def flat_map(self, mapper: ta.Callable[[T], 'Maybe[U]']) -> 'Maybe[U]':
86
+ if self.present:
87
+ if not isinstance(v := mapper(self.must()), Maybe):
88
+ raise TypeError(v)
89
+ return v
90
+ else:
91
+ return Maybe.empty()
92
+
93
+ @ta.final
94
+ def or_else(self, other: ta.Union[T, U]) -> ta.Union[T, U]:
95
+ if self.present:
96
+ return self.must()
97
+ else:
98
+ return other
99
+
100
+ @ta.final
101
+ def or_else_get(self, supplier: ta.Callable[[], ta.Union[T, U]]) -> ta.Union[T, U]:
102
+ if self.present:
103
+ return self.must()
104
+ else:
105
+ return supplier()
106
+
107
+ @ta.final
108
+ def or_else_raise(self, exception_supplier: ta.Callable[[], Exception]) -> T:
109
+ if self.present:
110
+ return self.must()
111
+ else:
112
+ raise exception_supplier()
113
+
114
+ #
115
+
116
+ @classmethod
117
+ def of_optional(cls, v: ta.Optional[T]) -> 'Maybe[T]':
118
+ if v is not None:
119
+ return cls.just(v)
120
+ else:
121
+ return cls.empty()
122
+
22
123
  @classmethod
23
124
  def just(cls, v: T) -> 'Maybe[T]':
24
- return tuple.__new__(_Maybe, (v,)) # noqa
125
+ return _JustMaybe(v)
25
126
 
26
127
  _empty: ta.ClassVar['Maybe']
27
128
 
@@ -30,33 +131,76 @@ class Maybe(ta.Generic[T]):
30
131
  return Maybe._empty
31
132
 
32
133
 
33
- class _Maybe(Maybe[T], tuple):
34
- __slots__ = ()
134
+ ##
35
135
 
36
- def __init_subclass__(cls, **kwargs):
37
- raise TypeError
136
+
137
+ class _Maybe(Maybe[T], abc.ABC):
138
+ def __lt__(self, other):
139
+ if not isinstance(other, _Maybe):
140
+ return NotImplemented
141
+ sp = self.present
142
+ op = other.present
143
+ if self.present and other.present:
144
+ return self.must() < other.must()
145
+ else:
146
+ return op and not sp
147
+
148
+
149
+ class _JustMaybe(_Maybe[T]):
150
+ __slots__ = ('_v', '_hash')
151
+
152
+ def __init__(self, v: T) -> None:
153
+ super().__init__()
154
+
155
+ self._v = v
38
156
 
39
157
  @property
40
158
  def present(self) -> bool:
41
- return bool(self)
159
+ return True
42
160
 
43
161
  def must(self) -> T:
44
- if not self:
45
- raise ValueError
46
- return self[0]
162
+ return self._v
47
163
 
164
+ #
48
165
 
49
- Maybe._empty = tuple.__new__(_Maybe, ()) # noqa
166
+ def __repr__(self) -> str:
167
+ return f'just({self._v!r})'
50
168
 
169
+ def __hash__(self) -> int:
170
+ try:
171
+ return self._hash # type: ignore[has-type]
172
+ except AttributeError:
173
+ pass
174
+ h = self._hash = hash((_JustMaybe, self._v))
175
+ return h
51
176
 
52
- ##
177
+ def __eq__(self, other):
178
+ return (
179
+ self.__class__ is other.__class__ and
180
+ self._v == other._v # noqa
181
+ )
182
+
183
+
184
+ class _EmptyMaybe(_Maybe[T]):
185
+ __slots__ = ()
186
+
187
+ @property
188
+ def present(self) -> bool:
189
+ return False
190
+
191
+ def must(self) -> T:
192
+ raise Maybe.ValueNotPresentError
193
+
194
+ #
195
+
196
+ def __repr__(self) -> str:
197
+ return 'empty()'
53
198
 
199
+ def __hash__(self) -> int:
200
+ return hash(_EmptyMaybe)
54
201
 
55
- @functools.singledispatch
56
- def as_maybe(obj: ta.Any) -> Maybe:
57
- raise TypeError(obj)
202
+ def __eq__(self, other):
203
+ return self.__class__ is other.__class__
58
204
 
59
205
 
60
- @as_maybe.register
61
- def _(obj: Maybe) -> Maybe:
62
- return obj
206
+ Maybe._empty = _EmptyMaybe() # noqa
omlish/logs/callers.py CHANGED
@@ -7,6 +7,9 @@ import types
7
7
  import typing as ta
8
8
 
9
9
 
10
+ ##
11
+
12
+
10
13
  class LoggingCaller(ta.NamedTuple):
11
14
  filename: str
12
15
  lineno: int
omlish/logs/color.py CHANGED
@@ -6,6 +6,9 @@ from ..term import codes as tc
6
6
  from .standard import StandardLogFormatter
7
7
 
8
8
 
9
+ ##
10
+
11
+
9
12
  class ColorLogFormatter(StandardLogFormatter):
10
13
  LEVEL_COLORS: ta.Mapping[int, tc.SGRs.FG] = {
11
14
  logging.WARNING: tc.SGRs.FG.BRIGHT_YELLOW,
omlish/logs/filters.py CHANGED
@@ -4,7 +4,14 @@ import logging
4
4
  import threading
5
5
 
6
6
 
7
+ ##
8
+
9
+
7
10
  class TidLogFilter(logging.Filter):
8
11
  def filter(self, record):
9
- record.tid = threading.get_native_id()
12
+ # FIXME: handle better - missing from wasm and cosmos
13
+ if hasattr(threading, 'get_native_id'):
14
+ record.tid = threading.get_native_id()
15
+ else:
16
+ record.tid = '?'
10
17
  return True
omlish/logs/handlers.py CHANGED
@@ -4,6 +4,9 @@ import logging
4
4
  import typing as ta
5
5
 
6
6
 
7
+ ##
8
+
9
+
7
10
  class ListHandler(logging.Handler):
8
11
  def __init__(self) -> None:
9
12
  super().__init__()
omlish/logs/json.py CHANGED
@@ -10,6 +10,9 @@ import typing as ta
10
10
  from ..lite.json import json_dumps_compact
11
11
 
12
12
 
13
+ ##
14
+
15
+
13
16
  class JsonLogFormatter(logging.Formatter):
14
17
  KEYS: ta.Mapping[str, bool] = {
15
18
  'name': False,
omlish/logs/noisy.py CHANGED
@@ -1,6 +1,9 @@
1
1
  import logging
2
2
 
3
3
 
4
+ ##
5
+
6
+
4
7
  NOISY_LOGGERS: set[str] = {
5
8
  'boto3.resources.action',
6
9
  'datadog.dogstatsd',
omlish/logs/proxy.py CHANGED
@@ -3,6 +3,9 @@
3
3
  import logging
4
4
 
5
5
 
6
+ ##
7
+
8
+
6
9
  class ProxyLogFilterer(logging.Filterer):
7
10
  def __init__(self, underlying: logging.Filterer) -> None: # noqa
8
11
  self._underlying = underlying
omlish/logs/utils.py CHANGED
@@ -2,6 +2,9 @@ import functools
2
2
  import logging
3
3
 
4
4
 
5
+ ##
6
+
7
+
5
8
  _log = logging.getLogger(__name__)
6
9
 
7
10
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omlish
3
- Version: 0.0.0.dev315
3
+ Version: 0.0.0.dev316
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=orgsRvtpHu8tdhaCvlP9v3P495OJopYYiHKjK68WtWg,8587
2
- omlish/__about__.py,sha256=LDFOlaYknirgV_RjbBKwDWTdloPE5HH2GlmJgG9phI4,3478
2
+ omlish/__about__.py,sha256=Lteg-7hW9bBGPlLc6vR48ef4x6Ods9p5RyKlY5-teWw,3478
3
3
  omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
4
4
  omlish/c3.py,sha256=rer-TPOFDU6fYq_AWio_AmA-ckZ8JDY5shIzQ_yXfzA,8414
5
5
  omlish/cached.py,sha256=MLap_p0rdGoDIMVhXVHm1tsbcWobJF0OanoodV03Ju8,542
@@ -262,10 +262,10 @@ omlish/formats/ini/sections.py,sha256=7wYyZdVTQbMPFpjQEACKJfAEPzUBrogINsrvFgxJoZ
262
262
  omlish/formats/json/__init__.py,sha256=HXFv4VDTBhx0k5U4JYWZqxziBwzJoPX51QK3xIboT8U,786
263
263
  omlish/formats/json/codecs.py,sha256=E5KErfqsgGZq763ixXLT3qysbk5MIsypT92xG5aSaIs,796
264
264
  omlish/formats/json/consts.py,sha256=A0cTAGGLyjo-gcYIQrL4JIaardI0yPMhQoNmh42BaRg,387
265
- omlish/formats/json/encoding.py,sha256=O4iIWle7W_-RwpOvJNlqOfkbnDyiQHexV5Za4hlrFzw,497
265
+ omlish/formats/json/encoding.py,sha256=iwoYyJePibgvRDZ6e9b2OlXmOBJEczquRNoiffVf3hE,502
266
266
  omlish/formats/json/json.py,sha256=Mdqv2vdMi7gp96eV0BIYH5UdWpjWfsh-tSMZeywG-08,331
267
- omlish/formats/json/literals.py,sha256=6ptwZyfTXodEtAjDnUhsx6XU3KRZWWYWKYtZ8T7rzsQ,5625
268
- omlish/formats/json/rendering.py,sha256=r6J5YKSzcxPg_RiG5idGqJ-AIZozJQ_Awj6W_oSGRjk,4555
267
+ omlish/formats/json/literals.py,sha256=NMMBhP43cX2mfpiFsMysQWhbSBc0Ux-zegiah62cSmE,7198
268
+ omlish/formats/json/rendering.py,sha256=rWDIiGvLQ0GkCyOKsPywFSo3FdYJ-pCHyrX6MCqitRs,4556
269
269
  omlish/formats/json/types.py,sha256=ueO9-uOU2eVWowJf0LH1fHFLjZ6fTIZyq9qybcLQaiQ,147
270
270
  omlish/formats/json/backends/__init__.py,sha256=gnaNDCxy_KmmPUPDnjxO5_WjuWxLGbI9FYWx8ZJuQUU,97
271
271
  omlish/formats/json/backends/base.py,sha256=WqtyoM82pyM0NyqpPwndrebr1bUVU1QlpmVQNrcAO8c,1114
@@ -335,7 +335,7 @@ omlish/http/clients/httpx.py,sha256=Grl9_sG7QNIZj8HqaU7XduAsBDyfXl36RjbYQzQqal0,
335
335
  omlish/http/clients/urllib.py,sha256=DVKFPLQzANiZmwnlbFw5pWs5ZPLLvvgCb3UInvCSqPE,2701
336
336
  omlish/http/coro/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
337
337
  omlish/http/coro/fdio.py,sha256=bd9K4EYVWbXV3e3npDPXI9DuDAruJiyDmrgFpgNcjzY,4035
338
- omlish/http/coro/server.py,sha256=30FTcJG8kuFeThf0HJYpTzMZN-giLTBP7wr5Wl3b9X0,18285
338
+ omlish/http/coro/server.py,sha256=r8qfVLn-wdB_GI0n41NjhHg72JU5K8-JZgU-KhuVoDs,18259
339
339
  omlish/http/coro/simple.py,sha256=inWA_ss6Nz5Rqmy4dL9_SGah4anYoDecDTRQqVIGYeY,3200
340
340
  omlish/http/coro/sockets.py,sha256=rtpZZ-XCOfC5tXr4Fmo1HSn-8f5nxfIOlJaPUkQeDyU,1654
341
341
  omlish/inject/__init__.py,sha256=pY-A8Q4v08-Xa4a-XdZ3lSFC3OwCO2T9HhesB67Q4tQ,1895
@@ -402,7 +402,7 @@ omlish/iterators/iterators.py,sha256=RxW35yQ5ed8vBQ22IqpDXFx-i5JiLQdp7-pkMZXhJJ8
402
402
  omlish/iterators/recipes.py,sha256=wOwOZg-zWG9Zc3wcAxJFSe2rtavVBYwZOfG09qYEx_4,472
403
403
  omlish/iterators/tools.py,sha256=c4hArZEVV8y9_dFfmRwakusv1cWJLT4MkTkGRjnGN5U,2556
404
404
  omlish/iterators/unique.py,sha256=Nw0pSaNEcHAkve0ugfLPvJcirDOn9ECyC5wIL8JlJKI,1395
405
- omlish/lang/__init__.py,sha256=7T9vv39wNkm9jb0LOpzQ1eMxtoMbltMCU554FqTZ4eY,5908
405
+ omlish/lang/__init__.py,sha256=Zs5YE5F7rq2cdEqK2e6QuamTQGGwLaM0OP_RNOmcT1A,5921
406
406
  omlish/lang/attrs.py,sha256=i7euRF81uNF8QDmUVXSK_BtqLGshaMi4VVdUnMjiMwg,5050
407
407
  omlish/lang/casing.py,sha256=cFUlbDdXLhwnWwcYx4qnM5c4zGX7hIRUfcjiZbxUD28,4636
408
408
  omlish/lang/clsdct.py,sha256=HAGIvBSbCefzRjXriwYSBLO7QHKRv2UsE78jixOb-fA,1828
@@ -413,13 +413,12 @@ omlish/lang/datetimes.py,sha256=mrTtA67JYpfQwSlzdPcBtvm6dAyYM_dXNnlxFwFQH0M,228
413
413
  omlish/lang/descriptors.py,sha256=zBtgO9LjdSTGHNUgiIqswh78WOVoGH6KzS0NbgB1Wls,6572
414
414
  omlish/lang/enums.py,sha256=F9tflHfaAoV2MpyuhZzpfX9-H55M3zNa9hCszsngEo8,111
415
415
  omlish/lang/functions.py,sha256=75JhKRNhe2iDeqN7yCdLTw_q5k1VFpdphypqb4yy2I0,6298
416
- omlish/lang/generators.py,sha256=yd3ebG2LlA3XQImP8rplt6tSToXwMxhlGRGCkdJ87ME,5230
416
+ omlish/lang/generators.py,sha256=a4D5HU_mySs2T2z3xCmE_s3t4QJkj0YRrK4-hhpGd0A,5197
417
417
  omlish/lang/imports.py,sha256=y9W9Y-d_cQ35QCLuSIPoa6vnEqSErFCz8b-34IH128U,10552
418
418
  omlish/lang/iterables.py,sha256=StoGp9yaP3njdLKHoWYcEevO3eE8SHEPYl5_avZob24,2149
419
- omlish/lang/maybes.py,sha256=pb1YrxmpXy-hWKmWR89GxXqZq1MoUD1uuTaTX30peh0,3697
420
419
  omlish/lang/objects.py,sha256=nbxBHfQHVw0OG4qeSTP2GvIiFIcH2tbbitY8y-mYPPo,5959
421
420
  omlish/lang/outcomes.py,sha256=mpFy_VoM-b74L1aCFsjsZVUHx_icZ1AHMOKeVesjOp4,8628
422
- omlish/lang/params.py,sha256=QmNVBfJsfxjDG5ilDPgHV7sK4UwRztkSQdLTo0umb8I,6648
421
+ omlish/lang/params.py,sha256=sfbNoGrKCsAtubFufj_uh_WKshIgA8fqJ4PmLH1PH00,6639
423
422
  omlish/lang/recursion.py,sha256=1VfSqzKO-8Is3t9LKw0W4jwPfE0aBS70EUlbUxAx4eE,1900
424
423
  omlish/lang/resolving.py,sha256=ei9LDyJexsMMHB9z8diUkNmynWhd_da7h7TqrMYM6lA,1611
425
424
  omlish/lang/resources.py,sha256=WKkAddC3ctMK1bvGw-elGe8ZxAj2IaUTKVSu2nfgHTo,2839
@@ -453,7 +452,7 @@ omlish/lite/inject.py,sha256=-tTsOqqef-Ix5Tgl2DP_JAsNWJQDFUptERl3lk14Uzs,29007
453
452
  omlish/lite/json.py,sha256=7-02Ny4fq-6YAu5ynvqoijhuYXWpLmfCI19GUeZnb1c,740
454
453
  omlish/lite/logs.py,sha256=CWFG0NKGhqNeEgryF5atN2gkPYbUdTINEw_s1phbINM,51
455
454
  omlish/lite/marshal.py,sha256=4DCbLoimLwJakihpvMjJ_kpc7v9aZQY8P3-gkoqEGUE,18471
456
- omlish/lite/maybes.py,sha256=I7b2dJFkDll4B_QDlI6iKJG8fy91L6_Tj_s5eB3KI7Q,1013
455
+ omlish/lite/maybes.py,sha256=00UUjtI29-gQD3sjgogIqxl74iD395GqdDQB-k0nxm8,4363
457
456
  omlish/lite/pycharm.py,sha256=pUOJevrPClSqTCEOkQBO11LKX2003tfDcp18a03QFrc,1163
458
457
  omlish/lite/reflect.py,sha256=pzOY2PPuHH0omdtglkN6DheXDrGopdL3PtTJnejyLFU,2189
459
458
  omlish/lite/reprs.py,sha256=QI5VBtvq_TW1TojWL25c04QfOABLi8Smt5jc5J-bArc,2008
@@ -468,18 +467,18 @@ omlish/lite/typing.py,sha256=U3-JaEnkDSYxK4tsu_MzUn3RP6qALBe5FXQXpD-licE,1090
468
467
  omlish/logs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
469
468
  omlish/logs/abc.py,sha256=ho4ABKYMKX-V7g4sp1BByuOLzslYzLlQ0MESmjEpT-o,8005
470
469
  omlish/logs/all.py,sha256=Er2NIcDvlMpuAcRr9b_uMHeoERU7I6lu5oLrDGRdV0U,728
471
- omlish/logs/callers.py,sha256=W0BdEtuGkQ0JM-FCsXQIBQCsNUbIsbDrtCaJy9DStk4,1143
472
- omlish/logs/color.py,sha256=CM-ceoPXs0j5_klnZDJkFCFRgHOToFzJyLjC6LsnPEk,665
470
+ omlish/logs/callers.py,sha256=aCAT-B161IB211x5CGMYGbzzrNut7xWGYJ_E1rZpan0,1148
471
+ omlish/logs/color.py,sha256=u1-6ulsxTWMPyeKu-pCQyF5_ljuEeuG4FG7i6DTzHe0,670
473
472
  omlish/logs/configs.py,sha256=XOc8rWxfPpPMxJESVD2mLCUoLtbQnGnZwvYhhqe7DD8,772
474
- omlish/logs/filters.py,sha256=2noFRyBez3y519fpfsDSt1vo8wX-85b8sMXZi5o_xyE,208
475
- omlish/logs/handlers.py,sha256=zgSnKQA5q9Fu7T0Nkd7twog9H1Wg9-bDCzz4_F1TOBo,319
476
- omlish/logs/json.py,sha256=zyqMWpZY3lk4WRk4wgmataBomGX9S3iDsydiM1sS-lI,1366
477
- omlish/logs/noisy.py,sha256=Ubc-eTH6ZbGYsLfUUi69JAotwuUwzb-SJBeGo_0dIZI,348
473
+ omlish/logs/filters.py,sha256=rNmRtoAktUT-CG__hgqW-8aSdR9ocby4pUmP1wKf4Vk,370
474
+ omlish/logs/handlers.py,sha256=wymFmRO8fcBePyfir9U4FIHzWuyW0D_HwEQAiIQLwAk,324
475
+ omlish/logs/json.py,sha256=muekHkKmGIqq_wr-tV94WwXjNFtUBbFeRdni-JhrCkA,1371
476
+ omlish/logs/noisy.py,sha256=hWpbseerZqlHdEPEajDTSmcRhx8LmmNAxz_7GBZAO9s,353
478
477
  omlish/logs/protocol.py,sha256=dfAR0_5kLEAkx0nhuWBhWMTVjWjhEl2uL-MxejrW1lk,4732
479
- omlish/logs/proxy.py,sha256=A-ROPUUAlF397qTbEqhel6YhQMstNuXL3Xmts7w9dAo,2347
478
+ omlish/logs/proxy.py,sha256=hypbn_x-lGJChP6iHPN3ZkyEA9rw1tbAnGd4aAuc0fk,2352
480
479
  omlish/logs/standard.py,sha256=FbKdF2Z4Na5i2TNwKn0avLJXyICe2JKsPufjvKCHGn0,3162
481
480
  omlish/logs/timing.py,sha256=XrFUHIPT4EHDujLKbGs9fGFMmoM3NEP8xPRaESJr7bQ,1513
482
- omlish/logs/utils.py,sha256=mzHrZ9ji75p5A8qR29eUr05CBAHMb8J753MSkID_VaQ,393
481
+ omlish/logs/utils.py,sha256=OkFWf1exmWImmT7BaSiIC7c0Fk9tAis-PRqo8H4ny3c,398
483
482
  omlish/manifests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
484
483
  omlish/manifests/base.py,sha256=D1WvJYcBR_njkc0gpALpFCWh1h3agb9qgqphnbbPlm4,935
485
484
  omlish/manifests/load.py,sha256=9mdsS3egmSX9pymO-m-y2Fhs4p6ruOdbsYaKT1-1Hwg,6655
@@ -853,9 +852,9 @@ omlish/typedvalues/holder.py,sha256=ZTnHiw-K38ciOBLEdwgrltr7Xp8jjEs_0Lp69DH-G-o,
853
852
  omlish/typedvalues/marshal.py,sha256=hWHRLcrGav7lvXJDtb9bNI0ickl4SKPQ6F4BbTpqw3A,4219
854
853
  omlish/typedvalues/reflect.py,sha256=Ih1YgU-srUjsvBn_P7C66f73_VCvcwqE3ffeBnZBgt4,674
855
854
  omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
856
- omlish-0.0.0.dev315.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
857
- omlish-0.0.0.dev315.dist-info/METADATA,sha256=Ork2jAan-wlGr9Z5xsOAkIrAD3jNAWqjaz6nKg7XiUs,4416
858
- omlish-0.0.0.dev315.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
859
- omlish-0.0.0.dev315.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
860
- omlish-0.0.0.dev315.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
861
- omlish-0.0.0.dev315.dist-info/RECORD,,
855
+ omlish-0.0.0.dev316.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
856
+ omlish-0.0.0.dev316.dist-info/METADATA,sha256=-NOxa8LncyL8kMJ9KG9rdMF4oCf60aY1fALrI0TCdMg,4416
857
+ omlish-0.0.0.dev316.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
858
+ omlish-0.0.0.dev316.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
859
+ omlish-0.0.0.dev316.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
860
+ omlish-0.0.0.dev316.dist-info/RECORD,,
omlish/lang/maybes.py DELETED
@@ -1,157 +0,0 @@
1
- import abc
2
- import typing as ta
3
-
4
- from ..lite.maybes import Maybe as _LiteMaybe
5
- from ..lite.maybes import as_maybe as _as_lite_maybe
6
-
7
-
8
- T = ta.TypeVar('T')
9
- U = ta.TypeVar('U')
10
-
11
-
12
- ##
13
-
14
-
15
- class ValueNotPresentException(BaseException):
16
- pass
17
-
18
-
19
- class Maybe(abc.ABC, ta.Generic[T]):
20
- @property
21
- @abc.abstractmethod
22
- def present(self) -> bool:
23
- raise NotImplementedError
24
-
25
- @abc.abstractmethod
26
- def must(self) -> T:
27
- raise NotImplementedError
28
-
29
- @abc.abstractmethod
30
- def __call__(self) -> T:
31
- raise NotImplementedError
32
-
33
- @abc.abstractmethod
34
- def __iter__(self) -> ta.Iterator[T]:
35
- raise NotImplementedError
36
-
37
- @abc.abstractmethod
38
- def __getitem__(self, item: int) -> T:
39
- raise NotImplementedError
40
-
41
- @abc.abstractmethod
42
- def if_present(self, consumer: ta.Callable[[T], None]) -> None:
43
- raise NotImplementedError
44
-
45
- @abc.abstractmethod
46
- def filter(self, predicate: ta.Callable[[T], bool]) -> 'Maybe[T]':
47
- raise NotImplementedError
48
-
49
- @abc.abstractmethod
50
- def map(self, mapper: ta.Callable[[T], U]) -> 'Maybe[U]':
51
- raise NotImplementedError
52
-
53
- @abc.abstractmethod
54
- def flat_map(self, mapper: ta.Callable[[T], 'Maybe[U]']) -> 'Maybe[U]':
55
- raise NotImplementedError
56
-
57
- @abc.abstractmethod
58
- def or_else(self, other: T | U) -> T | U:
59
- raise NotImplementedError
60
-
61
- @abc.abstractmethod
62
- def or_else_get(self, supplier: ta.Callable[[], U]) -> T | U:
63
- raise NotImplementedError
64
-
65
- @abc.abstractmethod
66
- def or_else_raise(self, exception_supplier: ta.Callable[[], Exception]) -> T:
67
- raise NotImplementedError
68
-
69
-
70
- class _Maybe(Maybe[T], tuple):
71
- __slots__ = ()
72
-
73
- def __init_subclass__(cls, **kwargs):
74
- raise TypeError
75
-
76
- @property
77
- def present(self) -> bool:
78
- return bool(self)
79
-
80
- def must(self) -> T:
81
- if not self:
82
- raise ValueNotPresentException
83
- return self[0]
84
-
85
- __call__ = must
86
-
87
- def __iter__(self) -> ta.Iterator[T]:
88
- raise TypeError
89
-
90
- locals()['__iter__'] = tuple.__iter__
91
-
92
- def __getitem__(self, item: int) -> T: # type: ignore
93
- raise TypeError
94
-
95
- locals()['__getitem__'] = tuple.__getitem__
96
-
97
- def if_present(self, consumer: ta.Callable[[T], None]) -> None:
98
- if self:
99
- consumer(self[0])
100
-
101
- def filter(self, predicate: ta.Callable[[T], bool]) -> Maybe[T]:
102
- return self if self and predicate(self[0]) else _empty
103
-
104
- def map(self, mapper: ta.Callable[[T], U]) -> Maybe[U]:
105
- if self:
106
- return just(mapper(self[0]))
107
- return _empty # noqa
108
-
109
- def flat_map(self, mapper: ta.Callable[[T], Maybe[U]]) -> Maybe[U]:
110
- if self:
111
- value = mapper(self[0])
112
- if not isinstance(value, Maybe):
113
- raise TypeError(value)
114
- return value
115
- return _empty # noqa
116
-
117
- def or_else(self, other: T | U) -> T | U:
118
- return self.must() if self else other
119
-
120
- def or_else_get(self, supplier: ta.Callable[[], T | U]) -> T | U:
121
- return self.must() if self else supplier()
122
-
123
- def or_else_raise(self, exception_supplier: ta.Callable[[], Exception]) -> T:
124
- if self:
125
- return self.must()
126
- raise exception_supplier()
127
-
128
-
129
- #
130
-
131
-
132
- def just(v: T) -> Maybe[T]:
133
- return tuple.__new__(_Maybe, (v,)) # noqa
134
-
135
-
136
- _empty = tuple.__new__(_Maybe, ())
137
-
138
-
139
- def empty() -> Maybe[T]:
140
- return _empty # noqa
141
-
142
-
143
- def maybe(o: T | None) -> Maybe[T]:
144
- if o is None:
145
- return _empty # noqa
146
- return just(o)
147
-
148
-
149
- ##
150
-
151
-
152
- @_as_lite_maybe.register
153
- def _(obj: Maybe) -> _LiteMaybe:
154
- if obj.present:
155
- return _LiteMaybe.just(obj.must())
156
- else:
157
- return _LiteMaybe.empty()