From a634e23209e90fd516fae1b4a303d57fdb1b9917 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Fri, 6 Jan 2017 17:32:01 +0900 Subject: [PATCH] Issue #29159: Fix regression in bytes(x) when x.__index__() raises Exception. --- Lib/test/test_bytes.py | 13 +++++++++++++ Misc/NEWS | 2 ++ Objects/bytearrayobject.c | 24 ++++++++++++++---------- Objects/bytesobject.c | 20 ++++++++++++-------- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index b396a76a40d..a103a7d39ca 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -4,6 +4,7 @@ XXX This is a mess. Common tests should be unified with string_tests.py (and the latter should be modernized). """ +import array import os import re import sys @@ -81,6 +82,18 @@ class BaseBytesTest: self.assertRaises(ValueError, self.type2test, [Indexable(-1)]) self.assertRaises(ValueError, self.type2test, [Indexable(256)]) + def test_from_buffer(self): + a = self.type2test(array.array('B', [1, 2, 3])) + self.assertEqual(a, b"\x01\x02\x03") + + # http://bugs.python.org/issue29159 + # Fallback when __index__ raises exception other than OverflowError + class B(bytes): + def __index__(self): + raise TypeError + + self.assertEqual(self.type2test(B(b"foobar")), b"foobar") + def test_from_ssize(self): self.assertEqual(self.type2test(0), b'') self.assertEqual(self.type2test(1), b'\x00') diff --git a/Misc/NEWS b/Misc/NEWS index 0a32e264b6c..113ca8abbe8 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,8 @@ What's New in Python 3.6.1 release candidate 1? Core and Builtins ----------------- +- Issue #29159: Fix regression in bytes(x) when x.__index__() raises Exception. + - Issue #28932: Do not include if it does not exist. - Issue #25677: Correct the positioning of the syntax error caret for diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index c6d0707167c..a8d69802508 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -798,18 +798,22 @@ bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) if (PyIndex_Check(arg)) { count = PyNumber_AsSsize_t(arg, PyExc_OverflowError); if (count == -1 && PyErr_Occurred()) { - return -1; - } - if (count < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); - return -1; - } - if (count > 0) { - if (PyByteArray_Resize((PyObject *)self, count)) + if (PyErr_ExceptionMatches(PyExc_OverflowError)) return -1; - memset(PyByteArray_AS_STRING(self), 0, count); + PyErr_Clear(); /* fall through */ + } + else { + if (count < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return -1; + } + if (count > 0) { + if (PyByteArray_Resize((PyObject *)self, count)) + return -1; + memset(PyByteArray_AS_STRING(self), 0, count); + } + return 0; } - return 0; } /* Use the buffer API */ diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index b22e57effe6..5d484409600 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2593,16 +2593,20 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (PyIndex_Check(x)) { size = PyNumber_AsSsize_t(x, PyExc_OverflowError); if (size == -1 && PyErr_Occurred()) { - return NULL; + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); /* fall through */ } - if (size < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); - return NULL; + else { + if (size < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return NULL; + } + new = _PyBytes_FromSize(size, 1); + if (new == NULL) + return NULL; + return new; } - new = _PyBytes_FromSize(size, 1); - if (new == NULL) - return NULL; - return new; } return PyBytes_FromObject(x);