This commit is contained in:
Benjamin Peterson 2012-12-19 15:28:46 -06:00
commit 7643c92cdd
3 changed files with 37 additions and 5 deletions

View File

@ -715,6 +715,12 @@ class BytesTest(BaseBytesTest):
def __bytes__(self): def __bytes__(self):
return None return None
self.assertRaises(TypeError, bytes, A()) self.assertRaises(TypeError, bytes, A())
class A:
def __bytes__(self):
return b'a'
def __index__(self):
return 42
self.assertEqual(bytes(A()), b'a')
# Test PyBytes_FromFormat() # Test PyBytes_FromFormat()
def test_from_format(self): def test_from_format(self):

View File

@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #16722: In the bytes() constructor, try to call __bytes__ on the
argument before __index__.
- Issue #16421: loading multiple modules from one shared object is now - Issue #16421: loading multiple modules from one shared object is now
handled correctly (previously, the first module loaded from that file handled correctly (previously, the first module loaded from that file
was silently returned). Patch by Václav Šmilauer. was silently returned). Patch by Václav Šmilauer.

View File

@ -2428,8 +2428,10 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
const char *encoding = NULL; const char *encoding = NULL;
const char *errors = NULL; const char *errors = NULL;
PyObject *new = NULL; PyObject *new = NULL;
PyObject *func;
Py_ssize_t size; Py_ssize_t size;
static char *kwlist[] = {"source", "encoding", "errors", 0}; static char *kwlist[] = {"source", "encoding", "errors", 0};
_Py_IDENTIFIER(__bytes__);
if (type != &PyBytes_Type) if (type != &PyBytes_Type)
return str_subtype_new(type, args, kwds); return str_subtype_new(type, args, kwds);
@ -2459,6 +2461,28 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
assert(PyBytes_Check(new)); assert(PyBytes_Check(new));
return new; return new;
} }
/* We'd like to call PyObject_Bytes here, but we need to check for an
integer argument before deferring to PyBytes_FromObject, something
PyObject_Bytes doesn't do. */
func = _PyObject_LookupSpecial(x, &PyId___bytes__);
if (func != NULL) {
new = PyObject_CallFunctionObjArgs(func, NULL);
Py_DECREF(func);
if (new == NULL)
return NULL;
if (!PyBytes_Check(new)) {
PyErr_Format(PyExc_TypeError,
"__bytes__ returned non-bytes (type %.200s)",
Py_TYPE(new)->tp_name);
Py_DECREF(new);
return NULL;
}
return new;
}
else if (PyErr_Occurred())
return NULL;
/* Is it an integer? */ /* Is it an integer? */
size = PyNumber_AsSsize_t(x, PyExc_OverflowError); size = PyNumber_AsSsize_t(x, PyExc_OverflowError);
if (size == -1 && PyErr_Occurred()) { if (size == -1 && PyErr_Occurred()) {
@ -2472,12 +2496,10 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
} }
else { else {
new = PyBytes_FromStringAndSize(NULL, size); new = PyBytes_FromStringAndSize(NULL, size);
if (new == NULL) { if (new == NULL)
return NULL; return NULL;
} if (size > 0)
if (size > 0) {
memset(((PyBytesObject*)new)->ob_sval, 0, size); memset(((PyBytesObject*)new)->ob_sval, 0, size);
}
return new; return new;
} }
@ -2487,7 +2509,8 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
"encoding or errors without a string argument"); "encoding or errors without a string argument");
return NULL; return NULL;
} }
return PyObject_Bytes(x);
return PyBytes_FromObject(x);
} }
PyObject * PyObject *