From 69c2de3ad69219d60c53827670856deee6f4241c Mon Sep 17 00:00:00 2001
From: Tim Peters <tim.peters@gmail.com>
Date: Tue, 11 Sep 2001 22:31:33 +0000
Subject: More bug 460020.  Disable a number of long optimizations for long
 subclasses.

---
 Lib/test/test_descr.py | 24 ++++++++++++++++++++++++
 Objects/longobject.c   | 33 +++++++++++++++------------------
 2 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index a50785f..11a3a5d 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -1389,6 +1389,30 @@ def inherits():
     a = octlong(12345)
     verify(long(a) == 12345L)
     verify(long(a).__class__ is long)
+    verify((+a).__class__ is long)
+    verify((-a).__class__ is long)
+    verify((-octlong(0)).__class__ is long)
+    verify((a >> 0).__class__ is long)
+    verify((a << 0).__class__ is long)
+    verify((a - 0).__class__ is long)
+    verify((a * 1).__class__ is long)
+    verify((a ** 1).__class__ is long)
+    verify((a // 1).__class__ is long)
+    verify((1 * a).__class__ is long)
+    verify((a | 0).__class__ is long)
+    verify((a ^ 0).__class__ is long)
+    verify((a & -1L).__class__ is long)
+    verify((octlong(0) << 12).__class__ is long)
+    verify((octlong(0) >> 12).__class__ is long)
+    verify(abs(octlong(0)).__class__ is long)
+
+    # Because octlong overrides __add__, we can't check the absence of +0
+    # optimizations using octlong.
+    class longclone(long):
+        pass
+    a = longclone(1)
+    verify((a + 0).__class__ is long)
+    verify((0 + a).__class__ is long)
 
     class precfloat(float):
         __slots__ = ['prec']
diff --git a/Objects/longobject.c b/Objects/longobject.c
index b9271e6..7a70903 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -1297,7 +1297,7 @@ x_add(PyLongObject *a, PyLongObject *b)
 	PyLongObject *z;
 	int i;
 	digit carry = 0;
-	
+
 	/* Ensure a is the larger of the two: */
 	if (size_a < size_b) {
 		{ PyLongObject *temp = a; a = b; b = temp; }
@@ -1332,7 +1332,7 @@ x_sub(PyLongObject *a, PyLongObject *b)
 	int i;
 	int sign = 1;
 	digit borrow = 0;
-	
+
 	/* Ensure a is the larger of the two: */
 	if (size_a < size_b) {
 		sign = -1;
@@ -1381,7 +1381,7 @@ static PyObject *
 long_add(PyLongObject *v, PyLongObject *w)
 {
 	PyLongObject *a, *b, *z;
-	
+
 	CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
 
 	if (a->ob_size < 0) {
@@ -1820,27 +1820,26 @@ long_invert(PyLongObject *v)
 static PyObject *
 long_pos(PyLongObject *v)
 {
-	Py_INCREF(v);
-	return (PyObject *)v;
+	if (PyLong_CheckExact(v)) {
+		Py_INCREF(v);
+		return (PyObject *)v;
+	}
+	else
+		return _PyLong_Copy(v);
 }
 
 static PyObject *
 long_neg(PyLongObject *v)
 {
 	PyLongObject *z;
-	int i, n;
-	n = ABS(v->ob_size);
-	if (n == 0) {
+	if (v->ob_size == 0 && PyLong_CheckExact(v)) {
 		/* -0 == 0 */
 		Py_INCREF(v);
 		return (PyObject *) v;
 	}
-	z = _PyLong_New(ABS(n));
-	if (z == NULL)
-		return NULL;
-	for (i = 0; i < n; i++)
-		z->ob_digit[i] = v->ob_digit[i];
-	z->ob_size = -(v->ob_size);
+	z = (PyLongObject *)_PyLong_Copy(v);
+	if (z != NULL)
+		z->ob_size = -(v->ob_size);
 	return (PyObject *)z;
 }
 
@@ -1849,10 +1848,8 @@ long_abs(PyLongObject *v)
 {
 	if (v->ob_size < 0)
 		return long_neg(v);
-	else {
-		Py_INCREF(v);
-		return (PyObject *)v;
-	}
+	else
+		return long_pos(v);
 }
 
 static int
-- 
cgit v0.12

