bpo-46361: Fix "small" `int` caching (GH-30583)

This commit is contained in:
Brandt Bucher 2022-01-16 08:06:37 -08:00 committed by GitHub
parent 09087b8519
commit 5cd9a162cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 24 additions and 1 deletions

View File

@ -2552,6 +2552,13 @@ class PythonAPItests(unittest.TestCase):
self.assertRaises(OverflowError, int, Decimal('inf')) self.assertRaises(OverflowError, int, Decimal('inf'))
self.assertRaises(OverflowError, int, Decimal('-inf')) self.assertRaises(OverflowError, int, Decimal('-inf'))
@cpython_only
def test_small_ints(self):
Decimal = self.decimal.Decimal
# bpo-46361
for x in range(-5, 257):
self.assertIs(int(Decimal(x)), x)
def test_trunc(self): def test_trunc(self):
Decimal = self.decimal.Decimal Decimal = self.decimal.Decimal

View File

@ -1471,6 +1471,13 @@ class LongTest(unittest.TestCase):
self.assertEqual(i, 1) self.assertEqual(i, 1)
self.assertEqual(getattr(i, 'foo', 'none'), 'bar') self.assertEqual(getattr(i, 'foo', 'none'), 'bar')
@support.cpython_only
def test_from_bytes_small(self):
# bpo-46361
for i in range(-5, 257):
b = i.to_bytes(2, signed=True)
self.assertIs(int.from_bytes(b, signed=True), i)
def test_access_to_nonexistent_digit_0(self): def test_access_to_nonexistent_digit_0(self):
# http://bugs.python.org/issue14630: A bug in _PyLong_Copy meant that # http://bugs.python.org/issue14630: A bug in _PyLong_Copy meant that
# ob_digit[0] was being incorrectly accessed for instances of a # ob_digit[0] was being incorrectly accessed for instances of a

View File

@ -0,0 +1,2 @@
Ensure that "small" integers created by :meth:`int.from_bytes` and
:class:`decimal.Decimal` are properly cached.

View File

@ -3394,6 +3394,13 @@ dec_as_long(PyObject *dec, PyObject *context, int round)
return NULL; return NULL;
} }
if (n == 1) {
sdigit val = mpd_arith_sign(x) * ob_digit[0];
mpd_free(ob_digit);
mpd_del(x);
return PyLong_FromLong(val);
}
assert(n > 0); assert(n > 0);
pylong = _PyLong_New(n); pylong = _PyLong_New(n);
if (pylong == NULL) { if (pylong == NULL) {

View File

@ -911,7 +911,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n,
} }
Py_SET_SIZE(v, is_signed ? -idigit : idigit); Py_SET_SIZE(v, is_signed ? -idigit : idigit);
return (PyObject *)long_normalize(v); return (PyObject *)maybe_small_long(long_normalize(v));
} }
int int