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

Fix test_exceptions_dont_leak in Python 3.12 #535

Merged
merged 1 commit into from
Jan 6, 2024

Conversation

nicoddemus
Copy link
Member

I wonder if clearing it is the right call, after all the purpose of sys.last_exc is for post-mortem debugging -- however I'm not sure that at that point is possible to breakpoint at that point.

Fixes #532

@@ -65,6 +65,8 @@ def fail_if_exceptions_occurred(self, when):
prefix = "%s ERROR: " % when
msg = prefix + format_captured_exceptions(exceptions)
del exceptions[:] # Don't keep exceptions alive longer.
if hasattr(sys, "last_exc"):
sys.last_exc = None
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is correct... 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

Can you elaborate?

Copy link
Member

Choose a reason for hiding this comment

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

I think it's intentional now in 3.12 that this last_exc exists. Perhaps it would be better to raise another exception without a reference to the widget in the test instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ahh yes, I wondered the same thing -- see the PR description.

However the problem is not that the exception references the widget, but that the exception references the traceback, which in turn references the locals, which contains a reference to the widget.

That was reported originally in #187.

Perhaps we should update the test to ensure the internal exceptions are cleared, but it seems now the "leak" will happen because of Python, not because of pytest-qt.

Copy link
Member Author

Choose a reason for hiding this comment

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

Will sleep on it, meanwhile suggestions are welcome. 👍

Choose a reason for hiding this comment

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

I've been thinking about this, and it seems that clearing sys.last_exc is probably OK. This is only done in the context of reporting that a test failed with an exception, and then clearing the exception information before the next test is performed. So clearing sys.last_exc as well would make sense. If there is some context in which preserving this might be wanted, there is a clunky way to do it: have a pytest marker saying save_last_exc, and don't clear the exception if that is set. But my guess is that any developer knowledgeable enough to use the Python debugger to understand why a test has failed with an exception has been triggered will be able to insert a breakpoint before this line and trace from there.

Alternatively, if it doesn't matter that the object remains accessible just through this sys.last_exc reference, then this code could be left unaltered and just drop the failing test.

@nicoddemus
Copy link
Member Author

Thought about this some more, I think this is fine because we are clearing the attribute past the lifetime of the test, so it should be fine and goes with the purpose of the original issue of avoiding leaking data from one test to another.

We can revisit this if it proves problematic in the future.

Thanks everyone for chiming in. 👍

@nicoddemus nicoddemus merged commit ed5668a into pytest-dev:master Jan 6, 2024
60 checks passed
@nicoddemus nicoddemus deleted the clear-sys-exc-532 branch January 6, 2024 10:28
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.

test_exceptions_dont_leak fails with Python 3.12
3 participants