blob: 729cc3b209ca84f96427ebf4c3ce19e9a9047670 [file] [log] [blame]
Raymond Hettingera690a992003-11-16 16:17:49 +00001import unittest
2from test import test_support
Raymond Hettinger691d8052004-05-30 07:26:47 +00003from weakref import proxy
Raymond Hettingera690a992003-11-16 16:17:49 +00004import operator
5import copy
6import pickle
Raymond Hettingereae05de2004-07-09 04:51:24 +00007import os
Raymond Hettinger82cb9a22005-07-05 05:34:43 +00008from random import randrange, shuffle
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00009import sys
Raymond Hettinger61708742008-01-24 21:23:58 +000010import collections
Raymond Hettingera690a992003-11-16 16:17:49 +000011
12class PassThru(Exception):
13 pass
14
15def check_pass_thru():
16 raise PassThru
17 yield 1
18
Raymond Hettinger9bda1d62005-09-16 07:14:21 +000019class BadCmp:
20 def __hash__(self):
21 return 1
22 def __cmp__(self, other):
23 raise RuntimeError
24
Raymond Hettinger53999102006-12-30 04:01:17 +000025class ReprWrapper:
26 'Used to test self-referential repr() calls'
27 def __repr__(self):
28 return repr(self.value)
29
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +000030class HashCountingInt(int):
31 'int-like object that counts the number of times __hash__ is called'
32 def __init__(self, *args):
33 self.hash_count = 0
34 def __hash__(self):
35 self.hash_count += 1
36 return int.__hash__(self)
37
Raymond Hettingera690a992003-11-16 16:17:49 +000038class TestJointOps(unittest.TestCase):
39 # Tests common to both set and frozenset
40
41 def setUp(self):
42 self.word = word = 'simsalabim'
43 self.otherword = 'madagascar'
44 self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
45 self.s = self.thetype(word)
46 self.d = dict.fromkeys(word)
47
Raymond Hettinger6429a472004-09-28 01:51:35 +000048 def test_new_or_init(self):
49 self.assertRaises(TypeError, self.thetype, [], 2)
50
Raymond Hettingera690a992003-11-16 16:17:49 +000051 def test_uniquification(self):
Raymond Hettinger64958a12003-12-17 20:43:33 +000052 actual = sorted(self.s)
53 expected = sorted(self.d)
Raymond Hettingera690a992003-11-16 16:17:49 +000054 self.assertEqual(actual, expected)
55 self.assertRaises(PassThru, self.thetype, check_pass_thru())
56 self.assertRaises(TypeError, self.thetype, [[]])
57
58 def test_len(self):
59 self.assertEqual(len(self.s), len(self.d))
60
61 def test_contains(self):
62 for c in self.letters:
63 self.assertEqual(c in self.s, c in self.d)
64 self.assertRaises(TypeError, self.s.__contains__, [[]])
Raymond Hettinger19c2d772003-11-21 18:36:54 +000065 s = self.thetype([frozenset(self.letters)])
66 self.assert_(self.thetype(self.letters) in s)
Raymond Hettingera690a992003-11-16 16:17:49 +000067
Raymond Hettingera690a992003-11-16 16:17:49 +000068 def test_union(self):
69 u = self.s.union(self.otherword)
70 for c in self.letters:
71 self.assertEqual(c in u, c in self.d or c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000072 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000073 self.assertEqual(type(u), self.thetype)
74 self.assertRaises(PassThru, self.s.union, check_pass_thru())
75 self.assertRaises(TypeError, self.s.union, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000076 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
77 self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
78 self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
79 self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
80 self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
Raymond Hettingeree4bcad2008-06-09 08:33:37 +000081 self.assertEqual(self.thetype('abcba').union(C('ef'), C('fg')), set('abcefg'))
Raymond Hettingera690a992003-11-16 16:17:49 +000082
83 def test_or(self):
84 i = self.s.union(self.otherword)
85 self.assertEqual(self.s | set(self.otherword), i)
86 self.assertEqual(self.s | frozenset(self.otherword), i)
87 try:
88 self.s | self.otherword
89 except TypeError:
90 pass
91 else:
92 self.fail("s|t did not screen-out general iterables")
93
94 def test_intersection(self):
95 i = self.s.intersection(self.otherword)
96 for c in self.letters:
97 self.assertEqual(c in i, c in self.d and c in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000098 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +000099 self.assertEqual(type(i), self.thetype)
100 self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000101 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
102 self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
103 self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
104 self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
105 self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
Raymond Hettinger5c4d3d02008-06-09 13:07:27 +0000106 self.assertEqual(self.thetype('abcba').intersection(C('cbcf'), C('bag')), set('b'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000107
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000108 def test_isdisjoint(self):
109 def f(s1, s2):
110 'Pure python equivalent of isdisjoint()'
111 return not set(s1).intersection(s2)
112 for larg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
113 s1 = self.thetype(larg)
114 for rarg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
115 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
116 s2 = C(rarg)
117 actual = s1.isdisjoint(s2)
118 expected = f(s1, s2)
119 self.assertEqual(actual, expected)
120 self.assert_(actual is True or actual is False)
121
Raymond Hettingera690a992003-11-16 16:17:49 +0000122 def test_and(self):
123 i = self.s.intersection(self.otherword)
124 self.assertEqual(self.s & set(self.otherword), i)
125 self.assertEqual(self.s & frozenset(self.otherword), i)
126 try:
127 self.s & self.otherword
128 except TypeError:
129 pass
130 else:
131 self.fail("s&t did not screen-out general iterables")
132
133 def test_difference(self):
134 i = self.s.difference(self.otherword)
135 for c in self.letters:
136 self.assertEqual(c in i, c in self.d and c not in self.otherword)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000137 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000138 self.assertEqual(type(i), self.thetype)
139 self.assertRaises(PassThru, self.s.difference, check_pass_thru())
140 self.assertRaises(TypeError, self.s.difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000141 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
142 self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
143 self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
144 self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
145 self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000146
147 def test_sub(self):
148 i = self.s.difference(self.otherword)
149 self.assertEqual(self.s - set(self.otherword), i)
150 self.assertEqual(self.s - frozenset(self.otherword), i)
151 try:
152 self.s - self.otherword
153 except TypeError:
154 pass
155 else:
156 self.fail("s-t did not screen-out general iterables")
157
158 def test_symmetric_difference(self):
159 i = self.s.symmetric_difference(self.otherword)
160 for c in self.letters:
161 self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000162 self.assertEqual(self.s, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000163 self.assertEqual(type(i), self.thetype)
164 self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
165 self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000166 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
167 self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
168 self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
169 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
170 self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000171
172 def test_xor(self):
173 i = self.s.symmetric_difference(self.otherword)
174 self.assertEqual(self.s ^ set(self.otherword), i)
175 self.assertEqual(self.s ^ frozenset(self.otherword), i)
176 try:
177 self.s ^ self.otherword
178 except TypeError:
179 pass
180 else:
181 self.fail("s^t did not screen-out general iterables")
182
183 def test_equality(self):
184 self.assertEqual(self.s, set(self.word))
185 self.assertEqual(self.s, frozenset(self.word))
186 self.assertEqual(self.s == self.word, False)
187 self.assertNotEqual(self.s, set(self.otherword))
188 self.assertNotEqual(self.s, frozenset(self.otherword))
189 self.assertEqual(self.s != self.word, True)
190
191 def test_setOfFrozensets(self):
192 t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
193 s = self.thetype(t)
194 self.assertEqual(len(s), 3)
195
196 def test_compare(self):
197 self.assertRaises(TypeError, self.s.__cmp__, self.s)
198
199 def test_sub_and_super(self):
200 p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
201 self.assert_(p < q)
202 self.assert_(p <= q)
203 self.assert_(q <= q)
204 self.assert_(q > p)
205 self.assert_(q >= p)
206 self.failIf(q < r)
207 self.failIf(q <= r)
208 self.failIf(q > r)
209 self.failIf(q >= r)
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000210 self.assert_(set('a').issubset('abc'))
211 self.assert_(set('abc').issuperset('a'))
212 self.failIf(set('a').issubset('cbs'))
213 self.failIf(set('cbs').issuperset('a'))
Raymond Hettingera690a992003-11-16 16:17:49 +0000214
215 def test_pickling(self):
Raymond Hettinger15056a52004-11-09 07:25:31 +0000216 for i in (0, 1, 2):
217 p = pickle.dumps(self.s, i)
218 dup = pickle.loads(p)
219 self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
220 if type(self.s) not in (set, frozenset):
221 self.s.x = 10
222 p = pickle.dumps(self.s)
223 dup = pickle.loads(p)
224 self.assertEqual(self.s.x, dup.x)
Raymond Hettingera690a992003-11-16 16:17:49 +0000225
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000226 def test_deepcopy(self):
227 class Tracer:
228 def __init__(self, value):
229 self.value = value
230 def __hash__(self):
Tim Peters58eb11c2004-01-18 20:29:55 +0000231 return self.value
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000232 def __deepcopy__(self, memo=None):
233 return Tracer(self.value + 1)
234 t = Tracer(10)
235 s = self.thetype([t])
236 dup = copy.deepcopy(s)
237 self.assertNotEqual(id(s), id(dup))
238 for elem in dup:
239 newt = elem
240 self.assertNotEqual(id(t), id(newt))
241 self.assertEqual(t.value + 1, newt.value)
242
Raymond Hettingerbb999b52005-06-18 21:00:26 +0000243 def test_gc(self):
244 # Create a nest of cycles to exercise overall ref count check
245 class A:
246 pass
247 s = set(A() for i in xrange(1000))
248 for elem in s:
249 elem.cycle = s
250 elem.sub = elem
251 elem.set = set([elem])
252
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000253 def test_subclass_with_custom_hash(self):
254 # Bug #1257731
255 class H(self.thetype):
256 def __hash__(self):
Tim Peters6902b442006-04-11 00:43:27 +0000257 return int(id(self) & 0x7fffffff)
Raymond Hettinger97979dd2005-08-12 23:58:22 +0000258 s=H()
259 f=set()
260 f.add(s)
261 self.assert_(s in f)
262 f.remove(s)
263 f.add(s)
264 f.discard(s)
265
Raymond Hettinger9bda1d62005-09-16 07:14:21 +0000266 def test_badcmp(self):
267 s = self.thetype([BadCmp()])
268 # Detect comparison errors during insertion and lookup
269 self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
270 self.assertRaises(RuntimeError, s.__contains__, BadCmp())
271 # Detect errors during mutating operations
272 if hasattr(s, 'add'):
273 self.assertRaises(RuntimeError, s.add, BadCmp())
274 self.assertRaises(RuntimeError, s.discard, BadCmp())
275 self.assertRaises(RuntimeError, s.remove, BadCmp())
276
Raymond Hettinger53999102006-12-30 04:01:17 +0000277 def test_cyclical_repr(self):
278 w = ReprWrapper()
279 s = self.thetype([w])
280 w.value = s
281 name = repr(s).partition('(')[0] # strip class name from repr string
282 self.assertEqual(repr(s), '%s([%s(...)])' % (name, name))
283
284 def test_cyclical_print(self):
285 w = ReprWrapper()
286 s = self.thetype([w])
287 w.value = s
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000288 fo = open(test_support.TESTFN, "wb")
Raymond Hettinger53999102006-12-30 04:01:17 +0000289 try:
Raymond Hettinger53999102006-12-30 04:01:17 +0000290 print >> fo, s,
291 fo.close()
292 fo = open(test_support.TESTFN, "rb")
293 self.assertEqual(fo.read(), repr(s))
294 finally:
295 fo.close()
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000296 test_support.unlink(test_support.TESTFN)
Raymond Hettinger53999102006-12-30 04:01:17 +0000297
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000298 def test_do_not_rehash_dict_keys(self):
299 n = 10
300 d = dict.fromkeys(map(HashCountingInt, xrange(n)))
301 self.assertEqual(sum(elem.hash_count for elem in d), n)
302 s = self.thetype(d)
303 self.assertEqual(sum(elem.hash_count for elem in d), n)
304 s.difference(d)
Tim Petersea5962f2007-03-12 18:07:52 +0000305 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000306 if hasattr(s, 'symmetric_difference_update'):
307 s.symmetric_difference_update(d)
Neal Norwitz0d4c06e2007-04-25 06:30:05 +0000308 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettinger0bbbfc42007-03-20 21:27:24 +0000309 d2 = dict.fromkeys(set(d))
310 self.assertEqual(sum(elem.hash_count for elem in d), n)
311 d3 = dict.fromkeys(frozenset(d))
Tim Petersea5962f2007-03-12 18:07:52 +0000312 self.assertEqual(sum(elem.hash_count for elem in d), n)
Raymond Hettingere3146f52007-03-21 20:33:57 +0000313 d3 = dict.fromkeys(frozenset(d), 123)
314 self.assertEqual(sum(elem.hash_count for elem in d), n)
315 self.assertEqual(d3, dict.fromkeys(d, 123))
Raymond Hettingerd6fc72a2007-02-19 02:03:19 +0000316
Raymond Hettingera690a992003-11-16 16:17:49 +0000317class TestSet(TestJointOps):
318 thetype = set
319
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000320 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000321 s = self.thetype()
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000322 s.__init__(self.word)
323 self.assertEqual(s, set(self.word))
324 s.__init__(self.otherword)
325 self.assertEqual(s, set(self.otherword))
Raymond Hettingereae05de2004-07-09 04:51:24 +0000326 self.assertRaises(TypeError, s.__init__, s, 2);
327 self.assertRaises(TypeError, s.__init__, 1);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000328
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000329 def test_constructor_identity(self):
330 s = self.thetype(range(3))
331 t = self.thetype(s)
332 self.assertNotEqual(id(s), id(t))
333
Raymond Hettingera690a992003-11-16 16:17:49 +0000334 def test_hash(self):
335 self.assertRaises(TypeError, hash, self.s)
336
337 def test_clear(self):
338 self.s.clear()
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000339 self.assertEqual(self.s, set())
340 self.assertEqual(len(self.s), 0)
Raymond Hettingera690a992003-11-16 16:17:49 +0000341
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000342 def test_copy(self):
343 dup = self.s.copy()
344 self.assertEqual(self.s, dup)
345 self.assertNotEqual(id(self.s), id(dup))
346
Raymond Hettingera690a992003-11-16 16:17:49 +0000347 def test_add(self):
348 self.s.add('Q')
349 self.assert_('Q' in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000350 dup = self.s.copy()
351 self.s.add('Q')
352 self.assertEqual(self.s, dup)
Raymond Hettingera690a992003-11-16 16:17:49 +0000353 self.assertRaises(TypeError, self.s.add, [])
354
355 def test_remove(self):
356 self.s.remove('a')
357 self.assert_('a' not in self.s)
358 self.assertRaises(KeyError, self.s.remove, 'Q')
359 self.assertRaises(TypeError, self.s.remove, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000360 s = self.thetype([frozenset(self.word)])
361 self.assert_(self.thetype(self.word) in s)
362 s.remove(self.thetype(self.word))
363 self.assert_(self.thetype(self.word) not in s)
364 self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000365
Raymond Hettingerc789f342006-12-08 17:35:25 +0000366 def test_remove_keyerror_unpacking(self):
367 # bug: www.python.org/sf/1576657
368 for v1 in ['Q', (1,)]:
369 try:
370 self.s.remove(v1)
371 except KeyError, e:
372 v2 = e.args[0]
373 self.assertEqual(v1, v2)
374 else:
375 self.fail()
376
Raymond Hettingera690a992003-11-16 16:17:49 +0000377 def test_discard(self):
378 self.s.discard('a')
379 self.assert_('a' not in self.s)
380 self.s.discard('Q')
381 self.assertRaises(TypeError, self.s.discard, [])
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000382 s = self.thetype([frozenset(self.word)])
383 self.assert_(self.thetype(self.word) in s)
384 s.discard(self.thetype(self.word))
385 self.assert_(self.thetype(self.word) not in s)
386 s.discard(self.thetype(self.word))
Raymond Hettingera690a992003-11-16 16:17:49 +0000387
388 def test_pop(self):
389 for i in xrange(len(self.s)):
390 elem = self.s.pop()
391 self.assert_(elem not in self.s)
392 self.assertRaises(KeyError, self.s.pop)
393
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000394 def test_update(self):
395 retval = self.s.update(self.otherword)
Raymond Hettingera690a992003-11-16 16:17:49 +0000396 self.assertEqual(retval, None)
397 for c in (self.word + self.otherword):
398 self.assert_(c in self.s)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000399 self.assertRaises(PassThru, self.s.update, check_pass_thru())
400 self.assertRaises(TypeError, self.s.update, [[]])
401 for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
402 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
403 s = self.thetype('abcba')
404 self.assertEqual(s.update(C(p)), None)
405 self.assertEqual(s, set(q))
Raymond Hettingeree4bcad2008-06-09 08:33:37 +0000406 for p in ('cdc', 'efgfe', 'ccb', 'ef', 'abcda'):
407 q = 'ahi'
408 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
409 s = self.thetype('abcba')
410 self.assertEqual(s.update(C(p), C(q)), None)
411 self.assertEqual(s, set(s) | set(p) | set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000412
413 def test_ior(self):
414 self.s |= set(self.otherword)
415 for c in (self.word + self.otherword):
416 self.assert_(c in self.s)
417
418 def test_intersection_update(self):
419 retval = self.s.intersection_update(self.otherword)
420 self.assertEqual(retval, None)
421 for c in (self.word + self.otherword):
422 if c in self.otherword and c in self.word:
423 self.assert_(c in self.s)
424 else:
425 self.assert_(c not in self.s)
426 self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
427 self.assertRaises(TypeError, self.s.intersection_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000428 for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
429 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
430 s = self.thetype('abcba')
431 self.assertEqual(s.intersection_update(C(p)), None)
432 self.assertEqual(s, set(q))
Raymond Hettinger5c4d3d02008-06-09 13:07:27 +0000433 ss = 'abcba'
434 s = self.thetype(ss)
435 t = 'cbc'
436 self.assertEqual(s.intersection_update(C(p), C(t)), None)
437 self.assertEqual(s, set('abcba')&set(p)&set(t))
Raymond Hettingera690a992003-11-16 16:17:49 +0000438
439 def test_iand(self):
440 self.s &= set(self.otherword)
441 for c in (self.word + self.otherword):
442 if c in self.otherword and c in self.word:
443 self.assert_(c in self.s)
444 else:
445 self.assert_(c not in self.s)
446
447 def test_difference_update(self):
448 retval = self.s.difference_update(self.otherword)
449 self.assertEqual(retval, None)
450 for c in (self.word + self.otherword):
451 if c in self.word and c not in self.otherword:
452 self.assert_(c in self.s)
453 else:
454 self.assert_(c not in self.s)
455 self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
456 self.assertRaises(TypeError, self.s.difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000457 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
458 for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
459 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
460 s = self.thetype('abcba')
461 self.assertEqual(s.difference_update(C(p)), None)
462 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000463
464 def test_isub(self):
465 self.s -= set(self.otherword)
466 for c in (self.word + self.otherword):
467 if c in self.word and c not in self.otherword:
468 self.assert_(c in self.s)
469 else:
470 self.assert_(c not in self.s)
471
472 def test_symmetric_difference_update(self):
473 retval = self.s.symmetric_difference_update(self.otherword)
474 self.assertEqual(retval, None)
475 for c in (self.word + self.otherword):
476 if (c in self.word) ^ (c in self.otherword):
477 self.assert_(c in self.s)
478 else:
479 self.assert_(c not in self.s)
480 self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
481 self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000482 for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
483 for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
484 s = self.thetype('abcba')
485 self.assertEqual(s.symmetric_difference_update(C(p)), None)
486 self.assertEqual(s, set(q))
Raymond Hettingera690a992003-11-16 16:17:49 +0000487
488 def test_ixor(self):
489 self.s ^= set(self.otherword)
490 for c in (self.word + self.otherword):
491 if (c in self.word) ^ (c in self.otherword):
492 self.assert_(c in self.s)
493 else:
494 self.assert_(c not in self.s)
495
Raymond Hettingerc991db22005-08-11 07:58:45 +0000496 def test_inplace_on_self(self):
497 t = self.s.copy()
498 t |= t
499 self.assertEqual(t, self.s)
500 t &= t
501 self.assertEqual(t, self.s)
502 t -= t
503 self.assertEqual(t, self.thetype())
504 t = self.s.copy()
505 t ^= t
506 self.assertEqual(t, self.thetype())
507
Raymond Hettinger691d8052004-05-30 07:26:47 +0000508 def test_weakref(self):
509 s = self.thetype('gallahad')
510 p = proxy(s)
511 self.assertEqual(str(p), str(s))
512 s = None
513 self.assertRaises(ReferenceError, str, p)
514
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000515 # C API test only available in a debug build
Barry Warsaw176014f2006-03-30 22:45:35 +0000516 if hasattr(set, "test_c_api"):
Raymond Hettingerc47e01d2005-08-16 10:44:15 +0000517 def test_c_api(self):
518 self.assertEqual(set('abc').test_c_api(), True)
519
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000520class SetSubclass(set):
521 pass
522
523class TestSetSubclass(TestSet):
524 thetype = SetSubclass
Raymond Hettingera690a992003-11-16 16:17:49 +0000525
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000526class SetSubclassWithKeywordArgs(set):
527 def __init__(self, iterable=[], newarg=None):
528 set.__init__(self, iterable)
529
530class TestSetSubclassWithKeywordArgs(TestSet):
Tim Petersf733abb2007-01-30 03:03:46 +0000531
Raymond Hettinger9fdfadb2007-01-11 18:22:55 +0000532 def test_keywords_in_subclass(self):
533 'SF bug #1486663 -- this used to erroneously raise a TypeError'
534 SetSubclassWithKeywordArgs(newarg=1)
535
Raymond Hettingera690a992003-11-16 16:17:49 +0000536class TestFrozenSet(TestJointOps):
537 thetype = frozenset
538
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000539 def test_init(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000540 s = self.thetype(self.word)
541 s.__init__(self.otherword)
542 self.assertEqual(s, set(self.word))
543
Raymond Hettingerd7946662005-08-01 21:39:29 +0000544 def test_singleton_empty_frozenset(self):
545 f = frozenset()
546 efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''),
547 frozenset(), frozenset([]), frozenset(()), frozenset(''),
548 frozenset(xrange(0)), frozenset(frozenset()),
549 frozenset(f), f]
550 # All of the empty frozensets should have just one id()
551 self.assertEqual(len(set(map(id, efs))), 1)
552
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000553 def test_constructor_identity(self):
554 s = self.thetype(range(3))
555 t = self.thetype(s)
556 self.assertEqual(id(s), id(t))
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000557
Raymond Hettingera690a992003-11-16 16:17:49 +0000558 def test_hash(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000559 self.assertEqual(hash(self.thetype('abcdeb')),
560 hash(self.thetype('ebecda')))
561
Raymond Hettinger82cb9a22005-07-05 05:34:43 +0000562 # make sure that all permutations give the same hash value
563 n = 100
564 seq = [randrange(n) for i in xrange(n)]
565 results = set()
566 for i in xrange(200):
567 shuffle(seq)
568 results.add(hash(self.thetype(seq)))
569 self.assertEqual(len(results), 1)
570
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000571 def test_copy(self):
572 dup = self.s.copy()
573 self.assertEqual(id(self.s), id(dup))
Raymond Hettingera690a992003-11-16 16:17:49 +0000574
575 def test_frozen_as_dictkey(self):
576 seq = range(10) + list('abcdefg') + ['apple']
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000577 key1 = self.thetype(seq)
578 key2 = self.thetype(reversed(seq))
Raymond Hettingera690a992003-11-16 16:17:49 +0000579 self.assertEqual(key1, key2)
580 self.assertNotEqual(id(key1), id(key2))
581 d = {}
582 d[key1] = 42
583 self.assertEqual(d[key2], 42)
584
585 def test_hash_caching(self):
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000586 f = self.thetype('abcdcda')
Raymond Hettingera690a992003-11-16 16:17:49 +0000587 self.assertEqual(hash(f), hash(f))
588
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000589 def test_hash_effectiveness(self):
590 n = 13
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000591 hashvalues = set()
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000592 addhashvalue = hashvalues.add
593 elemmasks = [(i+1, 1<<i) for i in range(n)]
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000594 for i in xrange(2**n):
Raymond Hettinger6e70acc2003-12-31 02:01:33 +0000595 addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
596 self.assertEqual(len(hashvalues), 2**n)
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000597
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000598class FrozenSetSubclass(frozenset):
599 pass
600
601class TestFrozenSetSubclass(TestFrozenSet):
602 thetype = FrozenSetSubclass
603
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000604 def test_constructor_identity(self):
605 s = self.thetype(range(3))
606 t = self.thetype(s)
607 self.assertNotEqual(id(s), id(t))
608
609 def test_copy(self):
610 dup = self.s.copy()
611 self.assertNotEqual(id(self.s), id(dup))
612
613 def test_nested_empty_constructor(self):
614 s = self.thetype()
615 t = self.thetype(s)
616 self.assertEqual(s, t)
617
Raymond Hettingerd7946662005-08-01 21:39:29 +0000618 def test_singleton_empty_frozenset(self):
619 Frozenset = self.thetype
620 f = frozenset()
621 F = Frozenset()
622 efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
623 Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
624 Frozenset(xrange(0)), Frozenset(Frozenset()),
625 Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
626 # All empty frozenset subclass instances should have different ids
627 self.assertEqual(len(set(map(id, efs))), len(efs))
628
Raymond Hettingera690a992003-11-16 16:17:49 +0000629# Tests taken from test_sets.py =============================================
630
631empty_set = set()
632
633#==============================================================================
634
635class TestBasicOps(unittest.TestCase):
636
637 def test_repr(self):
638 if self.repr is not None:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000639 self.assertEqual(repr(self.set), self.repr)
Raymond Hettingera690a992003-11-16 16:17:49 +0000640
Raymond Hettingereae05de2004-07-09 04:51:24 +0000641 def test_print(self):
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000642 fo = open(test_support.TESTFN, "wb")
Raymond Hettingereae05de2004-07-09 04:51:24 +0000643 try:
Raymond Hettingereae05de2004-07-09 04:51:24 +0000644 print >> fo, self.set,
645 fo.close()
646 fo = open(test_support.TESTFN, "rb")
647 self.assertEqual(fo.read(), repr(self.set))
648 finally:
649 fo.close()
Neal Norwitzbe9160b2008-03-25 06:35:10 +0000650 test_support.unlink(test_support.TESTFN)
Raymond Hettingereae05de2004-07-09 04:51:24 +0000651
Raymond Hettingera690a992003-11-16 16:17:49 +0000652 def test_length(self):
653 self.assertEqual(len(self.set), self.length)
654
655 def test_self_equality(self):
656 self.assertEqual(self.set, self.set)
657
658 def test_equivalent_equality(self):
659 self.assertEqual(self.set, self.dup)
660
661 def test_copy(self):
662 self.assertEqual(self.set.copy(), self.dup)
663
664 def test_self_union(self):
665 result = self.set | self.set
666 self.assertEqual(result, self.dup)
667
668 def test_empty_union(self):
669 result = self.set | empty_set
670 self.assertEqual(result, self.dup)
671
672 def test_union_empty(self):
673 result = empty_set | self.set
674 self.assertEqual(result, self.dup)
675
676 def test_self_intersection(self):
677 result = self.set & self.set
678 self.assertEqual(result, self.dup)
679
680 def test_empty_intersection(self):
681 result = self.set & empty_set
682 self.assertEqual(result, empty_set)
683
684 def test_intersection_empty(self):
685 result = empty_set & self.set
686 self.assertEqual(result, empty_set)
687
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000688 def test_self_isdisjoint(self):
689 result = self.set.isdisjoint(self.set)
690 self.assertEqual(result, not self.set)
691
692 def test_empty_isdisjoint(self):
693 result = self.set.isdisjoint(empty_set)
694 self.assertEqual(result, True)
695
696 def test_isdisjoint_empty(self):
697 result = empty_set.isdisjoint(self.set)
698 self.assertEqual(result, True)
699
Raymond Hettingera690a992003-11-16 16:17:49 +0000700 def test_self_symmetric_difference(self):
701 result = self.set ^ self.set
702 self.assertEqual(result, empty_set)
703
704 def checkempty_symmetric_difference(self):
705 result = self.set ^ empty_set
706 self.assertEqual(result, self.set)
707
708 def test_self_difference(self):
709 result = self.set - self.set
710 self.assertEqual(result, empty_set)
711
712 def test_empty_difference(self):
713 result = self.set - empty_set
714 self.assertEqual(result, self.dup)
715
716 def test_empty_difference_rev(self):
717 result = empty_set - self.set
718 self.assertEqual(result, empty_set)
719
720 def test_iteration(self):
721 for v in self.set:
722 self.assert_(v in self.values)
Neal Norwitzfcf44352005-11-27 20:37:43 +0000723 setiter = iter(self.set)
Armin Rigof5b3e362006-02-11 21:32:43 +0000724 # note: __length_hint__ is an internal undocumented API,
725 # don't rely on it in your own programs
726 self.assertEqual(setiter.__length_hint__(), len(self.set))
Raymond Hettingera690a992003-11-16 16:17:49 +0000727
728 def test_pickling(self):
729 p = pickle.dumps(self.set)
730 copy = pickle.loads(p)
731 self.assertEqual(self.set, copy,
732 "%s != %s" % (self.set, copy))
733
734#------------------------------------------------------------------------------
735
736class TestBasicOpsEmpty(TestBasicOps):
737 def setUp(self):
738 self.case = "empty set"
739 self.values = []
740 self.set = set(self.values)
741 self.dup = set(self.values)
742 self.length = 0
743 self.repr = "set([])"
744
745#------------------------------------------------------------------------------
746
747class TestBasicOpsSingleton(TestBasicOps):
748 def setUp(self):
749 self.case = "unit set (number)"
750 self.values = [3]
751 self.set = set(self.values)
752 self.dup = set(self.values)
753 self.length = 1
754 self.repr = "set([3])"
755
756 def test_in(self):
757 self.failUnless(3 in self.set)
758
759 def test_not_in(self):
760 self.failUnless(2 not in self.set)
761
762#------------------------------------------------------------------------------
763
764class TestBasicOpsTuple(TestBasicOps):
765 def setUp(self):
766 self.case = "unit set (tuple)"
767 self.values = [(0, "zero")]
768 self.set = set(self.values)
769 self.dup = set(self.values)
770 self.length = 1
771 self.repr = "set([(0, 'zero')])"
772
773 def test_in(self):
774 self.failUnless((0, "zero") in self.set)
775
776 def test_not_in(self):
777 self.failUnless(9 not in self.set)
778
779#------------------------------------------------------------------------------
780
781class TestBasicOpsTriple(TestBasicOps):
782 def setUp(self):
783 self.case = "triple set"
784 self.values = [0, "zero", operator.add]
785 self.set = set(self.values)
786 self.dup = set(self.values)
787 self.length = 3
788 self.repr = None
789
790#==============================================================================
791
792def baditer():
793 raise TypeError
794 yield True
795
796def gooditer():
797 yield True
798
799class TestExceptionPropagation(unittest.TestCase):
800 """SF 628246: Set constructor should not trap iterator TypeErrors"""
801
802 def test_instanceWithException(self):
803 self.assertRaises(TypeError, set, baditer())
804
805 def test_instancesWithoutException(self):
806 # All of these iterables should load without exception.
807 set([1,2,3])
808 set((1,2,3))
809 set({'one':1, 'two':2, 'three':3})
810 set(xrange(3))
811 set('abc')
812 set(gooditer())
813
Neal Norwitzfcf44352005-11-27 20:37:43 +0000814 def test_changingSizeWhileIterating(self):
815 s = set([1,2,3])
816 try:
817 for i in s:
818 s.update([4])
819 except RuntimeError:
820 pass
821 else:
822 self.fail("no exception when changing size during iteration")
823
Raymond Hettingera690a992003-11-16 16:17:49 +0000824#==============================================================================
825
826class TestSetOfSets(unittest.TestCase):
827 def test_constructor(self):
828 inner = frozenset([1])
829 outer = set([inner])
830 element = outer.pop()
831 self.assertEqual(type(element), frozenset)
832 outer.add(inner) # Rebuild set of sets with .add method
833 outer.remove(inner)
834 self.assertEqual(outer, set()) # Verify that remove worked
835 outer.discard(inner) # Absence of KeyError indicates working fine
836
837#==============================================================================
838
839class TestBinaryOps(unittest.TestCase):
840 def setUp(self):
841 self.set = set((2, 4, 6))
842
843 def test_eq(self): # SF bug 643115
844 self.assertEqual(self.set, set({2:1,4:3,6:5}))
845
846 def test_union_subset(self):
847 result = self.set | set([2])
848 self.assertEqual(result, set((2, 4, 6)))
849
850 def test_union_superset(self):
851 result = self.set | set([2, 4, 6, 8])
852 self.assertEqual(result, set([2, 4, 6, 8]))
853
854 def test_union_overlap(self):
855 result = self.set | set([3, 4, 5])
856 self.assertEqual(result, set([2, 3, 4, 5, 6]))
857
858 def test_union_non_overlap(self):
859 result = self.set | set([8])
860 self.assertEqual(result, set([2, 4, 6, 8]))
861
862 def test_intersection_subset(self):
863 result = self.set & set((2, 4))
864 self.assertEqual(result, set((2, 4)))
865
866 def test_intersection_superset(self):
867 result = self.set & set([2, 4, 6, 8])
868 self.assertEqual(result, set([2, 4, 6]))
869
870 def test_intersection_overlap(self):
871 result = self.set & set([3, 4, 5])
872 self.assertEqual(result, set([4]))
873
874 def test_intersection_non_overlap(self):
875 result = self.set & set([8])
876 self.assertEqual(result, empty_set)
877
Raymond Hettinger1760c8a2007-11-08 02:52:43 +0000878 def test_isdisjoint_subset(self):
879 result = self.set.isdisjoint(set((2, 4)))
880 self.assertEqual(result, False)
881
882 def test_isdisjoint_superset(self):
883 result = self.set.isdisjoint(set([2, 4, 6, 8]))
884 self.assertEqual(result, False)
885
886 def test_isdisjoint_overlap(self):
887 result = self.set.isdisjoint(set([3, 4, 5]))
888 self.assertEqual(result, False)
889
890 def test_isdisjoint_non_overlap(self):
891 result = self.set.isdisjoint(set([8]))
892 self.assertEqual(result, True)
893
Raymond Hettingera690a992003-11-16 16:17:49 +0000894 def test_sym_difference_subset(self):
895 result = self.set ^ set((2, 4))
896 self.assertEqual(result, set([6]))
897
898 def test_sym_difference_superset(self):
899 result = self.set ^ set((2, 4, 6, 8))
900 self.assertEqual(result, set([8]))
901
902 def test_sym_difference_overlap(self):
903 result = self.set ^ set((3, 4, 5))
904 self.assertEqual(result, set([2, 3, 5, 6]))
905
906 def test_sym_difference_non_overlap(self):
907 result = self.set ^ set([8])
908 self.assertEqual(result, set([2, 4, 6, 8]))
909
910 def test_cmp(self):
911 a, b = set('a'), set('b')
912 self.assertRaises(TypeError, cmp, a, b)
913
914 # You can view this as a buglet: cmp(a, a) does not raise TypeError,
915 # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
916 # which Python thinks is good enough to synthesize a cmp() result
917 # without calling __cmp__.
918 self.assertEqual(cmp(a, a), 0)
919
920 self.assertRaises(TypeError, cmp, a, 12)
921 self.assertRaises(TypeError, cmp, "abc", a)
922
923#==============================================================================
924
925class TestUpdateOps(unittest.TestCase):
926 def setUp(self):
927 self.set = set((2, 4, 6))
928
929 def test_union_subset(self):
930 self.set |= set([2])
931 self.assertEqual(self.set, set((2, 4, 6)))
932
933 def test_union_superset(self):
934 self.set |= set([2, 4, 6, 8])
935 self.assertEqual(self.set, set([2, 4, 6, 8]))
936
937 def test_union_overlap(self):
938 self.set |= set([3, 4, 5])
939 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
940
941 def test_union_non_overlap(self):
942 self.set |= set([8])
943 self.assertEqual(self.set, set([2, 4, 6, 8]))
944
945 def test_union_method_call(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000946 self.set.update(set([3, 4, 5]))
Raymond Hettingera690a992003-11-16 16:17:49 +0000947 self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
948
949 def test_intersection_subset(self):
950 self.set &= set((2, 4))
951 self.assertEqual(self.set, set((2, 4)))
952
953 def test_intersection_superset(self):
954 self.set &= set([2, 4, 6, 8])
955 self.assertEqual(self.set, set([2, 4, 6]))
956
957 def test_intersection_overlap(self):
958 self.set &= set([3, 4, 5])
959 self.assertEqual(self.set, set([4]))
960
961 def test_intersection_non_overlap(self):
962 self.set &= set([8])
963 self.assertEqual(self.set, empty_set)
964
965 def test_intersection_method_call(self):
966 self.set.intersection_update(set([3, 4, 5]))
967 self.assertEqual(self.set, set([4]))
968
969 def test_sym_difference_subset(self):
970 self.set ^= set((2, 4))
971 self.assertEqual(self.set, set([6]))
972
973 def test_sym_difference_superset(self):
974 self.set ^= set((2, 4, 6, 8))
975 self.assertEqual(self.set, set([8]))
976
977 def test_sym_difference_overlap(self):
978 self.set ^= set((3, 4, 5))
979 self.assertEqual(self.set, set([2, 3, 5, 6]))
980
981 def test_sym_difference_non_overlap(self):
982 self.set ^= set([8])
983 self.assertEqual(self.set, set([2, 4, 6, 8]))
984
985 def test_sym_difference_method_call(self):
986 self.set.symmetric_difference_update(set([3, 4, 5]))
987 self.assertEqual(self.set, set([2, 3, 5, 6]))
988
989 def test_difference_subset(self):
990 self.set -= set((2, 4))
991 self.assertEqual(self.set, set([6]))
992
993 def test_difference_superset(self):
994 self.set -= set((2, 4, 6, 8))
995 self.assertEqual(self.set, set([]))
996
997 def test_difference_overlap(self):
998 self.set -= set((3, 4, 5))
999 self.assertEqual(self.set, set([2, 6]))
1000
1001 def test_difference_non_overlap(self):
1002 self.set -= set([8])
1003 self.assertEqual(self.set, set([2, 4, 6]))
1004
1005 def test_difference_method_call(self):
1006 self.set.difference_update(set([3, 4, 5]))
1007 self.assertEqual(self.set, set([2, 6]))
1008
1009#==============================================================================
1010
1011class TestMutate(unittest.TestCase):
1012 def setUp(self):
1013 self.values = ["a", "b", "c"]
1014 self.set = set(self.values)
1015
1016 def test_add_present(self):
1017 self.set.add("c")
1018 self.assertEqual(self.set, set("abc"))
1019
1020 def test_add_absent(self):
1021 self.set.add("d")
1022 self.assertEqual(self.set, set("abcd"))
1023
1024 def test_add_until_full(self):
1025 tmp = set()
1026 expected_len = 0
1027 for v in self.values:
1028 tmp.add(v)
1029 expected_len += 1
1030 self.assertEqual(len(tmp), expected_len)
1031 self.assertEqual(tmp, self.set)
1032
1033 def test_remove_present(self):
1034 self.set.remove("b")
1035 self.assertEqual(self.set, set("ac"))
1036
1037 def test_remove_absent(self):
1038 try:
1039 self.set.remove("d")
1040 self.fail("Removing missing element should have raised LookupError")
1041 except LookupError:
1042 pass
1043
1044 def test_remove_until_empty(self):
1045 expected_len = len(self.set)
1046 for v in self.values:
1047 self.set.remove(v)
1048 expected_len -= 1
1049 self.assertEqual(len(self.set), expected_len)
1050
1051 def test_discard_present(self):
1052 self.set.discard("c")
1053 self.assertEqual(self.set, set("ab"))
1054
1055 def test_discard_absent(self):
1056 self.set.discard("d")
1057 self.assertEqual(self.set, set("abc"))
1058
1059 def test_clear(self):
1060 self.set.clear()
1061 self.assertEqual(len(self.set), 0)
1062
1063 def test_pop(self):
1064 popped = {}
1065 while self.set:
1066 popped[self.set.pop()] = None
1067 self.assertEqual(len(popped), len(self.values))
1068 for v in self.values:
1069 self.failUnless(v in popped)
1070
1071 def test_update_empty_tuple(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001072 self.set.update(())
Raymond Hettingera690a992003-11-16 16:17:49 +00001073 self.assertEqual(self.set, set(self.values))
1074
1075 def test_update_unit_tuple_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001076 self.set.update(("a",))
Raymond Hettingera690a992003-11-16 16:17:49 +00001077 self.assertEqual(self.set, set(self.values))
1078
1079 def test_update_unit_tuple_non_overlap(self):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001080 self.set.update(("a", "z"))
Raymond Hettingera690a992003-11-16 16:17:49 +00001081 self.assertEqual(self.set, set(self.values + ["z"]))
1082
1083#==============================================================================
1084
1085class TestSubsets(unittest.TestCase):
1086
1087 case2method = {"<=": "issubset",
1088 ">=": "issuperset",
1089 }
1090
1091 reverse = {"==": "==",
1092 "!=": "!=",
1093 "<": ">",
1094 ">": "<",
1095 "<=": ">=",
1096 ">=": "<=",
1097 }
1098
1099 def test_issubset(self):
1100 x = self.left
1101 y = self.right
1102 for case in "!=", "==", "<", "<=", ">", ">=":
1103 expected = case in self.cases
1104 # Test the binary infix spelling.
1105 result = eval("x" + case + "y", locals())
1106 self.assertEqual(result, expected)
1107 # Test the "friendly" method-name spelling, if one exists.
1108 if case in TestSubsets.case2method:
1109 method = getattr(x, TestSubsets.case2method[case])
1110 result = method(y)
1111 self.assertEqual(result, expected)
1112
1113 # Now do the same for the operands reversed.
1114 rcase = TestSubsets.reverse[case]
1115 result = eval("y" + rcase + "x", locals())
1116 self.assertEqual(result, expected)
1117 if rcase in TestSubsets.case2method:
1118 method = getattr(y, TestSubsets.case2method[rcase])
1119 result = method(x)
1120 self.assertEqual(result, expected)
1121#------------------------------------------------------------------------------
1122
1123class TestSubsetEqualEmpty(TestSubsets):
1124 left = set()
1125 right = set()
1126 name = "both empty"
1127 cases = "==", "<=", ">="
1128
1129#------------------------------------------------------------------------------
1130
1131class TestSubsetEqualNonEmpty(TestSubsets):
1132 left = set([1, 2])
1133 right = set([1, 2])
1134 name = "equal pair"
1135 cases = "==", "<=", ">="
1136
1137#------------------------------------------------------------------------------
1138
1139class TestSubsetEmptyNonEmpty(TestSubsets):
1140 left = set()
1141 right = set([1, 2])
1142 name = "one empty, one non-empty"
1143 cases = "!=", "<", "<="
1144
1145#------------------------------------------------------------------------------
1146
1147class TestSubsetPartial(TestSubsets):
1148 left = set([1])
1149 right = set([1, 2])
1150 name = "one a non-empty proper subset of other"
1151 cases = "!=", "<", "<="
1152
1153#------------------------------------------------------------------------------
1154
1155class TestSubsetNonOverlap(TestSubsets):
1156 left = set([1])
1157 right = set([2])
1158 name = "neither empty, neither contains"
1159 cases = "!="
1160
1161#==============================================================================
1162
1163class TestOnlySetsInBinaryOps(unittest.TestCase):
1164
1165 def test_eq_ne(self):
1166 # Unlike the others, this is testing that == and != *are* allowed.
1167 self.assertEqual(self.other == self.set, False)
1168 self.assertEqual(self.set == self.other, False)
1169 self.assertEqual(self.other != self.set, True)
1170 self.assertEqual(self.set != self.other, True)
1171
1172 def test_ge_gt_le_lt(self):
1173 self.assertRaises(TypeError, lambda: self.set < self.other)
1174 self.assertRaises(TypeError, lambda: self.set <= self.other)
1175 self.assertRaises(TypeError, lambda: self.set > self.other)
1176 self.assertRaises(TypeError, lambda: self.set >= self.other)
1177
1178 self.assertRaises(TypeError, lambda: self.other < self.set)
1179 self.assertRaises(TypeError, lambda: self.other <= self.set)
1180 self.assertRaises(TypeError, lambda: self.other > self.set)
1181 self.assertRaises(TypeError, lambda: self.other >= self.set)
1182
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001183 def test_update_operator(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001184 try:
1185 self.set |= self.other
1186 except TypeError:
1187 pass
1188 else:
1189 self.fail("expected TypeError")
1190
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001191 def test_update(self):
Raymond Hettingera690a992003-11-16 16:17:49 +00001192 if self.otherIsIterable:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001193 self.set.update(self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001194 else:
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001195 self.assertRaises(TypeError, self.set.update, self.other)
Raymond Hettingera690a992003-11-16 16:17:49 +00001196
1197 def test_union(self):
1198 self.assertRaises(TypeError, lambda: self.set | self.other)
1199 self.assertRaises(TypeError, lambda: self.other | self.set)
1200 if self.otherIsIterable:
1201 self.set.union(self.other)
1202 else:
1203 self.assertRaises(TypeError, self.set.union, self.other)
1204
1205 def test_intersection_update_operator(self):
1206 try:
1207 self.set &= self.other
1208 except TypeError:
1209 pass
1210 else:
1211 self.fail("expected TypeError")
1212
1213 def test_intersection_update(self):
1214 if self.otherIsIterable:
1215 self.set.intersection_update(self.other)
1216 else:
1217 self.assertRaises(TypeError,
1218 self.set.intersection_update,
1219 self.other)
1220
1221 def test_intersection(self):
1222 self.assertRaises(TypeError, lambda: self.set & self.other)
1223 self.assertRaises(TypeError, lambda: self.other & self.set)
1224 if self.otherIsIterable:
1225 self.set.intersection(self.other)
1226 else:
1227 self.assertRaises(TypeError, self.set.intersection, self.other)
1228
1229 def test_sym_difference_update_operator(self):
1230 try:
1231 self.set ^= self.other
1232 except TypeError:
1233 pass
1234 else:
1235 self.fail("expected TypeError")
1236
1237 def test_sym_difference_update(self):
1238 if self.otherIsIterable:
1239 self.set.symmetric_difference_update(self.other)
1240 else:
1241 self.assertRaises(TypeError,
1242 self.set.symmetric_difference_update,
1243 self.other)
1244
1245 def test_sym_difference(self):
1246 self.assertRaises(TypeError, lambda: self.set ^ self.other)
1247 self.assertRaises(TypeError, lambda: self.other ^ self.set)
1248 if self.otherIsIterable:
1249 self.set.symmetric_difference(self.other)
1250 else:
1251 self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
1252
1253 def test_difference_update_operator(self):
1254 try:
1255 self.set -= self.other
1256 except TypeError:
1257 pass
1258 else:
1259 self.fail("expected TypeError")
1260
1261 def test_difference_update(self):
1262 if self.otherIsIterable:
1263 self.set.difference_update(self.other)
1264 else:
1265 self.assertRaises(TypeError,
1266 self.set.difference_update,
1267 self.other)
1268
1269 def test_difference(self):
1270 self.assertRaises(TypeError, lambda: self.set - self.other)
1271 self.assertRaises(TypeError, lambda: self.other - self.set)
1272 if self.otherIsIterable:
1273 self.set.difference(self.other)
1274 else:
1275 self.assertRaises(TypeError, self.set.difference, self.other)
1276
1277#------------------------------------------------------------------------------
1278
1279class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
1280 def setUp(self):
1281 self.set = set((1, 2, 3))
1282 self.other = 19
1283 self.otherIsIterable = False
1284
1285#------------------------------------------------------------------------------
1286
1287class TestOnlySetsDict(TestOnlySetsInBinaryOps):
1288 def setUp(self):
1289 self.set = set((1, 2, 3))
1290 self.other = {1:2, 3:4}
1291 self.otherIsIterable = True
1292
1293#------------------------------------------------------------------------------
1294
1295class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
1296 def setUp(self):
1297 self.set = set((1, 2, 3))
1298 self.other = operator.add
1299 self.otherIsIterable = False
1300
1301#------------------------------------------------------------------------------
1302
1303class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
1304 def setUp(self):
1305 self.set = set((1, 2, 3))
1306 self.other = (2, 4, 6)
1307 self.otherIsIterable = True
1308
1309#------------------------------------------------------------------------------
1310
1311class TestOnlySetsString(TestOnlySetsInBinaryOps):
1312 def setUp(self):
1313 self.set = set((1, 2, 3))
1314 self.other = 'abc'
1315 self.otherIsIterable = True
1316
1317#------------------------------------------------------------------------------
1318
1319class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
1320 def setUp(self):
1321 def gen():
1322 for i in xrange(0, 10, 2):
1323 yield i
1324 self.set = set((1, 2, 3))
1325 self.other = gen()
1326 self.otherIsIterable = True
1327
1328#==============================================================================
1329
1330class TestCopying(unittest.TestCase):
1331
1332 def test_copy(self):
1333 dup = self.set.copy()
1334 dup_list = list(dup); dup_list.sort()
1335 set_list = list(self.set); set_list.sort()
1336 self.assertEqual(len(dup_list), len(set_list))
1337 for i in range(len(dup_list)):
1338 self.failUnless(dup_list[i] is set_list[i])
1339
1340 def test_deep_copy(self):
1341 dup = copy.deepcopy(self.set)
Walter Dörwald70a6b492004-02-12 17:35:32 +00001342 ##print type(dup), repr(dup)
Raymond Hettingera690a992003-11-16 16:17:49 +00001343 dup_list = list(dup); dup_list.sort()
1344 set_list = list(self.set); set_list.sort()
1345 self.assertEqual(len(dup_list), len(set_list))
1346 for i in range(len(dup_list)):
1347 self.assertEqual(dup_list[i], set_list[i])
1348
1349#------------------------------------------------------------------------------
1350
1351class TestCopyingEmpty(TestCopying):
1352 def setUp(self):
1353 self.set = set()
1354
1355#------------------------------------------------------------------------------
1356
1357class TestCopyingSingleton(TestCopying):
1358 def setUp(self):
1359 self.set = set(["hello"])
1360
1361#------------------------------------------------------------------------------
1362
1363class TestCopyingTriple(TestCopying):
1364 def setUp(self):
1365 self.set = set(["zero", 0, None])
1366
1367#------------------------------------------------------------------------------
1368
1369class TestCopyingTuple(TestCopying):
1370 def setUp(self):
1371 self.set = set([(1, 2)])
1372
1373#------------------------------------------------------------------------------
1374
1375class TestCopyingNested(TestCopying):
1376 def setUp(self):
1377 self.set = set([((1, 2), (3, 4))])
1378
1379#==============================================================================
1380
1381class TestIdentities(unittest.TestCase):
1382 def setUp(self):
1383 self.a = set('abracadabra')
1384 self.b = set('alacazam')
1385
1386 def test_binopsVsSubsets(self):
1387 a, b = self.a, self.b
1388 self.assert_(a - b < a)
1389 self.assert_(b - a < b)
1390 self.assert_(a & b < a)
1391 self.assert_(a & b < b)
1392 self.assert_(a | b > a)
1393 self.assert_(a | b > b)
1394 self.assert_(a ^ b < a | b)
1395
1396 def test_commutativity(self):
1397 a, b = self.a, self.b
1398 self.assertEqual(a&b, b&a)
1399 self.assertEqual(a|b, b|a)
1400 self.assertEqual(a^b, b^a)
1401 if a != b:
1402 self.assertNotEqual(a-b, b-a)
1403
1404 def test_summations(self):
1405 # check that sums of parts equal the whole
1406 a, b = self.a, self.b
1407 self.assertEqual((a-b)|(a&b)|(b-a), a|b)
1408 self.assertEqual((a&b)|(a^b), a|b)
1409 self.assertEqual(a|(b-a), a|b)
1410 self.assertEqual((a-b)|b, a|b)
1411 self.assertEqual((a-b)|(a&b), a)
1412 self.assertEqual((b-a)|(a&b), b)
1413 self.assertEqual((a-b)|(b-a), a^b)
1414
1415 def test_exclusion(self):
1416 # check that inverse operations show non-overlap
1417 a, b, zero = self.a, self.b, set()
1418 self.assertEqual((a-b)&b, zero)
1419 self.assertEqual((b-a)&a, zero)
1420 self.assertEqual((a&b)&(a^b), zero)
1421
1422# Tests derived from test_itertools.py =======================================
1423
1424def R(seqn):
1425 'Regular generator'
1426 for i in seqn:
1427 yield i
1428
1429class G:
1430 'Sequence using __getitem__'
1431 def __init__(self, seqn):
1432 self.seqn = seqn
1433 def __getitem__(self, i):
1434 return self.seqn[i]
1435
1436class I:
1437 'Sequence using iterator protocol'
1438 def __init__(self, seqn):
1439 self.seqn = seqn
1440 self.i = 0
1441 def __iter__(self):
1442 return self
1443 def next(self):
1444 if self.i >= len(self.seqn): raise StopIteration
1445 v = self.seqn[self.i]
1446 self.i += 1
1447 return v
1448
1449class Ig:
1450 'Sequence using iterator protocol defined with a generator'
1451 def __init__(self, seqn):
1452 self.seqn = seqn
1453 self.i = 0
1454 def __iter__(self):
1455 for val in self.seqn:
1456 yield val
1457
1458class X:
1459 'Missing __getitem__ and __iter__'
1460 def __init__(self, seqn):
1461 self.seqn = seqn
1462 self.i = 0
1463 def next(self):
1464 if self.i >= len(self.seqn): raise StopIteration
1465 v = self.seqn[self.i]
1466 self.i += 1
1467 return v
1468
1469class N:
1470 'Iterator missing next()'
1471 def __init__(self, seqn):
1472 self.seqn = seqn
1473 self.i = 0
1474 def __iter__(self):
1475 return self
1476
1477class E:
1478 'Test propagation of exceptions'
1479 def __init__(self, seqn):
1480 self.seqn = seqn
1481 self.i = 0
1482 def __iter__(self):
1483 return self
1484 def next(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +00001485 3 // 0
Raymond Hettingera690a992003-11-16 16:17:49 +00001486
1487class S:
1488 'Test immediate stop'
1489 def __init__(self, seqn):
1490 pass
1491 def __iter__(self):
1492 return self
1493 def next(self):
1494 raise StopIteration
1495
1496from itertools import chain, imap
1497def L(seqn):
1498 'Test multiple tiers of iterators'
1499 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
1500
1501class TestVariousIteratorArgs(unittest.TestCase):
1502
1503 def test_constructor(self):
1504 for cons in (set, frozenset):
1505 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
1506 for g in (G, I, Ig, S, L, R):
Raymond Hettinger64958a12003-12-17 20:43:33 +00001507 self.assertEqual(sorted(cons(g(s))), sorted(g(s)))
Raymond Hettingera690a992003-11-16 16:17:49 +00001508 self.assertRaises(TypeError, cons , X(s))
1509 self.assertRaises(TypeError, cons , N(s))
1510 self.assertRaises(ZeroDivisionError, cons , E(s))
1511
1512 def test_inline_methods(self):
1513 s = set('november')
1514 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001515 for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
Raymond Hettingera690a992003-11-16 16:17:49 +00001516 for g in (G, I, Ig, L, R):
1517 expected = meth(data)
1518 actual = meth(G(data))
Raymond Hettinger1760c8a2007-11-08 02:52:43 +00001519 if isinstance(expected, bool):
1520 self.assertEqual(actual, expected)
1521 else:
1522 self.assertEqual(sorted(actual), sorted(expected))
Raymond Hettingera690a992003-11-16 16:17:49 +00001523 self.assertRaises(TypeError, meth, X(s))
1524 self.assertRaises(TypeError, meth, N(s))
1525 self.assertRaises(ZeroDivisionError, meth, E(s))
1526
1527 def test_inplace_methods(self):
1528 for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001529 for methname in ('update', 'intersection_update',
Raymond Hettingera690a992003-11-16 16:17:49 +00001530 'difference_update', 'symmetric_difference_update'):
1531 for g in (G, I, Ig, S, L, R):
1532 s = set('january')
1533 t = s.copy()
1534 getattr(s, methname)(list(g(data)))
1535 getattr(t, methname)(g(data))
Raymond Hettinger64958a12003-12-17 20:43:33 +00001536 self.assertEqual(sorted(s), sorted(t))
Raymond Hettingera690a992003-11-16 16:17:49 +00001537
1538 self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
1539 self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
1540 self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
1541
Raymond Hettinger61708742008-01-24 21:23:58 +00001542# Application tests (based on David Eppstein's graph recipes ====================================
1543
1544def powerset(U):
1545 """Generates all subsets of a set or sequence U."""
1546 U = iter(U)
1547 try:
1548 x = frozenset([U.next()])
1549 for S in powerset(U):
1550 yield S
1551 yield S | x
1552 except StopIteration:
1553 yield frozenset()
1554
1555def cube(n):
1556 """Graph of n-dimensional hypercube."""
1557 singletons = [frozenset([x]) for x in range(n)]
1558 return dict([(x, frozenset([x^s for s in singletons]))
1559 for x in powerset(range(n))])
1560
1561def linegraph(G):
1562 """Graph, the vertices of which are edges of G,
1563 with two vertices being adjacent iff the corresponding
1564 edges share a vertex."""
1565 L = {}
1566 for x in G:
1567 for y in G[x]:
1568 nx = [frozenset([x,z]) for z in G[x] if z != y]
1569 ny = [frozenset([y,z]) for z in G[y] if z != x]
1570 L[frozenset([x,y])] = frozenset(nx+ny)
1571 return L
1572
1573def faces(G):
1574 'Return a set of faces in G. Where a face is a set of vertices on that face'
1575 # currently limited to triangles,squares, and pentagons
1576 f = set()
1577 for v1, edges in G.items():
1578 for v2 in edges:
1579 for v3 in G[v2]:
1580 if v1 == v3:
1581 continue
1582 if v1 in G[v3]:
1583 f.add(frozenset([v1, v2, v3]))
1584 else:
1585 for v4 in G[v3]:
1586 if v4 == v2:
1587 continue
1588 if v1 in G[v4]:
1589 f.add(frozenset([v1, v2, v3, v4]))
1590 else:
1591 for v5 in G[v4]:
1592 if v5 == v3 or v5 == v2:
1593 continue
1594 if v1 in G[v5]:
1595 f.add(frozenset([v1, v2, v3, v4, v5]))
1596 return f
1597
1598
1599class TestGraphs(unittest.TestCase):
1600
1601 def test_cube(self):
1602
1603 g = cube(3) # vert --> {v1, v2, v3}
1604 vertices1 = set(g)
1605 self.assertEqual(len(vertices1), 8) # eight vertices
1606 for edge in g.values():
1607 self.assertEqual(len(edge), 3) # each vertex connects to three edges
1608 vertices2 = set(v for edges in g.values() for v in edges)
1609 self.assertEqual(vertices1, vertices2) # edge vertices in original set
1610
1611 cubefaces = faces(g)
1612 self.assertEqual(len(cubefaces), 6) # six faces
1613 for face in cubefaces:
1614 self.assertEqual(len(face), 4) # each face is a square
1615
1616 def test_cuboctahedron(self):
1617
1618 # http://en.wikipedia.org/wiki/Cuboctahedron
1619 # 8 triangular faces and 6 square faces
1620 # 12 indentical vertices each connecting a triangle and square
1621
1622 g = cube(3)
1623 cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4}
1624 self.assertEqual(len(cuboctahedron), 12)# twelve vertices
1625
1626 vertices = set(cuboctahedron)
1627 for edges in cuboctahedron.values():
1628 self.assertEqual(len(edges), 4) # each vertex connects to four other vertices
1629 othervertices = set(edge for edges in cuboctahedron.values() for edge in edges)
1630 self.assertEqual(vertices, othervertices) # edge vertices in original set
1631
1632 cubofaces = faces(cuboctahedron)
1633 facesizes = collections.defaultdict(int)
1634 for face in cubofaces:
1635 facesizes[len(face)] += 1
1636 self.assertEqual(facesizes[3], 8) # eight triangular faces
1637 self.assertEqual(facesizes[4], 6) # six square faces
1638
1639 for vertex in cuboctahedron:
1640 edge = vertex # Cuboctahedron vertices are edges in Cube
1641 self.assertEqual(len(edge), 2) # Two cube vertices define an edge
1642 for cubevert in edge:
1643 self.assert_(cubevert in g)
1644
1645
Raymond Hettingera690a992003-11-16 16:17:49 +00001646#==============================================================================
1647
1648def test_main(verbose=None):
Raymond Hettingera690a992003-11-16 16:17:49 +00001649 from test import test_sets
1650 test_classes = (
1651 TestSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001652 TestSetSubclass,
Tim Petersf733abb2007-01-30 03:03:46 +00001653 TestSetSubclassWithKeywordArgs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001654 TestFrozenSet,
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001655 TestFrozenSetSubclass,
Raymond Hettingera690a992003-11-16 16:17:49 +00001656 TestSetOfSets,
1657 TestExceptionPropagation,
1658 TestBasicOpsEmpty,
1659 TestBasicOpsSingleton,
1660 TestBasicOpsTuple,
1661 TestBasicOpsTriple,
1662 TestBinaryOps,
1663 TestUpdateOps,
1664 TestMutate,
1665 TestSubsetEqualEmpty,
1666 TestSubsetEqualNonEmpty,
1667 TestSubsetEmptyNonEmpty,
1668 TestSubsetPartial,
1669 TestSubsetNonOverlap,
1670 TestOnlySetsNumeric,
1671 TestOnlySetsDict,
1672 TestOnlySetsOperator,
1673 TestOnlySetsTuple,
1674 TestOnlySetsString,
1675 TestOnlySetsGenerator,
1676 TestCopyingEmpty,
1677 TestCopyingSingleton,
1678 TestCopyingTriple,
1679 TestCopyingTuple,
1680 TestCopyingNested,
1681 TestIdentities,
1682 TestVariousIteratorArgs,
Raymond Hettinger61708742008-01-24 21:23:58 +00001683 TestGraphs,
Raymond Hettingera690a992003-11-16 16:17:49 +00001684 )
1685
1686 test_support.run_unittest(*test_classes)
1687
1688 # verify reference counting
1689 if verbose and hasattr(sys, "gettotalrefcount"):
1690 import gc
1691 counts = [None] * 5
1692 for i in xrange(len(counts)):
1693 test_support.run_unittest(*test_classes)
1694 gc.collect()
1695 counts[i] = sys.gettotalrefcount()
1696 print counts
1697
1698if __name__ == "__main__":
1699 test_main(verbose=True)