bpo-41334: Convert constructors of str, bytes and bytearray to Argument Clinic (GH-21535)

This commit is contained in:
Serhiy Storchaka 2020-07-20 15:53:55 +03:00 • committed by GitHub
parent e123012d79
commit 12f433411b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 307 additions and 93 deletions

View file

@ -2580,24 +2580,27 @@ static PyNumberMethods bytes_as_number = {
};
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 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
"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 @@ PyBytes_FromObject(PyObject *x)
}
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 @@ bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
((PyBytesObject *)pnew)->ob_shash =
((PyBytesObject *)tmp)->ob_shash;
}
Py_DECREF(tmp);
return pnew;
}