fix: mark.* objects are now immutable as long as they are not an attribute on a function, enables usage like this::

xfail = pytest.mark.xfail

    @xfail
    def test_func1():
        pass

    @xfail(reason="123")
    def test_func2():
        pass

where previously test_func1 and test_func2 would wrongly share the same reason
because the xfail object was modified in place.
This commit is contained in:
holger krekel 2010-11-20 20:17:38 +01:00
parent 9a21a81740
commit bd5a9ba392
3 changed files with 25 additions and 10 deletions

View File

@ -38,7 +38,7 @@ Changes between 1.3.4 and 2.0.0dev0
- fix bug: unittest collected functions now also can have "pytestmark" - fix bug: unittest collected functions now also can have "pytestmark"
applied at class/module level applied at class/module level
- add ability to use "class" level for cached_setup helper - 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 Changes between 1.3.3 and 1.3.4
---------------------------------------------- ----------------------------------------------

View File

@ -101,10 +101,10 @@ class MarkDecorator:
def test_function(): def test_function():
pass pass
""" """
def __init__(self, name): def __init__(self, name, args=None, kwargs=None):
self.markname = name self.markname = name
self.kwargs = {} self.args = args or ()
self.args = [] self.kwargs = kwargs or {}
def __repr__(self): def __repr__(self):
d = self.__dict__.copy() d = self.__dict__.copy()
@ -134,12 +134,12 @@ class MarkDecorator:
setattr(func, self.markname, holder) setattr(func, self.markname, holder)
else: else:
holder.kwargs.update(self.kwargs) holder.kwargs.update(self.kwargs)
holder.args.extend(self.args) holder.args += self.args
return func return func
else: kw = self.kwargs.copy()
self.args.extend(args) kw.update(kwargs)
self.kwargs.update(kwargs) args = self.args + args
return self return self.__class__(self.markname, args=args, kwargs=kw)
class MarkInfo: class MarkInfo:
""" Marking object created by :class:`MarkDecorator` instances. """ """ Marking object created by :class:`MarkDecorator` instances. """

View File

@ -48,6 +48,21 @@ class TestMark:
assert f.world.args[0] == "hello" assert f.world.args[0] == "hello"
mark.world("world")(f) 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: class TestFunctional:
def test_mark_per_function(self, testdir): def test_mark_per_function(self, testdir):
p = testdir.makepyfile(""" p = testdir.makepyfile("""
@ -136,7 +151,7 @@ class TestFunctional:
item, = items item, = items
keywords = item.keywords keywords = item.keywords
marker = keywords['hello'] marker = keywords['hello']
assert marker.args == ["pos0", "pos1"] assert marker.args == ("pos0", "pos1")
assert marker.kwargs == {'x': 3, 'y': 2, 'z': 4} assert marker.kwargs == {'x': 3, 'y': 2, 'z': 4}
def test_mark_other(self, testdir): def test_mark_other(self, testdir):