mirror of
https://github.com/python/cpython.git
synced 2025-11-01 14:11:41 +00:00

svn+ssh://pythondev@svn.python.org/python/trunk ........ r59343 | georg.brandl | 2007-12-05 08:02:47 +0100 (Wed, 05 Dec 2007) | 2 lines Fix typo. ........ r59347 | christian.heimes | 2007-12-05 13:31:44 +0100 (Wed, 05 Dec 2007) | 1 line Fixed quoting and paths in the sqlite project file ........ r59348 | christian.heimes | 2007-12-05 13:45:11 +0100 (Wed, 05 Dec 2007) | 1 line Fixed error in regrtest. I must have missed the spot. ........ r59350 | christian.heimes | 2007-12-05 13:49:14 +0100 (Wed, 05 Dec 2007) | 1 line merge -r59315:59316 from py3k: Fix issue #1553: An errornous __length_hint__ can make list() raise a SystemError ........ r59352 | christian.heimes | 2007-12-05 13:52:34 +0100 (Wed, 05 Dec 2007) | 1 line Added msg to Misc/NEWS ........ r59354 | andrew.kuchling | 2007-12-05 14:27:20 +0100 (Wed, 05 Dec 2007) | 1 line Spelling fix ........ r59356 | georg.brandl | 2007-12-05 18:56:50 +0100 (Wed, 05 Dec 2007) | 3 lines Add examples to csv, pprint and traceback docs. Written by Ross for GHOP. ........ r59358 | raymond.hettinger | 2007-12-05 19:11:08 +0100 (Wed, 05 Dec 2007) | 1 line Error checking was too aggressive (reported by Chris Tismer) ........ r59359 | georg.brandl | 2007-12-05 19:30:48 +0100 (Wed, 05 Dec 2007) | 2 lines Add examples to re docs. Written for GHOP by Dan Finnie. ........ r59366 | georg.brandl | 2007-12-05 20:49:21 +0100 (Wed, 05 Dec 2007) | 2 lines Fix markup. ........ r59367 | christian.heimes | 2007-12-05 20:57:54 +0100 (Wed, 05 Dec 2007) | 1 line Updated documentation and build_tkinter.py script ........ r59368 | georg.brandl | 2007-12-05 21:03:57 +0100 (Wed, 05 Dec 2007) | 2 lines Another markup fix. ........ r59369 | ronald.oussoren | 2007-12-05 21:07:36 +0100 (Wed, 05 Dec 2007) | 7 lines This "fixes" compilation issues for the Carbon._OSA module on OSX Leopard by purging bindings to OSA's debug API's. Those APIs we're completely unsupported on OSX 10.4 and are no longer available on OSX 10.5. Note that this patches a generated file. This is somewhat acceptable because regenerating the file is non-trivial and wouldn't use system headers anyway. ........ r59370 | christian.heimes | 2007-12-05 21:10:38 +0100 (Wed, 05 Dec 2007) | 1 line Fixed bug #1557 by using popen.communicate() before popen.wait() ........
293 lines
12 KiB
Python
293 lines
12 KiB
Python
"""Unit tests for collections.py."""
|
|
|
|
import unittest
|
|
from test import test_support
|
|
from collections import namedtuple
|
|
from collections import Hashable, Iterable, Iterator
|
|
from collections import Sized, Container, Callable
|
|
from collections import Set, MutableSet
|
|
from collections import Mapping, MutableMapping
|
|
from collections import Sequence, MutableSequence
|
|
from collections import ByteString
|
|
|
|
|
|
class TestNamedTuple(unittest.TestCase):
|
|
|
|
def test_factory(self):
|
|
Point = namedtuple('Point', 'x y')
|
|
self.assertEqual(Point.__name__, 'Point')
|
|
self.assertEqual(Point.__doc__, 'Point(x, y)')
|
|
self.assertEqual(Point.__slots__, ())
|
|
self.assertEqual(Point.__module__, __name__)
|
|
self.assertEqual(Point.__getitem__, tuple.__getitem__)
|
|
|
|
self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
|
|
self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
|
|
self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
|
|
|
|
self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
|
|
self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
|
|
self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
|
|
self.assertRaises(ValueError, namedtuple, 'abc', '__efg__ ghi') # field with double underscores
|
|
self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
|
|
|
|
namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
|
|
namedtuple('_', '_ __ ___') # Verify that underscores are allowed
|
|
|
|
def test_instance(self):
|
|
Point = namedtuple('Point', 'x y')
|
|
p = Point(11, 22)
|
|
self.assertEqual(p, Point(x=11, y=22))
|
|
self.assertEqual(p, Point(11, y=22))
|
|
self.assertEqual(p, Point(y=22, x=11))
|
|
self.assertEqual(p, Point(*(11, 22)))
|
|
self.assertEqual(p, Point(**dict(x=11, y=22)))
|
|
self.assertRaises(TypeError, Point, 1) # too few args
|
|
self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
|
|
self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
|
|
self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
|
|
self.assertEqual(repr(p), 'Point(x=11, y=22)')
|
|
self.assert_('__dict__' not in dir(p)) # verify instance has no dict
|
|
self.assert_('__weakref__' not in dir(p))
|
|
self.assertEqual(p.__fields__, ('x', 'y')) # test __fields__ attribute
|
|
self.assertEqual(p.__replace__(x=1), (1, 22)) # test __replace__ method
|
|
self.assertEqual(p.__asdict__(), dict(x=11, y=22)) # test __dict__ method
|
|
|
|
# Verify that __fields__ is read-only
|
|
try:
|
|
p.__fields__ = ('F1' ,'F2')
|
|
except AttributeError:
|
|
pass
|
|
else:
|
|
self.fail('The __fields__ attribute needs to be read-only')
|
|
|
|
# verify that field string can have commas
|
|
Point = namedtuple('Point', 'x, y')
|
|
p = Point(x=11, y=22)
|
|
self.assertEqual(repr(p), 'Point(x=11, y=22)')
|
|
|
|
# verify that fieldspec can be a non-string sequence
|
|
Point = namedtuple('Point', ('x', 'y'))
|
|
p = Point(x=11, y=22)
|
|
self.assertEqual(repr(p), 'Point(x=11, y=22)')
|
|
|
|
def test_tupleness(self):
|
|
Point = namedtuple('Point', 'x y')
|
|
p = Point(11, 22)
|
|
|
|
self.assert_(isinstance(p, tuple))
|
|
self.assertEqual(p, (11, 22)) # matches a real tuple
|
|
self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
|
|
self.assertEqual(list(p), [11, 22]) # coercable to a list
|
|
self.assertEqual(max(p), 22) # iterable
|
|
self.assertEqual(max(*p), 22) # star-able
|
|
x, y = p
|
|
self.assertEqual(p, (x, y)) # unpacks like a tuple
|
|
self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
|
|
self.assertRaises(IndexError, p.__getitem__, 3)
|
|
|
|
self.assertEqual(p.x, x)
|
|
self.assertEqual(p.y, y)
|
|
self.assertRaises(AttributeError, eval, 'p.z', locals())
|
|
|
|
def test_odd_sizes(self):
|
|
Zero = namedtuple('Zero', '')
|
|
self.assertEqual(Zero(), ())
|
|
Dot = namedtuple('Dot', 'd')
|
|
self.assertEqual(Dot(1), (1,))
|
|
|
|
|
|
class TestOneTrickPonyABCs(unittest.TestCase):
|
|
|
|
def test_Hashable(self):
|
|
# Check some non-hashables
|
|
non_samples = [bytearray(), list(), set(), dict()]
|
|
for x in non_samples:
|
|
self.failIf(isinstance(x, Hashable), repr(x))
|
|
self.failIf(issubclass(type(x), Hashable), repr(type(x)))
|
|
# Check some hashables
|
|
samples = [None,
|
|
int(), float(), complex(),
|
|
str(),
|
|
tuple(), frozenset(),
|
|
int, list, object, type, bytes()
|
|
]
|
|
for x in samples:
|
|
self.failUnless(isinstance(x, Hashable), repr(x))
|
|
self.failUnless(issubclass(type(x), Hashable), repr(type(x)))
|
|
self.assertRaises(TypeError, Hashable)
|
|
# Check direct subclassing
|
|
class H(Hashable):
|
|
def __hash__(self):
|
|
return super().__hash__()
|
|
self.assertEqual(hash(H()), 0)
|
|
self.failIf(issubclass(int, H))
|
|
|
|
def test_Iterable(self):
|
|
# Check some non-iterables
|
|
non_samples = [None, 42, 3.14, 1j]
|
|
for x in non_samples:
|
|
self.failIf(isinstance(x, Iterable), repr(x))
|
|
self.failIf(issubclass(type(x), Iterable), repr(type(x)))
|
|
# Check some iterables
|
|
samples = [bytes(), str(),
|
|
tuple(), list(), set(), frozenset(), dict(),
|
|
dict().keys(), dict().items(), dict().values(),
|
|
(lambda: (yield))(),
|
|
(x for x in []),
|
|
]
|
|
for x in samples:
|
|
self.failUnless(isinstance(x, Iterable), repr(x))
|
|
self.failUnless(issubclass(type(x), Iterable), repr(type(x)))
|
|
# Check direct subclassing
|
|
class I(Iterable):
|
|
def __iter__(self):
|
|
return super().__iter__()
|
|
self.assertEqual(list(I()), [])
|
|
self.failIf(issubclass(str, I))
|
|
|
|
def test_Iterator(self):
|
|
non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
|
|
for x in non_samples:
|
|
self.failIf(isinstance(x, Iterator), repr(x))
|
|
self.failIf(issubclass(type(x), Iterator), repr(type(x)))
|
|
samples = [iter(bytes()), iter(str()),
|
|
iter(tuple()), iter(list()), iter(dict()),
|
|
iter(set()), iter(frozenset()),
|
|
iter(dict().keys()), iter(dict().items()),
|
|
iter(dict().values()),
|
|
(lambda: (yield))(),
|
|
(x for x in []),
|
|
]
|
|
for x in samples:
|
|
self.failUnless(isinstance(x, Iterator), repr(x))
|
|
self.failUnless(issubclass(type(x), Iterator), repr(type(x)))
|
|
|
|
def test_Sized(self):
|
|
non_samples = [None, 42, 3.14, 1j,
|
|
(lambda: (yield))(),
|
|
(x for x in []),
|
|
]
|
|
for x in non_samples:
|
|
self.failIf(isinstance(x, Sized), repr(x))
|
|
self.failIf(issubclass(type(x), Sized), repr(type(x)))
|
|
samples = [bytes(), str(),
|
|
tuple(), list(), set(), frozenset(), dict(),
|
|
dict().keys(), dict().items(), dict().values(),
|
|
]
|
|
for x in samples:
|
|
self.failUnless(isinstance(x, Sized), repr(x))
|
|
self.failUnless(issubclass(type(x), Sized), repr(type(x)))
|
|
|
|
def test_Container(self):
|
|
non_samples = [None, 42, 3.14, 1j,
|
|
(lambda: (yield))(),
|
|
(x for x in []),
|
|
]
|
|
for x in non_samples:
|
|
self.failIf(isinstance(x, Container), repr(x))
|
|
self.failIf(issubclass(type(x), Container), repr(type(x)))
|
|
samples = [bytes(), str(),
|
|
tuple(), list(), set(), frozenset(), dict(),
|
|
dict().keys(), dict().items(),
|
|
]
|
|
for x in samples:
|
|
self.failUnless(isinstance(x, Container), repr(x))
|
|
self.failUnless(issubclass(type(x), Container), repr(type(x)))
|
|
|
|
def test_Callable(self):
|
|
non_samples = [None, 42, 3.14, 1j,
|
|
"", b"", (), [], {}, set(),
|
|
(lambda: (yield))(),
|
|
(x for x in []),
|
|
]
|
|
for x in non_samples:
|
|
self.failIf(isinstance(x, Callable), repr(x))
|
|
self.failIf(issubclass(type(x), Callable), repr(type(x)))
|
|
samples = [lambda: None,
|
|
type, int, object,
|
|
len,
|
|
list.append, [].append,
|
|
]
|
|
for x in samples:
|
|
self.failUnless(isinstance(x, Callable), repr(x))
|
|
self.failUnless(issubclass(type(x), Callable), repr(type(x)))
|
|
|
|
def test_direct_subclassing(self):
|
|
for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
|
|
class C(B):
|
|
pass
|
|
self.failUnless(issubclass(C, B))
|
|
self.failIf(issubclass(int, C))
|
|
|
|
def test_registration(self):
|
|
for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
|
|
class C:
|
|
__hash__ = None # Make sure it isn't hashable by default
|
|
self.failIf(issubclass(C, B), B.__name__)
|
|
B.register(C)
|
|
self.failUnless(issubclass(C, B))
|
|
|
|
|
|
class TestCollectionABCs(unittest.TestCase):
|
|
|
|
# XXX For now, we only test some virtual inheritance properties.
|
|
# We should also test the proper behavior of the collection ABCs
|
|
# as real base classes or mix-in classes.
|
|
|
|
def test_Set(self):
|
|
for sample in [set, frozenset]:
|
|
self.failUnless(isinstance(sample(), Set))
|
|
self.failUnless(issubclass(sample, Set))
|
|
|
|
def test_MutableSet(self):
|
|
self.failUnless(isinstance(set(), MutableSet))
|
|
self.failUnless(issubclass(set, MutableSet))
|
|
self.failIf(isinstance(frozenset(), MutableSet))
|
|
self.failIf(issubclass(frozenset, MutableSet))
|
|
|
|
def test_Mapping(self):
|
|
for sample in [dict]:
|
|
self.failUnless(isinstance(sample(), Mapping))
|
|
self.failUnless(issubclass(sample, Mapping))
|
|
|
|
def test_MutableMapping(self):
|
|
for sample in [dict]:
|
|
self.failUnless(isinstance(sample(), MutableMapping))
|
|
self.failUnless(issubclass(sample, MutableMapping))
|
|
|
|
def test_Sequence(self):
|
|
for sample in [tuple, list, bytes, str]:
|
|
self.failUnless(isinstance(sample(), Sequence))
|
|
self.failUnless(issubclass(sample, Sequence))
|
|
self.failUnless(issubclass(str, Sequence))
|
|
|
|
def test_ByteString(self):
|
|
for sample in [bytes, bytearray]:
|
|
self.failUnless(isinstance(sample(), ByteString))
|
|
self.failUnless(issubclass(sample, ByteString))
|
|
for sample in [str, list, tuple]:
|
|
self.failIf(isinstance(sample(), ByteString))
|
|
self.failIf(issubclass(sample, ByteString))
|
|
self.failIf(isinstance(memoryview(b""), ByteString))
|
|
self.failIf(issubclass(memoryview, ByteString))
|
|
|
|
def test_MutableSequence(self):
|
|
for sample in [tuple, str, bytes]:
|
|
self.failIf(isinstance(sample(), MutableSequence))
|
|
self.failIf(issubclass(sample, MutableSequence))
|
|
for sample in [list, bytearray]:
|
|
self.failUnless(isinstance(sample(), MutableSequence))
|
|
self.failUnless(issubclass(sample, MutableSequence))
|
|
self.failIf(issubclass(str, MutableSequence))
|
|
|
|
|
|
def test_main(verbose=None):
|
|
import collections as CollectionsModule
|
|
test_classes = [TestNamedTuple, TestOneTrickPonyABCs, TestCollectionABCs]
|
|
test_support.run_unittest(*test_classes)
|
|
test_support.run_doctest(CollectionsModule, verbose)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
test_main(verbose=True)
|