mirror of https://github.com/python/cpython
[3.13] Refactor test_capi.test_long (GH-122113) (GH-122137)
Share common code for tests for PyLong_As*() functions.
(cherry picked from commit 69f2dc5c06
)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
e175bd3aaf
commit
4892cc072a
|
@ -162,224 +162,125 @@ class LongTests(unittest.TestCase):
|
|||
# CRASHES fromunicodeobject(NULL, 0)
|
||||
# CRASHES fromunicodeobject(NULL, 16)
|
||||
|
||||
def check_long_asint(self, func, min_val, max_val, *,
|
||||
use_index=True,
|
||||
mask=False,
|
||||
negative_value_error=OverflowError):
|
||||
# round trip (object -> C integer -> object)
|
||||
values = (0, 1, 1234, max_val)
|
||||
if min_val < 0:
|
||||
values += (-1, min_val)
|
||||
for value in values:
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(func(value), value)
|
||||
self.assertEqual(func(IntSubclass(value)), value)
|
||||
if use_index:
|
||||
self.assertEqual(func(Index(value)), value)
|
||||
|
||||
if use_index:
|
||||
self.assertEqual(func(MyIndexAndInt()), 10)
|
||||
else:
|
||||
self.assertRaises(TypeError, func, Index(42))
|
||||
self.assertRaises(TypeError, func, MyIndexAndInt())
|
||||
|
||||
if mask:
|
||||
self.assertEqual(func(min_val - 1), max_val)
|
||||
self.assertEqual(func(max_val + 1), min_val)
|
||||
self.assertEqual(func(-1 << 1000), 0)
|
||||
self.assertEqual(func(1 << 1000), 0)
|
||||
else:
|
||||
self.assertRaises(negative_value_error, func, min_val - 1)
|
||||
self.assertRaises(negative_value_error, func, -1 << 1000)
|
||||
self.assertRaises(OverflowError, func, max_val + 1)
|
||||
self.assertRaises(OverflowError, func, 1 << 1000)
|
||||
self.assertRaises(TypeError, func, 1.0)
|
||||
self.assertRaises(TypeError, func, b'2')
|
||||
self.assertRaises(TypeError, func, '3')
|
||||
self.assertRaises(SystemError, func, NULL)
|
||||
|
||||
def check_long_asintandoverflow(self, func, min_val, max_val):
|
||||
# round trip (object -> C integer -> object)
|
||||
for value in (min_val, max_val, -1, 0, 1, 1234):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(func(value), (value, 0))
|
||||
self.assertEqual(func(IntSubclass(value)), (value, 0))
|
||||
self.assertEqual(func(Index(value)), (value, 0))
|
||||
|
||||
self.assertEqual(func(MyIndexAndInt()), (10, 0))
|
||||
|
||||
self.assertEqual(func(min_val - 1), (-1, -1))
|
||||
self.assertEqual(func(max_val + 1), (-1, +1))
|
||||
|
||||
# CRASHES func(1.0)
|
||||
# CRASHES func(NULL)
|
||||
|
||||
def test_long_asint(self):
|
||||
# Test PyLong_AsInt()
|
||||
PyLong_AsInt = _testlimitedcapi.PyLong_AsInt
|
||||
from _testcapi import INT_MIN, INT_MAX
|
||||
|
||||
# round trip (object -> int -> object)
|
||||
for value in (INT_MIN, INT_MAX, -1, 0, 1, 123):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(PyLong_AsInt(value), value)
|
||||
self.assertEqual(PyLong_AsInt(IntSubclass(42)), 42)
|
||||
self.assertEqual(PyLong_AsInt(Index(42)), 42)
|
||||
self.assertEqual(PyLong_AsInt(MyIndexAndInt()), 10)
|
||||
|
||||
# bound checking
|
||||
self.assertRaises(OverflowError, PyLong_AsInt, INT_MIN - 1)
|
||||
self.assertRaises(OverflowError, PyLong_AsInt, INT_MAX + 1)
|
||||
|
||||
# invalid type
|
||||
self.assertRaises(TypeError, PyLong_AsInt, 1.0)
|
||||
self.assertRaises(TypeError, PyLong_AsInt, b'2')
|
||||
self.assertRaises(TypeError, PyLong_AsInt, '3')
|
||||
self.assertRaises(SystemError, PyLong_AsInt, NULL)
|
||||
self.check_long_asint(PyLong_AsInt, INT_MIN, INT_MAX)
|
||||
|
||||
def test_long_aslong(self):
|
||||
# Test PyLong_AsLong() and PyLong_FromLong()
|
||||
aslong = _testlimitedcapi.pylong_aslong
|
||||
from _testcapi import LONG_MIN, LONG_MAX
|
||||
# round trip (object -> long -> object)
|
||||
for value in (LONG_MIN, LONG_MAX, -1, 0, 1, 1234):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(aslong(value), value)
|
||||
|
||||
self.assertEqual(aslong(IntSubclass(42)), 42)
|
||||
self.assertEqual(aslong(Index(42)), 42)
|
||||
self.assertEqual(aslong(MyIndexAndInt()), 10)
|
||||
|
||||
self.assertRaises(OverflowError, aslong, LONG_MIN - 1)
|
||||
self.assertRaises(OverflowError, aslong, LONG_MAX + 1)
|
||||
self.assertRaises(TypeError, aslong, 1.0)
|
||||
self.assertRaises(TypeError, aslong, b'2')
|
||||
self.assertRaises(TypeError, aslong, '3')
|
||||
self.assertRaises(SystemError, aslong, NULL)
|
||||
self.check_long_asint(aslong, LONG_MIN, LONG_MAX)
|
||||
|
||||
def test_long_aslongandoverflow(self):
|
||||
# Test PyLong_AsLongAndOverflow()
|
||||
aslongandoverflow = _testlimitedcapi.pylong_aslongandoverflow
|
||||
from _testcapi import LONG_MIN, LONG_MAX
|
||||
# round trip (object -> long -> object)
|
||||
for value in (LONG_MIN, LONG_MAX, -1, 0, 1, 1234):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(aslongandoverflow(value), (value, 0))
|
||||
|
||||
self.assertEqual(aslongandoverflow(IntSubclass(42)), (42, 0))
|
||||
self.assertEqual(aslongandoverflow(Index(42)), (42, 0))
|
||||
self.assertEqual(aslongandoverflow(MyIndexAndInt()), (10, 0))
|
||||
|
||||
self.assertEqual(aslongandoverflow(LONG_MIN - 1), (-1, -1))
|
||||
self.assertEqual(aslongandoverflow(LONG_MAX + 1), (-1, 1))
|
||||
# CRASHES aslongandoverflow(1.0)
|
||||
# CRASHES aslongandoverflow(NULL)
|
||||
self.check_long_asintandoverflow(aslongandoverflow, LONG_MIN, LONG_MAX)
|
||||
|
||||
def test_long_asunsignedlong(self):
|
||||
# Test PyLong_AsUnsignedLong() and PyLong_FromUnsignedLong()
|
||||
asunsignedlong = _testlimitedcapi.pylong_asunsignedlong
|
||||
from _testcapi import ULONG_MAX
|
||||
# round trip (object -> unsigned long -> object)
|
||||
for value in (ULONG_MAX, 0, 1, 1234):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(asunsignedlong(value), value)
|
||||
|
||||
self.assertEqual(asunsignedlong(IntSubclass(42)), 42)
|
||||
self.assertRaises(TypeError, asunsignedlong, Index(42))
|
||||
self.assertRaises(TypeError, asunsignedlong, MyIndexAndInt())
|
||||
|
||||
self.assertRaises(OverflowError, asunsignedlong, -1)
|
||||
self.assertRaises(OverflowError, asunsignedlong, ULONG_MAX + 1)
|
||||
self.assertRaises(TypeError, asunsignedlong, 1.0)
|
||||
self.assertRaises(TypeError, asunsignedlong, b'2')
|
||||
self.assertRaises(TypeError, asunsignedlong, '3')
|
||||
self.assertRaises(SystemError, asunsignedlong, NULL)
|
||||
self.check_long_asint(asunsignedlong, 0, ULONG_MAX,
|
||||
use_index=False)
|
||||
|
||||
def test_long_asunsignedlongmask(self):
|
||||
# Test PyLong_AsUnsignedLongMask()
|
||||
asunsignedlongmask = _testlimitedcapi.pylong_asunsignedlongmask
|
||||
from _testcapi import ULONG_MAX
|
||||
# round trip (object -> unsigned long -> object)
|
||||
for value in (ULONG_MAX, 0, 1, 1234):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(asunsignedlongmask(value), value)
|
||||
|
||||
self.assertEqual(asunsignedlongmask(IntSubclass(42)), 42)
|
||||
self.assertEqual(asunsignedlongmask(Index(42)), 42)
|
||||
self.assertEqual(asunsignedlongmask(MyIndexAndInt()), 10)
|
||||
|
||||
self.assertEqual(asunsignedlongmask(-1), ULONG_MAX)
|
||||
self.assertEqual(asunsignedlongmask(ULONG_MAX + 1), 0)
|
||||
self.assertRaises(TypeError, asunsignedlongmask, 1.0)
|
||||
self.assertRaises(TypeError, asunsignedlongmask, b'2')
|
||||
self.assertRaises(TypeError, asunsignedlongmask, '3')
|
||||
self.assertRaises(SystemError, asunsignedlongmask, NULL)
|
||||
self.check_long_asint(asunsignedlongmask, 0, ULONG_MAX, mask=True)
|
||||
|
||||
def test_long_aslonglong(self):
|
||||
# Test PyLong_AsLongLong() and PyLong_FromLongLong()
|
||||
aslonglong = _testlimitedcapi.pylong_aslonglong
|
||||
from _testcapi import LLONG_MIN, LLONG_MAX
|
||||
# round trip (object -> long long -> object)
|
||||
for value in (LLONG_MIN, LLONG_MAX, -1, 0, 1, 1234):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(aslonglong(value), value)
|
||||
|
||||
self.assertEqual(aslonglong(IntSubclass(42)), 42)
|
||||
self.assertEqual(aslonglong(Index(42)), 42)
|
||||
self.assertEqual(aslonglong(MyIndexAndInt()), 10)
|
||||
|
||||
self.assertRaises(OverflowError, aslonglong, LLONG_MIN - 1)
|
||||
self.assertRaises(OverflowError, aslonglong, LLONG_MAX + 1)
|
||||
self.assertRaises(TypeError, aslonglong, 1.0)
|
||||
self.assertRaises(TypeError, aslonglong, b'2')
|
||||
self.assertRaises(TypeError, aslonglong, '3')
|
||||
self.assertRaises(SystemError, aslonglong, NULL)
|
||||
self.check_long_asint(aslonglong, LLONG_MIN, LLONG_MAX)
|
||||
|
||||
def test_long_aslonglongandoverflow(self):
|
||||
# Test PyLong_AsLongLongAndOverflow()
|
||||
aslonglongandoverflow = _testlimitedcapi.pylong_aslonglongandoverflow
|
||||
from _testcapi import LLONG_MIN, LLONG_MAX
|
||||
# round trip (object -> long long -> object)
|
||||
for value in (LLONG_MIN, LLONG_MAX, -1, 0, 1, 1234):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(aslonglongandoverflow(value), (value, 0))
|
||||
|
||||
self.assertEqual(aslonglongandoverflow(IntSubclass(42)), (42, 0))
|
||||
self.assertEqual(aslonglongandoverflow(Index(42)), (42, 0))
|
||||
self.assertEqual(aslonglongandoverflow(MyIndexAndInt()), (10, 0))
|
||||
|
||||
self.assertEqual(aslonglongandoverflow(LLONG_MIN - 1), (-1, -1))
|
||||
self.assertEqual(aslonglongandoverflow(LLONG_MAX + 1), (-1, 1))
|
||||
# CRASHES aslonglongandoverflow(1.0)
|
||||
# CRASHES aslonglongandoverflow(NULL)
|
||||
self.check_long_asintandoverflow(aslonglongandoverflow, LLONG_MIN, LLONG_MAX)
|
||||
|
||||
def test_long_asunsignedlonglong(self):
|
||||
# Test PyLong_AsUnsignedLongLong() and PyLong_FromUnsignedLongLong()
|
||||
asunsignedlonglong = _testlimitedcapi.pylong_asunsignedlonglong
|
||||
from _testcapi import ULLONG_MAX
|
||||
# round trip (object -> unsigned long long -> object)
|
||||
for value in (ULLONG_MAX, 0, 1, 1234):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(asunsignedlonglong(value), value)
|
||||
|
||||
self.assertEqual(asunsignedlonglong(IntSubclass(42)), 42)
|
||||
self.assertRaises(TypeError, asunsignedlonglong, Index(42))
|
||||
self.assertRaises(TypeError, asunsignedlonglong, MyIndexAndInt())
|
||||
|
||||
self.assertRaises(OverflowError, asunsignedlonglong, -1)
|
||||
self.assertRaises(OverflowError, asunsignedlonglong, ULLONG_MAX + 1)
|
||||
self.assertRaises(TypeError, asunsignedlonglong, 1.0)
|
||||
self.assertRaises(TypeError, asunsignedlonglong, b'2')
|
||||
self.assertRaises(TypeError, asunsignedlonglong, '3')
|
||||
self.assertRaises(SystemError, asunsignedlonglong, NULL)
|
||||
self.check_long_asint(asunsignedlonglong, 0, ULLONG_MAX, use_index=False)
|
||||
|
||||
def test_long_asunsignedlonglongmask(self):
|
||||
# Test PyLong_AsUnsignedLongLongMask()
|
||||
asunsignedlonglongmask = _testlimitedcapi.pylong_asunsignedlonglongmask
|
||||
from _testcapi import ULLONG_MAX
|
||||
# round trip (object -> unsigned long long -> object)
|
||||
for value in (ULLONG_MAX, 0, 1, 1234):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(asunsignedlonglongmask(value), value)
|
||||
|
||||
self.assertEqual(asunsignedlonglongmask(IntSubclass(42)), 42)
|
||||
self.assertEqual(asunsignedlonglongmask(Index(42)), 42)
|
||||
self.assertEqual(asunsignedlonglongmask(MyIndexAndInt()), 10)
|
||||
|
||||
self.assertEqual(asunsignedlonglongmask(-1), ULLONG_MAX)
|
||||
self.assertEqual(asunsignedlonglongmask(ULLONG_MAX + 1), 0)
|
||||
self.assertRaises(TypeError, asunsignedlonglongmask, 1.0)
|
||||
self.assertRaises(TypeError, asunsignedlonglongmask, b'2')
|
||||
self.assertRaises(TypeError, asunsignedlonglongmask, '3')
|
||||
self.assertRaises(SystemError, asunsignedlonglongmask, NULL)
|
||||
self.check_long_asint(asunsignedlonglongmask, 0, ULLONG_MAX, mask=True)
|
||||
|
||||
def test_long_as_ssize_t(self):
|
||||
# Test PyLong_AsSsize_t() and PyLong_FromSsize_t()
|
||||
as_ssize_t = _testlimitedcapi.pylong_as_ssize_t
|
||||
from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
|
||||
# round trip (object -> Py_ssize_t -> object)
|
||||
for value in (PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, -1, 0, 1, 1234):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(as_ssize_t(value), value)
|
||||
|
||||
self.assertEqual(as_ssize_t(IntSubclass(42)), 42)
|
||||
self.assertRaises(TypeError, as_ssize_t, Index(42))
|
||||
self.assertRaises(TypeError, as_ssize_t, MyIndexAndInt())
|
||||
|
||||
self.assertRaises(OverflowError, as_ssize_t, PY_SSIZE_T_MIN - 1)
|
||||
self.assertRaises(OverflowError, as_ssize_t, PY_SSIZE_T_MAX + 1)
|
||||
self.assertRaises(TypeError, as_ssize_t, 1.0)
|
||||
self.assertRaises(TypeError, as_ssize_t, b'2')
|
||||
self.assertRaises(TypeError, as_ssize_t, '3')
|
||||
self.assertRaises(SystemError, as_ssize_t, NULL)
|
||||
self.check_long_asint(as_ssize_t, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX,
|
||||
use_index=False)
|
||||
|
||||
def test_long_as_size_t(self):
|
||||
# Test PyLong_AsSize_t() and PyLong_FromSize_t()
|
||||
as_size_t = _testlimitedcapi.pylong_as_size_t
|
||||
from _testcapi import SIZE_MAX
|
||||
# round trip (object -> size_t -> object)
|
||||
for value in (SIZE_MAX, 0, 1, 1234):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(as_size_t(value), value)
|
||||
|
||||
self.assertEqual(as_size_t(IntSubclass(42)), 42)
|
||||
self.assertRaises(TypeError, as_size_t, Index(42))
|
||||
self.assertRaises(TypeError, as_size_t, MyIndexAndInt())
|
||||
|
||||
self.assertRaises(OverflowError, as_size_t, -1)
|
||||
self.assertRaises(OverflowError, as_size_t, SIZE_MAX + 1)
|
||||
self.assertRaises(TypeError, as_size_t, 1.0)
|
||||
self.assertRaises(TypeError, as_size_t, b'2')
|
||||
self.assertRaises(TypeError, as_size_t, '3')
|
||||
self.assertRaises(SystemError, as_size_t, NULL)
|
||||
self.check_long_asint(as_size_t, 0, SIZE_MAX, use_index=False)
|
||||
|
||||
def test_long_asdouble(self):
|
||||
# Test PyLong_AsDouble()
|
||||
|
@ -431,21 +332,7 @@ class LongTests(unittest.TestCase):
|
|||
bits = 8 * SIZEOF_PID_T
|
||||
PID_T_MIN = -2**(bits-1)
|
||||
PID_T_MAX = 2**(bits-1) - 1
|
||||
# round trip (object -> long -> object)
|
||||
for value in (PID_T_MIN, PID_T_MAX, -1, 0, 1, 1234):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(aspid(value), value)
|
||||
|
||||
self.assertEqual(aspid(IntSubclass(42)), 42)
|
||||
self.assertEqual(aspid(Index(42)), 42)
|
||||
self.assertEqual(aspid(MyIndexAndInt()), 10)
|
||||
|
||||
self.assertRaises(OverflowError, aspid, PID_T_MIN - 1)
|
||||
self.assertRaises(OverflowError, aspid, PID_T_MAX + 1)
|
||||
self.assertRaises(TypeError, aspid, 1.0)
|
||||
self.assertRaises(TypeError, aspid, b'2')
|
||||
self.assertRaises(TypeError, aspid, '3')
|
||||
self.assertRaises(SystemError, aspid, NULL)
|
||||
self.check_long_asint(aspid, PID_T_MIN, PID_T_MAX)
|
||||
|
||||
def test_long_aspid(self):
|
||||
self._test_long_aspid(_testcapi.pylong_aspid)
|
||||
|
|
Loading…
Reference in New Issue