Skip to content

Commit 3d89e43

Browse files
committed
Issue #29159: Fix regression in bytes(x) when x.__index__() raises Exception.
1 parent 2638733 commit 3d89e43

4 files changed

Lines changed: 40 additions & 17 deletions

File tree

Lib/test/test_bytes.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
the latter should be modernized).
55
"""
66

7+
import array
78
import os
89
import re
910
import sys
@@ -81,6 +82,18 @@ def test_from_index(self):
8182
self.assertRaises(ValueError, self.type2test, [Indexable(-1)])
8283
self.assertRaises(ValueError, self.type2test, [Indexable(256)])
8384

85+
def test_from_buffer(self):
86+
a = self.type2test(array.array('B', [1, 2, 3]))
87+
self.assertEqual(a, b"\x01\x02\x03")
88+
89+
# http://bugs.python.org/issue29159
90+
# Fallback when __index__ raises exception other than OverflowError
91+
class B(bytes):
92+
def __index__(self):
93+
raise TypeError
94+
95+
self.assertEqual(self.type2test(B(b"foobar")), b"foobar")
96+
8497
def test_from_ssize(self):
8598
self.assertEqual(self.type2test(0), b'')
8699
self.assertEqual(self.type2test(1), b'\x00')

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ What's New in Python 3.6.1 release candidate 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #29159: Fix regression in bytes(x) when x.__index__() raises Exception.
14+
1315
- Issue #28932: Do not include <sys/random.h> if it does not exist.
1416

1517
- Issue #25677: Correct the positioning of the syntax error caret for

Objects/bytearrayobject.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -798,18 +798,22 @@ bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
798798
if (PyIndex_Check(arg)) {
799799
count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
800800
if (count == -1 && PyErr_Occurred()) {
801-
return -1;
802-
}
803-
if (count < 0) {
804-
PyErr_SetString(PyExc_ValueError, "negative count");
805-
return -1;
801+
if (PyErr_ExceptionMatches(PyExc_OverflowError))
802+
return -1;
803+
PyErr_Clear(); /* fall through */
806804
}
807-
if (count > 0) {
808-
if (PyByteArray_Resize((PyObject *)self, count))
805+
else {
806+
if (count < 0) {
807+
PyErr_SetString(PyExc_ValueError, "negative count");
809808
return -1;
810-
memset(PyByteArray_AS_STRING(self), 0, count);
809+
}
810+
if (count > 0) {
811+
if (PyByteArray_Resize((PyObject *)self, count))
812+
return -1;
813+
memset(PyByteArray_AS_STRING(self), 0, count);
814+
}
815+
return 0;
811816
}
812-
return 0;
813817
}
814818

815819
/* Use the buffer API */

Objects/bytesobject.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,16 +2593,20 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
25932593
if (PyIndex_Check(x)) {
25942594
size = PyNumber_AsSsize_t(x, PyExc_OverflowError);
25952595
if (size == -1 && PyErr_Occurred()) {
2596-
return NULL;
2596+
if (PyErr_ExceptionMatches(PyExc_OverflowError))
2597+
return NULL;
2598+
PyErr_Clear(); /* fall through */
25972599
}
2598-
if (size < 0) {
2599-
PyErr_SetString(PyExc_ValueError, "negative count");
2600-
return NULL;
2600+
else {
2601+
if (size < 0) {
2602+
PyErr_SetString(PyExc_ValueError, "negative count");
2603+
return NULL;
2604+
}
2605+
new = _PyBytes_FromSize(size, 1);
2606+
if (new == NULL)
2607+
return NULL;
2608+
return new;
26012609
}
2602-
new = _PyBytes_FromSize(size, 1);
2603-
if (new == NULL)
2604-
return NULL;
2605-
return new;
26062610
}
26072611

26082612
return PyBytes_FromObject(x);

0 commit comments

Comments
 (0)