extract application of marks and legacy markinfos
This commit is contained in:
parent
bdec2c8f9e
commit
64ae6ae25d
|
@ -8,6 +8,7 @@ from .compat import imap
|
||||||
|
|
||||||
|
|
||||||
def alias(name):
|
def alias(name):
|
||||||
|
# todo: introduce deprecationwarnings
|
||||||
return property(attrgetter(name), doc='alias for ' + name)
|
return property(attrgetter(name), doc='alias for ' + name)
|
||||||
|
|
||||||
|
|
||||||
|
@ -329,30 +330,39 @@ class MarkDecorator:
|
||||||
is_class = inspect.isclass(func)
|
is_class = inspect.isclass(func)
|
||||||
if len(args) == 1 and (istestfunc(func) or is_class):
|
if len(args) == 1 and (istestfunc(func) or is_class):
|
||||||
if is_class:
|
if is_class:
|
||||||
if hasattr(func, 'pytestmark'):
|
apply_mark(func, self.mark)
|
||||||
mark_list = func.pytestmark
|
|
||||||
if not isinstance(mark_list, list):
|
|
||||||
mark_list = [mark_list]
|
|
||||||
# always work on a copy to avoid updating pytestmark
|
|
||||||
# from a superclass by accident
|
|
||||||
mark_list = mark_list + [self]
|
|
||||||
func.pytestmark = mark_list
|
|
||||||
else:
|
|
||||||
func.pytestmark = [self]
|
|
||||||
else:
|
else:
|
||||||
holder = getattr(func, self.name, None)
|
apply_legacy_mark(func, self.mark)
|
||||||
if holder is None:
|
|
||||||
holder = MarkInfo(self.mark)
|
|
||||||
setattr(func, self.name, holder)
|
|
||||||
else:
|
|
||||||
holder.add_mark(self.mark)
|
|
||||||
return func
|
return func
|
||||||
|
|
||||||
mark = Mark(self.name, args, kwargs)
|
mark = Mark(self.name, args, kwargs)
|
||||||
return self.__class__(self.mark.combined_with(mark))
|
return self.__class__(self.mark.combined_with(mark))
|
||||||
|
|
||||||
|
|
||||||
|
def apply_mark(obj, mark):
|
||||||
|
assert isinstance(mark, Mark), mark
|
||||||
|
"""applies a marker to an object,
|
||||||
|
makrer transfers only update legacy markinfo objects
|
||||||
|
"""
|
||||||
|
mark_list = getattr(obj, 'pytestmark', [])
|
||||||
|
|
||||||
|
if not isinstance(mark_list, list):
|
||||||
|
mark_list = [mark_list]
|
||||||
|
# always work on a copy to avoid updating pytestmark
|
||||||
|
# from a superclass by accident
|
||||||
|
mark_list = mark_list + [mark]
|
||||||
|
obj.pytestmark = mark_list
|
||||||
|
|
||||||
|
|
||||||
|
def apply_legacy_mark(func, mark):
|
||||||
|
if not isinstance(mark, Mark):
|
||||||
|
raise TypeError("got {mark!r} instead of a Mark".format(mark=mark))
|
||||||
|
holder = getattr(func, mark.name, None)
|
||||||
|
if holder is None:
|
||||||
|
holder = MarkInfo(mark)
|
||||||
|
setattr(func, mark.name, holder)
|
||||||
|
else:
|
||||||
|
holder.add_mark(mark)
|
||||||
|
|
||||||
|
|
||||||
class Mark(namedtuple('Mark', 'name, args, kwargs')):
|
class Mark(namedtuple('Mark', 'name, args, kwargs')):
|
||||||
|
@ -404,17 +414,17 @@ def _marked(func, mark):
|
||||||
|
|
||||||
|
|
||||||
def transfer_markers(funcobj, cls, mod):
|
def transfer_markers(funcobj, cls, mod):
|
||||||
# XXX this should rather be code in the mark plugin or the mark
|
"""
|
||||||
# plugin should merge with the python plugin.
|
transfer legacy markers to the function level marminfo objects
|
||||||
for holder in (cls, mod):
|
this one is a major fsckup for mark breakages
|
||||||
try:
|
"""
|
||||||
pytestmark = holder.pytestmark
|
for obj in (cls, mod):
|
||||||
except AttributeError:
|
mark_list = getattr(obj, 'pytestmark', [])
|
||||||
continue
|
|
||||||
if isinstance(pytestmark, list):
|
if not isinstance(mark_list, list):
|
||||||
for mark in pytestmark:
|
mark_list = [mark_list]
|
||||||
if not _marked(funcobj, mark):
|
|
||||||
mark(funcobj)
|
for mark in mark_list:
|
||||||
else:
|
mark = getattr(mark, 'mark', mark) # unpack MarkDecorator
|
||||||
if not _marked(funcobj, pytestmark):
|
if not _marked(funcobj, mark):
|
||||||
pytestmark(funcobj)
|
apply_legacy_mark(funcobj, mark)
|
||||||
|
|
Loading…
Reference in New Issue