Issue 27598: Add Collections to collections.abc.

Patch by Ivan Levkivskyi, docs by Neil Girdhar.
This commit is contained in:
Guido van Rossum 2016-08-23 10:47:07 -07:00
parent 9ff4fb3619
commit f0666949fd
5 changed files with 132 additions and 21 deletions

View file

@ -21,7 +21,7 @@ from collections import ChainMap
from collections import deque
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 Sized, Container, Callable, Collection
from collections.abc import Set, MutableSet
from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView
from collections.abc import Sequence, MutableSequence
@ -771,6 +771,94 @@ class TestOneTrickPonyABCs(ABCTestCase):
self.assertFalse(issubclass(RevRevBlocked, Reversible))
self.assertFalse(isinstance(RevRevBlocked(), Reversible))
def test_Collection(self):
# Check some non-collections
non_collections = [None, 42, 3.14, 1j, lambda x: 2*x]
for x in non_collections:
self.assertNotIsInstance(x, Collection)
self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
# Check some non-collection iterables
non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()),
(x for x in []), dict().values()]
for x in non_col_iterables:
self.assertNotIsInstance(x, Collection)
self.assertFalse(issubclass(type(x), Collection), repr(type(x)))
# Check some collections
samples = [set(), frozenset(), dict(), bytes(), str(), tuple(),
list(), dict().keys(), dict().items()]
for x in samples:
self.assertIsInstance(x, Collection)
self.assertTrue(issubclass(type(x), Collection), repr(type(x)))
# Check also Mapping, MutableMapping, etc.
self.assertTrue(issubclass(Sequence, Collection), repr(Sequence))
self.assertTrue(issubclass(Mapping, Collection), repr(Mapping))
self.assertTrue(issubclass(MutableMapping, Collection),
repr(MutableMapping))
self.assertTrue(issubclass(Set, Collection), repr(Set))
self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet))
self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet))
# Check direct subclassing
class Col(Collection):
def __iter__(self):
return iter(list())
def __len__(self):
return 0
def __contains__(self, item):
return False
class DerCol(Col): pass
self.assertEqual(list(iter(Col())), [])
self.assertFalse(issubclass(list, Col))
self.assertFalse(issubclass(set, Col))
self.assertFalse(issubclass(float, Col))
self.assertEqual(list(iter(DerCol())), [])
self.assertFalse(issubclass(list, DerCol))
self.assertFalse(issubclass(set, DerCol))
self.assertFalse(issubclass(float, DerCol))
self.validate_abstract_methods(Collection, '__len__', '__iter__',
'__contains__')
# Check sized container non-iterable (which is not Collection) etc.
class ColNoIter:
def __len__(self): return 0
def __contains__(self, item): return False
class ColNoSize:
def __iter__(self): return iter([])
def __contains__(self, item): return False
class ColNoCont:
def __iter__(self): return iter([])
def __len__(self): return 0
self.assertFalse(issubclass(ColNoIter, Collection))
self.assertFalse(isinstance(ColNoIter(), Collection))
self.assertFalse(issubclass(ColNoSize, Collection))
self.assertFalse(isinstance(ColNoSize(), Collection))
self.assertFalse(issubclass(ColNoCont, Collection))
self.assertFalse(isinstance(ColNoCont(), Collection))
# Check None blocking
class SizeBlock:
def __iter__(self): return iter([])
def __contains__(self): return False
__len__ = None
class IterBlock:
def __len__(self): return 0
def __contains__(self): return True
__iter__ = None
self.assertFalse(issubclass(SizeBlock, Collection))
self.assertFalse(isinstance(SizeBlock(), Collection))
self.assertFalse(issubclass(IterBlock, Collection))
self.assertFalse(isinstance(IterBlock(), Collection))
# Check None blocking in subclass
class ColImpl:
def __iter__(self):
return iter(list())
def __len__(self):
return 0
def __contains__(self, item):
return False
class NonCol(ColImpl):
__contains__ = None
self.assertFalse(issubclass(NonCol, Collection))
self.assertFalse(isinstance(NonCol(), Collection))
def test_Iterator(self):
non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
for x in non_samples: