55_testlimitedcapi = import_helper .import_module ('_testlimitedcapi' )
66
77NULL = None
8- SIZE_MAX = sys .maxsize
9- SIZE_MIN = - sys .maxsize - 1
8+ SSIZE_MAX = sys .maxsize
9+ SSIZE_MIN = - sys .maxsize - 1
1010
11- VALUES = [None , 0 , 1 , 2 , 3 , 5 , 7 , - 1 , - 2 , - 3 , - 5 , - 7 ]
12- STEPS = [None , 1 , 2 , 3 , 5 , - 1 , - 2 , - 3 , - 5 ]
13- LENGTHS = [0 , 1 , 2 , 5 , 10 ]
11+ VALUES = [None , 0 , 1 , 3 , 7 , - 1 , - 3 , - 7 ]
12+ STEPS = [None , 1 , 3 , 5 , - 1 , - 3 , - 5 ]
13+ LENGTHS = [0 , 1 , 3 , 10 ]
1414
1515
1616class Index :
@@ -76,11 +76,11 @@ def test_getindices(self):
7676 self .assertIsNone (getindices (slice (1 , 'a' ), 10 ))
7777 self .assertIsNone (getindices (slice (1 , 7 , 'a' ), 10 ))
7878
79- # negative length
80- self .assertIsNone (getindices (slice (None ), - 1 ))
81- self .assertIsNone (getindices (slice (1 , 7 , 2 ), - 1 ))
82- self .assertEqual (getindices (slice (- 10 , - 5 , 1 ), - 1 ), (- 11 , - 6 , 1 ))
83- self .assertEqual (getindices (slice (- 5 , - 10 , - 2 ), - 1 ), (- 6 , - 11 , - 2 ))
79+ # Negative length is not supported, but does not fail.
80+ self .assertIsNone (getindices (slice (None ), - 3 ))
81+ self .assertIsNone (getindices (slice (1 , 7 , 2 ), - 3 ))
82+ self .assertEqual (getindices (slice (- 10 , - 5 , 1 ), - 3 ), (- 13 , - 8 , 1 ))
83+ self .assertEqual (getindices (slice (- 5 , - 10 , - 2 ), - 3 ), (- 8 , - 13 , - 2 ))
8484
8585 # CRASHES getindices(NULL, 10)
8686 # CRASHES getindices(object(), 10)
@@ -92,27 +92,27 @@ def test_unpack(self):
9292 self .assertEqual (unpack (slice (1 , 7 , 2 )), (1 , 7 , 2 ))
9393 self .assertEqual (unpack (slice (7 , 1 , - 2 )), (7 , 1 , - 2 ))
9494 self .assertEqual (unpack (slice (None , 7 , 2 )), (0 , 7 , 2 ))
95- self .assertEqual (unpack (slice (None , 7 , - 2 )), (SIZE_MAX , 7 , - 2 ))
96- self .assertEqual (unpack (slice (1 , None , 2 )), (1 , SIZE_MAX , 2 ))
97- self .assertEqual (unpack (slice (1 , None , - 2 )), (1 , SIZE_MIN , - 2 ))
98- self .assertEqual (unpack (slice (None )), (0 , SIZE_MAX , 1 ))
95+ self .assertEqual (unpack (slice (None , 7 , - 2 )), (SSIZE_MAX , 7 , - 2 ))
96+ self .assertEqual (unpack (slice (1 , None , 2 )), (1 , SSIZE_MAX , 2 ))
97+ self .assertEqual (unpack (slice (1 , None , - 2 )), (1 , SSIZE_MIN , - 2 ))
98+ self .assertEqual (unpack (slice (None )), (0 , SSIZE_MAX , 1 ))
9999 self .assertEqual (unpack (slice (None , None , - 1 )),
100- (SIZE_MAX , SIZE_MIN , - 1 ))
100+ (SSIZE_MAX , SSIZE_MIN , - 1 ))
101101 # Negative indices are not adjusted.
102102 self .assertEqual (unpack (slice (- 3 , - 1 )), (- 3 , - 1 , 1 ))
103103 self .assertEqual (unpack (slice (Index (1 ), Index (7 ), Index (2 ))),
104104 (1 , 7 , 2 ))
105105
106106 # Values which do not fit in Py_ssize_t are silently clipped.
107- self .assertEqual (unpack (slice (1 , 2 ** 1000 )), (1 , SIZE_MAX , 1 ))
108- self .assertEqual (unpack (slice (1 , - 2 ** 1000 )), (1 , SIZE_MIN , 1 ))
109- self .assertEqual (unpack (slice (2 ** 1000 , 7 )), (SIZE_MAX , 7 , 1 ))
110- self .assertEqual (unpack (slice (- 2 ** 1000 , 7 )), (SIZE_MIN , 7 , 1 ))
111- self .assertEqual (unpack (slice (1 , 7 , 2 ** 1000 )), (1 , 7 , SIZE_MAX ))
107+ self .assertEqual (unpack (slice (1 , 2 ** 1000 )), (1 , SSIZE_MAX , 1 ))
108+ self .assertEqual (unpack (slice (1 , - 2 ** 1000 )), (1 , SSIZE_MIN , 1 ))
109+ self .assertEqual (unpack (slice (2 ** 1000 , 7 )), (SSIZE_MAX , 7 , 1 ))
110+ self .assertEqual (unpack (slice (- 2 ** 1000 , 7 )), (SSIZE_MIN , 7 , 1 ))
111+ self .assertEqual (unpack (slice (1 , 7 , 2 ** 1000 )), (1 , 7 , SSIZE_MAX ))
112112 # The step is boosted to -PY_SSIZE_T_MAX, not PY_SSIZE_T_MIN, so
113113 # that negating it is safe.
114- self .assertEqual (unpack (slice (7 , 1 , - 2 ** 1000 )), (7 , 1 , - SIZE_MAX ))
115- self .assertEqual (unpack (slice (7 , 1 , SIZE_MIN )), (7 , 1 , - SIZE_MAX ))
114+ self .assertEqual (unpack (slice (7 , 1 , - 2 ** 1000 )), (7 , 1 , - SSIZE_MAX ))
115+ self .assertEqual (unpack (slice (7 , 1 , SSIZE_MIN )), (7 , 1 , - SSIZE_MAX ))
116116
117117 with self .assertRaisesRegex (ValueError , 'slice step cannot be zero' ):
118118 unpack (slice (1 , 1 , 0 ))
@@ -153,8 +153,8 @@ def test_adjustindices(self):
153153 # Out of bounds indices are clipped.
154154 self .assertEqual (adjust (10 , - 100 , 100 , 1 ), (10 , 0 , 10 ))
155155 self .assertEqual (adjust (10 , 100 , - 100 , - 1 ), (10 , 9 , - 1 ))
156- self .assertEqual (adjust (10 , SIZE_MIN , SIZE_MAX , 1 ), (10 , 0 , 10 ))
157- self .assertEqual (adjust (10 , SIZE_MAX , SIZE_MIN , - 1 ), (10 , 9 , - 1 ))
156+ self .assertEqual (adjust (10 , SSIZE_MIN , SSIZE_MAX , 1 ), (10 , 0 , 10 ))
157+ self .assertEqual (adjust (10 , SSIZE_MAX , SSIZE_MIN , - 1 ), (10 , 9 , - 1 ))
158158 self .assertEqual (adjust (0 , 1 , 7 , 1 ), (0 , 0 , 0 ))
159159 self .assertEqual (adjust (0 , 7 , 1 , - 1 ), (0 , - 1 , - 1 ))
160160
@@ -170,18 +170,24 @@ def test_adjustindices(self):
170170 self .assertEqual (slicelength ,
171171 len (range (start2 , stop2 , step )))
172172
173+ # Negative length is not supported, but does not fail.
174+ self .assertEqual (adjust (- 3 , 1 , 7 , 1 ), (0 , - 3 , - 3 ))
175+ self .assertEqual (adjust (- 3 , 7 , 1 , - 1 ), (0 , - 4 , - 4 ))
176+ self .assertEqual (adjust (- 3 , - 10 , - 5 , 1 ), (0 , 0 , 0 ))
177+
173178 # The step is asserted to be neither zero nor less than
174179 # -PY_SSIZE_T_MAX.
175180 # CRASHES adjust(10, 0, 10, 0)
176- # CRASHES adjust(10, 0, 10, SIZE_MIN )
181+ # CRASHES adjust(10, 0, 10, SSIZE_MIN )
177182
178183
179- class GetIndicesExTest (unittest .TestCase ):
184+ class GetIndicesExMacroTest (unittest .TestCase ):
180185 # PySlice_GetIndicesEx() is a macro using PySlice_Unpack() and
181186 # PySlice_AdjustIndices(). It is also a deprecated function, exported
182187 # for the stable ABI.
183- getindicesex = staticmethod (_testlimitedcapi .slice_getindicesex )
184- getindicesex_seq = staticmethod (_testlimitedcapi .slice_getindicesex_seq )
188+ getindicesex = staticmethod (_testlimitedcapi .slice_getindicesex_macro )
189+ getindicesex_seq = staticmethod (
190+ _testlimitedcapi .slice_getindicesex_seq_macro )
185191 # The macro evaluates the length after calling PySlice_Unpack(), so the
186192 # size of the list after removing an item is used.
187193 resized = (6 , 8 , 1 , 2 )
@@ -215,18 +221,21 @@ def test_getindicesex(self):
215221 self .assertEqual (getindicesex (slice (100 , - 100 , - 1 ), 10 ),
216222 (9 , - 1 , - 1 , 10 ))
217223 self .assertEqual (getindicesex (slice (None ), 0 ), (0 , 0 , 1 , 0 ))
224+ self .assertEqual (getindicesex (slice (1 , 7 , 2 ), 0 ), (0 , 0 , 2 , 0 ))
225+ self .assertEqual (getindicesex (slice (None , None , - 1 ), 0 ),
226+ (- 1 , - 1 , - 1 , 0 ))
218227
219228 # Indices which do not fit in Py_ssize_t are clipped, not rejected.
220229 # Note that slice.indices() does not clip the step.
221230 self .assertEqual (getindicesex (slice (1 , 2 ** 1000 ), 10 ), (1 , 10 , 1 , 9 ))
222231 self .assertEqual (getindicesex (slice (2 ** 1000 , 7 ), 10 ), (10 , 7 , 1 , 0 ))
223232 self .assertEqual (getindicesex (slice (1 , 7 , 2 ** 1000 ), 10 ),
224- (1 , 7 , SIZE_MAX , 1 ))
233+ (1 , 7 , SSIZE_MAX , 1 ))
225234 # -PY_SSIZE_T_MAX-1 is replaced with -PY_SSIZE_T_MAX.
226235 self .assertEqual (getindicesex (slice (7 , 1 , - 2 ** 1000 ), 10 ),
227- (7 , 1 , - SIZE_MAX , 1 ))
228- self .assertEqual (getindicesex (slice (7 , 1 , SIZE_MIN ), 10 ),
229- (7 , 1 , - SIZE_MAX , 1 ))
236+ (7 , 1 , - SSIZE_MAX , 1 ))
237+ self .assertEqual (getindicesex (slice (7 , 1 , SSIZE_MIN ), 10 ),
238+ (7 , 1 , - SSIZE_MAX , 1 ))
230239
231240 with self .assertRaisesRegex (ValueError , 'slice step cannot be zero' ):
232241 getindicesex (slice (1 , 7 , 0 ), 10 )
@@ -246,6 +255,11 @@ def test_getindicesex(self):
246255 with self .assertRaisesRegex (RuntimeError , 'bad index' ):
247256 getindicesex (slice (1 , 7 , BadIndex ()), 10 )
248257
258+ # Negative length is not supported, but does not fail.
259+ self .assertEqual (getindicesex (slice (None ), - 3 ), (- 3 , - 3 , 1 , 0 ))
260+ self .assertEqual (getindicesex (slice (1 , 7 , 2 ), - 3 ), (- 3 , - 3 , 2 , 0 ))
261+ self .assertEqual (getindicesex (slice (7 , 1 , - 2 ), - 3 ), (- 4 , - 4 , - 2 , 0 ))
262+
249263 # CRASHES getindicesex(NULL, 10)
250264 # CRASHES getindicesex(object(), 10)
251265
@@ -254,6 +268,7 @@ def test_getindicesex_seq(self):
254268 getindicesex_seq = self .getindicesex_seq
255269 seq = list (range (10 ))
256270 self .assertEqual (getindicesex_seq (slice (- 3 , - 1 ), seq ), (7 , 9 , 1 , 2 ))
271+ self .assertEqual (getindicesex_seq (slice (- 3 , - 1 ), []), (0 , 0 , 1 , 0 ))
257272
258273 # gh-72054: __index__() can resize the sequence. Negative indices
259274 # are adjusted by the length, so the result depends on when it is
@@ -278,12 +293,12 @@ def test_getindicesex_seq(self):
278293 # CRASHES getindicesex_seq(slice(None), object())
279294
280295
281- class GetIndicesExDeprecatedTest ( GetIndicesExTest ):
296+ class GetIndicesExFuncTest ( GetIndicesExMacroTest ):
282297 # The deprecated function is equivalent to the macro, except that the
283298 # length is evaluated before the call.
284- getindicesex = staticmethod (_testlimitedcapi .slice_getindicesex_deprecated )
299+ getindicesex = staticmethod (_testlimitedcapi .slice_getindicesex_func )
285300 getindicesex_seq = staticmethod (
286- _testlimitedcapi .slice_getindicesex_seq_deprecated )
301+ _testlimitedcapi .slice_getindicesex_seq_func )
287302 # The size of the list before removing an item is used.
288303 resized = (7 , 9 , 1 , 2 )
289304
0 commit comments