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:
		
							parent
							
								
									9a21a81740
								
							
						
					
					
						commit
						bd5a9ba392
					
				|  | @ -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 | ||||||
| ---------------------------------------------- | ---------------------------------------------- | ||||||
|  |  | ||||||
|  | @ -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. """ | ||||||
|  |  | ||||||
|  | @ -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): | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue