From f7ad173fee28dd2c04e87f6eae214d6ca35153b2 Mon Sep 17 00:00:00 2001 From: Dmitry Dygalo Date: Sat, 23 Jul 2016 17:37:58 +0200 Subject: [PATCH] Fixed collection of classes with custom ``__new__`` method --- AUTHORS | 1 + CHANGELOG.rst | 5 +++++ _pytest/python.py | 15 +++++++++++---- testing/python/collect.py | 12 ++++++++++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index 4ce6f0aa4..7ef2df84a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -35,6 +35,7 @@ David Díaz-Barquero David Mohr David Vierra Diego Russo +Dmitry Dygalo Edison Gustavo Muenz Eduardo Schettino Elizaveta Shashkova diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5cdb63470..c99947943 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -51,6 +51,10 @@ * ImportErrors in plugins now are a fatal error instead of issuing a pytest warning (`#1479`_). Thanks to `@The-Compiler`_ for the PR. +* Fixed collection of classes with custom ``__new__`` method. + Fixes `#1579`_. Thanks to `@Stranger6667`_ for the PR. + +.. _#1579: https://github.com/pytest-dev/pytest/issues/1579 .. _#1580: https://github.com/pytest-dev/pytest/pull/1580 .. _#1605: https://github.com/pytest-dev/pytest/issues/1605 .. _#1597: https://github.com/pytest-dev/pytest/pull/1597 @@ -72,6 +76,7 @@ .. _@DRMacIver: https://github.com/DRMacIver .. _@BeyondEvil: https://github.com/BeyondEvil .. _@JonathonSonesen: https://github.com/JonathonSonesen +.. _@Stranger6667: https://github.com/Stranger6667 2.9.2 diff --git a/_pytest/python.py b/_pytest/python.py index 6242fd497..812adf4b4 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -662,6 +662,10 @@ class Class(PyCollector): self.warn("C1", "cannot collect test class %r because it has a " "__init__ constructor" % self.obj.__name__) return [] + elif hasnew(self.obj): + self.warn("C1", "cannot collect test class %r because it has a " + "__new__ constructor" % self.obj.__name__) + return [] return [self._getcustomclass("Instance")(name="()", parent=self)] def setup(self): @@ -679,8 +683,7 @@ class Class(PyCollector): class Instance(PyCollector): def _getobj(self): - obj = self.parent.obj() - return obj + return self.parent.obj() def collect(self): self.session._fixturemanager.parsefactories(self) @@ -793,10 +796,14 @@ class Generator(FunctionMixin, PyCollector): def hasinit(obj): init = getattr(obj, '__init__', None) if init: - if init != object.__init__: - return True + return init != object.__init__ +def hasnew(obj): + new = getattr(obj, '__new__', None) + if new: + return new != object.__new__ + def fillfixtures(function): """ fill missing funcargs for a test function. """ diff --git a/testing/python/collect.py b/testing/python/collect.py index 22433da77..59760d8d1 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -109,6 +109,18 @@ class TestClass: colitems = modcol.collect() assert len(colitems) == 0 + def test_issue1579_namedtuple(self, testdir): + testdir.makepyfile(""" + import collections + + TestCase = collections.namedtuple('TestCase', ['a']) + """) + result = testdir.runpytest('-rw') + result.stdout.fnmatch_lines( + "*cannot collect test class 'TestCase' " + "because it has a __new__ constructor*" + ) + class TestGenerator: def test_generative_functions(self, testdir):