Issue 26915: Add identity checks to the collections ABC __contains__ methods.

This commit is contained in:
Raymond Hettinger 2016-05-05 11:14:06 +03:00
parent d7062de95d
commit 584e8aedc3
3 changed files with 30 additions and 4 deletions

View File

@ -689,7 +689,7 @@ class ItemsView(MappingView, Set):
except KeyError:
return False
else:
return v == value
return v is value or v == value
def __iter__(self):
for key in self._mapping:
@ -704,7 +704,8 @@ class ValuesView(MappingView):
def __contains__(self, value):
for key in self._mapping:
if value == self._mapping[key]:
v = self._mapping[key]
if v is value or v == value:
return True
return False
@ -839,7 +840,7 @@ class Sequence(Sized, Reversible, Container):
def __contains__(self, value):
for v in self:
if v == value:
if v is value or v == value:
return True
return False

View File

@ -23,7 +23,7 @@ from collections.abc import Awaitable, Coroutine, AsyncIterator, AsyncIterable
from collections.abc import Hashable, Iterable, Iterator, Generator, Reversible
from collections.abc import Sized, Container, Callable
from collections.abc import Set, MutableSet
from collections.abc import Mapping, MutableMapping, KeysView, ItemsView
from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView
from collections.abc import Sequence, MutableSequence
from collections.abc import ByteString
@ -1074,6 +1074,26 @@ class TestCollectionABCs(ABCTestCase):
self.assertFalse(ncs > cs)
self.assertTrue(ncs >= cs)
def test_issue26915(self):
# Container membership test should check identity first
class CustomEqualObject:
def __eq__(self, other):
return False
class CustomSequence(list):
def __contains__(self, value):
return Sequence.__contains__(self, value)
nan = float('nan')
obj = CustomEqualObject()
containers = [
CustomSequence([nan, obj]),
ItemsView({1: nan, 2: obj}),
ValuesView({1: nan, 2: obj})
]
for container in containers:
for elem in container:
self.assertIn(elem, container)
def assertSameSet(self, s1, s2):
# coerce both to a real set then check equality
self.assertSetEqual(set(s1), set(s2))

View File

@ -268,6 +268,11 @@ Library
- Issue #26873: xmlrpc now raises ResponseError on unsupported type tags
instead of silently return incorrect result.
- Issue #26915: The __contains__ methods in the collections ABCs now check
for identity before checking equality. This better matches the behavior
of the concrete classes, allows sensible handling of NaNs, and makes it
easier to reason about container invariants.
- Issue #26711: Fixed the comparison of plistlib.Data with other types.
- Issue #24114: Fix an uninitialized variable in `ctypes.util`.