diff --git a/CHANGELOG b/CHANGELOG index 520e4c93c..f646e7502 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -38,7 +38,7 @@ Changes between 1.3.4 and 2.0.0dev0 - fix bug: unittest collected functions now also can have "pytestmark" applied at class/module level - add ability to use "class" level for cached_setup helper - +- fix strangeness: mark.* objects are now immutable, create new instances Changes between 1.3.3 and 1.3.4 ---------------------------------------------- diff --git a/_pytest/mark.py b/_pytest/mark.py index 55ea0485b..5383e3a9d 100644 --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -101,10 +101,10 @@ class MarkDecorator: def test_function(): pass """ - def __init__(self, name): + def __init__(self, name, args=None, kwargs=None): self.markname = name - self.kwargs = {} - self.args = [] + self.args = args or () + self.kwargs = kwargs or {} def __repr__(self): d = self.__dict__.copy() @@ -134,12 +134,12 @@ class MarkDecorator: setattr(func, self.markname, holder) else: holder.kwargs.update(self.kwargs) - holder.args.extend(self.args) + holder.args += self.args return func - else: - self.args.extend(args) - self.kwargs.update(kwargs) - return self + kw = self.kwargs.copy() + kw.update(kwargs) + args = self.args + args + return self.__class__(self.markname, args=args, kwargs=kw) class MarkInfo: """ Marking object created by :class:`MarkDecorator` instances. """ diff --git a/testing/test_mark.py b/testing/test_mark.py index e8f747dc4..701b03915 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -48,6 +48,21 @@ class TestMark: assert f.world.args[0] == "hello" mark.world("world")(f) + def test_pytest_mark_reuse(self): + mark = Mark() + def f(): + pass + w = mark.some + w("hello", reason="123")(f) + assert f.some.args[0] == "hello" + assert f.some.kwargs['reason'] == "123" + def g(): + pass + w("world", reason2="456")(g) + assert g.some.args[0] == "world" + assert 'reason' not in g.some.kwargs + assert g.some.kwargs['reason2'] == "456" + class TestFunctional: def test_mark_per_function(self, testdir): p = testdir.makepyfile(""" @@ -136,7 +151,7 @@ class TestFunctional: item, = items keywords = item.keywords marker = keywords['hello'] - assert marker.args == ["pos0", "pos1"] + assert marker.args == ("pos0", "pos1") assert marker.kwargs == {'x': 3, 'y': 2, 'z': 4} def test_mark_other(self, testdir):