Skip to content

Commit d909411

Browse files
fix #10447 - consider marks in reverse mro order to give base classes priority
1 parent 2f7415c commit d909411

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

changelog/10447.bugfix.rst

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
markers are now considered in the reverse mro order to ensure base class markers are considered first
2+
this resolves a regression.

src/_pytest/mark/structures.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,9 @@ def get_unpacked_marks(
374374
if not consider_mro:
375375
mark_lists = [obj.__dict__.get("pytestmark", [])]
376376
else:
377-
mark_lists = [x.__dict__.get("pytestmark", []) for x in obj.__mro__]
377+
mark_lists = [
378+
x.__dict__.get("pytestmark", []) for x in reversed(obj.__mro__)
379+
]
378380
mark_list = []
379381
for item in mark_lists:
380382
if isinstance(item, list):

testing/test_mark.py

+36-1
Original file line numberDiff line numberDiff line change
@@ -1130,6 +1130,41 @@ class C(A, B):
11301130

11311131
all_marks = get_unpacked_marks(C)
11321132

1133-
assert all_marks == [xfail("c").mark, xfail("a").mark, xfail("b").mark]
1133+
assert all_marks == [xfail("b").mark, xfail("a").mark, xfail("c").mark]
11341134

11351135
assert get_unpacked_marks(C, consider_mro=False) == [xfail("c").mark]
1136+
1137+
1138+
@pytest.mark.issue("https://github.com/pytest-dev/pytest/issues/10447")
1139+
def test_mark_fixture_order_mro(pytester: Pytester):
1140+
"""This ensures we walk marks of the mro starting with the base classes
1141+
the action at a distance fixtures are taken as minimal example from a real project
1142+
1143+
"""
1144+
foo = pytester.makepyfile(
1145+
"""
1146+
import pytest
1147+
1148+
@pytest.fixture
1149+
def add_attr1(request):
1150+
request.instance.attr1 = object()
1151+
1152+
1153+
@pytest.fixture
1154+
def add_attr2(request):
1155+
request.instance.attr2 = request.instance.attr1
1156+
1157+
1158+
@pytest.mark.usefixtures('add_attr1')
1159+
class Parent:
1160+
pass
1161+
1162+
1163+
@pytest.mark.usefixtures('add_attr2')
1164+
class TestThings(Parent):
1165+
def test_attrs(self):
1166+
assert self.attr1 == self.attr2
1167+
"""
1168+
)
1169+
result = pytester.run(foo)
1170+
result.assert_outcomes(passed=1)

0 commit comments

Comments
 (0)