1From de47b73520fd9b7e41272701d7fd4663357af046 Mon Sep 17 00:00:00 2001
2From: Ran Benita <ran@unusedvar.com>
3Date: Fri, 7 Jun 2024 09:49:29 +0300
4Subject: [PATCH] unittest: fix assertion errors on unittest reruns
5
6This fixes unittest test reruns when using plugins like
7pytest-rerunfailures.
8
9The `instance` property uses AttributeError to check if the instance
10needs to be initialized, so `del` is the correct way to clear it, not
11setting to `None`.
12
13Regressed in 8.2.2.
14---
15 changelog/12424.bugfix.rst | 1 +
16 src/_pytest/unittest.py | 2 +-
17 .../pytest_rerunfailures_integration.py | 11 +++++++++++
18 tox.ini | 2 +-
19 4 files changed, 14 insertions(+), 2 deletions(-)
20 create mode 100644 changelog/12424.bugfix.rst
21 create mode 100644 testing/plugins_integration/pytest_rerunfailures_integration.py
22
23diff --git a/changelog/12424.bugfix.rst b/changelog/12424.bugfix.rst
24new file mode 100644
25index 00000000000..7ad1126858b
26--- /dev/null
27+++ b/changelog/12424.bugfix.rst
28@@ -0,0 +1 @@
29+Fix crash with `assert testcase is not None` assertion failure when re-running unittest tests using plugins like pytest-rerunfailures. Regressed in 8.2.2.
30diff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py
31index 643443f08c6..ca82ac5c14a 100644
32--- a/src/_pytest/unittest.py
33+++ b/src/_pytest/unittest.py
34@@ -222,7 +222,7 @@ def teardown(self) -> None:
35 self._explicit_tearDown()
36 self._explicit_tearDown = None
37 self._obj = None
38- self._instance = None
39+ del self._instance
40 super().teardown()
41
42 def startTest(self, testcase: "unittest.TestCase") -> None:
43diff --git a/testing/plugins_integration/pytest_rerunfailures_integration.py b/testing/plugins_integration/pytest_rerunfailures_integration.py
44new file mode 100644
45index 00000000000..9a13a3279a9
46--- /dev/null
47+++ b/testing/plugins_integration/pytest_rerunfailures_integration.py
48@@ -0,0 +1,11 @@
49+import unittest
50+
51+
52+class MyTestCase(unittest.TestCase):
53+ first_time = True
54+
55+ def test_fail_the_first_time(self) -> None:
56+ """Regression test for issue #12424."""
57+ if self.first_time:
58+ type(self).first_time = False
59+ self.fail()
60diff --git a/tox.ini b/tox.ini
61index 0a3f0acf5b8..35b335a015d 100644
62--- a/tox.ini
63+++ b/tox.ini
64@@ -141,7 +141,7 @@ commands =
65 pytest --cov=. simple_integration.py
66 pytest --ds=django_settings simple_integration.py
67 pytest --html=simple.html simple_integration.py
68- pytest --reruns 5 simple_integration.py
69+ pytest --reruns 5 simple_integration.py pytest_rerunfailures_integration.py
70 pytest pytest_anyio_integration.py
71 pytest pytest_asyncio_integration.py
72 pytest pytest_mock_integration.py