bpo-41334: Convert constructors of str, bytes and bytearray to Argument Clinic (GH-21535)
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 7632cb5..3a922d3 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -2580,24 +2580,27 @@
};
static PyObject *
-bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+bytes_subtype_new(PyTypeObject *, PyObject *);
+
+/*[clinic input]
+@classmethod
+bytes.__new__ as bytes_new
+
+ source as x: object = NULL
+ encoding: str = NULL
+ errors: str = NULL
+
+[clinic start generated code]*/
static PyObject *
-bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+bytes_new_impl(PyTypeObject *type, PyObject *x, const char *encoding,
+ const char *errors)
+/*[clinic end generated code: output=1e0c471be311a425 input=f0a966d19b7262b4]*/
{
- PyObject *x = NULL;
- const char *encoding = NULL;
- const char *errors = NULL;
- PyObject *new = NULL;
+ PyObject *bytes;
PyObject *func;
Py_ssize_t size;
- static char *kwlist[] = {"source", "encoding", "errors", 0};
- if (type != &PyBytes_Type)
- return bytes_subtype_new(type, args, kwds);
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist, &x,
- &encoding, &errors))
- return NULL;
if (x == NULL) {
if (encoding != NULL || errors != NULL) {
PyErr_SetString(PyExc_TypeError,
@@ -2606,78 +2609,73 @@
"errors without a string argument");
return NULL;
}
- return PyBytes_FromStringAndSize(NULL, 0);
+ bytes = PyBytes_FromStringAndSize(NULL, 0);
}
-
- if (encoding != NULL) {
+ else if (encoding != NULL) {
/* Encode via the codec registry */
if (!PyUnicode_Check(x)) {
PyErr_SetString(PyExc_TypeError,
"encoding without a string argument");
return NULL;
}
- new = PyUnicode_AsEncodedString(x, encoding, errors);
- if (new == NULL)
- return NULL;
- assert(PyBytes_Check(new));
- return new;
+ bytes = PyUnicode_AsEncodedString(x, encoding, errors);
}
-
- if (errors != NULL) {
+ else if (errors != NULL) {
PyErr_SetString(PyExc_TypeError,
PyUnicode_Check(x) ?
"string argument without an encoding" :
"errors without a string argument");
return NULL;
}
-
/* We'd like to call PyObject_Bytes here, but we need to check for an
integer argument before deferring to PyBytes_FromObject, something
PyObject_Bytes doesn't do. */
- func = _PyObject_LookupSpecial(x, &PyId___bytes__);
- if (func != NULL) {
- new = _PyObject_CallNoArg(func);
+ else if ((func = _PyObject_LookupSpecial(x, &PyId___bytes__)) != NULL) {
+ bytes = _PyObject_CallNoArg(func);
Py_DECREF(func);
- if (new == NULL)
+ if (bytes == NULL)
return NULL;
- if (!PyBytes_Check(new)) {
+ if (!PyBytes_Check(bytes)) {
PyErr_Format(PyExc_TypeError,
- "__bytes__ returned non-bytes (type %.200s)",
- Py_TYPE(new)->tp_name);
- Py_DECREF(new);
+ "__bytes__ returned non-bytes (type %.200s)",
+ Py_TYPE(bytes)->tp_name);
+ Py_DECREF(bytes);
return NULL;
}
- return new;
}
else if (PyErr_Occurred())
return NULL;
-
- if (PyUnicode_Check(x)) {
+ else if (PyUnicode_Check(x)) {
PyErr_SetString(PyExc_TypeError,
"string argument without an encoding");
return NULL;
}
/* Is it an integer? */
- if (_PyIndex_Check(x)) {
+ else if (_PyIndex_Check(x)) {
size = PyNumber_AsSsize_t(x, PyExc_OverflowError);
if (size == -1 && PyErr_Occurred()) {
if (!PyErr_ExceptionMatches(PyExc_TypeError))
return NULL;
PyErr_Clear(); /* fall through */
+ bytes = PyBytes_FromObject(x);
}
else {
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative count");
return NULL;
}
- new = _PyBytes_FromSize(size, 1);
- if (new == NULL)
- return NULL;
- return new;
+ bytes = _PyBytes_FromSize(size, 1);
}
}
+ else {
+ bytes = PyBytes_FromObject(x);
+ }
- return PyBytes_FromObject(x);
+ if (bytes != NULL && type != &PyBytes_Type) {
+ Py_SETREF(bytes, bytes_subtype_new(type, bytes));
+ }
+
+ return bytes;
}
static PyObject*
@@ -2889,15 +2887,12 @@
}
static PyObject *
-bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+bytes_subtype_new(PyTypeObject *type, PyObject *tmp)
{
- PyObject *tmp, *pnew;
+ PyObject *pnew;
Py_ssize_t n;
assert(PyType_IsSubtype(type, &PyBytes_Type));
- tmp = bytes_new(&PyBytes_Type, args, kwds);
- if (tmp == NULL)
- return NULL;
assert(PyBytes_Check(tmp));
n = PyBytes_GET_SIZE(tmp);
pnew = type->tp_alloc(type, n);
@@ -2907,7 +2902,6 @@
((PyBytesObject *)pnew)->ob_shash =
((PyBytesObject *)tmp)->ob_shash;
}
- Py_DECREF(tmp);
return pnew;
}