fix a collection bug where a:🅱️:c could not be resolved properly if
there are multiple 'b' nodes. --HG-- branch : trunk
This commit is contained in:
parent
f779d3f863
commit
a60e470573
|
@ -4,6 +4,8 @@ tags: bug 1.4 core xdist
|
||||||
|
|
||||||
* reportinfo -> location in hooks and items
|
* reportinfo -> location in hooks and items
|
||||||
* check oejskit plugin compatibility
|
* check oejskit plugin compatibility
|
||||||
|
* terminal reporting - dot-printing
|
||||||
|
* some simple profiling
|
||||||
|
|
||||||
refine session initialization / fix custom collect crash
|
refine session initialization / fix custom collect crash
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
|
|
|
@ -138,15 +138,14 @@ class Collection:
|
||||||
|
|
||||||
def getbyid(self, id):
|
def getbyid(self, id):
|
||||||
""" return one or more nodes matching the id. """
|
""" return one or more nodes matching the id. """
|
||||||
matching = [self._topcollector]
|
names = filter(None, id.split("::"))
|
||||||
if not id:
|
if names and '/' in names[0]:
|
||||||
return matching
|
names[:1] = names[0].split("/")
|
||||||
names = id.split("::")
|
return self._match([self._topcollector], names)
|
||||||
|
|
||||||
|
def _match(self, matching, names):
|
||||||
while names:
|
while names:
|
||||||
name = names.pop(0)
|
name = names.pop(0)
|
||||||
newnames = name.split("/")
|
|
||||||
name = newnames[0]
|
|
||||||
names[:0] = newnames[1:]
|
|
||||||
l = []
|
l = []
|
||||||
for current in matching:
|
for current in matching:
|
||||||
for x in current._memocollect():
|
for x in current._memocollect():
|
||||||
|
@ -169,22 +168,28 @@ class Collection:
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
def perform_collect(self):
|
def perform_collect(self):
|
||||||
idlist = [self._parsearg(arg) for arg in self.config.args]
|
|
||||||
nodes = []
|
nodes = []
|
||||||
for names in idlist:
|
for arg in self.config.args:
|
||||||
self.genitems([self._topcollector], names, nodes)
|
names = self._parsearg(arg)
|
||||||
|
try:
|
||||||
|
self.genitems([self._topcollector], names, nodes)
|
||||||
|
except NoMatch:
|
||||||
|
raise self.config.Error("can't collect: %s" % (arg,))
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
def genitems(self, matching, names, result):
|
def genitems(self, matching, names, result):
|
||||||
if not matching:
|
if not matching:
|
||||||
assert not names
|
assert not names
|
||||||
return result
|
return
|
||||||
names = list(names)
|
if names:
|
||||||
name = names and names.pop(0) or None
|
name = names[0]
|
||||||
|
names = names[1:]
|
||||||
|
else:
|
||||||
|
name = None
|
||||||
for node in matching:
|
for node in matching:
|
||||||
if isinstance(node, py.test.collect.Item):
|
if isinstance(node, py.test.collect.Item):
|
||||||
if name is None:
|
if name is None:
|
||||||
self.config.hook.pytest_log_itemcollect(item=node)
|
node.ihook.pytest_log_itemcollect(item=node)
|
||||||
result.append(node)
|
result.append(node)
|
||||||
continue
|
continue
|
||||||
assert isinstance(node, py.test.collect.Collector)
|
assert isinstance(node, py.test.collect.Collector)
|
||||||
|
@ -192,27 +197,31 @@ class Collection:
|
||||||
rep = node.ihook.pytest_make_collect_report(collector=node)
|
rep = node.ihook.pytest_make_collect_report(collector=node)
|
||||||
#print "matching", rep.result, "against name", name
|
#print "matching", rep.result, "against name", name
|
||||||
if rep.passed:
|
if rep.passed:
|
||||||
if name:
|
if not name:
|
||||||
matched = False
|
|
||||||
for subcol in rep.result:
|
|
||||||
if subcol.name != name and subcol.name == "()":
|
|
||||||
names.insert(0, name)
|
|
||||||
name = "()"
|
|
||||||
# see doctests/custom naming XXX
|
|
||||||
if subcol.name == name or subcol.fspath.basename == name:
|
|
||||||
self.genitems([subcol], names, result)
|
|
||||||
matched = True
|
|
||||||
if not matched:
|
|
||||||
raise self.config.Error(
|
|
||||||
"can't collect: %s" % (name,))
|
|
||||||
|
|
||||||
else:
|
|
||||||
self.genitems(rep.result, [], result)
|
self.genitems(rep.result, [], result)
|
||||||
|
else:
|
||||||
|
matched = False
|
||||||
|
for x in rep.result:
|
||||||
|
try:
|
||||||
|
if x.name == name or x.fspath.basename == name:
|
||||||
|
self.genitems([x], names, result)
|
||||||
|
matched = True
|
||||||
|
elif x.name == "()": # XXX special Instance() case
|
||||||
|
self.genitems([x], [name] + names, result)
|
||||||
|
matched = True
|
||||||
|
except NoMatch:
|
||||||
|
pass
|
||||||
|
if not matched:
|
||||||
|
node.ihook.pytest_collectreport(report=rep)
|
||||||
|
raise NoMatch(name)
|
||||||
node.ihook.pytest_collectreport(report=rep)
|
node.ihook.pytest_collectreport(report=rep)
|
||||||
x = getattr(self, 'shouldstop', None)
|
x = getattr(self, 'shouldstop', None)
|
||||||
if x:
|
if x:
|
||||||
raise Session.Interrupted(x)
|
raise Session.Interrupted(x)
|
||||||
|
|
||||||
|
class NoMatch(Exception):
|
||||||
|
""" raised if genitems cannot locate a matching names. """
|
||||||
|
|
||||||
def gettopdir(args):
|
def gettopdir(args):
|
||||||
""" return the top directory for the given paths.
|
""" return the top directory for the given paths.
|
||||||
if the common base dir resides in a python package
|
if the common base dir resides in a python package
|
||||||
|
|
|
@ -191,3 +191,23 @@ class TestGeneralUsage:
|
||||||
for dirname, other_dirname in [('a', 'b'), ('b', 'a')]:
|
for dirname, other_dirname in [('a', 'b'), ('b', 'a')]:
|
||||||
result = testdir.runpytest(dirname)
|
result = testdir.runpytest(dirname)
|
||||||
assert result.ret == 0, "test_sibling_conftest: py.test run for '%s', but '%s/conftest.py' loaded." % (dirname, other_dirname)
|
assert result.ret == 0, "test_sibling_conftest: py.test run for '%s', but '%s/conftest.py' loaded." % (dirname, other_dirname)
|
||||||
|
|
||||||
|
def test_multiple_items_per_collector_byid(self, testdir):
|
||||||
|
c = testdir.makeconftest("""
|
||||||
|
import py
|
||||||
|
class MyItem(py.test.collect.Item):
|
||||||
|
def runtest(self):
|
||||||
|
pass
|
||||||
|
class MyCollector(py.test.collect.File):
|
||||||
|
def collect(self):
|
||||||
|
return [MyItem(name="xyz", parent=self)]
|
||||||
|
def pytest_collect_file(path, parent):
|
||||||
|
if path.basename.startswith("conftest"):
|
||||||
|
return MyCollector(path, parent)
|
||||||
|
""")
|
||||||
|
result = testdir.runpytest(c.basename+"::"+"xyz")
|
||||||
|
assert result.ret == 0
|
||||||
|
result.stdout.fnmatch_lines([
|
||||||
|
"*1 pass*",
|
||||||
|
])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue