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(