Skip to content

Commit 69f2dc5

Browse files
Refactor test_capi.test_long (GH-122113)
Share common code for tests for PyLong_As*() functions. Co-authored-by: Victor Stinner <[email protected]>
1 parent ad935a9 commit 69f2dc5

File tree

1 file changed

+66
-179
lines changed

1 file changed

+66
-179
lines changed

Lib/test/test_capi/test_long.py

+66-179
Original file line numberDiff line numberDiff line change
@@ -162,224 +162,125 @@ def test_long_fromunicodeobject(self):
162162
# CRASHES fromunicodeobject(NULL, 0)
163163
# CRASHES fromunicodeobject(NULL, 16)
164164

165+
def check_long_asint(self, func, min_val, max_val, *,
166+
use_index=True,
167+
mask=False,
168+
negative_value_error=OverflowError):
169+
# round trip (object -> C integer -> object)
170+
values = (0, 1, 1234, max_val)
171+
if min_val < 0:
172+
values += (-1, min_val)
173+
for value in values:
174+
with self.subTest(value=value):
175+
self.assertEqual(func(value), value)
176+
self.assertEqual(func(IntSubclass(value)), value)
177+
if use_index:
178+
self.assertEqual(func(Index(value)), value)
179+
180+
if use_index:
181+
self.assertEqual(func(MyIndexAndInt()), 10)
182+
else:
183+
self.assertRaises(TypeError, func, Index(42))
184+
self.assertRaises(TypeError, func, MyIndexAndInt())
185+
186+
if mask:
187+
self.assertEqual(func(min_val - 1), max_val)
188+
self.assertEqual(func(max_val + 1), min_val)
189+
self.assertEqual(func(-1 << 1000), 0)
190+
self.assertEqual(func(1 << 1000), 0)
191+
else:
192+
self.assertRaises(negative_value_error, func, min_val - 1)
193+
self.assertRaises(negative_value_error, func, -1 << 1000)
194+
self.assertRaises(OverflowError, func, max_val + 1)
195+
self.assertRaises(OverflowError, func, 1 << 1000)
196+
self.assertRaises(TypeError, func, 1.0)
197+
self.assertRaises(TypeError, func, b'2')
198+
self.assertRaises(TypeError, func, '3')
199+
self.assertRaises(SystemError, func, NULL)
200+
201+
def check_long_asintandoverflow(self, func, min_val, max_val):
202+
# round trip (object -> C integer -> object)
203+
for value in (min_val, max_val, -1, 0, 1, 1234):
204+
with self.subTest(value=value):
205+
self.assertEqual(func(value), (value, 0))
206+
self.assertEqual(func(IntSubclass(value)), (value, 0))
207+
self.assertEqual(func(Index(value)), (value, 0))
208+
209+
self.assertEqual(func(MyIndexAndInt()), (10, 0))
210+
211+
self.assertEqual(func(min_val - 1), (-1, -1))
212+
self.assertEqual(func(max_val + 1), (-1, +1))
213+
214+
# CRASHES func(1.0)
215+
# CRASHES func(NULL)
216+
165217
def test_long_asint(self):
166218
# Test PyLong_AsInt()
167219
PyLong_AsInt = _testlimitedcapi.PyLong_AsInt
168220
from _testcapi import INT_MIN, INT_MAX
169-
170-
# round trip (object -> int -> object)
171-
for value in (INT_MIN, INT_MAX, -1, 0, 1, 123):
172-
with self.subTest(value=value):
173-
self.assertEqual(PyLong_AsInt(value), value)
174-
self.assertEqual(PyLong_AsInt(IntSubclass(42)), 42)
175-
self.assertEqual(PyLong_AsInt(Index(42)), 42)
176-
self.assertEqual(PyLong_AsInt(MyIndexAndInt()), 10)
177-
178-
# bound checking
179-
self.assertRaises(OverflowError, PyLong_AsInt, INT_MIN - 1)
180-
self.assertRaises(OverflowError, PyLong_AsInt, INT_MAX + 1)
181-
182-
# invalid type
183-
self.assertRaises(TypeError, PyLong_AsInt, 1.0)
184-
self.assertRaises(TypeError, PyLong_AsInt, b'2')
185-
self.assertRaises(TypeError, PyLong_AsInt, '3')
186-
self.assertRaises(SystemError, PyLong_AsInt, NULL)
221+
self.check_long_asint(PyLong_AsInt, INT_MIN, INT_MAX)
187222

188223
def test_long_aslong(self):
189224
# Test PyLong_AsLong() and PyLong_FromLong()
190225
aslong = _testlimitedcapi.pylong_aslong
191226
from _testcapi import LONG_MIN, LONG_MAX
192-
# round trip (object -> long -> object)
193-
for value in (LONG_MIN, LONG_MAX, -1, 0, 1, 1234):
194-
with self.subTest(value=value):
195-
self.assertEqual(aslong(value), value)
196-
197-
self.assertEqual(aslong(IntSubclass(42)), 42)
198-
self.assertEqual(aslong(Index(42)), 42)
199-
self.assertEqual(aslong(MyIndexAndInt()), 10)
200-
201-
self.assertRaises(OverflowError, aslong, LONG_MIN - 1)
202-
self.assertRaises(OverflowError, aslong, LONG_MAX + 1)
203-
self.assertRaises(TypeError, aslong, 1.0)
204-
self.assertRaises(TypeError, aslong, b'2')
205-
self.assertRaises(TypeError, aslong, '3')
206-
self.assertRaises(SystemError, aslong, NULL)
227+
self.check_long_asint(aslong, LONG_MIN, LONG_MAX)
207228

208229
def test_long_aslongandoverflow(self):
209230
# Test PyLong_AsLongAndOverflow()
210231
aslongandoverflow = _testlimitedcapi.pylong_aslongandoverflow
211232
from _testcapi import LONG_MIN, LONG_MAX
212-
# round trip (object -> long -> object)
213-
for value in (LONG_MIN, LONG_MAX, -1, 0, 1, 1234):
214-
with self.subTest(value=value):
215-
self.assertEqual(aslongandoverflow(value), (value, 0))
216-
217-
self.assertEqual(aslongandoverflow(IntSubclass(42)), (42, 0))
218-
self.assertEqual(aslongandoverflow(Index(42)), (42, 0))
219-
self.assertEqual(aslongandoverflow(MyIndexAndInt()), (10, 0))
220-
221-
self.assertEqual(aslongandoverflow(LONG_MIN - 1), (-1, -1))
222-
self.assertEqual(aslongandoverflow(LONG_MAX + 1), (-1, 1))
223-
# CRASHES aslongandoverflow(1.0)
224-
# CRASHES aslongandoverflow(NULL)
233+
self.check_long_asintandoverflow(aslongandoverflow, LONG_MIN, LONG_MAX)
225234

226235
def test_long_asunsignedlong(self):
227236
# Test PyLong_AsUnsignedLong() and PyLong_FromUnsignedLong()
228237
asunsignedlong = _testlimitedcapi.pylong_asunsignedlong
229238
from _testcapi import ULONG_MAX
230-
# round trip (object -> unsigned long -> object)
231-
for value in (ULONG_MAX, 0, 1, 1234):
232-
with self.subTest(value=value):
233-
self.assertEqual(asunsignedlong(value), value)
234-
235-
self.assertEqual(asunsignedlong(IntSubclass(42)), 42)
236-
self.assertRaises(TypeError, asunsignedlong, Index(42))
237-
self.assertRaises(TypeError, asunsignedlong, MyIndexAndInt())
238-
239-
self.assertRaises(OverflowError, asunsignedlong, -1)
240-
self.assertRaises(OverflowError, asunsignedlong, ULONG_MAX + 1)
241-
self.assertRaises(TypeError, asunsignedlong, 1.0)
242-
self.assertRaises(TypeError, asunsignedlong, b'2')
243-
self.assertRaises(TypeError, asunsignedlong, '3')
244-
self.assertRaises(SystemError, asunsignedlong, NULL)
239+
self.check_long_asint(asunsignedlong, 0, ULONG_MAX,
240+
use_index=False)
245241

246242
def test_long_asunsignedlongmask(self):
247243
# Test PyLong_AsUnsignedLongMask()
248244
asunsignedlongmask = _testlimitedcapi.pylong_asunsignedlongmask
249245
from _testcapi import ULONG_MAX
250-
# round trip (object -> unsigned long -> object)
251-
for value in (ULONG_MAX, 0, 1, 1234):
252-
with self.subTest(value=value):
253-
self.assertEqual(asunsignedlongmask(value), value)
254-
255-
self.assertEqual(asunsignedlongmask(IntSubclass(42)), 42)
256-
self.assertEqual(asunsignedlongmask(Index(42)), 42)
257-
self.assertEqual(asunsignedlongmask(MyIndexAndInt()), 10)
258-
259-
self.assertEqual(asunsignedlongmask(-1), ULONG_MAX)
260-
self.assertEqual(asunsignedlongmask(ULONG_MAX + 1), 0)
261-
self.assertRaises(TypeError, asunsignedlongmask, 1.0)
262-
self.assertRaises(TypeError, asunsignedlongmask, b'2')
263-
self.assertRaises(TypeError, asunsignedlongmask, '3')
264-
self.assertRaises(SystemError, asunsignedlongmask, NULL)
246+
self.check_long_asint(asunsignedlongmask, 0, ULONG_MAX, mask=True)
265247

266248
def test_long_aslonglong(self):
267249
# Test PyLong_AsLongLong() and PyLong_FromLongLong()
268250
aslonglong = _testlimitedcapi.pylong_aslonglong
269251
from _testcapi import LLONG_MIN, LLONG_MAX
270-
# round trip (object -> long long -> object)
271-
for value in (LLONG_MIN, LLONG_MAX, -1, 0, 1, 1234):
272-
with self.subTest(value=value):
273-
self.assertEqual(aslonglong(value), value)
274-
275-
self.assertEqual(aslonglong(IntSubclass(42)), 42)
276-
self.assertEqual(aslonglong(Index(42)), 42)
277-
self.assertEqual(aslonglong(MyIndexAndInt()), 10)
278-
279-
self.assertRaises(OverflowError, aslonglong, LLONG_MIN - 1)
280-
self.assertRaises(OverflowError, aslonglong, LLONG_MAX + 1)
281-
self.assertRaises(TypeError, aslonglong, 1.0)
282-
self.assertRaises(TypeError, aslonglong, b'2')
283-
self.assertRaises(TypeError, aslonglong, '3')
284-
self.assertRaises(SystemError, aslonglong, NULL)
252+
self.check_long_asint(aslonglong, LLONG_MIN, LLONG_MAX)
285253

286254
def test_long_aslonglongandoverflow(self):
287255
# Test PyLong_AsLongLongAndOverflow()
288256
aslonglongandoverflow = _testlimitedcapi.pylong_aslonglongandoverflow
289257
from _testcapi import LLONG_MIN, LLONG_MAX
290-
# round trip (object -> long long -> object)
291-
for value in (LLONG_MIN, LLONG_MAX, -1, 0, 1, 1234):
292-
with self.subTest(value=value):
293-
self.assertEqual(aslonglongandoverflow(value), (value, 0))
294-
295-
self.assertEqual(aslonglongandoverflow(IntSubclass(42)), (42, 0))
296-
self.assertEqual(aslonglongandoverflow(Index(42)), (42, 0))
297-
self.assertEqual(aslonglongandoverflow(MyIndexAndInt()), (10, 0))
298-
299-
self.assertEqual(aslonglongandoverflow(LLONG_MIN - 1), (-1, -1))
300-
self.assertEqual(aslonglongandoverflow(LLONG_MAX + 1), (-1, 1))
301-
# CRASHES aslonglongandoverflow(1.0)
302-
# CRASHES aslonglongandoverflow(NULL)
258+
self.check_long_asintandoverflow(aslonglongandoverflow, LLONG_MIN, LLONG_MAX)
303259

304260
def test_long_asunsignedlonglong(self):
305261
# Test PyLong_AsUnsignedLongLong() and PyLong_FromUnsignedLongLong()
306262
asunsignedlonglong = _testlimitedcapi.pylong_asunsignedlonglong
307263
from _testcapi import ULLONG_MAX
308-
# round trip (object -> unsigned long long -> object)
309-
for value in (ULLONG_MAX, 0, 1, 1234):
310-
with self.subTest(value=value):
311-
self.assertEqual(asunsignedlonglong(value), value)
312-
313-
self.assertEqual(asunsignedlonglong(IntSubclass(42)), 42)
314-
self.assertRaises(TypeError, asunsignedlonglong, Index(42))
315-
self.assertRaises(TypeError, asunsignedlonglong, MyIndexAndInt())
316-
317-
self.assertRaises(OverflowError, asunsignedlonglong, -1)
318-
self.assertRaises(OverflowError, asunsignedlonglong, ULLONG_MAX + 1)
319-
self.assertRaises(TypeError, asunsignedlonglong, 1.0)
320-
self.assertRaises(TypeError, asunsignedlonglong, b'2')
321-
self.assertRaises(TypeError, asunsignedlonglong, '3')
322-
self.assertRaises(SystemError, asunsignedlonglong, NULL)
264+
self.check_long_asint(asunsignedlonglong, 0, ULLONG_MAX, use_index=False)
323265

324266
def test_long_asunsignedlonglongmask(self):
325267
# Test PyLong_AsUnsignedLongLongMask()
326268
asunsignedlonglongmask = _testlimitedcapi.pylong_asunsignedlonglongmask
327269
from _testcapi import ULLONG_MAX
328-
# round trip (object -> unsigned long long -> object)
329-
for value in (ULLONG_MAX, 0, 1, 1234):
330-
with self.subTest(value=value):
331-
self.assertEqual(asunsignedlonglongmask(value), value)
332-
333-
self.assertEqual(asunsignedlonglongmask(IntSubclass(42)), 42)
334-
self.assertEqual(asunsignedlonglongmask(Index(42)), 42)
335-
self.assertEqual(asunsignedlonglongmask(MyIndexAndInt()), 10)
336-
337-
self.assertEqual(asunsignedlonglongmask(-1), ULLONG_MAX)
338-
self.assertEqual(asunsignedlonglongmask(ULLONG_MAX + 1), 0)
339-
self.assertRaises(TypeError, asunsignedlonglongmask, 1.0)
340-
self.assertRaises(TypeError, asunsignedlonglongmask, b'2')
341-
self.assertRaises(TypeError, asunsignedlonglongmask, '3')
342-
self.assertRaises(SystemError, asunsignedlonglongmask, NULL)
270+
self.check_long_asint(asunsignedlonglongmask, 0, ULLONG_MAX, mask=True)
343271

344272
def test_long_as_ssize_t(self):
345273
# Test PyLong_AsSsize_t() and PyLong_FromSsize_t()
346274
as_ssize_t = _testlimitedcapi.pylong_as_ssize_t
347275
from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
348-
# round trip (object -> Py_ssize_t -> object)
349-
for value in (PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, -1, 0, 1, 1234):
350-
with self.subTest(value=value):
351-
self.assertEqual(as_ssize_t(value), value)
352-
353-
self.assertEqual(as_ssize_t(IntSubclass(42)), 42)
354-
self.assertRaises(TypeError, as_ssize_t, Index(42))
355-
self.assertRaises(TypeError, as_ssize_t, MyIndexAndInt())
356-
357-
self.assertRaises(OverflowError, as_ssize_t, PY_SSIZE_T_MIN - 1)
358-
self.assertRaises(OverflowError, as_ssize_t, PY_SSIZE_T_MAX + 1)
359-
self.assertRaises(TypeError, as_ssize_t, 1.0)
360-
self.assertRaises(TypeError, as_ssize_t, b'2')
361-
self.assertRaises(TypeError, as_ssize_t, '3')
362-
self.assertRaises(SystemError, as_ssize_t, NULL)
276+
self.check_long_asint(as_ssize_t, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX,
277+
use_index=False)
363278

364279
def test_long_as_size_t(self):
365280
# Test PyLong_AsSize_t() and PyLong_FromSize_t()
366281
as_size_t = _testlimitedcapi.pylong_as_size_t
367282
from _testcapi import SIZE_MAX
368-
# round trip (object -> size_t -> object)
369-
for value in (SIZE_MAX, 0, 1, 1234):
370-
with self.subTest(value=value):
371-
self.assertEqual(as_size_t(value), value)
372-
373-
self.assertEqual(as_size_t(IntSubclass(42)), 42)
374-
self.assertRaises(TypeError, as_size_t, Index(42))
375-
self.assertRaises(TypeError, as_size_t, MyIndexAndInt())
376-
377-
self.assertRaises(OverflowError, as_size_t, -1)
378-
self.assertRaises(OverflowError, as_size_t, SIZE_MAX + 1)
379-
self.assertRaises(TypeError, as_size_t, 1.0)
380-
self.assertRaises(TypeError, as_size_t, b'2')
381-
self.assertRaises(TypeError, as_size_t, '3')
382-
self.assertRaises(SystemError, as_size_t, NULL)
283+
self.check_long_asint(as_size_t, 0, SIZE_MAX, use_index=False)
383284

384285
def test_long_asdouble(self):
385286
# Test PyLong_AsDouble()
@@ -431,21 +332,7 @@ def _test_long_aspid(self, aspid):
431332
bits = 8 * SIZEOF_PID_T
432333
PID_T_MIN = -2**(bits-1)
433334
PID_T_MAX = 2**(bits-1) - 1
434-
# round trip (object -> long -> object)
435-
for value in (PID_T_MIN, PID_T_MAX, -1, 0, 1, 1234):
436-
with self.subTest(value=value):
437-
self.assertEqual(aspid(value), value)
438-
439-
self.assertEqual(aspid(IntSubclass(42)), 42)
440-
self.assertEqual(aspid(Index(42)), 42)
441-
self.assertEqual(aspid(MyIndexAndInt()), 10)
442-
443-
self.assertRaises(OverflowError, aspid, PID_T_MIN - 1)
444-
self.assertRaises(OverflowError, aspid, PID_T_MAX + 1)
445-
self.assertRaises(TypeError, aspid, 1.0)
446-
self.assertRaises(TypeError, aspid, b'2')
447-
self.assertRaises(TypeError, aspid, '3')
448-
self.assertRaises(SystemError, aspid, NULL)
335+
self.check_long_asint(aspid, PID_T_MIN, PID_T_MAX)
449336

450337
def test_long_aspid(self):
451338
self._test_long_aspid(_testcapi.pylong_aspid)

0 commit comments

Comments
 (0)