Index: Objects/longobject.c =================================================================== --- Objects/longobject.c (revision 62951) +++ Objects/longobject.c (working copy) @@ -2980,7 +2980,7 @@ { PyLongObject *a, *b; PyLongObject *z = NULL; - long shiftby; + Py_ssize_t shiftby; Py_ssize_t newsize, wordshift, loshift, hishift, i, j; digit lomask, himask; @@ -2991,31 +2991,36 @@ PyLongObject *a1, *a2; a1 = (PyLongObject *) long_invert(a); if (a1 == NULL) - goto rshift_error; + goto rshift_done; a2 = (PyLongObject *) long_rshift(a1, b); Py_DECREF(a1); if (a2 == NULL) - goto rshift_error; + goto rshift_done; z = (PyLongObject *) long_invert(a2); Py_DECREF(a2); } else { - - shiftby = PyLong_AsLong((PyObject *)b); - if (shiftby == -1L && PyErr_Occurred()) - goto rshift_error; - if (shiftby < 0) { + if (Py_SIZE(b) < 0) { PyErr_SetString(PyExc_ValueError, "negative shift count"); - goto rshift_error; + goto rshift_done; } + shiftby = PyLong_AsSsize_t((PyObject *)b); + if (shiftby == -1L && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + /* Since number of digits is limited by what can + * fit in Py_ssize_t, an overflow here means that + * the result is zero */ + PyErr_Clear(); + z = _PyLong_New(0); + } + goto rshift_done; + } wordshift = shiftby / PyLong_SHIFT; newsize = ABS(Py_SIZE(a)) - wordshift; if (newsize <= 0) { z = _PyLong_New(0); - Py_DECREF(a); - Py_DECREF(b); - return (PyObject *)z; + goto rshift_done; } loshift = shiftby % PyLong_SHIFT; hishift = PyLong_SHIFT - loshift; @@ -3023,7 +3028,7 @@ himask = PyLong_MASK ^ lomask; z = _PyLong_New(newsize); if (z == NULL) - goto rshift_error; + goto rshift_done; if (Py_SIZE(a) < 0) Py_SIZE(z) = -(Py_SIZE(z)); for (i = 0, j = wordshift; i < newsize; i++, j++) { @@ -3034,7 +3039,7 @@ } z = long_normalize(z); } -rshift_error: +rshift_done: Py_DECREF(a); Py_DECREF(b); return (PyObject *) z; Index: Lib/test/test_long.py =================================================================== --- Lib/test/test_long.py (revision 62951) +++ Lib/test/test_long.py (working copy) @@ -18,6 +18,7 @@ BASE = 2 ** SHIFT MASK = BASE - 1 KARATSUBA_CUTOFF = 70 # from longobject.c +HUGE = 1<<100 # Max number of base BASE digits to use in test cases. Doubling # this will more than double the runtime. @@ -193,6 +194,7 @@ Frm("not x & -p2 == x >> n << n for x=%r n=%r p2=%r", (x, n, p2))) eq(x & -p2, x & ~(p2 - 1), Frm("not x & -p2 == x & ~(p2 - 1) for x=%r n=%r p2=%r", (x, n, p2))) + eq(x >> HUGE, -(x<0), Frm("x >> HUGE == 0")) def check_bitop_identities_2(self, x, y): eq = self.assertEqual