Skip to content
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

fix addmarker - extract mark from markdecorator #3577

Merged
merged 5 commits into from
Jun 13, 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/3555.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix regression in ``Node.add_marker`` by extracting the mark object of a ``MarkDecorator``.
13 changes: 12 additions & 1 deletion src/_pytest/mark/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,18 @@ def _marked(func, mark):
class MarkInfo(object):
""" Marking object created by :class:`MarkDecorator` instances. """

_marks = attr.ib()
_marks = attr.ib(convert=list)

@_marks.validator
def validate_marks(self, attribute, value):
for item in value:
if not isinstance(item, Mark):
raise ValueError(
"MarkInfo expects Mark instances, got {!r} ({!r})".format(
item, type(item)
)
)

combined = attr.ib(
repr=False,
default=attr.Factory(
Expand Down
6 changes: 3 additions & 3 deletions src/_pytest/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,9 @@ def listchain(self):
return chain

def add_marker(self, marker):
""" dynamically add a marker object to the node.
"""dynamically add a marker object to the node.

``marker`` can be a string or pytest.mark.* instance.
:type marker: str or pytest.mark.*
"""
from _pytest.mark import MarkDecorator, MARK_GEN

Expand All @@ -185,7 +185,7 @@ def add_marker(self, marker):
elif not isinstance(marker, MarkDecorator):
raise ValueError("is not a string or pytest.mark.* Marker")
self.keywords[marker.name] = marker
self.own_markers.append(marker)
self.own_markers.append(marker.mark)

def iter_markers(self, name=None):
"""
Expand Down
3 changes: 3 additions & 0 deletions testing/python/integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ def f(x):
values = getfuncargnames(f)
assert values == ("x",)

@pytest.mark.xfail(
strict=False, reason="getfuncargnames breaks if mock is imported"
)
def test_wrapped_getfuncargnames_patching(self):
from _pytest.compat import getfuncargnames

Expand Down
11 changes: 10 additions & 1 deletion testing/test_mark.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from __future__ import absolute_import, division, print_function
import os
import sys

import mock
import pytest
from _pytest.mark import (
MarkGenerator as Mark,
ParameterSet,
transfer_markers,
EMPTY_PARAMETERSET_OPTION,
)
from _pytest.nodes import Node

ignore_markinfo = pytest.mark.filterwarnings(
"ignore:MarkInfo objects:_pytest.deprecated.RemovedInPytest4Warning"
Expand Down Expand Up @@ -1123,3 +1124,11 @@ class TestBarClass(BaseTests):
passed_k, skipped_k, failed_k = reprec_keywords.countoutcomes()
assert passed_k == 2
assert skipped_k == failed_k == 0


def test_addmarker_getmarker():
node = Node("Test", config=mock.Mock(), session=mock.Mock(), nodeid="Test")
node.add_marker(pytest.mark.a(1))
node.add_marker("b")
node.get_marker("a").combined
node.get_marker("b").combined
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ commands = {[testenv:py27-pexpect]commands}
deps =
pytest-xdist>=1.13
hypothesis>=3.56
mock
distribute = true
changedir=testing
setenv =
Expand Down