omlish 0.0.0.dev1__py3-none-any.whl → 0.0.0.dev3__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.

Files changed (147) hide show
  1. omlish/__about__.py +2 -3
  2. omlish/argparse.py +8 -8
  3. omlish/asyncs/__init__.py +2 -2
  4. omlish/asyncs/anyio.py +64 -1
  5. omlish/asyncs/asyncs.py +1 -3
  6. omlish/asyncs/futures.py +16 -15
  7. omlish/c3.py +5 -5
  8. omlish/check.py +8 -8
  9. omlish/collections/__init__.py +98 -63
  10. omlish/collections/_abc.py +2 -0
  11. omlish/collections/_io_abc.py +4 -2
  12. omlish/collections/cache/__init__.py +1 -1
  13. omlish/collections/cache/descriptor.py +12 -12
  14. omlish/collections/cache/impl.py +27 -20
  15. omlish/collections/cache/types.py +1 -1
  16. omlish/collections/coerce.py +44 -44
  17. omlish/collections/frozen.py +9 -9
  18. omlish/collections/identity.py +4 -5
  19. omlish/collections/mappings.py +5 -5
  20. omlish/collections/ordered.py +8 -8
  21. omlish/collections/skiplist.py +7 -7
  22. omlish/collections/sorted.py +4 -4
  23. omlish/collections/treap.py +42 -17
  24. omlish/collections/treapmap.py +59 -7
  25. omlish/collections/unmodifiable.py +25 -24
  26. omlish/collections/utils.py +1 -1
  27. omlish/configs/flattening.py +8 -7
  28. omlish/configs/props.py +3 -3
  29. omlish/dataclasses/__init__.py +1 -1
  30. omlish/dataclasses/impl/__init__.py +18 -0
  31. omlish/dataclasses/impl/api.py +15 -24
  32. omlish/dataclasses/impl/as_.py +4 -4
  33. omlish/dataclasses/impl/exceptions.py +1 -1
  34. omlish/dataclasses/impl/fields.py +8 -8
  35. omlish/dataclasses/impl/frozen.py +2 -2
  36. omlish/dataclasses/impl/init.py +6 -6
  37. omlish/dataclasses/impl/internals.py +16 -1
  38. omlish/dataclasses/impl/main.py +4 -4
  39. omlish/dataclasses/impl/metaclass.py +2 -2
  40. omlish/dataclasses/impl/metadata.py +1 -1
  41. omlish/dataclasses/impl/order.py +2 -2
  42. omlish/dataclasses/impl/params.py +4 -38
  43. omlish/dataclasses/impl/reflect.py +1 -7
  44. omlish/dataclasses/impl/replace.py +1 -1
  45. omlish/dataclasses/impl/repr.py +24 -6
  46. omlish/dataclasses/impl/simple.py +2 -2
  47. omlish/dataclasses/impl/slots.py +2 -2
  48. omlish/dataclasses/impl/utils.py +7 -7
  49. omlish/defs.py +13 -17
  50. omlish/diag/procfs.py +334 -0
  51. omlish/diag/ps.py +47 -0
  52. omlish/{replserver → diag/replserver}/console.py +26 -28
  53. omlish/{replserver → diag/replserver}/server.py +12 -12
  54. omlish/dispatch/dispatch.py +14 -16
  55. omlish/dispatch/functions.py +1 -1
  56. omlish/dispatch/methods.py +6 -7
  57. omlish/docker.py +8 -6
  58. omlish/dynamic.py +13 -13
  59. omlish/fnpairs.py +311 -0
  60. omlish/graphs/dot/items.py +1 -1
  61. omlish/graphs/trees.py +25 -31
  62. omlish/inject/__init__.py +7 -7
  63. omlish/inject/elements.py +2 -2
  64. omlish/inject/exceptions.py +8 -8
  65. omlish/inject/impl/elements.py +4 -4
  66. omlish/inject/impl/injector.py +6 -6
  67. omlish/inject/impl/inspect.py +3 -3
  68. omlish/inject/impl/scopes.py +9 -9
  69. omlish/inject/injector.py +1 -1
  70. omlish/inject/providers.py +2 -2
  71. omlish/inject/proxy.py +5 -5
  72. omlish/iterators.py +62 -26
  73. omlish/json.py +7 -6
  74. omlish/lang/__init__.py +172 -112
  75. omlish/lang/cached.py +15 -10
  76. omlish/lang/classes/__init__.py +35 -24
  77. omlish/lang/classes/abstract.py +3 -3
  78. omlish/lang/classes/restrict.py +14 -14
  79. omlish/lang/classes/simple.py +2 -2
  80. omlish/lang/classes/virtual.py +5 -5
  81. omlish/lang/clsdct.py +2 -2
  82. omlish/lang/cmp.py +2 -2
  83. omlish/lang/contextmanagers.py +31 -25
  84. omlish/lang/datetimes.py +1 -1
  85. omlish/lang/descriptors.py +51 -6
  86. omlish/lang/exceptions.py +2 -0
  87. omlish/lang/functions.py +101 -35
  88. omlish/lang/imports.py +25 -30
  89. omlish/lang/iterables.py +2 -2
  90. omlish/lang/maybes.py +2 -1
  91. omlish/lang/objects.py +17 -11
  92. omlish/lang/resolving.py +1 -1
  93. omlish/lang/strings.py +1 -1
  94. omlish/lang/timeouts.py +53 -0
  95. omlish/lang/typing.py +5 -5
  96. omlish/libc.py +15 -11
  97. omlish/logs/_abc.py +5 -1
  98. omlish/logs/filters.py +2 -0
  99. omlish/logs/formatters.py +6 -2
  100. omlish/logs/utils.py +1 -1
  101. omlish/marshal/base.py +9 -9
  102. omlish/marshal/dataclasses.py +2 -2
  103. omlish/marshal/enums.py +2 -2
  104. omlish/marshal/exceptions.py +1 -1
  105. omlish/marshal/factories.py +10 -10
  106. omlish/marshal/global_.py +10 -4
  107. omlish/marshal/iterables.py +2 -2
  108. omlish/marshal/mappings.py +2 -2
  109. omlish/marshal/objects.py +1 -2
  110. omlish/marshal/optionals.py +4 -4
  111. omlish/marshal/polymorphism.py +4 -4
  112. omlish/marshal/registries.py +3 -3
  113. omlish/marshal/standard.py +6 -6
  114. omlish/marshal/utils.py +3 -3
  115. omlish/marshal/values.py +1 -1
  116. omlish/math.py +9 -9
  117. omlish/os.py +13 -4
  118. omlish/reflect.py +5 -15
  119. omlish/sql/__init__.py +0 -0
  120. omlish/sql/_abc.py +65 -0
  121. omlish/sql/dbs.py +90 -0
  122. omlish/stats.py +7 -8
  123. omlish/term.py +1 -1
  124. omlish/testing/pydevd.py +30 -12
  125. omlish/testing/pytest/inject/__init__.py +7 -0
  126. omlish/testing/pytest/inject/harness.py +24 -2
  127. omlish/testing/pytest/plugins/__init__.py +1 -1
  128. omlish/testing/pytest/plugins/pydevd.py +12 -0
  129. omlish/testing/pytest/plugins/switches.py +3 -3
  130. omlish/testing/testing.py +5 -5
  131. omlish/text/delimit.py +3 -6
  132. omlish/text/parts.py +3 -3
  133. omlish-0.0.0.dev3.dist-info/METADATA +31 -0
  134. omlish-0.0.0.dev3.dist-info/RECORD +191 -0
  135. {omlish-0.0.0.dev1.dist-info → omlish-0.0.0.dev3.dist-info}/WHEEL +1 -1
  136. omlish/lang/classes/test/test_abstract.py +0 -89
  137. omlish/lang/classes/test/test_restrict.py +0 -71
  138. omlish/lang/classes/test/test_simple.py +0 -58
  139. omlish/lang/classes/test/test_virtual.py +0 -72
  140. omlish/testing/pytest/plugins/pycharm.py +0 -54
  141. omlish-0.0.0.dev1.dist-info/METADATA +0 -17
  142. omlish-0.0.0.dev1.dist-info/RECORD +0 -187
  143. /omlish/{lang/classes/test → diag}/__init__.py +0 -0
  144. /omlish/{replserver → diag/replserver}/__init__.py +0 -0
  145. /omlish/{replserver → diag/replserver}/__main__.py +0 -0
  146. {omlish-0.0.0.dev1.dist-info → omlish-0.0.0.dev3.dist-info}/LICENSE +0 -0
  147. {omlish-0.0.0.dev1.dist-info → omlish-0.0.0.dev3.dist-info}/top_level.txt +0 -0
omlish/lang/objects.py CHANGED
@@ -9,18 +9,22 @@ T = ta.TypeVar('T')
9
9
 
10
10
 
11
11
  def attr_repr(obj: ta.Any, *attrs: str) -> str:
12
- return '%s(%s)' % (
13
- type(obj).__name__,
14
- ', '.join('%s=%r' % (attr, getattr(obj, attr)) for attr in attrs))
12
+ return f'{type(obj).__name__}({", ".join(f"{attr}={getattr(obj, attr)!r}" for attr in attrs)})'
15
13
 
16
14
 
17
15
  def arg_repr(*args, **kwargs) -> str:
18
16
  return ', '.join(*(
19
17
  list(map(repr, args)) +
20
- [f'{k}={repr(v)}' for k, v in kwargs.items()]
18
+ [f'{k}={v!r}' for k, v in kwargs.items()]
21
19
  ))
22
20
 
23
21
 
22
+ def opt_repr(obj: ta.Any) -> str | None:
23
+ if obj is None:
24
+ return None
25
+ return repr(obj)
26
+
27
+
24
28
  ##
25
29
 
26
30
 
@@ -28,8 +32,8 @@ def new_type(
28
32
  name: str,
29
33
  bases: ta.Sequence[ta.Any],
30
34
  namespace: ta.Mapping[str, ta.Any],
31
- **kwargs
32
- ) -> ta.Type:
35
+ **kwargs,
36
+ ) -> type:
33
37
  return types.new_class(
34
38
  name,
35
39
  tuple(bases),
@@ -40,12 +44,12 @@ def new_type(
40
44
 
41
45
  def super_meta(
42
46
  super_meta: ta.Any,
43
- meta: ta.Type,
47
+ meta: type,
44
48
  name: str,
45
49
  bases: ta.Sequence[ta.Any],
46
50
  namespace: ta.MutableMapping[str, ta.Any],
47
- **kwargs
48
- ) -> ta.Type:
51
+ **kwargs,
52
+ ) -> type:
49
53
  """Per types.new_class"""
50
54
  resolved_bases = types.resolve_bases(bases)
51
55
  if resolved_bases is not bases:
@@ -75,19 +79,21 @@ class SimpleProxy(ta.Generic[T]):
75
79
  if instance is None:
76
80
  return self
77
81
  setattr(object.__getattribute__(instance, '__wrapped__'), self._attr, value)
82
+ return None
78
83
 
79
84
  def __delete__(self, instance):
80
85
  if instance is None:
81
86
  return self
82
87
  delattr(object.__getattribute__(instance, '__wrapped__'), self._attr)
88
+ return None
83
89
 
84
- __wrapped_attrs__: ta.Iterable[str] = set()
90
+ __wrapped_attrs__: ta.ClassVar[ta.Iterable[str]] = ()
85
91
 
86
92
  def __init__(self, wrapped: T) -> None:
87
93
  super().__init__()
88
94
  object.__setattr__(self, '__wrapped__', wrapped)
89
95
 
90
- def __init_subclass__(cls, **kwargs):
96
+ def __init_subclass__(cls, **kwargs: ta.Any) -> None:
91
97
  super().__init_subclass__(**kwargs)
92
98
 
93
99
  for attr in cls.__wrapped_attrs__:
omlish/lang/resolving.py CHANGED
@@ -45,6 +45,6 @@ def get_fqcn_cls(fqcn: str, *, nocheck: bool = False) -> type:
45
45
 
46
46
 
47
47
  class Resolvable:
48
- def __init_subclass__(cls, **kwargs):
48
+ def __init_subclass__(cls, **kwargs: ta.Any) -> None:
49
49
  super().__init_subclass__(**kwargs)
50
50
  get_cls_fqcn(cls, nocheck=True)
omlish/lang/strings.py CHANGED
@@ -22,7 +22,7 @@ def camel_case(name: str) -> str:
22
22
 
23
23
  def snake_case(name: str) -> str:
24
24
  uppers: list[int | None] = [i for i, c in enumerate(name) if c.isupper()]
25
- return '_'.join([name[l:r].lower() for l, r in zip([None] + uppers, uppers + [None])]).strip('_')
25
+ return '_'.join([name[l:r].lower() for l, r in zip([None, *uppers], [*uppers, None])]).strip('_')
26
26
 
27
27
 
28
28
  def is_dunder(name: str) -> bool:
@@ -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 = ta.Union[bytes, bytearray]
15
+ BytesLike: ta.TypeAlias = bytes | bytearray
16
16
 
17
17
 
18
18
  ##
@@ -37,13 +37,13 @@ def _update_wrapper_no_anns(wrapper, wrapped):
37
37
  return wrapper
38
38
 
39
39
 
40
- def typed_lambda(ret=_MISSING, **kw):
40
+ def typed_lambda(ret=_MISSING, **kw): # noqa
41
41
  def inner(fn):
42
42
  ns = {}
43
43
  ns['__fn'] = fn
44
44
  proto = ['def __lam(']
45
45
  call = ['return __fn(']
46
- pkw = {k: v for k, v in kw.items()}
46
+ pkw = dict(kw)
47
47
  for i, (n, t) in enumerate(pkw.items()):
48
48
  if i:
49
49
  call.append(', ')
@@ -69,7 +69,7 @@ def typed_lambda(ret=_MISSING, **kw):
69
69
  return inner
70
70
 
71
71
 
72
- def typed_partial(obj, **kw):
72
+ def typed_partial(obj, **kw): # noqa
73
73
  for k in kw:
74
74
  if k.startswith('__'):
75
75
  raise NameError(k)
@@ -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
@@ -1,3 +1,7 @@
1
+ # ruff: noqa: ANN201
2
+ # ruff: noqa: N801
3
+ # ruff: noqa: N802
4
+
1
5
  import ctypes as ct
2
6
  import errno
3
7
  import platform
@@ -37,14 +41,14 @@ def lasterr() -> tuple[int, str]:
37
41
 
38
42
 
39
43
  # int raise(int sig);
40
- libc._raise = libc['raise'] # type: ignore
41
- libc._raise.restype = ct.c_int
42
- libc._raise.argtypes = [ct.c_int]
43
- _raise = libc._raise
44
+ libc._raise = libc['raise'] # type: ignore # noqa
45
+ libc._raise.restype = ct.c_int # noqa
46
+ libc._raise.argtypes = [ct.c_int] # noqa
47
+ _raise = libc._raise # noqa
44
48
 
45
49
 
46
50
  def sigtrap() -> None:
47
- libc._raise(signal.SIGTRAP)
51
+ libc._raise(signal.SIGTRAP) # noqa
48
52
 
49
53
 
50
54
  ##
@@ -94,7 +98,7 @@ libc.mmap.argtypes = [
94
98
  ct.c_int,
95
99
  ct.c_int,
96
100
  ct.c_int,
97
- ct.c_size_t
101
+ ct.c_size_t,
98
102
  ]
99
103
  mmap = libc.mmap
100
104
 
@@ -138,7 +142,7 @@ elif DARWIN:
138
142
  libc.munmap.restype = ct.c_int
139
143
  libc.munmap.argtypes = [
140
144
  ct.c_void_p,
141
- ct.c_size_t
145
+ ct.c_size_t,
142
146
  ]
143
147
  munmap = libc.munmap
144
148
 
@@ -148,7 +152,7 @@ libc.mprotect.restype = ct.c_int
148
152
  libc.mprotect.argtypes = [
149
153
  ct.c_void_p,
150
154
  ct.c_size_t,
151
- ct.c_int
155
+ ct.c_int,
152
156
  ]
153
157
  mprotect = libc.mprotect
154
158
 
@@ -164,7 +168,7 @@ if LINUX:
164
168
  ct.c_void_p,
165
169
  ct.c_size_t,
166
170
  ct.c_size_t,
167
- ct.c_int
171
+ ct.c_int,
168
172
  ]
169
173
  mremap = libc.mremap
170
174
 
@@ -179,7 +183,7 @@ class Mmap:
179
183
  length: int,
180
184
  *,
181
185
  prot: int = PROT_READ | PROT_WRITE,
182
- flags: ta.Optional[int] = None,
186
+ flags: int | None = None,
183
187
  fd: int = -1,
184
188
  offset: int = 0,
185
189
  desired_base: int = 0,
@@ -205,7 +209,7 @@ class Mmap:
205
209
  self._is_mapped = False
206
210
 
207
211
  @property
208
- def base(self) -> ta.Optional[int]:
212
+ def base(self) -> int | None:
209
213
  return self._base
210
214
 
211
215
  def __enter__(self) -> 'Mmap':
omlish/logs/_abc.py CHANGED
@@ -1,3 +1,7 @@
1
+ # ruff: noqa: A002
2
+ # ruff: noqa: N802
3
+ # ruff: noqa: N815
4
+
1
5
  import types
2
6
  import typing as ta
3
7
 
@@ -181,7 +185,7 @@ class Logger(Filterer, ta.Protocol):
181
185
 
182
186
  def log(self, level: Level, msg: str, *args: ta.Any, **kwargs: ta.Any) -> None: ...
183
187
 
184
- def findCaller(self, stack_info: bool = False, stacklevel: int = 1) -> Caller: ... #
188
+ def findCaller(self, stack_info: bool = False, stacklevel: int = 1) -> Caller: ...
185
189
 
186
190
  def makeRecord(
187
191
  self,
omlish/logs/filters.py CHANGED
@@ -1,3 +1,5 @@
1
+ # ruff: noqa: ANN201
2
+
1
3
  import logging
2
4
  import threading
3
5
 
omlish/logs/formatters.py CHANGED
@@ -1,5 +1,9 @@
1
+ # ruff: noqa: ANN201
2
+ # ruff: noqa: N802
3
+
1
4
  import datetime
2
5
  import logging
6
+ import typing as ta
3
7
 
4
8
  from .. import json
5
9
  from .. import term
@@ -20,7 +24,7 @@ class StandardLogFormatter(logging.Formatter):
20
24
 
21
25
  class ColorLogFormatter(StandardLogFormatter):
22
26
 
23
- LEVEL_COLORS = {
27
+ LEVEL_COLORS: ta.Mapping[int, term.SGRs.FG] = {
24
28
  logging.WARNING: term.SGRs.FG.BRIGHT_YELLOW,
25
29
  logging.ERROR: term.SGRs.FG.BRIGHT_RED,
26
30
  logging.CRITICAL: term.SGRs.FG.BRIGHT_RED,
@@ -39,7 +43,7 @@ class ColorLogFormatter(StandardLogFormatter):
39
43
 
40
44
  class JsonLogFormatter(logging.Formatter):
41
45
 
42
- KEYS = {
46
+ KEYS: ta.Mapping[str, bool] = {
43
47
  'name': False,
44
48
  'msg': False,
45
49
  'args': False,
omlish/logs/utils.py CHANGED
@@ -5,7 +5,7 @@ import logging
5
5
  log = logging.getLogger(__name__)
6
6
 
7
7
 
8
- def error_logging(log=log):
8
+ def error_logging(log=log): # noqa
9
9
  def outer(fn):
10
10
  @functools.wraps(fn)
11
11
  def inner(*args, **kwargs):
omlish/marshal/base.py CHANGED
@@ -81,7 +81,7 @@ from .. import check
81
81
  from .. import collections as col
82
82
  from .. import lang
83
83
  from .. import reflect as rfl
84
- from .exceptions import UnhandledTypeException
84
+ from .exceptions import UnhandledTypeError
85
85
  from .factories import Factory
86
86
  from .factories import RecursiveTypeFactory
87
87
  from .registries import Registry
@@ -146,24 +146,24 @@ class BaseContext(lang.Abstract):
146
146
 
147
147
  @dc.dataclass(frozen=True)
148
148
  class MarshalContext(BaseContext, lang.Final):
149
- factory: ta.Optional[MarshalerFactory] = None
149
+ factory: MarshalerFactory | None = None
150
150
 
151
151
  def make(self, o: ta.Any) -> Marshaler:
152
152
  rty = rfl.type_(o)
153
153
  if (m := check.not_none(self.factory)(self, rty)) is not None: # noqa
154
154
  return m
155
- raise UnhandledTypeException(rty)
155
+ raise UnhandledTypeError(rty)
156
156
 
157
157
 
158
158
  @dc.dataclass(frozen=True)
159
159
  class UnmarshalContext(BaseContext, lang.Final):
160
- factory: ta.Optional[UnmarshalerFactory] = None
160
+ factory: UnmarshalerFactory | None = None
161
161
 
162
162
  def make(self, o: ta.Any) -> Unmarshaler:
163
163
  rty = rfl.type_(o)
164
164
  if (m := check.not_none(self.factory)(self, rty)) is not None: # noqa
165
165
  return m
166
- raise UnhandledTypeException(rty)
166
+ raise UnhandledTypeError(rty)
167
167
 
168
168
 
169
169
  ##
@@ -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: ta.Optional[Marshaler] = None
198
- marshaler_factory: ta.Optional[MarshalerFactory] = None
197
+ marshaler: Marshaler | None = None
198
+ marshaler_factory: MarshalerFactory | None = None
199
199
 
200
- unmarshaler: ta.Optional[Unmarshaler] = None
201
- unmarshaler_factory: ta.Optional[UnmarshalerFactory] = None
200
+ unmarshaler: Unmarshaler | None = None
201
+ unmarshaler_factory: UnmarshalerFactory | None = None
@@ -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) -> ta.Optional[Marshaler]:
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) -> ta.Optional[Unmarshaler]:
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) -> ta.Optional[Marshaler]:
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) -> ta.Optional[Unmarshaler]:
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
@@ -1,7 +1,7 @@
1
1
  from .. import reflect as rfl
2
2
 
3
3
 
4
- class UnhandledTypeException(Exception):
4
+ class UnhandledTypeError(Exception):
5
5
  @property
6
6
  def rty(self) -> rfl.Type:
7
7
  return self.args[0]
@@ -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) -> ta.Optional[R]:
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], ta.Optional[R]]
29
+ fn: ta.Callable[[C, A], R | None]
30
30
 
31
- def __call__(self, ctx: C, arg: A) -> ta.Optional[R]:
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) -> ta.Optional[R]:
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, ta.Optional[R]] = {}
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) -> ta.Optional[R]:
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[ta.Optional[R], ta.Callable[[ta.Optional[R]], None]]],
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, ta.Optional[R]] = {}
81
+ self._dct: dict[rfl.Type, R | None] = {}
82
82
 
83
- def __call__(self, ctx: C, rty: rfl.Type) -> ta.Optional[R]:
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) -> ta.Optional[R]:
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/global_.py CHANGED
@@ -1,8 +1,14 @@
1
- from .registries import Registry
2
- from .standard import new_standard_marshaler_factory
1
+ import typing as ta
2
+
3
3
  from .base import MarshalContext
4
4
  from .base import UnmarshalContext
5
+ from .registries import Registry
6
+ from .standard import new_standard_marshaler_factory
5
7
  from .standard import new_standard_unmarshaler_factory
8
+ from .values import Value
9
+
10
+
11
+ T = ta.TypeVar('T')
6
12
 
7
13
 
8
14
  ##
@@ -17,7 +23,7 @@ GLOBAL_REGISTRY = Registry()
17
23
  GLOBAL_MARSHALER_FACTORY = new_standard_marshaler_factory()
18
24
 
19
25
 
20
- def marshal(obj, ty=None, **kwargs):
26
+ def marshal(obj: ta.Any, ty: type | None = None, **kwargs: ta.Any) -> Value:
21
27
  mc = MarshalContext(GLOBAL_REGISTRY, factory=GLOBAL_MARSHALER_FACTORY, **kwargs)
22
28
  return mc.make(ty if ty is not None else type(obj)).marshal(mc, obj)
23
29
 
@@ -28,6 +34,6 @@ def marshal(obj, ty=None, **kwargs):
28
34
  GLOBAL_UNMARSHALER_FACTORY = new_standard_unmarshaler_factory()
29
35
 
30
36
 
31
- def unmarshal(v, ty, **kwargs):
37
+ def unmarshal(v: Value, ty: type[T], **kwargs: ta.Any) -> T:
32
38
  uc = UnmarshalContext(GLOBAL_REGISTRY, factory=GLOBAL_UNMARSHALER_FACTORY, **kwargs)
33
39
  return uc.make(ty).unmarshal(uc, v)
@@ -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) -> ta.Optional[Marshaler]:
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) -> ta.Optional[Unmarshaler]:
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
@@ -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) -> ta.Optional[Marshaler]:
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) -> ta.Optional[Unmarshaler]:
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/objects.py CHANGED
@@ -98,8 +98,7 @@ class ObjectUnmarshaler(Unmarshaler):
98
98
  if ukf is not None:
99
99
  ukf[ks] = mv # FIXME: unmarshal?
100
100
  continue
101
- else:
102
- raise
101
+ raise
103
102
  if fi.name in kw:
104
103
  raise KeyError(f'Duplicate keys for field {fi.name!r}: {ks!r}')
105
104
  kw[fi.name] = u.unmarshal(ctx, mv)
@@ -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.Optional[ta.Any]) -> Value:
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) -> ta.Optional[Marshaler]:
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.Optional[ta.Any]:
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) -> ta.Optional[Unmarshaler]:
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
@@ -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.Optional[ta.Any]) -> Value:
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) -> ta.Optional[Marshaler]:
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.Optional[ta.Any]:
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) -> ta.Optional[Unmarshaler]:
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