diff -r 967f368b7f75 Include/bytes_methods.h --- a/Include/bytes_methods.h Sun Jan 19 00:38:36 2014 +0200 +++ b/Include/bytes_methods.h Tue Jan 21 21:40:45 2014 +0200 @@ -21,8 +21,8 @@ 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); /* Shared __doc__ strings. */ extern const char _Py_isspace__doc__[]; diff -r 967f368b7f75 Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Sun Jan 19 00:38:36 2014 +0200 +++ b/Objects/bytearrayobject.c Tue Jan 21 21:40:45 2014 +0200 @@ -5,6 +5,11 @@ #include "structmember.h" #include "bytes_methods.h" +/*[clinic input] +class bytearray +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + char _PyByteArray_empty_string[] = ""; void @@ -1457,36 +1462,84 @@ } -PyDoc_STRVAR(translate__doc__, -"B.translate(table[, deletechars]) -> bytearray\n\ -\n\ -Return a copy of B, where all characters occurring in the\n\ -optional argument deletechars are removed, and the remaining\n\ -characters have been mapped through the given translation\n\ -table, which must be a bytes object of length 256."); +/*[clinic input] +bytearray.translate + + self: self(type="PyByteArrayObject *") + table: object + Translation table, which must be a bytes object of length 256. + [ + deletechars: object + ] + / + +Return a copy with each character mapped by the given translation table. + +All characters occurring in the optional argument deletechars are removed. +The remaining characters are mapped through the given translation table. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_translate__doc__, +"translate(table, [deletechars])\n" +"Return a copy with each character mapped by the given translation table.\n" +"\n" +" table\n" +" Translation table, which must be a bytes object of length 256.\n" +"\n" +"All characters occurring in the optional argument deletechars are removed.\n" +"The remaining characters are mapped through the given translation table."); + +#define BYTEARRAY_TRANSLATE_METHODDEF \ + {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, bytearray_translate__doc__}, static PyObject * -bytearray_translate(PyByteArrayObject *self, PyObject *args) +bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, int group_right_1, PyObject *deletechars); + +static PyObject * +bytearray_translate(PyObject *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)) + return NULL; + break; + case 2: + if (!PyArg_ParseTuple(args, "OO:translate", &table, &deletechars)) + return NULL; + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "bytearray.translate requires 1 to 2 arguments"); + return NULL; + } + return_value = bytearray_translate_impl((PyByteArrayObject *)self, table, group_right_1, deletechars); + + return return_value; +} + +static PyObject * +bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, int group_right_1, PyObject *deletechars) +/*[clinic end generated code: checksum=f2a7cfdaea110471dc759e2d989d149797094ad3]*/ { char *input, *output; - const char *table; + const char *table_chars; Py_ssize_t i, c; PyObject *input_obj = (PyObject*)self; const char *output_start; 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; - tableobj = NULL; - } else if (_getbuffer(tableobj, &vtable) < 0) { + } else if (_getbuffer(table, &vtable) < 0) { return NULL; } else { if (vtable.len != 256) { @@ -1495,12 +1548,12 @@ PyBuffer_Release(&vtable); return NULL; } - table = (const char*)vtable.buf; + table_chars = (const char*)vtable.buf; } - if (delobj != NULL) { - if (_getbuffer(delobj, &vdel) < 0) { - if (tableobj != NULL) + if (deletechars != NULL) { + if (_getbuffer(deletechars, &vdel) < 0) { + if (table != NULL) PyBuffer_Release(&vtable); return NULL; } @@ -1517,21 +1570,21 @@ output_start = output = PyByteArray_AsString(result); input = PyByteArray_AS_STRING(input_obj); - if (vdel.len == 0 && table != NULL) { + if (vdel.len == 0 && table_chars != NULL) { /* If no deletions are required, use faster code */ for (i = inlen; --i >= 0; ) { c = Py_CHARMASK(*input++); - *output++ = table[c]; + *output++ = table_chars[c]; } goto done; } - 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]); } for (i = 0; i < vdel.len; i++) @@ -1551,18 +1604,68 @@ } done: - if (tableobj != NULL) + if (table != NULL) PyBuffer_Release(&vtable); - if (delobj != NULL) + if (deletechars != NULL) PyBuffer_Release(&vdel); return result; } +/*[clinic input] + +@staticmethod +bytearray.maketrans + + frm: object + to: object + / + +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" +"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(PyObject *null, PyObject *args) +bytearray_maketrans_impl(void *null, PyObject *frm, PyObject *to); + +static PyObject * +bytearray_maketrans(void *null, PyObject *args) { - return _Py_bytes_maketrans(args); + PyObject *return_value = NULL; + PyObject *frm; + PyObject *to; + + if (!PyArg_UnpackTuple(args, "maketrans", + 2, 2, + &frm, &to)) + goto exit; + return_value = bytearray_maketrans_impl(null, frm, to); + +exit: + return return_value; +} + +static PyObject * +bytearray_maketrans_impl(void *null, PyObject *frm, PyObject *to) +/*[clinic end generated code: checksum=079f962ae747259fcfc7c02807ddc406e274a1d5]*/ +{ + return _Py_bytes_maketrans(frm, to); } @@ -2053,67 +2156,146 @@ } -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 + 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(old, new, count=-1)\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(PyByteArrayObject *self, PyObject *args) +bytearray_replace_impl(PyObject *self, PyObject *old, PyObject *new, Py_ssize_t count); + +static PyObject * +bytearray_replace(PyObject *self, PyObject *args) { + PyObject *return_value = NULL; + PyObject *old; + PyObject *new; Py_ssize_t count = -1; - PyObject *from, *to, *res; - Py_buffer vfrom, vto; - - if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count)) + + if (!PyArg_ParseTuple(args, + "OO|n:replace", + &old, &new, &count)) + goto exit; + return_value = bytearray_replace_impl(self, old, new, count); + +exit: + return return_value; +} + +static PyObject * +bytearray_replace_impl(PyObject *self, PyObject *old, PyObject *new, Py_ssize_t count) +/*[clinic end generated code: checksum=f0498e627bcc35d8cf3c2d1385e3e1d44d0a1fb2]*/ +{ + PyObject *res; + Py_buffer vold, vnew; + + if (_getbuffer(old, &vold) < 0) return NULL; - - if (_getbuffer(from, &vfrom) < 0) - return NULL; - if (_getbuffer(to, &vto) < 0) { - PyBuffer_Release(&vfrom); + if (_getbuffer(new, &vnew) < 0) { + PyBuffer_Release(&vold); return NULL; } res = (PyObject *)replace((PyByteArrayObject *) self, - vfrom.buf, vfrom.len, - vto.buf, vto.len, count); - - PyBuffer_Release(&vfrom); - PyBuffer_Release(&vto); + vold.buf, vold.len, + vnew.buf, vnew.len, count); + + PyBuffer_Release(&vold); + PyBuffer_Release(&vnew); return res; } -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."); +/*[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(sep=None, maxsplit=-1)\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(PyObject *self, PyObject *sep, Py_ssize_t maxsplit); + +static PyObject * +bytearray_split(PyObject *self, PyObject *args, PyObject *kwargs) { - static char *kwlist[] = {"sep", "maxsplit", 0}; + 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(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: checksum=56a949c08b0d0b70f4db00e66ef8ac8c02efbb8f]*/ +{ Py_ssize_t len = PyByteArray_GET_SIZE(self), n; - Py_ssize_t maxsplit = -1; 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(subobj, &vsub) < 0) + if (_getbuffer(sep, &vsub) < 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -2125,19 +2307,44 @@ 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 bytearray objects."); +/*[clinic input] +bytearray.partition + + self: self(type="PyByteArrayObject *") + sep: object + / + +Partition the bytearray into three parts using the given separator. + +This will search for the separator sep in the bytearray. 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 +bytearray object and two empty bytearray objects. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_partition__doc__, +"partition(sep)\n" +"Partition the bytearray into three parts using the given separator.\n" +"\n" +"This will search for the separator sep in the bytearray. If the separator is\n" +"found, returns a 3-tuple containing the part before the separator, the\n" +"separator itself, and the part after it.\n" +"\n" +"If the separator is not found, returns a 3-tuple containing the original\n" +"bytearray object and two empty bytearray objects."); + +#define BYTEARRAY_PARTITION_METHODDEF \ + {"partition", (PyCFunction)bytearray_partition, METH_O, bytearray_partition__doc__}, static PyObject * -bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj) +bytearray_partition(PyByteArrayObject *self, PyObject *sep) +/*[clinic end generated code: checksum=3632cc41e0d6725b33ff2f2aa3547e03f39ac027]*/ { PyObject *bytesep, *result; - bytesep = PyByteArray_FromObject(sep_obj); + bytesep = PyByteArray_FromObject(sep); if (! bytesep) return NULL; @@ -2152,20 +2359,44 @@ return result; } -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\ -bytearray objects and B."); +/*[clinic input] +bytearray.rpartition + + self: self(type="PyByteArrayObject *") + sep: object + / + +Partition the bytes into three parts using the given separator. + +This will search for the separator sep in the bytearray, 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 bytearray +objects and the original bytearray object. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_rpartition__doc__, +"rpartition(sep)\n" +"Partition the bytes into three parts using the given separator.\n" +"\n" +"This will search for the separator sep in the bytearray, starting and the end.\n" +"If 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 bytearray\n" +"objects and the original bytearray object."); + +#define BYTEARRAY_RPARTITION_METHODDEF \ + {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, bytearray_rpartition__doc__}, static PyObject * -bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj) +bytearray_rpartition(PyByteArrayObject *self, PyObject *sep) +/*[clinic end generated code: checksum=30d016280011ac225c6cf0c6840c00c0a485cce2]*/ { PyObject *bytesep, *result; - bytesep = PyByteArray_FromObject(sep_obj); + bytesep = PyByteArray_FromObject(sep); if (! bytesep) return NULL; @@ -2180,35 +2411,68 @@ return result; } -PyDoc_STRVAR(rsplit__doc__, -"B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays\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] +bytearray.rsplit = bytearray.split + +Return a list of the sections in the bytearray, using sep as the delimiter. + +Splitting is done starting at the end of the bytearray and working to the front. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_rsplit__doc__, +"rsplit(sep=None, maxsplit=-1)\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.\n" +"\n" +"Splitting is done starting at the end of the bytearray and working to the front."); + +#define BYTEARRAY_RSPLIT_METHODDEF \ + {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS|METH_KEYWORDS, bytearray_rsplit__doc__}, static PyObject * -bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwds) +bytearray_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit); + +static PyObject * +bytearray_rsplit(PyObject *self, PyObject *args, PyObject *kwargs) { - static char *kwlist[] = {"sep", "maxsplit", 0}; + 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 = bytearray_rsplit_impl(self, sep, maxsplit); + +exit: + return return_value; +} + +static PyObject * +bytearray_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: checksum=ce2a2809e2540d0428baf666462f692215d868b9]*/ +{ Py_ssize_t len = PyByteArray_GET_SIZE(self), n; - Py_ssize_t maxsplit = -1; const char *s = PyByteArray_AS_STRING(self), *sub; - PyObject *list, *subobj = Py_None; + PyObject *list; Py_buffer vsub; - 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(subobj, &vsub) < 0) + if (_getbuffer(sep, &vsub) < 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -2220,12 +2484,33 @@ return list; } -PyDoc_STRVAR(reverse__doc__, -"B.reverse() -> None\n\ -\n\ -Reverse the order of the values in B in place."); +/*[clinic input] +bytearray.reverse + + self: self(type="PyByteArrayObject *") + +Reverse the order of the values in B in place. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_reverse__doc__, +"reverse()\n" +"Reverse the order of the values in B in place."); + +#define BYTEARRAY_REVERSE_METHODDEF \ + {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, bytearray_reverse__doc__}, + static PyObject * -bytearray_reverse(PyByteArrayObject *self, PyObject *unused) +bytearray_reverse_impl(PyByteArrayObject *self); + +static PyObject * +bytearray_reverse(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytearray_reverse_impl((PyByteArrayObject *)self); +} + +static PyObject * +bytearray_reverse_impl(PyByteArrayObject *self) +/*[clinic end generated code: checksum=6a0c02a5819a018a8ecdc2666d2f3111086d70fc]*/ { char swap, *head, *tail; Py_ssize_t i, j, n = Py_SIZE(self); @@ -2242,57 +2527,67 @@ Py_RETURN_NONE; } -PyDoc_STRVAR(insert__doc__, -"B.insert(index, int) -> None\n\ -\n\ -Insert a single item into the bytearray before the given index."); + +/*[python input] +class bytesvalue_converter(CConverter): + type = 'int' + converter = '_getbytevalue' +[python start generated code]*/ +/*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + + +/*[clinic input] +bytearray.insert + + self: self(type="PyByteArrayObject *") + index: Py_ssize_t + The index where the value is to be inserted. + item: bytesvalue + The item to be inserted. + / + +Insert a single item into the bytearray before the given index. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_insert__doc__, +"insert(index, item)\n" +"Insert a single item into the bytearray before the given index.\n" +"\n" +" index\n" +" The index where the value is to be inserted.\n" +" item\n" +" The item to be inserted."); + +#define BYTEARRAY_INSERT_METHODDEF \ + {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, bytearray_insert__doc__}, + static PyObject * -bytearray_insert(PyByteArrayObject *self, PyObject *args) +bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item); + +static PyObject * +bytearray_insert(PyObject *self, PyObject *args) { - PyObject *value; - int ival; - Py_ssize_t where, n = Py_SIZE(self); + PyObject *return_value = NULL; + Py_ssize_t index; + int item; + + if (!PyArg_ParseTuple(args, + "nO&:insert", + &index, _getbytevalue, &item)) + goto exit; + return_value = bytearray_insert_impl((PyByteArrayObject *)self, index, item); + +exit: + return return_value; +} + +static PyObject * +bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item) +/*[clinic end generated code: checksum=7fd8543091deca0bec87e4451c95b1f4a03eae9c]*/ +{ + Py_ssize_t n = Py_SIZE(self); char *buf; - if (!PyArg_ParseTuple(args, "nO:insert", &where, &value)) - return NULL; - - if (n == PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "cannot add more objects to bytearray"); - return NULL; - } - if (!_getbytevalue(value, &ival)) - return NULL; - if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) - return NULL; - buf = PyByteArray_AS_STRING(self); - - if (where < 0) { - where += n; - if (where < 0) - where = 0; - } - if (where > n) - where = n; - memmove(buf + where + 1, buf + where, n - where); - buf[where] = ival; - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(append__doc__, -"B.append(int) -> None\n\ -\n\ -Append a single item to the end of B."); -static PyObject * -bytearray_append(PyByteArrayObject *self, PyObject *arg) -{ - int value; - Py_ssize_t n = Py_SIZE(self); - - if (! _getbytevalue(arg, &value)) - return NULL; if (n == PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "cannot add more objects to bytearray"); @@ -2300,19 +2595,104 @@ } if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) return NULL; - - PyByteArray_AS_STRING(self)[n] = value; + buf = PyByteArray_AS_STRING(self); + + if (index < 0) { + index += n; + if (index < 0) + index = 0; + } + if (index > n) + index = n; + memmove(buf + index + 1, buf + index, n - index); + buf[index] = item; Py_RETURN_NONE; } -PyDoc_STRVAR(extend__doc__, -"B.extend(iterable_of_ints) -> None\n\ -\n\ -Append all the elements from the iterator or sequence to the\n\ -end of B."); +/*[clinic input] +bytearray.append + + self: self(type="PyByteArrayObject *") + item: bytesvalue + The item to be appended. + / + +Append a single item to the end of the bytearray. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_append__doc__, +"append(item)\n" +"Append a single item to the end of the bytearray.\n" +"\n" +" item\n" +" The item to be appended."); + +#define BYTEARRAY_APPEND_METHODDEF \ + {"append", (PyCFunction)bytearray_append, METH_VARARGS, bytearray_append__doc__}, + static PyObject * -bytearray_extend(PyByteArrayObject *self, PyObject *arg) +bytearray_append_impl(PyByteArrayObject *self, int item); + +static PyObject * +bytearray_append(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int item; + + if (!PyArg_ParseTuple(args, + "O&:append", + _getbytevalue, &item)) + goto exit; + return_value = bytearray_append_impl((PyByteArrayObject *)self, item); + +exit: + return return_value; +} + +static PyObject * +bytearray_append_impl(PyByteArrayObject *self, int item) +/*[clinic end generated code: checksum=091ee2f4103a946237b5d91f86d0fd5960c39ee1]*/ +{ + Py_ssize_t n = Py_SIZE(self); + + if (n == PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "cannot add more objects to bytearray"); + return NULL; + } + if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) + return NULL; + + PyByteArray_AS_STRING(self)[n] = item; + + Py_RETURN_NONE; +} + +/*[clinic input] +bytearray.extend + + self: self(type="PyByteArrayObject *") + iterable_of_ints: object + The iterable of items to append. + / + +Append all the items from the iterator or sequence to the end of the bytearray. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_extend__doc__, +"extend(iterable_of_ints)\n" +"Append all the items from the iterator or sequence to the end of the bytearray.\n" +"\n" +" iterable_of_ints\n" +" The iterable of items to append."); + +#define BYTEARRAY_EXTEND_METHODDEF \ + {"extend", (PyCFunction)bytearray_extend, METH_O, bytearray_extend__doc__}, + +static PyObject * +bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints) +/*[clinic end generated code: checksum=890c1be0f3e73c8fb0fae71ab291586fcfb49433]*/ { PyObject *it, *item, *bytearray_obj; Py_ssize_t buf_size = 0, len = 0; @@ -2320,19 +2700,19 @@ char *buf; /* bytearray_setslice code only accepts something supporting PEP 3118. */ - if (PyObject_CheckBuffer(arg)) { - if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1) + if (PyObject_CheckBuffer(iterable_of_ints)) { + if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1) return NULL; Py_RETURN_NONE; } - it = PyObject_GetIter(arg); + it = PyObject_GetIter(iterable_of_ints); if (it == NULL) return NULL; /* Try to determine the length of the argument. 32 is arbitrary. */ - buf_size = PyObject_LengthHint(arg, 32); + buf_size = PyObject_LengthHint(iterable_of_ints, 32); if (buf_size == -1) { Py_DECREF(it); return NULL; @@ -2384,29 +2764,68 @@ Py_RETURN_NONE; } -PyDoc_STRVAR(pop__doc__, -"B.pop([index]) -> int\n\ -\n\ -Remove and return a single item from B. If no index\n\ -argument is given, will pop the last value."); +/*[clinic input] +bytearray.pop + + self: self(type="PyByteArrayObject *") + index: Py_ssize_t = -1 + The index from where to remove the item. + -1 (the default value) means remove the last item. + / + +Remove and return a single item from B. + +If no index argument is given, will pop the last item. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_pop__doc__, +"pop(index=-1)\n" +"Remove and return a single item from B.\n" +"\n" +" index\n" +" The index from where to remove the item.\n" +" -1 (the default value) means remove the last item.\n" +"\n" +"If no index argument is given, will pop the last item."); + +#define BYTEARRAY_POP_METHODDEF \ + {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, bytearray_pop__doc__}, + static PyObject * -bytearray_pop(PyByteArrayObject *self, PyObject *args) +bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index); + +static PyObject * +bytearray_pop(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t index = -1; + + if (!PyArg_ParseTuple(args, + "|n:pop", + &index)) + goto exit; + return_value = bytearray_pop_impl((PyByteArrayObject *)self, index); + +exit: + return return_value; +} + +static PyObject * +bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index) +/*[clinic end generated code: checksum=fced0deb098dd025b055408158b930f7b9f43366]*/ { int value; - Py_ssize_t where = -1, n = Py_SIZE(self); + Py_ssize_t n = Py_SIZE(self); char *buf; - if (!PyArg_ParseTuple(args, "|n:pop", &where)) - return NULL; - if (n == 0) { PyErr_SetString(PyExc_IndexError, "pop from empty bytearray"); return NULL; } - if (where < 0) - where += Py_SIZE(self); - if (where < 0 || where >= Py_SIZE(self)) { + if (index < 0) + index += Py_SIZE(self); + if (index < 0 || index >= Py_SIZE(self)) { PyErr_SetString(PyExc_IndexError, "pop index out of range"); return NULL; } @@ -2414,28 +2833,61 @@ return NULL; buf = PyByteArray_AS_STRING(self); - value = buf[where]; - memmove(buf + where, buf + where + 1, n - where); + value = buf[index]; + memmove(buf + index, buf + index + 1, n - index); if (PyByteArray_Resize((PyObject *)self, n - 1) < 0) return NULL; return PyLong_FromLong((unsigned char)value); } -PyDoc_STRVAR(remove__doc__, -"B.remove(int) -> None\n\ -\n\ -Remove the first occurrence of a value in B."); +/*[clinic input] +bytearray.remove + + self: self(type="PyByteArrayObject *") + value: bytesvalue + The value to remove. + / + +Remove the first occurrence of a value in the bytearray. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_remove__doc__, +"remove(value)\n" +"Remove the first occurrence of a value in the bytearray.\n" +"\n" +" value\n" +" The value to remove."); + +#define BYTEARRAY_REMOVE_METHODDEF \ + {"remove", (PyCFunction)bytearray_remove, METH_VARARGS, bytearray_remove__doc__}, + static PyObject * -bytearray_remove(PyByteArrayObject *self, PyObject *arg) +bytearray_remove_impl(PyByteArrayObject *self, int value); + +static PyObject * +bytearray_remove(PyObject *self, PyObject *args) { + PyObject *return_value = NULL; int value; + + if (!PyArg_ParseTuple(args, + "O&:remove", + _getbytevalue, &value)) + goto exit; + return_value = bytearray_remove_impl((PyByteArrayObject *)self, value); + +exit: + return return_value; +} + +static PyObject * +bytearray_remove_impl(PyByteArrayObject *self, int value) +/*[clinic end generated code: checksum=fdf39be96ff8e39a9afa7545125e115c0cc4635c]*/ +{ Py_ssize_t where, n = Py_SIZE(self); char *buf = PyByteArray_AS_STRING(self); - if (! _getbytevalue(arg, &value)) - return NULL; - for (where = 0; where < n; where++) { if (buf[where] == value) break; @@ -2476,129 +2928,262 @@ return i + 1; } -PyDoc_STRVAR(strip__doc__, -"B.strip([bytes]) -> bytearray\n\ -\n\ -Strip leading and trailing bytes contained in the argument\n\ -and return the result as a new bytearray.\n\ -If the argument is omitted, strip ASCII whitespace."); +/*[clinic input] +bytearray.strip + + bytes: object = None + / + +Strip leading and trailing bytes contained in the argument. + +If the argument is omitted or None, strip leading and trailing ASCII whitespace. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_strip__doc__, +"strip(bytes=None)\n" +"Strip leading and trailing bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip leading and trailing ASCII whitespace."); + +#define BYTEARRAY_STRIP_METHODDEF \ + {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, bytearray_strip__doc__}, + static PyObject * -bytearray_strip(PyByteArrayObject *self, PyObject *args) +bytearray_strip_impl(PyObject *self, PyObject *bytes); + +static PyObject * +bytearray_strip(PyObject *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(PyObject *self, PyObject *bytes) +/*[clinic end generated code: checksum=fa940676574190dd8b3b49ebc62fb9ae83b4314b]*/ +{ + 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(arg, &varg) < 0) + if (_getbuffer(bytes, &vbytes) < 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); - left = lstrip_helper(myptr, mysize, argptr, argsize); + left = lstrip_helper(myptr, mysize, bytesptr, byteslen); if (left == mysize) right = left; else - right = rstrip_helper(myptr, mysize, argptr, argsize); - if (arg != Py_None) - PyBuffer_Release(&varg); + right = rstrip_helper(myptr, mysize, bytesptr, byteslen); + if (bytes != Py_None) + PyBuffer_Release(&vbytes); return PyByteArray_FromStringAndSize(myptr + left, right - left); } -PyDoc_STRVAR(lstrip__doc__, -"B.lstrip([bytes]) -> bytearray\n\ -\n\ -Strip leading bytes contained in the argument\n\ -and return the result as a new bytearray.\n\ -If the argument is omitted, strip leading ASCII whitespace."); +/*[clinic input] +bytearray.lstrip + + bytes: object = None + / + +Strip leading bytes contained in the argument. + +If the argument is omitted or None, strip leading ASCII whitespace. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_lstrip__doc__, +"lstrip(bytes=None)\n" +"Strip leading bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip leading ASCII whitespace."); + +#define BYTEARRAY_LSTRIP_METHODDEF \ + {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, bytearray_lstrip__doc__}, + static PyObject * -bytearray_lstrip(PyByteArrayObject *self, PyObject *args) +bytearray_lstrip_impl(PyObject *self, PyObject *bytes); + +static PyObject * +bytearray_lstrip(PyObject *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(PyObject *self, PyObject *bytes) +/*[clinic end generated code: checksum=37481269ed0d3ae422f21a623dad516dce686d4c]*/ +{ + 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(arg, &varg) < 0) + if (_getbuffer(bytes, &vbytes) < 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); - left = lstrip_helper(myptr, mysize, argptr, argsize); + left = lstrip_helper(myptr, mysize, bytesptr, byteslen); right = mysize; - if (arg != Py_None) - PyBuffer_Release(&varg); + if (bytes != Py_None) + PyBuffer_Release(&vbytes); return PyByteArray_FromStringAndSize(myptr + left, right - left); } -PyDoc_STRVAR(rstrip__doc__, -"B.rstrip([bytes]) -> bytearray\n\ -\n\ -Strip trailing bytes contained in the argument\n\ -and return the result as a new bytearray.\n\ -If the argument is omitted, strip trailing ASCII whitespace."); +/*[clinic input] +bytearray.rstrip + + bytes: object = None + / + +Strip trailing bytes contained in the argument. + +If the argument is omitted or None, strip trailing ASCII whitespace. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_rstrip__doc__, +"rstrip(bytes=None)\n" +"Strip trailing bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip trailing ASCII whitespace."); + +#define BYTEARRAY_RSTRIP_METHODDEF \ + {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, bytearray_rstrip__doc__}, + static PyObject * -bytearray_rstrip(PyByteArrayObject *self, PyObject *args) +bytearray_rstrip_impl(PyObject *self, PyObject *bytes); + +static PyObject * +bytearray_rstrip(PyObject *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(PyObject *self, PyObject *bytes) +/*[clinic end generated code: checksum=575a61a8024f222ba1b8de9e33c34cad461eca62]*/ +{ + 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(arg, &varg) < 0) + if (_getbuffer(bytes, &vbytes) < 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); - right = rstrip_helper(myptr, mysize, argptr, argsize); - if (arg != Py_None) - PyBuffer_Release(&varg); + right = rstrip_helper(myptr, mysize, bytesptr, byteslen); + if (bytes != Py_None) + PyBuffer_Release(&vbytes); return PyByteArray_FromStringAndSize(myptr, right); } -PyDoc_STRVAR(decode_doc, -"B.decode(encoding='utf-8', errors='strict') -> str\n\ -\n\ -Decode B using the codec registered for encoding. Default encoding\n\ -is 'utf-8'. errors may be given to set a different error\n\ -handling scheme. Default is 'strict' meaning that encoding errors raise\n\ -a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\ -as well as any other name registered with codecs.register_error that is\n\ -able to handle UnicodeDecodeErrors."); +/*[clinic input] +bytearray.decode + + encoding: str(c_default="NULL") = 'utf-8' + The encoding with which to decode the bytearray. + errors: str(c_default="NULL") = 'strict' + The error handling scheme to use for the handling of decoding errors. + The default is 'strict' meaning that decoding errors raise a + UnicodeDecodeError. Other possible values are 'ignore' and 'replace' + as well as any other name registered with codecs.register_error that + can handle UnicodeDecodeErrors. + +Decode the bytearray using the codec registered for encoding. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_decode__doc__, +"decode(encoding=\'utf-8\', errors=\'strict\')\n" +"Decode the bytearray using the codec registered for encoding.\n" +"\n" +" encoding\n" +" The encoding with which to decode the bytearray.\n" +" errors\n" +" The error handling scheme to use for the handling of decoding errors.\n" +" The default is \'strict\' meaning that decoding errors raise a\n" +" UnicodeDecodeError. Other possible values are \'ignore\' and \'replace\'\n" +" as well as any other name registered with codecs.register_error that\n" +" can handle UnicodeDecodeErrors."); + +#define BYTEARRAY_DECODE_METHODDEF \ + {"decode", (PyCFunction)bytearray_decode, METH_VARARGS|METH_KEYWORDS, bytearray_decode__doc__}, + +static PyObject * +bytearray_decode_impl(PyObject *self, const char *encoding, const char *errors); static PyObject * bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject *return_value = NULL; + static char *_keywords[] = {"encoding", "errors", NULL}; const char *encoding = NULL; const char *errors = NULL; - static char *kwlist[] = {"encoding", "errors", 0}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors)) - return NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|ss:decode", _keywords, + &encoding, &errors)) + goto exit; + return_value = bytearray_decode_impl(self, encoding, errors); + +exit: + return return_value; +} + +static PyObject * +bytearray_decode_impl(PyObject *self, const char *encoding, const char *errors) +/*[clinic end generated code: checksum=a78f8ada1c65fdcbd53829d0a30316dc6562099d]*/ +{ if (encoding == NULL) encoding = PyUnicode_GetDefaultEncoding(); return PyUnicode_FromEncodedObject(self, encoding, errors); @@ -2615,48 +3200,88 @@ return PyLong_FromSsize_t(self->ob_alloc); } -PyDoc_STRVAR(join_doc, -"B.join(iterable_of_bytes) -> bytearray\n\ -\n\ -Concatenate any number of bytes/bytearray objects, with B\n\ -in between each pair, and return the result as a new bytearray."); +/*[clinic input] +bytearray.join + + iterable_of_bytes: object + / + +Concatenate any number of bytes/bytearray objects. + +The bytearray whose method is called is inserted in between each pair. + +The result is returned as a new bytearray object. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_join__doc__, +"join(iterable_of_bytes)\n" +"Concatenate any number of bytes/bytearray objects.\n" +"\n" +"The bytearray whose method is called is inserted in between each pair.\n" +"\n" +"The result is returned as a new bytearray object."); + +#define BYTEARRAY_JOIN_METHODDEF \ + {"join", (PyCFunction)bytearray_join, METH_O, bytearray_join__doc__}, static PyObject * -bytearray_join(PyObject *self, PyObject *iterable) +bytearray_join(PyObject *self, PyObject *iterable_of_bytes) +/*[clinic end generated code: checksum=186386e0aaa621a816b922b3978588c485434d8c]*/ { - return stringlib_bytes_join(self, iterable); + return stringlib_bytes_join(self, iterable_of_bytes); } -PyDoc_STRVAR(splitlines__doc__, -"B.splitlines([keepends]) -> list of lines\n\ -\n\ -Return a list of the lines in B, breaking at line boundaries.\n\ -Line breaks are not included in the resulting list unless keepends\n\ -is given and true."); - -static PyObject* -bytearray_splitlines(PyObject *self, PyObject *args, PyObject *kwds) +/*[clinic input] +bytearray.splitlines + + keepends: int(py_default="False") = 0 + +Return a list of the lines in the bytearray, breaking at line boundaries. + +Line breaks are not included in the resulting list unless keepends is given and +true. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_splitlines__doc__, +"splitlines(keepends=False)\n" +"Return a list of the lines in the bytearray, breaking at line boundaries.\n" +"\n" +"Line breaks are not included in the resulting list unless keepends is given and\n" +"true."); + +#define BYTEARRAY_SPLITLINES_METHODDEF \ + {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS|METH_KEYWORDS, bytearray_splitlines__doc__}, + +static PyObject * +bytearray_splitlines_impl(PyObject *self, int keepends); + +static PyObject * +bytearray_splitlines(PyObject *self, PyObject *args, PyObject *kwargs) { - static char *kwlist[] = {"keepends", 0}; + PyObject *return_value = NULL; + static char *_keywords[] = {"keepends", NULL}; int keepends = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines", - kwlist, &keepends)) - return NULL; - + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|i:splitlines", _keywords, + &keepends)) + goto exit; + return_value = bytearray_splitlines_impl(self, keepends); + +exit: + return return_value; +} + +static PyObject * +bytearray_splitlines_impl(PyObject *self, int keepends) +/*[clinic end generated code: checksum=423e427f10cbec9e353b2dcc5618bfbe83d88aad]*/ +{ return stringlib_splitlines( (PyObject*) self, PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), keepends ); } -PyDoc_STRVAR(fromhex_doc, -"bytearray.fromhex(string) -> bytearray (static method)\n\ -\n\ -Create a bytearray object from a string of hexadecimal numbers.\n\ -Spaces between two numbers are accepted.\n\ -Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')."); - static int hex_digit_to_int(Py_UCS4 c) { @@ -2673,24 +3298,66 @@ return -1; } +/*[clinic input] +@classmethod +bytearray.fromhex + + cls: self(type="PyObject*") + string: unicode + / + +Create a bytearray object from a string of hexadecimal numbers. + +Spaces between two numbers are accepted. +Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef') +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_fromhex__doc__, +"fromhex(string)\n" +"Create a bytearray object from a string of hexadecimal numbers.\n" +"\n" +"Spaces between two numbers are accepted.\n" +"Example: bytearray.fromhex(\'B9 01EF\') -> bytearray(b\'\\xb9\\x01\\xef\')"); + +#define BYTEARRAY_FROMHEX_METHODDEF \ + {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS, bytearray_fromhex__doc__}, + static PyObject * -bytearray_fromhex(PyObject *cls, PyObject *args) +bytearray_fromhex_impl(PyObject*cls, PyObject *string); + +static PyObject * +bytearray_fromhex(PyTypeObject *cls, PyObject *args) { - PyObject *newbytes, *hexobj; + PyObject *return_value = NULL; + PyObject *string; + + if (!PyArg_ParseTuple(args, + "U:fromhex", + &string)) + goto exit; + return_value = bytearray_fromhex_impl((PyObject*)cls, string); + +exit: + return return_value; +} + +static PyObject * +bytearray_fromhex_impl(PyObject*cls, PyObject *string) +/*[clinic end generated code: checksum=538abd550900a73b4cfd1125ecdfc4c20ca9db00]*/ +{ + PyObject *newbytes; char *buf; Py_ssize_t hexlen, byteslen, i, j; int top, bot; void *data; unsigned int kind; - if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj)) + assert(PyUnicode_Check(string)); + if (PyUnicode_READY(string)) return NULL; - assert(PyUnicode_Check(hexobj)); - if (PyUnicode_READY(hexobj)) - return NULL; - kind = PyUnicode_KIND(hexobj); - data = PyUnicode_DATA(hexobj); - hexlen = PyUnicode_GET_LENGTH(hexobj); + kind = PyUnicode_KIND(string); + data = PyUnicode_DATA(string); + hexlen = PyUnicode_GET_LENGTH(string); byteslen = hexlen/2; /* This overestimates if there are spaces */ newbytes = PyByteArray_FromStringAndSize(NULL, byteslen); @@ -2758,33 +3425,107 @@ } } -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); +/*[clinic input] +bytearray.__reduce__ as bytearray_reduce + + self: self(type="PyByteArrayObject *") + +Return state information for pickling. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_reduce__doc__, +"__reduce__()\n" +"Return state information for pickling."); + +#define BYTEARRAY_REDUCE_METHODDEF \ + {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, bytearray_reduce__doc__}, static PyObject * -bytearray_reduce(PyByteArrayObject *self) +bytearray_reduce_impl(PyByteArrayObject *self); + +static PyObject * +bytearray_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytearray_reduce_impl((PyByteArrayObject *)self); +} + +static PyObject * +bytearray_reduce_impl(PyByteArrayObject *self) +/*[clinic end generated code: checksum=2a385adcdcdfa4f1de431d31a4a0546084236fef]*/ { return _common_reduce(self, 2); } -PyDoc_STRVAR(reduce_ex_doc, "Return state information for pickling."); +/*[clinic input] +bytearray.__reduce_ex__ as bytearray_reduce_ex + + self: self(type="PyByteArrayObject *") + proto: int = 0 + / + +Return state information for pickling. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_reduce_ex__doc__, +"__reduce_ex__(proto=0)\n" +"Return state information for pickling."); + +#define BYTEARRAY_REDUCE_EX_METHODDEF \ + {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, bytearray_reduce_ex__doc__}, static PyObject * -bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args) +bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto); + +static PyObject * +bytearray_reduce_ex(PyObject *self, PyObject *args) { + PyObject *return_value = NULL; int proto = 0; - if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto)) - return NULL; - + if (!PyArg_ParseTuple(args, + "|i:__reduce_ex__", + &proto)) + goto exit; + return_value = bytearray_reduce_ex_impl((PyByteArrayObject *)self, proto); + +exit: + return return_value; +} + +static PyObject * +bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto) +/*[clinic end generated code: checksum=4056764dba517ca1121c9a2887a8bfa7878a1bea]*/ +{ return _common_reduce(self, proto); } -PyDoc_STRVAR(sizeof_doc, -"B.__sizeof__() -> int\n\ - \n\ -Returns the size of B in memory, in bytes"); +/*[clinic input] +bytearray.__sizeof__ as bytearray_sizeof + + self: self(type="PyByteArrayObject *") + +Returns the size of the bytearray object in memory, in bytes. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_sizeof__doc__, +"__sizeof__()\n" +"Returns the size of the bytearray object in memory, in bytes."); + +#define BYTEARRAY_SIZEOF_METHODDEF \ + {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, bytearray_sizeof__doc__}, + static PyObject * -bytearray_sizeof(PyByteArrayObject *self) +bytearray_sizeof_impl(PyByteArrayObject *self); + +static PyObject * +bytearray_sizeof(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytearray_sizeof_impl((PyByteArrayObject *)self); +} + +static PyObject * +bytearray_sizeof_impl(PyByteArrayObject *self) +/*[clinic end generated code: checksum=a16502aa092ad934b80b84c5fa29531699fb7e05]*/ { Py_ssize_t res; @@ -2819,26 +3560,25 @@ static PyMethodDef bytearray_methods[] = { {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc}, - {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc}, - {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, reduce_ex_doc}, - {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc}, - {"append", (PyCFunction)bytearray_append, METH_O, append__doc__}, + BYTEARRAY_REDUCE_METHODDEF + BYTEARRAY_REDUCE_EX_METHODDEF + BYTEARRAY_SIZEOF_METHODDEF + BYTEARRAY_APPEND_METHODDEF {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, clear__doc__}, {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, copy__doc__}, {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc}, + BYTEARRAY_DECODE_METHODDEF {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__}, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS, expandtabs__doc__}, - {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__}, + BYTEARRAY_EXTEND_METHODDEF {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__}, - {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS, - fromhex_doc}, + BYTEARRAY_FROMHEX_METHODDEF {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__}, - {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__}, + BYTEARRAY_INSERT_METHODDEF {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS, @@ -2853,34 +3593,31 @@ _Py_istitle__doc__}, {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, _Py_isupper__doc__}, - {"join", (PyCFunction)bytearray_join, METH_O, join_doc}, + BYTEARRAY_JOIN_METHODDEF {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, - {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__}, - {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC, - _Py_maketrans__doc__}, - {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__}, - {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__}, - {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__}, - {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__}, - {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__}, + BYTEARRAY_LSTRIP_METHODDEF + BYTEARRAY_MAKETRANS_METHODDEF + BYTEARRAY_PARTITION_METHODDEF + BYTEARRAY_POP_METHODDEF + BYTEARRAY_REMOVE_METHODDEF + BYTEARRAY_REPLACE_METHODDEF + BYTEARRAY_REVERSE_METHODDEF {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__}, {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__}, {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, - {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__}, - {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__}, - {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__}, - {"split", (PyCFunction)bytearray_split, METH_VARARGS | METH_KEYWORDS, split__doc__}, - {"splitlines", (PyCFunction)bytearray_splitlines, - METH_VARARGS | METH_KEYWORDS, splitlines__doc__}, + BYTEARRAY_RPARTITION_METHODDEF + BYTEARRAY_RSPLIT_METHODDEF + BYTEARRAY_RSTRIP_METHODDEF + BYTEARRAY_SPLIT_METHODDEF + BYTEARRAY_SPLITLINES_METHODDEF {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS , startswith__doc__}, - {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__}, + BYTEARRAY_STRIP_METHODDEF {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, - translate__doc__}, + BYTEARRAY_TRANSLATE_METHODDEF {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, {NULL} @@ -3037,7 +3774,7 @@ {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS, length_hint_doc}, {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS, - reduce_doc}, + bytearray_reduce__doc__}, {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O, setstate_doc}, {NULL, NULL} /* sentinel */ diff -r 967f368b7f75 Objects/bytes_methods.c --- a/Objects/bytes_methods.c Sun Jan 19 00:38:36 2014 +0200 +++ b/Objects/bytes_methods.c Tue Jan 21 21:40:45 2014 +0200 @@ -382,9 +382,9 @@ } PyObject * -_Py_bytes_maketrans(PyObject *args) +_Py_bytes_maketrans(PyObject *frm, PyObject *to) { - PyObject *frm, *to, *res = NULL; + PyObject *res = NULL; Py_buffer bfrm, bto; Py_ssize_t i; char *p; @@ -392,8 +392,6 @@ bfrm.len = -1; bto.len = -1; - if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to)) - return NULL; if (_getbuffer(frm, &bfrm) < 0) return NULL; if (_getbuffer(to, &bto) < 0) diff -r 967f368b7f75 Objects/bytesobject.c --- a/Objects/bytesobject.c Sun Jan 19 00:38:36 2014 +0200 +++ b/Objects/bytesobject.c Tue Jan 21 21:40:45 2014 +0200 @@ -7,6 +7,11 @@ #include "bytes_methods.h" #include +/*[clinic input] +class bytes +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + static Py_ssize_t _getbuffer(PyObject *obj, Py_buffer *view) { @@ -1014,37 +1019,70 @@ #define RIGHTSTRIP 1 #define BOTHSTRIP 2 -/* Arrays indexed by above */ -static const char *stripformat[] = {"|O:lstrip", "|O:rstrip", "|O:strip"}; - -#define STRIPNAME(i) (stripformat[i]+3) - -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."); +/*[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(sep=None, maxsplit=-1)\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__}, static PyObject * -bytes_split(PyBytesObject *self, PyObject *args, PyObject *kwds) +bytes_split_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit); + +static PyObject * +bytes_split(PyObject *self, PyObject *args, PyObject *kwargs) { - static char *kwlist[] = {"sep", "maxsplit", 0}; + 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_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: checksum=0c1bf4dba4fc7e03254d9c2f670d8e2682b38785]*/ +{ 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; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split", - kwlist, &subobj, &maxsplit)) - return NULL; + PyObject *list; + 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(subobj, &vsub) < 0) + if (_getbuffer(sep, &vsub) < 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -1054,89 +1092,170 @@ 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 + / + +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(sep)\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__}, static PyObject * -bytes_partition(PyBytesObject *self, PyObject *sep_obj) +bytes_partition(PyBytesObject *self, PyObject *sep) +/*[clinic end generated code: checksum=02ddd49338037b02d203b165fb2e48c6eb779983]*/ { - const char *sep; + const char *sep_chars; Py_ssize_t sep_len; - if (PyBytes_Check(sep_obj)) { - sep = PyBytes_AS_STRING(sep_obj); - sep_len = PyBytes_GET_SIZE(sep_obj); + if (PyBytes_Check(sep)) { + sep_chars = PyBytes_AS_STRING(sep); + sep_len = PyBytes_GET_SIZE(sep); } - else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len)) + else if (PyObject_AsCharBuffer(sep, &sep_chars, &sep_len)) return NULL; return stringlib_partition( (PyObject*) self, PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sep_obj, sep, sep_len + sep, sep_chars, sep_len ); } -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 + / + +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(sep)\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__}, static PyObject * -bytes_rpartition(PyBytesObject *self, PyObject *sep_obj) +bytes_rpartition(PyBytesObject *self, PyObject *sep) +/*[clinic end generated code: checksum=af06be67ab873c2792db9961f504350bc99f126a]*/ { - const char *sep; + const char *sep_chars; Py_ssize_t sep_len; - if (PyBytes_Check(sep_obj)) { - sep = PyBytes_AS_STRING(sep_obj); - sep_len = PyBytes_GET_SIZE(sep_obj); + if (PyBytes_Check(sep)) { + sep_chars = PyBytes_AS_STRING(sep); + sep_len = PyBytes_GET_SIZE(sep); } - else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len)) + else if (PyObject_AsCharBuffer(sep, &sep_chars, &sep_len)) return NULL; return stringlib_rpartition( (PyObject*) self, PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sep_obj, sep, sep_len + sep, sep_chars, sep_len ); } -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(sep=None, maxsplit=-1)\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(PyBytesObject *self, PyObject *args, PyObject *kwds) +bytes_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit); + +static PyObject * +bytes_rsplit(PyObject *self, PyObject *args, PyObject *kwargs) { - static char *kwlist[] = {"sep", "maxsplit", 0}; + 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(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: checksum=f5bcee1d73b31b9df8821731f4ed3a8d1bc78588]*/ +{ 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; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit", - kwlist, &subobj, &maxsplit)) - return NULL; + PyObject *list; + 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(subobj, &vsub) < 0) + if (_getbuffer(sep, &vsub) < 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -1147,16 +1266,39 @@ } -PyDoc_STRVAR(join__doc__, -"B.join(iterable_of_bytes) -> bytes\n\ -\n\ -Concatenate any number of bytes objects, with B in between each pair.\n\ -Example: b'.'.join([b'ab', b'pq', b'rs']) -> b'ab.pq.rs'."); +/*[clinic input] +bytes.join + + iterable_of_bytes: object + / + +Concatenate any number of bytes objects. + +The bytes whose method is called is inserted in between each pair. + +The result is returned as a new bytes object. + +Example: b'.'.join([b'ab', b'pq', b'rs']) -> b'ab.pq.rs'. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_join__doc__, +"join(iterable_of_bytes)\n" +"Concatenate any number of bytes objects.\n" +"\n" +"The bytes whose method is called is inserted in between each pair.\n" +"\n" +"The result is returned as a new bytes object.\n" +"\n" +"Example: b\'.\'.join([b\'ab\', b\'pq\', b\'rs\']) -> b\'ab.pq.rs\'."); + +#define BYTES_JOIN_METHODDEF \ + {"join", (PyCFunction)bytes_join, METH_O, bytes_join__doc__}, static PyObject * -bytes_join(PyObject *self, PyObject *iterable) +bytes_join(PyObject *self, PyObject *iterable_of_bytes) +/*[clinic end generated code: checksum=3fa2b5fc3b1494ba4db416303571f4ecd055090b]*/ { - return stringlib_bytes_join(self, iterable); + return stringlib_bytes_join(self, iterable_of_bytes); } PyObject * @@ -1375,62 +1517,153 @@ Py_LOCAL_INLINE(PyObject *) -do_argstrip(PyBytesObject *self, int striptype, PyObject *args) +do_argstrip(PyBytesObject *self, int striptype, PyObject *bytes) { - PyObject *sep = NULL; - - if (!PyArg_ParseTuple(args, stripformat[striptype], &sep)) - return NULL; - - if (sep != NULL && sep != Py_None) { - return do_xstrip(self, striptype, sep); + if (bytes != NULL && bytes != Py_None) { + return do_xstrip(self, striptype, bytes); } return do_strip(self, striptype); } - -PyDoc_STRVAR(strip__doc__, -"B.strip([bytes]) -> bytes\n\ -\n\ -Strip leading and trailing bytes contained in the argument.\n\ -If the argument is omitted, strip leading and trailing ASCII whitespace."); +/*[clinic input] +bytes.strip + + self: self(type="PyBytesObject *") + bytes: object = None + / + +Strip leading and trailing bytes contained in the argument. + +If the argument is omitted or None, strip leading and trailing ASCII whitespace. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_strip__doc__, +"strip(bytes=None)\n" +"Strip leading and trailing bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip leading and trailing ASCII whitespace."); + +#define BYTES_STRIP_METHODDEF \ + {"strip", (PyCFunction)bytes_strip, METH_VARARGS, bytes_strip__doc__}, + static PyObject * -bytes_strip(PyBytesObject *self, PyObject *args) +bytes_strip_impl(PyBytesObject *self, PyObject *bytes); + +static PyObject * +bytes_strip(PyObject *self, PyObject *args) { - if (PyTuple_GET_SIZE(args) == 0) - return do_strip(self, BOTHSTRIP); /* Common case */ - else - return do_argstrip(self, BOTHSTRIP, args); + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "strip", + 0, 1, + &bytes)) + goto exit; + return_value = bytes_strip_impl((PyBytesObject *)self, bytes); + +exit: + return return_value; } - -PyDoc_STRVAR(lstrip__doc__, -"B.lstrip([bytes]) -> bytes\n\ -\n\ -Strip leading bytes contained in the argument.\n\ -If the argument is omitted, strip leading ASCII whitespace."); static PyObject * -bytes_lstrip(PyBytesObject *self, PyObject *args) +bytes_strip_impl(PyBytesObject *self, PyObject *bytes) +/*[clinic end generated code: checksum=3c59229e9332a1782987f047d43a9526a3b3c90f]*/ { - if (PyTuple_GET_SIZE(args) == 0) - return do_strip(self, LEFTSTRIP); /* Common case */ - else - return do_argstrip(self, LEFTSTRIP, args); + return do_argstrip(self, BOTHSTRIP, bytes); } - -PyDoc_STRVAR(rstrip__doc__, -"B.rstrip([bytes]) -> bytes\n\ -\n\ -Strip trailing bytes contained in the argument.\n\ -If the argument is omitted, strip trailing ASCII whitespace."); +/*[clinic input] +bytes.lstrip + + self: self(type="PyBytesObject *") + bytes: object = None + / + +Strip leading bytes contained in the argument. + +If the argument is omitted or None, strip leading ASCII whitespace. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_lstrip__doc__, +"lstrip(bytes=None)\n" +"Strip leading bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip leading ASCII whitespace."); + +#define BYTES_LSTRIP_METHODDEF \ + {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, bytes_lstrip__doc__}, + static PyObject * -bytes_rstrip(PyBytesObject *self, PyObject *args) +bytes_lstrip_impl(PyBytesObject *self, PyObject *bytes); + +static PyObject * +bytes_lstrip(PyObject *self, PyObject *args) { - if (PyTuple_GET_SIZE(args) == 0) - return do_strip(self, RIGHTSTRIP); /* Common case */ - else - return do_argstrip(self, RIGHTSTRIP, args); + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "lstrip", + 0, 1, + &bytes)) + goto exit; + return_value = bytes_lstrip_impl((PyBytesObject *)self, bytes); + +exit: + return return_value; +} + +static PyObject * +bytes_lstrip_impl(PyBytesObject *self, PyObject *bytes) +/*[clinic end generated code: checksum=34a0a2cae35c06ad984c5657659d4d28ec0e407a]*/ +{ + return do_argstrip(self, LEFTSTRIP, bytes); +} + +/*[clinic input] +bytes.rstrip + + self: self(type="PyBytesObject *") + bytes: object = None + / + +Strip trailing bytes contained in the argument. + +If the argument is omitted or None, strip trailing ASCII whitespace. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_rstrip__doc__, +"rstrip(bytes=None)\n" +"Strip trailing bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip trailing ASCII whitespace."); + +#define BYTES_RSTRIP_METHODDEF \ + {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, bytes_rstrip__doc__}, + +static PyObject * +bytes_rstrip_impl(PyBytesObject *self, PyObject *bytes); + +static PyObject * +bytes_rstrip(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "rstrip", + 0, 1, + &bytes)) + goto exit; + return_value = bytes_rstrip_impl((PyBytesObject *)self, bytes); + +exit: + return return_value; +} + +static PyObject * +bytes_rstrip_impl(PyBytesObject *self, PyObject *bytes) +/*[clinic end generated code: checksum=eeb1b0cff2f4bfbad7324eea81dd9dec2a872ad6]*/ +{ + return do_argstrip(self, RIGHTSTRIP, bytes); } @@ -1482,40 +1715,88 @@ } -PyDoc_STRVAR(translate__doc__, -"B.translate(table[, deletechars]) -> bytes\n\ -\n\ -Return a copy of B, where all characters occurring in the\n\ -optional argument deletechars are removed, and the remaining\n\ -characters have been mapped through the given translation\n\ -table, which must be a bytes object of length 256."); +/*[clinic input] +bytes.translate + + self: self(type="PyBytesObject *") + table: object + Translation table, which must be a bytes object of length 256. + [ + deletechars: object + ] + / + +Return a copy with each character mapped by the given translation table. + +All characters occurring in the optional argument deletechars are removed. +The remaining characters are mapped through the given translation table. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_translate__doc__, +"translate(table, [deletechars])\n" +"Return a copy with each character mapped by the given translation table.\n" +"\n" +" table\n" +" Translation table, which must be a bytes object of length 256.\n" +"\n" +"All characters occurring in the optional argument deletechars are removed.\n" +"The remaining characters are mapped through the given translation table."); + +#define BYTES_TRANSLATE_METHODDEF \ + {"translate", (PyCFunction)bytes_translate, METH_VARARGS, bytes_translate__doc__}, static PyObject * -bytes_translate(PyBytesObject *self, PyObject *args) +bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, PyObject *deletechars); + +static PyObject * +bytes_translate(PyObject *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)) + return NULL; + break; + case 2: + if (!PyArg_ParseTuple(args, "OO:translate", &table, &deletechars)) + return NULL; + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "bytes.translate requires 1 to 2 arguments"); + return NULL; + } + return_value = bytes_translate_impl((PyBytesObject *)self, table, group_right_1, deletechars); + + return return_value; +} + +static PyObject * +bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, PyObject *deletechars) +/*[clinic end generated code: checksum=5ebfc00fffd8122849d1e02ee784c29a7228f0bb]*/ { char *input, *output; - const char *table; + 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(tableobj, &table, &tablen)) + else if (PyObject_AsCharBuffer(table, &table_chars, &tablen)) return NULL; if (tablen != 256) { @@ -1524,16 +1805,16 @@ 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(delobj, &del_table, &dellen)) + else if (PyObject_AsCharBuffer(deletechars, &del_table_chars, &dellen)) return NULL; } else { - del_table = NULL; + del_table_chars = NULL; dellen = 0; } @@ -1544,11 +1825,11 @@ output_start = output = PyBytes_AsString(result); input = PyBytes_AS_STRING(input_obj); - if (dellen == 0 && table != NULL) { + if (dellen == 0 && table_chars != NULL) { /* 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)) @@ -1558,16 +1839,16 @@ return input_obj; } - 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]); } 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; for (i = inlen; --i >= 0; ) { c = Py_CHARMASK(*input++); @@ -1588,10 +1869,60 @@ } +/*[clinic input] + +@staticmethod +bytes.maketrans + + frm: object + to: object + / + +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" +"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(PyObject *null, PyObject *args) +bytes_maketrans_impl(void *null, PyObject *frm, PyObject *to); + +static PyObject * +bytes_maketrans(void *null, PyObject *args) { - return _Py_bytes_maketrans(args); + PyObject *return_value = NULL; + PyObject *frm; + PyObject *to; + + if (!PyArg_UnpackTuple(args, "maketrans", + 2, 2, + &frm, &to)) + goto exit; + return_value = bytes_maketrans_impl(null, frm, to); + +exit: + return return_value; +} + +static PyObject * +bytes_maketrans_impl(void *null, PyObject *frm, PyObject *to) +/*[clinic end generated code: checksum=79a066bfdc71b55bd4bc8bce540e34a57ac53a8d]*/ +{ + return _Py_bytes_maketrans(frm, to); } /* find and count characters and substrings */ @@ -2086,41 +2417,82 @@ } } -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 + 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(old, new, count=-1)\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(PyBytesObject *self, PyObject *args) +bytes_replace_impl(PyObject *self, PyObject *old, PyObject *new, Py_ssize_t count); + +static PyObject * +bytes_replace(PyObject *self, PyObject *args) { + PyObject *return_value = NULL; + PyObject *old; + PyObject *new; Py_ssize_t count = -1; - PyObject *from, *to; - const char *from_s, *to_s; - Py_ssize_t from_len, to_len; - - if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count)) + + if (!PyArg_ParseTuple(args, + "OO|n:replace", + &old, &new, &count)) + goto exit; + return_value = bytes_replace_impl(self, old, new, count); + +exit: + return return_value; +} + +static PyObject * +bytes_replace_impl(PyObject *self, PyObject *old, PyObject *new, Py_ssize_t count) +/*[clinic end generated code: checksum=a4dfe745baf7f8a8e6d98d3ed6cb838c588c4caa]*/ +{ + 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(from)) { - from_s = PyBytes_AS_STRING(from); - from_len = PyBytes_GET_SIZE(from); + if (PyBytes_Check(new)) { + new_s = PyBytes_AS_STRING(new); + new_len = PyBytes_GET_SIZE(new); } - else if (PyObject_AsCharBuffer(from, &from_s, &from_len)) + else if (PyObject_AsCharBuffer(new, &new_s, &new_len)) return NULL; - if (PyBytes_Check(to)) { - to_s = PyBytes_AS_STRING(to); - to_len = PyBytes_GET_SIZE(to); - } - else if (PyObject_AsCharBuffer(to, &to_s, &to_len)) - return NULL; - return (PyObject *)replace((PyBytesObject *) self, - from_s, from_len, - to_s, to_len, count); + old_s, old_len, + new_s, new_len, count); } /** End DALKE **/ @@ -2254,60 +2626,117 @@ } -PyDoc_STRVAR(decode__doc__, -"B.decode(encoding='utf-8', errors='strict') -> str\n\ -\n\ -Decode B using the codec registered for encoding. Default encoding\n\ -is 'utf-8'. errors may be given to set a different error\n\ -handling scheme. Default is 'strict' meaning that encoding errors raise\n\ -a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\ -as well as any other name registerd with codecs.register_error that is\n\ -able to handle UnicodeDecodeErrors."); +/*[clinic input] +bytes.decode + + encoding: str(c_default="NULL") = 'utf-8' + The encoding with which to decode the bytes. + errors: str(c_default="NULL") = 'strict' + The error handling scheme to use for the handling of decoding errors. + The default is 'strict' meaning that decoding errors raise a + UnicodeDecodeError. Other possible values are 'ignore' and 'replace' + as well as any other name registered with codecs.register_error that + can handle UnicodeDecodeErrors. + +Decode the bytes using the codec registered for encoding. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_decode__doc__, +"decode(encoding=\'utf-8\', errors=\'strict\')\n" +"Decode the bytes using the codec registered for encoding.\n" +"\n" +" encoding\n" +" The encoding with which to decode the bytes.\n" +" errors\n" +" The error handling scheme to use for the handling of decoding errors.\n" +" The default is \'strict\' meaning that decoding errors raise a\n" +" UnicodeDecodeError. Other possible values are \'ignore\' and \'replace\'\n" +" as well as any other name registered with codecs.register_error that\n" +" can handle UnicodeDecodeErrors."); + +#define BYTES_DECODE_METHODDEF \ + {"decode", (PyCFunction)bytes_decode, METH_VARARGS|METH_KEYWORDS, bytes_decode__doc__}, + +static PyObject * +bytes_decode_impl(PyObject *self, const char *encoding, const char *errors); static PyObject * bytes_decode(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject *return_value = NULL; + static char *_keywords[] = {"encoding", "errors", NULL}; const char *encoding = NULL; const char *errors = NULL; - static char *kwlist[] = {"encoding", "errors", 0}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors)) - return NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|ss:decode", _keywords, + &encoding, &errors)) + goto exit; + return_value = bytes_decode_impl(self, encoding, errors); + +exit: + return return_value; +} + +static PyObject * +bytes_decode_impl(PyObject *self, const char *encoding, const char *errors) +/*[clinic end generated code: checksum=b6efcc4420539a09d08df3aa733696a7119a22c7]*/ +{ return PyUnicode_FromEncodedObject(self, encoding, errors); } -PyDoc_STRVAR(splitlines__doc__, -"B.splitlines([keepends]) -> list of lines\n\ -\n\ -Return a list of the lines in B, breaking at line boundaries.\n\ -Line breaks are not included in the resulting list unless keepends\n\ -is given and true."); - -static PyObject* -bytes_splitlines(PyObject *self, PyObject *args, PyObject *kwds) +/*[clinic input] +bytes.splitlines + + keepends: int(py_default="False") = 0 + +Return a list of the lines in the bytes, breaking at line boundaries. + +Line breaks are not included in the resulting list unless keepends is given and +true. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_splitlines__doc__, +"splitlines(keepends=False)\n" +"Return a list of the lines in the bytes, breaking at line boundaries.\n" +"\n" +"Line breaks are not included in the resulting list unless keepends is given and\n" +"true."); + +#define BYTES_SPLITLINES_METHODDEF \ + {"splitlines", (PyCFunction)bytes_splitlines, METH_VARARGS|METH_KEYWORDS, bytes_splitlines__doc__}, + +static PyObject * +bytes_splitlines_impl(PyObject *self, int keepends); + +static PyObject * +bytes_splitlines(PyObject *self, PyObject *args, PyObject *kwargs) { - static char *kwlist[] = {"keepends", 0}; + PyObject *return_value = NULL; + static char *_keywords[] = {"keepends", NULL}; int keepends = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines", - kwlist, &keepends)) - return NULL; - + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|i:splitlines", _keywords, + &keepends)) + goto exit; + return_value = bytes_splitlines_impl(self, keepends); + +exit: + return return_value; +} + +static PyObject * +bytes_splitlines_impl(PyObject *self, int keepends) +/*[clinic end generated code: checksum=462dd01b87dcda72c538d8d89a310fcdab58cc8c]*/ +{ return stringlib_splitlines( (PyObject*) self, PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), keepends ); } - -PyDoc_STRVAR(fromhex_doc, -"bytes.fromhex(string) -> bytes\n\ -\n\ -Create a bytes object from a string of hexadecimal numbers.\n\ -Spaces between two numbers are accepted.\n\ -Example: bytes.fromhex('B9 01EF') -> b'\\xb9\\x01\\xef'."); - static int hex_digit_to_int(Py_UCS4 c) { @@ -2324,24 +2753,65 @@ return -1; } +/*[clinic input] +@classmethod +bytes.fromhex + + string: unicode + / + +Create a bytes object from a string of hexadecimal numbers. + +Spaces between two numbers are accepted. +Example: bytes.fromhex('B9 01EF') -> b'\\xb9\\x01\\xef'. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_fromhex__doc__, +"fromhex(string)\n" +"Create a bytes object from a string of hexadecimal numbers.\n" +"\n" +"Spaces between two numbers are accepted.\n" +"Example: bytes.fromhex(\'B9 01EF\') -> b\'\\xb9\\x01\\xef\'."); + +#define BYTES_FROMHEX_METHODDEF \ + {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS, bytes_fromhex__doc__}, + static PyObject * -bytes_fromhex(PyObject *cls, PyObject *args) +bytes_fromhex_impl(PyTypeObject *cls, PyObject *string); + +static PyObject * +bytes_fromhex(PyTypeObject *cls, PyObject *args) { - PyObject *newstring, *hexobj; + PyObject *return_value = NULL; + PyObject *string; + + if (!PyArg_ParseTuple(args, + "U:fromhex", + &string)) + goto exit; + return_value = bytes_fromhex_impl(cls, string); + +exit: + return return_value; +} + +static PyObject * +bytes_fromhex_impl(PyTypeObject *cls, PyObject *string) +/*[clinic end generated code: checksum=0b6825075af40e95429328af699b6aae26ecaf94]*/ +{ + PyObject *newstring; char *buf; Py_ssize_t hexlen, byteslen, i, j; int top, bot; void *data; unsigned int kind; - if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj)) + assert(PyUnicode_Check(string)); + if (PyUnicode_READY(string)) return NULL; - assert(PyUnicode_Check(hexobj)); - if (PyUnicode_READY(hexobj)) - return NULL; - kind = PyUnicode_KIND(hexobj); - data = PyUnicode_DATA(hexobj); - hexlen = PyUnicode_GET_LENGTH(hexobj); + kind = PyUnicode_KIND(string); + data = PyUnicode_DATA(string); + hexlen = PyUnicode_GET_LENGTH(string); byteslen = hexlen/2; /* This overestimates if there are spaces */ newstring = PyBytes_FromStringAndSize(NULL, byteslen); @@ -2373,14 +2843,36 @@ return NULL; } -PyDoc_STRVAR(sizeof__doc__, -"B.__sizeof__() -> size of B in memory, in bytes"); +/*[clinic input] +bytes.__sizeof__ as bytes_sizeof + + self: self(type="PyBytesObject *") + +Returns the size of the bytes object in memory, in bytes. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_sizeof__doc__, +"__sizeof__()\n" +"Returns the size of the bytes object in memory, in bytes."); + +#define BYTES_SIZEOF_METHODDEF \ + {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, bytes_sizeof__doc__}, static PyObject * -bytes_sizeof(PyBytesObject *v) +bytes_sizeof_impl(PyBytesObject *self); + +static PyObject * +bytes_sizeof(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytes_sizeof_impl((PyBytesObject *)self); +} + +static PyObject * +bytes_sizeof_impl(PyBytesObject *self) +/*[clinic end generated code: checksum=354ce9f0aa31e0fc76fa4d8ca5df234c8b78f49a]*/ { Py_ssize_t res; - res = PyBytesObject_SIZE + Py_SIZE(v) * Py_TYPE(v)->tp_itemsize; + res = PyBytesObject_SIZE + Py_SIZE(self) * Py_TYPE(self)->tp_itemsize; return PyLong_FromSsize_t(res); } @@ -2399,14 +2891,13 @@ _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, {"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)bytes_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__}, + BYTES_DECODE_METHODDEF {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, endswith__doc__}, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS, expandtabs__doc__}, {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__}, - {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS, - fromhex_doc}, + BYTES_FROMHEX_METHODDEF {"index", (PyCFunction)bytes_index, METH_VARARGS, index__doc__}, {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, @@ -2422,36 +2913,31 @@ _Py_istitle__doc__}, {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, _Py_isupper__doc__}, - {"join", (PyCFunction)bytes_join, METH_O, join__doc__}, + BYTES_JOIN_METHODDEF {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, - {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__}, - {"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC, - _Py_maketrans__doc__}, - {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__}, - {"replace", (PyCFunction)bytes_replace, METH_VARARGS, replace__doc__}, + BYTES_LSTRIP_METHODDEF + BYTES_MAKETRANS_METHODDEF + BYTES_PARTITION_METHODDEF + BYTES_REPLACE_METHODDEF {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, rfind__doc__}, {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, rindex__doc__}, {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, - {"rpartition", (PyCFunction)bytes_rpartition, METH_O, - rpartition__doc__}, - {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__}, - {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, rstrip__doc__}, - {"split", (PyCFunction)bytes_split, METH_VARARGS | METH_KEYWORDS, split__doc__}, - {"splitlines", (PyCFunction)bytes_splitlines, METH_VARARGS | METH_KEYWORDS, - splitlines__doc__}, + BYTES_RPARTITION_METHODDEF + BYTES_RSPLIT_METHODDEF + BYTES_RSTRIP_METHODDEF + BYTES_SPLIT_METHODDEF + BYTES_SPLITLINES_METHODDEF {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS, startswith__doc__}, - {"strip", (PyCFunction)bytes_strip, METH_VARARGS, strip__doc__}, + BYTES_STRIP_METHODDEF {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"translate", (PyCFunction)bytes_translate, METH_VARARGS, - translate__doc__}, + BYTES_TRANSLATE_METHODDEF {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, - {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, - sizeof__doc__}, + BYTES_SIZEOF_METHODDEF {NULL, NULL} /* sentinel */ };