10a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test import test_support, seq_tests
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport gc
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TupleTest(seq_tests.CommonTest):
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    type2test = tuple
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_constructors(self):
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        super(TupleTest, self).test_constructors()
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # calling built-in types without argument must return empty
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tuple(), ())
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t0_3 = (0, 1, 2, 3)
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t0_3_bis = tuple(t0_3)
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t0_3 is t0_3_bis)
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tuple([]), ())
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tuple([0, 1, 2, 3]), (0, 1, 2, 3))
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tuple(''), ())
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tuple('spam'), ('s', 'p', 'a', 'm'))
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_truth(self):
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        super(TupleTest, self).test_truth()
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not ())
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue((42, ))
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_len(self):
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        super(TupleTest, self).test_len()
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(len(()), 0)
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(len((0,)), 1)
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(len((0, 1, 2)), 3)
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_iadd(self):
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        super(TupleTest, self).test_iadd()
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        u = (0, 1)
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        u2 = u
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        u += (2, 3)
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(u is not u2)
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_imul(self):
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        super(TupleTest, self).test_imul()
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        u = (0, 1)
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        u2 = u
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        u *= 3
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(u is not u2)
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_tupleresizebug(self):
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check that a specific bug in _PyTuple_Resize() is squashed.
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def f():
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for i in range(1000):
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                yield i
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(list(tuple(f())), range(1000))
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_hash(self):
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # See SF bug 942952:  Weakness in tuple hash
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # The hash should:
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #      be non-commutative
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #      should spread-out closely spaced values
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #      should not exhibit cancellation in tuples like (x,(x,y))
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #      should be distinct from element hashes:  hash(x)!=hash((x,))
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # This test exercises those cases.
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # For a pure random hash and N=50, the expected number of occupied
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #      buckets when tossing 252,600 balls into 2**32 buckets
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #      is 252,592.6, or about 7.4 expected collisions.  The
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #      standard deviation is 2.73.  On a box with 64-bit hash
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #      codes, no collisions are expected.  Here we accept no
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #      more than 15 collisions.  Any worse and the hash function
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #      is sorely suspect.
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        N=50
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = range(N)
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        xp = [(i, j) for i in base for j in base]
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        inps = base + [(i, j) for i in base for j in xp] + \
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                     [(i, j) for i in xp for j in base] + xp + zip(base)
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        collisions = len(inps) - len(set(map(hash, inps)))
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(collisions <= 15)
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_repr(self):
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        l0 = tuple()
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        l2 = (0, 1, 2)
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a0 = self.type2test(l0)
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a2 = self.type2test(l2)
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(a0), repr(l0))
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(a2), repr(l2))
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(a0), "()")
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(a2), "(0, 1, 2)")
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def _not_tracked(self, t):
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Nested tuples can take several collections to untrack
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        gc.collect()
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        gc.collect()
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertFalse(gc.is_tracked(t), t)
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def _tracked(self, t):
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(gc.is_tracked(t), t)
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        gc.collect()
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        gc.collect()
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(gc.is_tracked(t), t)
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @test_support.cpython_only
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_track_literals(self):
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test GC-optimization of tuple literals
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        x, y, z = 1.5, "a", []
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._not_tracked(())
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._not_tracked((1,))
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._not_tracked((1, 2))
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._not_tracked((1, 2, "a"))
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._not_tracked((1, 2, (None, True, False, ()), int))
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._not_tracked((object(),))
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._not_tracked(((1, x), y, (2, 3)))
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Tuples with mutable elements are always tracked, even if those
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # elements are not tracked right now.
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._tracked(([],))
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._tracked(([1],))
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._tracked(({},))
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._tracked((set(),))
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._tracked((x, y, z))
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def check_track_dynamic(self, tp, always_track):
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        x, y, z = 1.5, "a", []
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        check = self._tracked if always_track else self._not_tracked
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        check(tp())
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        check(tp([]))
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        check(tp(set()))
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        check(tp([1, x, y]))
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        check(tp(obj for obj in [1, x, y]))
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        check(tp(set([1, x, y])))
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        check(tp(tuple([obj]) for obj in [1, x, y]))
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        check(tuple(tp([obj]) for obj in [1, x, y]))
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._tracked(tp([z]))
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._tracked(tp([[x, y]]))
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._tracked(tp([{x: y}]))
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._tracked(tp(obj for obj in [x, y, z]))
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._tracked(tp(tuple([obj]) for obj in [x, y, z]))
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._tracked(tuple(tp([obj]) for obj in [x, y, z]))
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @test_support.cpython_only
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_track_dynamic(self):
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test GC-optimization of dynamically constructed tuples.
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_track_dynamic(tuple, False)
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @test_support.cpython_only
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_track_subtypes(self):
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Tuple subtypes must always be tracked
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class MyTuple(tuple):
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.check_track_dynamic(MyTuple, True)
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @test_support.cpython_only
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bug7466(self):
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Trying to untrack an unfinished tuple could crash Python
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._not_tracked(tuple(gc.collect() for i in range(101)))
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef test_main():
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    test_support.run_unittest(TupleTest)
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__=="__main__":
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    test_main()
162