Merge pull request #9624 from bluetech/unittest-getobj
unittest: restore `UnitTestFunction.obj` to return unbound rather than bound method
This commit is contained in:
commit
2b6708b892
|
@ -0,0 +1,3 @@
|
|||
Restore `UnitTestFunction.obj` to return unbound rather than bound method.
|
||||
Fixes a crash during a failed teardown in unittest TestCases with non-default `__init__`.
|
||||
Regressed in pytest 7.0.0.
|
|
@ -185,6 +185,15 @@ class TestCaseFunction(Function):
|
|||
_excinfo: Optional[List[_pytest._code.ExceptionInfo[BaseException]]] = None
|
||||
_testcase: Optional["unittest.TestCase"] = None
|
||||
|
||||
def _getobj(self):
|
||||
assert self.parent is not None
|
||||
# Unlike a regular Function in a Class, where `item.obj` returns
|
||||
# a *bound* method (attached to an instance), TestCaseFunction's
|
||||
# `obj` returns an *unbound* method (not attached to an instance).
|
||||
# This inconsistency is probably not desirable, but needs some
|
||||
# consideration before changing.
|
||||
return getattr(self.parent.obj, self.originalname) # type: ignore[attr-defined]
|
||||
|
||||
def setup(self) -> None:
|
||||
# A bound method to be called during teardown() if set (see 'runtest()').
|
||||
self._explicit_tearDown: Optional[Callable[[], None]] = None
|
||||
|
|
|
@ -1472,3 +1472,29 @@ def test_do_cleanups_on_teardown_failure(pytester: Pytester) -> None:
|
|||
passed, skipped, failed = reprec.countoutcomes()
|
||||
assert failed == 2
|
||||
assert passed == 1
|
||||
|
||||
|
||||
def test_traceback_pruning(pytester: Pytester) -> None:
|
||||
"""Regression test for #9610 - doesn't crash during traceback pruning."""
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
import unittest
|
||||
|
||||
class MyTestCase(unittest.TestCase):
|
||||
def __init__(self, test_method):
|
||||
unittest.TestCase.__init__(self, test_method)
|
||||
|
||||
class TestIt(MyTestCase):
|
||||
@classmethod
|
||||
def tearDownClass(cls) -> None:
|
||||
assert False
|
||||
|
||||
def test_it(self):
|
||||
pass
|
||||
"""
|
||||
)
|
||||
reprec = pytester.inline_run()
|
||||
passed, skipped, failed = reprec.countoutcomes()
|
||||
assert passed == 1
|
||||
assert failed == 1
|
||||
assert reprec.ret == 1
|
||||
|
|
Loading…
Reference in New Issue