omlish 0.0.0.dev2__py3-none-any.whl → 0.0.0.dev4__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 +1 -2
- omlish/__init__.py +8 -0
- omlish/argparse.py +4 -4
- omlish/asyncs/__init__.py +23 -2
- omlish/asyncs/anyio.py +13 -11
- omlish/asyncs/asyncs.py +1 -3
- omlish/asyncs/flavors.py +201 -0
- omlish/asyncs/futures.py +10 -9
- omlish/asyncs/trio_asyncio.py +41 -0
- omlish/c3.py +1 -1
- omlish/check.py +3 -3
- omlish/collections/_abc.py +2 -0
- omlish/collections/_io_abc.py +4 -2
- omlish/collections/cache/__init__.py +1 -1
- omlish/collections/cache/descriptor.py +8 -8
- omlish/collections/cache/impl.py +24 -17
- omlish/collections/cache/types.py +1 -1
- omlish/collections/coerce.py +1 -1
- omlish/collections/frozen.py +6 -6
- omlish/collections/identity.py +3 -4
- omlish/collections/mappings.py +2 -2
- omlish/collections/ordered.py +7 -7
- omlish/collections/skiplist.py +1 -1
- omlish/collections/sorted.py +1 -1
- omlish/collections/treap.py +25 -0
- omlish/collections/treapmap.py +57 -5
- omlish/collections/unmodifiable.py +9 -9
- omlish/collections/utils.py +1 -1
- omlish/configs/flattening.py +7 -6
- omlish/configs/props.py +3 -3
- omlish/dataclasses/__init__.py +1 -1
- omlish/dataclasses/impl/__init__.py +17 -1
- omlish/dataclasses/impl/api.py +10 -11
- omlish/dataclasses/impl/as_.py +4 -4
- omlish/dataclasses/impl/exceptions.py +1 -1
- omlish/dataclasses/impl/fields.py +7 -7
- omlish/dataclasses/impl/frozen.py +2 -2
- omlish/dataclasses/impl/init.py +5 -5
- omlish/dataclasses/impl/internals.py +1 -1
- omlish/dataclasses/impl/metaclass.py +1 -1
- omlish/dataclasses/impl/order.py +1 -1
- omlish/dataclasses/impl/replace.py +1 -1
- omlish/dataclasses/impl/repr.py +4 -4
- omlish/dataclasses/impl/utils.py +6 -6
- omlish/defs.py +13 -17
- omlish/{procfs.py → diag/procfs.py} +22 -24
- omlish/diag/ps.py +47 -0
- omlish/{replserver → diag/replserver}/console.py +18 -20
- omlish/{replserver → diag/replserver}/server.py +8 -8
- omlish/dispatch/dispatch.py +5 -8
- omlish/dispatch/functions.py +1 -1
- omlish/dispatch/methods.py +4 -5
- omlish/docker.py +1 -1
- omlish/dynamic.py +10 -10
- omlish/fnpairs.py +400 -0
- omlish/graphs/trees.py +13 -13
- omlish/inject/__init__.py +7 -7
- omlish/inject/elements.py +1 -1
- omlish/inject/exceptions.py +7 -7
- omlish/inject/impl/elements.py +17 -5
- omlish/inject/impl/injector.py +12 -10
- omlish/inject/impl/inspect.py +2 -2
- omlish/inject/impl/scopes.py +12 -11
- omlish/inject/proxy.py +5 -5
- omlish/iterators.py +19 -24
- omlish/json.py +143 -6
- omlish/lang/__init__.py +13 -4
- omlish/lang/cached.py +2 -5
- omlish/lang/classes/__init__.py +2 -2
- omlish/lang/classes/abstract.py +2 -2
- omlish/lang/classes/restrict.py +14 -14
- omlish/lang/classes/simple.py +1 -1
- omlish/lang/classes/virtual.py +5 -5
- omlish/lang/clsdct.py +1 -1
- omlish/lang/cmp.py +2 -2
- omlish/lang/contextmanagers.py +12 -14
- omlish/lang/descriptors.py +16 -4
- omlish/lang/exceptions.py +1 -1
- omlish/lang/functions.py +58 -22
- omlish/lang/imports.py +22 -27
- omlish/lang/iterables.py +2 -2
- omlish/lang/maybes.py +1 -0
- omlish/lang/objects.py +15 -9
- omlish/lang/resolving.py +1 -1
- omlish/lang/strings.py +1 -1
- omlish/lang/sys.py +7 -0
- omlish/lang/typing.py +3 -3
- omlish/libc.py +9 -5
- omlish/logs/_abc.py +5 -1
- omlish/logs/filters.py +2 -0
- omlish/logs/formatters.py +6 -2
- omlish/logs/utils.py +1 -1
- omlish/marshal/base.py +3 -3
- omlish/marshal/exceptions.py +1 -1
- omlish/marshal/global_.py +10 -4
- omlish/marshal/objects.py +1 -2
- omlish/marshal/registries.py +3 -3
- omlish/marshal/utils.py +2 -2
- omlish/marshal/values.py +1 -1
- omlish/math.py +9 -9
- omlish/reflect.py +3 -3
- omlish/sql/__init__.py +9 -0
- omlish/sql/asyncs.py +148 -0
- omlish/stats.py +4 -5
- omlish/term.py +1 -1
- omlish/testing/pydevd.py +28 -6
- omlish/testing/pytest/inject/harness.py +1 -1
- omlish/testing/pytest/plugins/pydevd.py +1 -1
- omlish/testing/pytest/plugins/switches.py +1 -1
- omlish/text/delimit.py +3 -6
- {omlish-0.0.0.dev2.dist-info → omlish-0.0.0.dev4.dist-info}/METADATA +4 -1
- omlish-0.0.0.dev4.dist-info/RECORD +195 -0
- {omlish-0.0.0.dev2.dist-info → omlish-0.0.0.dev4.dist-info}/WHEEL +1 -1
- omlish/lang/classes/test/test_abstract.py +0 -89
- omlish/lang/classes/test/test_restrict.py +0 -71
- omlish/lang/classes/test/test_simple.py +0 -58
- omlish/lang/classes/test/test_virtual.py +0 -72
- omlish-0.0.0.dev2.dist-info/RECORD +0 -193
- /omlish/{lang/classes/test → diag}/__init__.py +0 -0
- /omlish/{replserver → diag/replserver}/__init__.py +0 -0
- /omlish/{replserver → diag/replserver}/__main__.py +0 -0
- /omlish/sql/{_abcs.py → _abc.py} +0 -0
- {omlish-0.0.0.dev2.dist-info → omlish-0.0.0.dev4.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev2.dist-info → omlish-0.0.0.dev4.dist-info}/top_level.txt +0 -0
omlish/inject/__init__.py
CHANGED
|
@@ -18,13 +18,13 @@ from .elements import ( # noqa
|
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
from .exceptions import ( # noqa
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
BaseKeyError,
|
|
22
|
+
CyclicDependencyError,
|
|
23
|
+
DuplicateKeyError,
|
|
24
|
+
ScopeAlreadyOpenError,
|
|
25
|
+
ScopeError,
|
|
26
|
+
ScopeNotOpenError,
|
|
27
|
+
UnboundKeyError,
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
from .injector import ( # noqa
|
omlish/inject/elements.py
CHANGED
omlish/inject/exceptions.py
CHANGED
|
@@ -9,7 +9,7 @@ from .types import Scope
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
@dc.dataclass()
|
|
12
|
-
class
|
|
12
|
+
class BaseKeyError(Exception):
|
|
13
13
|
key: Key
|
|
14
14
|
|
|
15
15
|
source: ta.Any = None
|
|
@@ -17,17 +17,17 @@ class KeyException(Exception):
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
@dc.dataclass()
|
|
20
|
-
class
|
|
20
|
+
class UnboundKeyError(KeyError):
|
|
21
21
|
pass
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
@dc.dataclass()
|
|
25
|
-
class
|
|
25
|
+
class DuplicateKeyError(KeyError):
|
|
26
26
|
pass
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
@dc.dataclass()
|
|
30
|
-
class
|
|
30
|
+
class CyclicDependencyError(KeyError):
|
|
31
31
|
pass
|
|
32
32
|
|
|
33
33
|
|
|
@@ -35,15 +35,15 @@ class CyclicDependencyException(KeyException):
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
@dc.dataclass()
|
|
38
|
-
class
|
|
38
|
+
class ScopeError(Exception):
|
|
39
39
|
scope: Scope
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
@dc.dataclass()
|
|
43
|
-
class
|
|
43
|
+
class ScopeAlreadyOpenError(ScopeError):
|
|
44
44
|
pass
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
@dc.dataclass()
|
|
48
|
-
class
|
|
48
|
+
class ScopeNotOpenError(ScopeError):
|
|
49
49
|
pass
|
omlish/inject/impl/elements.py
CHANGED
|
@@ -14,7 +14,7 @@ Element Types:
|
|
|
14
14
|
- Overrides
|
|
15
15
|
- Expose
|
|
16
16
|
- Private
|
|
17
|
-
-
|
|
17
|
+
- ScopeBinding
|
|
18
18
|
"""
|
|
19
19
|
import typing as ta
|
|
20
20
|
|
|
@@ -25,12 +25,13 @@ from ..bindings import Binding
|
|
|
25
25
|
from ..eagers import Eager
|
|
26
26
|
from ..elements import Element
|
|
27
27
|
from ..elements import Elements
|
|
28
|
-
from ..exceptions import
|
|
28
|
+
from ..exceptions import DuplicateKeyError
|
|
29
29
|
from ..keys import Key
|
|
30
30
|
from ..overrides import Overrides
|
|
31
31
|
from ..private import Expose
|
|
32
32
|
from ..private import Private
|
|
33
33
|
from ..scopes import ScopeBinding
|
|
34
|
+
from ..types import Scope
|
|
34
35
|
from .bindings import BindingImpl
|
|
35
36
|
from .providers import MultiProviderImpl
|
|
36
37
|
from .providers import make_provider_impl
|
|
@@ -51,7 +52,7 @@ class ElementCollection(lang.Final):
|
|
|
51
52
|
|
|
52
53
|
self._es = check.isinstance(es, Elements)
|
|
53
54
|
|
|
54
|
-
self._private_infos: ta.MutableMapping[Private,
|
|
55
|
+
self._private_infos: ta.MutableMapping[Private, private_.PrivateInfo] | None = None
|
|
55
56
|
|
|
56
57
|
##
|
|
57
58
|
|
|
@@ -98,7 +99,7 @@ class ElementCollection(lang.Final):
|
|
|
98
99
|
try:
|
|
99
100
|
bs = ovr[k]
|
|
100
101
|
except KeyError:
|
|
101
|
-
bs =
|
|
102
|
+
bs = b
|
|
102
103
|
add(k, *bs)
|
|
103
104
|
|
|
104
105
|
else:
|
|
@@ -139,7 +140,7 @@ class ElementCollection(lang.Final):
|
|
|
139
140
|
mm.setdefault(k, []).extend(bis)
|
|
140
141
|
else:
|
|
141
142
|
if len(bis) > 1:
|
|
142
|
-
raise
|
|
143
|
+
raise DuplicateKeyError(k)
|
|
143
144
|
[pm[k]] = bis
|
|
144
145
|
|
|
145
146
|
if mm:
|
|
@@ -152,3 +153,14 @@ class ElementCollection(lang.Final):
|
|
|
152
153
|
@lang.cached_function
|
|
153
154
|
def binding_impl_map(self) -> ta.Mapping[Key, BindingImpl]:
|
|
154
155
|
return self._build_binding_impl_map(self.element_multimap())
|
|
156
|
+
|
|
157
|
+
##
|
|
158
|
+
|
|
159
|
+
@lang.cached_function
|
|
160
|
+
def eager_keys_by_scope(self) -> ta.Mapping[Scope, ta.Sequence[Key]]:
|
|
161
|
+
bim = self.binding_impl_map()
|
|
162
|
+
ret: dict[Scope, list[Key]] = {}
|
|
163
|
+
for e in self.elements_of_type(Eager):
|
|
164
|
+
bi = bim[e.key]
|
|
165
|
+
ret.setdefault(bi.scope, []).append(e.key)
|
|
166
|
+
return ret
|
omlish/inject/impl/injector.py
CHANGED
|
@@ -7,6 +7,8 @@ TODO:
|
|
|
7
7
|
- config is probably shared with ElementCollection... but not 'bound', must be shared everywhere
|
|
8
8
|
- InjectorRoot object?
|
|
9
9
|
- ** eagers in any scope, on scope init/open
|
|
10
|
+
- injection listeners
|
|
11
|
+
- unions - raise on ambiguous - usecase: sql.AsyncEngineLike
|
|
10
12
|
"""
|
|
11
13
|
import contextlib
|
|
12
14
|
import typing as ta
|
|
@@ -14,10 +16,9 @@ import weakref
|
|
|
14
16
|
|
|
15
17
|
from ... import check
|
|
16
18
|
from ... import lang
|
|
17
|
-
from ..eagers import Eager
|
|
18
19
|
from ..elements import Elements
|
|
19
|
-
from ..exceptions import
|
|
20
|
-
from ..exceptions import
|
|
20
|
+
from ..exceptions import CyclicDependencyError
|
|
21
|
+
from ..exceptions import UnboundKeyError
|
|
21
22
|
from ..injector import Injector
|
|
22
23
|
from ..inspect import KwargsTarget
|
|
23
24
|
from ..keys import Key
|
|
@@ -52,9 +53,10 @@ class InjectorImpl(Injector, lang.Final):
|
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
self._bim = ec.binding_impl_map()
|
|
56
|
+
self._ekbs = ec.eager_keys_by_scope()
|
|
55
57
|
|
|
56
58
|
self._cs: weakref.WeakSet[InjectorImpl] | None = None
|
|
57
|
-
self._root: InjectorImpl = p._root if p is not None else self
|
|
59
|
+
self._root: InjectorImpl = p._root if p is not None else self # noqa
|
|
58
60
|
|
|
59
61
|
self.__cur_req: InjectorImpl._Request | None = None
|
|
60
62
|
|
|
@@ -66,13 +68,13 @@ class InjectorImpl(Injector, lang.Final):
|
|
|
66
68
|
s: make_scope_impl(s) for s in ss
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
self._instantiate_eagers()
|
|
71
|
+
self._instantiate_eagers(Unscoped())
|
|
70
72
|
|
|
71
73
|
_root: 'InjectorImpl'
|
|
72
74
|
|
|
73
|
-
def _instantiate_eagers(self) -> None:
|
|
74
|
-
for
|
|
75
|
-
self.provide(
|
|
75
|
+
def _instantiate_eagers(self, sc: Scope) -> None:
|
|
76
|
+
for k in self._ekbs.get(sc, ()):
|
|
77
|
+
self.provide(k)
|
|
76
78
|
|
|
77
79
|
def get_scope_impl(self, sc: Scope) -> ScopeImpl:
|
|
78
80
|
return self._scopes[sc]
|
|
@@ -97,7 +99,7 @@ class InjectorImpl(Injector, lang.Final):
|
|
|
97
99
|
except KeyError:
|
|
98
100
|
pass
|
|
99
101
|
if key in self._seen_keys:
|
|
100
|
-
raise
|
|
102
|
+
raise CyclicDependencyError(key)
|
|
101
103
|
self._seen_keys.add(key)
|
|
102
104
|
return lang.empty()
|
|
103
105
|
|
|
@@ -154,7 +156,7 @@ class InjectorImpl(Injector, lang.Final):
|
|
|
154
156
|
v = self.try_provide(key)
|
|
155
157
|
if v.present:
|
|
156
158
|
return v.must()
|
|
157
|
-
raise
|
|
159
|
+
raise UnboundKeyError(key)
|
|
158
160
|
|
|
159
161
|
def provide_kwargs(self, kt: KwargsTarget) -> ta.Mapping[str, ta.Any]:
|
|
160
162
|
ret: dict[str, ta.Any] = {}
|
omlish/inject/impl/inspect.py
CHANGED
|
@@ -11,7 +11,7 @@ import typing as ta
|
|
|
11
11
|
import weakref
|
|
12
12
|
|
|
13
13
|
from ... import reflect as rfl
|
|
14
|
-
from ..exceptions import
|
|
14
|
+
from ..exceptions import DuplicateKeyError
|
|
15
15
|
from ..inspect import Kwarg
|
|
16
16
|
from ..inspect import KwargsTarget
|
|
17
17
|
from ..keys import Key
|
|
@@ -83,7 +83,7 @@ def build_kwargs_target(
|
|
|
83
83
|
k = tag(k, pt)
|
|
84
84
|
|
|
85
85
|
if k in seen:
|
|
86
|
-
raise
|
|
86
|
+
raise DuplicateKeyError(k)
|
|
87
87
|
seen.add(k)
|
|
88
88
|
|
|
89
89
|
kws.append(Kwarg(
|
omlish/inject/impl/scopes.py
CHANGED
|
@@ -9,8 +9,8 @@ from ... import lang
|
|
|
9
9
|
from ..bindings import Binding
|
|
10
10
|
from ..elements import Elements
|
|
11
11
|
from ..elements import as_elements
|
|
12
|
-
from ..exceptions import
|
|
13
|
-
from ..exceptions import
|
|
12
|
+
from ..exceptions import ScopeAlreadyOpenError
|
|
13
|
+
from ..exceptions import ScopeNotOpenError
|
|
14
14
|
from ..injector import Injector
|
|
15
15
|
from ..keys import Key
|
|
16
16
|
from ..providers import Provider
|
|
@@ -134,27 +134,28 @@ class SeededScopeImpl(ScopeImpl):
|
|
|
134
134
|
|
|
135
135
|
def must_state(self) -> 'SeededScopeImpl.State':
|
|
136
136
|
if (st := self._st) is None:
|
|
137
|
-
raise
|
|
137
|
+
raise ScopeNotOpenError(self._ss)
|
|
138
138
|
return st
|
|
139
139
|
|
|
140
140
|
class Manager(SeededScope.Manager, lang.Final):
|
|
141
141
|
def __init__(self, ss: SeededScope, i: Injector) -> None:
|
|
142
142
|
super().__init__()
|
|
143
143
|
self._ss = check.isinstance(ss, SeededScope)
|
|
144
|
-
|
|
145
|
-
self._ssi = check.isinstance(
|
|
144
|
+
self._ii = check.isinstance(i, injector_.InjectorImpl)
|
|
145
|
+
self._ssi = check.isinstance(self._ii.get_scope_impl(self._ss), SeededScopeImpl)
|
|
146
146
|
|
|
147
147
|
@contextlib.contextmanager
|
|
148
148
|
def __call__(self, seeds: ta.Mapping[Key, ta.Any]) -> ta.Generator[None, None, None]:
|
|
149
149
|
try:
|
|
150
|
-
if self._ssi._st is not None:
|
|
151
|
-
raise
|
|
152
|
-
self._ssi._st = SeededScopeImpl.State(dict(seeds))
|
|
150
|
+
if self._ssi._st is not None: # noqa
|
|
151
|
+
raise ScopeAlreadyOpenError(self._ss)
|
|
152
|
+
self._ssi._st = SeededScopeImpl.State(dict(seeds)) # noqa
|
|
153
|
+
self._ii._instantiate_eagers(self._ss) # noqa
|
|
153
154
|
yield
|
|
154
155
|
finally:
|
|
155
|
-
if self._ssi._st is None:
|
|
156
|
-
raise
|
|
157
|
-
self._ssi._st = None
|
|
156
|
+
if self._ssi._st is None: # noqa
|
|
157
|
+
raise ScopeNotOpenError(self._ss)
|
|
158
|
+
self._ssi._st = None # noqa
|
|
158
159
|
|
|
159
160
|
def auto_elements(self) -> Elements:
|
|
160
161
|
return as_elements(
|
omlish/inject/proxy.py
CHANGED
|
@@ -22,7 +22,7 @@ def _cyclic_dependency_proxy() -> tuple[type, ta.Callable[[ta.Any, ta.Any], None
|
|
|
22
22
|
def __init__(self, cls):
|
|
23
23
|
super().__init__(_CyclicDependencyPlaceholder(cls))
|
|
24
24
|
if isinstance(cls, type):
|
|
25
|
-
self._self__class__ = cls
|
|
25
|
+
self._self__class__ = cls # noqa
|
|
26
26
|
|
|
27
27
|
def __repr__(self) -> str:
|
|
28
28
|
return f'_CyclicDependencyProxy({self.__wrapped__!r})'
|
|
@@ -35,14 +35,14 @@ def _cyclic_dependency_proxy() -> tuple[type, ta.Callable[[ta.Any, ta.Any], None
|
|
|
35
35
|
pass
|
|
36
36
|
return object.__getattribute__(self, att) # noqa
|
|
37
37
|
|
|
38
|
-
def
|
|
38
|
+
def set_obj(prox, obj):
|
|
39
39
|
check.state(type(prox) is _CyclicDependencyProxy)
|
|
40
40
|
check.not_isinstance(obj, _CyclicDependencyPlaceholder)
|
|
41
41
|
check.isinstance(prox.__wrapped__, _CyclicDependencyPlaceholder)
|
|
42
42
|
if hasattr(prox, '_self__class__'):
|
|
43
|
-
check.issubclass(type(obj), prox._self__class__)
|
|
43
|
+
check.issubclass(type(obj), prox._self__class__) # noqa
|
|
44
44
|
prox.__wrapped__ = obj
|
|
45
45
|
if hasattr(prox, '_self__class__'):
|
|
46
|
-
del prox._self__class__
|
|
46
|
+
del prox._self__class__ # noqa
|
|
47
47
|
|
|
48
|
-
return (_CyclicDependencyProxy,
|
|
48
|
+
return (_CyclicDependencyProxy, set_obj) # noqa
|
omlish/iterators.py
CHANGED
|
@@ -22,66 +22,61 @@ class PeekIterator(ta.Iterator[T]):
|
|
|
22
22
|
|
|
23
23
|
_item: T
|
|
24
24
|
|
|
25
|
-
def __iter__(self) -> ta.
|
|
25
|
+
def __iter__(self) -> ta.Self:
|
|
26
26
|
return self
|
|
27
27
|
|
|
28
28
|
@property
|
|
29
29
|
def done(self) -> bool:
|
|
30
30
|
try:
|
|
31
31
|
self.peek()
|
|
32
|
-
return False
|
|
33
32
|
except StopIteration:
|
|
34
33
|
return True
|
|
34
|
+
else:
|
|
35
|
+
return False
|
|
35
36
|
|
|
36
37
|
def __next__(self) -> T:
|
|
37
38
|
if self._next_item is not _MISSING:
|
|
38
39
|
self._item = ta.cast(T, self._next_item)
|
|
39
40
|
self._next_item = _MISSING
|
|
40
41
|
else:
|
|
41
|
-
|
|
42
|
-
self._item = next(self._it)
|
|
43
|
-
except StopIteration:
|
|
44
|
-
raise
|
|
42
|
+
self._item = next(self._it)
|
|
45
43
|
self._pos += 1
|
|
46
44
|
return self._item
|
|
47
45
|
|
|
48
46
|
def peek(self) -> T:
|
|
49
47
|
if self._next_item is not _MISSING:
|
|
50
48
|
return ta.cast(T, self._next_item)
|
|
51
|
-
|
|
52
|
-
self._next_item = next(self._it)
|
|
53
|
-
except StopIteration:
|
|
54
|
-
raise
|
|
49
|
+
self._next_item = next(self._it)
|
|
55
50
|
return self._next_item
|
|
56
51
|
|
|
57
52
|
def next_peek(self) -> T:
|
|
58
53
|
next(self)
|
|
59
54
|
return self.peek()
|
|
60
55
|
|
|
61
|
-
def takewhile(self, fn):
|
|
56
|
+
def takewhile(self, fn: ta.Callable[[T], bool]) -> ta.Iterator[T]:
|
|
62
57
|
while fn(self.peek()):
|
|
63
58
|
yield next(self)
|
|
64
59
|
|
|
65
|
-
def skipwhile(self, fn):
|
|
60
|
+
def skipwhile(self, fn: ta.Callable[[T], bool]) -> None:
|
|
66
61
|
while fn(self.peek()):
|
|
67
62
|
next(self)
|
|
68
63
|
|
|
69
|
-
def takeuntil(self, fn):
|
|
64
|
+
def takeuntil(self, fn: ta.Callable[[T], bool]) -> ta.Iterator[T]:
|
|
70
65
|
return self.takewhile(lambda e: not fn(e))
|
|
71
66
|
|
|
72
|
-
def skipuntil(self, fn):
|
|
67
|
+
def skipuntil(self, fn: ta.Callable[[T], bool]) -> None:
|
|
73
68
|
self.skipwhile(lambda e: not fn(e))
|
|
74
69
|
|
|
75
|
-
def takethrough(self, pos):
|
|
70
|
+
def takethrough(self, pos: int) -> ta.Iterator[T]:
|
|
76
71
|
return self.takewhile(lambda _: self._pos < pos)
|
|
77
72
|
|
|
78
|
-
def skipthrough(self, pos):
|
|
73
|
+
def skipthrough(self, pos: int) -> None:
|
|
79
74
|
self.skipwhile(lambda _: self._pos < pos)
|
|
80
75
|
|
|
81
|
-
def taketo(self, pos):
|
|
76
|
+
def taketo(self, pos: int) -> ta.Iterator[T]:
|
|
82
77
|
return self.takethrough(pos - 1)
|
|
83
78
|
|
|
84
|
-
def skipto(self, pos):
|
|
79
|
+
def skipto(self, pos: int) -> None:
|
|
85
80
|
self.skipthrough(pos - 1)
|
|
86
81
|
|
|
87
82
|
|
|
@@ -90,7 +85,7 @@ class ProxyIterator(ta.Iterator[T]):
|
|
|
90
85
|
def __init__(self, fn: ta.Callable[[], T]) -> None:
|
|
91
86
|
self._fn = fn
|
|
92
87
|
|
|
93
|
-
def __iter__(self) -> ta.
|
|
88
|
+
def __iter__(self) -> ta.Self:
|
|
94
89
|
return self
|
|
95
90
|
|
|
96
91
|
def __next__(self) -> T:
|
|
@@ -103,9 +98,9 @@ class PrefetchIterator(ta.Iterator[T]):
|
|
|
103
98
|
super().__init__()
|
|
104
99
|
|
|
105
100
|
self._fn = fn
|
|
106
|
-
self._deque:
|
|
101
|
+
self._deque: collections.deque[T] = collections.deque()
|
|
107
102
|
|
|
108
|
-
def __iter__(self) -> ta.
|
|
103
|
+
def __iter__(self) -> ta.Self:
|
|
109
104
|
return self
|
|
110
105
|
|
|
111
106
|
def push(self, item) -> None:
|
|
@@ -116,7 +111,7 @@ class PrefetchIterator(ta.Iterator[T]):
|
|
|
116
111
|
return self._deque.popleft()
|
|
117
112
|
except IndexError:
|
|
118
113
|
if self._fn is None:
|
|
119
|
-
raise StopIteration
|
|
114
|
+
raise StopIteration from None
|
|
120
115
|
return self._fn()
|
|
121
116
|
|
|
122
117
|
|
|
@@ -126,9 +121,9 @@ class RetainIterator(ta.Iterator[T]):
|
|
|
126
121
|
super().__init__()
|
|
127
122
|
|
|
128
123
|
self._fn = fn
|
|
129
|
-
self._deque:
|
|
124
|
+
self._deque: collections.deque[T] = collections.deque()
|
|
130
125
|
|
|
131
|
-
def __iter__(self) -> ta.
|
|
126
|
+
def __iter__(self) -> ta.Self:
|
|
132
127
|
return self
|
|
133
128
|
|
|
134
129
|
def pop(self) -> None:
|
omlish/json.py
CHANGED
|
@@ -1,5 +1,141 @@
|
|
|
1
|
+
"""
|
|
2
|
+
json
|
|
3
|
+
dump
|
|
4
|
+
skipkeys=False
|
|
5
|
+
ensure_ascii=True
|
|
6
|
+
check_circular=True
|
|
7
|
+
allow_nan=True
|
|
8
|
+
cls=None
|
|
9
|
+
indent=None
|
|
10
|
+
separators=None
|
|
11
|
+
default=None
|
|
12
|
+
sort_keys=False
|
|
13
|
+
dumps
|
|
14
|
+
^
|
|
15
|
+
load
|
|
16
|
+
cls=None
|
|
17
|
+
object_hook=None
|
|
18
|
+
parse_float=None
|
|
19
|
+
parse_int=None
|
|
20
|
+
parse_constant=None
|
|
21
|
+
object_pairs_hook=None
|
|
22
|
+
loads
|
|
23
|
+
^
|
|
24
|
+
|
|
25
|
+
ujson
|
|
26
|
+
dump
|
|
27
|
+
ensure_ascii
|
|
28
|
+
encode_html_chars
|
|
29
|
+
escape_forward_slashes
|
|
30
|
+
sort_keys
|
|
31
|
+
indent
|
|
32
|
+
allow_nan
|
|
33
|
+
reject_bytes
|
|
34
|
+
default
|
|
35
|
+
separators
|
|
36
|
+
dumps
|
|
37
|
+
^
|
|
38
|
+
load
|
|
39
|
+
loads
|
|
40
|
+
|
|
41
|
+
orjson
|
|
42
|
+
dumps
|
|
43
|
+
default
|
|
44
|
+
option
|
|
45
|
+
OPT_INDENT_2
|
|
46
|
+
OPT_NAIVE_UTC
|
|
47
|
+
OPT_NON_STR_KEYS
|
|
48
|
+
OPT_OMIT_MICROSECONDS
|
|
49
|
+
OPT_PASSTHROUGH_DATACLASS
|
|
50
|
+
OPT_PASSTHROUGH_DATETIME
|
|
51
|
+
OPT_PASSTHROUGH_SUBCLASS
|
|
52
|
+
OPT_SERIALIZE_DATACLASS
|
|
53
|
+
OPT_SERIALIZE_NUMPY
|
|
54
|
+
OPT_SERIALIZE_UUID
|
|
55
|
+
OPT_SORT_KEYS
|
|
56
|
+
OPT_STRICT_INTEGER
|
|
57
|
+
OPT_UTC_Z
|
|
58
|
+
loads
|
|
59
|
+
|
|
60
|
+
rapidjson
|
|
61
|
+
dump
|
|
62
|
+
skipkeys=False,
|
|
63
|
+
ensure_ascii=True,
|
|
64
|
+
write_mode=WM_COMPACT,
|
|
65
|
+
WM_COMPACT
|
|
66
|
+
WM_PRETTY
|
|
67
|
+
WM_SINGLE_LINE_ARRAY
|
|
68
|
+
indent=4,
|
|
69
|
+
default=None,
|
|
70
|
+
sort_keys=False,
|
|
71
|
+
number_mode=None,
|
|
72
|
+
NM_NONE
|
|
73
|
+
NM_DECIMAL
|
|
74
|
+
NM_NAN
|
|
75
|
+
NM_NATIVE
|
|
76
|
+
datetime_mode=None,
|
|
77
|
+
DM_NONE
|
|
78
|
+
DM_ISO8601
|
|
79
|
+
DM_UNIX_TIME
|
|
80
|
+
DM_ONLY_SECONDS
|
|
81
|
+
DM_IGNORE_TZ
|
|
82
|
+
DM_NAIVE_IS_UTC
|
|
83
|
+
DM_SHIFT_TO_UTC
|
|
84
|
+
uuid_mode=None,
|
|
85
|
+
UM_NONE
|
|
86
|
+
UM_CANONICAL
|
|
87
|
+
UM_HEX
|
|
88
|
+
bytes_mode=BM_UTF8,
|
|
89
|
+
BM_NONE
|
|
90
|
+
BM_UTF8
|
|
91
|
+
iterable_mode=IM_ANY_ITERABLE,
|
|
92
|
+
IM_ANY_ITERABLE
|
|
93
|
+
IM_ONLY_LISTS
|
|
94
|
+
mapping_mode=MM_ANY_MAPPING,
|
|
95
|
+
MM_ANY_MAPPING
|
|
96
|
+
MM_ONLY_DICTS
|
|
97
|
+
MM_COERCE_KEYS_TO_STRINGS
|
|
98
|
+
MM_SKIP_NON_STRING_KEYS
|
|
99
|
+
MM_SORT_KEYS
|
|
100
|
+
chunk_size
|
|
101
|
+
allow_nan=True
|
|
102
|
+
dumps
|
|
103
|
+
^
|
|
104
|
+
-chunk_size
|
|
105
|
+
load
|
|
106
|
+
object_hook=None,
|
|
107
|
+
number_mode=None,
|
|
108
|
+
^
|
|
109
|
+
datetime_mode=None,
|
|
110
|
+
^
|
|
111
|
+
uuid_mode=None,
|
|
112
|
+
^
|
|
113
|
+
parse_mode=None,
|
|
114
|
+
PM_NONE
|
|
115
|
+
PM_COMMENTS
|
|
116
|
+
PM_TRAILING_COMMAS
|
|
117
|
+
chunk_size=65536,
|
|
118
|
+
allow_nan=True
|
|
119
|
+
loads
|
|
120
|
+
^
|
|
121
|
+
-chunk_size
|
|
122
|
+
|
|
123
|
+
"""
|
|
1
124
|
import functools
|
|
2
125
|
import json as _json
|
|
126
|
+
import typing as ta
|
|
127
|
+
|
|
128
|
+
from . import lang
|
|
129
|
+
|
|
130
|
+
if ta.TYPE_CHECKING:
|
|
131
|
+
import orjson as _orjson
|
|
132
|
+
import ujson as _ujson
|
|
133
|
+
else:
|
|
134
|
+
_orjson = lang.proxy_import('orjson')
|
|
135
|
+
_ujson = lang.proxy_import('ujson')
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
##
|
|
3
139
|
|
|
4
140
|
|
|
5
141
|
dump = _json.dump
|
|
@@ -10,30 +146,31 @@ detect_encoding = _json.detect_encoding
|
|
|
10
146
|
load = _json.load
|
|
11
147
|
loads = _json.loads
|
|
12
148
|
|
|
149
|
+
|
|
13
150
|
##
|
|
14
151
|
|
|
15
152
|
|
|
16
153
|
PRETTY_INDENT = 2
|
|
17
154
|
|
|
18
|
-
PRETTY_KWARGS = dict(
|
|
155
|
+
PRETTY_KWARGS: ta.Mapping[str, ta.Any] = dict(
|
|
19
156
|
indent=PRETTY_INDENT,
|
|
20
157
|
)
|
|
21
158
|
|
|
22
|
-
dump_pretty = functools.partial(dump, **PRETTY_KWARGS)
|
|
23
|
-
dumps_pretty = functools.partial(dumps, **PRETTY_KWARGS)
|
|
159
|
+
dump_pretty: ta.Callable[..., bytes] = functools.partial(dump, **PRETTY_KWARGS) # type: ignore
|
|
160
|
+
dumps_pretty: ta.Callable[..., str] = functools.partial(dumps, **PRETTY_KWARGS)
|
|
24
161
|
|
|
25
162
|
##
|
|
26
163
|
|
|
27
164
|
|
|
28
165
|
COMPACT_SEPARATORS = (',', ':')
|
|
29
166
|
|
|
30
|
-
COMPACT_KWARGS = dict(
|
|
167
|
+
COMPACT_KWARGS: ta.Mapping[str, ta.Any] = dict(
|
|
31
168
|
indent=0,
|
|
32
169
|
separators=COMPACT_SEPARATORS,
|
|
33
170
|
)
|
|
34
171
|
|
|
35
|
-
dump_compact = functools.partial(dump, **COMPACT_KWARGS)
|
|
36
|
-
dumps_compact = functools.partial(dumps, **COMPACT_KWARGS)
|
|
172
|
+
dump_compact: ta.Callable[..., bytes] = functools.partial(dump, **COMPACT_KWARGS) # type: ignore
|
|
173
|
+
dumps_compact: ta.Callable[..., str] = functools.partial(dumps, **COMPACT_KWARGS)
|
|
37
174
|
|
|
38
175
|
|
|
39
176
|
##
|
omlish/lang/__init__.py
CHANGED
|
@@ -8,7 +8,7 @@ from .classes import ( # noqa
|
|
|
8
8
|
Callable,
|
|
9
9
|
Descriptor,
|
|
10
10
|
Final,
|
|
11
|
-
|
|
11
|
+
FinalError,
|
|
12
12
|
LazySingleton,
|
|
13
13
|
Marker,
|
|
14
14
|
Namespace,
|
|
@@ -18,7 +18,7 @@ from .classes import ( # noqa
|
|
|
18
18
|
PackageSealed,
|
|
19
19
|
Picklable,
|
|
20
20
|
Sealed,
|
|
21
|
-
|
|
21
|
+
SealedError,
|
|
22
22
|
SimpleMetaDict,
|
|
23
23
|
Singleton,
|
|
24
24
|
Virtual,
|
|
@@ -74,10 +74,12 @@ from .datetimes import ( # noqa
|
|
|
74
74
|
)
|
|
75
75
|
|
|
76
76
|
from .descriptors import ( # noqa
|
|
77
|
-
|
|
77
|
+
AccessForbiddenError,
|
|
78
78
|
access_forbidden,
|
|
79
|
+
attr_property,
|
|
79
80
|
classonly,
|
|
80
81
|
is_method_descriptor,
|
|
82
|
+
item_property,
|
|
81
83
|
unwrap_method_descriptors,
|
|
82
84
|
)
|
|
83
85
|
|
|
@@ -87,8 +89,9 @@ from .exceptions import ( # noqa
|
|
|
87
89
|
|
|
88
90
|
from .functions import ( # noqa
|
|
89
91
|
Args,
|
|
90
|
-
|
|
92
|
+
VoidError,
|
|
91
93
|
constant,
|
|
94
|
+
finally_,
|
|
92
95
|
identity,
|
|
93
96
|
is_lambda,
|
|
94
97
|
is_none,
|
|
@@ -96,6 +99,7 @@ from .functions import ( # noqa
|
|
|
96
99
|
maybe_call,
|
|
97
100
|
periodically,
|
|
98
101
|
raise_,
|
|
102
|
+
raising,
|
|
99
103
|
recurse,
|
|
100
104
|
try_,
|
|
101
105
|
unwrap_func,
|
|
@@ -136,6 +140,7 @@ from .objects import ( # noqa
|
|
|
136
140
|
arg_repr,
|
|
137
141
|
attr_repr,
|
|
138
142
|
new_type,
|
|
143
|
+
opt_repr,
|
|
139
144
|
super_meta,
|
|
140
145
|
)
|
|
141
146
|
|
|
@@ -151,6 +156,10 @@ from .strings import ( # noqa
|
|
|
151
156
|
snake_case,
|
|
152
157
|
)
|
|
153
158
|
|
|
159
|
+
from .sys import ( # noqa
|
|
160
|
+
is_gil_enabled,
|
|
161
|
+
)
|
|
162
|
+
|
|
154
163
|
from .timeouts import ( # noqa
|
|
155
164
|
DeadlineTimeout,
|
|
156
165
|
InfiniteTimeout,
|