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