6
6
import attr
7
7
8
8
import _pytest
9
+ import _pytest ._code
10
+
9
11
from _pytest .mark .structures import NodeKeywords
10
12
11
13
SEP = "/"
@@ -69,7 +71,7 @@ class Node(object):
69
71
""" base class for Collector and Item the test collection tree.
70
72
Collector subclasses have children, Items are terminal nodes."""
71
73
72
- def __init__ (self , name , parent = None , config = None , session = None ):
74
+ def __init__ (self , name , parent = None , config = None , session = None , fspath = None , nodeid = None ):
73
75
#: a unique name within the scope of the parent node
74
76
self .name = name
75
77
@@ -83,7 +85,7 @@ def __init__(self, name, parent=None, config=None, session=None):
83
85
self .session = session or parent .session
84
86
85
87
#: filesystem path where this node was collected from (can be None)
86
- self .fspath = getattr (parent , 'fspath' , None )
88
+ self .fspath = fspath or getattr (parent , 'fspath' , None )
87
89
88
90
#: keywords/markers collected from all scopes
89
91
self .keywords = NodeKeywords (self )
@@ -94,6 +96,12 @@ def __init__(self, name, parent=None, config=None, session=None):
94
96
# used for storing artificial fixturedefs for direct parametrization
95
97
self ._name2pseudofixturedef = {}
96
98
99
+ if nodeid is not None :
100
+ self ._nodeid = nodeid
101
+ else :
102
+ assert parent is not None
103
+ self ._nodeid = self .parent .nodeid + "::" + self .name
104
+
97
105
@property
98
106
def ihook (self ):
99
107
""" fspath sensitive hook proxy used to call pytest hooks"""
@@ -137,14 +145,7 @@ def warn(self, code, message):
137
145
@property
138
146
def nodeid (self ):
139
147
""" a ::-separated string denoting its collection tree address. """
140
- try :
141
- return self ._nodeid
142
- except AttributeError :
143
- self ._nodeid = x = self ._makeid ()
144
- return x
145
-
146
- def _makeid (self ):
147
- return self .parent .nodeid + "::" + self .name
148
+ return self ._nodeid
148
149
149
150
def __hash__ (self ):
150
151
return hash (self .nodeid )
@@ -281,31 +282,34 @@ def _prunetraceback(self, excinfo):
281
282
excinfo .traceback = ntraceback .filter ()
282
283
283
284
285
+ def _check_initialpaths_for_relpath (session , fspath ):
286
+ for initial_path in session ._initialpaths :
287
+ if fspath .common (initial_path ) == initial_path :
288
+ return fspath .relto (initial_path .dirname )
289
+
290
+
284
291
class FSCollector (Collector ):
285
- def __init__ (self , fspath , parent = None , config = None , session = None ):
292
+ def __init__ (self , fspath , parent = None , config = None , session = None , nodeid = None ):
286
293
fspath = py .path .local (fspath ) # xxx only for test_resultlog.py?
287
294
name = fspath .basename
288
295
if parent is not None :
289
296
rel = fspath .relto (parent .fspath )
290
297
if rel :
291
298
name = rel
292
299
name = name .replace (os .sep , SEP )
293
- super (FSCollector , self ).__init__ (name , parent , config , session )
294
300
self .fspath = fspath
295
301
296
- def _check_initialpaths_for_relpath ( self ):
297
- for initialpath in self . session . _initialpaths :
298
- if self . fspath . common ( initialpath ) == initialpath :
299
- return self .fspath .relto (initialpath . dirname )
302
+ session = session or parent . session
303
+
304
+ if nodeid is None :
305
+ nodeid = self .fspath .relto (session . config . rootdir )
300
306
301
- def _makeid (self ):
302
- relpath = self .fspath .relto (self .config .rootdir )
307
+ if not nodeid :
308
+ nodeid = _check_initialpaths_for_relpath (session , fspath )
309
+ if os .sep != SEP :
310
+ nodeid = nodeid .replace (os .sep , SEP )
303
311
304
- if not relpath :
305
- relpath = self ._check_initialpaths_for_relpath ()
306
- if os .sep != SEP :
307
- relpath = relpath .replace (os .sep , SEP )
308
- return relpath
312
+ super (FSCollector , self ).__init__ (name , parent , config , session , nodeid = nodeid , fspath = fspath )
309
313
310
314
311
315
class File (FSCollector ):
@@ -318,8 +322,8 @@ class Item(Node):
318
322
"""
319
323
nextitem = None
320
324
321
- def __init__ (self , name , parent = None , config = None , session = None ):
322
- super (Item , self ).__init__ (name , parent , config , session )
325
+ def __init__ (self , name , parent = None , config = None , session = None , nodeid = None ):
326
+ super (Item , self ).__init__ (name , parent , config , session , nodeid = nodeid )
323
327
self ._report_sections = []
324
328
325
329
#: user properties is a list of tuples (name, value) that holds user
0 commit comments