Skip to content

Commit

Permalink
Merge pull request #9168 from bluetech/node-keywords-dups
Browse files Browse the repository at this point in the history
mark/structures: fix NodeKeywords.{__iter__,__len__} given duplicates
  • Loading branch information
bluetech authored Oct 6, 2021
2 parents c9267af + cf4495f commit e077f1c
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
11 changes: 7 additions & 4 deletions src/_pytest/mark/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,14 +579,17 @@ def __delitem__(self, key: str) -> None:
raise ValueError("cannot delete key in keywords dict")

def __iter__(self) -> Iterator[str]:
# Doesn't need to be fast.
yield from self._markers
if self.parent is not None:
yield from self.parent.keywords
for keyword in self.parent.keywords:
# self._marks and self.parent.keywords can have duplicates.
if keyword not in self._markers:
yield keyword

def __len__(self) -> int:
return len(self._markers) + (
len(self.parent.keywords) if self.parent is not None else 0
)
# Doesn't need to be fast.
return sum(1 for keyword in self)

def __repr__(self) -> str:
return f"<NodeKeywords for node {self.node}>"
20 changes: 19 additions & 1 deletion testing/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ def runtest(self):
res.stdout.fnmatch_lines(["*1 passed*"])


class TestNodekeywords:
class TestNodeKeywords:
def test_no_under(self, pytester: Pytester) -> None:
modcol = pytester.getmodulecol(
"""
Expand Down Expand Up @@ -859,6 +859,24 @@ def test_failing_5():
reprec = pytester.inline_run("-k " + expression)
reprec.assertoutcome(passed=num_matching_tests, failed=0)

def test_duplicates_handled_correctly(self, pytester: Pytester) -> None:
item = pytester.getitem(
"""
import pytest
pytestmark = pytest.mark.kw
class TestClass:
pytestmark = pytest.mark.kw
def test_method(self): pass
test_method.kw = 'method'
""",
"test_method",
)
assert item.parent is not None and item.parent.parent is not None
item.parent.parent.keywords["kw"] = "class"

assert item.keywords["kw"] == "method"
assert len(item.keywords) == len(set(item.keywords))


COLLECTION_ERROR_PY_FILES = dict(
test_01_failure="""
Expand Down

0 comments on commit e077f1c

Please sign in to comment.