mirror of https://github.com/python/cpython
bpo-28856: Let %b format for bytes support objects that follow the buffer protocol (GH-546)
This commit is contained in:
parent
9e52c907b5
commit
7e2a54cdd9
|
@ -332,10 +332,12 @@ class FormatTest(unittest.TestCase):
|
||||||
testcommon(b"%b", b"abc", b"abc")
|
testcommon(b"%b", b"abc", b"abc")
|
||||||
testcommon(b"%b", bytearray(b"def"), b"def")
|
testcommon(b"%b", bytearray(b"def"), b"def")
|
||||||
testcommon(b"%b", fb, b"123")
|
testcommon(b"%b", fb, b"123")
|
||||||
|
testcommon(b"%b", memoryview(b"abc"), b"abc")
|
||||||
# # %s is an alias for %b -- should only be used for Py2/3 code
|
# # %s is an alias for %b -- should only be used for Py2/3 code
|
||||||
testcommon(b"%s", b"abc", b"abc")
|
testcommon(b"%s", b"abc", b"abc")
|
||||||
testcommon(b"%s", bytearray(b"def"), b"def")
|
testcommon(b"%s", bytearray(b"def"), b"def")
|
||||||
testcommon(b"%s", fb, b"123")
|
testcommon(b"%s", fb, b"123")
|
||||||
|
testcommon(b"%s", memoryview(b"abc"), b"abc")
|
||||||
# %a will give the equivalent of
|
# %a will give the equivalent of
|
||||||
# repr(some_obj).encode('ascii', 'backslashreplace')
|
# repr(some_obj).encode('ascii', 'backslashreplace')
|
||||||
testcommon(b"%a", 3.14, b"3.14")
|
testcommon(b"%a", 3.14, b"3.14")
|
||||||
|
@ -372,9 +374,11 @@ class FormatTest(unittest.TestCase):
|
||||||
test_exc(b"%c", 3.14, TypeError,
|
test_exc(b"%c", 3.14, TypeError,
|
||||||
"%c requires an integer in range(256) or a single byte")
|
"%c requires an integer in range(256) or a single byte")
|
||||||
test_exc(b"%b", "Xc", TypeError,
|
test_exc(b"%b", "Xc", TypeError,
|
||||||
"%b requires bytes, or an object that implements __bytes__, not 'str'")
|
"%b requires a bytes-like object, "
|
||||||
|
"or an object that implements __bytes__, not 'str'")
|
||||||
test_exc(b"%s", "Wd", TypeError,
|
test_exc(b"%s", "Wd", TypeError,
|
||||||
"%b requires bytes, or an object that implements __bytes__, not 'str'")
|
"%b requires a bytes-like object, "
|
||||||
|
"or an object that implements __bytes__, not 'str'")
|
||||||
|
|
||||||
if maxsize == 2**31-1:
|
if maxsize == 2**31-1:
|
||||||
# crashes 2.2.1 and earlier:
|
# crashes 2.2.1 and earlier:
|
||||||
|
|
|
@ -10,6 +10,9 @@ What's New in Python 3.7.0 alpha 1?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- bpo-28856: Fix an oversight that %b format for bytes should support objects
|
||||||
|
follow the buffer protocol.
|
||||||
|
|
||||||
- bpo-29723: The ``sys.path[0]`` initialization change for bpo-29139 caused a
|
- bpo-29723: The ``sys.path[0]`` initialization change for bpo-29139 caused a
|
||||||
regression by revealing an inconsistency in how sys.path is initialized when
|
regression by revealing an inconsistency in how sys.path is initialized when
|
||||||
executing ``__main__`` from a zipfile, directory, or other import location.
|
executing ``__main__`` from a zipfile, directory, or other import location.
|
||||||
|
|
|
@ -528,6 +528,8 @@ byte_converter(PyObject *arg, char *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *_PyBytes_FromBuffer(PyObject *x);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
format_obj(PyObject *v, const char **pbuf, Py_ssize_t *plen)
|
format_obj(PyObject *v, const char **pbuf, Py_ssize_t *plen)
|
||||||
{
|
{
|
||||||
|
@ -564,8 +566,19 @@ format_obj(PyObject *v, const char **pbuf, Py_ssize_t *plen)
|
||||||
*plen = PyBytes_GET_SIZE(result);
|
*plen = PyBytes_GET_SIZE(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
/* does it support buffer protocol? */
|
||||||
|
if (PyObject_CheckBuffer(v)) {
|
||||||
|
/* maybe we can avoid making a copy of the buffer object here? */
|
||||||
|
result = _PyBytes_FromBuffer(v);
|
||||||
|
if (result == NULL)
|
||||||
|
return NULL;
|
||||||
|
*pbuf = PyBytes_AS_STRING(result);
|
||||||
|
*plen = PyBytes_GET_SIZE(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"%%b requires bytes, or an object that implements __bytes__, not '%.100s'",
|
"%%b requires a bytes-like object, "
|
||||||
|
"or an object that implements __bytes__, not '%.100s'",
|
||||||
Py_TYPE(v)->tp_name);
|
Py_TYPE(v)->tp_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue