omlish 0.0.0.dev1__py3-none-any.whl → 0.0.0.dev2__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.
Potentially problematic release.
This version of omlish might be problematic. Click here for more details.
- omlish/__about__.py +2 -2
- omlish/argparse.py +4 -4
- omlish/asyncs/anyio.py +62 -1
- omlish/asyncs/futures.py +6 -6
- omlish/c3.py +4 -4
- omlish/check.py +6 -6
- omlish/collections/__init__.py +98 -63
- omlish/collections/cache/descriptor.py +5 -5
- omlish/collections/cache/impl.py +4 -4
- omlish/collections/coerce.py +43 -43
- omlish/collections/frozen.py +3 -3
- omlish/collections/identity.py +1 -1
- omlish/collections/mappings.py +3 -3
- omlish/collections/ordered.py +1 -1
- omlish/collections/skiplist.py +6 -6
- omlish/collections/sorted.py +3 -3
- omlish/collections/treap.py +17 -17
- omlish/collections/treapmap.py +2 -2
- omlish/collections/unmodifiable.py +28 -27
- omlish/configs/flattening.py +1 -1
- omlish/configs/props.py +1 -1
- omlish/dataclasses/impl/__init__.py +2 -0
- omlish/dataclasses/impl/api.py +5 -13
- omlish/dataclasses/impl/fields.py +1 -1
- omlish/dataclasses/impl/init.py +1 -1
- omlish/dataclasses/impl/internals.py +15 -0
- omlish/dataclasses/impl/main.py +4 -4
- omlish/dataclasses/impl/metaclass.py +1 -1
- omlish/dataclasses/impl/metadata.py +1 -1
- omlish/dataclasses/impl/order.py +1 -1
- omlish/dataclasses/impl/params.py +4 -38
- omlish/dataclasses/impl/reflect.py +1 -7
- omlish/dataclasses/impl/repr.py +23 -5
- omlish/dataclasses/impl/simple.py +2 -2
- omlish/dataclasses/impl/slots.py +2 -2
- omlish/dataclasses/impl/utils.py +4 -4
- omlish/dispatch/dispatch.py +9 -8
- omlish/dispatch/methods.py +2 -2
- omlish/docker.py +8 -6
- omlish/dynamic.py +5 -5
- omlish/graphs/dot/items.py +1 -1
- omlish/graphs/trees.py +15 -21
- omlish/inject/elements.py +1 -1
- omlish/inject/exceptions.py +1 -1
- omlish/inject/impl/injector.py +1 -1
- omlish/inject/impl/inspect.py +1 -1
- omlish/inject/injector.py +1 -1
- omlish/inject/providers.py +2 -2
- omlish/iterators.py +43 -2
- omlish/lang/__init__.py +167 -112
- omlish/lang/cached.py +13 -5
- omlish/lang/classes/__init__.py +35 -24
- omlish/lang/classes/abstract.py +1 -1
- omlish/lang/classes/simple.py +1 -1
- omlish/lang/clsdct.py +1 -1
- omlish/lang/contextmanagers.py +23 -15
- omlish/lang/datetimes.py +1 -1
- omlish/lang/descriptors.py +35 -2
- omlish/lang/exceptions.py +2 -0
- omlish/lang/functions.py +43 -13
- omlish/lang/imports.py +8 -8
- omlish/lang/iterables.py +1 -1
- omlish/lang/maybes.py +1 -1
- omlish/lang/objects.py +2 -2
- omlish/lang/timeouts.py +53 -0
- omlish/lang/typing.py +2 -2
- omlish/libc.py +6 -6
- omlish/marshal/base.py +6 -6
- omlish/marshal/dataclasses.py +2 -2
- omlish/marshal/enums.py +2 -2
- omlish/marshal/factories.py +10 -10
- omlish/marshal/iterables.py +2 -2
- omlish/marshal/mappings.py +2 -2
- omlish/marshal/optionals.py +4 -4
- omlish/marshal/polymorphism.py +4 -4
- omlish/marshal/standard.py +6 -6
- omlish/marshal/utils.py +1 -1
- omlish/os.py +13 -4
- omlish/procfs.py +336 -0
- omlish/reflect.py +2 -12
- omlish/replserver/console.py +9 -9
- omlish/replserver/server.py +4 -4
- omlish/sql/__init__.py +0 -0
- omlish/sql/_abcs.py +65 -0
- omlish/sql/dbs.py +90 -0
- omlish/stats.py +3 -3
- omlish/testing/pydevd.py +4 -6
- omlish/testing/pytest/inject/__init__.py +7 -0
- omlish/testing/pytest/inject/harness.py +23 -1
- omlish/testing/pytest/plugins/__init__.py +1 -1
- omlish/testing/pytest/plugins/pydevd.py +12 -0
- omlish/testing/pytest/plugins/switches.py +2 -2
- omlish/testing/testing.py +5 -5
- omlish/text/parts.py +3 -3
- omlish-0.0.0.dev2.dist-info/METADATA +31 -0
- omlish-0.0.0.dev2.dist-info/RECORD +193 -0
- {omlish-0.0.0.dev1.dist-info → omlish-0.0.0.dev2.dist-info}/WHEEL +1 -1
- omlish/testing/pytest/plugins/pycharm.py +0 -54
- omlish-0.0.0.dev1.dist-info/METADATA +0 -17
- omlish-0.0.0.dev1.dist-info/RECORD +0 -187
- {omlish-0.0.0.dev1.dist-info → omlish-0.0.0.dev2.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev1.dist-info → omlish-0.0.0.dev2.dist-info}/top_level.txt +0 -0
omlish/lang/functions.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import dataclasses as dc
|
|
1
2
|
import functools
|
|
2
3
|
import time
|
|
3
4
|
import typing as ta
|
|
@@ -6,6 +7,7 @@ from .descriptors import is_method_descriptor
|
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
T = ta.TypeVar('T')
|
|
10
|
+
CallableT = ta.TypeVar('CallableT', bound=ta.Callable)
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
def is_lambda(f: ta.Any) -> bool:
|
|
@@ -50,8 +52,8 @@ def raise_(o: BaseException) -> ta.NoReturn:
|
|
|
50
52
|
|
|
51
53
|
|
|
52
54
|
def try_(
|
|
53
|
-
exc:
|
|
54
|
-
default:
|
|
55
|
+
exc: type[Exception] | ta.Iterable[type[Exception]] = Exception,
|
|
56
|
+
default: T | None = None,
|
|
55
57
|
) -> ta.Callable[..., T]:
|
|
56
58
|
def outer(fn):
|
|
57
59
|
def inner(*args, **kwargs):
|
|
@@ -113,14 +115,42 @@ def void(*args, **kwargs) -> ta.NoReturn:
|
|
|
113
115
|
raise VoidException
|
|
114
116
|
|
|
115
117
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
_MISSING = object()
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def periodically(
|
|
122
|
+
fn: CallableT,
|
|
123
|
+
interval_s: float,
|
|
124
|
+
initial: ta.Any = _MISSING,
|
|
125
|
+
*,
|
|
126
|
+
include_runtime: bool = False,
|
|
127
|
+
) -> CallableT:
|
|
128
|
+
nxt = time.time() + interval_s
|
|
129
|
+
ret = initial
|
|
130
|
+
|
|
131
|
+
@functools.wraps(fn)
|
|
132
|
+
def inner(*args, **kwargs):
|
|
133
|
+
nonlocal nxt, ret
|
|
134
|
+
if time.time() >= nxt or ret is _MISSING:
|
|
135
|
+
if include_runtime:
|
|
136
|
+
nxt = time.time() + interval_s
|
|
137
|
+
ret = fn(*args, **kwargs)
|
|
138
|
+
if not include_runtime:
|
|
139
|
+
nxt = time.time() + interval_s
|
|
140
|
+
return ret
|
|
141
|
+
|
|
142
|
+
return inner # type: ignore
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@dc.dataclass(init=False)
|
|
146
|
+
class Args:
|
|
147
|
+
args: ta.Sequence[ta.Any]
|
|
148
|
+
kwargs: ta.Mapping[str, ta.Any]
|
|
149
|
+
|
|
150
|
+
def __init__(self, *args: ta.Any, **kwargs: ta.Any) -> None:
|
|
151
|
+
super().__init__()
|
|
152
|
+
self.args = args
|
|
153
|
+
self.kwargs = kwargs
|
|
154
|
+
|
|
155
|
+
def __call__(self, fn: ta.Callable[..., T]) -> T:
|
|
156
|
+
return fn(*self.args, **self.kwargs)
|
omlish/lang/imports.py
CHANGED
|
@@ -10,11 +10,11 @@ from .cached import cached_function
|
|
|
10
10
|
##
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def lazy_import(name: str, package:
|
|
13
|
+
def lazy_import(name: str, package: str | None = None) -> ta.Callable[[], ta.Any]:
|
|
14
14
|
return cached_function(functools.partial(importlib.import_module, name, package=package))
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
def proxy_import(name: str, package:
|
|
17
|
+
def proxy_import(name: str, package: str | None = None) -> types.ModuleType:
|
|
18
18
|
omod = None
|
|
19
19
|
|
|
20
20
|
def __getattr__(att):
|
|
@@ -65,7 +65,7 @@ def yield_importable(
|
|
|
65
65
|
package_root: str,
|
|
66
66
|
*,
|
|
67
67
|
recursive: bool = False,
|
|
68
|
-
filter: ta.
|
|
68
|
+
filter: ta.Callable[[str], bool] | None = None,
|
|
69
69
|
include_special: bool = False,
|
|
70
70
|
) -> ta.Iterator[str]:
|
|
71
71
|
def rec(dir):
|
|
@@ -112,10 +112,10 @@ def yield_importable(
|
|
|
112
112
|
def yield_import_all(
|
|
113
113
|
package_root: str,
|
|
114
114
|
*,
|
|
115
|
-
globals:
|
|
116
|
-
locals:
|
|
115
|
+
globals: dict[str, ta.Any] | None = None,
|
|
116
|
+
locals: dict[str, ta.Any] | None = None,
|
|
117
117
|
recursive: bool = False,
|
|
118
|
-
filter: ta.
|
|
118
|
+
filter: ta.Callable[[str], bool] | None = None,
|
|
119
119
|
include_special: bool = False,
|
|
120
120
|
) -> ta.Iterator[str]:
|
|
121
121
|
for import_path in yield_importable(
|
|
@@ -132,7 +132,7 @@ def import_all(
|
|
|
132
132
|
package_root: str,
|
|
133
133
|
*,
|
|
134
134
|
recursive: bool = False,
|
|
135
|
-
filter: ta.
|
|
135
|
+
filter: ta.Callable[[str], bool] | None = None,
|
|
136
136
|
include_special: bool = False,
|
|
137
137
|
) -> None:
|
|
138
138
|
for _ in yield_import_all(
|
|
@@ -144,7 +144,7 @@ def import_all(
|
|
|
144
144
|
pass
|
|
145
145
|
|
|
146
146
|
|
|
147
|
-
def try_import(spec: str) ->
|
|
147
|
+
def try_import(spec: str) -> types.ModuleType | None:
|
|
148
148
|
s = spec.lstrip('.')
|
|
149
149
|
l = len(spec) - len(s)
|
|
150
150
|
try:
|
omlish/lang/iterables.py
CHANGED
|
@@ -34,7 +34,7 @@ def peek(vs: ta.Iterable[T]) -> ta.Tuple[T, ta.Iterator[T]]:
|
|
|
34
34
|
return v, itertools.chain(iter((v,)), it)
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
Rangeable: ta.TypeAlias =
|
|
37
|
+
Rangeable: ta.TypeAlias = int | ta.Tuple[int] | ta.Tuple[int, int] | ta.Iterable[int]
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
def asrange(i: Rangeable) -> ta.Iterable[int]:
|
omlish/lang/maybes.py
CHANGED
omlish/lang/objects.py
CHANGED
|
@@ -28,7 +28,7 @@ def new_type(
|
|
|
28
28
|
name: str,
|
|
29
29
|
bases: ta.Sequence[ta.Any],
|
|
30
30
|
namespace: ta.Mapping[str, ta.Any],
|
|
31
|
-
**kwargs
|
|
31
|
+
**kwargs,
|
|
32
32
|
) -> ta.Type:
|
|
33
33
|
return types.new_class(
|
|
34
34
|
name,
|
|
@@ -44,7 +44,7 @@ def super_meta(
|
|
|
44
44
|
name: str,
|
|
45
45
|
bases: ta.Sequence[ta.Any],
|
|
46
46
|
namespace: ta.MutableMapping[str, ta.Any],
|
|
47
|
-
**kwargs
|
|
47
|
+
**kwargs,
|
|
48
48
|
) -> ta.Type:
|
|
49
49
|
"""Per types.new_class"""
|
|
50
50
|
resolved_bases = types.resolve_bases(bases)
|
omlish/lang/timeouts.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import time
|
|
3
|
+
import typing as ta
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
TimeoutLike: ta.TypeAlias = ta.Union['Timeout', float]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Timeout(abc.ABC):
|
|
10
|
+
@abc.abstractmethod
|
|
11
|
+
def __call__(self) -> float:
|
|
12
|
+
raise NotImplementedError
|
|
13
|
+
|
|
14
|
+
@abc.abstractmethod
|
|
15
|
+
def or_(self, o: ta.Any) -> ta.Any:
|
|
16
|
+
raise NotImplementedError
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class DeadlineTimeout(Timeout):
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
deadline: float,
|
|
23
|
+
exc: type[BaseException] | BaseException = TimeoutError,
|
|
24
|
+
) -> None:
|
|
25
|
+
super().__init__()
|
|
26
|
+
self.deadline = deadline
|
|
27
|
+
self.exc = exc
|
|
28
|
+
|
|
29
|
+
def __call__(self) -> float:
|
|
30
|
+
if (rem := self.deadline - time.time()) > 0:
|
|
31
|
+
return rem
|
|
32
|
+
raise self.exc
|
|
33
|
+
|
|
34
|
+
def or_(self, o: ta.Any) -> ta.Any:
|
|
35
|
+
return self()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class InfiniteTimeout(Timeout):
|
|
39
|
+
def __call__(self) -> float:
|
|
40
|
+
return float('inf')
|
|
41
|
+
|
|
42
|
+
def or_(self, o: ta.Any) -> ta.Any:
|
|
43
|
+
return o
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def timeout(t: TimeoutLike | None) -> Timeout:
|
|
47
|
+
if t is None:
|
|
48
|
+
return InfiniteTimeout()
|
|
49
|
+
if isinstance(t, Timeout):
|
|
50
|
+
return t
|
|
51
|
+
if isinstance(t, (float, int)):
|
|
52
|
+
return DeadlineTimeout(time.time() + t)
|
|
53
|
+
raise TypeError(t)
|
omlish/lang/typing.py
CHANGED
|
@@ -12,7 +12,7 @@ import typing as ta
|
|
|
12
12
|
Ty = ta.TypeVar('Ty', bound=type)
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
BytesLike: ta.TypeAlias =
|
|
15
|
+
BytesLike: ta.TypeAlias = bytes | bytearray
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
##
|
|
@@ -87,6 +87,6 @@ def typed_partial(obj, **kw):
|
|
|
87
87
|
for n, p in sig.parameters.items()
|
|
88
88
|
if n not in kw
|
|
89
89
|
and p.annotation is not inspect.Signature.empty
|
|
90
|
-
}
|
|
90
|
+
},
|
|
91
91
|
)(inner)
|
|
92
92
|
return _update_wrapper_no_anns(lam, obj)
|
omlish/libc.py
CHANGED
|
@@ -94,7 +94,7 @@ libc.mmap.argtypes = [
|
|
|
94
94
|
ct.c_int,
|
|
95
95
|
ct.c_int,
|
|
96
96
|
ct.c_int,
|
|
97
|
-
ct.c_size_t
|
|
97
|
+
ct.c_size_t,
|
|
98
98
|
]
|
|
99
99
|
mmap = libc.mmap
|
|
100
100
|
|
|
@@ -138,7 +138,7 @@ elif DARWIN:
|
|
|
138
138
|
libc.munmap.restype = ct.c_int
|
|
139
139
|
libc.munmap.argtypes = [
|
|
140
140
|
ct.c_void_p,
|
|
141
|
-
ct.c_size_t
|
|
141
|
+
ct.c_size_t,
|
|
142
142
|
]
|
|
143
143
|
munmap = libc.munmap
|
|
144
144
|
|
|
@@ -148,7 +148,7 @@ libc.mprotect.restype = ct.c_int
|
|
|
148
148
|
libc.mprotect.argtypes = [
|
|
149
149
|
ct.c_void_p,
|
|
150
150
|
ct.c_size_t,
|
|
151
|
-
ct.c_int
|
|
151
|
+
ct.c_int,
|
|
152
152
|
]
|
|
153
153
|
mprotect = libc.mprotect
|
|
154
154
|
|
|
@@ -164,7 +164,7 @@ if LINUX:
|
|
|
164
164
|
ct.c_void_p,
|
|
165
165
|
ct.c_size_t,
|
|
166
166
|
ct.c_size_t,
|
|
167
|
-
ct.c_int
|
|
167
|
+
ct.c_int,
|
|
168
168
|
]
|
|
169
169
|
mremap = libc.mremap
|
|
170
170
|
|
|
@@ -179,7 +179,7 @@ class Mmap:
|
|
|
179
179
|
length: int,
|
|
180
180
|
*,
|
|
181
181
|
prot: int = PROT_READ | PROT_WRITE,
|
|
182
|
-
flags:
|
|
182
|
+
flags: int | None = None,
|
|
183
183
|
fd: int = -1,
|
|
184
184
|
offset: int = 0,
|
|
185
185
|
desired_base: int = 0,
|
|
@@ -205,7 +205,7 @@ class Mmap:
|
|
|
205
205
|
self._is_mapped = False
|
|
206
206
|
|
|
207
207
|
@property
|
|
208
|
-
def base(self) ->
|
|
208
|
+
def base(self) -> int | None:
|
|
209
209
|
return self._base
|
|
210
210
|
|
|
211
211
|
def __enter__(self) -> 'Mmap':
|
omlish/marshal/base.py
CHANGED
|
@@ -146,7 +146,7 @@ class BaseContext(lang.Abstract):
|
|
|
146
146
|
|
|
147
147
|
@dc.dataclass(frozen=True)
|
|
148
148
|
class MarshalContext(BaseContext, lang.Final):
|
|
149
|
-
factory:
|
|
149
|
+
factory: MarshalerFactory | None = None
|
|
150
150
|
|
|
151
151
|
def make(self, o: ta.Any) -> Marshaler:
|
|
152
152
|
rty = rfl.type_(o)
|
|
@@ -157,7 +157,7 @@ class MarshalContext(BaseContext, lang.Final):
|
|
|
157
157
|
|
|
158
158
|
@dc.dataclass(frozen=True)
|
|
159
159
|
class UnmarshalContext(BaseContext, lang.Final):
|
|
160
|
-
factory:
|
|
160
|
+
factory: UnmarshalerFactory | None = None
|
|
161
161
|
|
|
162
162
|
def make(self, o: ta.Any) -> Unmarshaler:
|
|
163
163
|
rty = rfl.type_(o)
|
|
@@ -194,8 +194,8 @@ class RecursiveUnmarshalerFactory(RecursiveTypeFactory[Unmarshaler, UnmarshalCon
|
|
|
194
194
|
|
|
195
195
|
@dc.dataclass(frozen=True)
|
|
196
196
|
class SetType(RegistryItem, lang.Final):
|
|
197
|
-
marshaler:
|
|
198
|
-
marshaler_factory:
|
|
197
|
+
marshaler: Marshaler | None = None
|
|
198
|
+
marshaler_factory: MarshalerFactory | None = None
|
|
199
199
|
|
|
200
|
-
unmarshaler:
|
|
201
|
-
unmarshaler_factory:
|
|
200
|
+
unmarshaler: Unmarshaler | None = None
|
|
201
|
+
unmarshaler_factory: UnmarshalerFactory | None = None
|
omlish/marshal/dataclasses.py
CHANGED
|
@@ -79,7 +79,7 @@ def _make_field_obj(ctx, ty, obj, fac):
|
|
|
79
79
|
|
|
80
80
|
|
|
81
81
|
class DataclassMarshalerFactory(MarshalerFactory):
|
|
82
|
-
def __call__(self, ctx: MarshalContext, rty: rfl.Type) ->
|
|
82
|
+
def __call__(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler | None:
|
|
83
83
|
if isinstance(rty, type) and dc.is_dataclass(rty):
|
|
84
84
|
dc_md = get_dataclass_metadata(rty)
|
|
85
85
|
fields = [
|
|
@@ -97,7 +97,7 @@ class DataclassMarshalerFactory(MarshalerFactory):
|
|
|
97
97
|
|
|
98
98
|
|
|
99
99
|
class DataclassUnmarshalerFactory(UnmarshalerFactory):
|
|
100
|
-
def __call__(self, ctx: UnmarshalContext, rty: rfl.Type) ->
|
|
100
|
+
def __call__(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler | None:
|
|
101
101
|
if isinstance(rty, type) and dc.is_dataclass(rty):
|
|
102
102
|
dc_md = get_dataclass_metadata(rty)
|
|
103
103
|
d: dict[str, tuple[FieldInfo, Unmarshaler]] = {}
|
omlish/marshal/enums.py
CHANGED
|
@@ -22,7 +22,7 @@ class EnumMarshaler(Marshaler):
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class EnumMarshalerFactory(MarshalerFactory):
|
|
25
|
-
def __call__(self, ctx: MarshalContext, rty: rfl.Type) ->
|
|
25
|
+
def __call__(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler | None:
|
|
26
26
|
if isinstance(rty, type) and issubclass(rty, enum.Enum):
|
|
27
27
|
return EnumMarshaler(rty)
|
|
28
28
|
return None
|
|
@@ -37,7 +37,7 @@ class EnumUnmarshaler(Unmarshaler):
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
class EnumUnmarshalerFactory(UnmarshalerFactory):
|
|
40
|
-
def __call__(self, ctx: UnmarshalContext, rty: rfl.Type) ->
|
|
40
|
+
def __call__(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler | None:
|
|
41
41
|
if isinstance(rty, type) and issubclass(rty, enum.Enum):
|
|
42
42
|
return EnumUnmarshaler(rty)
|
|
43
43
|
return None
|
omlish/marshal/factories.py
CHANGED
|
@@ -17,7 +17,7 @@ A = ta.TypeVar('A')
|
|
|
17
17
|
|
|
18
18
|
class Factory(abc.ABC, ta.Generic[R, C, A]):
|
|
19
19
|
@abc.abstractmethod
|
|
20
|
-
def __call__(self, ctx: C, arg: A) ->
|
|
20
|
+
def __call__(self, ctx: C, arg: A) -> R | None:
|
|
21
21
|
raise NotImplementedError
|
|
22
22
|
|
|
23
23
|
|
|
@@ -26,9 +26,9 @@ class Factory(abc.ABC, ta.Generic[R, C, A]):
|
|
|
26
26
|
|
|
27
27
|
@dc.dataclass(frozen=True)
|
|
28
28
|
class FuncFactory(ta.Generic[R, C, A]):
|
|
29
|
-
fn: ta.Callable[[C, A],
|
|
29
|
+
fn: ta.Callable[[C, A], R | None]
|
|
30
30
|
|
|
31
|
-
def __call__(self, ctx: C, arg: A) ->
|
|
31
|
+
def __call__(self, ctx: C, arg: A) -> R | None:
|
|
32
32
|
return self.fn(ctx, arg)
|
|
33
33
|
|
|
34
34
|
|
|
@@ -39,7 +39,7 @@ class FuncFactory(ta.Generic[R, C, A]):
|
|
|
39
39
|
class TypeMapFactory(Factory[R, C, rfl.Type]):
|
|
40
40
|
m: ta.Mapping[rfl.Type, R] = dc.field(default_factory=dict)
|
|
41
41
|
|
|
42
|
-
def __call__(self, ctx: C, rty: rfl.Type) ->
|
|
42
|
+
def __call__(self, ctx: C, rty: rfl.Type) -> R | None:
|
|
43
43
|
return self.m.get(rty)
|
|
44
44
|
|
|
45
45
|
|
|
@@ -50,10 +50,10 @@ class TypeCacheFactory(Factory[R, C, rfl.Type]):
|
|
|
50
50
|
def __init__(self, f: Factory[R, C, rfl.Type]) -> None:
|
|
51
51
|
super().__init__()
|
|
52
52
|
self._f = f
|
|
53
|
-
self._dct: dict[rfl.Type,
|
|
53
|
+
self._dct: dict[rfl.Type, R | None] = {}
|
|
54
54
|
self._mtx = threading.RLock()
|
|
55
55
|
|
|
56
|
-
def __call__(self, ctx: C, rty: rfl.Type) ->
|
|
56
|
+
def __call__(self, ctx: C, rty: rfl.Type) -> R | None:
|
|
57
57
|
try:
|
|
58
58
|
return self._dct[rty]
|
|
59
59
|
except KeyError:
|
|
@@ -73,14 +73,14 @@ class RecursiveTypeFactory(Factory[R, C, rfl.Type]):
|
|
|
73
73
|
def __init__(
|
|
74
74
|
self,
|
|
75
75
|
f: Factory[R, C, rfl.Type],
|
|
76
|
-
prx: ta.Callable[[], tuple[
|
|
76
|
+
prx: ta.Callable[[], tuple[R | None, ta.Callable[[R | None], None]]],
|
|
77
77
|
) -> None:
|
|
78
78
|
super().__init__()
|
|
79
79
|
self._f = f
|
|
80
80
|
self._prx = prx
|
|
81
|
-
self._dct: dict[rfl.Type,
|
|
81
|
+
self._dct: dict[rfl.Type, R | None] = {}
|
|
82
82
|
|
|
83
|
-
def __call__(self, ctx: C, rty: rfl.Type) ->
|
|
83
|
+
def __call__(self, ctx: C, rty: rfl.Type) -> R | None:
|
|
84
84
|
try:
|
|
85
85
|
return self._dct[rty]
|
|
86
86
|
except KeyError:
|
|
@@ -108,7 +108,7 @@ class CompositeFactory(Factory[R, C, A]):
|
|
|
108
108
|
self._fs = fs
|
|
109
109
|
self._st = strategy
|
|
110
110
|
|
|
111
|
-
def __call__(self, ctx: C, arg: A) ->
|
|
111
|
+
def __call__(self, ctx: C, arg: A) -> R | None:
|
|
112
112
|
w: list[R] = []
|
|
113
113
|
for c in self._fs:
|
|
114
114
|
if (r := c(ctx, arg)) is None:
|
omlish/marshal/iterables.py
CHANGED
|
@@ -23,7 +23,7 @@ class IterableMarshaler(Marshaler):
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class IterableMarshalerFactory(MarshalerFactory):
|
|
26
|
-
def __call__(self, ctx: MarshalContext, rty: rfl.Type) ->
|
|
26
|
+
def __call__(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler | None:
|
|
27
27
|
if isinstance(rty, rfl.Generic) and issubclass(rty.cls, collections.abc.Iterable):
|
|
28
28
|
if (e := ctx.make(check.single(rty.args))) is None:
|
|
29
29
|
return None # type: ignore
|
|
@@ -45,7 +45,7 @@ class IterableUnmarshaler(Unmarshaler):
|
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
class IterableUnmarshalerFactory(UnmarshalerFactory):
|
|
48
|
-
def __call__(self, ctx: UnmarshalContext, rty: rfl.Type) ->
|
|
48
|
+
def __call__(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler | None:
|
|
49
49
|
if isinstance(rty, rfl.Generic) and issubclass(rty.cls, collections.abc.Iterable):
|
|
50
50
|
if (e := ctx.make(check.single(rty.args))) is None:
|
|
51
51
|
return None # type: ignore
|
omlish/marshal/mappings.py
CHANGED
|
@@ -26,7 +26,7 @@ class MappingMarshaler(Marshaler):
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
class MappingMarshalerFactory(MarshalerFactory):
|
|
29
|
-
def __call__(self, ctx: MarshalContext, rty: rfl.Type) ->
|
|
29
|
+
def __call__(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler | None:
|
|
30
30
|
if isinstance(rty, rfl.Generic) and issubclass(rty.cls, collections.abc.Mapping):
|
|
31
31
|
kt, vt = rty.args
|
|
32
32
|
if (ke := ctx.make(kt)) is None or (ve := ctx.make(vt)) is None:
|
|
@@ -53,7 +53,7 @@ class MappingUnmarshaler(Unmarshaler):
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
class MappingUnmarshalerFactory(UnmarshalerFactory):
|
|
56
|
-
def __call__(self, ctx: UnmarshalContext, rty: rfl.Type) ->
|
|
56
|
+
def __call__(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler | None:
|
|
57
57
|
if isinstance(rty, rfl.Generic) and issubclass(rty.cls, collections.abc.Mapping):
|
|
58
58
|
kt, vt = rty.args
|
|
59
59
|
if (ke := ctx.make(kt)) is None or (ve := ctx.make(vt)) is None:
|
omlish/marshal/optionals.py
CHANGED
|
@@ -15,14 +15,14 @@ from .values import Value
|
|
|
15
15
|
class OptionalMarshaler(Marshaler):
|
|
16
16
|
e: Marshaler
|
|
17
17
|
|
|
18
|
-
def marshal(self, ctx: MarshalContext, o: ta.
|
|
18
|
+
def marshal(self, ctx: MarshalContext, o: ta.Any | None) -> Value:
|
|
19
19
|
if o is None:
|
|
20
20
|
return None
|
|
21
21
|
return self.e.marshal(ctx, o)
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class OptionalMarshalerFactory(MarshalerFactory):
|
|
25
|
-
def __call__(self, ctx: MarshalContext, rty: rfl.Type) ->
|
|
25
|
+
def __call__(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler | None:
|
|
26
26
|
if isinstance(rty, rfl.Union) and rty.is_optional:
|
|
27
27
|
if (e := ctx.make(rty.without_none())) is None:
|
|
28
28
|
return None # type: ignore
|
|
@@ -34,14 +34,14 @@ class OptionalMarshalerFactory(MarshalerFactory):
|
|
|
34
34
|
class OptionalUnmarshaler(Unmarshaler):
|
|
35
35
|
e: Unmarshaler
|
|
36
36
|
|
|
37
|
-
def unmarshal(self, ctx: UnmarshalContext, v: Value) -> ta.
|
|
37
|
+
def unmarshal(self, ctx: UnmarshalContext, v: Value) -> ta.Any | None:
|
|
38
38
|
if v is None:
|
|
39
39
|
return None
|
|
40
40
|
return self.e.unmarshal(ctx, v)
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
class OptionalUnmarshalerFactory(UnmarshalerFactory):
|
|
44
|
-
def __call__(self, ctx: UnmarshalContext, rty: rfl.Type) ->
|
|
44
|
+
def __call__(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler | None:
|
|
45
45
|
if isinstance(rty, rfl.Union) and rty.is_optional:
|
|
46
46
|
if (e := ctx.make(rty.without_none())) is None:
|
|
47
47
|
return None # type: ignore
|
omlish/marshal/polymorphism.py
CHANGED
|
@@ -100,7 +100,7 @@ def polymorphism_from_subclasses(ty: type, *, naming: Naming | None = None) -> P
|
|
|
100
100
|
class PolymorphismMarshaler(Marshaler):
|
|
101
101
|
m: ta.Mapping[type, tuple[str, Marshaler]]
|
|
102
102
|
|
|
103
|
-
def marshal(self, ctx: MarshalContext, o: ta.
|
|
103
|
+
def marshal(self, ctx: MarshalContext, o: ta.Any | None) -> Value:
|
|
104
104
|
tag, m = self.m[type(o)]
|
|
105
105
|
return {tag: m.marshal(ctx, o)}
|
|
106
106
|
|
|
@@ -109,7 +109,7 @@ class PolymorphismMarshaler(Marshaler):
|
|
|
109
109
|
class PolymorphismMarshalerFactory(MarshalerFactory):
|
|
110
110
|
p: Polymorphism
|
|
111
111
|
|
|
112
|
-
def __call__(self, ctx: MarshalContext, rty: rfl.Type) ->
|
|
112
|
+
def __call__(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler | None:
|
|
113
113
|
if rty is self.p.ty:
|
|
114
114
|
return PolymorphismMarshaler({
|
|
115
115
|
i.ty: (i.tag, ctx.make(i.ty))
|
|
@@ -125,7 +125,7 @@ class PolymorphismMarshalerFactory(MarshalerFactory):
|
|
|
125
125
|
class PolymorphismUnmarshaler(Unmarshaler):
|
|
126
126
|
m: ta.Mapping[str, Unmarshaler]
|
|
127
127
|
|
|
128
|
-
def unmarshal(self, ctx: UnmarshalContext, v: Value) -> ta.
|
|
128
|
+
def unmarshal(self, ctx: UnmarshalContext, v: Value) -> ta.Any | None:
|
|
129
129
|
ma = check.isinstance(v, collections.abc.Mapping)
|
|
130
130
|
[(tag, iv)] = ma.items()
|
|
131
131
|
u = self.m[tag] # type: ignore
|
|
@@ -136,7 +136,7 @@ class PolymorphismUnmarshaler(Unmarshaler):
|
|
|
136
136
|
class PolymorphismUnmarshalerFactory(UnmarshalerFactory):
|
|
137
137
|
p: Polymorphism
|
|
138
138
|
|
|
139
|
-
def __call__(self, ctx: UnmarshalContext, rty: rfl.Type) ->
|
|
139
|
+
def __call__(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler | None:
|
|
140
140
|
if rty is self.p.ty:
|
|
141
141
|
return PolymorphismUnmarshaler({
|
|
142
142
|
t: u
|
omlish/marshal/standard.py
CHANGED
|
@@ -47,9 +47,9 @@ def new_standard_marshaler_factory() -> MarshalerFactory:
|
|
|
47
47
|
return TypeCacheFactory( # noqa
|
|
48
48
|
RecursiveMarshalerFactory(
|
|
49
49
|
CompositeFactory(
|
|
50
|
-
*STANDARD_MARSHALER_FACTORIES
|
|
51
|
-
)
|
|
52
|
-
)
|
|
50
|
+
*STANDARD_MARSHALER_FACTORIES,
|
|
51
|
+
),
|
|
52
|
+
),
|
|
53
53
|
)
|
|
54
54
|
|
|
55
55
|
|
|
@@ -74,7 +74,7 @@ def new_standard_unmarshaler_factory() -> UnmarshalerFactory:
|
|
|
74
74
|
return TypeCacheFactory( # noqa
|
|
75
75
|
RecursiveUnmarshalerFactory(
|
|
76
76
|
CompositeFactory(
|
|
77
|
-
*STANDARD_UNMARSHALER_FACTORIES
|
|
78
|
-
)
|
|
79
|
-
)
|
|
77
|
+
*STANDARD_UNMARSHALER_FACTORIES,
|
|
78
|
+
),
|
|
79
|
+
),
|
|
80
80
|
)
|
omlish/marshal/utils.py
CHANGED
omlish/os.py
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
import contextlib
|
|
2
|
+
import resource
|
|
2
3
|
import shutil
|
|
3
4
|
import tempfile
|
|
4
5
|
import typing as ta
|
|
5
6
|
|
|
6
7
|
|
|
8
|
+
PAGE_SIZE = resource.getpagesize()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def round_to_page_size(sz: int) -> int:
|
|
12
|
+
sz += PAGE_SIZE - 1
|
|
13
|
+
return sz - (sz % PAGE_SIZE)
|
|
14
|
+
|
|
15
|
+
|
|
7
16
|
@contextlib.contextmanager
|
|
8
17
|
def tmp_dir(
|
|
9
|
-
root_dir:
|
|
18
|
+
root_dir: str | None = None,
|
|
10
19
|
cleanup: bool = True,
|
|
11
|
-
**kwargs: ta.Any
|
|
20
|
+
**kwargs: ta.Any,
|
|
12
21
|
) -> ta.Iterator[str]:
|
|
13
22
|
path = tempfile.mkdtemp(dir=root_dir, **kwargs)
|
|
14
23
|
try:
|
|
@@ -20,9 +29,9 @@ def tmp_dir(
|
|
|
20
29
|
|
|
21
30
|
@contextlib.contextmanager
|
|
22
31
|
def tmp_file(
|
|
23
|
-
root_dir:
|
|
32
|
+
root_dir: str | None = None,
|
|
24
33
|
cleanup: bool = True,
|
|
25
|
-
**kwargs: ta.Any
|
|
34
|
+
**kwargs: ta.Any,
|
|
26
35
|
) -> ta.Iterator[tempfile._TemporaryFileWrapper]: # noqa
|
|
27
36
|
with tempfile.NamedTemporaryFile(dir=root_dir, delete=False, **kwargs) as f:
|
|
28
37
|
try:
|