1# tests for slice objects; in particular the indices method.
2
3import unittest
4import weakref
5
6from cPickle import loads, dumps
7from test import test_support
8
9import sys
10
11class SliceTest(unittest.TestCase):
12
13    def test_constructor(self):
14        self.assertRaises(TypeError, slice)
15        self.assertRaises(TypeError, slice, 1, 2, 3, 4)
16
17    def test_repr(self):
18        self.assertEqual(repr(slice(1, 2, 3)), "slice(1, 2, 3)")
19
20    def test_hash(self):
21        # Verify clearing of SF bug #800796
22        self.assertRaises(TypeError, hash, slice(5))
23        with self.assertRaises(TypeError):
24            slice(5).__hash__()
25
26    def test_cmp(self):
27        s1 = slice(1, 2, 3)
28        s2 = slice(1, 2, 3)
29        s3 = slice(1, 2, 4)
30        self.assertEqual(s1, s2)
31        self.assertNotEqual(s1, s3)
32
33        class Exc(Exception):
34            pass
35
36        class BadCmp(object):
37            def __eq__(self, other):
38                raise Exc
39            __hash__ = None # Silence Py3k warning
40
41        s1 = slice(BadCmp())
42        s2 = slice(BadCmp())
43        self.assertRaises(Exc, cmp, s1, s2)
44        self.assertEqual(s1, s1)
45
46        s1 = slice(1, BadCmp())
47        s2 = slice(1, BadCmp())
48        self.assertEqual(s1, s1)
49        self.assertRaises(Exc, cmp, s1, s2)
50
51        s1 = slice(1, 2, BadCmp())
52        s2 = slice(1, 2, BadCmp())
53        self.assertEqual(s1, s1)
54        self.assertRaises(Exc, cmp, s1, s2)
55
56    def test_members(self):
57        s = slice(1)
58        self.assertEqual(s.start, None)
59        self.assertEqual(s.stop, 1)
60        self.assertEqual(s.step, None)
61
62        s = slice(1, 2)
63        self.assertEqual(s.start, 1)
64        self.assertEqual(s.stop, 2)
65        self.assertEqual(s.step, None)
66
67        s = slice(1, 2, 3)
68        self.assertEqual(s.start, 1)
69        self.assertEqual(s.stop, 2)
70        self.assertEqual(s.step, 3)
71
72        class AnyClass:
73            pass
74
75        obj = AnyClass()
76        s = slice(obj)
77        self.assertTrue(s.stop is obj)
78
79    def test_indices(self):
80        self.assertEqual(slice(None           ).indices(10), (0, 10,  1))
81        self.assertEqual(slice(None,  None,  2).indices(10), (0, 10,  2))
82        self.assertEqual(slice(1,     None,  2).indices(10), (1, 10,  2))
83        self.assertEqual(slice(None,  None, -1).indices(10), (9, -1, -1))
84        self.assertEqual(slice(None,  None, -2).indices(10), (9, -1, -2))
85        self.assertEqual(slice(3,     None, -2).indices(10), (3, -1, -2))
86        # issue 3004 tests
87        self.assertEqual(slice(None, -9).indices(10), (0, 1, 1))
88        self.assertEqual(slice(None, -10).indices(10), (0, 0, 1))
89        self.assertEqual(slice(None, -11).indices(10), (0, 0, 1))
90        self.assertEqual(slice(None, -10, -1).indices(10), (9, 0, -1))
91        self.assertEqual(slice(None, -11, -1).indices(10), (9, -1, -1))
92        self.assertEqual(slice(None, -12, -1).indices(10), (9, -1, -1))
93        self.assertEqual(slice(None, 9).indices(10), (0, 9, 1))
94        self.assertEqual(slice(None, 10).indices(10), (0, 10, 1))
95        self.assertEqual(slice(None, 11).indices(10), (0, 10, 1))
96        self.assertEqual(slice(None, 8, -1).indices(10), (9, 8, -1))
97        self.assertEqual(slice(None, 9, -1).indices(10), (9, 9, -1))
98        self.assertEqual(slice(None, 10, -1).indices(10), (9, 9, -1))
99
100        self.assertEqual(
101            slice(-100,  100     ).indices(10),
102            slice(None).indices(10)
103        )
104        self.assertEqual(
105            slice(100,  -100,  -1).indices(10),
106            slice(None, None, -1).indices(10)
107        )
108        self.assertEqual(slice(-100L, 100L, 2L).indices(10), (0, 10,  2))
109
110        self.assertEqual(range(10)[::sys.maxint - 1], [0])
111
112        self.assertRaises(OverflowError, slice(None).indices, 1L<<100)
113
114    def test_setslice_without_getslice(self):
115        tmp = []
116        class X(object):
117            def __setslice__(self, i, j, k):
118                tmp.append((i, j, k))
119
120        x = X()
121        with test_support.check_py3k_warnings():
122            x[1:2] = 42
123        self.assertEqual(tmp, [(1, 2, 42)])
124
125    def test_pickle(self):
126        s = slice(10, 20, 3)
127        for protocol in (0,1,2):
128            t = loads(dumps(s, protocol))
129            self.assertEqual(s, t)
130            self.assertEqual(s.indices(15), t.indices(15))
131            self.assertNotEqual(id(s), id(t))
132
133    def test_cycle(self):
134        class myobj(): pass
135        o = myobj()
136        o.s = slice(o)
137        w = weakref.ref(o)
138        o = None
139        test_support.gc_collect()
140        self.assertIsNone(w())
141
142def test_main():
143    test_support.run_unittest(SliceTest)
144
145if __name__ == "__main__":
146    test_main()
147