Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change strict_exception_groups default to True #2886

Merged
merged 30 commits into from
Jan 22, 2024
Merged
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
cfc0755
change strict_exception_groups default to True
jakkdl Nov 24, 2023
84fb527
get rid of the last vestiges of _assert_raises
jakkdl Nov 24, 2023
c4548bd
Merge remote-tracking branch 'origin/master' into remove_multierror
jakkdl Nov 28, 2023
2437d1e
fix check for @final
jakkdl Nov 28, 2023
dcadc87
add typeguard to ExpectedExceptionGroup.matches
jakkdl Nov 29, 2023
a39732f
update comments/tests where I was confused about lack of ExceptionGro…
jakkdl Dec 11, 2023
669c345
Merge branch 'master' into remove_multierror
CoolCat467 Dec 13, 2023
f7e0b8f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 13, 2023
38f47a5
Fix ruff issues
CoolCat467 Dec 13, 2023
d455a45
Merge remote-tracking branch 'origin/master' into remove_multierror
jakkdl Dec 22, 2023
4232be2
Merge remote-tracking branch 'origin/master' into remove_multierror
jakkdl Jan 7, 2024
5caf49f
replace all instances of ExpectedExceptionGroup with RaisesGroup
jakkdl Jan 7, 2024
f50386c
gone through the whole PR and cleaned it up
jakkdl Jan 7, 2024
5acae48
fix tests: remove stray pytest import
jakkdl Jan 7, 2024
a33bea6
fix coverage
jakkdl Jan 7, 2024
295e5af
proposed fix for run_process raising exceptiongroup
jakkdl Jan 8, 2024
0089248
add test for TrioInternalError from run_process
jakkdl Jan 8, 2024
26a9c62
Apply suggestions from code review
jakkdl Jan 8, 2024
a93a185
rephrase newsfragment, and add rst cross-references
jakkdl Jan 8, 2024
b3d5aa3
update docstrings
jakkdl Jan 8, 2024
c00a05f
add comment with TODO about rewriting strict_exception_groups section
jakkdl Jan 8, 2024
4b393ed
parametrize run/nursery strictness tests
jakkdl Jan 8, 2024
e64d508
revert reraising exceptiongroup as a TrioInternalError, mention that …
jakkdl Jan 11, 2024
0547313
Merge remote-tracking branch 'origin/master' into remove_multierror
jakkdl Jan 11, 2024
22e4765
fix test_run_process_internal_error, add test_bad_deliver_cancel
jakkdl Jan 11, 2024
79754b8
fix docstring
jakkdl Jan 11, 2024
506e211
Merge branch 'master' into remove_multierror
CoolCat467 Jan 19, 2024
ea48cf0
revert accidental removal of empty line
jakkdl Jan 21, 2024
3f519f8
Add a bunch of words to the newsfragment
jakkdl Jan 21, 2024
0b45ec9
Merge remote-tracking branch 'origin/master' into remove_multierror
jakkdl Jan 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
parametrize run/nursery strictness tests
jakkdl committed Jan 8, 2024

Verified

This commit was signed with the committer’s verified signature.
danielleadams Danielle Adams
commit 4b393ed620b3355ce6ef8858843e1bfcc5681c15
112 changes: 44 additions & 68 deletions src/trio/_core/_tests/test_run.py
Original file line number Diff line number Diff line change
@@ -2543,98 +2543,74 @@ async def task() -> None:
assert destroyed


def test_run_strict_exception_groups() -> None:
"""
Test that nurseries respect the global context setting of strict_exception_groups.
"""
def _create_kwargs(strictness: bool | None) -> dict[str, bool]:
"""Turn a bool|None into a kwarg dict that can be passed to `run` or `open_nursery`"""

async def main() -> NoReturn:
async with _core.open_nursery():
raise Exception("foo")

with RaisesGroup(
Matcher(match="^foo$", check=lambda e: type(e) is Exception),
match="^Exceptions from Trio nursery \\(1 sub-exception\\)$",
):
_core.run(main, strict_exception_groups=True)
if strictness is None:
return {}
return {"strict_exception_groups": strictness}


def test_run_strict_exception_groups_nursery_override() -> None:
@pytest.mark.parametrize("run_strict", [True, False, None])
@pytest.mark.parametrize("open_nursery_strict", [True, False, None])
@pytest.mark.parametrize("multiple_exceptions", [True, False])
def test_setting_strict_exception_groups(
run_strict: bool | None, open_nursery_strict: bool | None, multiple_exceptions: bool
) -> None:
"""
Test that a nursery can override the global context setting of
strict_exception_groups.
Test default values and that nurseries can both inherit and override the global context
setting of strict_exception_groups.
"""

async def main() -> NoReturn:
async with _core.open_nursery(strict_exception_groups=False):
raise Exception("foo")

with pytest.raises(Exception, match="^foo$"):
_core.run(main, strict_exception_groups=True)


async def test_nursery_strict_exception_groups() -> None:
"""Test that strict exception groups can be enabled on a per-nursery basis."""
with RaisesGroup(Matcher(match="^foo$", check=lambda e: type(e) is Exception)):
async with _core.open_nursery(strict_exception_groups=True):
raise Exception("foo")


async def test_nursery_loose_exception_groups() -> None:
"""Test that loose exception groups can be enabled on a per-nursery basis."""

async def raise_error() -> NoReturn:
raise RuntimeError("test error")

with pytest.raises(RuntimeError, match="^test error$"):
async with _core.open_nursery(strict_exception_groups=False) as nursery:
nursery.start_soon(raise_error)
m = Matcher(RuntimeError, match="^test error$")

with RaisesGroup(
m,
m,
match="Exceptions from Trio nursery \\(2 sub-exceptions\\)",
check=lambda x: x.__notes__ == [_core._run.NONSTRICT_EXCEPTIONGROUP_NOTE],
):
async with _core.open_nursery(strict_exception_groups=False) as nursery:
nursery.start_soon(raise_error)
async def main() -> None:
"""Open a nursery, and raise one or two errors inside"""
async with _core.open_nursery(**_create_kwargs(open_nursery_strict)) as nursery:
nursery.start_soon(raise_error)
if multiple_exceptions:
nursery.start_soon(raise_error)

def run_main() -> None:
# mypy doesn't like kwarg magic
_core.run(main, **_create_kwargs(run_strict)) # type: ignore[arg-type]

async def test_nursery_collapse_strict() -> None:
"""
Test that a single exception from a nested nursery with strict semantics doesn't get
collapsed when CancelledErrors are stripped from it.
"""
matcher = Matcher(RuntimeError, "^test error$")

async def raise_error() -> NoReturn:
raise RuntimeError("test error")

with RaisesGroup(RuntimeError, RaisesGroup(RuntimeError)):
async with _core.open_nursery() as nursery:
nursery.start_soon(sleep_forever)
nursery.start_soon(raise_error)
async with _core.open_nursery(strict_exception_groups=True) as nursery2:
nursery2.start_soon(sleep_forever)
nursery2.start_soon(raise_error)
nursery.cancel_scope.cancel()
if multiple_exceptions:
with RaisesGroup(matcher, matcher):
run_main()
elif open_nursery_strict or (
open_nursery_strict is None and run_strict is not False
):
with RaisesGroup(matcher):
run_main()
else:
with pytest.raises(RuntimeError, match="^test error$"):
run_main()


async def test_nursery_collapse_loose() -> None:
@pytest.mark.parametrize("strict", [True, False, None])
async def test_nursery_collapse(strict: bool | None) -> None:
"""
Test that a single exception from a nested nursery with loose semantics gets
collapsed when CancelledErrors are stripped from it.
Test that a single exception from a nested nursery gets collapsed correctly
depending on strict_exception_groups value when CancelledErrors are stripped from it.
"""

async def raise_error() -> NoReturn:
raise RuntimeError("test error")

with RaisesGroup(RuntimeError, RuntimeError):
# mypy requires explicit type for conditional expression
maybe_wrapped_runtime_error: type[RuntimeError] | RaisesGroup[RuntimeError] = (
RuntimeError if strict is False else RaisesGroup(RuntimeError)
)

with RaisesGroup(RuntimeError, maybe_wrapped_runtime_error):
async with _core.open_nursery() as nursery:
nursery.start_soon(sleep_forever)
nursery.start_soon(raise_error)
async with _core.open_nursery(strict_exception_groups=False) as nursery2:
async with _core.open_nursery(**_create_kwargs(strict)) as nursery2:
nursery2.start_soon(sleep_forever)
nursery2.start_soon(raise_error)
nursery.cancel_scope.cancel()

Unchanged files with check annotations Beta

async with _core.open_nursery() as nursery:
async def write_forever() -> None:
with pytest.raises(_core.ClosedResourceError) as excinfo:

Check warning on line 99 in src/trio/_tests/test_windows_pipes.py

Codecov / codecov/patch

src/trio/_tests/test_windows_pipes.py#L99

Added line #L99 was not covered by tests
while True:
await w.send_all(b"x" * 4096)
assert "another task" in str(excinfo.value)