Skip to content

[3.13] Refactor test_capi.test_long (GH-122113) #122137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
245 changes: 66 additions & 179 deletions Lib/test/test_capi/test_long.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,224 +162,125 @@ def test_long_fromunicodeobject(self):
# 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()
Expand Down Expand Up @@ -431,21 +332,7 @@ def _test_long_aspid(self, aspid):
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)
Expand Down
Loading