diff -r fa9933bf4ea0 Lib/test/test_bytes.py --- a/Lib/test/test_bytes.py Tue Dec 27 17:59:04 2016 +0200 +++ b/Lib/test/test_bytes.py Thu Jan 05 09:38:27 2017 +0900 @@ -1,12 +1,13 @@ """Unit tests for the bytes and bytearray types. 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 import copy import functools import pickle @@ -78,12 +79,24 @@ b = self.type2test([Indexable(), Indexable(1), Indexable(254), Indexable(255)]) self.assertEqual(list(b), [0, 1, 254, 255]) 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(b"\x01\x02\x03", a) + + # http://bugs.python.org/issue29159 + # Fallback when __index__ raises exception other than OverflowError + class B(bytes): + def __index__(self): + raise TypeError + + self.assertEqual(b"foobar", self.type2test(B(b"foobar"))) + def test_from_ssize(self): self.assertEqual(self.type2test(0), b'') self.assertEqual(self.type2test(1), b'\x00') self.assertEqual(self.type2test(5), b'\x00\x00\x00\x00\x00') self.assertRaises(ValueError, self.type2test, -1) diff -r fa9933bf4ea0 Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Tue Dec 27 17:59:04 2016 +0200 +++ b/Objects/bytearrayobject.c Thu Jan 05 09:38:27 2017 +0900 @@ -795,24 +795,28 @@ } /* Is it an int? */ 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 (PyErr_ExceptionMatches(PyExc_OverflowError)) + return -1; + PyErr_Clear(); /* fall through */ } - if (count > 0) { - if (PyByteArray_Resize((PyObject *)self, count)) + else { + if (count < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); return -1; - memset(PyByteArray_AS_STRING(self), 0, count); + } + 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 */ if (PyObject_CheckBuffer(arg)) { Py_ssize_t size; Py_buffer view; diff -r fa9933bf4ea0 Objects/bytesobject.c --- a/Objects/bytesobject.c Tue Dec 27 17:59:04 2016 +0200 +++ b/Objects/bytesobject.c Thu Jan 05 09:38:27 2017 +0900 @@ -2590,22 +2590,26 @@ return NULL; } /* Is it an integer? */ 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); } static PyObject*