Skip to content

Commit 7643c92

Browse files
committed
merge 3.3 (#16722)
2 parents af5e29a + 5ff3f73 commit 7643c92

3 files changed

Lines changed: 37 additions & 5 deletions

File tree

‎Lib/test/test_bytes.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,12 @@ class A:
715715
def __bytes__(self):
716716
return None
717717
self.assertRaises(TypeError, bytes, A())
718+
class A:
719+
def __bytes__(self):
720+
return b'a'
721+
def __index__(self):
722+
return 42
723+
self.assertEqual(bytes(A()), b'a')
718724

719725
# Test PyBytes_FromFormat()
720726
def test_from_format(self):

‎Misc/NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #16722: In the bytes() constructor, try to call __bytes__ on the
14+
argument before __index__.
15+
1316
- Issue #16421: loading multiple modules from one shared object is now
1417
handled correctly (previously, the first module loaded from that file
1518
was silently returned). Patch by Václav Šmilauer.

‎Objects/bytesobject.c‎

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,8 +2428,10 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
24282428
const char *encoding = NULL;
24292429
const char *errors = NULL;
24302430
PyObject *new = NULL;
2431+
PyObject *func;
24312432
Py_ssize_t size;
24322433
static char *kwlist[] = {"source", "encoding", "errors", 0};
2434+
_Py_IDENTIFIER(__bytes__);
24332435

24342436
if (type != &PyBytes_Type)
24352437
return str_subtype_new(type, args, kwds);
@@ -2459,6 +2461,28 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
24592461
assert(PyBytes_Check(new));
24602462
return new;
24612463
}
2464+
2465+
/* We'd like to call PyObject_Bytes here, but we need to check for an
2466+
integer argument before deferring to PyBytes_FromObject, something
2467+
PyObject_Bytes doesn't do. */
2468+
func = _PyObject_LookupSpecial(x, &PyId___bytes__);
2469+
if (func != NULL) {
2470+
new = PyObject_CallFunctionObjArgs(func, NULL);
2471+
Py_DECREF(func);
2472+
if (new == NULL)
2473+
return NULL;
2474+
if (!PyBytes_Check(new)) {
2475+
PyErr_Format(PyExc_TypeError,
2476+
"__bytes__ returned non-bytes (type %.200s)",
2477+
Py_TYPE(new)->tp_name);
2478+
Py_DECREF(new);
2479+
return NULL;
2480+
}
2481+
return new;
2482+
}
2483+
else if (PyErr_Occurred())
2484+
return NULL;
2485+
24622486
/* Is it an integer? */
24632487
size = PyNumber_AsSsize_t(x, PyExc_OverflowError);
24642488
if (size == -1 && PyErr_Occurred()) {
@@ -2472,12 +2496,10 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
24722496
}
24732497
else {
24742498
new = PyBytes_FromStringAndSize(NULL, size);
2475-
if (new == NULL) {
2499+
if (new == NULL)
24762500
return NULL;
2477-
}
2478-
if (size > 0) {
2501+
if (size > 0)
24792502
memset(((PyBytesObject*)new)->ob_sval, 0, size);
2480-
}
24812503
return new;
24822504
}
24832505

@@ -2487,7 +2509,8 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
24872509
"encoding or errors without a string argument");
24882510
return NULL;
24892511
}
2490-
return PyObject_Bytes(x);
2512+
2513+
return PyBytes_FromObject(x);
24912514
}
24922515

24932516
PyObject *

0 commit comments

Comments
 (0)