diff options
Diffstat (limited to 'Objects/bytesobject.c')
-rw-r--r-- | Objects/bytesobject.c | 86 |
1 files changed, 40 insertions, 46 deletions
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 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); + } + + if (bytes != NULL && type != &PyBytes_Type) { + Py_SETREF(bytes, bytes_subtype_new(type, bytes)); + } - return PyBytes_FromObject(x); + 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; } |