jenkins-bot has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1331669?usp=email )

Change subject: itertools: Preserve colliding intersection items
......................................................................

itertools: Preserve colliding intersection items

Keep yielded items in the seen set instead of storing only their hash
values. Set membership then resolves collisions with equality, preventing
unequal items from being silently discarded.

Change-Id: Idcbde6948c95a5c73f50a4a921b36dfe3c297bb1
---
M pywikibot/tools/itertools.py
M tests/tools_tests.py
2 files changed, 16 insertions(+), 3 deletions(-)

Approvals:
  Xqt: Looks good to me, approved
  jenkins-bot: Verified




diff --git a/pywikibot/tools/itertools.py b/pywikibot/tools/itertools.py
index 457face..c32ac4a 100644
--- a/pywikibot/tools/itertools.py
+++ b/pywikibot/tools/itertools.py
@@ -158,7 +158,7 @@

     ones = collections.Counter(range(n_gen))
     active_iterables = set(range(n_gen))
-    seen = set()
+    seen: set[Hashable] = set()

     # Get items from iterables in a round-robin way.
     sentinel = object()
@@ -169,7 +169,7 @@
                 active_iterables.discard(index)
                 continue

-            if not allow_duplicates and hash(item) in seen:
+            if not allow_duplicates and item in seen:
                 continue

             # Each cache entry is a Counter of iterables' index
@@ -181,7 +181,7 @@
                 # Remove item from cache if possible or decrease Counter entry
                 if not allow_duplicates:
                     del cache[item]
-                    seen.add(hash(item))
+                    seen.add(item)
                 elif cache[item] == ones:
                     del cache[item]
                 else:
diff --git a/tests/tools_tests.py b/tests/tools_tests.py
index 9ae9c68..14c73d9 100755
--- a/tests/tools_tests.py
+++ b/tests/tools_tests.py
@@ -823,6 +823,19 @@
         """Test basic intersect with duplicates."""
         self.assertEqualItertools(['aabc', 'dddb', 'baa'])

+    def test_intersect_hash_collision(self) -> None:
+        """Test unequal items with the same hash are not deduplicated."""
+        class CollidingInt(int):
+
+            """Integer whose instances all share one hash value."""
+
+            def __hash__(self) -> int:
+                """Return a constant hash."""
+                return 1
+
+        values = [CollidingInt(1), CollidingInt(2)]
+        self.assertEqualItertools([values, values])
+
     def test_intersect_with_accepted_dups(self) -> None:
         """Test intersect with duplicates accepted."""
         self.assertEqualItertoolsWithDuplicates(['abc', 'db', 'ba'])

--
To view, visit 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1331669?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.wikimedia.org/r/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Idcbde6948c95a5c73f50a4a921b36dfe3c297bb1
Gerrit-Change-Number: 1331669
Gerrit-PatchSet: 2
Gerrit-Owner: Mahveotm <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to