remove NodeMarkers, turn own_markers into a list and use iter_markers api exclusively
This commit is contained in:
parent
8805036fd8
commit
dbb1b5a227
|
@ -983,7 +983,7 @@ class FixtureManager(object):
|
||||||
argnames = getfuncargnames(func, cls=cls)
|
argnames = getfuncargnames(func, cls=cls)
|
||||||
else:
|
else:
|
||||||
argnames = ()
|
argnames = ()
|
||||||
usefixtures = flatten(uf_mark.args for uf_mark in node.find_markers("usefixtures"))
|
usefixtures = flatten(mark.args for mark in node.iter_markers() if mark.name == "usefixtures")
|
||||||
initialnames = argnames
|
initialnames = argnames
|
||||||
initialnames = tuple(usefixtures) + initialnames
|
initialnames = tuple(usefixtures) + initialnames
|
||||||
fm = node.session._fixturemanager
|
fm = node.session._fixturemanager
|
||||||
|
|
|
@ -35,7 +35,7 @@ class MarkEvaluator(object):
|
||||||
return not hasattr(self, 'exc')
|
return not hasattr(self, 'exc')
|
||||||
|
|
||||||
def _get_marks(self):
|
def _get_marks(self):
|
||||||
return list(self.item.find_markers(self._mark_name))
|
return [x for x in self.item.iter_markers() if x.name == self._mark_name]
|
||||||
|
|
||||||
def invalidraise(self, exc):
|
def invalidraise(self, exc):
|
||||||
raises = self.get('raises')
|
raises = self.get('raises')
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
from __future__ import absolute_import, division, print_function
|
from __future__ import absolute_import, division, print_function
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from itertools import chain
|
|
||||||
from operator import itemgetter
|
|
||||||
import six
|
import six
|
||||||
import py
|
import py
|
||||||
import attr
|
import attr
|
||||||
|
@ -10,7 +8,7 @@ import attr
|
||||||
import _pytest
|
import _pytest
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
|
|
||||||
from _pytest.mark.structures import NodeKeywords, NodeMarkers, MarkInfo
|
from _pytest.mark.structures import NodeKeywords, MarkInfo
|
||||||
|
|
||||||
SEP = "/"
|
SEP = "/"
|
||||||
|
|
||||||
|
@ -91,7 +89,9 @@ class Node(object):
|
||||||
|
|
||||||
#: keywords/markers collected from all scopes
|
#: keywords/markers collected from all scopes
|
||||||
self.keywords = NodeKeywords(self)
|
self.keywords = NodeKeywords(self)
|
||||||
self._markers = NodeMarkers()
|
|
||||||
|
#: the marker objects belonging to this node
|
||||||
|
self.own_markers = []
|
||||||
|
|
||||||
#: allow adding of extra keywords to use for matching
|
#: allow adding of extra keywords to use for matching
|
||||||
self.extra_keyword_matches = set()
|
self.extra_keyword_matches = set()
|
||||||
|
@ -181,30 +181,13 @@ class Node(object):
|
||||||
elif not isinstance(marker, MarkDecorator):
|
elif not isinstance(marker, MarkDecorator):
|
||||||
raise ValueError("is not a string or pytest.mark.* Marker")
|
raise ValueError("is not a string or pytest.mark.* Marker")
|
||||||
self.keywords[marker.name] = marker
|
self.keywords[marker.name] = marker
|
||||||
self._markers.update([marker])
|
self.own_markers.append(marker)
|
||||||
|
|
||||||
def find_markers(self, name):
|
|
||||||
"""find all marks with the given name on the node and its parents
|
|
||||||
|
|
||||||
:param str name: name of the marker
|
|
||||||
:returns: iterator over marks matching the name"""
|
|
||||||
return map(itemgetter(1), self.find_markers_with_node(name))
|
|
||||||
|
|
||||||
def find_markers_with_node(self, name):
|
|
||||||
"""find all marks with the given name on the node and its parents
|
|
||||||
|
|
||||||
:param str name: name of the marker
|
|
||||||
:returns: iterator over (node, mark) matching the name
|
|
||||||
"""
|
|
||||||
for node in reversed(self.listchain()):
|
|
||||||
for mark in node._markers.find(name):
|
|
||||||
yield node, mark
|
|
||||||
|
|
||||||
def iter_markers(self):
|
def iter_markers(self):
|
||||||
"""
|
"""
|
||||||
iterate over all markers of the node
|
iterate over all markers of the node
|
||||||
"""
|
"""
|
||||||
return chain.from_iterable(x._markers for x in reversed(self.listchain()))
|
return (x[1] for x in self.iter_markers_with_node())
|
||||||
|
|
||||||
def iter_markers_with_node(self):
|
def iter_markers_with_node(self):
|
||||||
"""
|
"""
|
||||||
|
@ -212,7 +195,7 @@ class Node(object):
|
||||||
returns sequence of tuples (node, mark)
|
returns sequence of tuples (node, mark)
|
||||||
"""
|
"""
|
||||||
for node in reversed(self.listchain()):
|
for node in reversed(self.listchain()):
|
||||||
for mark in node._markers:
|
for mark in node.own_markers:
|
||||||
yield node, mark
|
yield node, mark
|
||||||
|
|
||||||
def get_marker(self, name):
|
def get_marker(self, name):
|
||||||
|
@ -223,7 +206,7 @@ class Node(object):
|
||||||
|
|
||||||
deprecated
|
deprecated
|
||||||
"""
|
"""
|
||||||
markers = list(self.find_markers(name))
|
markers = [x for x in self.iter_markers() if x.name == name]
|
||||||
if markers:
|
if markers:
|
||||||
return MarkInfo(markers)
|
return MarkInfo(markers)
|
||||||
|
|
||||||
|
|
|
@ -117,8 +117,9 @@ def pytest_generate_tests(metafunc):
|
||||||
if hasattr(metafunc.function, attr):
|
if hasattr(metafunc.function, attr):
|
||||||
msg = "{0} has '{1}', spelling should be 'parametrize'"
|
msg = "{0} has '{1}', spelling should be 'parametrize'"
|
||||||
raise MarkerError(msg.format(metafunc.function.__name__, attr))
|
raise MarkerError(msg.format(metafunc.function.__name__, attr))
|
||||||
for marker in metafunc.definition.find_markers('parametrize'):
|
for marker in metafunc.definition.iter_markers():
|
||||||
metafunc.parametrize(*marker.args, **marker.kwargs)
|
if marker.name == 'parametrize':
|
||||||
|
metafunc.parametrize(*marker.args, **marker.kwargs)
|
||||||
|
|
||||||
|
|
||||||
def pytest_configure(config):
|
def pytest_configure(config):
|
||||||
|
@ -221,7 +222,7 @@ class PyobjMixin(PyobjContext):
|
||||||
# XXX evil hack
|
# XXX evil hack
|
||||||
# used to avoid Instance collector marker duplication
|
# used to avoid Instance collector marker duplication
|
||||||
if self._ALLOW_MARKERS:
|
if self._ALLOW_MARKERS:
|
||||||
self._markers.update(get_unpacked_marks(self.obj))
|
self.own_markers.extend(get_unpacked_marks(self.obj))
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def fset(self, value):
|
def fset(self, value):
|
||||||
|
@ -1132,7 +1133,7 @@ class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr):
|
||||||
self.obj = callobj
|
self.obj = callobj
|
||||||
|
|
||||||
self.keywords.update(self.obj.__dict__)
|
self.keywords.update(self.obj.__dict__)
|
||||||
self._markers.update(get_unpacked_marks(self.obj))
|
self.own_markers.extend(get_unpacked_marks(self.obj))
|
||||||
if callspec:
|
if callspec:
|
||||||
self.callspec = callspec
|
self.callspec = callspec
|
||||||
# this is total hostile and a mess
|
# this is total hostile and a mess
|
||||||
|
@ -1142,7 +1143,7 @@ class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr):
|
||||||
# feel free to cry, this was broken for years before
|
# feel free to cry, this was broken for years before
|
||||||
# and keywords cant fix it per design
|
# and keywords cant fix it per design
|
||||||
self.keywords[mark.name] = mark
|
self.keywords[mark.name] = mark
|
||||||
self._markers.update(callspec.marks)
|
self.own_markers.extend(callspec.marks)
|
||||||
if keywords:
|
if keywords:
|
||||||
self.keywords.update(keywords)
|
self.keywords.update(keywords)
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,9 @@ def pytest_runtest_setup(item):
|
||||||
item._skipped_by_mark = True
|
item._skipped_by_mark = True
|
||||||
skip(eval_skipif.getexplanation())
|
skip(eval_skipif.getexplanation())
|
||||||
|
|
||||||
for skip_info in item.find_markers('skip'):
|
for skip_info in item.iter_markers():
|
||||||
|
if skip_info.name != 'skip':
|
||||||
|
continue
|
||||||
item._skipped_by_mark = True
|
item._skipped_by_mark = True
|
||||||
if 'reason' in skip_info.kwargs:
|
if 'reason' in skip_info.kwargs:
|
||||||
skip(skip_info.kwargs['reason'])
|
skip(skip_info.kwargs['reason'])
|
||||||
|
|
|
@ -60,9 +60,10 @@ def catch_warnings_for_item(item):
|
||||||
for arg in inifilters:
|
for arg in inifilters:
|
||||||
_setoption(warnings, arg)
|
_setoption(warnings, arg)
|
||||||
|
|
||||||
for mark in item.find_markers('filterwarnings'):
|
for mark in item.iter_markers():
|
||||||
for arg in mark.args:
|
if mark.name == 'filterwarnings':
|
||||||
warnings._setoption(arg)
|
for arg in mark.args:
|
||||||
|
warnings._setoption(arg)
|
||||||
|
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
|
@ -533,7 +533,7 @@ class TestFunctional(object):
|
||||||
items, rec = testdir.inline_genitems(p)
|
items, rec = testdir.inline_genitems(p)
|
||||||
for item in items:
|
for item in items:
|
||||||
print(item, item.keywords)
|
print(item, item.keywords)
|
||||||
assert list(item.find_markers('a'))
|
assert [x for x in item.iter_markers() if x.name == 'a']
|
||||||
|
|
||||||
def test_mark_decorator_subclass_does_not_propagate_to_base(self, testdir):
|
def test_mark_decorator_subclass_does_not_propagate_to_base(self, testdir):
|
||||||
p = testdir.makepyfile("""
|
p = testdir.makepyfile("""
|
||||||
|
|
Loading…
Reference in New Issue