Accept err-type override in `is_multi_cancelled()`
Such that equivalents of `trio.Cancelled` from other runtimes such as `asyncio.CancelledError` and `subprocess.CalledProcessError` (with a `.returncode == -2`) can be gracefully ignored as needed by the caller. For example this is handy if you want to avoid debug-mode REPL entry on an exception-group full of only some subset of exception types since you expect certain tasks to raise such errors after having been cancelled by a request from some parent supervision sys (some "higher up" `trio.CancelScope`, a remote triggered `ContextCancelled` or just from and OS SIGINT). Impl deats, - offer a new `ignore_nested: set[BaseException]` param which by default we add `trio.Cancelled` to when no other types are provided. - use `ExceptionGroup.subgroup(tuple(ignore_nested)` to filter to egs of the "ignored sub-errors set" and return any such match (instead of `True`). - detail a comment on exclusion case.hilevel_serman
parent
0945631629
commit
350a94f39e
|
@ -1146,19 +1146,51 @@ def unpack_error(
|
||||||
|
|
||||||
|
|
||||||
def is_multi_cancelled(
|
def is_multi_cancelled(
|
||||||
exc: BaseException|BaseExceptionGroup
|
exc: BaseException|BaseExceptionGroup,
|
||||||
) -> bool:
|
|
||||||
|
ignore_nested: set[BaseException] = set(),
|
||||||
|
|
||||||
|
) -> bool|BaseExceptionGroup:
|
||||||
'''
|
'''
|
||||||
Predicate to determine if a possible ``BaseExceptionGroup`` contains
|
Predicate to determine if an `BaseExceptionGroup` only contains
|
||||||
only ``trio.Cancelled`` sub-exceptions (and is likely the result of
|
some (maybe nested) set of sub-grouped exceptions (like only
|
||||||
cancelling a collection of subtasks.
|
`trio.Cancelled`s which get swallowed silently by default) and is
|
||||||
|
thus the result of "gracefully cancelling" a collection of
|
||||||
|
sub-tasks (or other conc primitives) and receiving a "cancelled
|
||||||
|
ACK" from each after termination.
|
||||||
|
|
||||||
|
Docs:
|
||||||
|
----
|
||||||
|
- https://docs.python.org/3/library/exceptions.html#exception-groups
|
||||||
|
- https://docs.python.org/3/library/exceptions.html#BaseExceptionGroup.subgroup
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
if (
|
||||||
|
not ignore_nested
|
||||||
|
or
|
||||||
|
trio.Cancelled in ignore_nested
|
||||||
|
# XXX always count-in `trio`'s native signal
|
||||||
|
):
|
||||||
|
ignore_nested |= {trio.Cancelled}
|
||||||
|
|
||||||
if isinstance(exc, BaseExceptionGroup):
|
if isinstance(exc, BaseExceptionGroup):
|
||||||
return exc.subgroup(
|
matched_exc: BaseExceptionGroup|None = exc.subgroup(
|
||||||
lambda exc: isinstance(exc, trio.Cancelled)
|
tuple(ignore_nested),
|
||||||
) is not None
|
|
||||||
|
|
||||||
|
# TODO, complain about why not allowed XD
|
||||||
|
# condition=tuple(ignore_nested),
|
||||||
|
)
|
||||||
|
if matched_exc is not None:
|
||||||
|
return matched_exc
|
||||||
|
|
||||||
|
# NOTE, IFF no excs types match (throughout the error-tree)
|
||||||
|
# -> return `False`, OW return the matched sub-eg.
|
||||||
|
#
|
||||||
|
# IOW, for the inverse of ^ for the purpose of
|
||||||
|
# maybe-enter-REPL--logic: "only debug when the err-tree contains
|
||||||
|
# at least one exc-type NOT in `ignore_nested`" ; i.e. the case where
|
||||||
|
# we fallthrough and return `False` here.
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue