Skip to content

Remove sys.last_traceback attribute using del instead of setting to None #6256

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

Merged
merged 6 commits into from
Nov 21, 2019

Conversation

mdickinson
Copy link
Contributor

Existing code in the test runner clears the sys.last_traceback, sys.last_type and sys.last_exc attributes by setting them to None. This PR changes that code to delete these attributes using del instead.

Rationale:

  • In the (presumably common and desirable) case that there were no exceptions, this ensures that the state of this particular part of sys module is unchanged by the test run. (Going from the attribute not existing to it existing but being None is a change, albeit a fairly benign one.)
  • This better matches the behaviour of the Python standard library: in the (very) few places where CPython clears these attributes, it uses del.
  • In general, we want to restrict the possible states of sys.last_traceback (for example) to just two: either the attribute doesn't exist, or it does exist and it's a genuine traceback. Allowing None introduces a new third possible state that any user of sys.last_traceback needs to be aware of.

Fixes #6255.

@mdickinson
Copy link
Contributor Author

Looks like the Travis CI failure is a result of the py:attr markup. I'll remove that and replace with the usual double backticks.

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

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

Thanks a lot @mdickinson!

@nicoddemus nicoddemus merged commit f1ac0ee into pytest-dev:master Nov 21, 2019
@mdickinson mdickinson deleted the del-sys-last-traceback branch November 21, 2019 14:44
@blueyed
Copy link
Contributor

blueyed commented Feb 3, 2020

@mdickinson
I can see that it makes sense to not use None. Thanks for fixing this!

What do you think about not deleting it though? I.e. it would always contain the last exception that occurred, which can be useful with pdb.pm() etc.
I can also see that having them deleted is better for a clean test env, so I am curious what you think.

@blueyed blueyed added type: enhancement new feature or API change, should be merged into features branch type: bug problem that needs to be addressed and removed type: enhancement new feature or API change, should be merged into features branch labels Feb 3, 2020
@mdickinson
Copy link
Contributor Author

mdickinson commented Feb 9, 2020

@blueyed I'm not sure: personally, I think I prefer the deletion.

At work, we have quite a lot of large (>1000 individual test methods) test suites that take some time to run (e.g., 20 minutes or more). In that situation, test interactions are one of the most costly problems: if a test passes fine by itself, but fails in the context of the larger test suite, it can take hours to track down the interactions that are causing it to fail.

And one of the key ingredients in avoiding test interactions is ensuring that tests don't modify shared global state; or at least that if they do modify that state, then they restore it to its previous state before the test ends. (And the sys.last_* attributes count as shared global state, of course; it was a test interaction that led me to make this PR in the first place.)

So on the one hand, if a test runner helps reset state changes, that's helpful. On the other hand, in a well-written test those state changes shouldn't be happening in the first place, so as a developer I'd quite like some kind of warning about those state changes so that I can fix the test. The core Python test runner (python -m test, not python -m unittest) does this for example, warning about changes to logging state, warnings filters, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug problem that needs to be addressed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Suggestion: reset sys.last_traceback using del rather than setting to None
4 participants