ยปCore Development>Code coverage>Lib/test/test_slice.py

Python code coverage for Lib/test/test_slice.py

#countcontent
1n/a# tests for slice objects; in particular the indices method.
2n/a
3n/aimport itertools
4n/aimport operator
5n/aimport sys
6n/aimport unittest
7n/aimport weakref
8n/a
9n/afrom pickle import loads, dumps
10n/afrom test import support
11n/a
12n/a
13n/adef evaluate_slice_index(arg):
14n/a """
15n/a Helper function to convert a slice argument to an integer, and raise
16n/a TypeError with a suitable message on failure.
17n/a
18n/a """
19n/a if hasattr(arg, '__index__'):
20n/a return operator.index(arg)
21n/a else:
22n/a raise TypeError(
23n/a "slice indices must be integers or "
24n/a "None or have an __index__ method")
25n/a
26n/adef slice_indices(slice, length):
27n/a """
28n/a Reference implementation for the slice.indices method.
29n/a
30n/a """
31n/a # Compute step and length as integers.
32n/a length = operator.index(length)
33n/a step = 1 if slice.step is None else evaluate_slice_index(slice.step)
34n/a
35n/a # Raise ValueError for negative length or zero step.
36n/a if length < 0:
37n/a raise ValueError("length should not be negative")
38n/a if step == 0:
39n/a raise ValueError("slice step cannot be zero")
40n/a
41n/a # Find lower and upper bounds for start and stop.
42n/a lower = -1 if step < 0 else 0
43n/a upper = length - 1 if step < 0 else length
44n/a
45n/a # Compute start.
46n/a if slice.start is None:
47n/a start = upper if step < 0 else lower
48n/a else:
49n/a start = evaluate_slice_index(slice.start)
50n/a start = max(start + length, lower) if start < 0 else min(start, upper)
51n/a
52n/a # Compute stop.
53n/a if slice.stop is None:
54n/a stop = lower if step < 0 else upper
55n/a else:
56n/a stop = evaluate_slice_index(slice.stop)
57n/a stop = max(stop + length, lower) if stop < 0 else min(stop, upper)
58n/a
59n/a return start, stop, step
60n/a
61n/a
62n/a# Class providing an __index__ method. Used for testing slice.indices.
63n/a
64n/aclass MyIndexable(object):
65n/a def __init__(self, value):
66n/a self.value = value
67n/a
68n/a def __index__(self):
69n/a return self.value
70n/a
71n/a
72n/aclass SliceTest(unittest.TestCase):
73n/a
74n/a def test_constructor(self):
75n/a self.assertRaises(TypeError, slice)
76n/a self.assertRaises(TypeError, slice, 1, 2, 3, 4)
77n/a
78n/a def test_repr(self):
79n/a self.assertEqual(repr(slice(1, 2, 3)), "slice(1, 2, 3)")
80n/a
81n/a def test_hash(self):
82n/a # Verify clearing of SF bug #800796
83n/a self.assertRaises(TypeError, hash, slice(5))
84n/a with self.assertRaises(TypeError):
85n/a slice(5).__hash__()
86n/a
87n/a def test_cmp(self):
88n/a s1 = slice(1, 2, 3)
89n/a s2 = slice(1, 2, 3)
90n/a s3 = slice(1, 2, 4)
91n/a self.assertEqual(s1, s2)
92n/a self.assertNotEqual(s1, s3)
93n/a self.assertNotEqual(s1, None)
94n/a self.assertNotEqual(s1, (1, 2, 3))
95n/a self.assertNotEqual(s1, "")
96n/a
97n/a class Exc(Exception):
98n/a pass
99n/a
100n/a class BadCmp(object):
101n/a def __eq__(self, other):
102n/a raise Exc
103n/a
104n/a s1 = slice(BadCmp())
105n/a s2 = slice(BadCmp())
106n/a self.assertEqual(s1, s1)
107n/a self.assertRaises(Exc, lambda: s1 == s2)
108n/a
109n/a s1 = slice(1, BadCmp())
110n/a s2 = slice(1, BadCmp())
111n/a self.assertEqual(s1, s1)
112n/a self.assertRaises(Exc, lambda: s1 == s2)
113n/a
114n/a s1 = slice(1, 2, BadCmp())
115n/a s2 = slice(1, 2, BadCmp())
116n/a self.assertEqual(s1, s1)
117n/a self.assertRaises(Exc, lambda: s1 == s2)
118n/a
119n/a def test_members(self):
120n/a s = slice(1)
121n/a self.assertEqual(s.start, None)
122n/a self.assertEqual(s.stop, 1)
123n/a self.assertEqual(s.step, None)
124n/a
125n/a s = slice(1, 2)
126n/a self.assertEqual(s.start, 1)
127n/a self.assertEqual(s.stop, 2)
128n/a self.assertEqual(s.step, None)
129n/a
130n/a s = slice(1, 2, 3)
131n/a self.assertEqual(s.start, 1)
132n/a self.assertEqual(s.stop, 2)
133n/a self.assertEqual(s.step, 3)
134n/a
135n/a class AnyClass:
136n/a pass
137n/a
138n/a obj = AnyClass()
139n/a s = slice(obj)
140n/a self.assertTrue(s.stop is obj)
141n/a
142n/a def check_indices(self, slice, length):
143n/a try:
144n/a actual = slice.indices(length)
145n/a except ValueError:
146n/a actual = "valueerror"
147n/a try:
148n/a expected = slice_indices(slice, length)
149n/a except ValueError:
150n/a expected = "valueerror"
151n/a self.assertEqual(actual, expected)
152n/a
153n/a if length >= 0 and slice.step != 0:
154n/a actual = range(*slice.indices(length))
155n/a expected = range(length)[slice]
156n/a self.assertEqual(actual, expected)
157n/a
158n/a def test_indices(self):
159n/a self.assertEqual(slice(None ).indices(10), (0, 10, 1))
160n/a self.assertEqual(slice(None, None, 2).indices(10), (0, 10, 2))
161n/a self.assertEqual(slice(1, None, 2).indices(10), (1, 10, 2))
162n/a self.assertEqual(slice(None, None, -1).indices(10), (9, -1, -1))
163n/a self.assertEqual(slice(None, None, -2).indices(10), (9, -1, -2))
164n/a self.assertEqual(slice(3, None, -2).indices(10), (3, -1, -2))
165n/a # issue 3004 tests
166n/a self.assertEqual(slice(None, -9).indices(10), (0, 1, 1))
167n/a self.assertEqual(slice(None, -10).indices(10), (0, 0, 1))
168n/a self.assertEqual(slice(None, -11).indices(10), (0, 0, 1))
169n/a self.assertEqual(slice(None, -10, -1).indices(10), (9, 0, -1))
170n/a self.assertEqual(slice(None, -11, -1).indices(10), (9, -1, -1))
171n/a self.assertEqual(slice(None, -12, -1).indices(10), (9, -1, -1))
172n/a self.assertEqual(slice(None, 9).indices(10), (0, 9, 1))
173n/a self.assertEqual(slice(None, 10).indices(10), (0, 10, 1))
174n/a self.assertEqual(slice(None, 11).indices(10), (0, 10, 1))
175n/a self.assertEqual(slice(None, 8, -1).indices(10), (9, 8, -1))
176n/a self.assertEqual(slice(None, 9, -1).indices(10), (9, 9, -1))
177n/a self.assertEqual(slice(None, 10, -1).indices(10), (9, 9, -1))
178n/a
179n/a self.assertEqual(
180n/a slice(-100, 100 ).indices(10),
181n/a slice(None).indices(10)
182n/a )
183n/a self.assertEqual(
184n/a slice(100, -100, -1).indices(10),
185n/a slice(None, None, -1).indices(10)
186n/a )
187n/a self.assertEqual(slice(-100, 100, 2).indices(10), (0, 10, 2))
188n/a
189n/a self.assertEqual(list(range(10))[::sys.maxsize - 1], [0])
190n/a
191n/a # Check a variety of start, stop, step and length values, including
192n/a # values exceeding sys.maxsize (see issue #14794).
193n/a vals = [None, -2**100, -2**30, -53, -7, -1, 0, 1, 7, 53, 2**30, 2**100]
194n/a lengths = [0, 1, 7, 53, 2**30, 2**100]
195n/a for slice_args in itertools.product(vals, repeat=3):
196n/a s = slice(*slice_args)
197n/a for length in lengths:
198n/a self.check_indices(s, length)
199n/a self.check_indices(slice(0, 10, 1), -3)
200n/a
201n/a # Negative length should raise ValueError
202n/a with self.assertRaises(ValueError):
203n/a slice(None).indices(-1)
204n/a
205n/a # Zero step should raise ValueError
206n/a with self.assertRaises(ValueError):
207n/a slice(0, 10, 0).indices(5)
208n/a
209n/a # Using a start, stop or step or length that can't be interpreted as an
210n/a # integer should give a TypeError ...
211n/a with self.assertRaises(TypeError):
212n/a slice(0.0, 10, 1).indices(5)
213n/a with self.assertRaises(TypeError):
214n/a slice(0, 10.0, 1).indices(5)
215n/a with self.assertRaises(TypeError):
216n/a slice(0, 10, 1.0).indices(5)
217n/a with self.assertRaises(TypeError):
218n/a slice(0, 10, 1).indices(5.0)
219n/a
220n/a # ... but it should be fine to use a custom class that provides index.
221n/a self.assertEqual(slice(0, 10, 1).indices(5), (0, 5, 1))
222n/a self.assertEqual(slice(MyIndexable(0), 10, 1).indices(5), (0, 5, 1))
223n/a self.assertEqual(slice(0, MyIndexable(10), 1).indices(5), (0, 5, 1))
224n/a self.assertEqual(slice(0, 10, MyIndexable(1)).indices(5), (0, 5, 1))
225n/a self.assertEqual(slice(0, 10, 1).indices(MyIndexable(5)), (0, 5, 1))
226n/a
227n/a def test_setslice_without_getslice(self):
228n/a tmp = []
229n/a class X(object):
230n/a def __setitem__(self, i, k):
231n/a tmp.append((i, k))
232n/a
233n/a x = X()
234n/a x[1:2] = 42
235n/a self.assertEqual(tmp, [(slice(1, 2), 42)])
236n/a
237n/a def test_pickle(self):
238n/a s = slice(10, 20, 3)
239n/a for protocol in (0,1,2):
240n/a t = loads(dumps(s, protocol))
241n/a self.assertEqual(s, t)
242n/a self.assertEqual(s.indices(15), t.indices(15))
243n/a self.assertNotEqual(id(s), id(t))
244n/a
245n/a def test_cycle(self):
246n/a class myobj(): pass
247n/a o = myobj()
248n/a o.s = slice(o)
249n/a w = weakref.ref(o)
250n/a o = None
251n/a support.gc_collect()
252n/a self.assertIsNone(w())
253n/a
254n/aif __name__ == "__main__":
255n/a unittest.main()