1from asyncutils._internal import helpers as H, patch as P
2from asyncutils._internal.submodules import exceptions_all as __all__
3from sys import audit, exception
4CRITICAL = SystemExit, SystemError, KeyboardInterrupt
5def _unnest(f, g, h, s, /, *, raise_critical=True, keep=Exception, filter_out=(), predicate=lambda _, /: True, ack1=(a := lambda _, /: None), ack2=a, ack3=a, _=audit): # noqa: PLR0913
6 _('asyncutils.exceptions.unnest'+'_reverse'*isinstance(s, list), len(s))
7 while s:
8 if isinstance(group := f(), BaseExceptionGroup): g(group.exceptions)
9 elif raise_critical and isinstance(group, CRITICAL): raise Critical(group)
10 elif isinstance(group, keep):
11 if isinstance(group, filter_out): ack1(group)
12 elif not predicate(group): ack2(group)
13 elif (y := (yield group)) is not None: h(y)
14 else: ack3(group)
[docs]
15def unnest(g, /, *A, d=__import__('_collections').deque, h=_unnest, **k): (s := d(g.exceptions)).extend(A) if isinstance(g, BaseExceptionGroup) else (s := d(A)).appendleft(g); return h(s.popleft, lambda e, g=s.extendleft: g(reversed(e)), s.appendleft, s, **k)
[docs]
16def unnest_reverse(g, /, *A, h=_unnest, **k): (g := (s := list(g.exceptions) if isinstance(g, BaseExceptionGroup) else [g]).extend)(A); return h(s.pop, g, s.append, s, **k)
[docs]
17def potent_derive(*G, ordered=False, **k):
18 n = (P := lambda _, p=(p := k.pop): p(_, None))('notes')
19 if not isinstance(g := G[0], BaseExceptionGroup): _ = p('suppress', False), *map(P, ('context', 'cause', 'traceback')); (g := BaseExceptionGroup(p('message'), tuple((unnest if ordered else unnest_reverse)(*G, **k)))).__suppress_context__, g.__context__, g.__cause__, g.__traceback__ = _
20 if n is None: ...
21 elif isinstance(n, str): g.add_note(n)
22 elif (N := getattr(g, '__notes__', None)) is None: g.__notes__ = list(n)
23 else: N.extend(n)
24 return g
[docs]
25def prepare_exception(e, /, *, traceback=None, cause=None, context=None, suppress=False, notes=(), _=exception):
26 if not isinstance(e, BaseException): raise TypeError(f'cannot prepare non-exception: {e!r}')
27 if isinstance(notes, str): e.add_note(notes)
28 elif (n := getattr(e, '__notes__', None)) is None: e.__notes__ = list(notes)
29 else: n.extend(notes)
30 if cause is None is e.__context__: e.__context__ = context or _()
31 else: e.__cause__ = cause
32 e.__suppress_context__, e.__traceback__ = suppress, traceback; return e
[docs]
33def raise_exc(e, /, *a, traceback=None, cause=None, context=None, suppress=False, notes=(), _a_=audit, **k):
34 if isinstance(e, type): e = e(*a, **k)
35 elif a or k: raise TypeError('asyncutils.exceptions.raise_exc: no additional arguments were expected\n')
36 _a_('asyncutils.exceptions.raise_exc', e := prepare_exception(e, traceback=traceback, cause=cause, context=context, suppress=suppress, notes=notes)); raise e
37P.patch_function_signatures((unnest, s := 'group, /, *additional, raise_critical=True, keep={0}, filter_out=(), predicate={0}, ack1={0}, ack2={0}, ack3={0}'), (unnest_reverse, s), (prepare_exception, 'exc, /, *, traceback=None, cause=None, context=None, suppress=False, notes=()'), (raise_exc, 'exc, /, *args, traceback=None, cause=None, suppress=False, notes=(), **kwds'), (potent_derive, 'group, /, *groups, message={0}, ordered=False, predicate={0}, raise_critical=True, keep={0}, filter_out=(), predicate={0}, ack1={0}, ack2={0}, ack3={0}, notes=None, traceback=None, context=None, cause=None, suppress=False'))
38class ExceptionWrapper:
39 __slots__ = '__exc',
40 def __new__(cls, e, /):
41 if isinstance(e, CRITICAL): raise e
42 (s := super().__new__(cls)).__exc = e; return s
43 def __getattr__(self, n, /): return getattr(self.__exc, n)
44 def __repr__(self): return f'ExceptionWrapper({self.__exc!r})'
45 def __init_subclass__(cls): raise TypeError('cannot subclass the type of proxies to exceptions')
46exception_occurred, wrap_exc, unwrap_exc = ExceptionWrapper.__instancecheck__, ExceptionWrapper.__new__.__get__(ExceptionWrapper), ExceptionWrapper._ExceptionWrapper__exc.__get__ # ty: ignore[unresolved-attribute]
47@H.subscriptable
48class ref: # noqa: N801
49 __slots__ = '__o',
50 def __new__(cls, obj, r=__import__('_weakref').ref):
51 if isinstance(obj, (cls, r)): return obj
52 try: return r(obj)
53 except TypeError: (_ := object.__new__(cls)).__o = obj; return _
54 def __call__(self): return self.__o # ty: ignore[unresolved-attribute]
55 def __init_subclass__(cls): raise TypeError('cannot subclass asyncutils.exceptions.ref')
[docs]
56@H.subscriptable
57class Critical(BaseException):
58 def __init__(self, e=None, /, _m='critical error occurred or user attempted to terminate the program', _e=exception): super().__init__(_m); self.__context__ = e.__context__ if isinstance(e, __class__) else _e() if e is None else e
59 @property
60 def __suppress_context__(self): return False # noqa: PLW3201
61 @property
62 def exc(self): return self.__cause__ or self.__context__
[docs]
63class StateCorrupted(BaseException):
64 def __init__(self, a, d, /): self.adjective, self.details = a, d; super().__init__(f'asyncutils: user tampered with {a} state; {d}')
[docs]
65class VersionError(Exception): ...
66for A, B in (('obj', '_ro'), ('normalizer', '_rn'), ('exc', '_re')):
67 def _(self, a=A, b=B, f=H.fullname):
68 if (r := getattr(self, b, None)) is None: raise AttributeError(f'object of type {f(self)!r} has no attribute {a!r}')
69 if isinstance(r, ref) and (r := r()) is None: raise RuntimeError(f'{a} has been garbage collected')
70 return r
71 _.__name__, _.__qualname__ = A, f'VersionError.{A}'; setattr(VersionError, A, property(_))
[docs]
72class VersionConversionError(VersionError): ...
[docs]
73class VersionValueError(VersionConversionError, ValueError): ...
[docs]
74@H.subscriptable
75class VersionNormalizerMissing(VersionConversionError, TypeError):
76 def __init__(self, o, /, _='attempt to normalize object {0!r} of type {0.__class__.__qualname__!r} failed since a normalizer has not been registered'.format): self._ro = ref(o); super().__init__(_(o))
77 P.patch_method_signatures((__init__, 'obj, /'))
[docs]
78@H.subscriptable
79class VersionNormalizerTypeError(VersionConversionError, TypeError):
80 def __init__(self, /, *a, _='custom normalizer {0!r} for type {1.__class__.__qualname__!r} did not return an iterable of ints as expected when handling {1!r}'.format): self._rn, self._ro = map(ref, a); super().__init__(_(*a))
81 P.patch_method_signatures((__init__, 'normalizer, obj, /'))
[docs]
82@H.subscriptable
83class VersionNormalizerFault(VersionConversionError):
84 def __init__(self, /, *a, _='custom normalizer {0!r} for type {1.__class__.__qualname__!r} threw {2.__class__.__qualname__} when passed {1!r}'.format): self._rn, self._ro, self._re = map(ref, a); super().__init__(_(*a))
85 P.patch_method_signatures((__init__, 'normalizer, obj, exc, /'))
[docs]
86class VersionCorrupted(VersionError, RuntimeError):
87 def __init__(self, o, /, _='instance of %s at %#x was tampered with by the user (parts: %r; should be a tuple of 3 positive integers)'): self._ro = ref(o); super().__init__(_%(type(o).__qualname__, id(o), getattr(o, 'parts', '<not present>')))
[docs]
88 def __getattr__(self, n, /): return getattr(self.obj, n)
89 P.patch_method_signatures((__init__, 'obj, /'))
[docs]
90class Deadlock(BaseException): ...
[docs]
92class BulkheadFull(BulkheadError): ...
[docs]
93class BulkheadShutDown(BulkheadError): ...
[docs]
94class PoolError(RuntimeError): ...
[docs]
95class PoolFull(PoolError): ...
[docs]
96class PoolShutDown(PoolError): ...
[docs]
97class ResourceBusy(RuntimeError): ...
[docs]
98class MoreThanOne(ValueError):
99 def __init__(self, i, m, /): self.it = i; super().__init__(m)
[docs]
100class BusError(Exception): ...
[docs]
101class BusTimeout(BusError, TimeoutError): ...
[docs]
102class BusShutDown(BusError): ...
[docs]
103class BusStatsError(BusError): ...
[docs]
104class BusPublishingError(BusError):
105 def __init__(self, /, *a, _='{.name}: severe error in middleware {!r}'.format): self._rb, self._rm = map(ref, a); super().__init__(_(*a))
106 @property
107 def bus(self): return self._rb()
108 @property
109 def middleware(self): return self._rm()
110 P.patch_method_signatures((__init__, 'bus, mw, /'))
[docs]
111class CircuitBreakerError(RuntimeError): ...
[docs]
112class CircuitHalfOpen(CircuitBreakerError): ...
[docs]
113class CircuitOpen(CircuitBreakerError): ...
[docs]
114class EventValueError(ValueError): ...
[docs]
115class FutureCorrupted(RuntimeError): ...
[docs]
116class MaxIterationsError(RuntimeError): ...
[docs]
117class ItemsExhausted(ValueError): ...
[docs]
118class RateLimitExceeded(RuntimeError):
119 def __init__(self, f, a, k, c, p, l, /): self.__f, self.__a, self.__k = f, a, k; super().__init__(f'rate limit of {c} calls in {p} periods exceeded by {l} calls when calling {f!r}')
[docs]
120 async def repeat_call(self): return await self.__f(*self.__a, **self.__k)
[docs]
121class LockForceRequest(BaseException):
122 def __init__(self, s, a, l, i, /): self.requester, self.fulfil, self.lock, self.info = s, a, l, i; super().__init__(f'request from {type(s).__qualname__} to release {type(l).__qualname__}'); self.add_note(str(i))
[docs]
123class PasswordQueueError(Exception): ...
[docs]
124class PasswordRetrievalError(PasswordQueueError):
125 def __init__(self, from_): self.from_ = from_; super().__init__(f'failed to retrieve correct password of password-protected queue from closure variable of name {from_!r}')
[docs]
126class GetPasswordRetrievalError(PasswordRetrievalError): ...
[docs]
127class PutPasswordRetrievalError(PasswordRetrievalError): ...
[docs]
128class ForbiddenOperation(PasswordQueueError, TypeError):
129 def __init__(self, op, *a): self.op = op = op%a; super().__init__(f'cannot {op} the type of password-protected queue')
[docs]
130@H.subscriptable
131class PasswordError(PasswordQueueError):
132 @property
133 def wrong_pwd(self): return self._rp() # ty: ignore[unresolved-attribute]
[docs]
134class WrongPassword(PasswordError, ValueError):
135 def __init__(self, q, p, /, _='failure to modify queue because %r received incorrect password: %r'): self.qid, self._rp = id(q), ref(p); super().__init__(_%(q, p))
[docs]
136class WrongPasswordType(PasswordError, TypeError):
137 def __init__(self, q, *a, _='{!r} received password {!r} of wrong type {.__qualname__!r}; should be {!r}'.format): self.qid, self._rp, self._rt, self._rc = id(q), *map(ref, a); super().__init__(_(q, *a))
138 @property
139 def wrong_type(self): return self._rt()
140 @property
141 def correct_type(self): return self._rc()
[docs]
142class PasswordMissing(PasswordQueueError, TypeError):
143 def __init__(self): raise TypeError('asyncutils.exceptions.PasswordMissing: use GetPasswordMissing or PutPasswordMissing instead')
144 def __init_subclass__(cls, *, m): cls.__init__ = lambda self, _=m: BaseException.__init__(self, _) # ty: ignore[invalid-assignment]
[docs]
145class GetPasswordMissing(PasswordMissing, m='asyncutils.queues.password_queue: no password provided when trying to get from password-protected queue'): ...
[docs]
146class PutPasswordMissing(PasswordMissing, m='asyncutils.queues.password_queue: no password provided when trying to put to password-protected queue'): ...
[docs]
147class IgnoreErrors:
148 __slots__ = 'but', 'exc'
149 def __init__(self, /, *_, exclude=(), d=(Exception,)): a, b = map(frozenset, (_ or d, exclude)); a, b = a-b, b-a; self.exc, self.but = map(tuple, (a, (c for c in b if any(d in a for d in c.__mro__))))
[docs]
150 def __enter__(self): return self
[docs]
151 def __exit__(self, t, /, *_): return False if t is None else issubclass(t, self.exc) and not issubclass(t, self.but)
152 def __repr__(self): return f'IgnoreErrors{self.exc!r}.excluding{self.but!r}'
[docs]
153 async def __aenter__(self): return self
[docs]
154 async def __aexit__(self, /, *_): return self.__exit__(*_)
[docs]
155 def excluding(self, *O, _=__import__('itertools').chain): return type(self)(*self.exc, exclude=_(self.but, O))
[docs]
156 def combined(self, *O, _=H.check_methods):
157 f, g, h, j, p = (S := set(self.exc)).update, (P := set(self.but)).update, S.add, (d := []).extend, d.pop
158 for o in O:
159 if isinstance(o, IgnoreErrors): f(o.exc); g(o.but)
160 elif isinstance(o, type): h(o)
161 elif _(o, '__iter__'): j(o)
162 while d:
163 if isinstance(o := p(), type): h(o)
164 else: f(o.exc); g(o.but)
165 return type(self)(*S, exclude=P)
166 P.patch_method_signatures((__init__, '*exc, exclude=()'), (excluding, r := '*others'), (combined, r), (__exit__, P.exit_sig), (__aexit__, P.exit_sig)); del r
167ignore_noncritical, ignore_typical = (ignore_all := IgnoreErrors(BaseException)).excluding(*CRITICAL), IgnoreErrors()
168ignore_stop_iteration, ignore_stop_async_iteration, ignore_valerrs, ignore_typeerrs, ignore_warnings = map(IgnoreErrors, (StopIteration, StopAsyncIteration, ValueError, TypeError, Warning))
[docs]
169class WarningToError:
170 __slots__ = '__cm', '__w'
171 def __init__(self, /, *_): self.__w, self.__cm = _ or (Warning,), None
[docs]
172 def __enter__(self): self.__cm = c = __import__('warnings').catch_warnings(action='error', category=self.__w); c.__enter__(); return self
[docs]
173 def __exit__(self, t, /, *_):
174 if (c := self.__cm) is None: raise RuntimeError('asyncutils.exceptions.WarningToError: __exit__ called without prior __enter__ call')
175 c.__exit__(t, *_)
[docs]
176 async def __aenter__(self): return self.__enter__()
[docs]
177 async def __aexit__(self, /, *_): self.__exit__(*_)
178 P.patch_method_signatures((__enter__, ''), (__aenter__, ''), (__exit__, P.exit_sig), (__aexit__, P.exit_sig))
179del P, s, _, A, B, H, ExceptionWrapper, _unnest, audit, exception