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:
parent
1d926011a4
commit
23d016f114
|
@ -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"
|
||||||
|
)
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue