diff -r 3156dd82df2d Lib/_collections_abc.py --- a/Lib/_collections_abc.py Wed Jun 10 15:44:18 2015 -0700 +++ b/Lib/_collections_abc.py Thu Jun 11 11:30:10 2015 -0700 @@ -672,13 +672,11 @@ return set(it) def __contains__(self, item): - key, value = item - try: - v = self._mapping[key] - except KeyError: + # ItemsViews technically behave like sets of *tuple pairs*, and + # should reject lists, and improperly sized tuples. + if not isinstance(item, tuple) or len(item) != 2: return False - else: - return v == value + return item[0] in self._mapping and self._mapping[item[0]] == item[1] def __iter__(self): for key in self._mapping: diff -r 3156dd82df2d Lib/test/test_collections.py --- a/Lib/test/test_collections.py Wed Jun 10 15:44:18 2015 -0700 +++ b/Lib/test/test_collections.py Thu Jun 11 11:30:10 2015 -0700 @@ -1343,6 +1343,34 @@ mss.clear() self.assertEqual(len(mss), 0) + def test_ItemsView_contains(self): + # Ensure that ItemsView mimics the behavior of dict.items() + class DictLikeMapping(Mapping): + def __init__(self, *args, **kwargs): + self._mapping = dict(*args, **kwargs) + def __getitem__(self, key): + return self._mapping[key] + def __iter__(self): + return iter(self._mapping) + def __len__(self): + return len(self._mapping) + d = DictLikeMapping(a=1, b=2, c=3) + ditems = d.items() + ddict = dict(d) + self.assertIsInstance(ditems, ItemsView) + # Corner cases designed to match dict.items(). In particular test the + # list and generator are not in the ItemsView as they are not tuples, + # which are the elements of a dict_view set. + NotIn = ["a", ("a", ), 1, ["a", 1], (i for i in ("a", 1))] + for el in NotIn: + self.assertNotIn(el, ditems) + self.assertEqual(el in ditems, el in ddict.items()) + for el in zip(d.keys(), d.values()): + self.assertIn(el, ditems) + gen = NotIn[-1] + # Testing if x is in X should not affect x for items. + self.assertEqual("a", next(gen)) + ################################################################################ ### Counter ################################################################################