]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-27145: small_ints[x] could be returned in long_add and long_sub (GH-15716)
authorHongWeipeng <961365124@qq.com>
Tue, 26 Nov 2019 07:54:49 +0000 (15:54 +0800)
committerInada Naoki <songofacandy@gmail.com>
Tue, 26 Nov 2019 07:54:49 +0000 (16:54 +0900)
Lib/test/test_long.py
Misc/NEWS.d/next/Core and Builtins/2019-09-06-16-40-12.bpo-27145.njuCXU.rst [new file with mode: 0644]
Objects/longobject.c

index 53101b3badb36d682db79d90bf7aaa1eec2951ce..7ce37e8dbd6c7ee4feb2fdf4bf776ae7fa9cf28f 100644 (file)
@@ -956,6 +956,14 @@ class LongTest(unittest.TestCase):
         self.assertEqual(huge >> (sys.maxsize + 1), (1 << 499) + 5)
         self.assertEqual(huge >> (sys.maxsize + 1000), 0)
 
+    @support.cpython_only
+    def test_small_ints_in_huge_calculation(self):
+        a = 2 ** 100
+        b = -a + 1
+        c = a + 1
+        self.assertIs(a + b, 1)
+        self.assertIs(c - a, 1)
+
     def test_small_ints(self):
         for i in range(-5, 257):
             self.assertIs(i, i + 0)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-06-16-40-12.bpo-27145.njuCXU.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-06-16-40-12.bpo-27145.njuCXU.rst
new file mode 100644 (file)
index 0000000..229753a
--- /dev/null
@@ -0,0 +1 @@
+int + int and int - int operators can now return small integer singletons. Patch by hongweipeng.
index 294308e3e126ddb9b79dc670cd2883c0cc752fbf..f0567970468a82815b734426a9f39165c2c3439e 100644 (file)
@@ -3206,7 +3206,7 @@ x_sub(PyLongObject *a, PyLongObject *b)
     if (sign < 0) {
         Py_SIZE(z) = -Py_SIZE(z);
     }
-    return long_normalize(z);
+    return maybe_small_long(long_normalize(z));
 }
 
 static PyObject *
@@ -3254,13 +3254,15 @@ long_sub(PyLongObject *a, PyLongObject *b)
         return PyLong_FromLong(MEDIUM_VALUE(a) - MEDIUM_VALUE(b));
     }
     if (Py_SIZE(a) < 0) {
-        if (Py_SIZE(b) < 0)
-            z = x_sub(a, b);
-        else
+        if (Py_SIZE(b) < 0) {
+            z = x_sub(b, a);
+        }
+        else {
             z = x_add(a, b);
-        if (z != NULL) {
-            assert(Py_SIZE(z) == 0 || Py_REFCNT(z) == 1);
-            Py_SIZE(z) = -(Py_SIZE(z));
+            if (z != NULL) {
+                assert(Py_SIZE(z) == 0 || Py_REFCNT(z) == 1);
+                Py_SIZE(z) = -(Py_SIZE(z));
+            }
         }
     }
     else {