Various test tweaks related to 3.13 egs

Including changes like,
- loose eg flagging in various test emedded `trio.open_nursery()`s.
- changes to eg handling (like using `except*`).
- added `debug_mode` integration to tests that needed some REPLin
  in order to figure out appropriate updates.
py313_support
Tyler Goodlet 2025-03-03 12:24:29 -05:00
parent 387f989c05
commit b048ad893b
12 changed files with 60 additions and 36 deletions

View File

@ -62,7 +62,9 @@ async def recv_and_spawn_net_killers(
await ctx.started() await ctx.started()
async with ( async with (
ctx.open_stream() as stream, ctx.open_stream() as stream,
trio.open_nursery() as n, trio.open_nursery(
strict_exception_groups=False,
) as tn,
): ):
async for i in stream: async for i in stream:
print(f'child echoing {i}') print(f'child echoing {i}')
@ -77,11 +79,11 @@ async def recv_and_spawn_net_killers(
i >= break_ipc_after i >= break_ipc_after
): ):
broke_ipc = True broke_ipc = True
n.start_soon( tn.start_soon(
iter_ipc_stream, iter_ipc_stream,
stream, stream,
) )
n.start_soon( tn.start_soon(
partial( partial(
break_ipc_then_error, break_ipc_then_error,
stream=stream, stream=stream,

View File

@ -21,11 +21,13 @@ async def name_error():
async def main(): async def main():
"""Test breakpoint in a streaming actor. '''
""" Test breakpoint in a streaming actor.
'''
async with tractor.open_nursery( async with tractor.open_nursery(
debug_mode=True, debug_mode=True,
# loglevel='cancel', loglevel='cancel',
# loglevel='devx', # loglevel='devx',
) as n: ) as n:

View File

@ -40,7 +40,7 @@ async def main():
""" """
async with tractor.open_nursery( async with tractor.open_nursery(
debug_mode=True, debug_mode=True,
# loglevel='cancel', loglevel='devx',
) as n: ) as n:
# spawn both actors # spawn both actors

View File

@ -91,7 +91,7 @@ async def main() -> list[int]:
an: ActorNursery an: ActorNursery
async with tractor.open_nursery( async with tractor.open_nursery(
loglevel='cancel', loglevel='cancel',
debug_mode=True, # debug_mode=True,
) as an: ) as an:
seed = int(1e3) seed = int(1e3)

View File

@ -309,10 +309,13 @@ def test_subactor_breakpoint(
child.expect(EOF) child.expect(EOF)
assert in_prompt_msg( assert in_prompt_msg(
child, child, [
['RemoteActorError:', 'MessagingError:',
'RemoteActorError:',
"('breakpoint_forever'", "('breakpoint_forever'",
'bdb.BdbQuit',] 'bdb.BdbQuit',
],
pause_on_false=True,
) )

View File

@ -3,7 +3,6 @@ Sketchy network blackoutz, ugly byzantine gens, puedes eschuchar la
cancelacion?.. cancelacion?..
''' '''
import itertools
from functools import partial from functools import partial
from types import ModuleType from types import ModuleType
@ -230,13 +229,10 @@ def test_ipc_channel_break_during_stream(
# get raw instance from pytest wrapper # get raw instance from pytest wrapper
value = excinfo.value value = excinfo.value
if isinstance(value, ExceptionGroup): if isinstance(value, ExceptionGroup):
value = next( excs = value.exceptions
itertools.dropwhile( assert len(excs) == 1
lambda exc: not isinstance(exc, expect_final_exc), final_exc = excs[0]
value.exceptions, assert isinstance(final_exc, expect_final_exc)
)
)
assert value
@tractor.context @tractor.context

View File

@ -307,7 +307,15 @@ async def inf_streamer(
async with ( async with (
ctx.open_stream() as stream, ctx.open_stream() as stream,
trio.open_nursery() as tn,
# XXX TODO, INTERESTING CASE!!
# - if we don't collapse the eg then the embedded
# `trio.EndOfChannel` doesn't propagate directly to the above
# .open_stream() parent, resulting in it also raising instead
# of gracefully absorbing as normal.. so how to handle?
trio.open_nursery(
strict_exception_groups=False,
) as tn,
): ):
async def close_stream_on_sentinel(): async def close_stream_on_sentinel():
async for msg in stream: async for msg in stream:

View File

@ -519,7 +519,9 @@ def test_cancel_via_SIGINT_other_task(
async def main(): async def main():
# should never timeout since SIGINT should cancel the current program # should never timeout since SIGINT should cancel the current program
with trio.fail_after(timeout): with trio.fail_after(timeout):
async with trio.open_nursery() as n: async with trio.open_nursery(
strict_exception_groups=False,
) as n:
await n.start(spawn_and_sleep_forever) await n.start(spawn_and_sleep_forever)
if 'mp' in spawn_backend: if 'mp' in spawn_backend:
time.sleep(0.1) time.sleep(0.1)
@ -612,6 +614,12 @@ def test_fast_graceful_cancel_when_spawn_task_in_soft_proc_wait_for_daemon(
nurse.start_soon(delayed_kbi) nurse.start_soon(delayed_kbi)
await p.run(do_nuthin) await p.run(do_nuthin)
# need to explicitly re-raise the lone kbi..now
except* KeyboardInterrupt as kbi_eg:
assert (len(excs := kbi_eg.exceptions) == 1)
raise excs[0]
finally: finally:
duration = time.time() - start duration = time.time() - start
if duration > timeout: if duration > timeout:

View File

@ -874,13 +874,13 @@ def chk_pld_type(
return roundtrip return roundtrip
def test_limit_msgspec(): def test_limit_msgspec(
debug_mode: bool,
):
async def main(): async def main():
async with tractor.open_root_actor( async with tractor.open_root_actor(
debug_mode=True debug_mode=debug_mode,
): ):
# ensure we can round-trip a boxing `PayloadMsg` # ensure we can round-trip a boxing `PayloadMsg`
assert chk_pld_type( assert chk_pld_type(
payload_spec=Any, payload_spec=Any,

View File

@ -95,8 +95,8 @@ async def trio_main(
# stash a "service nursery" as "actor local" (aka a Python global) # stash a "service nursery" as "actor local" (aka a Python global)
global _nursery global _nursery
n = _nursery tn = _nursery
assert n assert tn
async def consume_stream(): async def consume_stream():
async with wrapper_mngr() as stream: async with wrapper_mngr() as stream:
@ -104,10 +104,10 @@ async def trio_main(
print(msg) print(msg)
# run 2 tasks to ensure broadcaster chan use # run 2 tasks to ensure broadcaster chan use
n.start_soon(consume_stream) tn.start_soon(consume_stream)
n.start_soon(consume_stream) tn.start_soon(consume_stream)
n.start_soon(trio_sleep_and_err) tn.start_soon(trio_sleep_and_err)
await trio.sleep_forever() await trio.sleep_forever()
@ -119,8 +119,8 @@ async def open_actor_local_nursery(
global _nursery global _nursery
async with trio.open_nursery( async with trio.open_nursery(
strict_exception_groups=False, strict_exception_groups=False,
) as n: ) as tn:
_nursery = n _nursery = tn
await ctx.started() await ctx.started()
await trio.sleep(10) await trio.sleep(10)
# await trio.sleep(1) # await trio.sleep(1)
@ -134,7 +134,7 @@ async def open_actor_local_nursery(
# never yields back.. aka a scenario where the # never yields back.. aka a scenario where the
# ``tractor.context`` task IS NOT in the service n's cancel # ``tractor.context`` task IS NOT in the service n's cancel
# scope. # scope.
n.cancel_scope.cancel() tn.cancel_scope.cancel()
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -159,7 +159,7 @@ def test_actor_managed_trio_nursery_task_error_cancels_aio(
async with tractor.open_nursery() as n: async with tractor.open_nursery() as n:
p = await n.start_actor( p = await n.start_actor(
'nursery_mngr', 'nursery_mngr',
infect_asyncio=asyncio_mode, infect_asyncio=asyncio_mode, # TODO, is this enabling debug mode?
enable_modules=[__name__], enable_modules=[__name__],
) )
async with ( async with (

View File

@ -181,7 +181,9 @@ async def spawn_and_check_registry(
try: try:
async with tractor.open_nursery() as n: async with tractor.open_nursery() as n:
async with trio.open_nursery() as trion: async with trio.open_nursery(
strict_exception_groups=False,
) as trion:
portals = {} portals = {}
for i in range(3): for i in range(3):

View File

@ -101,6 +101,7 @@ def test_stashed_child_nursery(use_start_soon):
def test_acm_embedded_nursery_propagates_enter_err( def test_acm_embedded_nursery_propagates_enter_err(
canc_from_finally: bool, canc_from_finally: bool,
unmask_from_canc: bool, unmask_from_canc: bool,
debug_mode: bool,
): ):
''' '''
Demo how a masking `trio.Cancelled` could be handled by unmasking from the Demo how a masking `trio.Cancelled` could be handled by unmasking from the
@ -174,7 +175,9 @@ def test_acm_embedded_nursery_propagates_enter_err(
await trio.lowlevel.checkpoint() await trio.lowlevel.checkpoint()
async def _main(): async def _main():
with tractor.devx.open_crash_handler() as bxerr: with tractor.devx.maybe_open_crash_handler(
pdb=debug_mode,
) as bxerr:
assert not bxerr.value assert not bxerr.value
async with ( async with (