From ee8a5976c8e4be4a0073b4e89481349753c583f0 Mon Sep 17 00:00:00 2001 From: jakkdl Date: Thu, 25 Jan 2024 15:04:05 +0100 Subject: [PATCH 1/2] add deprecation warning for specifying strict_exception_groups=False --- src/trio/_core/_run.py | 25 ++++++++ src/trio/_core/_tests/test_run.py | 9 +++ ...deprecate_strict_exception_groups_false.py | 61 +++++++++++++++++++ src/trio/_tests/test_subprocess.py | 3 - 4 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 src/trio/_tests/test_deprecate_strict_exception_groups_false.py diff --git a/src/trio/_core/_run.py b/src/trio/_core/_run.py index 7ebfc9cf80..b9b5d42763 100644 --- a/src/trio/_core/_run.py +++ b/src/trio/_core/_run.py @@ -33,6 +33,7 @@ from .. import _core from .._abc import Clock, Instrument +from .._deprecate import warn_deprecated from .._util import NoPublicConstructor, coroutine_or_error, final from ._asyncgens import AsyncGenerators from ._concat_tb import concat_tb @@ -997,6 +998,15 @@ def open_nursery( and ultimately removed in a future version of Trio. """ + # only warn if explicitly set to False, not if we get it from the global context. + if strict_exception_groups is False: + warn_deprecated( + "open_nursery(strict_exception_groups=False)", + version="0.24.1", + issue=2929, + instead="Use the default value of True and rewrite exception handlers to handle ExceptionGroups", + ) + if strict_exception_groups is None: strict_exception_groups = GLOBAL_RUN_CONTEXT.runner.strict_exception_groups @@ -2244,6 +2254,13 @@ def run( propagates it. """ + if strict_exception_groups is False: + warn_deprecated( + "trio.run(..., strict_exception_groups=False)", + version="0.24.1", + issue=2929, + instead="the default value of True and rewrite exception handlers to handle ExceptionGroups", + ) __tracebackhide__ = True @@ -2350,6 +2367,14 @@ def my_done_callback(run_outcome): For the meaning of other arguments, see `trio.run`. """ + if strict_exception_groups is False: + warn_deprecated( + "trio.start_guest_run(..., strict_exception_groups=False)", + version="0.24.1", + issue=2929, + instead="Use the default value of True and rewrite exception handlers to handle ExceptionGroups", + ) + runner = setup_runner( clock, instruments, diff --git a/src/trio/_core/_tests/test_run.py b/src/trio/_core/_tests/test_run.py index b1011a4e1b..034792b35d 100644 --- a/src/trio/_core/_tests/test_run.py +++ b/src/trio/_core/_tests/test_run.py @@ -2551,6 +2551,9 @@ def _create_kwargs(strictness: bool | None) -> dict[str, bool]: return {"strict_exception_groups": strictness} +@pytest.mark.filterwarnings( + "ignore:.*strict_exception_groups=False:trio.TrioDeprecationWarning" +) @pytest.mark.parametrize("run_strict", [True, False, None]) @pytest.mark.parametrize("open_nursery_strict", [True, False, None]) @pytest.mark.parametrize("multiple_exceptions", [True, False]) @@ -2591,6 +2594,9 @@ def run_main() -> None: run_main() +@pytest.mark.filterwarnings( + "ignore:.*strict_exception_groups=False:trio.TrioDeprecationWarning" +) @pytest.mark.parametrize("strict", [True, False, None]) async def test_nursery_collapse(strict: bool | None) -> None: """ @@ -2630,6 +2636,9 @@ async def test_cancel_scope_no_cancellederror() -> None: assert not scope.cancelled_caught +@pytest.mark.filterwarnings( + "ignore:.*strict_exception_groups=False:trio.TrioDeprecationWarning" +) @pytest.mark.parametrize("run_strict", [False, True]) @pytest.mark.parametrize("start_raiser_strict", [False, True, None]) @pytest.mark.parametrize("raise_after_started", [False, True]) diff --git a/src/trio/_tests/test_deprecate_strict_exception_groups_false.py b/src/trio/_tests/test_deprecate_strict_exception_groups_false.py new file mode 100644 index 0000000000..317672bf23 --- /dev/null +++ b/src/trio/_tests/test_deprecate_strict_exception_groups_false.py @@ -0,0 +1,61 @@ +from typing import Awaitable, Callable + +import pytest + +import trio + + +async def test_deprecation_warning_open_nursery() -> None: + with pytest.warns( + trio.TrioDeprecationWarning, match="strict_exception_groups=False" + ) as record: + async with trio.open_nursery(strict_exception_groups=False): + ... + assert len(record) == 1 + async with trio.open_nursery(strict_exception_groups=True): + ... + async with trio.open_nursery(): + ... + + +def test_deprecation_warning_run() -> None: + async def foo() -> None: ... + + async def foo_nursery() -> None: + # this should not raise a warning, even if it's implied loose + async with trio.open_nursery(): + ... + + async def foo_loose_nursery() -> None: + # this should raise a warning, even if specifying the parameter is redundant + async with trio.open_nursery(strict_exception_groups=False): + ... + + def helper(fun: Callable[..., Awaitable[None]], num: int) -> None: + with pytest.warns( + trio.TrioDeprecationWarning, match="strict_exception_groups=False" + ) as record: + trio.run(fun, strict_exception_groups=False) + assert len(record) == num + + helper(foo, 1) + helper(foo_nursery, 1) + helper(foo_loose_nursery, 2) + + +def test_deprecation_warning_start_guest_run() -> None: + # "The simplest possible "host" loop." + from .._core._tests.test_guest_mode import trivial_guest_run + + async def trio_return(in_host: object) -> str: + await trio.lowlevel.checkpoint() + return "ok" + + with pytest.warns( + trio.TrioDeprecationWarning, match="strict_exception_groups=False" + ) as record: + trivial_guest_run( + trio_return, + strict_exception_groups=False, + ) + assert len(record) == 1 diff --git a/src/trio/_tests/test_subprocess.py b/src/trio/_tests/test_subprocess.py index a4f07189e4..0a70e7a974 100644 --- a/src/trio/_tests/test_subprocess.py +++ b/src/trio/_tests/test_subprocess.py @@ -582,9 +582,6 @@ async def do_stuff() -> None: with RaisesGroup(RaisesGroup(Matcher(ValueError, "^foo$"))): _core.run(do_stuff, strict_exception_groups=True) - with pytest.raises(ValueError, match="^foo$"): - _core.run(do_stuff, strict_exception_groups=False) - async def test_warn_on_failed_cancel_terminate(monkeypatch: pytest.MonkeyPatch) -> None: original_terminate = Process.terminate From 06168d2200b917ab2cb6039527234cf9fa7cf6fb Mon Sep 17 00:00:00 2001 From: jakkdl Date: Thu, 1 Feb 2024 13:45:35 +0100 Subject: [PATCH 2/2] fixes after review --- src/trio/_core/_run.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/trio/_core/_run.py b/src/trio/_core/_run.py index b9b5d42763..492f61b50c 100644 --- a/src/trio/_core/_run.py +++ b/src/trio/_core/_run.py @@ -998,13 +998,13 @@ def open_nursery( and ultimately removed in a future version of Trio. """ - # only warn if explicitly set to False, not if we get it from the global context. - if strict_exception_groups is False: + # only warn if explicitly set to falsy, not if we get it from the global context. + if strict_exception_groups is not None and not strict_exception_groups: warn_deprecated( "open_nursery(strict_exception_groups=False)", version="0.24.1", issue=2929, - instead="Use the default value of True and rewrite exception handlers to handle ExceptionGroups", + instead="the default value of True and rewrite exception handlers to handle ExceptionGroups", ) if strict_exception_groups is None: @@ -2254,7 +2254,7 @@ def run( propagates it. """ - if strict_exception_groups is False: + if strict_exception_groups is not None and not strict_exception_groups: warn_deprecated( "trio.run(..., strict_exception_groups=False)", version="0.24.1", @@ -2367,12 +2367,12 @@ def my_done_callback(run_outcome): For the meaning of other arguments, see `trio.run`. """ - if strict_exception_groups is False: + if strict_exception_groups is not None and not strict_exception_groups: warn_deprecated( "trio.start_guest_run(..., strict_exception_groups=False)", version="0.24.1", issue=2929, - instead="Use the default value of True and rewrite exception handlers to handle ExceptionGroups", + instead="the default value of True and rewrite exception handlers to handle ExceptionGroups", ) runner = setup_runner(