14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom test import test_support, seq_tests 24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 34adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport gc 44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TupleTest(seq_tests.CommonTest): 64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao type2test = tuple 74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_constructors(self): 94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao super(TupleTest, self).test_constructors() 104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # calling built-in types without argument must return empty 114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tuple(), ()) 124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t0_3 = (0, 1, 2, 3) 134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t0_3_bis = tuple(t0_3) 144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t0_3 is t0_3_bis) 154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tuple([]), ()) 164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tuple([0, 1, 2, 3]), (0, 1, 2, 3)) 174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tuple(''), ()) 184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tuple('spam'), ('s', 'p', 'a', 'm')) 194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_truth(self): 214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao super(TupleTest, self).test_truth() 224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not ()) 234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue((42, )) 244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_len(self): 264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao super(TupleTest, self).test_len() 274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(()), 0) 284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len((0,)), 1) 294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len((0, 1, 2)), 3) 304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_iadd(self): 324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao super(TupleTest, self).test_iadd() 334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao u = (0, 1) 344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao u2 = u 354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao u += (2, 3) 364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(u is not u2) 374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_imul(self): 394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao super(TupleTest, self).test_imul() 404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao u = (0, 1) 414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao u2 = u 424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao u *= 3 434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(u is not u2) 444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_tupleresizebug(self): 464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Check that a specific bug in _PyTuple_Resize() is squashed. 474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def f(): 484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in range(1000): 494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yield i 504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(list(tuple(f())), range(1000)) 514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_hash(self): 534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # See SF bug 942952: Weakness in tuple hash 544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # The hash should: 554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # be non-commutative 564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # should spread-out closely spaced values 574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # should not exhibit cancellation in tuples like (x,(x,y)) 584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # should be distinct from element hashes: hash(x)!=hash((x,)) 594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # This test exercises those cases. 604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # For a pure random hash and N=50, the expected number of occupied 614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # buckets when tossing 252,600 balls into 2**32 buckets 624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # is 252,592.6, or about 7.4 expected collisions. The 634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # standard deviation is 2.73. On a box with 64-bit hash 644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # codes, no collisions are expected. Here we accept no 654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # more than 15 collisions. Any worse and the hash function 664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # is sorely suspect. 674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao N=50 694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = range(N) 704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao xp = [(i, j) for i in base for j in base] 714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao inps = base + [(i, j) for i in base for j in xp] + \ 724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao [(i, j) for i in xp for j in base] + xp + zip(base) 734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao collisions = len(inps) - len(set(map(hash, inps))) 744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(collisions <= 15) 754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_repr(self): 774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao l0 = tuple() 784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao l2 = (0, 1, 2) 794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a0 = self.type2test(l0) 804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a2 = self.type2test(l2) 814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(a0), repr(l0)) 834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(a2), repr(l2)) 844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(a0), "()") 854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(a2), "(0, 1, 2)") 864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def _not_tracked(self, t): 884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Nested tuples can take several collections to untrack 894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao gc.collect() 904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao gc.collect() 914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertFalse(gc.is_tracked(t), t) 924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def _tracked(self, t): 944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(gc.is_tracked(t), t) 954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao gc.collect() 964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao gc.collect() 974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(gc.is_tracked(t), t) 984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @test_support.cpython_only 1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_track_literals(self): 1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Test GC-optimization of tuple literals 1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao x, y, z = 1.5, "a", [] 1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._not_tracked(()) 1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._not_tracked((1,)) 1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._not_tracked((1, 2)) 1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._not_tracked((1, 2, "a")) 1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._not_tracked((1, 2, (None, True, False, ()), int)) 1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._not_tracked((object(),)) 1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._not_tracked(((1, x), y, (2, 3))) 1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Tuples with mutable elements are always tracked, even if those 1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # elements are not tracked right now. 1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tracked(([],)) 1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tracked(([1],)) 1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tracked(({},)) 1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tracked((set(),)) 1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tracked((x, y, z)) 1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def check_track_dynamic(self, tp, always_track): 1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao x, y, z = 1.5, "a", [] 1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao check = self._tracked if always_track else self._not_tracked 1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao check(tp()) 1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao check(tp([])) 1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao check(tp(set())) 1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao check(tp([1, x, y])) 1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao check(tp(obj for obj in [1, x, y])) 1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao check(tp(set([1, x, y]))) 1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao check(tp(tuple([obj]) for obj in [1, x, y])) 1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao check(tuple(tp([obj]) for obj in [1, x, y])) 1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tracked(tp([z])) 1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tracked(tp([[x, y]])) 1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tracked(tp([{x: y}])) 1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tracked(tp(obj for obj in [x, y, z])) 1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tracked(tp(tuple([obj]) for obj in [x, y, z])) 1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tracked(tuple(tp([obj]) for obj in [x, y, z])) 1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @test_support.cpython_only 1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_track_dynamic(self): 1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Test GC-optimization of dynamically constructed tuples. 1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.check_track_dynamic(tuple, False) 1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @test_support.cpython_only 1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_track_subtypes(self): 1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Tuple subtypes must always be tracked 1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class MyTuple(tuple): 1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.check_track_dynamic(MyTuple, True) 1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @test_support.cpython_only 1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bug7466(self): 1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Trying to untrack an unfinished tuple could crash Python 1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._not_tracked(tuple(gc.collect() for i in range(101))) 1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef test_main(): 1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao test_support.run_unittest(TupleTest) 1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif __name__=="__main__": 1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao test_main() 162