cpython: 2e684ce772de (original) (raw)
--- a/Include/bytes_methods.h +++ b/Include/bytes_methods.h @@ -22,7 +22,7 @@ extern void _Py_bytes_capitalize(char *r extern void _Py_bytes_swapcase(char *result, char s, Py_ssize_t len); / The maketrans() static method. / -extern PyObject _Py_bytes_maketrans(PyObject *frm, PyObject to); +extern PyObject Py_bytes_maketrans(Py_buffer *frm, Py_buffer to); / Shared doc strings. */ extern const char Py_isspace__doc[];
--- a/Lib/ctypes/test/test_frombuffer.py +++ b/Lib/ctypes/test/test_frombuffer.py @@ -10,7 +10,7 @@ class X(Structure): self._init_called = True class Test(unittest.TestCase):
@@ -23,25 +23,37 @@ class Test(unittest.TestCase): a[0], a[-1] = 200, -200 self.assertEqual(x[:], a.tolist())
self.assertIn(a, x._objects.values())[](#l2.16)
self.assertRaises(BufferError, a.append, 100)[](#l2.17)
self.assertRaises(BufferError, a.pop)[](#l2.18)
self.assertRaises(ValueError,[](#l2.20)
c_int.from_buffer, a, -1)[](#l2.21)
del x; del y; gc.collect(); gc.collect(); gc.collect()[](#l2.22)
a.append(100)[](#l2.23)
a.pop()[](#l2.24)
x = (c_int * 16).from_buffer(a)[](#l2.25)
self.assertIn(a, [obj.obj if isinstance(obj, memoryview) else obj[](#l2.27)
for obj in x._objects.values()])[](#l2.28)
expected = x[:] del a; gc.collect(); gc.collect(); gc.collect() self.assertEqual(x[:], expected)
self.assertRaises(TypeError,[](#l2.34)
(c_char * 16).from_buffer, "a" * 16)[](#l2.35)
with self.assertRaises(TypeError):[](#l2.36)
(c_char * 16).from_buffer(b"a" * 16)[](#l2.37)
with self.assertRaises(TypeError):[](#l2.38)
(c_char * 16).from_buffer("a" * 16)[](#l2.39)
- def test_from_buffer_with_offset(self): a = array.array("i", range(16)) x = (c_int * 15).from_buffer(a, sizeof(c_int))
self.assertEqual(x[:], a.tolist()[1:])
self.assertRaises(ValueError, lambda: (c_int * 16).from_buffer(a, sizeof(c_int)))[](#l2.47)
self.assertRaises(ValueError, lambda: (c_int * 1).from_buffer(a, 16 * sizeof(c_int)))[](#l2.48)
with self.assertRaises(ValueError):[](#l2.49)
c_int.from_buffer(a, -1)[](#l2.50)
with self.assertRaises(ValueError):[](#l2.51)
(c_int * 16).from_buffer(a, sizeof(c_int))[](#l2.52)
with self.assertRaises(ValueError):[](#l2.53)
(c_int * 1).from_buffer(a, 16 * sizeof(c_int))[](#l2.54)
def test_from_buffer_copy(self): a = array.array("i", range(16)) @@ -56,26 +68,30 @@ class Test(unittest.TestCase): a[0], a[-1] = 200, -200 self.assertEqual(x[:], list(range(16)))
self.assertEqual(x._objects, None)[](#l2.62)
a.append(100)[](#l2.63)
self.assertEqual(x[:], list(range(16)))[](#l2.64)
self.assertRaises(ValueError,[](#l2.66)
c_int.from_buffer, a, -1)[](#l2.67)
self.assertEqual(x._objects, None)[](#l2.68)
del a; gc.collect(); gc.collect(); gc.collect() self.assertEqual(x[:], list(range(16))) x = (c_char * 16).from_buffer_copy(b"a" * 16) self.assertEqual(x[:], b"a" * 16)
with self.assertRaises(TypeError):[](#l2.75)
(c_char * 16).from_buffer_copy("a" * 16)[](#l2.76)
- def test_from_buffer_copy_with_offset(self): a = array.array("i", range(16)) x = (c_int * 15).from_buffer_copy(a, sizeof(c_int))
self.assertEqual(x[:], a.tolist()[1:])
self.assertRaises(ValueError,[](#l2.84)
(c_int * 16).from_buffer_copy, a, sizeof(c_int))[](#l2.85)
self.assertRaises(ValueError,[](#l2.86)
(c_int * 1).from_buffer_copy, a, 16 * sizeof(c_int))[](#l2.87)
with self.assertRaises(ValueError):[](#l2.88)
c_int.from_buffer_copy(a, -1)[](#l2.89)
with self.assertRaises(ValueError):[](#l2.90)
(c_int * 16).from_buffer_copy(a, sizeof(c_int))[](#l2.91)
with self.assertRaises(ValueError):[](#l2.92)
(c_int * 1).from_buffer_copy(a, 16 * sizeof(c_int))[](#l2.93)
if name == 'main': unittest.main()
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Release date: TBA Core and Builtins ----------------- +- Issue #22896: Avoid using PyObject_AsCharBuffer(), PyObject_AsReadBuffer()
- Issue #21295: Revert some changes (issue #16795) to AST line numbers and column offsets that constituted a regression.
--- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -288,8 +288,6 @@ unicode_internal_decode(PyObject *self, { PyObject *obj; const char *errors = NULL;
if (!PyArg_ParseTuple(args, "O|z:unicode_internal_decode", &obj, &errors)) @@ -302,11 +300,16 @@ unicode_internal_decode(PyObject *self, return codec_tuple(obj, PyUnicode_GET_LENGTH(obj)); } else {
if (PyObject_AsReadBuffer(obj, (const void **)&data, &size))[](#l4.16)
Py_buffer view;[](#l4.17)
PyObject *result;[](#l4.18)
if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0)[](#l4.19) return NULL;[](#l4.20)
return codec_tuple(_PyUnicode_DecodeUnicodeInternal(data, size, errors),[](#l4.22)
size);[](#l4.23)
result = codec_tuple([](#l4.24)
_PyUnicode_DecodeUnicodeInternal(view.buf, view.len, errors),[](#l4.25)
view.len);[](#l4.26)
PyBuffer_Release(&view);[](#l4.27)
} } @@ -731,8 +734,6 @@ unicode_internal_encode(PyObject *self, { PyObject *obj; const char *errors = NULL;return result;[](#l4.28)
if (PyErr_WarnEx(PyExc_DeprecationWarning, "unicode_internal codec has been deprecated", @@ -745,6 +746,7 @@ unicode_internal_encode(PyObject *self, if (PyUnicode_Check(obj)) { Py_UNICODE *u;
Py_ssize_t len, size;[](#l4.45)
if (PyUnicode_READY(obj) < 0) return NULL; @@ -759,9 +761,13 @@ unicode_internal_encode(PyObject *self, PyUnicode_GET_LENGTH(obj)); } else {
if (PyObject_AsReadBuffer(obj, (const void **)&data, &size))[](#l4.53)
Py_buffer view;[](#l4.54)
PyObject *result;[](#l4.55)
if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0)[](#l4.56) return NULL;[](#l4.57)
return codec_tuple(PyBytes_FromStringAndSize(data, size), size);[](#l4.58)
result = codec_tuple(PyBytes_FromStringAndSize(view.buf, view.len), view.len);[](#l4.59)
PyBuffer_Release(&view);[](#l4.60)
} }return result;[](#l4.61)
--- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -463,39 +463,45 @@ KeepRef(CDataObject *target, Py_ssize_t static PyObject * CDataType_from_buffer(PyObject *type, PyObject *args) {
if (offset < 0) { PyErr_SetString(PyExc_ValueError, "offset cannot be negative");
- if (dict->size > buffer.len - offset) { PyErr_Format(PyExc_ValueError, "Buffer size too small (%zd instead of at least %zd bytes)",
buffer_len, dict->size + offset);[](#l5.33)
buffer.len, dict->size + offset);[](#l5.34)
PyBuffer_Release(&buffer);[](#l5.35)
return NULL;[](#l5.36)
- }
- result = PyCData_AtAddress(type, (char *)buffer.buf + offset);
- if (result == NULL) {
}PyBuffer_Release(&buffer);[](#l5.41) return NULL;[](#l5.42)
- mv = PyMemoryView_FromBuffer(&buffer);
- if (mv == NULL) {
PyBuffer_Release(&buffer);[](#l5.49) return NULL;[](#l5.50)
- }
- /* Hack the memoryview so that it will release the buffer. */
- ((PyMemoryViewObject *)mv)->mbuf->master.obj = buffer.obj;
- ((PyMemoryViewObject *)mv)->view.obj = buffer.obj;
- if (-1 == KeepRef((CDataObject *)result, -1, mv))
return result; } @@ -508,37 +514,36 @@ GenericPyCData_new(PyTypeObject *type, P static PyObject * CDataType_from_buffer_copy(PyObject *type, PyObject *args) {result = NULL;[](#l5.61)
if (offset < 0) { PyErr_SetString(PyExc_ValueError, "offset cannot be negative");
- if (dict->size > buffer.len - offset) { PyErr_Format(PyExc_ValueError, "Buffer size too small (%zd instead of at least %zd bytes)",
buffer_len, dict->size + offset);[](#l5.96)
buffer.len, dict->size + offset);[](#l5.97)
} result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL);PyBuffer_Release(&buffer);[](#l5.98) return NULL;[](#l5.99)
- if (result == NULL)
return NULL;[](#l5.104)
- memcpy(((CDataObject *)result)->b_ptr,
(char *)buffer+offset, dict->size);[](#l5.106)
- if (result != NULL) {
memcpy(((CDataObject *)result)->b_ptr,[](#l5.108)
(char *)buffer.buf + offset, dict->size);[](#l5.109)
- }
- PyBuffer_Release(&buffer); return result; }
--- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -553,17 +553,18 @@ PyDoc_STRVAR(readinto_doc, "is set not to block as has no data to read."); static PyObject * -bytesio_readinto(bytesio *self, PyObject *buffer) +bytesio_readinto(bytesio *self, PyObject *arg) {
@@ -571,10 +572,11 @@ bytesio_readinto(bytesio *self, PyObject len = 0; }
- memcpy(buffer.buf, self->buf + self->pos, len); assert(self->pos + len < PY_SSIZE_T_MAX); assert(len >= 0); self->pos += len;
- PyBuffer_Release(&buffer);
return PyLong_FromSsize_t(len); }
--- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -522,19 +522,20 @@ static int return -1; sqlite3_result_text(context, str, -1, SQLITE_TRANSIENT); } else if (PyObject_CheckBuffer(py_val)) {
const char* buffer;[](#l7.7)
Py_ssize_t buflen;[](#l7.8)
if (PyObject_AsCharBuffer(py_val, &buffer, &buflen) != 0) {[](#l7.9)
Py_buffer view;[](#l7.10)
if (PyObject_GetBuffer(py_val, &view, PyBUF_SIMPLE) != 0) {[](#l7.11) PyErr_SetString(PyExc_ValueError,[](#l7.12) "could not convert BLOB to buffer");[](#l7.13) return -1;[](#l7.14) }[](#l7.15)
if (buflen > INT_MAX) {[](#l7.16)
if (view.len > INT_MAX) {[](#l7.17) PyErr_SetString(PyExc_OverflowError,[](#l7.18) "BLOB longer than INT_MAX bytes");[](#l7.19)
PyBuffer_Release(&view);[](#l7.20) return -1;[](#l7.21) }[](#l7.22)
sqlite3_result_blob(context, buffer, (int)buflen, SQLITE_TRANSIENT);[](#l7.23)
sqlite3_result_blob(context, view.buf, (int)view.len, SQLITE_TRANSIENT);[](#l7.24)
} else { return -1; }PyBuffer_Release(&view);[](#l7.25)
--- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -94,7 +94,6 @@ int pysqlite_statement_create(pysqlite_S int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter) { int rc = SQLITE_OK;
- const char* buffer; char* string; Py_ssize_t buflen; parameter_type paramtype; @@ -145,18 +144,22 @@ int pysqlite_statement_bind_parameter(py } rc = sqlite3_bind_text(self->st, pos, string, (int)buflen, SQLITE_TRANSIENT); break;
case TYPE_BUFFER:[](#l8.15)
if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) != 0) {[](#l8.16)
case TYPE_BUFFER: {[](#l8.17)
Py_buffer view;[](#l8.18)
if (PyObject_GetBuffer(parameter, &view, PyBUF_SIMPLE) != 0) {[](#l8.19) PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");[](#l8.20) return -1;[](#l8.21) }[](#l8.22)
if (buflen > INT_MAX) {[](#l8.23)
if (view.len > INT_MAX) {[](#l8.24) PyErr_SetString(PyExc_OverflowError,[](#l8.25) "BLOB longer than INT_MAX bytes");[](#l8.26)
PyBuffer_Release(&view);[](#l8.27) return -1;[](#l8.28) }[](#l8.29)
rc = sqlite3_bind_blob(self->st, pos, buffer, buflen, SQLITE_TRANSIENT);[](#l8.30)
rc = sqlite3_bind_blob(self->st, pos, view.buf, (int)view.len, SQLITE_TRANSIENT);[](#l8.31)
PyBuffer_Release(&view);[](#l8.32) break;[](#l8.33)
}}[](#l8.34) case TYPE_UNKNOWN:[](#l8.35) rc = -1;[](#l8.36)
--- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -1842,8 +1842,8 @@ static PyObject * s_pack_into(PyObject *self, PyObject *args) { PyStructObject *soself;
/* Validate arguments. +1 is for the first arg as buffer. */ soself = (PyStructObject *)self; @@ -1868,34 +1868,37 @@ s_pack_into(PyObject *self, PyObject ar } / Extract a writable memory buffer from the first argument */
- if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
(void**)&buffer, &buffer_len) == -1 ) {[](#l9.19)
/* Extract the offset from the first argument */ offset = PyNumber_AsSsize_t(PyTuple_GET_ITEM(args, 1), PyExc_IndexError);
- if (offset == -1 && PyErr_Occurred()) {
PyBuffer_Release(&buffer);[](#l9.30) return NULL;[](#l9.31)
- }
/* Support negative offsets. */ if (offset < 0)
offset += buffer_len;[](#l9.36)
offset += buffer.len;[](#l9.37)
- if (offset < 0 || (buffer.len - offset) < soself->s_size) { PyErr_Format(StructError, "pack_into requires a buffer of at least %zd bytes", soself->s_size);
} /* Call the guts */PyBuffer_Release(&buffer);[](#l9.45) return NULL;[](#l9.46)
- if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) {
}PyBuffer_Release(&buffer);[](#l9.52) return NULL;[](#l9.53)
- PyBuffer_Release(&buffer); Py_RETURN_NONE; }
--- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -250,27 +250,7 @@ PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len) {
- if (obj == NULL || buffer == NULL || buffer_len == NULL) {
null_error();[](#l10.11)
return -1;[](#l10.12)
- }
- pb = obj->ob_type->tp_as_buffer;
- if (pb == NULL || pb->bf_getbuffer == NULL) {
PyErr_SetString(PyExc_TypeError,[](#l10.16)
"expected a bytes-like object");[](#l10.17)
return -1;[](#l10.18)
- }
- if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE)) return -1;
- *buffer = view.buf;
- *buffer_len = view.len;
- if (pb->bf_releasebuffer != NULL)
(*pb->bf_releasebuffer)(obj, &view);[](#l10.25)
- Py_XDECREF(view.obj);
- return 0;
} int @@ -294,28 +274,18 @@ int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) {
- PyBufferProcs *pb; Py_buffer view; if (obj == NULL || buffer == NULL || buffer_len == NULL) { null_error(); return -1; }
- pb = obj->ob_type->tp_as_buffer;
- if (pb == NULL ||
pb->bf_getbuffer == NULL) {[](#l10.45)
PyErr_SetString(PyExc_TypeError,[](#l10.46)
"expected a bytes-like object");[](#l10.47)
*buffer = view.buf; *buffer_len = view.len;
- if (pb->bf_releasebuffer != NULL)
(*pb->bf_releasebuffer)(obj, &view);[](#l10.57)
- Py_XDECREF(view.obj);
@@ -341,9 +311,7 @@ int PyObject_AsWriteBuffer(PyObject *obj *buffer = view.buf; *buffer_len = view.len;
- if (pb->bf_releasebuffer != NULL)
(*pb->bf_releasebuffer)(obj, &view);[](#l10.68)
- Py_XDECREF(view.obj);
@@ -352,13 +320,15 @@ int PyObject_AsWriteBuffer(PyObject *obj int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
- if (pb == NULL || pb->bf_getbuffer == NULL) { PyErr_Format(PyExc_TypeError, "a bytes-like object is required, not '%.100s'", Py_TYPE(obj)->tp_name); return -1; }
} static int @@ -676,10 +646,14 @@ void PyBuffer_Release(Py_buffer *view) { PyObject *obj = view->obj;
- if (obj && Py_TYPE(obj)->tp_as_buffer && Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer)
Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer(obj, view);[](#l10.97)
- Py_XDECREF(obj);
- PyBufferProcs *pb;
- if (obj == NULL)
return;[](#l10.101)
- pb = Py_TYPE(obj)->tp_as_buffer;
- if (pb && pb->bf_releasebuffer)
view->obj = NULL;pb->bf_releasebuffer(obj, view);[](#l10.104)
- Py_DECREF(obj);
} PyObject * @@ -1288,8 +1262,7 @@ PyNumber_Long(PyObject *o) { PyNumberMethods *m; PyObject *trunc_func;
- Py_buffer view; _Py_IDENTIFIER(trunc); if (o == NULL) @@ -1327,21 +1300,22 @@ PyNumber_Long(PyObject *o) if (PyErr_Occurred()) return NULL;
- if (PyUnicode_Check(o))
/* The below check is done in PyLong_FromUnicode(). */[](#l10.126)
return PyLong_FromUnicodeObject(o, 10);[](#l10.127)
- if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == 0) { /* need to do extra error checking that PyLong_FromString() * doesn't do. In particular int('9\x005') must raise an * exception, not truncate at the null. */
return _PyLong_FromBytes(PyBytes_AS_STRING(o),[](#l10.134)
PyBytes_GET_SIZE(o), 10);[](#l10.135)
- if (PyUnicode_Check(o))
/* The above check is done in PyLong_FromUnicode(). */[](#l10.137)
return PyLong_FromUnicodeObject(o, 10);[](#l10.138)
- if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
return _PyLong_FromBytes(buffer, buffer_len, 10);[](#l10.140)
PyObject *result = _PyLong_FromBytes(view.buf, view.len, 10);[](#l10.144)
PyBuffer_Release(&view);[](#l10.145)
return result;[](#l10.146)
- }
- return type_error("int() argument must be a string, a bytes-like object "
"or a number, not '%.200s'", o);[](#l10.150)
--- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -80,24 +80,6 @@ bytearray_releasebuffer(PyByteArrayObjec obj->ob_exports--; } -static Py_ssize_t -_getbuffer(PyObject *obj, Py_buffer *view) -{
- if (buffer == NULL || buffer->bf_getbuffer == NULL)
- {
PyErr_Format(PyExc_TypeError,[](#l11.14)
"a bytes-like object is required, not '%.100s'",[](#l11.15)
Py_TYPE(obj)->tp_name);[](#l11.16)
return -1;[](#l11.17)
- }
-} - static int _canresize(PyByteArrayObject *self) { @@ -268,8 +250,8 @@ PyByteArray_Concat(PyObject *a, PyObject va.len = -1; vb.len = -1;
- if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {[](#l11.35) PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",[](#l11.36) Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);[](#l11.37) goto done;[](#l11.38)
@@ -335,7 +317,7 @@ bytearray_iconcat(PyByteArrayObject *sel Py_ssize_t size; Py_buffer vo;
- if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) { PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name); return NULL;
@@ -595,14 +577,14 @@ bytearray_setslice(PyByteArrayObject *se needed = 0; } else {
if (_getbuffer(values, &vbytes) < 0) {[](#l11.52)
PyErr_Format(PyExc_TypeError,[](#l11.53)
"can't set bytearray slice from %.100s",[](#l11.54)
Py_TYPE(values)->tp_name);[](#l11.55)
return -1;[](#l11.56)
}[](#l11.57)
needed = vbytes.len;[](#l11.58)
bytes = vbytes.buf;[](#l11.59)
if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {[](#l11.60)
PyErr_Format(PyExc_TypeError,[](#l11.61)
"can't set bytearray slice from %.100s",[](#l11.62)
Py_TYPE(values)->tp_name);[](#l11.63)
return -1;[](#l11.64)
}[](#l11.65)
needed = vbytes.len;[](#l11.66)
} if (lo < 0) @@ -1047,18 +1029,18 @@ bytearray_richcompare(PyObject *self, Py Py_RETURN_NOTIMPLEMENTED; }bytes = vbytes.buf;[](#l11.67)
- if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) { PyErr_Clear(); Py_RETURN_NOTIMPLEMENTED; } -
- if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) { PyErr_Clear(); PyBuffer_Release(&self_bytes); Py_RETURN_NOTIMPLEMENTED; }
- other_size = other_bytes.len;
if (self_size != other_size && (op == Py_EQ || op == Py_NE)) { /* Shortcut: if the lengths differ, the objects differ */ @@ -1170,7 +1152,7 @@ bytearray_find_internal(PyByteArrayObjec return -2; if (subobj) {
if (_getbuffer(subobj, &subbuf) < 0)[](#l11.99)
if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)[](#l11.100) return -2;[](#l11.101)
sub = subbuf.buf; @@ -1238,7 +1220,7 @@ bytearray_count(PyByteArrayObject *self, return NULL; if (sub_obj) {
if (_getbuffer(sub_obj, &vsub) < 0)[](#l11.108)
if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)[](#l11.109) return NULL;[](#l11.110)
sub = vsub.buf; @@ -1397,7 +1379,7 @@ bytearray_contains(PyObject *self, PyObj Py_buffer varg; Py_ssize_t pos; PyErr_Clear();
if (_getbuffer(arg, &varg) < 0)[](#l11.117)
if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)[](#l11.118) return -1;[](#l11.119) pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),[](#l11.120) varg.buf, varg.len, 0);[](#l11.121)
@@ -1428,7 +1410,7 @@ Py_LOCAL(int) str = PyByteArray_AS_STRING(self);
ADJUST_INDICES(start, end, len); @@ -1621,7 +1603,7 @@ bytearray_translate_impl(PyByteArrayObje if (table == Py_None) { table_chars = NULL; table = NULL;
- } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) { return NULL; } else { if (vtable.len != 256) {
@@ -1634,7 +1616,7 @@ bytearray_translate_impl(PyByteArrayObje } if (deletechars != NULL) {
if (_getbuffer(deletechars, &vdel) < 0) {[](#l11.144)
if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {[](#l11.145) if (table != NULL)[](#l11.146) PyBuffer_Release(&vtable);[](#l11.147) return NULL;[](#l11.148)
@@ -1699,8 +1681,8 @@ done: @staticmethod bytearray.maketrans
- frm: Py_buffer
- to: Py_buffer / Return a translation table useable for the bytes or bytearray translate method. @@ -1726,28 +1708,35 @@ PyDoc_STRVAR(bytearray_maketrans__doc__, {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC, bytearray_maketrans__doc__}, static PyObject * -bytearray_maketrans_impl(PyObject *frm, PyObject *to); +bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to); static PyObject * bytearray_maketrans(void *null, PyObject *args) { PyObject *return_value = NULL;
- if (!PyArg_ParseTuple(args,
"y*y*:maketrans",[](#l11.180) &frm, &to))[](#l11.181) goto exit;[](#l11.182)
- /* Cleanup for frm */
- if (frm.obj)
PyBuffer_Release(&frm);[](#l11.189)
- /* Cleanup for to */
- if (to.obj)
PyBuffer_Release(&to);[](#l11.192)
+ return return_value; } static PyObject * -bytearray_maketrans_impl(PyObject frm, PyObject to) -/[clinic end generated code: output=307752019d9b25b5 input=ea9bdc6b328c15e2]/ +bytearray_maketrans_impl(Py_buffer frm, Py_buffer to) +/[clinic end generated code: output=d332622814c26f4b input=5925a81d2fbbf151]/ { return _Py_bytes_maketrans(frm, to); } @@ -2243,8 +2232,8 @@ replace(PyByteArrayObject self, /[clinic input] bytearray.replace
- old: Py_buffer
- new: Py_buffer count: Py_ssize_t = -1 Maximum number of occurrences to replace. -1 (the default value) means replace all occurrences.
@@ -2273,47 +2262,40 @@ PyDoc_STRVAR(bytearray_replace__doc__, {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, bytearray_replace__doc__}, static PyObject * -bytearray_replace_impl(PyByteArrayObject *self, PyObject *old, PyObject *new, Py_ssize_t count); +bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old, Py_buffer *new, Py_ssize_t count); static PyObject * bytearray_replace(PyByteArrayObject *self, PyObject *args) { PyObject *return_value = NULL;
- Py_buffer old = {NULL, NULL};
- Py_buffer new = {NULL, NULL}; Py_ssize_t count = -1; if (!PyArg_ParseTuple(args,
"OO|n:replace",[](#l11.234)
"y*y*|n:replace",[](#l11.235) &old, &new, &count))[](#l11.236) goto exit;[](#l11.237)
- /* Cleanup for old */
- if (old.obj)
PyBuffer_Release(&old);[](#l11.244)
- /* Cleanup for new */
- if (new.obj)
PyBuffer_Release(&new);[](#l11.247)
+ return return_value; } static PyObject * -bytearray_replace_impl(PyByteArrayObject *self, PyObject old, PyObject new, Py_ssize_t count) -/[clinic end generated code: output=4d2e3c9130da0f96 input=9aaaa123608dfc1f]/ +bytearray_replace_impl(PyByteArrayObject *self, Py_buffer old, Py_buffer new, Py_ssize_t count) +/[clinic end generated code: output=9997fbbd5bac4883 input=aa379d988637c7fb]/ {
- if (_getbuffer(old, &vold) < 0)
return NULL;[](#l11.262)
- if (_getbuffer(new, &vnew) < 0) {
PyBuffer_Release(&vold);[](#l11.264)
return NULL;[](#l11.265)
- }
- res = (PyObject *)replace((PyByteArrayObject *) self,
vold.buf, vold.len,[](#l11.269)
vnew.buf, vnew.len, count);[](#l11.270)
- return (PyObject *)replace((PyByteArrayObject *) self,
old->buf, old->len,[](#l11.276)
new->buf, new->len, count);[](#l11.277)
} /*[clinic input] @@ -2383,7 +2365,7 @@ bytearray_split_impl(PyByteArrayObject if (sep == Py_None) return stringlib_split_whitespace((PyObject) self, s, len, maxsplit);
- if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -2566,7 +2548,7 @@ bytearray_rsplit_impl(PyByteArrayObject if (sep == Py_None) return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
- if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -3088,7 +3070,7 @@ bytearray_strip_impl(PyByteArrayObject * byteslen = 6; } else {
if (_getbuffer(bytes, &vbytes) < 0)[](#l11.303)
if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)[](#l11.304) return NULL;[](#l11.305) bytesptr = (char *) vbytes.buf;[](#l11.306) byteslen = vbytes.len;[](#l11.307)
@@ -3159,7 +3141,7 @@ bytearray_lstrip_impl(PyByteArrayObject byteslen = 6; } else {
if (_getbuffer(bytes, &vbytes) < 0)[](#l11.312)
if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)[](#l11.313) return NULL;[](#l11.314) bytesptr = (char *) vbytes.buf;[](#l11.315) byteslen = vbytes.len;[](#l11.316)
@@ -3227,7 +3209,7 @@ bytearray_rstrip_impl(PyByteArrayObject byteslen = 6; } else {
if (_getbuffer(bytes, &vbytes) < 0)[](#l11.321)
if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)[](#l11.322) return NULL;[](#l11.323) bytesptr = (char *) vbytes.buf;[](#l11.324) byteslen = vbytes.len;[](#l11.325)
--- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -363,59 +363,27 @@ for use in the bytes or bytearray transl in frm is mapped to the byte at the same position in to.\n[](#l12.4) The bytes objects frm and to must be of the same length."); -static Py_ssize_t -_getbuffer(PyObject *obj, Py_buffer *view) -{
- if (buffer == NULL || buffer->bf_getbuffer == NULL)
- {
PyErr_Format(PyExc_TypeError,[](#l12.14)
"a bytes-like object is required, not '%.100s'",[](#l12.15)
Py_TYPE(obj)->tp_name);[](#l12.16)
return -1;[](#l12.17)
- }
-} - PyObject * -_Py_bytes_maketrans(PyObject *frm, PyObject *to) +_Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to) { PyObject *res = NULL;
- if (_getbuffer(frm, &bfrm) < 0)
return NULL;[](#l12.38)
- if (_getbuffer(to, &bto) < 0)
goto done;[](#l12.40)
- if (bfrm.len != bto.len) {
- if (frm->len != to->len) { PyErr_Format(PyExc_ValueError, "maketrans arguments must have same length");
goto done;[](#l12.45)
- if (!res)
p = PyBytes_AS_STRING(res); for (i = 0; i < 256; i++) p[i] = (char) i;return NULL;[](#l12.53)
- for (i = 0; i < bfrm.len; i++) {
p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i];[](#l12.58)
- for (i = 0; i < frm->len; i++) {
} -done:p[((unsigned char *)frm->buf)[i]] = ((char *)to->buf)[i];[](#l12.60)
- if (bfrm.len != -1)
PyBuffer_Release(&bfrm);[](#l12.65)
- if (bto.len != -1)
return res; }PyBuffer_Release(&bto);[](#l12.67)
--- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -12,33 +12,6 @@ class bytes "PyBytesObject*" "&PyBytes_T [clinic start generated code]/ /[clinic end generated code: output=da39a3ee5e6b4b0d input=1a1d9102afc1b00c]*/ -static Py_ssize_t -_getbuffer(PyObject *obj, Py_buffer *view) -{
- PyBufferProcs *bufferprocs;
- if (PyBytes_CheckExact(obj)) {
/* Fast path, e.g. for .join() of many bytes objects */[](#l13.12)
Py_INCREF(obj);[](#l13.13)
view->obj = obj;[](#l13.14)
view->buf = PyBytes_AS_STRING(obj);[](#l13.15)
view->len = PyBytes_GET_SIZE(obj);[](#l13.16)
return view->len;[](#l13.17)
- }
- bufferprocs = Py_TYPE(obj)->tp_as_buffer;
- if (bufferprocs == NULL || bufferprocs->bf_getbuffer == NULL)
- {
PyErr_Format(PyExc_TypeError,[](#l13.23)
"a bytes-like object is required, not '%.100s'",[](#l13.24)
Py_TYPE(obj)->tp_name);[](#l13.25)
return -1;[](#l13.26)
- }
-} - #ifdef COUNT_ALLOCS Py_ssize_t null_strings, one_strings; #endif @@ -1349,8 +1322,8 @@ bytes_concat(PyObject *a, PyObject *b) va.len = -1; vb.len = -1;
- if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {[](#l13.44) PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",[](#l13.45) Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);[](#l13.46) goto done;[](#l13.47)
@@ -1448,7 +1421,7 @@ bytes_contains(PyObject *self, PyObject Py_buffer varg; Py_ssize_t pos; PyErr_Clear();
if (_getbuffer(arg, &varg) < 0)[](#l13.52)
if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)[](#l13.53) return -1;[](#l13.54) pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self),[](#l13.55) varg.buf, varg.len, 0);[](#l13.56)
@@ -1737,7 +1710,7 @@ bytes_split_impl(PyBytesObjectself, PyO maxsplit = PY_SSIZE_T_MAX; if (sep == Py_None) return stringlib_split_whitespace((PyObject) self, s, len, maxsplit);
- if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -1751,7 +1724,7 @@ bytes_split_impl(PyBytesObject*self, PyO bytes.partition self: self(type="PyBytesObject *")
- sep: Py_buffer / Partition the bytes into three parts using the given separator. @@ -1778,26 +1751,39 @@ PyDoc_STRVAR(bytes_partition__doc__, "object and two empty bytes objects.");
#define BYTES_PARTITION_METHODDEF [](#l13.78)
+ +static PyObject * +bytes_partition_impl(PyBytesObject *self, Py_buffer *sep); static PyObject * -bytes_partition(PyBytesObject self, PyObject sep) -/[clinic end generated code: output=b41e119c873c08bc input=6c5b9dcc5a9fd62e]/ +bytes_partition(PyBytesObject *self, PyObject *args) {
- if (PyBytes_Check(sep)) {
sep_chars = PyBytes_AS_STRING(sep);[](#l13.94)
sep_len = PyBytes_GET_SIZE(sep);[](#l13.95)
- }
- else if (PyObject_AsCharBuffer(sep, &sep_chars, &sep_len))
return NULL;[](#l13.98)
- if (!PyArg_ParseTuple(args,
"y*:partition",[](#l13.104)
&sep))[](#l13.105)
goto exit;[](#l13.106)
- return_value = bytes_partition_impl(self, &sep);
+} + +static PyObject +bytes_partition_impl(PyBytesObject self, Py_buffer sep) +/[clinic end generated code: output=3006727cfbf83aa4 input=bc855dc63ca949de]/ +{ return stringlib_partition( (PyObject) self, PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self),
sep, sep_chars, sep_len[](#l13.124)
sep->obj, (const char *)sep->buf, sep->len[](#l13.125) );[](#l13.126)
} @@ -1805,7 +1791,7 @@ bytes_partition(PyBytesObject *self, PyO bytes.rpartition self: self(type="PyBytesObject *")
- sep: Py_buffer / Partition the bytes into three parts using the given separator. @@ -1832,26 +1818,39 @@ PyDoc_STRVAR(bytes_rpartition__doc__, "objects and the original bytes object.");
#define BYTES_RPARTITION_METHODDEF [](#l13.141)
+ +static PyObject * +bytes_rpartition_impl(PyBytesObject *self, Py_buffer *sep); static PyObject * -bytes_rpartition(PyBytesObject self, PyObject sep) -/[clinic end generated code: output=3a620803657196ee input=79bc2932e78e5ce0]/ +bytes_rpartition(PyBytesObject *self, PyObject *args) {
- if (PyBytes_Check(sep)) {
sep_chars = PyBytes_AS_STRING(sep);[](#l13.157)
sep_len = PyBytes_GET_SIZE(sep);[](#l13.158)
- }
- else if (PyObject_AsCharBuffer(sep, &sep_chars, &sep_len))
return NULL;[](#l13.161)
- if (!PyArg_ParseTuple(args,
"y*:rpartition",[](#l13.167)
&sep))[](#l13.168)
goto exit;[](#l13.169)
- return_value = bytes_rpartition_impl(self, &sep);
+} + +static PyObject +bytes_rpartition_impl(PyBytesObject self, Py_buffer sep) +/[clinic end generated code: output=57b169dc47fa90e8 input=6588fff262a9170e]/ +{ return stringlib_rpartition( (PyObject) self, PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self),
sep, sep_chars, sep_len[](#l13.187)
sep->obj, (const char *)sep->buf, sep->len[](#l13.188) );[](#l13.189)
} @@ -1916,7 +1915,7 @@ bytes_rsplit_impl(PyBytesObjectself, Py maxsplit = PY_SSIZE_T_MAX; if (sep == Py_None) return stringlib_rsplit_whitespace((PyObject) self, s, len, maxsplit);
- if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -2003,7 +2002,7 @@ bytes_find_internal(PyBytesObject *self, return -2;
if (_getbuffer(subobj, &subbuf) < 0)[](#l13.205)
if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)[](#l13.206) return -2;[](#l13.207)
sub = subbuf.buf; @@ -2118,7 +2117,7 @@ do_xstrip(PyBytesObject *self, int strip Py_ssize_t seplen; Py_ssize_t i, j;
- if (PyObject_GetBuffer(sepobj, &vsep, PyBUF_SIMPLE) != 0) return NULL; sep = vsep.buf; seplen = vsep.len; @@ -2360,7 +2359,7 @@ bytes_count(PyBytesObject *self, PyObjec return NULL;
if (_getbuffer(sub_obj, &vsub) < 0)[](#l13.223)
if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)[](#l13.224) return NULL;[](#l13.225)
sub = vsub.buf; @@ -2450,6 +2449,8 @@ bytes_translate_impl(PyBytesObject self /[clinic end generated code: output=f0f29a57f41df5d8 input=d8fa5519d7cc4be7]*/ { char *input, *output;
- Py_buffer table_view = {NULL, NULL};
- Py_buffer del_table_view = {NULL, NULL}; const char *table_chars; Py_ssize_t i, c, changed = 0; PyObject input_obj = (PyObject)self; @@ -2466,12 +2467,17 @@ bytes_translate_impl(PyBytesObject *self table_chars = NULL; tablen = 256; }
- else {
if (PyObject_GetBuffer(table, &table_view, PyBUF_SIMPLE) != 0)[](#l13.244)
return NULL;[](#l13.245)
table_chars = table_view.buf;[](#l13.246)
tablen = table_view.len;[](#l13.247)
- }
if (tablen != 256) { PyErr_SetString(PyExc_ValueError, "translation table must be 256 characters long");
} @@ -2480,8 +2486,14 @@ bytes_translate_impl(PyBytesObject *self del_table_chars = PyBytes_AS_STRING(deletechars); dellen = PyBytes_GET_SIZE(deletechars); }PyBuffer_Release(&table_view);[](#l13.253) return NULL;[](#l13.254)
else if (PyObject_AsCharBuffer(deletechars, &del_table_chars, &dellen))[](#l13.261)
return NULL;[](#l13.262)
else {[](#l13.263)
if (PyObject_GetBuffer(deletechars, &del_table_view, PyBUF_SIMPLE) != 0) {[](#l13.264)
PyBuffer_Release(&table_view);[](#l13.265)
return NULL;[](#l13.266)
}[](#l13.267)
del_table_chars = del_table_view.buf;[](#l13.268)
dellen = del_table_view.len;[](#l13.269)
} else { del_table_chars = NULL;}[](#l13.270)
@@ -2490,8 +2502,11 @@ bytes_translate_impl(PyBytesObject *self inlen = PyBytes_GET_SIZE(input_obj); result = PyBytes_FromStringAndSize((char *)NULL, inlen);
- if (result == NULL) {
PyBuffer_Release(&del_table_view);[](#l13.280)
PyBuffer_Release(&table_view);[](#l13.281) return NULL;[](#l13.282)
- } output_start = output = PyBytes_AsString(result); input = PyBytes_AS_STRING(input_obj); @@ -2502,11 +2517,14 @@ bytes_translate_impl(PyBytesObject *self if (Py_CHARMASK((*output++ = table_chars[c])) != c) changed = 1; }
if (changed || !PyBytes_CheckExact(input_obj))[](#l13.291)
return result;[](#l13.292)
Py_DECREF(result);[](#l13.293)
Py_INCREF(input_obj);[](#l13.294)
return input_obj;[](#l13.295)
if (!changed && PyBytes_CheckExact(input_obj)) {[](#l13.296)
Py_INCREF(input_obj);[](#l13.297)
Py_DECREF(result);[](#l13.298)
result = input_obj;[](#l13.299)
}[](#l13.300)
PyBuffer_Release(&del_table_view);[](#l13.301)
PyBuffer_Release(&table_view);[](#l13.302)
} if (table_chars == NULL) { @@ -2516,9 +2534,11 @@ bytes_translate_impl(PyBytesObject *self for (i = 0; i < 256; i++) trans_table[i] = Py_CHARMASK(table_chars[i]); }return result;[](#l13.303)
- PyBuffer_Release(&table_view);
for (i = 0; i < dellen; i++) trans_table[(int) Py_CHARMASK(del_table_chars[i])] = -1;
for (i = inlen; --i >= 0; ) { c = Py_CHARMASK(*input++); @@ -2544,8 +2564,8 @@ bytes_translate_impl(PyBytesObject *self @staticmethod bytes.maketrans
- frm: Py_buffer
- to: Py_buffer / Return a translation table useable for the bytes or bytearray translate method. @@ -2571,28 +2591,35 @@ PyDoc_STRVAR(bytes_maketrans__doc__, {"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC, bytes_maketrans__doc__}, static PyObject * -bytes_maketrans_impl(PyObject *frm, PyObject *to); +bytes_maketrans_impl(Py_buffer *frm, Py_buffer *to); static PyObject * bytes_maketrans(void *null, PyObject *args) { PyObject *return_value = NULL;
- if (!PyArg_ParseTuple(args,
"y*y*:maketrans",[](#l13.350) &frm, &to))[](#l13.351) goto exit;[](#l13.352)
- /* Cleanup for frm */
- if (frm.obj)
PyBuffer_Release(&frm);[](#l13.359)
- /* Cleanup for to */
- if (to.obj)
PyBuffer_Release(&to);[](#l13.362)
+ return return_value; } static PyObject * -bytes_maketrans_impl(PyObject frm, PyObject to) -/[clinic end generated code: output=89a3c3556975e466 input=d204f680f85da382]/ +bytes_maketrans_impl(Py_buffer frm, Py_buffer to) +/[clinic end generated code: output=7df47390c476ac60 input=de7a8fc5632bb8f1]/ { return _Py_bytes_maketrans(frm, to); } @@ -3093,8 +3120,8 @@ replace(PyBytesObject self, /[clinic input] bytes.replace
- old: Py_buffer
- new: Py_buffer count: Py_ssize_t = -1 Maximum number of occurrences to replace. -1 (the default value) means replace all occurrences.
@@ -3123,50 +3150,40 @@ PyDoc_STRVAR(bytes_replace__doc__, {"replace", (PyCFunction)bytes_replace, METH_VARARGS, bytes_replace__doc__}, static PyObject -bytes_replace_impl(PyBytesObjectself, PyObject *old, PyObject new, Py_ssize_t count); +bytes_replace_impl(PyBytesObjectself, Py_buffer *old, Py_buffer *new, Py_ssize_t count); static PyObject bytes_replace(PyBytesObjectself, PyObject *args) { PyObject *return_value = NULL;
- Py_buffer old = {NULL, NULL};
- Py_buffer new = {NULL, NULL}; Py_ssize_t count = -1; if (!PyArg_ParseTuple(args,
"OO|n:replace",[](#l13.404)
"y*y*|n:replace",[](#l13.405) &old, &new, &count))[](#l13.406) goto exit;[](#l13.407)
- /* Cleanup for old */
- if (old.obj)
PyBuffer_Release(&old);[](#l13.414)
- /* Cleanup for new */
- if (new.obj)
PyBuffer_Release(&new);[](#l13.417)
+ return return_value; } static PyObject -bytes_replace_impl(PyBytesObjectself, PyObject old, PyObject new, Py_ssize_t count) -/[clinic end generated code: output=14ce72f4f9cb91cf input=d3ac254ea50f4ac1]/ +bytes_replace_impl(PyBytesObject*self, Py_buffer old, Py_buffer new, Py_ssize_t count) +/[clinic end generated code: output=f07bd9ecf29ee8d8 input=b2fbbf0bf04de8e5]/ {
- if (PyBytes_Check(old)) {
old_s = PyBytes_AS_STRING(old);[](#l13.432)
old_len = PyBytes_GET_SIZE(old);[](#l13.433)
- }
- else if (PyObject_AsCharBuffer(old, &old_s, &old_len))
return NULL;[](#l13.436)
- if (PyBytes_Check(new)) {
new_s = PyBytes_AS_STRING(new);[](#l13.439)
new_len = PyBytes_GET_SIZE(new);[](#l13.440)
- }
- else if (PyObject_AsCharBuffer(new, &new_s, &new_len))
return NULL;[](#l13.443)
- return (PyObject *)replace((PyBytesObject *) self,
old_s, old_len,[](#l13.446)
new_s, new_len, count);[](#l13.447)
(const char *)old->buf, old->len,[](#l13.448)
(const char *)new->buf, new->len, count);[](#l13.449)
} /** End DALKE **/ @@ -3181,6 +3198,7 @@ Py_LOCAL(int) { Py_ssize_t len = PyBytes_GET_SIZE(self); Py_ssize_t slen;
- Py_buffer sub_view = {NULL, NULL}; const char* sub; const char* str; @@ -3188,8 +3206,12 @@ Py_LOCAL(int) sub = PyBytes_AS_STRING(substr); slen = PyBytes_GET_SIZE(substr); }
- else {
if (PyObject_GetBuffer(substr, &sub_view, PyBUF_SIMPLE) != 0)[](#l13.468)
return -1;[](#l13.469)
sub = sub_view.buf;[](#l13.470)
slen = sub_view.len;[](#l13.471)
- } str = PyBytes_AS_STRING(self); ADJUST_INDICES(start, end, len); @@ -3197,17 +3219,25 @@ Py_LOCAL(int) if (direction < 0) { /* startswith */ if (start+slen > len)
return 0;[](#l13.480)
return 0;[](#l13.485)
goto notfound;[](#l13.486)
if (end-slen > start) start = end - slen; }
- if (end-start < slen)
goto notfound;[](#l13.494)
- if (memcmp(str+start, sub, slen) != 0)
goto notfound;[](#l13.496)
@@ -3978,7 +4008,7 @@ PyBytes_Concat(PyObject **pv, PyObject * Py_buffer wb; wb.len = -1;
if (_getbuffer(w, &wb) < 0) {[](#l13.510)
if (PyObject_GetBuffer(w, &wb, PyBUF_SIMPLE) != 0) {[](#l13.511) PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",[](#l13.512) Py_TYPE(w)->tp_name, Py_TYPE(*pv)->tp_name);[](#l13.513) Py_CLEAR(*pv);[](#l13.514)
--- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -767,6 +767,7 @@ complex_subtype_from_string(PyTypeObject int got_bracket=0; PyObject *s_buffer = NULL; Py_ssize_t len;
if (PyUnicode_Check(v)) { s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v); @@ -776,7 +777,11 @@ complex_subtype_from_string(PyTypeObject if (s == NULL) goto error; }
- else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) {
s = (const char *)view.buf;[](#l14.17)
len = view.len;[](#l14.18)
- }
- else { PyErr_Format(PyExc_TypeError, "complex() argument must be a string or a number, not '%.200s'", Py_TYPE(v)->tp_name);
@@ -890,6 +895,7 @@ complex_subtype_from_string(PyTypeObject if (s-start != len) goto parse_error;
- PyBuffer_Release(&view); Py_XDECREF(s_buffer); return complex_subtype_from_doubles(type, x, y); @@ -897,6 +903,7 @@ complex_subtype_from_string(PyTypeObject PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string");
--- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1922,8 +1922,6 @@ static int UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds) { PyUnicodeErrorObject *ude;
if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) return -1; @@ -1944,21 +1942,27 @@ UnicodeDecodeError_init(PyObject *self, return -1; }
+ if (!PyBytes_Check(ude->object)) {
if (PyObject_AsReadBuffer(ude->object, (const void **)&data, &size)) {[](#l15.21)
ude->encoding = ude->object = ude->reason = NULL;[](#l15.22)
return -1;[](#l15.23)
}[](#l15.24)
ude->object = PyBytes_FromStringAndSize(data, size);[](#l15.25)
Py_buffer view;[](#l15.26)
if (PyObject_GetBuffer(ude->object, &view, PyBUF_SIMPLE) != 0)[](#l15.27)
goto error;[](#l15.28)
Py_CLEAR(ude->object);[](#l15.29)
ude->object = PyBytes_FromStringAndSize(view.buf, view.len);[](#l15.30)
PyBuffer_Release(&view);[](#l15.31)
if (!ude->object)[](#l15.32)
}goto error;[](#l15.33)
--- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -131,6 +131,7 @@ PyFloat_FromString(PyObject *v) double x; PyObject *s_buffer = NULL; Py_ssize_t len;
- Py_buffer view = {NULL, NULL}; PyObject *result = NULL; if (PyUnicode_Check(v)) { @@ -143,7 +144,11 @@ PyFloat_FromString(PyObject *v) return NULL; } }
- else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) {
s = (const char *)view.buf;[](#l16.17)
len = view.len;[](#l16.18)
- }
- else { PyErr_Format(PyExc_TypeError, "float() argument must be a string or a number, not '%.200s'", Py_TYPE(v)->tp_name);
@@ -170,6 +175,7 @@ PyFloat_FromString(PyObject *v) else result = PyFloat_FromDouble(x);
--- a/Objects/stringlib/join.h +++ b/Objects/stringlib/join.h @@ -58,7 +58,14 @@ STRINGLIB(bytes_join)(PyObject *sep, PyO for (i = 0, nbufs = 0; i < seqlen; i++) { Py_ssize_t itemlen; item = PySequence_Fast_GET_ITEM(seq, i);
if (_getbuffer(item, &buffers[i]) < 0) {[](#l17.7)
if (PyBytes_CheckExact(item)) {[](#l17.8)
/* Fast path. */[](#l17.9)
Py_INCREF(item);[](#l17.10)
buffers[i].obj = item;[](#l17.11)
buffers[i].buf = PyBytes_AS_STRING(item);[](#l17.12)
buffers[i].len = PyBytes_GET_SIZE(item);[](#l17.13)
}[](#l17.14)
else if (PyObject_GetBuffer(item, &buffers[i], PyBUF_SIMPLE) != 0) {[](#l17.15) PyErr_Format(PyExc_TypeError,[](#l17.16) "sequence item %zd: expected a bytes-like object, "[](#l17.17) "%.80s found",[](#l17.18)
--- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -723,10 +723,10 @@ builtin_chr_impl(PyModuleDef *module, in } -static char * -source_as_string(PyObject *cmd, char *funcname, char *what, PyCompilerFlags *cf) +static const char * +source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, Py_buffer *view) {
- const char *str; Py_ssize_t size; if (PyUnicode_Check(cmd)) { @@ -735,19 +735,21 @@ source_as_string(PyObject *cmd, char *fu if (str == NULL) return NULL; }
- else if (PyObject_GetBuffer(cmd, view, PyBUF_SIMPLE) == 0) {
str = (const char *)view->buf;[](#l18.23)
size = view->len;[](#l18.24)
- }
- else { PyErr_Format(PyExc_TypeError, "%s() arg 1 must be a %s object", funcname, what); return NULL; }
- if (strlen(str) != (size_t)size) { PyErr_SetString(PyExc_ValueError, "source code string cannot contain null bytes");
} return str; @@ -827,7 +829,8 @@ static PyObject * builtin_compile_impl(PyModuleDef *module, PyObject *source, PyObject filename, const char mode, int flags, int dont_inherit, int optimize) /[clinic end generated code: output=c72d197809d178fc input=c6212a9d21472f7e]/ {PyBuffer_Release(view);[](#l18.41) return NULL;[](#l18.42)
- Py_buffer view = {NULL, NULL};
- const char *str; int compile_mode = -1; int is_ast; PyCompilerFlags cf; @@ -898,11 +901,12 @@ builtin_compile_impl(PyModuleDef *module goto finally; }
- str = source_as_string(source, "compile", "string, bytes or AST", &cf, &view); if (str == NULL) goto error;
result = Py_CompileStringObject(str, filename, start[compile_mode], &cf, optimize);
- PyBuffer_Release(&view); goto finally; error: @@ -1042,7 +1046,8 @@ builtin_eval_impl(PyModuleDef module, P /[clinic end generated code: output=644fd59012538ce6 input=31e42c1d2125b50b]*/ { PyObject *result, *tmp = NULL;
- Py_buffer view = {NULL, NULL};
- const char *str; PyCompilerFlags cf; if (locals != Py_None && !PyMapping_Check(locals)) { @@ -1089,7 +1094,7 @@ builtin_eval_impl(PyModuleDef *module, P } cf.cf_flags = PyCF_SOURCE_IS_UTF8;
- str = source_as_string(source, "eval", "string, bytes or code", &cf, &view); if (str == NULL) return NULL;
@@ -1098,6 +1103,7 @@ builtin_eval_impl(PyModuleDef *module, P (void)PyEval_MergeCompilerFlags(&cf); result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf);
@@ -1204,11 +1210,12 @@ builtin_exec_impl(PyModuleDef *module, P v = PyEval_EvalCode(source, globals, locals); } else {
char *str;[](#l18.100)
Py_buffer view = {NULL, NULL};[](#l18.101)
const char *str;[](#l18.102) PyCompilerFlags cf;[](#l18.103) cf.cf_flags = PyCF_SOURCE_IS_UTF8;[](#l18.104) str = source_as_string(source, "exec",[](#l18.105)
"string, bytes or code", &cf);[](#l18.106)
"string, bytes or code", &cf, &view);[](#l18.107) if (str == NULL)[](#l18.108) return NULL;[](#l18.109) if (PyEval_MergeCompilerFlags(&cf))[](#l18.110)
@@ -1216,6 +1223,7 @@ builtin_exec_impl(PyModuleDef *module, P locals, &cf); else v = PyRun_String(str, Py_file_input, globals, locals);