blob: 24266ed27f759b577d38e0abb36e84729adc2a80 [file] [log] [blame]
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001"""Unit tests for collections.py."""
2
Guido van Rossumd8faa362007-04-27 19:54:29 +00003import unittest
4from test import test_support
5from collections import NamedTuple
Guido van Rossumcd16bf62007-06-13 18:07:49 +00006from collections import Hashable, Iterable, Iterator
7from collections import Sized, Container, Callable
8from collections import Set, MutableSet
9from collections import Mapping, MutableMapping
10from collections import Sequence, MutableSequence
11
Guido van Rossumd8faa362007-04-27 19:54:29 +000012
13class TestNamedTuple(unittest.TestCase):
14
15 def test_factory(self):
16 Point = NamedTuple('Point', 'x y')
17 self.assertEqual(Point.__name__, 'Point')
18 self.assertEqual(Point.__doc__, 'Point(x, y)')
19 self.assertEqual(Point.__slots__, ())
20 self.assertEqual(Point.__module__, __name__)
21 self.assertEqual(Point.__getitem__, tuple.__getitem__)
Guido van Rossumd59da4b2007-05-22 18:11:13 +000022 self.assertRaises(ValueError, NamedTuple, 'abc%', 'def ghi')
23 self.assertRaises(ValueError, NamedTuple, 'abc', 'def g%hi')
24 NamedTuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
Guido van Rossumd8faa362007-04-27 19:54:29 +000025
26 def test_instance(self):
27 Point = NamedTuple('Point', 'x y')
28 p = Point(11, 22)
29 self.assertEqual(p, Point(x=11, y=22))
30 self.assertEqual(p, Point(11, y=22))
31 self.assertEqual(p, Point(y=22, x=11))
32 self.assertEqual(p, Point(*(11, 22)))
33 self.assertEqual(p, Point(**dict(x=11, y=22)))
34 self.assertRaises(TypeError, Point, 1) # too few args
35 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
36 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
37 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
38 self.assertEqual(repr(p), 'Point(x=11, y=22)')
39 self.assert_('__dict__' not in dir(p)) # verify instance has no dict
40 self.assert_('__weakref__' not in dir(p))
Thomas Wouters1b7f8912007-09-19 03:06:30 +000041 self.assertEqual(p.__fields__, ('x', 'y')) # test __fields__ attribute
42 self.assertEqual(p.__replace__('x', 1), (1, 22)) # test __replace__ method
43
44 # verify that field string can have commas
45 Point = NamedTuple('Point', 'x, y')
46 p = Point(x=11, y=22)
47 self.assertEqual(repr(p), 'Point(x=11, y=22)')
Guido van Rossumd8faa362007-04-27 19:54:29 +000048
49 def test_tupleness(self):
50 Point = NamedTuple('Point', 'x y')
51 p = Point(11, 22)
52
53 self.assert_(isinstance(p, tuple))
54 self.assertEqual(p, (11, 22)) # matches a real tuple
55 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
56 self.assertEqual(list(p), [11, 22]) # coercable to a list
57 self.assertEqual(max(p), 22) # iterable
58 self.assertEqual(max(*p), 22) # star-able
59 x, y = p
60 self.assertEqual(p, (x, y)) # unpacks like a tuple
61 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
62 self.assertRaises(IndexError, p.__getitem__, 3)
63
64 self.assertEqual(p.x, x)
65 self.assertEqual(p.y, y)
66 self.assertRaises(AttributeError, eval, 'p.z', locals())
67
Thomas Wouters1b7f8912007-09-19 03:06:30 +000068 def test_odd_sizes(self):
69 Zero = NamedTuple('Zero', '')
70 self.assertEqual(Zero(), ())
71 Dot = NamedTuple('Dot', 'd')
72 self.assertEqual(Dot(1), (1,))
73
Guido van Rossumd8faa362007-04-27 19:54:29 +000074
Guido van Rossumcd16bf62007-06-13 18:07:49 +000075class TestOneTrickPonyABCs(unittest.TestCase):
76
77 def test_Hashable(self):
78 # Check some non-hashables
79 non_samples = [bytes(), list(), set(), dict()]
80 for x in non_samples:
81 self.failIf(isinstance(x, Hashable), repr(x))
82 self.failIf(issubclass(type(x), Hashable), repr(type(x)))
83 # Check some hashables
84 samples = [None,
85 int(), float(), complex(),
Guido van Rossum07d4e782007-07-03 16:59:47 +000086 str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +000087 tuple(), frozenset(),
88 int, list, object, type,
89 ]
90 for x in samples:
91 self.failUnless(isinstance(x, Hashable), repr(x))
92 self.failUnless(issubclass(type(x), Hashable), repr(type(x)))
93 self.assertRaises(TypeError, Hashable)
94 # Check direct subclassing
95 class H(Hashable):
96 def __hash__(self):
97 return super().__hash__()
98 self.assertEqual(hash(H()), 0)
99 self.failIf(issubclass(int, H))
100
101 def test_Iterable(self):
102 # Check some non-iterables
103 non_samples = [None, 42, 3.14, 1j]
104 for x in non_samples:
105 self.failIf(isinstance(x, Iterable), repr(x))
106 self.failIf(issubclass(type(x), Iterable), repr(type(x)))
107 # Check some iterables
Guido van Rossum07d4e782007-07-03 16:59:47 +0000108 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000109 tuple(), list(), set(), frozenset(), dict(),
110 dict().keys(), dict().items(), dict().values(),
111 (lambda: (yield))(),
112 (x for x in []),
113 ]
114 for x in samples:
115 self.failUnless(isinstance(x, Iterable), repr(x))
116 self.failUnless(issubclass(type(x), Iterable), repr(type(x)))
117 # Check direct subclassing
118 class I(Iterable):
119 def __iter__(self):
120 return super().__iter__()
121 self.assertEqual(list(I()), [])
122 self.failIf(issubclass(str, I))
123
124 def test_Iterator(self):
Guido van Rossum07d4e782007-07-03 16:59:47 +0000125 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()]
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000126 for x in non_samples:
127 self.failIf(isinstance(x, Iterator), repr(x))
128 self.failIf(issubclass(type(x), Iterator), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000129 samples = [iter(bytes()), iter(str()),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000130 iter(tuple()), iter(list()), iter(dict()),
131 iter(set()), iter(frozenset()),
132 iter(dict().keys()), iter(dict().items()),
133 iter(dict().values()),
134 (lambda: (yield))(),
135 (x for x in []),
136 ]
137 for x in samples:
138 self.failUnless(isinstance(x, Iterator), repr(x))
139 self.failUnless(issubclass(type(x), Iterator), repr(type(x)))
140
141 def test_Sized(self):
142 non_samples = [None, 42, 3.14, 1j,
143 (lambda: (yield))(),
144 (x for x in []),
145 ]
146 for x in non_samples:
147 self.failIf(isinstance(x, Sized), repr(x))
148 self.failIf(issubclass(type(x), Sized), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000149 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000150 tuple(), list(), set(), frozenset(), dict(),
151 dict().keys(), dict().items(), dict().values(),
152 ]
153 for x in samples:
154 self.failUnless(isinstance(x, Sized), repr(x))
155 self.failUnless(issubclass(type(x), Sized), repr(type(x)))
156
157 def test_Container(self):
158 non_samples = [None, 42, 3.14, 1j,
159 (lambda: (yield))(),
160 (x for x in []),
161 ]
162 for x in non_samples:
163 self.failIf(isinstance(x, Container), repr(x))
164 self.failIf(issubclass(type(x), Container), repr(type(x)))
Guido van Rossum07d4e782007-07-03 16:59:47 +0000165 samples = [bytes(), str(),
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000166 tuple(), list(), set(), frozenset(), dict(),
167 dict().keys(), dict().items(),
168 ]
169 for x in samples:
170 self.failUnless(isinstance(x, Container), repr(x))
171 self.failUnless(issubclass(type(x), Container), repr(type(x)))
172
173 def test_Callable(self):
174 non_samples = [None, 42, 3.14, 1j,
175 "", b"", (), [], {}, set(),
176 (lambda: (yield))(),
177 (x for x in []),
178 ]
179 for x in non_samples:
180 self.failIf(isinstance(x, Callable), repr(x))
181 self.failIf(issubclass(type(x), Callable), repr(type(x)))
182 samples = [lambda: None,
183 type, int, object,
184 len,
185 list.append, [].append,
186 ]
187 for x in samples:
188 self.failUnless(isinstance(x, Callable), repr(x))
189 self.failUnless(issubclass(type(x), Callable), repr(type(x)))
190
191 def test_direct_subclassing(self):
192 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
193 class C(B):
194 pass
195 self.failUnless(issubclass(C, B))
196 self.failIf(issubclass(int, C))
197
198 def test_registration(self):
199 for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
200 class C:
201 __hash__ = None # Make sure it isn't hashable by default
202 self.failIf(issubclass(C, B), B.__name__)
203 B.register(C)
204 self.failUnless(issubclass(C, B))
205
206
207class TestCollectionABCs(unittest.TestCase):
208
209 # XXX For now, we only test some virtual inheritance properties.
210 # We should also test the proper behavior of the collection ABCs
211 # as real base classes or mix-in classes.
212
213 def test_Set(self):
214 for sample in [set, frozenset]:
215 self.failUnless(isinstance(sample(), Set))
216 self.failUnless(issubclass(sample, Set))
217
218 def test_MutableSet(self):
219 self.failUnless(isinstance(set(), MutableSet))
220 self.failUnless(issubclass(set, MutableSet))
221 self.failIf(isinstance(frozenset(), MutableSet))
222 self.failIf(issubclass(frozenset, MutableSet))
223
224 def test_Mapping(self):
225 for sample in [dict]:
226 self.failUnless(isinstance(sample(), Mapping))
227 self.failUnless(issubclass(sample, Mapping))
228
229 def test_MutableMapping(self):
230 for sample in [dict]:
231 self.failUnless(isinstance(sample(), MutableMapping))
232 self.failUnless(issubclass(sample, MutableMapping))
233
234 def test_Sequence(self):
235 for sample in [tuple, list, bytes, str]:
236 self.failUnless(isinstance(sample(), Sequence))
237 self.failUnless(issubclass(sample, Sequence))
238 self.failUnless(issubclass(basestring, Sequence))
239
240 def test_MutableSequence(self):
241 for sample in [tuple, str]:
242 self.failIf(isinstance(sample(), MutableSequence))
243 self.failIf(issubclass(sample, MutableSequence))
244 for sample in [list, bytes]:
245 self.failUnless(isinstance(sample(), MutableSequence))
246 self.failUnless(issubclass(sample, MutableSequence))
247 self.failIf(issubclass(basestring, MutableSequence))
248
249
Guido van Rossumd8faa362007-04-27 19:54:29 +0000250def test_main(verbose=None):
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000251 import collections as CollectionsModule
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000252 test_classes = [TestNamedTuple, TestOneTrickPonyABCs, TestCollectionABCs]
Guido van Rossumd8faa362007-04-27 19:54:29 +0000253 test_support.run_unittest(*test_classes)
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000254 test_support.run_doctest(CollectionsModule, verbose)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000255
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000256
Guido van Rossumd8faa362007-04-27 19:54:29 +0000257if __name__ == "__main__":
258 test_main(verbose=True)