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

first draft of handling marker exceptions wrapped in exceptiongroup #4110

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jakkdl
Copy link

@jakkdl jakkdl commented Sep 19, 2024

I have barely used Hypothesis, and never worked with the codebase, so there are several gaps in code coverage and question marks on implementation decisions. If somebody more familiar wants to take a quick pass and opine it'd be very helpful :)

I can get code coverage by manually raising the specific ExceptionGroups that'll trigger the different branches, but it'd likely be better to do the actual things that causes those exceptions. So would likewise appreciate quick pointers on how to, if at all possible, cause e.g. multiple StopTest, multiple Frozen, a single Frozen, etc.

fixes #4106

Copy link
Contributor

@jobh jobh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice, thanks! 👍

I think most of the build errors will go away with some of the minor commented changes, the remaining will hopefully be manageable :-)

Comment on lines +152 to +153
if sys.version_info < (3, 11):
from exceptiongroup import ExceptionGroup
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if sys.version_info < (3, 11):
from exceptiongroup import ExceptionGroup
from hypothesis.internal.compat import BaseExceptionGroup

# multiple frozen exceptions
# TODO: raise a group? The first one? None of them?
raise frozen_exceptions[0] from excgroup

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, the semantics here (generally) are a good question.

I'd opine:

  • If all exceptions are Frozen, raise the first (as above).
  • Else, if exactly one exception is non-Frozen, raise that one [*].
  • Otherwise, reconstruct and raise a group with just the non-frozen ones (maybe .with_traceback(eg.__traceback__)).

[*] hm, I see, that would cause an undesired unwrapping if user code raises a single-exception ExceptionGroup. Maybe the second step should be "if exactly one ... and that exception is a StopException or HypothesisException.

def test_single_exc_group(data):
raise ExceptionGroup("important message for user", [ValueError()])

with RaisesGroup(ValueError, match="important message for user"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd just catch BaseExceptionGroup (via hypothesis.internal.compat.BaseExceptionGroup) and check the subexceptions explicitly, to avoid the trio dependency.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ye that's probably the way to go. I'm incredibly biased on the matter as the person who wrote trio.testing.RaisesGroup and is trying to get it added to pytest 😇

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(and as a dual maintainer of Pytest and Trio, among other things, I'm pretty keen to support that when I have time 😅)

@jobh
Copy link
Contributor

jobh commented Sep 19, 2024

I can get code coverage by manually raising the specific ExceptionGroups that'll trigger the different branches, but it'd likely be better to do the actual things that causes those exceptions. So would likewise appreciate quick pointers on how to, if at all possible, cause e.g. multiple StopTest, multiple Frozen, a single Frozen, etc.

It should be possible to provoke most of these situations by playing around with multiple tasks failing in different ways. But I think it's fine to create the non-obvious situations explicitly, too.

@jobh
Copy link
Contributor

jobh commented Sep 19, 2024

It should be possible to provoke most of these situations by playing around with multiple tasks failing in different ways. But I think it's fine to create the non-obvious situations explicitly, too.

Sorry: "most" should probably be replaced by "some" 😁

@jobh
Copy link
Contributor

jobh commented Sep 19, 2024

Oh, and one other tip: hypothesis will transform/trim the tracebacks by default, which may be confusing sometimes when working on exceptions and not seeing what you'd expect. See get_trimmed_traceback().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Our internals should handle StopTest and other marker exceptions even when wrapped in an ExceptionGroup
3 participants