diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index a50785f58a2..11a3a5da7f4 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 b9271e66170..7a709033fb1 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