From 43308dfc3335906cfefe9f14a44e468935f3c321 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 15 Oct 2018 08:46:16 +0300 Subject: [PATCH] [2.7] bpo-34974: Do not replace unexpected errors in bytearray(). (GH-9852) (GH-9885) The bytearray constructor converted unexpected exceptions (e.g. MemoryError and KeyboardInterrupt) to TypeError. (cherry picked from commit e890421e334ccf0c000c6b29c4a521d86cd12f47) --- Lib/test/test_bytes.py | 18 ++++++++++++++++-- .../2018-10-13-22-24-19.bpo-34974.7LgTc2.rst | 3 +++ Objects/bytearrayobject.c | 8 +++++--- 3 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-10-13-22-24-19.bpo-34974.7LgTc2.rst diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 9b5f713b0b8..c04f7b305a0 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -116,8 +116,8 @@ class BaseBytesTest(unittest.TestCase): a = self.type2test(b"\x01\x02\x03") self.assertEqual(a, b"\x01\x02\x03") - # http://bugs.python.org/issue29159 - # Fallback when __index__ raises exception other than OverflowError + # Issues #29159 and #34974. + # Fallback when __index__ raises a TypeError class B(bytes): def __index__(self): raise TypeError @@ -156,6 +156,20 @@ class BaseBytesTest(unittest.TestCase): self.assertRaises(ValueError, self.type2test, [sys.maxint+1]) self.assertRaises(ValueError, self.type2test, [10**100]) + def test_constructor_exceptions(self): + # Issue #34974: bytes and bytearray constructors replace unexpected + # exceptions. + class BadInt: + def __index__(self): + 1/0 + self.assertRaises(ZeroDivisionError, self.type2test, BadInt()) + self.assertRaises(ZeroDivisionError, self.type2test, [BadInt()]) + + class BadIterable: + def __iter__(self): + 1/0 + self.assertRaises(ZeroDivisionError, self.type2test, BadIterable()) + def test_compare(self): b1 = self.type2test([1, 2, 3]) b2 = self.type2test([1, 2, 3]) diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-10-13-22-24-19.bpo-34974.7LgTc2.rst b/Misc/NEWS.d/next/Core and Builtins/2018-10-13-22-24-19.bpo-34974.7LgTc2.rst new file mode 100644 index 00000000000..34e6273db94 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-10-13-22-24-19.bpo-34974.7LgTc2.rst @@ -0,0 +1,3 @@ +The :class:`bytearray` constructor no longer convert +unexpected exceptions (e.g. :exc:`MemoryError` and :exc:`KeyboardInterrupt`) +to :exc:`TypeError`. diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index c178d9ef65d..a96d6d981dd 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -41,8 +41,10 @@ _getbytevalue(PyObject* arg, int *value) else { PyObject *index = PyNumber_Index(arg); if (index == NULL) { - PyErr_Format(PyExc_TypeError, - "an integer or string of size 1 is required"); + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Format(PyExc_TypeError, + "an integer or string of size 1 is required"); + } return 0; } face_value = PyLong_AsLong(index); @@ -852,7 +854,7 @@ bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) /* Is it an int? */ count = PyNumber_AsSsize_t(arg, PyExc_OverflowError); if (count == -1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) + if (!PyErr_ExceptionMatches(PyExc_TypeError)) return -1; PyErr_Clear(); }