summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2015-02-02 23:25:42 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2015-02-02 23:25:42 (GMT)
commit3dd3e26680110b3eeadedc9c8457dfe1db2b913c (patch)
tree584a98eda6e93033ddaf313b95826e6e3cd887cb /Objects
parent0b2a6dc42b9bf02408764133a8dfcd843bbd0e66 (diff)
parent4fdb68491e8b2d044c9173babf625bbb815c39d1 (diff)
downloadcpython-3dd3e26680110b3eeadedc9c8457dfe1db2b913c.zip
cpython-3dd3e26680110b3eeadedc9c8457dfe1db2b913c.tar.gz
cpython-3dd3e26680110b3eeadedc9c8457dfe1db2b913c.tar.bz2
Issue #22896: Avoid to use PyObject_AsCharBuffer(), PyObject_AsReadBuffer()
and PyObject_AsWriteBuffer().
Diffstat (limited to 'Objects')
-rw-r--r--Objects/abstract.c80
-rw-r--r--Objects/bytearrayobject.c142
-rw-r--r--Objects/bytes_methods.c46
-rw-r--r--Objects/bytesobject.c262
-rw-r--r--Objects/complexobject.c9
-rw-r--r--Objects/exceptions.c30
-rw-r--r--Objects/floatobject.c8
-rw-r--r--Objects/stringlib/join.h9
8 files changed, 282 insertions, 304 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index d7dde91..483f4da 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -250,27 +250,7 @@ PyObject_AsCharBuffer(PyObject *obj,
const char **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) {
- PyErr_SetString(PyExc_TypeError,
- "expected a bytes-like object");
- return -1;
- }
- 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);
- Py_XDECREF(view.obj);
- return 0;
+ return PyObject_AsReadBuffer(obj, (const void **)buffer, buffer_len);
}
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) {
- PyErr_SetString(PyExc_TypeError,
- "expected a bytes-like object");
+ if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0)
return -1;
- }
-
- 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);
- Py_XDECREF(view.obj);
+ PyBuffer_Release(&view);
return 0;
}
@@ -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);
- Py_XDECREF(view.obj);
+ PyBuffer_Release(&view);
return 0;
}
@@ -352,13 +320,15 @@ int PyObject_AsWriteBuffer(PyObject *obj,
int
PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
{
- if (!PyObject_CheckBuffer(obj)) {
+ PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
+
+ 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;
}
- return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags);
+ return (*pb->bf_getbuffer)(obj, view, flags);
}
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);
- Py_XDECREF(obj);
+ PyBufferProcs *pb;
+ if (obj == NULL)
+ return;
+ pb = Py_TYPE(obj)->tp_as_buffer;
+ if (pb && pb->bf_releasebuffer)
+ pb->bf_releasebuffer(obj, view);
view->obj = NULL;
+ Py_DECREF(obj);
}
PyObject *
@@ -1288,8 +1262,7 @@ PyNumber_Long(PyObject *o)
{
PyNumberMethods *m;
PyObject *trunc_func;
- const char *buffer;
- Py_ssize_t buffer_len;
+ Py_buffer view;
_Py_IDENTIFIER(__trunc__);
if (o == NULL)
@@ -1327,21 +1300,22 @@ PyNumber_Long(PyObject *o)
if (PyErr_Occurred())
return NULL;
- if (PyBytes_Check(o))
+ if (PyUnicode_Check(o))
+ /* The below check is done in PyLong_FromUnicode(). */
+ return PyLong_FromUnicodeObject(o, 10);
+
+ 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),
- PyBytes_GET_SIZE(o), 10);
- if (PyUnicode_Check(o))
- /* The above check is done in PyLong_FromUnicode(). */
- return PyLong_FromUnicodeObject(o, 10);
- if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
- return _PyLong_FromBytes(buffer, buffer_len, 10);
+ PyObject *result = _PyLong_FromBytes(view.buf, view.len, 10);
+ PyBuffer_Release(&view);
+ return result;
+ }
- return type_error("int() argument must be a string or a "
- "number, not '%.200s'", o);
+ return type_error("int() argument must be a string, a bytes-like object "
+ "or a number, not '%.200s'", o);
}
PyObject *
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index b9a87d6..ce22f4b 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -80,24 +80,6 @@ bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
obj->ob_exports--;
}
-static Py_ssize_t
-_getbuffer(PyObject *obj, Py_buffer *view)
-{
- PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
-
- if (buffer == NULL || buffer->bf_getbuffer == NULL)
- {
- PyErr_Format(PyExc_TypeError,
- "a bytes-like object is required, not '%.100s'",
- Py_TYPE(obj)->tp_name);
- return -1;
- }
-
- if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
- return -1;
- return view->len;
-}
-
static int
_canresize(PyByteArrayObject *self)
{
@@ -268,8 +250,8 @@ PyByteArray_Concat(PyObject *a, PyObject *b)
va.len = -1;
vb.len = -1;
- if (_getbuffer(a, &va) < 0 ||
- _getbuffer(b, &vb) < 0) {
+ if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
+ PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
goto done;
@@ -335,7 +317,7 @@ bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Py_ssize_t size;
Py_buffer vo;
- if (_getbuffer(other, &vo) < 0) {
+ 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 *self, Py_ssize_t lo, Py_ssize_t hi,
needed = 0;
}
else {
- if (_getbuffer(values, &vbytes) < 0) {
- PyErr_Format(PyExc_TypeError,
- "can't set bytearray slice from %.100s",
- Py_TYPE(values)->tp_name);
- return -1;
- }
- needed = vbytes.len;
- bytes = vbytes.buf;
+ if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
+ PyErr_Format(PyExc_TypeError,
+ "can't set bytearray slice from %.100s",
+ Py_TYPE(values)->tp_name);
+ return -1;
+ }
+ needed = vbytes.len;
+ bytes = vbytes.buf;
}
if (lo < 0)
@@ -1047,18 +1029,18 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op)
Py_RETURN_NOTIMPLEMENTED;
}
- self_size = _getbuffer(self, &self_bytes);
- if (self_size < 0) {
+ if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
PyErr_Clear();
Py_RETURN_NOTIMPLEMENTED;
}
+ self_size = self_bytes.len;
- other_size = _getbuffer(other, &other_bytes);
- if (other_size < 0) {
+ 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(PyByteArrayObject *self, PyObject *args, int dir)
return -2;
if (subobj) {
- if (_getbuffer(subobj, &subbuf) < 0)
+ if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)
return -2;
sub = subbuf.buf;
@@ -1238,7 +1220,7 @@ bytearray_count(PyByteArrayObject *self, PyObject *args)
return NULL;
if (sub_obj) {
- if (_getbuffer(sub_obj, &vsub) < 0)
+ if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)
return NULL;
sub = vsub.buf;
@@ -1397,7 +1379,7 @@ bytearray_contains(PyObject *self, PyObject *arg)
Py_buffer varg;
Py_ssize_t pos;
PyErr_Clear();
- if (_getbuffer(arg, &varg) < 0)
+ if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
return -1;
pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
varg.buf, varg.len, 0);
@@ -1428,7 +1410,7 @@ _bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start
str = PyByteArray_AS_STRING(self);
- if (_getbuffer(substr, &vsubstr) < 0)
+ if (PyObject_GetBuffer(substr, &vsubstr, PyBUF_SIMPLE) != 0)
return -1;
ADJUST_INDICES(start, end, len);
@@ -1621,7 +1603,7 @@ bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, int group_rig
if (table == Py_None) {
table_chars = NULL;
table = NULL;
- } else if (_getbuffer(table, &vtable) < 0) {
+ } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
return NULL;
} else {
if (vtable.len != 256) {
@@ -1634,7 +1616,7 @@ bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, int group_rig
}
if (deletechars != NULL) {
- if (_getbuffer(deletechars, &vdel) < 0) {
+ if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
if (table != NULL)
PyBuffer_Release(&vtable);
return NULL;
@@ -1699,8 +1681,8 @@ done:
@staticmethod
bytearray.maketrans
- frm: object
- to: object
+ 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;
- PyObject *frm;
- PyObject *to;
+ Py_buffer frm = {NULL, NULL};
+ Py_buffer to = {NULL, NULL};
- if (!PyArg_UnpackTuple(args, "maketrans",
- 2, 2,
+ if (!PyArg_ParseTuple(args,
+ "y*y*:maketrans",
&frm, &to))
goto exit;
- return_value = bytearray_maketrans_impl(frm, to);
+ return_value = bytearray_maketrans_impl(&frm, &to);
exit:
+ /* Cleanup for frm */
+ if (frm.obj)
+ PyBuffer_Release(&frm);
+ /* Cleanup for to */
+ if (to.obj)
+ PyBuffer_Release(&to);
+
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: object
- new: object
+ 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;
- PyObject *old;
- PyObject *new;
+ Py_buffer old = {NULL, NULL};
+ Py_buffer new = {NULL, NULL};
Py_ssize_t count = -1;
if (!PyArg_ParseTuple(args,
- "OO|n:replace",
+ "y*y*|n:replace",
&old, &new, &count))
goto exit;
- return_value = bytearray_replace_impl(self, old, new, count);
+ return_value = bytearray_replace_impl(self, &old, &new, count);
exit:
+ /* Cleanup for old */
+ if (old.obj)
+ PyBuffer_Release(&old);
+ /* Cleanup for new */
+ if (new.obj)
+ PyBuffer_Release(&new);
+
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]*/
{
- PyObject *res;
- Py_buffer vold, vnew;
-
- if (_getbuffer(old, &vold) < 0)
- return NULL;
- if (_getbuffer(new, &vnew) < 0) {
- PyBuffer_Release(&vold);
- return NULL;
- }
-
- res = (PyObject *)replace((PyByteArrayObject *) self,
- vold.buf, vold.len,
- vnew.buf, vnew.len, count);
-
- PyBuffer_Release(&vold);
- PyBuffer_Release(&vnew);
- return res;
+ return (PyObject *)replace((PyByteArrayObject *) self,
+ old->buf, old->len,
+ new->buf, new->len, count);
}
/*[clinic input]
@@ -2383,7 +2365,7 @@ bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit
if (sep == Py_None)
return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
- if (_getbuffer(sep, &vsub) < 0)
+ if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
return NULL;
sub = vsub.buf;
n = vsub.len;
@@ -2566,7 +2548,7 @@ bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxspli
if (sep == Py_None)
return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
- if (_getbuffer(sep, &vsub) < 0)
+ if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
return NULL;
sub = vsub.buf;
n = vsub.len;
@@ -3088,7 +3070,7 @@ bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
byteslen = 6;
}
else {
- if (_getbuffer(bytes, &vbytes) < 0)
+ if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
return NULL;
bytesptr = (char *) vbytes.buf;
byteslen = vbytes.len;
@@ -3159,7 +3141,7 @@ bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
byteslen = 6;
}
else {
- if (_getbuffer(bytes, &vbytes) < 0)
+ if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
return NULL;
bytesptr = (char *) vbytes.buf;
byteslen = vbytes.len;
@@ -3227,7 +3209,7 @@ bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
byteslen = 6;
}
else {
- if (_getbuffer(bytes, &vbytes) < 0)
+ if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
return NULL;
bytesptr = (char *) vbytes.buf;
byteslen = vbytes.len;
diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c
index 1cf20c9..a299915 100644
--- a/Objects/bytes_methods.c
+++ b/Objects/bytes_methods.c
@@ -363,59 +363,27 @@ for use in the bytes or bytearray translate method where each byte\n\
in frm is mapped to the byte at the same position in to.\n\
The bytes objects frm and to must be of the same length.");
-static Py_ssize_t
-_getbuffer(PyObject *obj, Py_buffer *view)
-{
- PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
-
- if (buffer == NULL || buffer->bf_getbuffer == NULL)
- {
- PyErr_Format(PyExc_TypeError,
- "a bytes-like object is required, not '%.100s'",
- Py_TYPE(obj)->tp_name);
- return -1;
- }
-
- if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
- return -1;
- return view->len;
-}
-
PyObject *
-_Py_bytes_maketrans(PyObject *frm, PyObject *to)
+_Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to)
{
PyObject *res = NULL;
- Py_buffer bfrm, bto;
Py_ssize_t i;
char *p;
- bfrm.len = -1;
- bto.len = -1;
-
- if (_getbuffer(frm, &bfrm) < 0)
- return NULL;
- if (_getbuffer(to, &bto) < 0)
- goto done;
- if (bfrm.len != bto.len) {
+ if (frm->len != to->len) {
PyErr_Format(PyExc_ValueError,
"maketrans arguments must have same length");
- goto done;
+ return NULL;
}
res = PyBytes_FromStringAndSize(NULL, 256);
- if (!res) {
- goto done;
- }
+ if (!res)
+ return NULL;
p = PyBytes_AS_STRING(res);
for (i = 0; i < 256; i++)
p[i] = (char) i;
- for (i = 0; i < bfrm.len; i++) {
- p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i];
+ for (i = 0; i < frm->len; i++) {
+ p[((unsigned char *)frm->buf)[i]] = ((char *)to->buf)[i];
}
-done:
- if (bfrm.len != -1)
- PyBuffer_Release(&bfrm);
- if (bto.len != -1)
- PyBuffer_Release(&bto);
return res;
}
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index d4f7d01..b2fbc92 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -12,33 +12,6 @@ class bytes "PyBytesObject*" "&PyBytes_Type"
[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 */
- Py_INCREF(obj);
- view->obj = obj;
- view->buf = PyBytes_AS_STRING(obj);
- view->len = PyBytes_GET_SIZE(obj);
- return view->len;
- }
-
- bufferprocs = Py_TYPE(obj)->tp_as_buffer;
- if (bufferprocs == NULL || bufferprocs->bf_getbuffer == NULL)
- {
- PyErr_Format(PyExc_TypeError,
- "a bytes-like object is required, not '%.100s'",
- Py_TYPE(obj)->tp_name);
- return -1;
- }
-
- if (bufferprocs->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
- return -1;
- return view->len;
-}
-
#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 (_getbuffer(a, &va) < 0 ||
- _getbuffer(b, &vb) < 0) {
+ if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
+ PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
goto done;
@@ -1448,7 +1421,7 @@ bytes_contains(PyObject *self, PyObject *arg)
Py_buffer varg;
Py_ssize_t pos;
PyErr_Clear();
- if (_getbuffer(arg, &varg) < 0)
+ if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
return -1;
pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self),
varg.buf, varg.len, 0);
@@ -1737,7 +1710,7 @@ bytes_split_impl(PyBytesObject*self, PyObject *sep, Py_ssize_t maxsplit)
maxsplit = PY_SSIZE_T_MAX;
if (sep == Py_None)
return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
- if (_getbuffer(sep, &vsub) < 0)
+ 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, PyObject *sep, Py_ssize_t maxsplit)
bytes.partition
self: self(type="PyBytesObject *")
- sep: object
+ 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 \
- {"partition", (PyCFunction)bytes_partition, METH_O, bytes_partition__doc__},
+ {"partition", (PyCFunction)bytes_partition, METH_VARARGS, bytes_partition__doc__},
static PyObject *
-bytes_partition(PyBytesObject *self, PyObject *sep)
-/*[clinic end generated code: output=b41e119c873c08bc input=6c5b9dcc5a9fd62e]*/
+bytes_partition_impl(PyBytesObject *self, Py_buffer *sep);
+
+static PyObject *
+bytes_partition(PyBytesObject *self, PyObject *args)
{
- const char *sep_chars;
- Py_ssize_t sep_len;
+ PyObject *return_value = NULL;
+ Py_buffer sep = {NULL, NULL};
- if (PyBytes_Check(sep)) {
- sep_chars = PyBytes_AS_STRING(sep);
- sep_len = PyBytes_GET_SIZE(sep);
- }
- else if (PyObject_AsCharBuffer(sep, &sep_chars, &sep_len))
- return NULL;
+ if (!PyArg_ParseTuple(args,
+ "y*:partition",
+ &sep))
+ goto exit;
+ return_value = bytes_partition_impl(self, &sep);
+
+exit:
+ /* Cleanup for sep */
+ if (sep.obj)
+ PyBuffer_Release(&sep);
+ return return_value;
+}
+
+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
+ sep->obj, (const char *)sep->buf, sep->len
);
}
@@ -1805,7 +1791,7 @@ bytes_partition(PyBytesObject *self, PyObject *sep)
bytes.rpartition
self: self(type="PyBytesObject *")
- sep: object
+ 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 \
- {"rpartition", (PyCFunction)bytes_rpartition, METH_O, bytes_rpartition__doc__},
+ {"rpartition", (PyCFunction)bytes_rpartition, METH_VARARGS, bytes_rpartition__doc__},
static PyObject *
-bytes_rpartition(PyBytesObject *self, PyObject *sep)
-/*[clinic end generated code: output=3a620803657196ee input=79bc2932e78e5ce0]*/
+bytes_rpartition_impl(PyBytesObject *self, Py_buffer *sep);
+
+static PyObject *
+bytes_rpartition(PyBytesObject *self, PyObject *args)
{
- const char *sep_chars;
- Py_ssize_t sep_len;
+ PyObject *return_value = NULL;
+ Py_buffer sep = {NULL, NULL};
- if (PyBytes_Check(sep)) {
- sep_chars = PyBytes_AS_STRING(sep);
- sep_len = PyBytes_GET_SIZE(sep);
- }
- else if (PyObject_AsCharBuffer(sep, &sep_chars, &sep_len))
- return NULL;
+ if (!PyArg_ParseTuple(args,
+ "y*:rpartition",
+ &sep))
+ goto exit;
+ return_value = bytes_rpartition_impl(self, &sep);
+
+exit:
+ /* Cleanup for sep */
+ if (sep.obj)
+ PyBuffer_Release(&sep);
+ return return_value;
+}
+
+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
+ sep->obj, (const char *)sep->buf, sep->len
);
}
@@ -1916,7 +1915,7 @@ bytes_rsplit_impl(PyBytesObject*self, PyObject *sep, Py_ssize_t maxsplit)
maxsplit = PY_SSIZE_T_MAX;
if (sep == Py_None)
return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
- if (_getbuffer(sep, &vsub) < 0)
+ 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, PyObject *args, int dir)
return -2;
if (subobj) {
- if (_getbuffer(subobj, &subbuf) < 0)
+ if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)
return -2;
sub = subbuf.buf;
@@ -2118,7 +2117,7 @@ do_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj)
Py_ssize_t seplen;
Py_ssize_t i, j;
- if (_getbuffer(sepobj, &vsep) < 0)
+ if (PyObject_GetBuffer(sepobj, &vsep, PyBUF_SIMPLE) != 0)
return NULL;
sep = vsep.buf;
seplen = vsep.len;
@@ -2360,7 +2359,7 @@ bytes_count(PyBytesObject *self, PyObject *args)
return NULL;
if (sub_obj) {
- if (_getbuffer(sub_obj, &vsub) < 0)
+ if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)
return NULL;
sub = vsub.buf;
@@ -2450,6 +2449,8 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, Py
/*[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, PyObject *table, int group_right_1, Py
table_chars = NULL;
tablen = 256;
}
- else if (PyObject_AsCharBuffer(table, &table_chars, &tablen))
- return NULL;
+ else {
+ if (PyObject_GetBuffer(table, &table_view, PyBUF_SIMPLE) != 0)
+ return NULL;
+ table_chars = table_view.buf;
+ tablen = table_view.len;
+ }
if (tablen != 256) {
PyErr_SetString(PyExc_ValueError,
"translation table must be 256 characters long");
+ PyBuffer_Release(&table_view);
return NULL;
}
@@ -2480,8 +2486,14 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, Py
del_table_chars = PyBytes_AS_STRING(deletechars);
dellen = PyBytes_GET_SIZE(deletechars);
}
- else if (PyObject_AsCharBuffer(deletechars, &del_table_chars, &dellen))
- return NULL;
+ else {
+ if (PyObject_GetBuffer(deletechars, &del_table_view, PyBUF_SIMPLE) != 0) {
+ PyBuffer_Release(&table_view);
+ return NULL;
+ }
+ del_table_chars = del_table_view.buf;
+ dellen = del_table_view.len;
+ }
}
else {
del_table_chars = NULL;
@@ -2490,8 +2502,11 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, Py
inlen = PyBytes_GET_SIZE(input_obj);
result = PyBytes_FromStringAndSize((char *)NULL, inlen);
- if (result == NULL)
+ if (result == NULL) {
+ PyBuffer_Release(&del_table_view);
+ PyBuffer_Release(&table_view);
return NULL;
+ }
output_start = output = PyBytes_AsString(result);
input = PyBytes_AS_STRING(input_obj);
@@ -2502,11 +2517,14 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, Py
if (Py_CHARMASK((*output++ = table_chars[c])) != c)
changed = 1;
}
- if (changed || !PyBytes_CheckExact(input_obj))
- return result;
- Py_DECREF(result);
- Py_INCREF(input_obj);
- return input_obj;
+ if (!changed && PyBytes_CheckExact(input_obj)) {
+ Py_INCREF(input_obj);
+ Py_DECREF(result);
+ result = input_obj;
+ }
+ PyBuffer_Release(&del_table_view);
+ PyBuffer_Release(&table_view);
+ return result;
}
if (table_chars == NULL) {
@@ -2516,9 +2534,11 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, Py
for (i = 0; i < 256; i++)
trans_table[i] = Py_CHARMASK(table_chars[i]);
}
+ PyBuffer_Release(&table_view);
for (i = 0; i < dellen; i++)
trans_table[(int) Py_CHARMASK(del_table_chars[i])] = -1;
+ PyBuffer_Release(&del_table_view);
for (i = inlen; --i >= 0; ) {
c = Py_CHARMASK(*input++);
@@ -2544,8 +2564,8 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, Py
@staticmethod
bytes.maketrans
- frm: object
- to: object
+ 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;
- PyObject *frm;
- PyObject *to;
+ Py_buffer frm = {NULL, NULL};
+ Py_buffer to = {NULL, NULL};
- if (!PyArg_UnpackTuple(args, "maketrans",
- 2, 2,
+ if (!PyArg_ParseTuple(args,
+ "y*y*:maketrans",
&frm, &to))
goto exit;
- return_value = bytes_maketrans_impl(frm, to);
+ return_value = bytes_maketrans_impl(&frm, &to);
exit:
+ /* Cleanup for frm */
+ if (frm.obj)
+ PyBuffer_Release(&frm);
+ /* Cleanup for to */
+ if (to.obj)
+ PyBuffer_Release(&to);
+
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: object
- new: object
+ 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(PyBytesObject*self, PyObject *old, PyObject *new, Py_ssize_t count);
+bytes_replace_impl(PyBytesObject*self, Py_buffer *old, Py_buffer *new, Py_ssize_t count);
static PyObject *
bytes_replace(PyBytesObject*self, PyObject *args)
{
PyObject *return_value = NULL;
- PyObject *old;
- PyObject *new;
+ Py_buffer old = {NULL, NULL};
+ Py_buffer new = {NULL, NULL};
Py_ssize_t count = -1;
if (!PyArg_ParseTuple(args,
- "OO|n:replace",
+ "y*y*|n:replace",
&old, &new, &count))
goto exit;
- return_value = bytes_replace_impl(self, old, new, count);
+ return_value = bytes_replace_impl(self, &old, &new, count);
exit:
+ /* Cleanup for old */
+ if (old.obj)
+ PyBuffer_Release(&old);
+ /* Cleanup for new */
+ if (new.obj)
+ PyBuffer_Release(&new);
+
return return_value;
}
static PyObject *
-bytes_replace_impl(PyBytesObject*self, 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]*/
{
- const char *old_s, *new_s;
- Py_ssize_t old_len, new_len;
-
- if (PyBytes_Check(old)) {
- old_s = PyBytes_AS_STRING(old);
- old_len = PyBytes_GET_SIZE(old);
- }
- else if (PyObject_AsCharBuffer(old, &old_s, &old_len))
- return NULL;
-
- if (PyBytes_Check(new)) {
- new_s = PyBytes_AS_STRING(new);
- new_len = PyBytes_GET_SIZE(new);
- }
- else if (PyObject_AsCharBuffer(new, &new_s, &new_len))
- return NULL;
-
return (PyObject *)replace((PyBytesObject *) self,
- old_s, old_len,
- new_s, new_len, count);
+ (const char *)old->buf, old->len,
+ (const char *)new->buf, new->len, count);
}
/** End DALKE **/
@@ -3181,6 +3198,7 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start,
{
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 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start,
sub = PyBytes_AS_STRING(substr);
slen = PyBytes_GET_SIZE(substr);
}
- else if (PyObject_AsCharBuffer(substr, &sub, &slen))
- return -1;
+ else {
+ if (PyObject_GetBuffer(substr, &sub_view, PyBUF_SIMPLE) != 0)
+ return -1;
+ sub = sub_view.buf;
+ slen = sub_view.len;
+ }
str = PyBytes_AS_STRING(self);
ADJUST_INDICES(start, end, len);
@@ -3197,17 +3219,25 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start,
if (direction < 0) {
/* startswith */
if (start+slen > len)
- return 0;
+ goto notfound;
} else {
/* endswith */
if (end-start < slen || start > len)
- return 0;
+ goto notfound;
if (end-slen > start)
start = end - slen;
}
- if (end-start >= slen)
- return ! memcmp(str+start, sub, slen);
+ if (end-start < slen)
+ goto notfound;
+ if (memcmp(str+start, sub, slen) != 0)
+ goto notfound;
+
+ PyBuffer_Release(&sub_view);
+ return 1;
+
+notfound:
+ PyBuffer_Release(&sub_view);
return 0;
}
@@ -3978,7 +4008,7 @@ PyBytes_Concat(PyObject **pv, PyObject *w)
Py_buffer wb;
wb.len = -1;
- if (_getbuffer(w, &wb) < 0) {
+ if (PyObject_GetBuffer(w, &wb, PyBUF_SIMPLE) != 0) {
PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
Py_TYPE(w)->tp_name, Py_TYPE(*pv)->tp_name);
Py_CLEAR(*pv);
diff --git a/Objects/complexobject.c b/Objects/complexobject.c
index 7e2e88a..dc1212e 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -767,6 +767,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
int got_bracket=0;
PyObject *s_buffer = NULL;
Py_ssize_t len;
+ Py_buffer view = {NULL, NULL};
if (PyUnicode_Check(v)) {
s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v);
@@ -776,7 +777,11 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
if (s == NULL)
goto error;
}
- else if (PyObject_AsCharBuffer(v, &s, &len)) {
+ else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) {
+ s = (const char *)view.buf;
+ len = view.len;
+ }
+ 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 *type, PyObject *v)
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 *type, PyObject *v)
PyErr_SetString(PyExc_ValueError,
"complex() arg is a malformed string");
error:
+ PyBuffer_Release(&view);
Py_XDECREF(s_buffer);
return NULL;
}
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index 5532821..e09d384 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -1922,8 +1922,6 @@ static int
UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyUnicodeErrorObject *ude;
- const char *data;
- Py_ssize_t size;
if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
return -1;
@@ -1944,21 +1942,27 @@ UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
return -1;
}
- if (!PyBytes_Check(ude->object)) {
- if (PyObject_AsReadBuffer(ude->object, (const void **)&data, &size)) {
- ude->encoding = ude->object = ude->reason = NULL;
- return -1;
- }
- ude->object = PyBytes_FromStringAndSize(data, size);
- }
- else {
- Py_INCREF(ude->object);
- }
-
Py_INCREF(ude->encoding);
+ Py_INCREF(ude->object);
Py_INCREF(ude->reason);
+ if (!PyBytes_Check(ude->object)) {
+ Py_buffer view;
+ if (PyObject_GetBuffer(ude->object, &view, PyBUF_SIMPLE) != 0)
+ goto error;
+ Py_CLEAR(ude->object);
+ ude->object = PyBytes_FromStringAndSize(view.buf, view.len);
+ PyBuffer_Release(&view);
+ if (!ude->object)
+ goto error;
+ }
return 0;
+
+error:
+ Py_CLEAR(ude->encoding);
+ Py_CLEAR(ude->object);
+ Py_CLEAR(ude->reason);
+ return -1;
}
static PyObject *
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index dceb55e..8d85121 100644
--- 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_AsCharBuffer(v, &s, &len)) {
+ else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) {
+ s = (const char *)view.buf;
+ len = view.len;
+ }
+ 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);
+ PyBuffer_Release(&view);
Py_XDECREF(s_buffer);
return result;
}
diff --git a/Objects/stringlib/join.h b/Objects/stringlib/join.h
index 35eb984..cbf81be 100644
--- a/Objects/stringlib/join.h
+++ b/Objects/stringlib/join.h
@@ -58,7 +58,14 @@ STRINGLIB(bytes_join)(PyObject *sep, PyObject *iterable)
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) {
+ if (PyBytes_CheckExact(item)) {
+ /* Fast path. */
+ Py_INCREF(item);
+ buffers[i].obj = item;
+ buffers[i].buf = PyBytes_AS_STRING(item);
+ buffers[i].len = PyBytes_GET_SIZE(item);
+ }
+ else if (PyObject_GetBuffer(item, &buffers[i], PyBUF_SIMPLE) != 0) {
PyErr_Format(PyExc_TypeError,
"sequence item %zd: expected a bytes-like object, "
"%.80s found",