Skip to content

Commit b24ca6a

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

File tree

1 file changed

+65
-161
lines changed

1 file changed

+65
-161
lines changed

Lib/test/test_capi/test_long.py

+65-161
Original file line numberDiff line numberDiff line change
@@ -160,201 +160,119 @@ def test_long_fromunicodeobject(self):
160160
# CRASHES fromunicodeobject(NULL, 0)
161161
# CRASHES fromunicodeobject(NULL, 16)
162162

163+
def check_long_asint(self, func, min_val, max_val, *,
164+
use_index=True,
165+
mask=False,
166+
negative_value_error=OverflowError):
167+
# round trip (object -> C integer -> object)
168+
values = (0, 1, 1234, max_val)
169+
if min_val < 0:
170+
values += (-1, min_val)
171+
for value in values:
172+
with self.subTest(value=value):
173+
self.assertEqual(func(value), value)
174+
self.assertEqual(func(IntSubclass(value)), value)
175+
if use_index:
176+
self.assertEqual(func(Index(value)), value)
177+
178+
if use_index:
179+
self.assertEqual(func(MyIndexAndInt()), 10)
180+
else:
181+
self.assertRaises(TypeError, func, Index(42))
182+
self.assertRaises(TypeError, func, MyIndexAndInt())
183+
184+
if mask:
185+
self.assertEqual(func(min_val - 1), max_val)
186+
self.assertEqual(func(max_val + 1), min_val)
187+
self.assertEqual(func(-1 << 1000), 0)
188+
self.assertEqual(func(1 << 1000), 0)
189+
else:
190+
self.assertRaises(negative_value_error, func, min_val - 1)
191+
self.assertRaises(negative_value_error, func, -1 << 1000)
192+
self.assertRaises(OverflowError, func, max_val + 1)
193+
self.assertRaises(OverflowError, func, 1 << 1000)
194+
self.assertRaises(TypeError, func, 1.0)
195+
self.assertRaises(TypeError, func, b'2')
196+
self.assertRaises(TypeError, func, '3')
197+
self.assertRaises(SystemError, func, NULL)
198+
199+
def check_long_asintandoverflow(self, func, min_val, max_val):
200+
# round trip (object -> C integer -> object)
201+
for value in (min_val, max_val, -1, 0, 1, 1234):
202+
with self.subTest(value=value):
203+
self.assertEqual(func(value), (value, 0))
204+
self.assertEqual(func(IntSubclass(value)), (value, 0))
205+
self.assertEqual(func(Index(value)), (value, 0))
206+
207+
self.assertEqual(func(MyIndexAndInt()), (10, 0))
208+
209+
self.assertEqual(func(min_val - 1), (-1, -1))
210+
self.assertEqual(func(max_val + 1), (-1, +1))
211+
212+
# CRASHES func(1.0)
213+
# CRASHES func(NULL)
214+
163215
def test_long_aslong(self):
164216
# Test PyLong_AsLong() and PyLong_FromLong()
165217
aslong = _testcapi.pylong_aslong
166218
from _testcapi import LONG_MIN, LONG_MAX
167-
# round trip (object -> long -> object)
168-
for value in (LONG_MIN, LONG_MAX, -1, 0, 1, 1234):
169-
with self.subTest(value=value):
170-
self.assertEqual(aslong(value), value)
171-
172-
self.assertEqual(aslong(IntSubclass(42)), 42)
173-
self.assertEqual(aslong(Index(42)), 42)
174-
self.assertEqual(aslong(MyIndexAndInt()), 10)
175-
176-
self.assertRaises(OverflowError, aslong, LONG_MIN - 1)
177-
self.assertRaises(OverflowError, aslong, LONG_MAX + 1)
178-
self.assertRaises(TypeError, aslong, 1.0)
179-
self.assertRaises(TypeError, aslong, b'2')
180-
self.assertRaises(TypeError, aslong, '3')
181-
self.assertRaises(SystemError, aslong, NULL)
219+
self.check_long_asint(aslong, LONG_MIN, LONG_MAX)
182220

183221
def test_long_aslongandoverflow(self):
184222
# Test PyLong_AsLongAndOverflow()
185223
aslongandoverflow = _testcapi.pylong_aslongandoverflow
186224
from _testcapi import LONG_MIN, LONG_MAX
187-
# round trip (object -> long -> object)
188-
for value in (LONG_MIN, LONG_MAX, -1, 0, 1, 1234):
189-
with self.subTest(value=value):
190-
self.assertEqual(aslongandoverflow(value), (value, 0))
191-
192-
self.assertEqual(aslongandoverflow(IntSubclass(42)), (42, 0))
193-
self.assertEqual(aslongandoverflow(Index(42)), (42, 0))
194-
self.assertEqual(aslongandoverflow(MyIndexAndInt()), (10, 0))
195-
196-
self.assertEqual(aslongandoverflow(LONG_MIN - 1), (-1, -1))
197-
self.assertEqual(aslongandoverflow(LONG_MAX + 1), (-1, 1))
198-
# CRASHES aslongandoverflow(1.0)
199-
# CRASHES aslongandoverflow(NULL)
225+
self.check_long_asintandoverflow(aslongandoverflow, LONG_MIN, LONG_MAX)
200226

201227
def test_long_asunsignedlong(self):
202228
# Test PyLong_AsUnsignedLong() and PyLong_FromUnsignedLong()
203229
asunsignedlong = _testcapi.pylong_asunsignedlong
204230
from _testcapi import ULONG_MAX
205-
# round trip (object -> unsigned long -> object)
206-
for value in (ULONG_MAX, 0, 1, 1234):
207-
with self.subTest(value=value):
208-
self.assertEqual(asunsignedlong(value), value)
209-
210-
self.assertEqual(asunsignedlong(IntSubclass(42)), 42)
211-
self.assertRaises(TypeError, asunsignedlong, Index(42))
212-
self.assertRaises(TypeError, asunsignedlong, MyIndexAndInt())
213-
214-
self.assertRaises(OverflowError, asunsignedlong, -1)
215-
self.assertRaises(OverflowError, asunsignedlong, ULONG_MAX + 1)
216-
self.assertRaises(TypeError, asunsignedlong, 1.0)
217-
self.assertRaises(TypeError, asunsignedlong, b'2')
218-
self.assertRaises(TypeError, asunsignedlong, '3')
219-
self.assertRaises(SystemError, asunsignedlong, NULL)
231+
self.check_long_asint(asunsignedlong, 0, ULONG_MAX,
232+
use_index=False)
220233

221234
def test_long_asunsignedlongmask(self):
222235
# Test PyLong_AsUnsignedLongMask()
223236
asunsignedlongmask = _testcapi.pylong_asunsignedlongmask
224237
from _testcapi import ULONG_MAX
225-
# round trip (object -> unsigned long -> object)
226-
for value in (ULONG_MAX, 0, 1, 1234):
227-
with self.subTest(value=value):
228-
self.assertEqual(asunsignedlongmask(value), value)
229-
230-
self.assertEqual(asunsignedlongmask(IntSubclass(42)), 42)
231-
self.assertEqual(asunsignedlongmask(Index(42)), 42)
232-
self.assertEqual(asunsignedlongmask(MyIndexAndInt()), 10)
233-
234-
self.assertEqual(asunsignedlongmask(-1), ULONG_MAX)
235-
self.assertEqual(asunsignedlongmask(ULONG_MAX + 1), 0)
236-
self.assertRaises(TypeError, asunsignedlongmask, 1.0)
237-
self.assertRaises(TypeError, asunsignedlongmask, b'2')
238-
self.assertRaises(TypeError, asunsignedlongmask, '3')
239-
self.assertRaises(SystemError, asunsignedlongmask, NULL)
238+
self.check_long_asint(asunsignedlongmask, 0, ULONG_MAX, mask=True)
240239

241240
def test_long_aslonglong(self):
242241
# Test PyLong_AsLongLong() and PyLong_FromLongLong()
243242
aslonglong = _testcapi.pylong_aslonglong
244243
from _testcapi import LLONG_MIN, LLONG_MAX
245-
# round trip (object -> long long -> object)
246-
for value in (LLONG_MIN, LLONG_MAX, -1, 0, 1, 1234):
247-
with self.subTest(value=value):
248-
self.assertEqual(aslonglong(value), value)
249-
250-
self.assertEqual(aslonglong(IntSubclass(42)), 42)
251-
self.assertEqual(aslonglong(Index(42)), 42)
252-
self.assertEqual(aslonglong(MyIndexAndInt()), 10)
253-
254-
self.assertRaises(OverflowError, aslonglong, LLONG_MIN - 1)
255-
self.assertRaises(OverflowError, aslonglong, LLONG_MAX + 1)
256-
self.assertRaises(TypeError, aslonglong, 1.0)
257-
self.assertRaises(TypeError, aslonglong, b'2')
258-
self.assertRaises(TypeError, aslonglong, '3')
259-
self.assertRaises(SystemError, aslonglong, NULL)
244+
self.check_long_asint(aslonglong, LLONG_MIN, LLONG_MAX)
260245

261246
def test_long_aslonglongandoverflow(self):
262247
# Test PyLong_AsLongLongAndOverflow()
263248
aslonglongandoverflow = _testcapi.pylong_aslonglongandoverflow
264249
from _testcapi import LLONG_MIN, LLONG_MAX
265-
# round trip (object -> long long -> object)
266-
for value in (LLONG_MIN, LLONG_MAX, -1, 0, 1, 1234):
267-
with self.subTest(value=value):
268-
self.assertEqual(aslonglongandoverflow(value), (value, 0))
269-
270-
self.assertEqual(aslonglongandoverflow(IntSubclass(42)), (42, 0))
271-
self.assertEqual(aslonglongandoverflow(Index(42)), (42, 0))
272-
self.assertEqual(aslonglongandoverflow(MyIndexAndInt()), (10, 0))
273-
274-
self.assertEqual(aslonglongandoverflow(LLONG_MIN - 1), (-1, -1))
275-
self.assertEqual(aslonglongandoverflow(LLONG_MAX + 1), (-1, 1))
276-
# CRASHES aslonglongandoverflow(1.0)
277-
# CRASHES aslonglongandoverflow(NULL)
250+
self.check_long_asintandoverflow(aslonglongandoverflow, LLONG_MIN, LLONG_MAX)
278251

279252
def test_long_asunsignedlonglong(self):
280253
# Test PyLong_AsUnsignedLongLong() and PyLong_FromUnsignedLongLong()
281254
asunsignedlonglong = _testcapi.pylong_asunsignedlonglong
282255
from _testcapi import ULLONG_MAX
283-
# round trip (object -> unsigned long long -> object)
284-
for value in (ULLONG_MAX, 0, 1, 1234):
285-
with self.subTest(value=value):
286-
self.assertEqual(asunsignedlonglong(value), value)
287-
288-
self.assertEqual(asunsignedlonglong(IntSubclass(42)), 42)
289-
self.assertRaises(TypeError, asunsignedlonglong, Index(42))
290-
self.assertRaises(TypeError, asunsignedlonglong, MyIndexAndInt())
291-
292-
self.assertRaises(OverflowError, asunsignedlonglong, -1)
293-
self.assertRaises(OverflowError, asunsignedlonglong, ULLONG_MAX + 1)
294-
self.assertRaises(TypeError, asunsignedlonglong, 1.0)
295-
self.assertRaises(TypeError, asunsignedlonglong, b'2')
296-
self.assertRaises(TypeError, asunsignedlonglong, '3')
297-
self.assertRaises(SystemError, asunsignedlonglong, NULL)
256+
self.check_long_asint(asunsignedlonglong, 0, ULLONG_MAX, use_index=False)
298257

299258
def test_long_asunsignedlonglongmask(self):
300259
# Test PyLong_AsUnsignedLongLongMask()
301260
asunsignedlonglongmask = _testcapi.pylong_asunsignedlonglongmask
302261
from _testcapi import ULLONG_MAX
303-
# round trip (object -> unsigned long long -> object)
304-
for value in (ULLONG_MAX, 0, 1, 1234):
305-
with self.subTest(value=value):
306-
self.assertEqual(asunsignedlonglongmask(value), value)
307-
308-
self.assertEqual(asunsignedlonglongmask(IntSubclass(42)), 42)
309-
self.assertEqual(asunsignedlonglongmask(Index(42)), 42)
310-
self.assertEqual(asunsignedlonglongmask(MyIndexAndInt()), 10)
311-
312-
self.assertEqual(asunsignedlonglongmask(-1), ULLONG_MAX)
313-
self.assertEqual(asunsignedlonglongmask(ULLONG_MAX + 1), 0)
314-
self.assertRaises(TypeError, asunsignedlonglongmask, 1.0)
315-
self.assertRaises(TypeError, asunsignedlonglongmask, b'2')
316-
self.assertRaises(TypeError, asunsignedlonglongmask, '3')
317-
self.assertRaises(SystemError, asunsignedlonglongmask, NULL)
262+
self.check_long_asint(asunsignedlonglongmask, 0, ULLONG_MAX, mask=True)
318263

319264
def test_long_as_ssize_t(self):
320265
# Test PyLong_AsSsize_t() and PyLong_FromSsize_t()
321266
as_ssize_t = _testcapi.pylong_as_ssize_t
322267
from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
323-
# round trip (object -> Py_ssize_t -> object)
324-
for value in (PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, -1, 0, 1, 1234):
325-
with self.subTest(value=value):
326-
self.assertEqual(as_ssize_t(value), value)
327-
328-
self.assertEqual(as_ssize_t(IntSubclass(42)), 42)
329-
self.assertRaises(TypeError, as_ssize_t, Index(42))
330-
self.assertRaises(TypeError, as_ssize_t, MyIndexAndInt())
331-
332-
self.assertRaises(OverflowError, as_ssize_t, PY_SSIZE_T_MIN - 1)
333-
self.assertRaises(OverflowError, as_ssize_t, PY_SSIZE_T_MAX + 1)
334-
self.assertRaises(TypeError, as_ssize_t, 1.0)
335-
self.assertRaises(TypeError, as_ssize_t, b'2')
336-
self.assertRaises(TypeError, as_ssize_t, '3')
337-
self.assertRaises(SystemError, as_ssize_t, NULL)
268+
self.check_long_asint(as_ssize_t, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX,
269+
use_index=False)
338270

339271
def test_long_as_size_t(self):
340272
# Test PyLong_AsSize_t() and PyLong_FromSize_t()
341273
as_size_t = _testcapi.pylong_as_size_t
342274
from _testcapi import SIZE_MAX
343-
# round trip (object -> size_t -> object)
344-
for value in (SIZE_MAX, 0, 1, 1234):
345-
with self.subTest(value=value):
346-
self.assertEqual(as_size_t(value), value)
347-
348-
self.assertEqual(as_size_t(IntSubclass(42)), 42)
349-
self.assertRaises(TypeError, as_size_t, Index(42))
350-
self.assertRaises(TypeError, as_size_t, MyIndexAndInt())
351-
352-
self.assertRaises(OverflowError, as_size_t, -1)
353-
self.assertRaises(OverflowError, as_size_t, SIZE_MAX + 1)
354-
self.assertRaises(TypeError, as_size_t, 1.0)
355-
self.assertRaises(TypeError, as_size_t, b'2')
356-
self.assertRaises(TypeError, as_size_t, '3')
357-
self.assertRaises(SystemError, as_size_t, NULL)
275+
self.check_long_asint(as_size_t, 0, SIZE_MAX, use_index=False)
358276

359277
def test_long_asdouble(self):
360278
# Test PyLong_AsDouble()
@@ -407,21 +325,7 @@ def test_long_aspid(self):
407325
bits = 8 * SIZEOF_PID_T
408326
PID_T_MIN = -2**(bits-1)
409327
PID_T_MAX = 2**(bits-1) - 1
410-
# round trip (object -> long -> object)
411-
for value in (PID_T_MIN, PID_T_MAX, -1, 0, 1, 1234):
412-
with self.subTest(value=value):
413-
self.assertEqual(aspid(value), value)
414-
415-
self.assertEqual(aspid(IntSubclass(42)), 42)
416-
self.assertEqual(aspid(Index(42)), 42)
417-
self.assertEqual(aspid(MyIndexAndInt()), 10)
418-
419-
self.assertRaises(OverflowError, aspid, PID_T_MIN - 1)
420-
self.assertRaises(OverflowError, aspid, PID_T_MAX + 1)
421-
self.assertRaises(TypeError, aspid, 1.0)
422-
self.assertRaises(TypeError, aspid, b'2')
423-
self.assertRaises(TypeError, aspid, '3')
424-
self.assertRaises(SystemError, aspid, NULL)
328+
self.check_long_asint(aspid, PID_T_MIN, PID_T_MAX)
425329

426330

427331
if __name__ == "__main__":

0 commit comments

Comments
 (0)