Skip to content

Fix 3605 #3606

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/3605.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
no longer ValueError when using the ``get_marker`` api.
11 changes: 10 additions & 1 deletion src/_pytest/mark/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,18 @@ def get_unpacked_marks(obj):
obtain the unpacked marks that are stored on an object
"""
mark_list = getattr(obj, "pytestmark", [])

if not isinstance(mark_list, list):
mark_list = [mark_list]
return normalize_mark_list(mark_list)


def normalize_mark_list(mark_list):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a docstring here explaining why this is needed

"""
normalizes marker decorating helpers to mark objects

:type mark_list: List[Union[Mark, Markdecorator]]
:rtype: List[Mark]
"""
return [getattr(mark, "mark", mark) for mark in mark_list] # unpack MarkDecorator


Expand Down
10 changes: 7 additions & 3 deletions src/_pytest/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@
get_default_arg_names,
)
from _pytest.outcomes import fail
from _pytest.mark.structures import transfer_markers, get_unpacked_marks
from _pytest.mark.structures import (
transfer_markers,
get_unpacked_marks,
normalize_mark_list,
)


# relative paths that we use to filter traceback entries from appearing to the user;
Expand Down Expand Up @@ -773,7 +777,7 @@ def setmulti2(self, valtypes, argnames, valset, id, marks, scopenum, param_index
self.indices[arg] = param_index
self._arg2scopenum[arg] = scopenum
self._idlist.append(id)
self.marks.extend(marks)
self.marks.extend(normalize_mark_list(marks))

def setall(self, funcargs, id, param):
for x in funcargs:
Expand Down Expand Up @@ -1254,7 +1258,7 @@ def __init__(
# feel free to cry, this was broken for years before
# and keywords cant fix it per design
self.keywords[mark.name] = mark
self.own_markers.extend(callspec.marks)
self.own_markers.extend(normalize_mark_list(callspec.marks))
if keywords:
self.keywords.update(keywords)

Expand Down
39 changes: 39 additions & 0 deletions testing/test_mark.py
Original file line number Diff line number Diff line change
Expand Up @@ -1130,3 +1130,42 @@ def test_addmarker_getmarker():
node.add_marker("b")
node.get_marker("a").combined
node.get_marker("b").combined


@pytest.mark.issue("https://github.com/pytest-dev/pytest/issues/3605")
@pytest.mark.filterwarnings("ignore")
def test_markers_from_parametrize(testdir):
testdir.makepyfile(
"""
from __future__ import print_function
import pytest

first_custom_mark = pytest.mark.custom_marker
custom_mark = pytest.mark.custom_mark
@pytest.fixture(autouse=True)
def trigger(request):
custom_mark =request.node.get_marker('custom_mark')
print("Custom mark %s" % custom_mark)

@custom_mark("custom mark non parametrized")
def test_custom_mark_non_parametrized():
print("Hey from test")

@pytest.mark.parametrize(
"obj_type",
[
first_custom_mark("first custom mark")("template"),
pytest.param( # Think this should be recommended way?
"disk",
marks=custom_mark('custom mark1')
),
custom_mark("custom mark2")("vm"), # Tried also this
]
)
def test_custom_mark_parametrized(obj_type):
print("obj_type is:", obj_type)
"""
)

result = testdir.runpytest()
result.assert_outcomes(passed=4)