omlish 0.0.0.dev315__py3-none-any.whl → 0.0.0.dev317__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 +2 -2
- omlish/collections/utils.py +99 -5
- omlish/formats/json/encoding.py +3 -0
- omlish/formats/json/literals.py +90 -4
- omlish/formats/json/rendering.py +4 -2
- omlish/formats/json5/rendering.py +44 -0
- omlish/http/coro/server.py +1 -2
- omlish/lang/__init__.py +7 -7
- omlish/lang/cached/function.py +66 -9
- omlish/lang/generators.py +3 -5
- omlish/lang/params.py +7 -9
- omlish/lite/maybes.py +163 -17
- omlish/logs/callers.py +3 -0
- omlish/logs/color.py +3 -0
- omlish/logs/filters.py +8 -1
- omlish/logs/handlers.py +3 -0
- omlish/logs/json.py +3 -0
- omlish/logs/noisy.py +3 -0
- omlish/logs/proxy.py +3 -0
- omlish/logs/utils.py +3 -0
- omlish/sockets/ports.py +24 -7
- omlish/testing/pytest/plugins/switches.py +103 -44
- {omlish-0.0.0.dev315.dist-info → omlish-0.0.0.dev317.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev315.dist-info → omlish-0.0.0.dev317.dist-info}/RECORD +28 -28
- {omlish-0.0.0.dev315.dist-info → omlish-0.0.0.dev317.dist-info}/WHEEL +1 -1
- omlish/lang/maybes.py +0 -157
- {omlish-0.0.0.dev315.dist-info → omlish-0.0.0.dev317.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev315.dist-info → omlish-0.0.0.dev317.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev315.dist-info → omlish-0.0.0.dev317.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
omlish/collections/utils.py
CHANGED
@@ -58,13 +58,33 @@ def unique(
|
|
58
58
|
##
|
59
59
|
|
60
60
|
|
61
|
+
@ta.overload
|
62
|
+
def make_map(
|
63
|
+
kvs: ta.Iterable[tuple[K, V]],
|
64
|
+
*,
|
65
|
+
identity: ta.Literal[False] = False,
|
66
|
+
strict: bool = False,
|
67
|
+
) -> dict[K, V]:
|
68
|
+
...
|
69
|
+
|
70
|
+
|
71
|
+
@ta.overload
|
61
72
|
def make_map(
|
62
73
|
kvs: ta.Iterable[tuple[K, V]],
|
63
74
|
*,
|
64
75
|
identity: bool = False,
|
65
76
|
strict: bool = False,
|
66
77
|
) -> ta.MutableMapping[K, V]:
|
67
|
-
|
78
|
+
...
|
79
|
+
|
80
|
+
|
81
|
+
def make_map(
|
82
|
+
kvs,
|
83
|
+
*,
|
84
|
+
identity=False,
|
85
|
+
strict=False,
|
86
|
+
):
|
87
|
+
d: ta.MutableMapping = IdentityKeyDict() if identity else {}
|
68
88
|
for k, v in kvs:
|
69
89
|
if k in d:
|
70
90
|
if strict:
|
@@ -74,6 +94,21 @@ def make_map(
|
|
74
94
|
return d
|
75
95
|
|
76
96
|
|
97
|
+
#
|
98
|
+
|
99
|
+
|
100
|
+
@ta.overload
|
101
|
+
def make_map_by(
|
102
|
+
fn: ta.Callable[[V], K],
|
103
|
+
vs: ta.Iterable[V],
|
104
|
+
*,
|
105
|
+
identity: ta.Literal[False] = False,
|
106
|
+
strict: bool = False,
|
107
|
+
) -> dict[K, V]:
|
108
|
+
...
|
109
|
+
|
110
|
+
|
111
|
+
@ta.overload
|
77
112
|
def make_map_by(
|
78
113
|
fn: ta.Callable[[V], K],
|
79
114
|
vs: ta.Iterable[V],
|
@@ -81,6 +116,16 @@ def make_map_by(
|
|
81
116
|
identity: bool = False,
|
82
117
|
strict: bool = False,
|
83
118
|
) -> ta.MutableMapping[K, V]:
|
119
|
+
...
|
120
|
+
|
121
|
+
|
122
|
+
def make_map_by(
|
123
|
+
fn,
|
124
|
+
vs,
|
125
|
+
*,
|
126
|
+
identity=False,
|
127
|
+
strict=False,
|
128
|
+
):
|
84
129
|
return make_map(
|
85
130
|
((fn(v), v) for v in vs),
|
86
131
|
identity=identity,
|
@@ -91,9 +136,30 @@ def make_map_by(
|
|
91
136
|
##
|
92
137
|
|
93
138
|
|
94
|
-
|
95
|
-
|
96
|
-
|
139
|
+
@ta.overload
|
140
|
+
def multi_map(
|
141
|
+
kvs: ta.Iterable[tuple[K, V]],
|
142
|
+
*,
|
143
|
+
identity: ta.Literal[False] = False,
|
144
|
+
) -> dict[K, list[V]]:
|
145
|
+
...
|
146
|
+
|
147
|
+
|
148
|
+
@ta.overload
|
149
|
+
def multi_map(
|
150
|
+
kvs: ta.Iterable[tuple[K, V]],
|
151
|
+
*,
|
152
|
+
identity: bool = False,
|
153
|
+
) -> ta.MutableMapping[K, list[V]]:
|
154
|
+
...
|
155
|
+
|
156
|
+
|
157
|
+
def multi_map(
|
158
|
+
kvs,
|
159
|
+
*,
|
160
|
+
identity=False,
|
161
|
+
):
|
162
|
+
d: ta.MutableMapping = IdentityKeyDict() if identity else {}
|
97
163
|
for k, v in kvs:
|
98
164
|
try:
|
99
165
|
l = d[k]
|
@@ -103,7 +169,35 @@ def multi_map(kvs: ta.Iterable[tuple[K, V]], *, identity: bool = False) -> ta.Mu
|
|
103
169
|
return d
|
104
170
|
|
105
171
|
|
106
|
-
|
172
|
+
#
|
173
|
+
|
174
|
+
|
175
|
+
@ta.overload
|
176
|
+
def multi_map_by(
|
177
|
+
fn: ta.Callable[[V], K],
|
178
|
+
vs: ta.Iterable[V],
|
179
|
+
*,
|
180
|
+
identity: ta.Literal[False] = False,
|
181
|
+
) -> dict[K, list[V]]: # noqa
|
182
|
+
...
|
183
|
+
|
184
|
+
|
185
|
+
@ta.overload
|
186
|
+
def multi_map_by(
|
187
|
+
fn: ta.Callable[[V], K],
|
188
|
+
vs: ta.Iterable[V],
|
189
|
+
*,
|
190
|
+
identity: bool = False,
|
191
|
+
) -> ta.MutableMapping[K, list[V]]: # noqa
|
192
|
+
...
|
193
|
+
|
194
|
+
|
195
|
+
def multi_map_by(
|
196
|
+
fn,
|
197
|
+
vs,
|
198
|
+
*,
|
199
|
+
identity=False,
|
200
|
+
):
|
107
201
|
return multi_map(((fn(v), v) for v in vs), identity=identity)
|
108
202
|
|
109
203
|
|
omlish/formats/json/encoding.py
CHANGED
omlish/formats/json/literals.py
CHANGED
@@ -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,91 @@ 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_MAP: ta.Mapping[str, str] = {
|
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(
|
60
|
+
s: str | bytes,
|
61
|
+
q: str = '"',
|
62
|
+
*,
|
63
|
+
escape_map: ta.Mapping[str, str] | None = None,
|
64
|
+
) -> str:
|
65
|
+
"""Return a JSON representation of a Python string."""
|
66
|
+
|
67
|
+
if escape_map is None:
|
68
|
+
escape_map = ESCAPE_MAP
|
69
|
+
|
70
|
+
s = _convert_to_string(s)
|
71
|
+
|
72
|
+
def replace(m):
|
73
|
+
return escape_map[m.group(0)]
|
74
|
+
|
75
|
+
return q + _ESCAPE_PAT.sub(replace, s) + q
|
76
|
+
|
77
|
+
|
78
|
+
def encode_string_ascii(
|
79
|
+
s: str | bytes,
|
80
|
+
q: str = '"',
|
81
|
+
*,
|
82
|
+
escape_map: ta.Mapping[str, str] | None = None,
|
83
|
+
) -> str:
|
84
|
+
"""Return an ASCII-only JSON representation of a Python string."""
|
85
|
+
|
86
|
+
if escape_map is None:
|
87
|
+
escape_map = ESCAPE_MAP
|
88
|
+
|
89
|
+
s = _convert_to_string(s)
|
90
|
+
|
91
|
+
def replace(m):
|
92
|
+
s = m.group(0)
|
93
|
+
|
94
|
+
try:
|
95
|
+
return escape_map[s]
|
96
|
+
|
97
|
+
except KeyError:
|
98
|
+
n = ord(s)
|
99
|
+
if n < 0x10000:
|
100
|
+
return f'\\u{n:04x}'
|
101
|
+
|
102
|
+
# surrogate pair
|
103
|
+
n -= 0x10000
|
104
|
+
s1 = 0xD800 | ((n >> 10) & 0x3FF)
|
105
|
+
s2 = 0xDC00 | (n & 0x3FF)
|
106
|
+
return f'\\u{s1:04x}\\u{s2:04x}'
|
107
|
+
|
108
|
+
return q + str(_ESCAPE_ASCII_PAT.sub(replace, s)) + q
|
109
|
+
|
110
|
+
|
111
|
+
##
|
112
|
+
|
113
|
+
|
28
114
|
_FOUR_DIGIT_HEX_PAT = re.compile(r'^[0-9a-fA-F]{4}$')
|
29
115
|
|
30
116
|
|
@@ -32,7 +118,7 @@ def _scan_four_digit_hex(
|
|
32
118
|
s: str,
|
33
119
|
end: int,
|
34
120
|
):
|
35
|
-
"""Scan a four digit hex number from s[end:end + 4]"""
|
121
|
+
"""Scan a four digit hex number from s[end:end + 4]."""
|
36
122
|
|
37
123
|
msg = 'Invalid \\uXXXX escape sequence'
|
38
124
|
esc = s[end: end + 4]
|
@@ -47,7 +133,7 @@ def _scan_four_digit_hex(
|
|
47
133
|
|
48
134
|
_STRING_CHUNK_PAT = re.compile(r'(.*?)(["\\\x00-\x1f])', re.VERBOSE | re.MULTILINE | re.DOTALL)
|
49
135
|
|
50
|
-
|
136
|
+
BACKSLASH_MAP: ta.Mapping[str, str] = {
|
51
137
|
'"': '"',
|
52
138
|
'\\': '\\',
|
53
139
|
'/': '/',
|
@@ -86,7 +172,7 @@ def parse_string(
|
|
86
172
|
prev_end = end
|
87
173
|
end = chunk.end()
|
88
174
|
content, terminator = chunk.groups()
|
89
|
-
# Content
|
175
|
+
# Content contains zero or more unescaped string characters
|
90
176
|
if content:
|
91
177
|
chunks.append(content)
|
92
178
|
|
@@ -110,7 +196,7 @@ def parse_string(
|
|
110
196
|
# If not a unicode escape sequence, must be in the lookup table
|
111
197
|
if esc != 'u':
|
112
198
|
try:
|
113
|
-
char =
|
199
|
+
char = BACKSLASH_MAP[esc]
|
114
200
|
except KeyError:
|
115
201
|
msg = 'Invalid \\X escape sequence %r'
|
116
202
|
raise json.JSONDecodeError(msg, s, end) from None
|
omlish/formats/json/rendering.py
CHANGED
@@ -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()
|
@@ -25,6 +26,7 @@ class AbstractJsonRenderer(lang.Abstract, ta.Generic[I]):
|
|
25
26
|
|
26
27
|
def __init__(
|
27
28
|
self,
|
29
|
+
*,
|
28
30
|
indent: int | str | None = None,
|
29
31
|
separators: tuple[str, str] | None = None,
|
30
32
|
sort_keys: bool = False,
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
from ..json import Scalar
|
4
|
+
from ..json.literals import ESCAPE_MAP
|
5
|
+
from ..json.literals import encode_string
|
6
|
+
from ..json.literals import encode_string_ascii
|
7
|
+
from ..json.rendering import JsonRenderer
|
8
|
+
from ..json.rendering import JsonRendererOut
|
9
|
+
|
10
|
+
|
11
|
+
##
|
12
|
+
|
13
|
+
|
14
|
+
MULTILINE_STRINGS_ESCAPE_MAP = {
|
15
|
+
**ESCAPE_MAP,
|
16
|
+
'\n': '\\n\\\n',
|
17
|
+
}
|
18
|
+
|
19
|
+
|
20
|
+
class Json5Renderer(JsonRenderer):
|
21
|
+
def __init__(
|
22
|
+
self,
|
23
|
+
out: JsonRendererOut,
|
24
|
+
*,
|
25
|
+
multiline_strings: bool = False,
|
26
|
+
**kwargs: ta.Any,
|
27
|
+
) -> None:
|
28
|
+
super().__init__(out, **kwargs)
|
29
|
+
|
30
|
+
self._multiline_strings = multiline_strings
|
31
|
+
|
32
|
+
def _format_scalar(self, o: Scalar) -> str:
|
33
|
+
if (
|
34
|
+
self._multiline_strings and
|
35
|
+
isinstance(o, str) and
|
36
|
+
'\n' in o
|
37
|
+
):
|
38
|
+
if self._ensure_ascii:
|
39
|
+
return encode_string_ascii(o, escape_map=MULTILINE_STRINGS_ESCAPE_MAP)
|
40
|
+
else:
|
41
|
+
return encode_string(o, escape_map=MULTILINE_STRINGS_ESCAPE_MAP)
|
42
|
+
|
43
|
+
else:
|
44
|
+
return super()._format_scalar(o)
|
omlish/http/coro/server.py
CHANGED
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/cached/function.py
CHANGED
@@ -22,6 +22,7 @@ TODO:
|
|
22
22
|
import dataclasses as dc
|
23
23
|
import functools
|
24
24
|
import inspect
|
25
|
+
import types
|
25
26
|
import typing as ta
|
26
27
|
|
27
28
|
from ..classes.abstract import Abstract
|
@@ -153,6 +154,10 @@ def _make_cache_key_maker(
|
|
153
154
|
##
|
154
155
|
|
155
156
|
|
157
|
+
class _CachedException(ta.NamedTuple):
|
158
|
+
ex: BaseException
|
159
|
+
|
160
|
+
|
156
161
|
class _CachedFunction(ta.Generic[T], Abstract):
|
157
162
|
@dc.dataclass(frozen=True, kw_only=True)
|
158
163
|
class Opts:
|
@@ -160,6 +165,19 @@ class _CachedFunction(ta.Generic[T], Abstract):
|
|
160
165
|
lock: DefaultLockable = None
|
161
166
|
transient: bool = False
|
162
167
|
no_wrapper_update: bool = False
|
168
|
+
cache_exceptions: type[BaseException] | tuple[type[BaseException], ...] | None = None
|
169
|
+
|
170
|
+
def __post_init__(self) -> None:
|
171
|
+
if (ce := self.cache_exceptions) is not None:
|
172
|
+
if isinstance(ce, type):
|
173
|
+
if not issubclass(ce, BaseException):
|
174
|
+
raise TypeError(ce)
|
175
|
+
elif isinstance(ce, tuple):
|
176
|
+
for e in ce:
|
177
|
+
if not issubclass(e, BaseException):
|
178
|
+
raise TypeError(e)
|
179
|
+
else:
|
180
|
+
raise TypeError(ce)
|
163
181
|
|
164
182
|
def __init__(
|
165
183
|
self,
|
@@ -199,13 +217,33 @@ class _CachedFunction(ta.Generic[T], Abstract):
|
|
199
217
|
def __call__(self, *args, **kwargs) -> T:
|
200
218
|
k = self._key_maker(*args, **kwargs)
|
201
219
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
220
|
+
if (ce := self._opts.cache_exceptions) is None:
|
221
|
+
try:
|
222
|
+
return self._values[k]
|
223
|
+
except KeyError:
|
224
|
+
pass
|
206
225
|
|
207
|
-
|
208
|
-
|
226
|
+
else:
|
227
|
+
try:
|
228
|
+
hit = self._values[k]
|
229
|
+
except KeyError:
|
230
|
+
pass
|
231
|
+
else:
|
232
|
+
if isinstance(hit, _CachedException):
|
233
|
+
raise hit.ex
|
234
|
+
else:
|
235
|
+
return hit
|
236
|
+
|
237
|
+
if ce is None:
|
238
|
+
def call_value_fn():
|
239
|
+
return self._value_fn(*args, **kwargs)
|
240
|
+
|
241
|
+
else:
|
242
|
+
def call_value_fn():
|
243
|
+
try:
|
244
|
+
return self._value_fn(*args, **kwargs)
|
245
|
+
except ce as ex: # type: ignore[misc]
|
246
|
+
return _CachedException(ex)
|
209
247
|
|
210
248
|
if self._lock is not None:
|
211
249
|
with self._lock:
|
@@ -220,7 +258,11 @@ class _CachedFunction(ta.Generic[T], Abstract):
|
|
220
258
|
value = call_value_fn()
|
221
259
|
|
222
260
|
self._values[k] = value
|
223
|
-
|
261
|
+
|
262
|
+
if isinstance(value, _CachedException):
|
263
|
+
raise value.ex
|
264
|
+
else:
|
265
|
+
return value
|
224
266
|
|
225
267
|
|
226
268
|
#
|
@@ -369,12 +411,27 @@ def cached_function(fn=None, **kwargs): # noqa
|
|
369
411
|
|
370
412
|
opts = _CachedFunction.Opts(**kwargs)
|
371
413
|
|
414
|
+
if isinstance(fn, types.MethodType):
|
415
|
+
return _FreeCachedFunction(
|
416
|
+
fn,
|
417
|
+
opts=opts,
|
418
|
+
key_maker=_make_cache_key_maker(fn, bound=True),
|
419
|
+
)
|
420
|
+
|
372
421
|
if isinstance(fn, staticmethod):
|
373
|
-
return _FreeCachedFunction(
|
422
|
+
return _FreeCachedFunction(
|
423
|
+
fn,
|
424
|
+
opts=opts,
|
425
|
+
value_fn=unwrap_func(fn),
|
426
|
+
)
|
374
427
|
|
375
428
|
scope = classmethod if isinstance(fn, classmethod) else None
|
376
429
|
|
377
|
-
return _DescriptorCachedFunction(
|
430
|
+
return _DescriptorCachedFunction(
|
431
|
+
fn,
|
432
|
+
scope,
|
433
|
+
opts=opts,
|
434
|
+
)
|
378
435
|
|
379
436
|
|
380
437
|
def static_init(fn: CallableT) -> CallableT:
|
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))
|