diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py
index 7de8f9f54..0e42cd8de 100644
--- a/src/_pytest/mark/structures.py
+++ b/src/_pytest/mark/structures.py
@@ -579,14 +579,17 @@ class NodeKeywords(MutableMapping[str, Any]):
         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}>"
diff --git a/testing/test_collection.py b/testing/test_collection.py
index 1ea569f71..6532959cb 100644
--- a/testing/test_collection.py
+++ b/testing/test_collection.py
@@ -793,7 +793,7 @@ def test_matchnodes_two_collections_same_file(pytester: Pytester) -> None:
     res.stdout.fnmatch_lines(["*1 passed*"])
 
 
-class TestNodekeywords:
+class TestNodeKeywords:
     def test_no_under(self, pytester: Pytester) -> None:
         modcol = pytester.getmodulecol(
             """
@@ -859,6 +859,24 @@ class TestNodekeywords:
             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="""