Add `never_warn_on: dict` support to unmasker

Such that key->value pairs can be defined which should *never be*
unmasked where values of
- the keys are exc-types which might be masked, and
- the values are exc-types which masked the equivalent key.

For example, the default includes:
- KBI->taskc: a kbi should never be unmasked from its masking
  `trio.Cancelled`.

For the impl, a new `do_warn: bool` in the fn-body determines the
primary guard for whether a warning or re-raising is necessary.
to_asyncio_eoc_signal
Tyler Goodlet 2025-07-28 12:50:06 -04:00
parent 7459a4127c
commit aef306465d
1 changed files with 43 additions and 9 deletions

View File

@ -22,7 +22,10 @@ from __future__ import annotations
from contextlib import ( from contextlib import (
asynccontextmanager as acm, asynccontextmanager as acm,
) )
from typing import TYPE_CHECKING from typing import (
Type,
TYPE_CHECKING,
)
import trio import trio
from tractor.log import get_logger from tractor.log import get_logger
@ -80,9 +83,19 @@ async def maybe_raise_from_masking_exc(
# ^TODO? other cases? # ^TODO? other cases?
), ),
always_warn_on: tuple[BaseException] = ( always_warn_on: tuple[Type[BaseException]] = (
trio.Cancelled, trio.Cancelled,
), ),
# don't ever unmask or warn on any masking pair,
# {<masked-excT-key> -> <masking-excT-value>}
never_warn_on: dict[
Type[BaseException],
Type[BaseException],
] = {
KeyboardInterrupt: trio.Cancelled,
trio.Cancelled: trio.Cancelled,
},
# ^XXX, special case(s) where we warn-log bc likely # ^XXX, special case(s) where we warn-log bc likely
# there will be no operational diff since the exc # there will be no operational diff since the exc
# is always expected to be consumed. # is always expected to be consumed.
@ -144,7 +157,10 @@ async def maybe_raise_from_masking_exc(
maybe_masker=exc_match, maybe_masker=exc_match,
unmask_from=set(unmask_from), unmask_from=set(unmask_from),
): ):
masked.append((exc_ctx, exc_match)) masked.append((
exc_ctx,
exc_match,
))
boxed_maybe_exc.value = exc_match boxed_maybe_exc.value = exc_match
note: str = ( note: str = (
f'\n' f'\n'
@ -156,18 +172,36 @@ async def maybe_raise_from_masking_exc(
f'\n' f'\n'
f'{extra_note}\n' f'{extra_note}\n'
) )
exc_ctx.add_note(note)
if type(exc_match) in always_warn_on: do_warn: bool = (
never_warn_on.get(
type(exc_ctx) # masking type
)
is not
type(exc_match) # masked type
)
if do_warn:
exc_ctx.add_note(note)
if (
do_warn
and
type(exc_match) in always_warn_on
):
log.warning(note) log.warning(note)
if raise_unmasked: if (
do_warn
and
raise_unmasked
):
if len(masked) < 2: if len(masked) < 2:
raise exc_ctx from exc_match raise exc_ctx from exc_match
# ??TODO, see above but, possibly unmasking sub-exc
# entries if there are > 1
# else: # else:
# # ?TODO, see above but, possibly unmasking sub-exc
# # entries if there are > 1
# await pause(shield=True) # await pause(shield=True)
else: else:
raise raise