Skip to content

Commit be42484

Browse files
adamchainzblueyed
authored andcommitted
unittest: fix _classmethod_is_defined_at_leaf: use __dict__
Fixes #624. Closes #625.
1 parent 9da244b commit be42484

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

docs/changelog.rst

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Bug fixes
99

1010
* Fixed registration of :py:func:`~pytest.mark.ignore_template_errors` marker,
1111
which is required with ``pytest --strict`` (#609).
12+
* Fix another regression with unittest (#624, #625).
1213

1314
3.3.2 (2018-06-21)
1415
------------------

pytest_django/plugin.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,8 @@ def _classmethod_is_defined_at_leaf(cls, method_name):
268268
super_method = None
269269

270270
for base_cls in cls.__mro__[1:]: # pragma: no branch
271-
if hasattr(base_cls, method_name):
272-
super_method = getattr(base_cls, method_name)
271+
super_method = base_cls.__dict__.get(method_name)
272+
if super_method is not None:
273273
break
274274

275275
assert super_method is not None, (
@@ -297,7 +297,7 @@ def _disable_class_methods(cls):
297297

298298
_disabled_classmethods[cls] = (
299299
# Get the classmethod object (not the resulting bound method),
300-
# otherwise inheritence will be broken when restoring.
300+
# otherwise inheritance will be broken when restoring.
301301
cls.__dict__.get('setUpClass'),
302302
_classmethod_is_defined_at_leaf(cls, 'setUpClass'),
303303
cls.__dict__.get('tearDownClass'),

tests/test_unittest.py

+28
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,34 @@ def test_pass(self):
337337
])
338338
assert result.ret == 0
339339

340+
def test_setUpClass_leaf_but_not_in_dunder_dict(self, django_testdir):
341+
django_testdir.create_test_module('''
342+
from django.test import testcases
343+
344+
class CMSTestCase(testcases.TestCase):
345+
pass
346+
347+
class FooBarTestCase(testcases.TestCase):
348+
349+
@classmethod
350+
def setUpClass(cls):
351+
print('FooBarTestCase.setUpClass')
352+
super(FooBarTestCase, cls).setUpClass()
353+
354+
class TestContact(CMSTestCase, FooBarTestCase):
355+
356+
def test_noop(self):
357+
print('test_noop')
358+
''')
359+
360+
result = django_testdir.runpytest_subprocess('-q', '-s')
361+
result.stdout.fnmatch_lines([
362+
"*FooBarTestCase.setUpClass*",
363+
"*test_noop*",
364+
"1 passed*",
365+
])
366+
assert result.ret == 0
367+
340368

341369
class TestCaseWithDbFixture(TestCase):
342370
pytestmark = pytest.mark.usefixtures('db')

0 commit comments

Comments
 (0)