mirror of https://github.com/python/cpython
try to call __bytes__ before __index__ (closes #16722)
This commit is contained in:
parent
1f415cf2c2
commit
5ff3f73d94
|
@ -701,6 +701,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):
|
||||||
|
|
|
@ -12,6 +12,9 @@ What's New in Python 3.3.1?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #16722: In the bytes() constructor, try to call __bytes__ on the
|
||||||
|
argument before __index__.
|
||||||
|
|
||||||
- Issue #16602: When a weakref's target was part of a long deallocation
|
- Issue #16602: When a weakref's target was part of a long deallocation
|
||||||
chain, the object could remain reachable through its weakref even though
|
chain, the object could remain reachable through its weakref even though
|
||||||
its refcount had dropped to zero.
|
its refcount had dropped to zero.
|
||||||
|
|
|
@ -2505,8 +2505,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);
|
||||||
|
@ -2536,6 +2538,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()) {
|
||||||
|
@ -2549,12 +2573,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2564,7 +2586,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 *
|
||||||
|
|
Loading…
Reference in New Issue