address review comments

* enhance api for fetching marks off an object
* rename functions for storing marks
* enhance deprecation message for MarkInfo
This commit is contained in:
Ronny Pfannschmidt 2017-06-23 11:05:38 +02:00
parent 1d926011a4
commit 23d016f114
2 changed files with 36 additions and 27 deletions

View File

@ -8,8 +8,8 @@ be removed when the time comes.
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
class RemovedInPytest4_0Warning(DeprecationWarning): class RemovedInPytest4Warning(DeprecationWarning):
"warning class for features removed in pytest 4.0" """warning class for features removed in pytest 4.0"""
MAIN_STR_ARGS = 'passing a string to pytest.main() is deprecated, ' \ MAIN_STR_ARGS = 'passing a string to pytest.main() is deprecated, ' \
@ -28,5 +28,6 @@ GETFUNCARGVALUE = "use of getfuncargvalue is deprecated, use getfixturevalue"
RESULT_LOG = '--result-log is deprecated and scheduled for removal in pytest 4.0' RESULT_LOG = '--result-log is deprecated and scheduled for removal in pytest 4.0'
MARK_INFO_ATTRIBUTE = RemovedInPytest4_0Warning( MARK_INFO_ATTRIBUTE = RemovedInPytest4Warning(
"Markinfo attributes are deprecated, please iterate the mark Collection") "MarkInfo objects are deprecated as they contain the merged marks"
)

View File

@ -336,32 +336,42 @@ 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:
apply_mark(func, self.mark) store_mark(func, self.mark)
else: else:
apply_legacy_mark(func, self.mark) store_legacy_markinfo(func, self.mark)
apply_mark(func, self.mark) store_mark(func, 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 get_unpacked_marks(obj):
def apply_mark(obj, mark): """
assert isinstance(mark, Mark), mark obtain the unpacked marks that are stored on a object
"""applies a marker to an object,
makrer transfers only update legacy markinfo objects
""" """
mark_list = getattr(obj, 'pytestmark', []) mark_list = getattr(obj, 'pytestmark', [])
if not isinstance(mark_list, list): if not isinstance(mark_list, list):
mark_list = [mark_list] mark_list = [mark_list]
# always work on a copy to avoid updating pytestmark return [
# from a superclass by accident getattr(mark, 'mark', mark) # unpack MarkDecorator
mark_list = mark_list + [mark] for mark in mark_list
obj.pytestmark = mark_list ]
def apply_legacy_mark(func, mark): def store_mark(obj, mark):
"""store a Mark on a object
this is used to implement the Mark declarations/decorators correctly
"""
assert isinstance(mark, Mark), mark
# always reassign name to avoid updating pytestmark
# in a referene that was only borrowed
obj.pytestmark = get_unpacked_marks(obj) + [mark]
def store_legacy_markinfo(func, mark):
"""create the legacy MarkInfo objects and put them onto the function
"""
if not isinstance(mark, Mark): if not isinstance(mark, Mark):
raise TypeError("got {mark!r} instead of a Mark".format(mark=mark)) raise TypeError("got {mark!r} instead of a Mark".format(mark=mark))
holder = getattr(func, mark.name, None) holder = getattr(func, mark.name, None)
@ -422,16 +432,14 @@ def _marked(func, mark):
def transfer_markers(funcobj, cls, mod): def transfer_markers(funcobj, cls, mod):
""" """
transfer legacy markers to the function level marminfo objects this function transfers class level markers and module level markers
this one is a major fsckup for mark breakages into function level markinfo objects
this is the main reason why marks are so broken
the resolution will involve phasing out function level MarkInfo objects
""" """
for obj in (cls, mod): for obj in (cls, mod):
mark_list = getattr(obj, 'pytestmark', []) for mark in get_unpacked_marks(obj):
if not isinstance(mark_list, list):
mark_list = [mark_list]
for mark in mark_list:
mark = getattr(mark, 'mark', mark) # unpack MarkDecorator
if not _marked(funcobj, mark): if not _marked(funcobj, mark):
apply_legacy_mark(funcobj, mark) store_legacy_markinfo(funcobj, mark)