omlish 0.0.0.dev339__py3-none-any.whl → 0.0.0.dev340__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.
Files changed (35) hide show
  1. omlish/__about__.py +2 -2
  2. omlish/asyncs/bluelet/LICENSE +1 -1
  3. omlish/asyncs/bluelet/api.py +1 -1
  4. omlish/asyncs/bluelet/core.py +1 -1
  5. omlish/asyncs/bluelet/events.py +1 -1
  6. omlish/asyncs/bluelet/files.py +1 -1
  7. omlish/asyncs/bluelet/runner.py +1 -1
  8. omlish/asyncs/bluelet/sockets.py +1 -1
  9. omlish/collections/__init__.py +19 -0
  10. omlish/collections/multimaps.py +151 -0
  11. omlish/formats/json/__init__.py +13 -13
  12. omlish/formats/json/backends/__init__.py +2 -2
  13. omlish/formats/json/backends/default.py +56 -12
  14. omlish/formats/json/backends/orjson.py +6 -5
  15. omlish/formats/json/backends/std.py +4 -1
  16. omlish/formats/json/backends/ujson.py +6 -5
  17. omlish/formats/json/codecs.py +4 -4
  18. omlish/graphs/dags.py +112 -48
  19. omlish/graphs/domination.py +5 -1
  20. omlish/graphs/dot/items.py +3 -0
  21. omlish/graphs/dot/make.py +3 -0
  22. omlish/graphs/dot/rendering.py +3 -0
  23. omlish/graphs/dot/utils.py +3 -0
  24. omlish/graphs/trees.py +5 -4
  25. omlish/lang/classes/bindable.py +2 -0
  26. omlish/math/__init__.py +15 -15
  27. omlish/math/fixed.py +25 -15
  28. omlish/os/forkhooks.py +4 -4
  29. {omlish-0.0.0.dev339.dist-info → omlish-0.0.0.dev340.dist-info}/METADATA +1 -1
  30. {omlish-0.0.0.dev339.dist-info → omlish-0.0.0.dev340.dist-info}/RECORD +34 -34
  31. omlish/formats/json/json.py +0 -17
  32. {omlish-0.0.0.dev339.dist-info → omlish-0.0.0.dev340.dist-info}/WHEEL +0 -0
  33. {omlish-0.0.0.dev339.dist-info → omlish-0.0.0.dev340.dist-info}/entry_points.txt +0 -0
  34. {omlish-0.0.0.dev339.dist-info → omlish-0.0.0.dev340.dist-info}/licenses/LICENSE +0 -0
  35. {omlish-0.0.0.dev339.dist-info → omlish-0.0.0.dev340.dist-info}/top_level.txt +0 -0
omlish/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev339'
2
- __revision__ = '0d8d4714d9a9ea7145586e0bce55833b86e980bd'
1
+ __version__ = '0.0.0.dev340'
2
+ __revision__ = 'de9a88b0e8d5578e5348e4f23db01e09dd3ebbd0'
3
3
 
4
4
 
5
5
  #
@@ -1,6 +1,6 @@
1
1
  Based on bluelet ( https://github.com/sampsyo/bluelet ) by Adrian Sampson, original license:
2
2
 
3
- THE SOFTWARE IS PROVIDED AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
3
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
4
4
  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
5
5
  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
6
6
  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,7 +1,7 @@
1
1
  # ruff: noqa: UP006 UP007
2
2
  # @omlish-lite
3
3
  # Based on bluelet ( https://github.com/sampsyo/bluelet ) by Adrian Sampson, original license:
4
- # THE SOFTWARE IS PROVIDED AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
4
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
5
5
  # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
6
6
  # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
7
7
  # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,7 +1,7 @@
1
1
  # ruff: noqa: UP006 UP007
2
2
  # @omlish-lite
3
3
  # Based on bluelet ( https://github.com/sampsyo/bluelet ) by Adrian Sampson, original license:
4
- # THE SOFTWARE IS PROVIDED AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
4
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
5
5
  # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
6
6
  # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
7
7
  # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,7 +1,7 @@
1
1
  # ruff: noqa: UP007
2
2
  # @omlish-lite
3
3
  # Based on bluelet ( https://github.com/sampsyo/bluelet ) by Adrian Sampson, original license:
4
- # THE SOFTWARE IS PROVIDED AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
4
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
5
5
  # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
6
6
  # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
7
7
  # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,7 +1,7 @@
1
1
  # ruff: noqa: UP006 UP007
2
2
  # @omlish-lite
3
3
  # Based on bluelet ( https://github.com/sampsyo/bluelet ) by Adrian Sampson, original license:
4
- # THE SOFTWARE IS PROVIDED AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
4
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
5
5
  # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
6
6
  # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
7
7
  # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,7 +1,7 @@
1
1
  # ruff: noqa: UP006 UP007
2
2
  # @omlish-lite
3
3
  # Based on bluelet ( https://github.com/sampsyo/bluelet ) by Adrian Sampson, original license:
4
- # THE SOFTWARE IS PROVIDED AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
4
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
5
5
  # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
6
6
  # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
7
7
  # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,7 +1,7 @@
1
1
  # ruff: noqa: UP006 UP007
2
2
  # @omlish-lite
3
3
  # Based on bluelet ( https://github.com/sampsyo/bluelet ) by Adrian Sampson, original license:
4
- # THE SOFTWARE IS PROVIDED AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
4
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
5
5
  # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
6
6
  # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
7
7
  # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -76,6 +76,25 @@ from .mappings import ( # noqa
76
76
  multikey_dict,
77
77
  )
78
78
 
79
+ from .multimaps import ( # noqa
80
+ MultiMap,
81
+
82
+ SequenceMultiMap,
83
+ AbstractSetMultiMap,
84
+
85
+ BiMultiMap,
86
+ InverseBiMultiMap,
87
+
88
+ SequenceBiMultiMap,
89
+ AbstractSetBiMultiMap,
90
+
91
+ TupleBiMultiMap,
92
+ seq_bi_multi_map,
93
+
94
+ FrozensetBiMultiMap,
95
+ abs_set_bi_multi_map,
96
+ )
97
+
79
98
  from .ordered import ( # noqa
80
99
  OrderedFrozenSet,
81
100
  OrderedSet,
@@ -0,0 +1,151 @@
1
+ import abc
2
+ import typing as ta
3
+
4
+ from .. import lang
5
+
6
+
7
+ K = ta.TypeVar('K')
8
+ V = ta.TypeVar('V')
9
+ MV = ta.TypeVar('MV', bound=ta.Iterable)
10
+
11
+
12
+ ##
13
+
14
+
15
+ class MultiMap(ta.Mapping[K, MV], abc.ABC, ta.Generic[K, V, MV]):
16
+ pass
17
+
18
+
19
+ SequenceMultiMap: ta.TypeAlias = MultiMap[K, V, ta.Sequence[V]]
20
+ AbstractSetMultiMap: ta.TypeAlias = MultiMap[K, V, ta.AbstractSet[V]]
21
+
22
+
23
+ ##
24
+
25
+
26
+ class BiMultiMap(MultiMap[K, V, MV], abc.ABC, ta.Generic[K, V, MV]):
27
+ @abc.abstractmethod
28
+ def inverse(self) -> 'InverseBiMultiMap[K, V, MV]':
29
+ raise NotImplementedError
30
+
31
+
32
+ class InverseBiMultiMap(ta.Mapping[V, K], abc.ABC, ta.Generic[K, V, MV]):
33
+ @abc.abstractmethod
34
+ def inverse(self) -> BiMultiMap[K, V, MV]:
35
+ raise NotImplementedError
36
+
37
+
38
+ SequenceBiMultiMap: ta.TypeAlias = BiMultiMap[K, V, ta.Sequence[V]]
39
+ AbstractSetBiMultiMap: ta.TypeAlias = BiMultiMap[K, V, ta.AbstractSet[V]]
40
+
41
+
42
+ ##
43
+
44
+
45
+ class InverseBiMultiMapImpl(InverseBiMultiMap[K, V, MV], ta.Generic[K, V, MV]):
46
+ def __init__(self, m: BiMultiMap[K, V, MV], dct: ta.Mapping[V, K]) -> None:
47
+ super().__init__()
48
+
49
+ self._m = m
50
+ self._dct = dct
51
+
52
+ def inverse(self) -> BiMultiMap[K, V, MV]:
53
+ return self._m
54
+
55
+ def __getitem__(self, key: V, /) -> K:
56
+ return self._dct[key]
57
+
58
+ def __len__(self) -> int:
59
+ return len(self._dct)
60
+
61
+ def __iter__(self) -> ta.Iterator[V]:
62
+ return iter(self._dct)
63
+
64
+
65
+ class BaseBiMultiMap(BiMultiMap[K, V, MV], abc.ABC, ta.Generic[K, V, MV]):
66
+ def __init__(self, *args: ta.Any, **kwargs: ta.Any) -> None:
67
+ super().__init__()
68
+
69
+ dct: dict[K, MV] = {}
70
+ i_dct: dict[V, K] = {}
71
+ for k, mv in lang.yield_dict_init(*args, **kwargs):
72
+ l: list[V] = []
73
+ for v in mv:
74
+ if v in i_dct:
75
+ raise KeyError(v)
76
+ l.append(v)
77
+ i_dct[v] = k
78
+ dct[k] = self._aggregate_values(l)
79
+
80
+ self._dct = dct
81
+ self._i: InverseBiMultiMap[K, V, MV] = InverseBiMultiMapImpl(self, i_dct)
82
+
83
+ @abc.abstractmethod
84
+ def _aggregate_values(self, vs: list[V]) -> MV:
85
+ raise NotImplementedError
86
+
87
+ def inverse(self) -> 'InverseBiMultiMap[K, V, MV]':
88
+ return self._i
89
+
90
+ def __getitem__(self, key: K, /) -> MV:
91
+ return self._dct[key]
92
+
93
+ def __len__(self) -> int:
94
+ return len(self._dct)
95
+
96
+ def __iter__(self) -> ta.Iterator[K]:
97
+ return iter(self._dct)
98
+
99
+
100
+ #
101
+
102
+
103
+ class TupleBiMultiMap(BaseBiMultiMap[K, V, tuple[V, ...]], ta.Generic[K, V]):
104
+ def _aggregate_values(self, vs: list[V]) -> tuple[V, ...]:
105
+ return tuple(vs)
106
+
107
+
108
+ # FIXME: lame
109
+ # lang.static_check_issubclass[BiMultiMap[int, str, tuple[str, ...]]](TupleBiMultiMap[int, str])
110
+ # lang.static_check_issubclass[BiMultiMap[int, str, ta.Sequence[str]]](TupleBiMultiMap[int, str])
111
+ # lang.static_check_issubclass[SequenceBiMultiMap[int, str]](TupleBiMultiMap[int, str])
112
+
113
+
114
+ @ta.overload
115
+ def seq_bi_multi_map(dct: ta.Mapping[K, ta.Iterable[V]]) -> SequenceBiMultiMap[K, V]:
116
+ ...
117
+
118
+
119
+ @ta.overload
120
+ def seq_bi_multi_map(items: ta.Iterable[tuple[K, ta.Iterable[V]]]) -> SequenceBiMultiMap[K, V]:
121
+ ...
122
+
123
+
124
+ def seq_bi_multi_map(*args, **kwargs):
125
+ return TupleBiMultiMap(*args, **kwargs)
126
+
127
+
128
+ #
129
+
130
+
131
+ class FrozensetBiMultiMap(BaseBiMultiMap[K, V, frozenset[V]], ta.Generic[K, V]):
132
+ def _aggregate_values(self, vs: list[V]) -> frozenset[V]:
133
+ return frozenset(vs)
134
+
135
+
136
+ # FIXME: lame
137
+ # lang.static_check_issubclass[AbstractSetBiMultiMap[int, str]](FrozensetBiMultiMap[int, str])
138
+
139
+
140
+ @ta.overload
141
+ def abs_set_bi_multi_map(dct: ta.Mapping[K, ta.Iterable[V]]) -> AbstractSetBiMultiMap[K, V]:
142
+ ...
143
+
144
+
145
+ @ta.overload
146
+ def abs_set_bi_multi_map(items: ta.Iterable[tuple[K, ta.Iterable[V]]]) -> AbstractSetBiMultiMap[K, V]:
147
+ ...
148
+
149
+
150
+ def abs_set_bi_multi_map(*args, **kwargs):
151
+ return FrozensetBiMultiMap(*args, **kwargs)
@@ -12,10 +12,21 @@ from ... import lang as _lang
12
12
  from .backends import ( # noqa
13
13
  Backend,
14
14
 
15
- DEFAULT_BACKED,
15
+ default_backend,
16
16
 
17
17
  StdBackend,
18
- STD_BACKEND,
18
+ std_backend,
19
+ )
20
+
21
+ from .backends.default import ( # noqa
22
+ dump,
23
+ dump_compact,
24
+ dump_pretty,
25
+ dumps,
26
+ dumps_compact,
27
+ dumps_pretty,
28
+ load,
29
+ loads,
19
30
  )
20
31
 
21
32
  from .consts import ( # noqa
@@ -32,17 +43,6 @@ from .encoding import ( # noqa
32
43
  detect_encoding,
33
44
  )
34
45
 
35
- from .json import ( # noqa
36
- dump,
37
- dump_compact,
38
- dump_pretty,
39
- dumps,
40
- dumps_compact,
41
- dumps_pretty,
42
- load,
43
- loads,
44
- )
45
-
46
46
  if _ta.TYPE_CHECKING:
47
47
  from .rendering import ( # noqa
48
48
  JsonRenderer,
@@ -3,10 +3,10 @@ from .base import ( # noqa
3
3
  )
4
4
 
5
5
  from .default import ( # noqa
6
- DEFAULT_BACKED,
6
+ default_backend,
7
7
  )
8
8
 
9
9
  from .std import ( # noqa
10
10
  StdBackend,
11
- STD_BACKEND,
11
+ std_backend,
12
12
  )
@@ -1,13 +1,57 @@
1
+ import typing as ta
2
+
3
+ from .... import lang
1
4
  from .base import Backend
2
- from .orjson import ORJSON_BACKEND
3
- from .std import STD_BACKEND
4
- from .ujson import UJSON_BACKEND
5
-
6
-
7
- DEFAULT_BACKED: Backend
8
- if ORJSON_BACKEND is not None:
9
- DEFAULT_BACKED = ORJSON_BACKEND
10
- elif UJSON_BACKEND is not None:
11
- DEFAULT_BACKED = UJSON_BACKEND
12
- else:
13
- DEFAULT_BACKED = STD_BACKEND
5
+ from .orjson import orjson_backend
6
+ from .std import std_backend
7
+ from .ujson import ujson_backend
8
+
9
+
10
+ ##
11
+
12
+
13
+ @lang.cached_function
14
+ def default_backend() -> Backend:
15
+ for fn in [
16
+ orjson_backend,
17
+ ujson_backend,
18
+ ]:
19
+ if (be := fn()) is not None:
20
+ return be
21
+
22
+ return std_backend()
23
+
24
+
25
+ ##
26
+
27
+
28
+ def dump(obj: ta.Any, fp: ta.Any, **kwargs: ta.Any) -> None:
29
+ return default_backend().dump(obj, fp, **kwargs)
30
+
31
+
32
+ def dumps(obj: ta.Any, **kwargs: ta.Any) -> str:
33
+ return default_backend().dumps(obj, **kwargs)
34
+
35
+
36
+ def load(fp: ta.Any, **kwargs: ta.Any) -> ta.Any:
37
+ return default_backend().load(fp, **kwargs)
38
+
39
+
40
+ def loads(s: str | bytes | bytearray, **kwargs: ta.Any) -> ta.Any:
41
+ return default_backend().loads(s, **kwargs)
42
+
43
+
44
+ def dump_pretty(obj: ta.Any, fp: ta.Any, **kwargs: ta.Any) -> None:
45
+ return default_backend().dump_pretty(obj, fp, **kwargs)
46
+
47
+
48
+ def dumps_pretty(obj: ta.Any, **kwargs: ta.Any) -> str:
49
+ return default_backend().dumps_pretty(obj, **kwargs)
50
+
51
+
52
+ def dump_compact(obj: ta.Any, fp: ta.Any, **kwargs: ta.Any) -> None:
53
+ return default_backend().dump_compact(obj, fp, **kwargs)
54
+
55
+
56
+ def dumps_compact(obj: ta.Any, **kwargs: ta.Any) -> str:
57
+ return default_backend().dumps_compact(obj, **kwargs)
@@ -109,8 +109,9 @@ class OrjsonBackend(Backend):
109
109
  return self.dumps(obj, **kwargs)
110
110
 
111
111
 
112
- ORJSON_BACKEND: OrjsonBackend | None
113
- if lang.can_import('orjson'):
114
- ORJSON_BACKEND = OrjsonBackend()
115
- else:
116
- ORJSON_BACKEND = None
112
+ @lang.cached_function
113
+ def orjson_backend() -> OrjsonBackend | None:
114
+ if lang.can_import('orjson'):
115
+ return OrjsonBackend()
116
+ else:
117
+ return None
@@ -8,6 +8,7 @@ import dataclasses as dc
8
8
  import json
9
9
  import typing as ta
10
10
 
11
+ from .... import lang
11
12
  from ..consts import COMPACT_KWARGS
12
13
  from ..consts import PRETTY_KWARGS
13
14
  from .base import Backend
@@ -73,4 +74,6 @@ class StdBackend(Backend):
73
74
  return json.dumps(obj, **COMPACT_KWARGS, **kwargs)
74
75
 
75
76
 
76
- STD_BACKEND = StdBackend()
77
+ @lang.cached_function
78
+ def std_backend() -> StdBackend:
79
+ return StdBackend()
@@ -67,8 +67,9 @@ class UjsonBackend(Backend):
67
67
  return uj.dumps(obj, **kwargs)
68
68
 
69
69
 
70
- UJSON_BACKEND: UjsonBackend | None
71
- if lang.can_import('ujson'):
72
- UJSON_BACKEND = UjsonBackend()
73
- else:
74
- UJSON_BACKEND = None
70
+ @lang.cached_function
71
+ def ujson_backend() -> UjsonBackend | None:
72
+ if lang.can_import('ujson'):
73
+ return UjsonBackend()
74
+ else:
75
+ return None
@@ -1,9 +1,9 @@
1
1
  from ..codecs import make_object_lazy_loaded_codec
2
2
  from ..codecs import make_str_object_codec
3
- from .json import dumps
4
- from .json import dumps_compact
5
- from .json import dumps_pretty
6
- from .json import loads
3
+ from .backends.default import dumps
4
+ from .backends.default import dumps_compact
5
+ from .backends.default import dumps_pretty
6
+ from .backends.default import loads
7
7
 
8
8
 
9
9
  ##
omlish/graphs/dags.py CHANGED
@@ -12,100 +12,164 @@ from .. import check
12
12
  from .. import lang
13
13
 
14
14
 
15
- K = ta.TypeVar('K')
16
- V = ta.TypeVar('V')
17
15
  T = ta.TypeVar('T')
18
- U = ta.TypeVar('U')
19
16
 
20
17
 
21
- def traverse_links(data: ta.Mapping[T, ta.Iterable[T]], keys: ta.Iterable[T]) -> set[T]:
22
- keys = set(keys)
23
- todo = set(keys)
18
+ ##
19
+
20
+
21
+ class LinkError(KeyError):
22
+ pass
23
+
24
+
25
+ def traverse_links(
26
+ links: ta.Mapping[T, ta.Iterable[T]],
27
+ roots: ta.Iterable[T],
28
+ *,
29
+ include_roots: bool = False,
30
+ strict: bool = False,
31
+ ) -> set[T]:
32
+ """Returns all keys deeply reachable from given roots. Handles cycles."""
33
+
34
+ roots = set(roots)
35
+
36
+ todo = set(roots)
24
37
  seen: set[T] = set()
25
38
  while todo:
26
39
  key = todo.pop()
27
40
  seen.add(key)
28
- cur = data.get(key, [])
29
- todo.update(set(cur) - seen)
30
- return seen - keys
31
-
32
41
 
33
- def invert_set_map(src: ta.Mapping[K, ta.Iterable[V]]) -> dict[V, set[K]]:
34
- dst: dict[V, set[K]] = {}
35
- for l, rs in src.items():
36
- for r in rs:
42
+ try:
43
+ cur = links[key]
44
+ except KeyError:
45
+ if strict:
46
+ raise LinkError(key) from None
47
+ else:
48
+ todo.update(set(cur) - seen)
49
+
50
+ if include_roots:
51
+ return seen
52
+ else:
53
+ return seen - roots
54
+
55
+
56
+ def invert_links(
57
+ links: ta.Mapping[T, ta.Iterable[T]],
58
+ *,
59
+ auto_add_roots: bool = False,
60
+ if_absent: ta.Literal['raise', 'ignore', 'add'] = 'add',
61
+ ) -> dict[T, set[T]]:
62
+ check.in_(if_absent, ('raise', 'ignore', 'add'))
63
+ if if_absent != 'add':
64
+ check.arg(auto_add_roots, 'auto_add_roots must be True with given if_absent is not "add"')
65
+
66
+ ret: dict[T, set[T]]
67
+ if auto_add_roots:
68
+ ret = {src: set() for src in links}
69
+ else:
70
+ ret = {}
71
+
72
+ for src, dsts in links.items():
73
+ for dst in dsts:
37
74
  try:
38
- s = dst[r]
75
+ tgt = ret[dst]
39
76
  except KeyError:
40
- s = dst[r] = set()
41
- s.add(l)
42
- return dst
77
+ if if_absent == 'raise':
78
+ raise LinkError(dst) from None
79
+ elif if_absent == 'ignore':
80
+ continue
81
+ elif if_absent == 'add':
82
+ tgt = ret[dst] = set()
83
+ else:
84
+ raise RuntimeError from None
85
+
86
+ tgt.add(src)
43
87
 
88
+ return ret
44
89
 
45
- def invert_symmetric_set_map(src: ta.Mapping[T, ta.Iterable[T]]) -> dict[T, set[T]]:
46
- dst: dict[T, set[T]] = {l: set() for l in src}
47
- for l, rs in src.items():
48
- for r in rs:
49
- dst[r].add(l)
50
- return dst
90
+
91
+ ##
51
92
 
52
93
 
53
94
  class Dag(ta.Generic[T]):
54
- def __init__(self, input_its_by_outputs: ta.Mapping[T, ta.Iterable[T]]) -> None:
95
+ """Given 'input_its_by_outputs', or a map from nodes to that node's dependencies."""
96
+
97
+ def __init__(
98
+ self,
99
+ input_its_by_outputs: ta.Mapping[T, ta.Iterable[T]],
100
+ *,
101
+ auto_add_outputs: bool = True,
102
+ if_absent: ta.Literal['raise', 'ignore', 'add'] = 'add',
103
+ ) -> None:
55
104
  super().__init__()
56
105
 
57
106
  self._input_sets_by_output = {u: set(d) for u, d in input_its_by_outputs.items()}
58
107
 
108
+ self._output_sets_by_input = invert_links(
109
+ self._input_sets_by_output,
110
+ auto_add_roots=auto_add_outputs,
111
+ if_absent=if_absent,
112
+ )
113
+
59
114
  @property
60
115
  def input_sets_by_output(self) -> ta.Mapping[T, ta.AbstractSet[T]]:
61
116
  return self._input_sets_by_output
62
117
 
63
- @lang.cached_property
118
+ @property
64
119
  def output_sets_by_input(self) -> ta.Mapping[T, ta.AbstractSet[T]]:
65
- return invert_symmetric_set_map(self._input_sets_by_output)
120
+ return self._output_sets_by_input
66
121
 
67
- def subdag(self, *args, **kwargs) -> 'Subdag[T]':
68
- return Subdag(self, *args, **kwargs)
122
+ def subdag(
123
+ self,
124
+ roots: ta.Iterable[T],
125
+ *,
126
+ ignored: ta.Iterable[T] | None = None,
127
+ ) -> 'Subdag[T]':
128
+ return Subdag(
129
+ self,
130
+ roots,
131
+ ignored=ignored,
132
+ )
69
133
 
70
134
 
71
- class Subdag(ta.Generic[U]):
135
+ class Subdag(ta.Generic[T]):
72
136
  def __init__(
73
137
  self,
74
- dag: 'Dag[U]',
75
- targets: ta.Iterable[U],
138
+ dag: Dag[T],
139
+ roots: ta.Iterable[T],
76
140
  *,
77
- ignored: ta.Iterable[U] | None = None,
141
+ ignored: ta.Iterable[T] | None = None,
78
142
  ) -> None:
79
143
  super().__init__()
80
144
 
81
- self._dag: Dag[U] = check.isinstance(dag, Dag)
82
- self._targets = set(targets)
83
- self._ignored = set(ignored or []) - self._targets
145
+ self._dag: Dag[T] = check.isinstance(dag, Dag)
146
+ self._roots = set(roots)
147
+ self._ignored = set(ignored or []) - self._roots
84
148
 
85
149
  @property
86
- def dag(self) -> 'Dag[U]':
150
+ def dag(self) -> Dag[T]:
87
151
  return self._dag
88
152
 
89
153
  @property
90
- def targets(self) -> ta.AbstractSet[U]:
91
- return self._targets
154
+ def roots(self) -> ta.AbstractSet[T]:
155
+ return self._roots
92
156
 
93
157
  @property
94
- def ignored(self) -> ta.AbstractSet[U]:
158
+ def ignored(self) -> ta.AbstractSet[T]:
95
159
  return self._ignored
96
160
 
97
161
  @lang.cached_property
98
- def inputs(self) -> ta.AbstractSet[U]:
99
- return traverse_links(self.dag.input_sets_by_output, self.targets) - self.ignored
162
+ def inputs(self) -> ta.AbstractSet[T]:
163
+ return traverse_links(self._dag.input_sets_by_output, self._roots) - self._ignored
100
164
 
101
165
  @lang.cached_property
102
- def outputs(self) -> ta.AbstractSet[U]:
103
- return traverse_links(self.dag.output_sets_by_input, self.targets) - self.ignored
166
+ def outputs(self) -> ta.AbstractSet[T]:
167
+ return traverse_links(self._dag.output_sets_by_input, self._roots) - self._ignored
104
168
 
105
169
  @lang.cached_property
106
- def output_inputs(self) -> ta.AbstractSet[U]:
107
- return traverse_links(self.dag.input_sets_by_output, self.outputs) - self.ignored
170
+ def output_inputs(self) -> ta.AbstractSet[T]:
171
+ return traverse_links(self._dag.input_sets_by_output, self.outputs) - self._ignored
108
172
 
109
173
  @lang.cached_property
110
- def all(self) -> ta.AbstractSet[U]:
111
- return self.targets | self.inputs | self.outputs | self.output_inputs
174
+ def all(self) -> ta.AbstractSet[T]:
175
+ return self.roots | self.inputs | self.outputs | self.output_inputs
@@ -9,7 +9,11 @@ from .. import lang
9
9
  V = ta.TypeVar('V')
10
10
  MK = ta.TypeVar('MK')
11
11
  MV = ta.TypeVar('MV')
12
- SetMap = ta.Mapping[MK, ta.AbstractSet[MV]]
12
+
13
+ SetMap: ta.TypeAlias = ta.Mapping[MK, ta.AbstractSet[MV]]
14
+
15
+
16
+ ##
13
17
 
14
18
 
15
19
  class DirectedGraph(ta.Generic[V], lang.Abstract):
@@ -12,6 +12,9 @@ from ... import dataclasses as dc
12
12
  from ... import lang
13
13
 
14
14
 
15
+ ##
16
+
17
+
15
18
  class Item(dc.Frozen, lang.Abstract, lang.Sealed):
16
19
  pass
17
20
 
omlish/graphs/dot/make.py CHANGED
@@ -9,6 +9,9 @@ from .items import Node
9
9
  T = ta.TypeVar('T')
10
10
 
11
11
 
12
+ ##
13
+
14
+
12
15
  def make_simple(graph: ta.Mapping[T, ta.Iterable[T]]) -> Graph:
13
16
  return Graph([
14
17
  *[Node(n) for n in {*graph, *lang.flatten(graph.values())}],
@@ -20,6 +20,9 @@ from .items import Table
20
20
  from .items import Text
21
21
 
22
22
 
23
+ ##
24
+
25
+
23
26
  class Renderer:
24
27
  def __init__(self, out: ta.TextIO) -> None:
25
28
  super().__init__()
@@ -2,6 +2,9 @@ import html
2
2
  import typing as ta
3
3
 
4
4
 
5
+ ##
6
+
7
+
5
8
  def escape(s: str) -> str:
6
9
  return html.escape(s).replace('@', '@')
7
10
 
omlish/graphs/trees.py CHANGED
@@ -10,13 +10,14 @@ from .. import cached
10
10
  from .. import check
11
11
  from .. import collections as col
12
12
  from .. import lang
13
- from ..algorithm import all as alg
13
+ from ..algorithm.toposort import mut_toposort
14
14
 
15
15
 
16
16
  T = ta.TypeVar('T')
17
17
  NodeT = ta.TypeVar('NodeT')
18
- NodeWalker = ta.Callable[[NodeT], ta.Iterable[NodeT]]
19
- NodeGenerator = ta.Generator[NodeT, None, None]
18
+
19
+ NodeWalker: ta.TypeAlias = ta.Callable[[NodeT], ta.Iterable[NodeT]]
20
+ NodeGenerator: ta.TypeAlias = ta.Generator[NodeT, None, None]
20
21
 
21
22
 
22
23
  ##
@@ -200,7 +201,7 @@ class BasicTreeAnalysis(ta.Generic[NodeT]):
200
201
  else:
201
202
  e, d = lang.identity, lang.identity
202
203
  tsd = {e(n): {e(p)} for n, p in parents_by_node.items()}
203
- ts = list(alg.mut_toposort(tsd))
204
+ ts = list(mut_toposort(tsd))
204
205
  root = d(check.single(ts[0]))
205
206
 
206
207
  return cls(
@@ -27,6 +27,8 @@ class BindableClass(ta.Generic[T]):
27
27
  setattr(self, '_bound', _bound)
28
28
 
29
29
  def __class_getitem__(cls, *args, **kwargs):
30
+ # FIXME: this could handle __mro_items__ to be subclassable, but it's not currently really intended to be
31
+ # subclassed
30
32
  if cls is BindableClass:
31
33
  return super().__class_getitem__(*args, **kwargs) # type: ignore[misc]
32
34
 
omlish/math/__init__.py CHANGED
@@ -35,11 +35,11 @@ from .fixed import ( # noqa
35
35
  CheckedInt64,
36
36
  CheckedInt128,
37
37
 
38
- CheckedUInt8,
39
- CheckedUInt16,
40
- CheckedUInt32,
41
- CheckedUInt64,
42
- CheckedUInt128,
38
+ CheckedUint8,
39
+ CheckedUint16,
40
+ CheckedUint32,
41
+ CheckedUint64,
42
+ CheckedUint128,
43
43
 
44
44
  ClampedInt8,
45
45
  ClampedInt16,
@@ -47,11 +47,11 @@ from .fixed import ( # noqa
47
47
  ClampedInt64,
48
48
  ClampedInt128,
49
49
 
50
- ClampedUInt8,
51
- ClampedUInt16,
52
- ClampedUInt32,
53
- ClampedUInt64,
54
- ClampedUInt128,
50
+ ClampedUint8,
51
+ ClampedUint16,
52
+ ClampedUint32,
53
+ ClampedUint64,
54
+ ClampedUint128,
55
55
 
56
56
  WrappedInt8,
57
57
  WrappedInt16,
@@ -59,11 +59,11 @@ from .fixed import ( # noqa
59
59
  WrappedInt64,
60
60
  WrappedInt128,
61
61
 
62
- WrappedUInt8,
63
- WrappedUInt16,
64
- WrappedUInt32,
65
- WrappedUInt64,
66
- WrappedUInt128,
62
+ WrappedUint8,
63
+ WrappedUint16,
64
+ WrappedUint32,
65
+ WrappedUint64,
66
+ WrappedUint128,
67
67
  )
68
68
 
69
69
  from .floats import ( # noqa
omlish/math/fixed.py CHANGED
@@ -183,6 +183,16 @@ class FixedWidthInt(int, lang.Abstract):
183
183
  locals()[_proxy_name] = _gen_tuple_proxy_method(_proxy_name)
184
184
  del _proxy_name
185
185
 
186
+ #
187
+
188
+ def __invert__(self) -> ta.Self:
189
+ if not self.SIGNED:
190
+ return self.__class__(~int(self) & self.MASK)
191
+ else:
192
+ return self.__class__(super().__invert__())
193
+
194
+ #
195
+
186
196
  def __repr__(self) -> str:
187
197
  return f'{self.__class__.__name__}({int(self)})'
188
198
 
@@ -278,23 +288,23 @@ class CheckedInt128(CheckedInt, SignedInt, AnyInt128):
278
288
  #
279
289
 
280
290
 
281
- class CheckedUInt8(CheckedInt, UnsignedInt, AnyInt8):
291
+ class CheckedUint8(CheckedInt, UnsignedInt, AnyInt8):
282
292
  pass
283
293
 
284
294
 
285
- class CheckedUInt16(CheckedInt, UnsignedInt, AnyInt16):
295
+ class CheckedUint16(CheckedInt, UnsignedInt, AnyInt16):
286
296
  pass
287
297
 
288
298
 
289
- class CheckedUInt32(CheckedInt, UnsignedInt, AnyInt32):
299
+ class CheckedUint32(CheckedInt, UnsignedInt, AnyInt32):
290
300
  pass
291
301
 
292
302
 
293
- class CheckedUInt64(CheckedInt, UnsignedInt, AnyInt64):
303
+ class CheckedUint64(CheckedInt, UnsignedInt, AnyInt64):
294
304
  pass
295
305
 
296
306
 
297
- class CheckedUInt128(CheckedInt, UnsignedInt, AnyInt128):
307
+ class CheckedUint128(CheckedInt, UnsignedInt, AnyInt128):
298
308
  pass
299
309
 
300
310
 
@@ -324,23 +334,23 @@ class ClampedInt128(ClampedInt, SignedInt, AnyInt128):
324
334
  #
325
335
 
326
336
 
327
- class ClampedUInt8(ClampedInt, UnsignedInt, AnyInt8):
337
+ class ClampedUint8(ClampedInt, UnsignedInt, AnyInt8):
328
338
  pass
329
339
 
330
340
 
331
- class ClampedUInt16(ClampedInt, UnsignedInt, AnyInt16):
341
+ class ClampedUint16(ClampedInt, UnsignedInt, AnyInt16):
332
342
  pass
333
343
 
334
344
 
335
- class ClampedUInt32(ClampedInt, UnsignedInt, AnyInt32):
345
+ class ClampedUint32(ClampedInt, UnsignedInt, AnyInt32):
336
346
  pass
337
347
 
338
348
 
339
- class ClampedUInt64(ClampedInt, UnsignedInt, AnyInt64):
349
+ class ClampedUint64(ClampedInt, UnsignedInt, AnyInt64):
340
350
  pass
341
351
 
342
352
 
343
- class ClampedUInt128(ClampedInt, UnsignedInt, AnyInt128):
353
+ class ClampedUint128(ClampedInt, UnsignedInt, AnyInt128):
344
354
  pass
345
355
 
346
356
 
@@ -370,21 +380,21 @@ class WrappedInt128(WrappedInt, SignedInt, AnyInt128):
370
380
  #
371
381
 
372
382
 
373
- class WrappedUInt8(WrappedInt, UnsignedInt, AnyInt8):
383
+ class WrappedUint8(WrappedInt, UnsignedInt, AnyInt8):
374
384
  pass
375
385
 
376
386
 
377
- class WrappedUInt16(WrappedInt, UnsignedInt, AnyInt16):
387
+ class WrappedUint16(WrappedInt, UnsignedInt, AnyInt16):
378
388
  pass
379
389
 
380
390
 
381
- class WrappedUInt32(WrappedInt, UnsignedInt, AnyInt32):
391
+ class WrappedUint32(WrappedInt, UnsignedInt, AnyInt32):
382
392
  pass
383
393
 
384
394
 
385
- class WrappedUInt64(WrappedInt, UnsignedInt, AnyInt64):
395
+ class WrappedUint64(WrappedInt, UnsignedInt, AnyInt64):
386
396
  pass
387
397
 
388
398
 
389
- class WrappedUInt128(WrappedInt, UnsignedInt, AnyInt128):
399
+ class WrappedUint128(WrappedInt, UnsignedInt, AnyInt128):
390
400
  pass
omlish/os/forkhooks.py CHANGED
@@ -36,9 +36,9 @@ class _ForkHookManager:
36
36
 
37
37
  #
38
38
 
39
- _hooks_by_key: ta.ClassVar[ta.Dict[str, Hook]] = {}
39
+ _hooks_by_key: ta.ClassVar[ta.Dict[ta.Any, Hook]] = {}
40
40
 
41
- _hook_keys: ta.ClassVar[ta.FrozenSet[str]] = frozenset()
41
+ _hook_keys: ta.ClassVar[ta.FrozenSet[ta.Any]] = frozenset()
42
42
  _priority_ordered_hooks: ta.ClassVar[ta.List[Hook]] = []
43
43
 
44
44
  @classmethod
@@ -191,7 +191,7 @@ class ForkHook(abc.ABC): # noqa
191
191
  ##
192
192
 
193
193
 
194
- class _ForkDepthTracker(ForkHook):
194
+ class ForkDepthTracker(ForkHook):
195
195
  _hook_priority = -1000
196
196
 
197
197
  _fork_depth: ta.ClassVar[int] = 0
@@ -208,7 +208,7 @@ class _ForkDepthTracker(ForkHook):
208
208
 
209
209
 
210
210
  def get_fork_depth() -> int:
211
- return _ForkDepthTracker.get_fork_depth()
211
+ return ForkDepthTracker.get_fork_depth()
212
212
 
213
213
 
214
214
  ##
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omlish
3
- Version: 0.0.0.dev339
3
+ Version: 0.0.0.dev340
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=9rj0m3n7RBQVQZMvY6T23ySBhV_U7yrnp5EbbcfsW48,3478
2
+ omlish/__about__.py,sha256=6UJoYTHXIFWagDFn93wfY_32T-1b-9-HV7hM8VXYLNE,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
@@ -45,15 +45,15 @@ omlish/asyncs/asyncio/streams.py,sha256=J_d1hgX4Mx9SfyW4DjOzh91PqzZmjOtiIB95ytF8
45
45
  omlish/asyncs/asyncio/subprocesses.py,sha256=Mvy5cXHbY-JB5Yl57G05c2O7aEMAjSe29Ed_J63pvx0,6896
46
46
  omlish/asyncs/asyncio/timeouts.py,sha256=c-DhZi0yFXhJ6NtHa4EhB1Vrr1QDVd-7HBRkr96Q2So,446
47
47
  omlish/asyncs/asyncio/utils.py,sha256=mDjYNm1cylUhQ8slWXwdPoXasuWfafjzu78GHt2Mdig,2437
48
- omlish/asyncs/bluelet/LICENSE,sha256=VHf3oPQihOHnWyIR8LcXX0dpONa1lgyJnjWC2qVuRR0,559
48
+ omlish/asyncs/bluelet/LICENSE,sha256=q5Kpj4s30qpi8H66tXFlh5v8_fkaKMFIzqdGfnN0Hz0,555
49
49
  omlish/asyncs/bluelet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
50
  omlish/asyncs/bluelet/all.py,sha256=aUV6PwnR8DqnEBS9wsZuPW_UtP6G9M8_KY-mmxZeVG0,1516
51
- omlish/asyncs/bluelet/api.py,sha256=yeM5SauiIbvKj26mDdxn5mOj8s5fFIw2xBSe-P6HVC0,904
52
- omlish/asyncs/bluelet/core.py,sha256=NpGQhb865aeXPKV_67l-6FiuQzdDJJ85zjfvCR5R8Pc,5430
53
- omlish/asyncs/bluelet/events.py,sha256=iXpRWmy64YcshT_nuyiJ39jbketZdtj8LrdlX3JmpoY,2440
54
- omlish/asyncs/bluelet/files.py,sha256=pgcLV_3oGbpqQmOrii8SeizyYLp8XKofQJhqM82RlKw,2389
55
- omlish/asyncs/bluelet/runner.py,sha256=F6Ep0th09f-FkIRJfMN3_u-iG21jNNv11WyqnHyITYU,15475
56
- omlish/asyncs/bluelet/sockets.py,sha256=RrC2vU52dOEBYKzvoh1qA39uUE8p3uCB_oxnhaP1AeA,6752
51
+ omlish/asyncs/bluelet/api.py,sha256=KESn5CJR_KytAeztrPoQXNzBS6lZQXV7jbCspy4s0OU,900
52
+ omlish/asyncs/bluelet/core.py,sha256=56fhNayTGLdXvPxYfPJYEOlACPxe5KEfL-IQ9STQ_fo,5426
53
+ omlish/asyncs/bluelet/events.py,sha256=6lO6DoSikQzPkwz7iV9MACs8AMCwCo8hSI9lH30Tfv8,2436
54
+ omlish/asyncs/bluelet/files.py,sha256=N5oRUHcgwtHVa1dbSzJUG7QKUq9VExhDrC-pKxbCp3s,2385
55
+ omlish/asyncs/bluelet/runner.py,sha256=31blG6OAy66FZ9DmPG4h6t_nr8idxVSqyV0aSbc4ywE,15471
56
+ omlish/asyncs/bluelet/sockets.py,sha256=-HCSJN6k1uAwMs1-Rsgv0f3LdNStAuMyqmSIEJMxQRo,6748
57
57
  omlish/asyncs/ioproxy/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
58
58
  omlish/asyncs/ioproxy/all.py,sha256=_0mg0OjNKbnpGPSQZ-ftXYhKSpt-Po4Rlu2kam7v3XQ,1003
59
59
  omlish/asyncs/ioproxy/io.py,sha256=JDfxqqNw0uKB7rliI-SCDtqK7tGyn6NKnPJea8WXHec,5117
@@ -76,7 +76,7 @@ omlish/codecs/funcs.py,sha256=p4imNt7TobyZVXWC-WhntHVu9KfJrO4QwdtPRh-cVOk,850
76
76
  omlish/codecs/registry.py,sha256=2FnO5YP7ui1LzkguwESY0MP3WIdwgPTIJTM_4RyTOEg,3896
77
77
  omlish/codecs/standard.py,sha256=eiZ4u9ep0XrA4Z_D1zJI0vmWyuN8HLrX4Se_r_Cq_ZM,60
78
78
  omlish/codecs/text.py,sha256=JzrdwMpQPo2NBBg3K1EZszzQy5vEWmd82SIerJd4yeQ,5723
79
- omlish/collections/__init__.py,sha256=_7sct5tPAzV3BadIGYRdz6KzazntZIws9e8fEDlUwsU,2404
79
+ omlish/collections/__init__.py,sha256=AKf3dEpZar2KTrSaRF0VQ3CRjqUBZObY3zNwYL7lbmY,2690
80
80
  omlish/collections/abc.py,sha256=ikTJlJ5dhXjU6tlNsI0Wm0_7GaIEpe3mftpvdGY_nc8,2620
81
81
  omlish/collections/bimap.py,sha256=3szDCscPJlFRtkpyVQNWneg4s50mr6Rd0jdTzVEIcnE,1661
82
82
  omlish/collections/coerce.py,sha256=tAls15v_7p5bUN33R7Zbko87KW5toWHl9fRialCqyNY,7030
@@ -85,6 +85,7 @@ omlish/collections/frozen.py,sha256=LMbAHYDENIQk1hvjCTvpnx66m1TalrHa4CSn8n_tsXQ,
85
85
  omlish/collections/hasheq.py,sha256=uHypfZlHhicQPvx9OOlpT9MSLwfc_mFil-WaxF9dTOo,3732
86
86
  omlish/collections/identity.py,sha256=S_W508EkU-AW0TZ7cv1wWUc6EG54vww4XbcfGjDFTgg,4793
87
87
  omlish/collections/mappings.py,sha256=iXb7oq1rCQak0KgzblgrzWCJLrkfJAYHFvl9lprOVUI,2804
88
+ omlish/collections/multimaps.py,sha256=8Sqi1iVxUObnL47s8b1esa2TERoiEyyY4RBWF1VjDiw,3820
88
89
  omlish/collections/ordered.py,sha256=7zTbrAt12rf6i33XHkQERKar258fJacaw_WbtGEBgWo,2338
89
90
  omlish/collections/ranked.py,sha256=McB8C2UQfUvrbmxGTpBz1-EZuyCLkBFtktzncMdt8_Y,2287
90
91
  omlish/collections/unmodifiable.py,sha256=X7kKhPFdZF4m28SfLDxZL-riWlhbZffdPv35aTP30YM,4753
@@ -260,21 +261,20 @@ omlish/formats/edn/values.py,sha256=jf0g88KJIMALxcuH51SoaMWg1HqTUqc1ugldmyyXWoc,
260
261
  omlish/formats/ini/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
261
262
  omlish/formats/ini/codec.py,sha256=omuFg0kiDksv8rRlWd_v32ebzEcKlgmiPgGID3bRi2M,631
262
263
  omlish/formats/ini/sections.py,sha256=7wYyZdVTQbMPFpjQEACKJfAEPzUBrogINsrvFgxJoZ0,1015
263
- omlish/formats/json/__init__.py,sha256=MAvDQlUgn6DlVZaL03539tYfdtU0cT1Y9Rcy9yBhjYs,889
264
- omlish/formats/json/codecs.py,sha256=E5KErfqsgGZq763ixXLT3qysbk5MIsypT92xG5aSaIs,796
264
+ omlish/formats/json/__init__.py,sha256=i41uhoyXjuLjj5JmdRj4Ud2sfKD0j6KAyk_XyyCIB3M,902
265
+ omlish/formats/json/codecs.py,sha256=wvPHZw8cDHaOV6u7e9rfpCH3JVF_IjA6ND_fQUhcCXU,844
265
266
  omlish/formats/json/consts.py,sha256=A0cTAGGLyjo-gcYIQrL4JIaardI0yPMhQoNmh42BaRg,387
266
267
  omlish/formats/json/encoding.py,sha256=iwoYyJePibgvRDZ6e9b2OlXmOBJEczquRNoiffVf3hE,502
267
- omlish/formats/json/json.py,sha256=Mdqv2vdMi7gp96eV0BIYH5UdWpjWfsh-tSMZeywG-08,331
268
268
  omlish/formats/json/literals.py,sha256=MMou9UIoztL9EyX2Zhv3Kzfq8eaKMfGNCFhL16n-fTk,7532
269
269
  omlish/formats/json/rendering.py,sha256=0S_ppr5ihkUW7PP0mipZXHr72otqwUCNfanwopcboag,4571
270
270
  omlish/formats/json/types.py,sha256=ueO9-uOU2eVWowJf0LH1fHFLjZ6fTIZyq9qybcLQaiQ,147
271
- omlish/formats/json/backends/__init__.py,sha256=foi543hIIODpUfvlwVMtkWDGhZSRGaC3BBxdIrinofo,160
271
+ omlish/formats/json/backends/__init__.py,sha256=K5nAP-fCgUvaSylHqgRvmJp6j6PTWdMjrNhvMouKrFc,161
272
272
  omlish/formats/json/backends/base.py,sha256=WqtyoM82pyM0NyqpPwndrebr1bUVU1QlpmVQNrcAO8c,1114
273
- omlish/formats/json/backends/default.py,sha256=a-eM-Y1IHdpYvZFjazwq_orRncjtYR7BKxP_2kpEXog,322
273
+ omlish/formats/json/backends/default.py,sha256=PXVM8kM0LWRA1-aEAJ0JMfu9BDuHpPFCDgBme6JNdAw,1317
274
274
  omlish/formats/json/backends/jiter.py,sha256=8qv_XWGpcupPtVm6Z_egHio_iY1Kk8eqkvXTF6fVZr4,1193
275
- omlish/formats/json/backends/orjson.py,sha256=wR8pMGFtkhZGHcNVk7vNYUnv8lUapdK89p6QpETIs9w,3778
276
- omlish/formats/json/backends/std.py,sha256=PM00Kh9ZR2XzollHMEvdo35Eml1N-zFfRW-LOCV5ftM,3085
277
- omlish/formats/json/backends/ujson.py,sha256=BNJCU4kluGHdqTUKLJEuHhE2m2TmqR7HEN289S0Eokg,2278
275
+ omlish/formats/json/backends/orjson.py,sha256=dHrD75f0ZOHve80Xpq8A2_ec69kXcj4nEM-pIdiemtU,3805
276
+ omlish/formats/json/backends/std.py,sha256=Hhiug5CkC1TXLFrE9rnMR2on7xP-RliSvfYA9ill_U0,3159
277
+ omlish/formats/json/backends/ujson.py,sha256=U3iOlAURfiCdXbiNlXfIjDdtJDbDaLZsSuZriTUvbxs,2307
278
278
  omlish/formats/json/stream/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
279
279
  omlish/formats/json/stream/building.py,sha256=SGbExmaerqOEiNSom2AERlpyXTj4dpM0QbMW-2WWM2o,2550
280
280
  omlish/formats/json/stream/errors.py,sha256=c8M8UAYmIZ-vWZLeKD2jMj4EDCJbr9QR8Jq_DyHjujQ,43
@@ -304,14 +304,14 @@ omlish/funcs/match.py,sha256=MAzpWkdIvhdoQTm-R2ivRDkfG8--RmdusiRF137cKEM,6085
304
304
  omlish/funcs/pairs.py,sha256=VCkZjDmJGtR76BsejsHNfb4TcpHCtkkmak-zWDFchAo,3904
305
305
  omlish/funcs/pipes.py,sha256=E7Sz8Aj8ke_vCs5AMNwg1I36kRdHVGTnzxVQaDyn43U,2490
306
306
  omlish/graphs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
307
- omlish/graphs/dags.py,sha256=7ee4GfzHcAVUA5-LMJyT7odwxoooh4cTwz4H8qi8Anc,3045
308
- omlish/graphs/domination.py,sha256=N-rCzB3uAug964Tx4YGew1Nuh7GvzGjA598GcOj-Who,7571
309
- omlish/graphs/trees.py,sha256=dPlIBqWNqPn-kGHBeTkSgmZ_3haq5nEmsdBY1fYnvgE,8197
307
+ omlish/graphs/dags.py,sha256=GsTVDehSGxIpjuZ3qe29dldhVydqWexZD9mpqZErhnI,4400
308
+ omlish/graphs/domination.py,sha256=iwQa4QUXitLU2X4cdPxJ1ltRRUTuXnz0lI8j4GtuBsw,7591
309
+ omlish/graphs/trees.py,sha256=Y-ifC3_z2ND1N4czMkD3nVVWYTdJfNlCPrghvWFZCH0,8233
310
310
  omlish/graphs/dot/__init__.py,sha256=Y1MZRQBZkcYyG1Tn7K2FhL8aYbm4v4tk6f5g9AqEkUw,359
311
- omlish/graphs/dot/items.py,sha256=7c-lvB2pp6LKWDI2di-S6Zh4vlUZt97eJeNQzuGilGc,4082
312
- omlish/graphs/dot/make.py,sha256=RN30gHfJPiXx5Q51kbDdhVJYf59Fr84Lz9J-mXRt9sI,360
313
- omlish/graphs/dot/rendering.py,sha256=eN1NufiUaKFeRxRTOfIT-oLTg1YQCuPybBx3AmrhdBw,3629
314
- omlish/graphs/dot/utils.py,sha256=_FMwn77WfiiAfLsRTOKWm4IYbNv5kQN22YJ5psw6CWg,801
311
+ omlish/graphs/dot/items.py,sha256=GIzUqLHJPR4AVtF141uA8JnyybkRZx6mFYsNJHu_JVg,4087
312
+ omlish/graphs/dot/make.py,sha256=e-M1IEdh4kHEjJmBxpaEUPxvFLrm5uIXdGxjQZr2HRo,365
313
+ omlish/graphs/dot/rendering.py,sha256=IOCEEOqlsRctoIgnz1I9v0ycHHDAr5zYubTXT7v_YwA,3634
314
+ omlish/graphs/dot/utils.py,sha256=8cGKIdcM-w1q4ITUYyC0lnYwLqNWuH2OddmmbLxVgEo,806
315
315
  omlish/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
316
316
  omlish/http/all.py,sha256=4dSBbitsrQIadivSo2rBLg8dgdmC0efpboylGUZgKKo,829
317
317
  omlish/http/asgi.py,sha256=D-8ZnnR5Asv9o02FXorCBYfolFV9TIcCPm51hSlMkCA,3195
@@ -433,7 +433,7 @@ omlish/lang/cached/function.py,sha256=su9QxYECK9NK-UfMFKbgx4lqH2WoGBiYshnEfaGvfh
433
433
  omlish/lang/cached/property.py,sha256=WHYyg4-6EA86TcNMfbXTjVhjEZPc0kngt9hfY3WN5w8,2768
434
434
  omlish/lang/classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
435
435
  omlish/lang/classes/abstract.py,sha256=A-Jg5X8o_WvFryN0Cm2TpVkrZoTT1SYKQnv_pXjZk7o,3808
436
- omlish/lang/classes/bindable.py,sha256=ekVyOxrM9kQ9AtI9Zzc89zP_JBfJizIThKFNw4YZtS8,1096
436
+ omlish/lang/classes/bindable.py,sha256=gviEabI5gEx0Rpu4G0LDWaD4N_VO1WUeFs1_XEisoAE,1233
437
437
  omlish/lang/classes/namespaces.py,sha256=_FBLekx2gNLql1C1ZRlpBtxuLWbcdFEzBm8CrD5XeOA,3589
438
438
  omlish/lang/classes/protocols.py,sha256=T98ZsHLgzw8hPvvNluxoreevoF8fD4zs8SwcnTXkLuY,701
439
439
  omlish/lang/classes/restrict.py,sha256=Ki-UOc2yUVteqC7i_EgIVpeEcnvRHVczjts5Fyiz7Mk,4125
@@ -532,10 +532,10 @@ omlish/marshal/trivial/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
532
532
  omlish/marshal/trivial/any.py,sha256=YjbHgUtwktXuFfkPCSQIxdwC6tA70CPA3-msAE4slKs,791
533
533
  omlish/marshal/trivial/forbidden.py,sha256=w-U_tZB7X0IuFpV4j1DxCQmOL02InmZSICROtq-w3-s,1033
534
534
  omlish/marshal/trivial/nop.py,sha256=EoxaCbfkLbDfSGdE_xJbH1ghIeYwaptmqq3OGHKgmAg,471
535
- omlish/math/__init__.py,sha256=sejGr6RkG6WaowGKSfICtHKqgb_BgqEaGCnj9mWaZiY,1185
535
+ omlish/math/__init__.py,sha256=0N2LtQYsAit7wXDKa-Dj6XPkVzEviP-tB2BNQoMhzLI,1185
536
536
  omlish/math/bits.py,sha256=pcTuWxNXXfG-CtTITNNbW3YConAkCeU8PLNcglCc43E,533
537
537
  omlish/math/c.py,sha256=JUHHZfVUUE4sb-6_LxJksbcLOLi9za0LdPs4dky5Ba8,308
538
- omlish/math/fixed.py,sha256=Ql9JP1MPr8ny--xz7rSDf_Wlcri6jHhyjH0-UyLcXUA,7211
538
+ omlish/math/fixed.py,sha256=pplyqqD6BxZWS9UEc8MHLsiMwx0-D1GLTeB8EL6yxHs,7419
539
539
  omlish/math/floats.py,sha256=xbuGQccA3wC0DoTDqR4awgrzfwoOEYQLdQmFgw7c6-w,332
540
540
  omlish/math/histogram.py,sha256=gDYJG9Cq2sZEjae0cFOb-ADzwNY_xKSnF73Tyd34EPQ,3859
541
541
  omlish/math/stats.py,sha256=HxWJhZD5vdPcCAZ2HO9jYz798EPl2JtyEbXLoJdlRjE,6225
@@ -548,7 +548,7 @@ omlish/os/deathsig.py,sha256=hk9Yq2kyDdI-cI7OQH7mOfpRbOKzY_TfPKEqgrjVYbA,641
548
548
  omlish/os/fcntl.py,sha256=riQf9iEEEIC28lJp8ud06MU56w2XJHJ9nBFtck_hdhc,1501
549
549
  omlish/os/filemodes.py,sha256=ZIk6XpPw2oyoytSsuVmBXQ6fvMDHzctNEDIA2uHTBC4,4575
550
550
  omlish/os/files.py,sha256=WJ_42vsZIZukQURN3TTccp-n74ZNhbux_ps3TLbHj18,1106
551
- omlish/os/forkhooks.py,sha256=STzhEuV7oOegfqlq1DJIhESO1icMzgat0V9m02Ubky8,5668
551
+ omlish/os/forkhooks.py,sha256=AnGnM69w-tdFZmejX68ijfGlXxHePU6q0PDvyHOBjPc,5672
552
552
  omlish/os/journald.py,sha256=2nI8Res1poXkbLc31--MPUlzYMESnCcPUkIxDOCjZW0,3903
553
553
  omlish/os/linux.py,sha256=whJ6scwMKSFBdXiVhJW0BCpJV4jOGMr-a_a3Bhwz6Ls,18938
554
554
  omlish/os/mangle.py,sha256=M0v-SDt4TMnL68I45GekQrUaXkTIILXIlPdqRxKBTKM,524
@@ -864,9 +864,9 @@ omlish/typedvalues/marshal.py,sha256=AtBz7Jq-BfW8vwM7HSxSpR85JAXmxK2T0xDblmm1HI0
864
864
  omlish/typedvalues/of_.py,sha256=UXkxSj504WI2UrFlqdZJbu2hyDwBhL7XVrc2qdR02GQ,1309
865
865
  omlish/typedvalues/reflect.py,sha256=PAvKW6T4cW7u--iX80w3HWwZUS3SmIZ2_lQjT65uAyk,1026
866
866
  omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
867
- omlish-0.0.0.dev339.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
868
- omlish-0.0.0.dev339.dist-info/METADATA,sha256=Bx0Qfyj8FjWFBV_s8fjqv2aA13OgX8R1SCRM5RKTMSU,4416
869
- omlish-0.0.0.dev339.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
870
- omlish-0.0.0.dev339.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
871
- omlish-0.0.0.dev339.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
872
- omlish-0.0.0.dev339.dist-info/RECORD,,
867
+ omlish-0.0.0.dev340.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
868
+ omlish-0.0.0.dev340.dist-info/METADATA,sha256=C8Px98rFp8jX4oXUDcpPH5CJ5UFR9qVA5TcDjeu07KA,4416
869
+ omlish-0.0.0.dev340.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
870
+ omlish-0.0.0.dev340.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
871
+ omlish-0.0.0.dev340.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
872
+ omlish-0.0.0.dev340.dist-info/RECORD,,
@@ -1,17 +0,0 @@
1
- from .backends import DEFAULT_BACKED
2
-
3
-
4
- ##
5
-
6
-
7
- dump = DEFAULT_BACKED.dump
8
- dumps = DEFAULT_BACKED.dumps
9
-
10
- load = DEFAULT_BACKED.load
11
- loads = DEFAULT_BACKED.loads
12
-
13
- dump_pretty = DEFAULT_BACKED.dump_pretty
14
- dumps_pretty = DEFAULT_BACKED.dumps_pretty
15
-
16
- dump_compact = DEFAULT_BACKED.dump_compact
17
- dumps_compact = DEFAULT_BACKED.dumps_compact