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

Call cleanup functions if explicit teardown is needed #7049

Closed
wants to merge 1 commit into from

Conversation

scorphus
Copy link

@scorphus scorphus commented Apr 8, 2020

Not calling cleanup functions after a test fails may affect other tests down the row.

This issue was introduced in 04f27d4 (git bisect FTW)

When a test fails, a GetOutOf_testPartExecutor exception is raised to make unittest halt testPartExecutor:

def runtest(self):
# TODO: move testcase reporter into separate class, this shouldnt be on item
import unittest
testMethod = getattr(self._testcase, self._testcase._testMethodName)
class _GetOutOf_testPartExecutor(KeyboardInterrupt):
"""Helper exception to get out of unittests's testPartExecutor (see TestCase.run)."""
@functools.wraps(testMethod)
def wrapped_testMethod(*args, **kwargs):
"""Wrap the original method to call into pytest's machinery, so other pytest
features can have a chance to kick in (notably --pdb)"""
try:
self.ihook.pytest_pyfunc_call(pyfuncitem=self)
except unittest.SkipTest:
raise
except Exception as exc:
expecting_failure = self._expecting_failure(testMethod)
if expecting_failure:
raise
self._needs_explicit_tearDown = True
raise _GetOutOf_testPartExecutor(exc)

That prevents teardown and cleanup functions from being called. That's why self._needs_explicit_tearDown is set to True to then explicitly call teardown later on:

def teardown(self):
if self._needs_explicit_tearDown:
self._testcase.tearDown()
self._testcase = None
self._obj = None

But no cleanup functions are called. Hence this PR.

@blueyed
Copy link
Contributor

blueyed commented Apr 8, 2020

Thanks for trying to tackle this, but it does not fix #6947 unfortunately (there is an explicit test there: #6947 (comment)).

@scorphus
Copy link
Author

scorphus commented Apr 9, 2020

I fail to see what that test has to do with cleanups. Maybe it's a test for a different issue and it should be either renamed or reported as a new one. I'm also happy to investigate it.

This PR does not make that test pass, for sure, but it fixes the problem with cleanup functions not being called after a test failure and... a KeyboardInterrupt exception is raised.

Anyways I'll remove the Fix #6947 so it remains open for any sake.

Then, can you please accept this pull request and make a new release? This is a big blocker for me and my team – and I believe for others too.

Thanks a bunch!

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.

I fail to see what that test has to do with cleanups.

I agree, I left a comment there asking for clarification. 👍

This looks great to me, thanks for the PR!

Note to ourselves: we need to backport this to 5.4.x for the next release.

@@ -0,0 +1 @@
Call cleanup functions on test failure.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Call cleanup functions on test failure.
Call cleanup functions of `unittest.TestCase` subclasses on test failures.

@nicoddemus nicoddemus added the needs backport applied to PRs, indicates that it should be ported to the current bug-fix branch label Apr 9, 2020
@scorphus
Copy link
Author

scorphus commented Apr 9, 2020

@nicoddemus I'm up for backporting it. I'll lookup how to do it. Any links or hints?

@nicoddemus
Copy link
Member

@nicoddemus I'm up for backporting it. I'll lookup how to do it. Any links or hints?

Thanks for the offer! Weirdly I can't find the instructions right now, but I'm sure @bluetech can point at them when he get's a chance.

(Btw @bluetech just noticed that this document also needs to be updated: https://github.com/pytest-dev/pytest/blob/master/doc/en/development_guide.rst)

Not calling cleanup functions after a test fails may affect other tests
down the row.

This issue was introduced in 04f27d4.

When a test fails, a `_GetOutOf_testPartExecutor` exception is raised to
make `unittest` halt `testPartExecutor`:

https://github.com/pytest-dev/pytest/blob/413ca8a4d097ed1a98b2d1012ca7df17aa6837b1/src/_pytest/unittest.py#L206-L228

That prevents `teardown` **and** cleanup functions from being called.
That's why `self._needs_explicit_tearDown` is set to `True` to then
explicitly call `teardown` later on:

https://github.com/pytest-dev/pytest/blob/413ca8a4d097ed1a98b2d1012ca7df17aa6837b1/src/_pytest/unittest.py#L122-L126

But no cleanup functions are called. Hence this commit.
@blueyed
Copy link
Contributor

blueyed commented Apr 9, 2020

@nicoddemus
I've thought it was clear that "raising out of unittest" is the main problem, and this is just a side-effect of it. I.e. this fixes just one symptom of it.
When fixing it like this you basically need to also do everything else unittest is doing, e.g. feeding errors etc.
Therefore I still think it should be reverted instead (#6014) - given that nobody is working on fixing it "properly" anytime soon.

@nicoddemus
Copy link
Member

Therefore I still think it should be reverted instead (#6014) - given that nobody is working on fixing it "properly" anytime soon.

I agree, but this still counts as a bug fix that can be released in the next patch release. Reverting it would require at least a minor version, and as I understand our users would like to get this released ASAP.

Merging this now won't make reverting #6014 any harder, and we will even have a regression test to boot to prevent further mistakes.

@RonnyPfannschmidt
Copy link
Member

I agree with @nicoddemus 's assessment of the timeline.

@blueyed
Copy link
Contributor

blueyed commented Apr 9, 2020

If you do not want to fix it proper I suggest taking #6972 instead - which basically is a revert of the "raising out of unittest".

@blueyed
Copy link
Contributor

blueyed commented Apr 9, 2020

Merging this now won't make reverting #6014 any harder

#6014 was meant to be a revert.
By now #5996 would have to be reverted (and any follow-ups like this one (if merged)).

All I am saying is that it fixes one symptom, but e.g. pytest-django would still be affected (if it would not monkeypatch it out already).

@scorphus
Copy link
Author

scorphus commented Apr 21, 2020

So, what's the verdict? Is that one small single line so bad compared to pytest not working as it should for a particular case?

Should I close this PR?

What are you going to do about it?

Thanks.

@nicoddemus
Copy link
Member

Hi @scorphus,

Thanks again for the PR, and sorry for the delay! We were solving some internal issues.

This has been fixed (along with pdb/trace support) in #7151, which supersedes this PR.

We plan to release 5.4.2 soon, probably today. 👍

Again thanks for the PR and sorry for the long response time here.

@nicoddemus nicoddemus closed this May 8, 2020
@scorphus scorphus deleted the fix-cleanup-bug branch May 8, 2020 12:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs backport applied to PRs, indicates that it should be ported to the current bug-fix branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants