Skip to content

Commit 64ae6ae

Browse files
extract application of marks and legacy markinfos
1 parent bdec2c8 commit 64ae6ae

File tree

1 file changed

+40
-30
lines changed

1 file changed

+40
-30
lines changed

_pytest/mark.py

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99

1010
def alias(name):
11+
# todo: introduce deprecationwarnings
1112
return property(attrgetter(name), doc='alias for ' + name)
1213

1314

@@ -329,30 +330,39 @@ def __call__(self, *args, **kwargs):
329330
is_class = inspect.isclass(func)
330331
if len(args) == 1 and (istestfunc(func) or is_class):
331332
if is_class:
332-
if hasattr(func, 'pytestmark'):
333-
mark_list = func.pytestmark
334-
if not isinstance(mark_list, list):
335-
mark_list = [mark_list]
336-
# always work on a copy to avoid updating pytestmark
337-
# from a superclass by accident
338-
mark_list = mark_list + [self]
339-
func.pytestmark = mark_list
340-
else:
341-
func.pytestmark = [self]
333+
apply_mark(func, self.mark)
342334
else:
343-
holder = getattr(func, self.name, None)
344-
if holder is None:
345-
holder = MarkInfo(self.mark)
346-
setattr(func, self.name, holder)
347-
else:
348-
holder.add_mark(self.mark)
335+
apply_legacy_mark(func, self.mark)
349336
return func
350337

351338
mark = Mark(self.name, args, kwargs)
352339
return self.__class__(self.mark.combined_with(mark))
353340

354341

342+
def apply_mark(obj, mark):
343+
assert isinstance(mark, Mark), mark
344+
"""applies a marker to an object,
345+
makrer transfers only update legacy markinfo objects
346+
"""
347+
mark_list = getattr(obj, 'pytestmark', [])
348+
349+
if not isinstance(mark_list, list):
350+
mark_list = [mark_list]
351+
# always work on a copy to avoid updating pytestmark
352+
# from a superclass by accident
353+
mark_list = mark_list + [mark]
354+
obj.pytestmark = mark_list
355+
355356

357+
def apply_legacy_mark(func, mark):
358+
if not isinstance(mark, Mark):
359+
raise TypeError("got {mark!r} instead of a Mark".format(mark=mark))
360+
holder = getattr(func, mark.name, None)
361+
if holder is None:
362+
holder = MarkInfo(mark)
363+
setattr(func, mark.name, holder)
364+
else:
365+
holder.add_mark(mark)
356366

357367

358368
class Mark(namedtuple('Mark', 'name, args, kwargs')):
@@ -404,17 +414,17 @@ def _marked(func, mark):
404414

405415

406416
def transfer_markers(funcobj, cls, mod):
407-
# XXX this should rather be code in the mark plugin or the mark
408-
# plugin should merge with the python plugin.
409-
for holder in (cls, mod):
410-
try:
411-
pytestmark = holder.pytestmark
412-
except AttributeError:
413-
continue
414-
if isinstance(pytestmark, list):
415-
for mark in pytestmark:
416-
if not _marked(funcobj, mark):
417-
mark(funcobj)
418-
else:
419-
if not _marked(funcobj, pytestmark):
420-
pytestmark(funcobj)
417+
"""
418+
transfer legacy markers to the function level marminfo objects
419+
this one is a major fsckup for mark breakages
420+
"""
421+
for obj in (cls, mod):
422+
mark_list = getattr(obj, 'pytestmark', [])
423+
424+
if not isinstance(mark_list, list):
425+
mark_list = [mark_list]
426+
427+
for mark in mark_list:
428+
mark = getattr(mark, 'mark', mark) # unpack MarkDecorator
429+
if not _marked(funcobj, mark):
430+
apply_legacy_mark(funcobj, mark)

0 commit comments

Comments
 (0)