fix a pypy related regression - re-allow self.NAME style collection tree customization
This commit is contained in:
parent
aea4d1bd7a
commit
b8f0d10f80
|
@ -152,6 +152,7 @@ class Node(object):
|
||||||
|
|
||||||
Module = compatproperty("Module")
|
Module = compatproperty("Module")
|
||||||
Class = compatproperty("Class")
|
Class = compatproperty("Class")
|
||||||
|
Instance = compatproperty("Instance")
|
||||||
Function = compatproperty("Function")
|
Function = compatproperty("Function")
|
||||||
File = compatproperty("File")
|
File = compatproperty("File")
|
||||||
Item = compatproperty("Item")
|
Item = compatproperty("Item")
|
||||||
|
|
|
@ -73,7 +73,7 @@ def pytest_pycollect_makeitem(__multicall__, collector, name, obj):
|
||||||
if collector._istestclasscandidate(name, obj):
|
if collector._istestclasscandidate(name, obj):
|
||||||
#if hasattr(collector.obj, 'unittest'):
|
#if hasattr(collector.obj, 'unittest'):
|
||||||
# return # we assume it's a mixin class for a TestCase derived one
|
# return # we assume it's a mixin class for a TestCase derived one
|
||||||
return Class(name, parent=collector)
|
return collector.Class(name, parent=collector)
|
||||||
elif collector.funcnamefilter(name) and hasattr(obj, '__call__'):
|
elif collector.funcnamefilter(name) and hasattr(obj, '__call__'):
|
||||||
if is_generator(obj):
|
if is_generator(obj):
|
||||||
return Generator(name, parent=collector)
|
return Generator(name, parent=collector)
|
||||||
|
@ -160,7 +160,7 @@ class PyCollectorMixin(PyobjMixin, pytest.Collector):
|
||||||
for prefix in self.config.getini("python_functions"):
|
for prefix in self.config.getini("python_functions"):
|
||||||
if name.startswith(prefix):
|
if name.startswith(prefix):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def classnamefilter(self, name):
|
def classnamefilter(self, name):
|
||||||
for prefix in self.config.getini("python_classes"):
|
for prefix in self.config.getini("python_classes"):
|
||||||
if name.startswith(prefix):
|
if name.startswith(prefix):
|
||||||
|
@ -214,11 +214,11 @@ class PyCollectorMixin(PyobjMixin, pytest.Collector):
|
||||||
plugins = self.getplugins() + extra
|
plugins = self.getplugins() + extra
|
||||||
gentesthook.pcall(plugins, metafunc=metafunc)
|
gentesthook.pcall(plugins, metafunc=metafunc)
|
||||||
if not metafunc._calls:
|
if not metafunc._calls:
|
||||||
return Function(name, parent=self)
|
return self.Function(name, parent=self)
|
||||||
l = []
|
l = []
|
||||||
for callspec in metafunc._calls:
|
for callspec in metafunc._calls:
|
||||||
subname = "%s[%s]" %(name, callspec.id)
|
subname = "%s[%s]" %(name, callspec.id)
|
||||||
function = Function(name=subname, parent=self,
|
function = self.Function(name=subname, parent=self,
|
||||||
callspec=callspec, callobj=funcobj, keywords={callspec.id:True})
|
callspec=callspec, callobj=funcobj, keywords={callspec.id:True})
|
||||||
l.append(function)
|
l.append(function)
|
||||||
return l
|
return l
|
||||||
|
@ -272,7 +272,7 @@ class Module(pytest.File, PyCollectorMixin):
|
||||||
class Class(PyCollectorMixin, pytest.Collector):
|
class Class(PyCollectorMixin, pytest.Collector):
|
||||||
|
|
||||||
def collect(self):
|
def collect(self):
|
||||||
return [Instance(name="()", parent=self)]
|
return [self.Instance(name="()", parent=self)]
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
setup_class = getattr(self.obj, 'setup_class', None)
|
setup_class = getattr(self.obj, 'setup_class', None)
|
||||||
|
@ -394,7 +394,7 @@ class Generator(FunctionMixin, PyCollectorMixin, pytest.Collector):
|
||||||
if name in seen:
|
if name in seen:
|
||||||
raise ValueError("%r generated tests with non-unique name %r" %(self, name))
|
raise ValueError("%r generated tests with non-unique name %r" %(self, name))
|
||||||
seen[name] = True
|
seen[name] = True
|
||||||
l.append(Function(name, self, args=args, callobj=call))
|
l.append(self.Function(name, self, args=args, callobj=call))
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def getcallargs(self, obj):
|
def getcallargs(self, obj):
|
||||||
|
@ -528,10 +528,10 @@ class Metafunc:
|
||||||
def addcall(self, funcargs=None, id=_notexists, param=_notexists):
|
def addcall(self, funcargs=None, id=_notexists, param=_notexists):
|
||||||
""" add a new call to the underlying test function during the
|
""" add a new call to the underlying test function during the
|
||||||
collection phase of a test run.
|
collection phase of a test run.
|
||||||
|
|
||||||
:arg funcargs: argument keyword dictionary used when invoking
|
:arg funcargs: argument keyword dictionary used when invoking
|
||||||
the test function.
|
the test function.
|
||||||
|
|
||||||
:arg id: used for reporting and identification purposes. If you
|
:arg id: used for reporting and identification purposes. If you
|
||||||
don't supply an `id` the length of the currently
|
don't supply an `id` the length of the currently
|
||||||
list of calls to the test function will be used.
|
list of calls to the test function will be used.
|
||||||
|
@ -562,7 +562,7 @@ class FuncargRequest:
|
||||||
|
|
||||||
class LookupError(LookupError):
|
class LookupError(LookupError):
|
||||||
""" error on performing funcarg request. """
|
""" error on performing funcarg request. """
|
||||||
|
|
||||||
def __init__(self, pyfuncitem):
|
def __init__(self, pyfuncitem):
|
||||||
self._pyfuncitem = pyfuncitem
|
self._pyfuncitem = pyfuncitem
|
||||||
if hasattr(pyfuncitem, '_requestparam'):
|
if hasattr(pyfuncitem, '_requestparam'):
|
||||||
|
@ -590,7 +590,7 @@ class FuncargRequest:
|
||||||
def module(self):
|
def module(self):
|
||||||
""" module where the test function was collected. """
|
""" module where the test function was collected. """
|
||||||
return self._pyfuncitem.getparent(pytest.Module).obj
|
return self._pyfuncitem.getparent(pytest.Module).obj
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cls(self):
|
def cls(self):
|
||||||
""" class (can be None) where the test function was collected. """
|
""" class (can be None) where the test function was collected. """
|
||||||
|
@ -606,7 +606,7 @@ class FuncargRequest:
|
||||||
def config(self):
|
def config(self):
|
||||||
""" the pytest config object associated with this request. """
|
""" the pytest config object associated with this request. """
|
||||||
return self._pyfuncitem.config
|
return self._pyfuncitem.config
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fspath(self):
|
def fspath(self):
|
||||||
""" the file system path of the test module which collected this test. """
|
""" the file system path of the test module which collected this test. """
|
||||||
|
@ -780,7 +780,7 @@ def getlocation(function, curdir):
|
||||||
def raises(ExpectedException, *args, **kwargs):
|
def raises(ExpectedException, *args, **kwargs):
|
||||||
""" assert that a code block/function call raises @ExpectedException
|
""" assert that a code block/function call raises @ExpectedException
|
||||||
and raise a failure exception otherwise.
|
and raise a failure exception otherwise.
|
||||||
|
|
||||||
If using Python 2.5 or above, you may use this function as a
|
If using Python 2.5 or above, you may use this function as a
|
||||||
context manager::
|
context manager::
|
||||||
|
|
||||||
|
@ -803,7 +803,7 @@ def raises(ExpectedException, *args, **kwargs):
|
||||||
|
|
||||||
A third possibility is to use a string which which will
|
A third possibility is to use a string which which will
|
||||||
be executed::
|
be executed::
|
||||||
|
|
||||||
>>> raises(ZeroDivisionError, "f(0)")
|
>>> raises(ZeroDivisionError, "f(0)")
|
||||||
<ExceptionInfo ...>
|
<ExceptionInfo ...>
|
||||||
"""
|
"""
|
||||||
|
@ -852,3 +852,4 @@ class RaisesContext(object):
|
||||||
pytest.fail("DID NOT RAISE")
|
pytest.fail("DID NOT RAISE")
|
||||||
self.excinfo.__init__(tp)
|
self.excinfo.__init__(tp)
|
||||||
return issubclass(self.excinfo.type, self.ExpectedException)
|
return issubclass(self.excinfo.type, self.ExpectedException)
|
||||||
|
|
||||||
|
|
|
@ -1280,3 +1280,49 @@ def test_customized_python_discovery(testdir):
|
||||||
result.stdout.fnmatch_lines([
|
result.stdout.fnmatch_lines([
|
||||||
"*2 passed*",
|
"*2 passed*",
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def test_collector_attributes(testdir):
|
||||||
|
testdir.makeconftest("""
|
||||||
|
import pytest
|
||||||
|
def pytest_pycollect_makeitem(collector):
|
||||||
|
assert collector.Function == pytest.Function
|
||||||
|
assert collector.Class == pytest.Class
|
||||||
|
assert collector.Instance == pytest.Instance
|
||||||
|
assert collector.Module == pytest.Module
|
||||||
|
""")
|
||||||
|
testdir.makepyfile("""
|
||||||
|
def test_hello():
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.stdout.fnmatch_lines([
|
||||||
|
"*1 passed*",
|
||||||
|
])
|
||||||
|
|
||||||
|
def test_customize_through_attributes(testdir):
|
||||||
|
testdir.makeconftest("""
|
||||||
|
import pytest
|
||||||
|
class MyFunction(pytest.Function):
|
||||||
|
pass
|
||||||
|
class MyInstance(pytest.Instance):
|
||||||
|
Function = MyFunction
|
||||||
|
class MyClass(pytest.Class):
|
||||||
|
Instance = MyInstance
|
||||||
|
|
||||||
|
def pytest_pycollect_makeitem(collector, name, obj):
|
||||||
|
if name.startswith("MyTestClass"):
|
||||||
|
return MyClass(name, parent=collector)
|
||||||
|
""")
|
||||||
|
testdir.makepyfile("""
|
||||||
|
class MyTestClass:
|
||||||
|
def test_hello(self):
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
result = testdir.runpytest("--collectonly")
|
||||||
|
result.stdout.fnmatch_lines([
|
||||||
|
"*MyClass*",
|
||||||
|
"*MyInstance*",
|
||||||
|
"*MyFunction*test_hello*",
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue