2222try :
2323 from _pytest .mark .structures import MarkDecorator , Mark # noqa
2424except ImportError :
25- pass
25+ from _pytest . mark import MarkDecorator , MarkInfo as Mark # noqa
2626
2727from .common_mini_six import string_types
2828
@@ -114,15 +114,26 @@ def copy_pytest_marks(from_f, to_f, override=False):
114114 to_f .pytestmark = to_marks + from_marks
115115
116116
117- def filter_marks (marks ,
117+ def filter_marks (marks , # type: Iterable[Mark]
118118 remove # type: str
119119 ):
120- return [m for m in marks if m .name != remove ]
120+ # type: (...) -> Tuple[Mark]
121+ """
122+ Returns a tuple of all marks in `marks` that do not have a 'parametrize' name.
123+
124+ :param marks:
125+ :param remove:
126+ :return:
127+ """
128+ return tuple (m for m in marks if m .name != remove )
121129
122130
123- def get_pytest_marks_on_function (f , as_decorators = False ):
131+ def get_pytest_marks_on_function (f ,
132+ as_decorators = False # type: bool
133+ ):
134+ # type: (...) -> Union[List[Mark], List[MarkDecorator]]
124135 """
125- Utility to return *ALL* pytest marks (not only parametrization) applied on a function
136+ Utility to return a list of *ALL* pytest marks (not only parametrization) applied on a function
126137 Note that this also works on classes
127138
128139 :param f:
@@ -146,6 +157,14 @@ def get_pytest_marks_on_function(f, as_decorators=False):
146157 return mks
147158
148159
160+ def get_pytest_marks_on_item (item ):
161+ """lists all marks on an item such as `request._pyfuncitem`"""
162+ if PYTEST3_OR_GREATER :
163+ return item .callspec .marks
164+ else :
165+ return [val for val in item .keywords .values () if isinstance (val , (MarkDecorator , Mark ))]
166+
167+
149168def get_pytest_usefixture_marks (f ):
150169 # pytest > 3.2.0
151170 marks = getattr (f , 'pytestmark' , None )
@@ -253,10 +272,13 @@ def make_marked_parameter_value(argvalues_tuple, marks):
253272def markinfos_to_markdecorators (marks , # type: Iterable[Mark]
254273 function_marks = False # type: bool
255274 ):
275+ # type: (...) -> List[MarkDecorator]
256276 """
257277 Transforms the provided marks (MarkInfo or Mark in recent pytest) obtained from marked cases, into MarkDecorator so
258278 that they can be re-applied to generated pytest parameters in the global @pytest.mark.parametrize.
259279
280+ Returns a list.
281+
260282 :param marks:
261283 :param function_marks:
262284 :return:
@@ -297,7 +319,7 @@ def markinfos_to_markdecorators(marks, # type: Iterable[Mark]
297319 return marks_mod
298320
299321
300- def markdecorators_as_tuple (marks # type: Optional[Union[MarkDecorator, Tuple[MarkDecorator, ...], List[MarkDecorator], Set [MarkDecorator]]]
322+ def markdecorators_as_tuple (marks # type: Optional[Union[MarkDecorator, Iterable [MarkDecorator]]]
301323 ):
302324 # type: (...) -> Tuple[MarkDecorator, ...]
303325 """
@@ -306,18 +328,23 @@ def markdecorators_as_tuple(marks # type: Optional[Union[MarkDecorator, Tuple[M
306328 :param marks:
307329 :return:
308330 """
309- if isinstance (marks , (tuple , list , set )):
331+ if marks is None :
332+ return ()
333+
334+ try :
335+ # iterable ?
310336 return tuple (marks )
311- elif marks is not None :
337+ except TypeError :
338+ # single
312339 return (marks ,)
313340
314341
315342def markdecorators_to_markinfos (marks # type: Sequence[MarkDecorator]
316343 ):
344+ # type: (...) -> Tuple[Mark, ...]
317345 if PYTEST3_OR_GREATER :
318346 return tuple (m .mark for m in marks )
347+ elif len (marks ) == 0 :
348+ return ()
319349 else :
320- if len (marks ) == 0 :
321- return ()
322- else :
323- raise NotImplementedError ("TODO" )
350+ return tuple (Mark (m .name , m .args , m .kwargs ) for m in marks )
0 commit comments