and PyObject_AsWriteBuffer().
extern void _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len);
extern void _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len);
-/* This one gets the raw argument list. */
-extern PyObject* _Py_bytes_maketrans(PyObject *args);
+/* 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__[];
"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)
{
- void *raw_buffer;
+ Py_buffer buffer;
Py_ssize_t len, n;
- CHECK_CLOSED(self);
+ CHECK_CLOSED(self, NULL);
- if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &len) == -1)
+ if (!PyArg_Parse(arg, "w*", &buffer))
return NULL;
/* adjust invalid sizes */
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,
- "'%.100s' does not support the buffer interface",
+ "a bytes-like object is required, not '%.100s'",
Py_TYPE(obj)->tp_name);
return -1;
}
Py_ssize_t inlen;
PyObject *result = NULL;
int trans_table[256];
- PyObject *tableobj = NULL, *delobj = NULL;
Py_buffer vtable, vdel;
- if (!PyArg_UnpackTuple(args, "translate", 1, 2,
- &tableobj, &delobj))
- return NULL;
-
- if (tableobj == Py_None) {
+ if (table == Py_None) {
+ table_chars = NULL;
table = NULL;
- } else if (_getbuffer(table, &vtable) < 0) {
- tableobj = NULL;
- } else if (PyObject_GetBuffer(tableobj, &vtable, PyBUF_SIMPLE) != 0) {
++ } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
return NULL;
} else {
if (vtable.len != 256) {
PyBuffer_Release(&vtable);
return NULL;
}
- table = (const char*)vtable.buf;
+ table_chars = (const char*)vtable.buf;
}
- if (delobj != NULL) {
- if (PyObject_GetBuffer(delobj, &vdel, PyBUF_SIMPLE) != 0) {
- if (tableobj != NULL)
+ if (deletechars != NULL) {
- if (_getbuffer(deletechars, &vdel) < 0) {
++ if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
+ if (table != NULL)
PyBuffer_Release(&vtable);
return NULL;
}
}
- frm: object
- to: object
+/*[clinic input]
+
+@staticmethod
+bytearray.maketrans
+
- bytearray_maketrans_impl(PyObject *frm, PyObject *to);
++ frm: Py_buffer
++ to: Py_buffer
+ /
+
+Return a translation table useable for the bytes or bytearray translate method.
+
+The returned table will be one where each byte in frm is mapped to the byte at
+the same position in to.
+
+The bytes objects frm and to must be of the same length.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(bytearray_maketrans__doc__,
+"maketrans(frm, to, /)\n"
+"--\n"
+"\n"
+"Return a translation table useable for the bytes or bytearray translate method.\n"
+"\n"
+"The returned table will be one where each byte in frm is mapped to the byte at\n"
+"the same position in to.\n"
+"\n"
+"The bytes objects frm and to must be of the same length.");
+
+#define BYTEARRAY_MAKETRANS_METHODDEF \
+ {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC, bytearray_maketrans__doc__},
+
+static PyObject *
++bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to);
+
static PyObject *
-bytearray_maketrans(PyObject *null, PyObject *args)
+bytearray_maketrans(void *null, PyObject *args)
{
- return _Py_bytes_maketrans(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);
}
}
-PyDoc_STRVAR(replace__doc__,
-"B.replace(old, new[, count]) -> bytearray\n\
-\n\
-Return a copy of B with all occurrences of subsection\n\
-old replaced by new. If the optional argument count is\n\
-given, only the first count occurrences are replaced.");
+/*[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.
+ /
+
+Return a copy with all occurrences of substring old replaced by new.
+
+If the optional argument count is given, only the first count occurrences are
+replaced.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(bytearray_replace__doc__,
+"replace($self, old, new, count=-1, /)\n"
+"--\n"
+"\n"
+"Return a copy with all occurrences of substring old replaced by new.\n"
+"\n"
+" count\n"
+" Maximum number of occurrences to replace.\n"
+" -1 (the default value) means replace all occurrences.\n"
+"\n"
+"If the optional argument count is given, only the first count occurrences are\n"
+"replaced.");
+
+#define BYTEARRAY_REPLACE_METHODDEF \
+ {"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 *res;
+ 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, "y*y*|n:replace", &old, &new, &count))
- return NULL;
+ 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);
- res = (PyObject *)replace((PyByteArrayObject *) self,
- (const char *)old.buf, old.len,
- (const char *)new.buf, new.len, count);
+exit:
++ /* Cleanup for old */
++ if (old.obj)
++ PyBuffer_Release(&old);
++ /* Cleanup for new */
++ if (new.obj)
++ PyBuffer_Release(&new);
+
- PyBuffer_Release(&old);
- PyBuffer_Release(&new);
- return res;
+ return return_value;
}
-PyDoc_STRVAR(split__doc__,
-"B.split(sep=None, maxsplit=-1) -> list of bytearrays\n\
-\n\
-Return a list of the sections in B, using sep as the delimiter.\n\
-If sep is not given, B is split on ASCII whitespace characters\n\
-(space, tab, return, newline, formfeed, vertical tab).\n\
-If maxsplit is given, at most maxsplit splits are done.");
+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]
+bytearray.split
+
+ sep: object = None
+ The delimiter according which to split the bytearray.
+ None (the default value) means split on ASCII whitespace characters
+ (space, tab, return, newline, formfeed, vertical tab).
+ maxsplit: Py_ssize_t = -1
+ Maximum number of splits to do.
+ -1 (the default value) means no limit.
+
+Return a list of the sections in the bytearray, using sep as the delimiter.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(bytearray_split__doc__,
+"split($self, /, sep=None, maxsplit=-1)\n"
+"--\n"
+"\n"
+"Return a list of the sections in the bytearray, using sep as the delimiter.\n"
+"\n"
+" sep\n"
+" The delimiter according which to split the bytearray.\n"
+" None (the default value) means split on ASCII whitespace characters\n"
+" (space, tab, return, newline, formfeed, vertical tab).\n"
+" maxsplit\n"
+" Maximum number of splits to do.\n"
+" -1 (the default value) means no limit.");
+
+#define BYTEARRAY_SPLIT_METHODDEF \
+ {"split", (PyCFunction)bytearray_split, METH_VARARGS|METH_KEYWORDS, bytearray_split__doc__},
static PyObject *
-bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
+bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit);
+
+static PyObject *
+bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwargs)
{
- static char *kwlist[] = {"sep", "maxsplit", 0};
- Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
+ PyObject *return_value = NULL;
+ static char *_keywords[] = {"sep", "maxsplit", NULL};
+ PyObject *sep = Py_None;
Py_ssize_t maxsplit = -1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "|On:split", _keywords,
+ &sep, &maxsplit))
+ goto exit;
+ return_value = bytearray_split_impl(self, sep, maxsplit);
+
+exit:
+ return return_value;
+}
+
+static PyObject *
+bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit)
+/*[clinic end generated code: output=062a3d87d6f918fa input=24f82669f41bf523]*/
+{
+ Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
const char *s = PyByteArray_AS_STRING(self), *sub;
- PyObject *list, *subobj = Py_None;
+ PyObject *list;
Py_buffer vsub;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split",
- kwlist, &subobj, &maxsplit))
- return NULL;
if (maxsplit < 0)
maxsplit = PY_SSIZE_T_MAX;
- if (subobj == Py_None)
+ if (sep == Py_None)
return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
- if (_getbuffer(sep, &vsub) < 0)
- if (PyObject_GetBuffer(subobj, &vsub, PyBUF_SIMPLE) != 0)
++ if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
return NULL;
sub = vsub.buf;
n = vsub.len;
if (maxsplit < 0)
maxsplit = PY_SSIZE_T_MAX;
- if (subobj == Py_None)
+ if (sep == Py_None)
return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
- if (_getbuffer(sep, &vsub) < 0)
- if (PyObject_GetBuffer(subobj, &vsub, PyBUF_SIMPLE) != 0)
++ if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
return NULL;
sub = vsub.buf;
n = vsub.len;
static PyObject *
bytearray_strip(PyByteArrayObject *self, PyObject *args)
{
- Py_ssize_t left, right, mysize, argsize;
- char *myptr, *argptr;
- PyObject *arg = Py_None;
- Py_buffer varg;
- if (!PyArg_ParseTuple(args, "|O:strip", &arg))
- return NULL;
- if (arg == Py_None) {
- argptr = "\t\n\r\f\v ";
- argsize = 6;
+ PyObject *return_value = NULL;
+ PyObject *bytes = Py_None;
+
+ if (!PyArg_UnpackTuple(args, "strip",
+ 0, 1,
+ &bytes))
+ goto exit;
+ return_value = bytearray_strip_impl(self, bytes);
+
+exit:
+ return return_value;
+}
+
+static PyObject *
+bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
+/*[clinic end generated code: output=2e3d3358acc4c235 input=ef7bb59b09c21d62]*/
+{
+ Py_ssize_t left, right, mysize, byteslen;
+ char *myptr, *bytesptr;
+ Py_buffer vbytes;
+
+ if (bytes == Py_None) {
+ bytesptr = "\t\n\r\f\v ";
+ byteslen = 6;
}
else {
- if (_getbuffer(bytes, &vbytes) < 0)
- if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
++ if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
return NULL;
- argptr = (char *) varg.buf;
- argsize = varg.len;
+ bytesptr = (char *) vbytes.buf;
+ byteslen = vbytes.len;
}
myptr = PyByteArray_AS_STRING(self);
mysize = Py_SIZE(self);
static PyObject *
bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
{
- Py_ssize_t left, right, mysize, argsize;
- char *myptr, *argptr;
- PyObject *arg = Py_None;
- Py_buffer varg;
- if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
- return NULL;
- if (arg == Py_None) {
- argptr = "\t\n\r\f\v ";
- argsize = 6;
+ PyObject *return_value = NULL;
+ PyObject *bytes = Py_None;
+
+ if (!PyArg_UnpackTuple(args, "lstrip",
+ 0, 1,
+ &bytes))
+ goto exit;
+ return_value = bytearray_lstrip_impl(self, bytes);
+
+exit:
+ return return_value;
+}
+
+static PyObject *
+bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
+/*[clinic end generated code: output=2599309808a9ec02 input=80843f975dd7c480]*/
+{
+ Py_ssize_t left, right, mysize, byteslen;
+ char *myptr, *bytesptr;
+ Py_buffer vbytes;
+
+ if (bytes == Py_None) {
+ bytesptr = "\t\n\r\f\v ";
+ byteslen = 6;
}
else {
- if (_getbuffer(bytes, &vbytes) < 0)
- if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
++ if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
return NULL;
- argptr = (char *) varg.buf;
- argsize = varg.len;
+ bytesptr = (char *) vbytes.buf;
+ byteslen = vbytes.len;
}
myptr = PyByteArray_AS_STRING(self);
mysize = Py_SIZE(self);
static PyObject *
bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
{
- Py_ssize_t right, mysize, argsize;
- char *myptr, *argptr;
- PyObject *arg = Py_None;
- Py_buffer varg;
- if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
- return NULL;
- if (arg == Py_None) {
- argptr = "\t\n\r\f\v ";
- argsize = 6;
+ PyObject *return_value = NULL;
+ PyObject *bytes = Py_None;
+
+ if (!PyArg_UnpackTuple(args, "rstrip",
+ 0, 1,
+ &bytes))
+ goto exit;
+ return_value = bytearray_rstrip_impl(self, bytes);
+
+exit:
+ return return_value;
+}
+
+static PyObject *
+bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
+/*[clinic end generated code: output=b5ca6259f4f4f2a3 input=e728b994954cfd91]*/
+{
+ Py_ssize_t right, mysize, byteslen;
+ char *myptr, *bytesptr;
+ Py_buffer vbytes;
+
+ if (bytes == Py_None) {
+ bytesptr = "\t\n\r\f\v ";
+ byteslen = 6;
}
else {
- if (_getbuffer(bytes, &vbytes) < 0)
- if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
++ if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
return NULL;
- argptr = (char *) varg.buf;
- argsize = varg.len;
+ bytesptr = (char *) vbytes.buf;
+ byteslen = vbytes.len;
}
myptr = PyByteArray_AS_STRING(self);
mysize = Py_SIZE(self);
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(PyObject *args)
++_Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to)
{
PyObject *res = NULL;
- Py_buffer bfrm, bto;
- Py_buffer bfrm = {NULL, NULL};
- Py_buffer bto = {NULL, NULL};
Py_ssize_t i;
char *p;
-- bfrm.len = -1;
-- bto.len = -1;
--
- if (_getbuffer(frm, &bfrm) < 0)
- if (!PyArg_ParseTuple(args, "y*y*:maketrans", &bfrm, &bto))
-- 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)
- if (bfrm.obj != NULL)
-- PyBuffer_Release(&bfrm);
- if (bto.len != -1)
- if (bfrm.obj != NULL)
-- PyBuffer_Release(&bto);
return res;
}
#include "bytes_methods.h"
#include <stddef.h>
- 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;
- }
-
+/*[clinic input]
+class bytes "PyBytesObject*" "&PyBytes_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1a1d9102afc1b00c]*/
+
#ifdef COUNT_ALLOCS
Py_ssize_t null_strings, one_strings;
#endif
#define RIGHTSTRIP 1
#define BOTHSTRIP 2
-/* Arrays indexed by above */
-static const char *stripformat[] = {"|O:lstrip", "|O:rstrip", "|O:strip"};
+/*[clinic input]
+bytes.split
+
+ sep: object = None
+ The delimiter according which to split the bytes.
+ None (the default value) means split on ASCII whitespace characters
+ (space, tab, return, newline, formfeed, vertical tab).
+ maxsplit: Py_ssize_t = -1
+ Maximum number of splits to do.
+ -1 (the default value) means no limit.
+
+Return a list of the sections in the bytes, using sep as the delimiter.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(bytes_split__doc__,
+"split($self, /, sep=None, maxsplit=-1)\n"
+"--\n"
+"\n"
+"Return a list of the sections in the bytes, using sep as the delimiter.\n"
+"\n"
+" sep\n"
+" The delimiter according which to split the bytes.\n"
+" None (the default value) means split on ASCII whitespace characters\n"
+" (space, tab, return, newline, formfeed, vertical tab).\n"
+" maxsplit\n"
+" Maximum number of splits to do.\n"
+" -1 (the default value) means no limit.");
+
+#define BYTES_SPLIT_METHODDEF \
+ {"split", (PyCFunction)bytes_split, METH_VARARGS|METH_KEYWORDS, bytes_split__doc__},
-#define STRIPNAME(i) (stripformat[i]+3)
+static PyObject *
+bytes_split_impl(PyBytesObject*self, PyObject *sep, Py_ssize_t maxsplit);
-PyDoc_STRVAR(split__doc__,
-"B.split(sep=None, maxsplit=-1) -> list of bytes\n\
-\n\
-Return a list of the sections in B, using sep as the delimiter.\n\
-If sep is not specified or is None, B is split on ASCII whitespace\n\
-characters (space, tab, return, newline, formfeed, vertical tab).\n\
-If maxsplit is given, at most maxsplit splits are done.");
+static PyObject *
+bytes_split(PyBytesObject*self, PyObject *args, PyObject *kwargs)
+{
+ PyObject *return_value = NULL;
+ static char *_keywords[] = {"sep", "maxsplit", NULL};
+ PyObject *sep = Py_None;
+ Py_ssize_t maxsplit = -1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "|On:split", _keywords,
+ &sep, &maxsplit))
+ goto exit;
+ return_value = bytes_split_impl(self, sep, maxsplit);
+
+exit:
+ return return_value;
+}
static PyObject *
-bytes_split(PyBytesObject *self, PyObject *args, PyObject *kwds)
+bytes_split_impl(PyBytesObject*self, PyObject *sep, Py_ssize_t maxsplit)
+/*[clinic end generated code: output=c80a47afdd505975 input=8b809b39074abbfa]*/
{
- static char *kwlist[] = {"sep", "maxsplit", 0};
Py_ssize_t len = PyBytes_GET_SIZE(self), n;
- Py_ssize_t maxsplit = -1;
const char *s = PyBytes_AS_STRING(self), *sub;
Py_buffer vsub;
- PyObject *list, *subobj = Py_None;
+ PyObject *list;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split",
- kwlist, &subobj, &maxsplit))
- return NULL;
if (maxsplit < 0)
maxsplit = PY_SSIZE_T_MAX;
- if (subobj == Py_None)
+ if (sep == Py_None)
return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
- if (_getbuffer(sep, &vsub) < 0)
- if (PyObject_GetBuffer(subobj, &vsub, PyBUF_SIMPLE) != 0)
++ if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
return NULL;
sub = vsub.buf;
n = vsub.len;
return list;
}
-PyDoc_STRVAR(partition__doc__,
-"B.partition(sep) -> (head, sep, tail)\n\
-\n\
-Search for the separator sep in B, and return the part before it,\n\
-the separator itself, and the part after it. If the separator is not\n\
-found, returns B and two empty bytes objects.");
+/*[clinic input]
+bytes.partition
+
+ self: self(type="PyBytesObject *")
- sep: object
++ sep: Py_buffer
+ /
+
+Partition the bytes into three parts using the given separator.
+
+This will search for the separator sep in the bytes. If the separator is found,
+returns a 3-tuple containing the part before the separator, the separator
+itself, and the part after it.
+
+If the separator is not found, returns a 3-tuple containing the original bytes
+object and two empty bytes objects.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(bytes_partition__doc__,
+"partition($self, sep, /)\n"
+"--\n"
+"\n"
+"Partition the bytes into three parts using the given separator.\n"
+"\n"
+"This will search for the separator sep in the bytes. If the separator is found,\n"
+"returns a 3-tuple containing the part before the separator, the separator\n"
+"itself, and the part after it.\n"
+"\n"
+"If the separator is not found, returns a 3-tuple containing the original bytes\n"
+"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 *sep_obj)
++bytes_partition(PyBytesObject *self, PyObject *args)
{
- const char *sep_chars;
- Py_ssize_t sep_len;
++ PyObject *return_value = NULL;
+ Py_buffer sep = {NULL, NULL};
- PyObject *res;
- 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))
- if (PyObject_GetBuffer(sep_obj, &sep, PyBUF_SIMPLE) != 0)
-- 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;
++}
+
- res = stringlib_partition(
++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, sep.buf, sep.len
++ sep->obj, (const char *)sep->buf, sep->len
);
- PyBuffer_Release(&sep);
- return res;
}
-PyDoc_STRVAR(rpartition__doc__,
-"B.rpartition(sep) -> (head, sep, tail)\n\
-\n\
-Search for the separator sep in B, starting at the end of B,\n\
-and return the part before it, the separator itself, and the\n\
-part after it. If the separator is not found, returns two empty\n\
-bytes objects and B.");
+/*[clinic input]
+bytes.rpartition
+
+ self: self(type="PyBytesObject *")
- sep: object
++ sep: Py_buffer
+ /
+
+Partition the bytes into three parts using the given separator.
+
+This will search for the separator sep in the bytes, starting and the end. If
+the separator is found, returns a 3-tuple containing the part before the
+separator, the separator itself, and the part after it.
+
+If the separator is not found, returns a 3-tuple containing two empty bytes
+objects and the original bytes object.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(bytes_rpartition__doc__,
+"rpartition($self, sep, /)\n"
+"--\n"
+"\n"
+"Partition the bytes into three parts using the given separator.\n"
+"\n"
+"This will search for the separator sep in the bytes, starting and the end. If\n"
+"the separator is found, returns a 3-tuple containing the part before the\n"
+"separator, the separator itself, and the part after it.\n"
+"\n"
+"If the separator is not found, returns a 3-tuple containing two empty bytes\n"
+"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(PyBytesObject *self, PyObject *sep_obj)
++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};
- PyObject *res;
- 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))
- if (PyObject_GetBuffer(sep_obj, &sep, PyBUF_SIMPLE) != 0)
-- 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);
+
- res = stringlib_rpartition(
++ 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, sep.buf, sep.len
++ sep->obj, (const char *)sep->buf, sep->len
);
- PyBuffer_Release(&sep);
- return res;
}
-PyDoc_STRVAR(rsplit__doc__,
-"B.rsplit(sep=None, maxsplit=-1) -> list of bytes\n\
-\n\
-Return a list of the sections in B, using sep as the delimiter,\n\
-starting at the end of B and working to the front.\n\
-If sep is not given, B is split on ASCII whitespace characters\n\
-(space, tab, return, newline, formfeed, vertical tab).\n\
-If maxsplit is given, at most maxsplit splits are done.");
+/*[clinic input]
+bytes.rsplit = bytes.split
+
+Return a list of the sections in the bytes, using sep as the delimiter.
+Splitting is done starting at the end of the bytes and working to the front.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(bytes_rsplit__doc__,
+"rsplit($self, /, sep=None, maxsplit=-1)\n"
+"--\n"
+"\n"
+"Return a list of the sections in the bytes, using sep as the delimiter.\n"
+"\n"
+" sep\n"
+" The delimiter according which to split the bytes.\n"
+" None (the default value) means split on ASCII whitespace characters\n"
+" (space, tab, return, newline, formfeed, vertical tab).\n"
+" maxsplit\n"
+" Maximum number of splits to do.\n"
+" -1 (the default value) means no limit.\n"
+"\n"
+"Splitting is done starting at the end of the bytes and working to the front.");
+
+#define BYTES_RSPLIT_METHODDEF \
+ {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS|METH_KEYWORDS, bytes_rsplit__doc__},
+
+static PyObject *
+bytes_rsplit_impl(PyBytesObject*self, PyObject *sep, Py_ssize_t maxsplit);
static PyObject *
-bytes_rsplit(PyBytesObject *self, PyObject *args, PyObject *kwds)
+bytes_rsplit(PyBytesObject*self, PyObject *args, PyObject *kwargs)
{
- static char *kwlist[] = {"sep", "maxsplit", 0};
- Py_ssize_t len = PyBytes_GET_SIZE(self), n;
+ PyObject *return_value = NULL;
+ static char *_keywords[] = {"sep", "maxsplit", NULL};
+ PyObject *sep = Py_None;
Py_ssize_t maxsplit = -1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "|On:rsplit", _keywords,
+ &sep, &maxsplit))
+ goto exit;
+ return_value = bytes_rsplit_impl(self, sep, maxsplit);
+
+exit:
+ return return_value;
+}
+
+static PyObject *
+bytes_rsplit_impl(PyBytesObject*self, PyObject *sep, Py_ssize_t maxsplit)
+/*[clinic end generated code: output=f86feddedbd7b26d input=0f86c9f28f7d7b7b]*/
+{
+ Py_ssize_t len = PyBytes_GET_SIZE(self), n;
const char *s = PyBytes_AS_STRING(self), *sub;
Py_buffer vsub;
- PyObject *list, *subobj = Py_None;
+ PyObject *list;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit",
- kwlist, &subobj, &maxsplit))
- return NULL;
if (maxsplit < 0)
maxsplit = PY_SSIZE_T_MAX;
- if (subobj == Py_None)
+ if (sep == Py_None)
return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
- if (_getbuffer(sep, &vsub) < 0)
- if (PyObject_GetBuffer(subobj, &vsub, PyBUF_SIMPLE) != 0)
++ if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
return NULL;
sub = vsub.buf;
n = vsub.len;
static PyObject *
bytes_translate(PyBytesObject *self, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ PyObject *table;
+ int group_right_1 = 0;
+ PyObject *deletechars = NULL;
+
+ switch (PyTuple_GET_SIZE(args)) {
+ case 1:
+ if (!PyArg_ParseTuple(args, "O:translate", &table))
+ goto exit;
+ break;
+ case 2:
+ if (!PyArg_ParseTuple(args, "OO:translate", &table, &deletechars))
+ goto exit;
+ group_right_1 = 1;
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "bytes.translate requires 1 to 2 arguments");
+ goto exit;
+ }
+ return_value = bytes_translate_impl(self, table, group_right_1, deletechars);
+
+exit:
+ return return_value;
+}
+
+static PyObject *
+bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, PyObject *deletechars)
+/*[clinic end generated code: output=f0f29a57f41df5d8 input=d8fa5519d7cc4be7]*/
{
char *input, *output;
- const char *table;
+ 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;
- const char *output_start, *del_table=NULL;
+ const char *output_start, *del_table_chars=NULL;
Py_ssize_t inlen, tablen, dellen = 0;
PyObject *result;
int trans_table[256];
- PyObject *tableobj, *delobj = NULL;
-
- if (!PyArg_UnpackTuple(args, "translate", 1, 2,
- &tableobj, &delobj))
- return NULL;
- if (PyBytes_Check(tableobj)) {
- table = PyBytes_AS_STRING(tableobj);
- tablen = PyBytes_GET_SIZE(tableobj);
+ if (PyBytes_Check(table)) {
+ table_chars = PyBytes_AS_STRING(table);
+ tablen = PyBytes_GET_SIZE(table);
}
- else if (tableobj == Py_None) {
- table = NULL;
+ else if (table == Py_None) {
+ table_chars = NULL;
tablen = 256;
}
- else if (PyObject_AsCharBuffer(table, &table_chars, &tablen))
- return NULL;
+ else {
- if (PyObject_GetBuffer(tableobj, &table_view, PyBUF_SIMPLE) != 0)
++ if (PyObject_GetBuffer(table, &table_view, PyBUF_SIMPLE) != 0)
+ return NULL;
- table = table_view.buf;
++ table_chars = table_view.buf;
+ tablen = table_view.len;
+ }
if (tablen != 256) {
PyErr_SetString(PyExc_ValueError,
return NULL;
}
- if (delobj != NULL) {
- if (PyBytes_Check(delobj)) {
- del_table = PyBytes_AS_STRING(delobj);
- dellen = PyBytes_GET_SIZE(delobj);
+ if (deletechars != NULL) {
+ if (PyBytes_Check(deletechars)) {
+ 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(delobj, &del_table_view, PyBUF_SIMPLE) != 0) {
++ if (PyObject_GetBuffer(deletechars, &del_table_view, PyBUF_SIMPLE) != 0) {
+ PyBuffer_Release(&table_view);
+ return NULL;
+ }
- del_table = del_table_view.buf;
++ del_table_chars = del_table_view.buf;
+ dellen = del_table_view.len;
+ }
}
else {
- del_table = NULL;
+ del_table_chars = NULL;
dellen = 0;
}
/* If no deletions are required, use faster code */
for (i = inlen; --i >= 0; ) {
c = Py_CHARMASK(*input++);
- if (Py_CHARMASK((*output++ = table[c])) != c)
+ 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 == NULL) {
+ if (table_chars == NULL) {
for (i = 0; i < 256; i++)
trans_table[i] = Py_CHARMASK(i);
} else {
for (i = 0; i < 256; i++)
- trans_table[i] = Py_CHARMASK(table[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[i])] = -1;
+ trans_table[(int) Py_CHARMASK(del_table_chars[i])] = -1;
+ PyBuffer_Release(&del_table_view);
for (i = inlen; --i >= 0; ) {
c = Py_CHARMASK(*input++);
}
- frm: object
- to: object
+/*[clinic input]
+
+@staticmethod
+bytes.maketrans
+
++ frm: Py_buffer
++ to: Py_buffer
+ /
+
+Return a translation table useable for the bytes or bytearray translate method.
+
+The returned table will be one where each byte in frm is mapped to the byte at
+the same position in to.
+
+The bytes objects frm and to must be of the same length.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(bytes_maketrans__doc__,
+"maketrans(frm, to, /)\n"
+"--\n"
+"\n"
+"Return a translation table useable for the bytes or bytearray translate method.\n"
+"\n"
+"The returned table will be one where each byte in frm is mapped to the byte at\n"
+"the same position in to.\n"
+"\n"
+"The bytes objects frm and to must be of the same length.");
+
+#define BYTES_MAKETRANS_METHODDEF \
+ {"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC, bytes_maketrans__doc__},
+
static PyObject *
- bytes_maketrans_impl(PyObject *frm, PyObject *to);
-bytes_maketrans(PyObject *null, PyObject *args)
++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(args);
+ return _Py_bytes_maketrans(frm, to);
}
/* find and count characters and substrings */
}
}
-PyDoc_STRVAR(replace__doc__,
-"B.replace(old, new[, count]) -> bytes\n\
-\n\
-Return a copy of B with all occurrences of subsection\n\
-old replaced by new. If the optional argument count is\n\
-given, only first count occurances are replaced.");
+
+/*[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.
+ /
+
+Return a copy with all occurrences of substring old replaced by new.
+
+If the optional argument count is given, only the first count occurrences are
+replaced.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(bytes_replace__doc__,
+"replace($self, old, new, count=-1, /)\n"
+"--\n"
+"\n"
+"Return a copy with all occurrences of substring old replaced by new.\n"
+"\n"
+" count\n"
+" Maximum number of occurrences to replace.\n"
+" -1 (the default value) means replace all occurrences.\n"
+"\n"
+"If the optional argument count is given, only the first count occurrences are\n"
+"replaced.");
+
+#define BYTES_REPLACE_METHODDEF \
+ {"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)
+bytes_replace(PyBytesObject*self, PyObject *args)
{
- PyObject *res;
+ 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, "y*y*|n:replace", &old, &new, &count))
- return NULL;
+ 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);
- res = (PyObject *)replace((PyBytesObject *) self,
- (const char *)old.buf, old.len,
- (const char *)new.buf, new.len, count);
+exit:
++ /* Cleanup for old */
++ if (old.obj)
++ PyBuffer_Release(&old);
++ /* Cleanup for new */
++ if (new.obj)
++ PyBuffer_Release(&new);
+
- PyBuffer_Release(&old);
- PyBuffer_Release(&new);
- return res;
+ 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 **/
Py_CLEAR(*pv);
return;
}
- v = bytes_concat(*pv, w);
- Py_DECREF(*pv);
- *pv = v;
+
+ if (Py_REFCNT(*pv) == 1 && PyBytes_CheckExact(*pv)) {
+ /* Only one reference, so we can resize in place */
+ Py_ssize_t oldsize;
+ 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);
+ return;
+ }
+
+ oldsize = PyBytes_GET_SIZE(*pv);
+ if (oldsize > PY_SSIZE_T_MAX - wb.len) {
+ PyErr_NoMemory();
+ goto error;
+ }
+ if (_PyBytes_Resize(pv, oldsize + wb.len) < 0)
+ goto error;
+
+ memcpy(PyBytes_AS_STRING(*pv) + oldsize, wb.buf, wb.len);
+ PyBuffer_Release(&wb);
+ return;
+
+ error:
+ PyBuffer_Release(&wb);
+ Py_CLEAR(*pv);
+ return;
+ }
+
+ else {
+ /* Multiple references, need to create new object */
+ PyObject *v;
+ v = bytes_concat(*pv, w);
+ Py_DECREF(*pv);
+ *pv = v;
+ }
}
void
return PyObject_Format(value, format_spec);
}
-PyDoc_STRVAR(format_doc,
-"format(value[, format_spec]) -> string\n\
-\n\
-Returns value.__format__(format_spec)\n\
-format_spec defaults to \"\"");
+/*[clinic input]
+chr as builtin_chr
+
+ i: 'i'
+ /
+
+Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(builtin_chr__doc__,
+"chr($module, i, /)\n"
+"--\n"
+"\n"
+"Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.");
+
+#define BUILTIN_CHR_METHODDEF \
+ {"chr", (PyCFunction)builtin_chr, METH_VARARGS, builtin_chr__doc__},
+
+static PyObject *
+builtin_chr_impl(PyModuleDef *module, int i);
static PyObject *
-builtin_chr(PyObject *self, PyObject *args)
+builtin_chr(PyModuleDef *module, PyObject *args)
{
- int x;
+ PyObject *return_value = NULL;
+ int i;
- if (!PyArg_ParseTuple(args, "i:chr", &x))
- return NULL;
+ if (!PyArg_ParseTuple(args,
+ "i:chr",
+ &i))
+ goto exit;
+ return_value = builtin_chr_impl(module, i);
- return PyUnicode_FromOrdinal(x);
+exit:
+ return return_value;
}
-PyDoc_STRVAR(chr_doc,
-"chr(i) -> Unicode character\n\
-\n\
-Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.");
+static PyObject *
+builtin_chr_impl(PyModuleDef *module, int i)
+/*[clinic end generated code: output=4d6bbe948f56e2ae input=9b1ced29615adf66]*/
+{
+ return PyUnicode_FromOrdinal(i);
+}
- 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)
{
- char *str;
+ const char *str;
Py_ssize_t size;
if (PyUnicode_Check(cmd)) {
funcname, what);
return NULL;
}
- else if (PyObject_AsReadBuffer(cmd, (const void **)&str, &size) < 0) {
- return NULL;
- }
- if (strlen(str) != (size_t)size) {
- if (strlen(str) != size) {
- PyErr_SetString(PyExc_TypeError,
++ if (strlen(str) != (size_t)size) {
+ PyErr_SetString(PyExc_ValueError,
"source code string cannot contain null bytes");
+ PyBuffer_Release(view);
return NULL;
}
return str;
}
+/*[clinic input]
+compile as builtin_compile
+
+ source: 'O'
+ filename: object(converter="PyUnicode_FSDecoder")
+ mode: 's'
+ flags: 'i' = 0
+ dont_inherit: 'i' = 0
+ optimize: 'i' = -1
+
+Compile source into a code object that can be executed by exec() or eval().
+
+The source code may represent a Python module, statement or expression.
+The filename will be used for run-time error messages.
+The mode must be 'exec' to compile a module, 'single' to compile a
+single (interactive) statement, or 'eval' to compile an expression.
+The flags argument, if present, controls which future statements influence
+the compilation of the code.
+The dont_inherit argument, if non-zero, stops the compilation inheriting
+the effects of any future statements in effect in the code calling
+compile; if absent or zero these statements do influence the compilation,
+in addition to any features explicitly specified.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(builtin_compile__doc__,
+"compile($module, /, source, filename, mode, flags=0, dont_inherit=0,\n"
+" optimize=-1)\n"
+"--\n"
+"\n"
+"Compile source into a code object that can be executed by exec() or eval().\n"
+"\n"
+"The source code may represent a Python module, statement or expression.\n"
+"The filename will be used for run-time error messages.\n"
+"The mode must be \'exec\' to compile a module, \'single\' to compile a\n"
+"single (interactive) statement, or \'eval\' to compile an expression.\n"
+"The flags argument, if present, controls which future statements influence\n"
+"the compilation of the code.\n"
+"The dont_inherit argument, if non-zero, stops the compilation inheriting\n"
+"the effects of any future statements in effect in the code calling\n"
+"compile; if absent or zero these statements do influence the compilation,\n"
+"in addition to any features explicitly specified.");
+
+#define BUILTIN_COMPILE_METHODDEF \
+ {"compile", (PyCFunction)builtin_compile, METH_VARARGS|METH_KEYWORDS, builtin_compile__doc__},
+
+static PyObject *
+builtin_compile_impl(PyModuleDef *module, PyObject *source, PyObject *filename, const char *mode, int flags, int dont_inherit, int optimize);
+
static PyObject *
-builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
+builtin_compile(PyModuleDef *module, PyObject *args, PyObject *kwargs)
{
- Py_buffer view = {NULL, NULL};
- const char *str;
+ PyObject *return_value = NULL;
+ static char *_keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", NULL};
+ PyObject *source;
PyObject *filename;
- char *startstr;
- int mode = -1;
+ const char *mode;
+ int flags = 0;
int dont_inherit = 0;
- int supplied_flags = 0;
int optimize = -1;
- char *str;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "OO&s|iii:compile", _keywords,
+ &source, PyUnicode_FSDecoder, &filename, &mode, &flags, &dont_inherit, &optimize))
+ goto exit;
+ return_value = builtin_compile_impl(module, source, filename, mode, flags, dont_inherit, optimize);
+
+exit:
+ return return_value;
+}
+
+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]*/
+{
++ Py_buffer view = {NULL, NULL};
++ const char *str;
+ int compile_mode = -1;
int is_ast;
PyCompilerFlags cf;
- PyObject *cmd;
- static char *kwlist[] = {"source", "filename", "mode", "flags",
- "dont_inherit", "optimize", NULL};
int start[] = {Py_file_input, Py_eval_input, Py_single_input};
PyObject *result;
goto finally;
}
- str = source_as_string(source, "compile", "string, bytes or AST", &cf);
- str = source_as_string(cmd, "compile", "string, bytes or AST", &cf, &view);
++ str = source_as_string(source, "compile", "string, bytes or AST", &cf, &view);
if (str == NULL)
goto error;
- result = Py_CompileStringObject(str, filename, start[mode], &cf, optimize);
+ result = Py_CompileStringObject(str, filename, start[compile_mode], &cf, optimize);
+ PyBuffer_Release(&view);
goto finally;
error:
" for any other object: its attributes, its class's attributes, and\n"
" recursively the attributes of its class's base classes.");
+/*[clinic input]
+divmod as builtin_divmod
+
+ x: 'O'
+ y: 'O'
+ /
+
+Return the tuple ((x-x%y)/y, x%y). Invariant: div*y + mod == x.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(builtin_divmod__doc__,
+"divmod($module, x, y, /)\n"
+"--\n"
+"\n"
+"Return the tuple ((x-x%y)/y, x%y). Invariant: div*y + mod == x.");
+
+#define BUILTIN_DIVMOD_METHODDEF \
+ {"divmod", (PyCFunction)builtin_divmod, METH_VARARGS, builtin_divmod__doc__},
+
+static PyObject *
+builtin_divmod_impl(PyModuleDef *module, PyObject *x, PyObject *y);
+
static PyObject *
-builtin_divmod(PyObject *self, PyObject *args)
+builtin_divmod(PyModuleDef *module, PyObject *args)
{
- PyObject *v, *w;
+ PyObject *return_value = NULL;
+ PyObject *x;
+ PyObject *y;
+
+ if (!PyArg_UnpackTuple(args, "divmod",
+ 2, 2,
+ &x, &y))
+ goto exit;
+ return_value = builtin_divmod_impl(module, x, y);
+
+exit:
+ return return_value;
+}
- if (!PyArg_UnpackTuple(args, "divmod", 2, 2, &v, &w))
- return NULL;
- return PyNumber_Divmod(v, w);
+static PyObject *
+builtin_divmod_impl(PyModuleDef *module, PyObject *x, PyObject *y)
+/*[clinic end generated code: output=77e8d408b1338886 input=c9c617b7bb74c615]*/
+{
+ return PyNumber_Divmod(x, y);
}
-PyDoc_STRVAR(divmod_doc,
-"divmod(x, y) -> (div, mod)\n\
-\n\
-Return the tuple ((x-x%y)/y, x%y). Invariant: div*y + mod == x.");
+/*[clinic input]
+eval as builtin_eval
+
+ source: 'O'
+ globals: 'O' = None
+ locals: 'O' = None
+ /
+
+Evaluate the given source in the context of globals and locals.
+
+The source may be a string representing a Python expression
+or a code object as returned by compile().
+The globals must be a dictionary and locals can be any mapping,
+defaulting to the current globals and locals.
+If only globals is given, locals defaults to it.
+[clinic start generated code]*/
+
+PyDoc_STRVAR(builtin_eval__doc__,
+"eval($module, source, globals=None, locals=None, /)\n"
+"--\n"
+"\n"
+"Evaluate the given source in the context of globals and locals.\n"
+"\n"
+"The source may be a string representing a Python expression\n"
+"or a code object as returned by compile().\n"
+"The globals must be a dictionary and locals can be any mapping,\n"
+"defaulting to the current globals and locals.\n"
+"If only globals is given, locals defaults to it.");
+
+#define BUILTIN_EVAL_METHODDEF \
+ {"eval", (PyCFunction)builtin_eval, METH_VARARGS, builtin_eval__doc__},
+
+static PyObject *
+builtin_eval_impl(PyModuleDef *module, PyObject *source, PyObject *globals, PyObject *locals);
static PyObject *
-builtin_eval(PyObject *self, PyObject *args)
+builtin_eval(PyModuleDef *module, PyObject *args)
{
- PyObject *cmd, *result, *tmp = NULL;
- PyObject *globals = Py_None, *locals = Py_None;
+ PyObject *return_value = NULL;
+ PyObject *source;
+ PyObject *globals = Py_None;
+ PyObject *locals = Py_None;
+
+ if (!PyArg_UnpackTuple(args, "eval",
+ 1, 3,
+ &source, &globals, &locals))
+ goto exit;
+ return_value = builtin_eval_impl(module, source, globals, locals);
+
+exit:
+ return return_value;
+}
+
+static PyObject *
+builtin_eval_impl(PyModuleDef *module, PyObject *source, PyObject *globals, PyObject *locals)
+/*[clinic end generated code: output=644fd59012538ce6 input=31e42c1d2125b50b]*/
+{
+ PyObject *result, *tmp = NULL;
- char *str;
+ Py_buffer view = {NULL, NULL};
+ const char *str;
PyCompilerFlags cf;
- if (!PyArg_UnpackTuple(args, "eval", 1, 3, &cmd, &globals, &locals))
- return NULL;
if (locals != Py_None && !PyMapping_Check(locals)) {
PyErr_SetString(PyExc_TypeError, "locals must be a mapping");
return NULL;
}
cf.cf_flags = PyCF_SOURCE_IS_UTF8;
- str = source_as_string(source, "eval", "string, bytes or code", &cf);
- str = source_as_string(cmd, "eval", "string, bytes or code", &cf, &view);
++ str = source_as_string(source, "eval", "string, bytes or code", &cf, &view);
if (str == NULL)
return NULL;
"contain free variables");
return NULL;
}
- v = PyEval_EvalCode(prog, globals, locals);
+ v = PyEval_EvalCode(source, globals, locals);
}
else {
- char *str;
+ Py_buffer view = {NULL, NULL};
+ const char *str;
PyCompilerFlags cf;
cf.cf_flags = PyCF_SOURCE_IS_UTF8;
- str = source_as_string(prog, "exec",
- "string, bytes or code", &cf, &view);
+ str = source_as_string(source, "exec",
- "string, bytes or code", &cf);
++ "string, bytes or code", &cf, &view);
if (str == NULL)
return NULL;
if (PyEval_MergeCompilerFlags(&cf))