make nodeids precalculated, there is no sane reason to commpute lazyly

This commit is contained in:
Ronny Pfannschmidt 2018-03-09 10:52:59 +01:00
parent 45b6b7df92
commit 5e5935759e
3 changed files with 31 additions and 30 deletions

View File

@ -300,7 +300,7 @@ class Session(nodes.FSCollector):
def __init__(self, config): def __init__(self, config):
nodes.FSCollector.__init__( nodes.FSCollector.__init__(
self, config.rootdir, parent=None, self, config.rootdir, parent=None,
config=config, session=self) config=config, session=self, nodeid="")
self.testsfailed = 0 self.testsfailed = 0
self.testscollected = 0 self.testscollected = 0
self.shouldstop = False self.shouldstop = False
@ -311,9 +311,6 @@ class Session(nodes.FSCollector):
self.config.pluginmanager.register(self, name="session") self.config.pluginmanager.register(self, name="session")
def _makeid(self):
return ""
@hookimpl(tryfirst=True) @hookimpl(tryfirst=True)
def pytest_collectstart(self): def pytest_collectstart(self):
if self.shouldfail: if self.shouldfail:

View File

@ -6,6 +6,8 @@ import py
import attr import attr
import _pytest import _pytest
import _pytest._code
from _pytest.mark.structures import NodeKeywords from _pytest.mark.structures import NodeKeywords
SEP = "/" SEP = "/"
@ -69,7 +71,7 @@ class Node(object):
""" base class for Collector and Item the test collection tree. """ base class for Collector and Item the test collection tree.
Collector subclasses have children, Items are terminal nodes.""" Collector subclasses have children, Items are terminal nodes."""
def __init__(self, name, parent=None, config=None, session=None): def __init__(self, name, parent=None, config=None, session=None, fspath=None, nodeid=None):
#: a unique name within the scope of the parent node #: a unique name within the scope of the parent node
self.name = name self.name = name
@ -83,7 +85,7 @@ class Node(object):
self.session = session or parent.session self.session = session or parent.session
#: filesystem path where this node was collected from (can be None) #: filesystem path where this node was collected from (can be None)
self.fspath = getattr(parent, 'fspath', None) self.fspath = fspath or getattr(parent, 'fspath', None)
#: keywords/markers collected from all scopes #: keywords/markers collected from all scopes
self.keywords = NodeKeywords(self) self.keywords = NodeKeywords(self)
@ -94,6 +96,12 @@ class Node(object):
# used for storing artificial fixturedefs for direct parametrization # used for storing artificial fixturedefs for direct parametrization
self._name2pseudofixturedef = {} self._name2pseudofixturedef = {}
if nodeid is not None:
self._nodeid = nodeid
else:
assert parent is not None
self._nodeid = self.parent.nodeid + "::" + self.name
@property @property
def ihook(self): def ihook(self):
""" fspath sensitive hook proxy used to call pytest hooks""" """ fspath sensitive hook proxy used to call pytest hooks"""
@ -137,14 +145,7 @@ class Node(object):
@property @property
def nodeid(self): def nodeid(self):
""" a ::-separated string denoting its collection tree address. """ """ a ::-separated string denoting its collection tree address. """
try: return self._nodeid
return self._nodeid
except AttributeError:
self._nodeid = x = self._makeid()
return x
def _makeid(self):
return self.parent.nodeid + "::" + self.name
def __hash__(self): def __hash__(self):
return hash(self.nodeid) return hash(self.nodeid)
@ -281,8 +282,14 @@ class Collector(Node):
excinfo.traceback = ntraceback.filter() excinfo.traceback = ntraceback.filter()
def _check_initialpaths_for_relpath(session, fspath):
for initial_path in session._initialpaths:
if fspath.common(initial_path) == initial_path:
return fspath.relto(initial_path.dirname)
class FSCollector(Collector): class FSCollector(Collector):
def __init__(self, fspath, parent=None, config=None, session=None): def __init__(self, fspath, parent=None, config=None, session=None, nodeid=None):
fspath = py.path.local(fspath) # xxx only for test_resultlog.py? fspath = py.path.local(fspath) # xxx only for test_resultlog.py?
name = fspath.basename name = fspath.basename
if parent is not None: if parent is not None:
@ -290,22 +297,19 @@ class FSCollector(Collector):
if rel: if rel:
name = rel name = rel
name = name.replace(os.sep, SEP) name = name.replace(os.sep, SEP)
super(FSCollector, self).__init__(name, parent, config, session)
self.fspath = fspath self.fspath = fspath
def _check_initialpaths_for_relpath(self): session = session or parent.session
for initialpath in self.session._initialpaths:
if self.fspath.common(initialpath) == initialpath:
return self.fspath.relto(initialpath.dirname)
def _makeid(self): if nodeid is None:
relpath = self.fspath.relto(self.config.rootdir) nodeid = self.fspath.relto(session.config.rootdir)
if not relpath: if not nodeid:
relpath = self._check_initialpaths_for_relpath() nodeid = _check_initialpaths_for_relpath(session, fspath)
if os.sep != SEP: if os.sep != SEP:
relpath = relpath.replace(os.sep, SEP) nodeid = nodeid.replace(os.sep, SEP)
return relpath
super(FSCollector, self).__init__(name, parent, config, session, nodeid=nodeid, fspath=fspath)
class File(FSCollector): class File(FSCollector):
@ -318,8 +322,8 @@ class Item(Node):
""" """
nextitem = None nextitem = None
def __init__(self, name, parent=None, config=None, session=None): def __init__(self, name, parent=None, config=None, session=None, nodeid=None):
super(Item, self).__init__(name, parent, config, session) super(Item, self).__init__(name, parent, config, session, nodeid=nodeid)
self._report_sections = [] self._report_sections = []
#: user properties is a list of tuples (name, value) that holds user #: user properties is a list of tuples (name, value) that holds user

View File

@ -13,7 +13,7 @@ def test_generic_path(testdir):
from _pytest.main import Session from _pytest.main import Session
config = testdir.parseconfig() config = testdir.parseconfig()
session = Session(config) session = Session(config)
p1 = Node('a', config=config, session=session) p1 = Node('a', config=config, session=session, nodeid='a')
# assert p1.fspath is None # assert p1.fspath is None
p2 = Node('B', parent=p1) p2 = Node('B', parent=p1)
p3 = Node('()', parent=p2) p3 = Node('()', parent=p2)