diff options
Diffstat (limited to 'Objects/typeobject.c')
-rw-r--r-- | Objects/typeobject.c | 108 |
1 files changed, 63 insertions, 45 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 8eaf51fb39..434608fd69 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -902,7 +902,7 @@ subtype_dealloc(PyObject *self) /* Find the nearest base with a different tp_dealloc */ base = type; - while ((basedealloc = base->tp_dealloc) == subtype_dealloc) { + while ((/*basedealloc =*/ base->tp_dealloc) == subtype_dealloc) { base = base->tp_base; assert(base); } @@ -3073,14 +3073,19 @@ static PyObject * import_copyreg(void) { static PyObject *copyreg_str; + static PyObject *mod_copyreg = NULL; if (!copyreg_str) { copyreg_str = PyUnicode_InternFromString("copyreg"); if (copyreg_str == NULL) return NULL; } + if (!mod_copyreg) { + mod_copyreg = PyImport_Import(copyreg_str); + } - return PyImport_Import(copyreg_str); + Py_XINCREF(mod_copyreg); + return mod_copyreg; } static PyObject * @@ -3089,14 +3094,16 @@ slotnames(PyObject *cls) PyObject *clsdict; PyObject *copyreg; PyObject *slotnames; + static PyObject *str_slotnames; - if (!PyType_Check(cls)) { - Py_INCREF(Py_None); - return Py_None; + if (str_slotnames == NULL) { + str_slotnames = PyUnicode_InternFromString("__slotnames__"); + if (str_slotnames == NULL) + return NULL; } clsdict = ((PyTypeObject *)cls)->tp_dict; - slotnames = PyDict_GetItemString(clsdict, "__slotnames__"); + slotnames = PyDict_GetItem(clsdict, str_slotnames); if (slotnames != NULL && PyList_Check(slotnames)) { Py_INCREF(slotnames); return slotnames; @@ -3130,12 +3137,20 @@ reduce_2(PyObject *obj) PyObject *slots = NULL, *listitems = NULL, *dictitems = NULL; PyObject *copyreg = NULL, *newobj = NULL, *res = NULL; Py_ssize_t i, n; + static PyObject *str_getnewargs = NULL, *str_getstate = NULL, + *str_newobj = NULL; + + if (str_getnewargs == NULL) { + str_getnewargs = PyUnicode_InternFromString("__getnewargs__"); + str_getstate = PyUnicode_InternFromString("__getstate__"); + str_newobj = PyUnicode_InternFromString("__newobj__"); + if (!str_getnewargs || !str_getstate || !str_newobj) + return NULL; + } - cls = PyObject_GetAttrString(obj, "__class__"); - if (cls == NULL) - return NULL; + cls = (PyObject *) Py_TYPE(obj); - getnewargs = PyObject_GetAttrString(obj, "__getnewargs__"); + getnewargs = PyObject_GetAttr(obj, str_getnewargs); if (getnewargs != NULL) { args = PyObject_CallObject(getnewargs, NULL); Py_DECREF(getnewargs); @@ -3153,7 +3168,7 @@ reduce_2(PyObject *obj) if (args == NULL) goto end; - getstate = PyObject_GetAttrString(obj, "__getstate__"); + getstate = PyObject_GetAttr(obj, str_getstate); if (getstate != NULL) { state = PyObject_CallObject(getstate, NULL); Py_DECREF(getstate); @@ -3161,17 +3176,18 @@ reduce_2(PyObject *obj) goto end; } else { + PyObject **dict; PyErr_Clear(); - state = PyObject_GetAttrString(obj, "__dict__"); - if (state == NULL) { - PyErr_Clear(); + dict = _PyObject_GetDictPtr(obj); + if (dict && *dict) + state = *dict; + else state = Py_None; - Py_INCREF(state); - } + Py_INCREF(state); names = slotnames(cls); if (names == NULL) goto end; - if (names != Py_None) { + if (names != Py_None && PyList_GET_SIZE(names) > 0) { assert(PyList_Check(names)); slots = PyDict_New(); if (slots == NULL) @@ -3230,7 +3246,7 @@ reduce_2(PyObject *obj) copyreg = import_copyreg(); if (copyreg == NULL) goto end; - newobj = PyObject_GetAttrString(copyreg, "__newobj__"); + newobj = PyObject_GetAttr(copyreg, str_newobj); if (newobj == NULL) goto end; @@ -3238,8 +3254,8 @@ reduce_2(PyObject *obj) args2 = PyTuple_New(n+1); if (args2 == NULL) goto end; + Py_INCREF(cls); PyTuple_SET_ITEM(args2, 0, cls); - cls = NULL; for (i = 0; i < n; i++) { PyObject *v = PyTuple_GET_ITEM(args, i); Py_INCREF(v); @@ -3249,7 +3265,6 @@ reduce_2(PyObject *obj) res = PyTuple_Pack(5, newobj, args2, state, listitems, dictitems); end: - Py_XDECREF(cls); Py_XDECREF(args); Py_XDECREF(args2); Py_XDECREF(slots); @@ -3309,31 +3324,34 @@ object_reduce(PyObject *self, PyObject *args) static PyObject * object_reduce_ex(PyObject *self, PyObject *args) { + static PyObject *str_reduce = NULL, *objreduce; PyObject *reduce, *res; int proto = 0; if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto)) return NULL; - reduce = PyObject_GetAttrString(self, "__reduce__"); + if (str_reduce == NULL) { + str_reduce = PyUnicode_InternFromString("__reduce__"); + objreduce = PyDict_GetItemString(PyBaseObject_Type.tp_dict, + "__reduce__"); + if (str_reduce == NULL || objreduce == NULL) + return NULL; + } + + reduce = PyObject_GetAttr(self, str_reduce); if (reduce == NULL) PyErr_Clear(); else { - PyObject *cls, *clsreduce, *objreduce; + PyObject *cls, *clsreduce; int override; - cls = PyObject_GetAttrString(self, "__class__"); - if (cls == NULL) { - Py_DECREF(reduce); - return NULL; - } - clsreduce = PyObject_GetAttrString(cls, "__reduce__"); - Py_DECREF(cls); + + cls = (PyObject *) Py_TYPE(self); + clsreduce = PyObject_GetAttr(cls, str_reduce); if (clsreduce == NULL) { Py_DECREF(reduce); return NULL; } - objreduce = PyDict_GetItemString(PyBaseObject_Type.tp_dict, - "__reduce__"); override = (clsreduce != objreduce); Py_DECREF(clsreduce); if (override) { @@ -3383,21 +3401,21 @@ object_format(PyObject *self, PyObject *args) self_as_str = PyObject_Str(self); if (self_as_str != NULL) { /* Issue 7994: If we're converting to a string, we - should reject format specifications */ + should reject format specifications */ if (PyUnicode_GET_SIZE(format_spec) > 0) { - if (PyErr_WarnEx(PyExc_PendingDeprecationWarning, - "object.__format__ with a non-empty format " - "string is deprecated", 1) < 0) { - goto done; - } - /* Eventually this will become an error: - PyErr_Format(PyExc_TypeError, - "non-empty format string passed to object.__format__"); - goto done; - */ - } + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "object.__format__ with a non-empty format " + "string is deprecated", 1) < 0) { + goto done; + } + /* Eventually this will become an error: + PyErr_Format(PyExc_TypeError, + "non-empty format string passed to object.__format__"); + goto done; + */ + } - result = PyObject_Format(self_as_str, format_spec); + result = PyObject_Format(self_as_str, format_spec); } done: @@ -4975,7 +4993,7 @@ slot_tp_str(PyObject *self) res = slot_tp_repr(self); if (!res) return NULL; - ress = _PyUnicode_AsDefaultEncodedString(res, NULL); + ress = _PyUnicode_AsDefaultEncodedString(res); Py_DECREF(res); return ress; } |