Merge pull request #11155 from RonnyPfannschmidt/fix-10447-maker-mro-order-needs-reverse
fix #10447 - consider marks in reverse mro order to give base classes priority
This commit is contained in:
		
						commit
						f9410fddcd
					
				| 
						 | 
					@ -0,0 +1,2 @@
 | 
				
			||||||
 | 
					markers are now considered in the reverse mro order to ensure base  class markers are considered first
 | 
				
			||||||
 | 
					this resolves a regression.
 | 
				
			||||||
| 
						 | 
					@ -374,7 +374,9 @@ def get_unpacked_marks(
 | 
				
			||||||
        if not consider_mro:
 | 
					        if not consider_mro:
 | 
				
			||||||
            mark_lists = [obj.__dict__.get("pytestmark", [])]
 | 
					            mark_lists = [obj.__dict__.get("pytestmark", [])]
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            mark_lists = [x.__dict__.get("pytestmark", []) for x in obj.__mro__]
 | 
					            mark_lists = [
 | 
				
			||||||
 | 
					                x.__dict__.get("pytestmark", []) for x in reversed(obj.__mro__)
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
        mark_list = []
 | 
					        mark_list = []
 | 
				
			||||||
        for item in mark_lists:
 | 
					        for item in mark_lists:
 | 
				
			||||||
            if isinstance(item, list):
 | 
					            if isinstance(item, list):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1130,6 +1130,41 @@ def test_mark_mro() -> None:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    all_marks = get_unpacked_marks(C)
 | 
					    all_marks = get_unpacked_marks(C)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert all_marks == [xfail("c").mark, xfail("a").mark, xfail("b").mark]
 | 
					    assert all_marks == [xfail("b").mark, xfail("a").mark, xfail("c").mark]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert get_unpacked_marks(C, consider_mro=False) == [xfail("c").mark]
 | 
					    assert get_unpacked_marks(C, consider_mro=False) == [xfail("c").mark]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# @pytest.mark.issue("https://github.com/pytest-dev/pytest/issues/10447")
 | 
				
			||||||
 | 
					def test_mark_fixture_order_mro(pytester: Pytester):
 | 
				
			||||||
 | 
					    """This ensures we walk marks of the mro starting with the base classes
 | 
				
			||||||
 | 
					    the action at a distance fixtures are taken as minimal example from a real project
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    foo = pytester.makepyfile(
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @pytest.fixture
 | 
				
			||||||
 | 
					        def add_attr1(request):
 | 
				
			||||||
 | 
					            request.instance.attr1 = object()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @pytest.fixture
 | 
				
			||||||
 | 
					        def add_attr2(request):
 | 
				
			||||||
 | 
					            request.instance.attr2 = request.instance.attr1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @pytest.mark.usefixtures('add_attr1')
 | 
				
			||||||
 | 
					        class Parent:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @pytest.mark.usefixtures('add_attr2')
 | 
				
			||||||
 | 
					        class TestThings(Parent):
 | 
				
			||||||
 | 
					            def test_attrs(self):
 | 
				
			||||||
 | 
					                assert self.attr1 == self.attr2
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    result = pytester.runpytest(foo)
 | 
				
			||||||
 | 
					    result.assert_outcomes(passed=1)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue