summaryrefslogtreecommitdiff
path: root/Objects/typeobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/typeobject.c')
-rw-r--r--Objects/typeobject.c115
1 files changed, 64 insertions, 51 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 317334f739..d42054a7f1 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -460,7 +460,7 @@ type_module(PyTypeObject *type, void *context)
PyErr_Format(PyExc_AttributeError, "__module__");
return 0;
}
- Py_XINCREF(mod);
+ Py_INCREF(mod);
return mod;
}
else {
@@ -500,7 +500,7 @@ type_abstractmethods(PyTypeObject *type, void *context)
PyErr_SetObject(PyExc_AttributeError, message);
return NULL;
}
- Py_XINCREF(mod);
+ Py_INCREF(mod);
return mod;
}
@@ -548,7 +548,7 @@ type_get_bases(PyTypeObject *type, void *context)
static PyTypeObject *best_base(PyObject *);
static int mro_internal(PyTypeObject *, PyObject **);
Py_LOCAL_INLINE(int) type_is_subtype_base_chain(PyTypeObject *, PyTypeObject *);
-static int compatible_for_assignment(PyTypeObject *, PyTypeObject *, char *);
+static int compatible_for_assignment(PyTypeObject *, PyTypeObject *, const char *);
static int add_subclass(PyTypeObject*, PyTypeObject*);
static int add_all_subclasses(PyTypeObject *type, PyObject *bases);
static void remove_subclass(PyTypeObject *, PyTypeObject *);
@@ -859,9 +859,9 @@ type_repr(PyTypeObject *type)
}
if (mod != NULL && _PyUnicode_CompareWithId(mod, &PyId_builtins))
- rtn = PyUnicode_FromFormat("<class '%U.%U'>", mod, name);
- else
- rtn = PyUnicode_FromFormat("<class '%s'>", type->tp_name);
+ rtn = PyUnicode_FromFormat("<class '%U.%U' at %p>", mod, name, type);
+ else
+ rtn = PyUnicode_FromFormat("<class '%s' at %p>", type->tp_name, type);
Py_XDECREF(mod);
Py_DECREF(name);
@@ -888,25 +888,33 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
#endif
obj = type->tp_new(type, args, kwds);
- if (obj != NULL) {
- /* Ugly exception: when the call was type(something),
- don't call tp_init on the result. */
- if (type == &PyType_Type &&
- PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
- (kwds == NULL ||
- (PyDict_Check(kwds) && PyDict_Size(kwds) == 0)))
- return obj;
- /* If the returned object is not an instance of type,
- it won't be initialized. */
- if (!PyType_IsSubtype(Py_TYPE(obj), type))
- return obj;
- type = Py_TYPE(obj);
- if (type->tp_init != NULL) {
- int res = type->tp_init(obj, args, kwds);
- if (res < 0) {
- Py_DECREF(obj);
- obj = NULL;
- }
+ obj = _Py_CheckFunctionResult((PyObject*)type, obj, NULL);
+ if (obj == NULL)
+ return NULL;
+
+ /* Ugly exception: when the call was type(something),
+ don't call tp_init on the result. */
+ if (type == &PyType_Type &&
+ PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
+ (kwds == NULL ||
+ (PyDict_Check(kwds) && PyDict_Size(kwds) == 0)))
+ return obj;
+
+ /* If the returned object is not an instance of type,
+ it won't be initialized. */
+ if (!PyType_IsSubtype(Py_TYPE(obj), type))
+ return obj;
+
+ type = Py_TYPE(obj);
+ if (type->tp_init != NULL) {
+ int res = type->tp_init(obj, args, kwds);
+ if (res < 0) {
+ assert(PyErr_Occurred());
+ Py_DECREF(obj);
+ obj = NULL;
+ }
+ else {
+ assert(!PyErr_Occurred());
}
}
return obj;
@@ -1411,7 +1419,7 @@ _PyObject_LookupSpecial(PyObject *self, _Py_Identifier *attrid)
as lookup_method to cache the interned name string object. */
static PyObject *
-call_method(PyObject *o, _Py_Identifier *nameid, char *format, ...)
+call_method(PyObject *o, _Py_Identifier *nameid, const char *format, ...)
{
va_list va;
PyObject *args, *func = 0, *retval;
@@ -1447,7 +1455,7 @@ call_method(PyObject *o, _Py_Identifier *nameid, char *format, ...)
/* Clone of call_method() that returns NotImplemented when the lookup fails. */
static PyObject *
-call_maybe(PyObject *o, _Py_Identifier *nameid, char *format, ...)
+call_maybe(PyObject *o, _Py_Identifier *nameid, const char *format, ...)
{
va_list va;
PyObject *args, *func = 0, *retval;
@@ -1526,7 +1534,6 @@ class_name(PyObject *cls)
PyObject *name = _PyObject_GetAttrId(cls, &PyId___name__);
if (name == NULL) {
PyErr_Clear();
- Py_XDECREF(name);
name = PyObject_Repr(cls);
}
if (name == NULL)
@@ -2084,7 +2091,7 @@ subtype_dict(PyObject *obj, void *context)
static int
subtype_setdict(PyObject *obj, PyObject *value, void *context)
{
- PyObject *dict, **dictptr;
+ PyObject **dictptr;
PyTypeObject *base;
base = get_builtin_base_with_dict(Py_TYPE(obj));
@@ -2115,10 +2122,8 @@ subtype_setdict(PyObject *obj, PyObject *value, void *context)
"not a '%.200s'", Py_TYPE(value)->tp_name);
return -1;
}
- dict = *dictptr;
Py_XINCREF(value);
- *dictptr = value;
- Py_XDECREF(dict);
+ Py_XSETREF(*dictptr, value);
return 0;
}
@@ -2673,7 +2678,7 @@ error:
return NULL;
}
-static short slotoffsets[] = {
+static const short slotoffsets[] = {
-1, /* invalid slot */
#include "typeslots.inc"
};
@@ -3592,7 +3597,7 @@ same_slots_added(PyTypeObject *a, PyTypeObject *b)
}
static int
-compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, char* attr)
+compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, const char* attr)
{
PyTypeObject *newbase, *oldbase;
@@ -3868,6 +3873,24 @@ _PyObject_GetState(PyObject *obj, int required)
}
assert(slotnames == Py_None || PyList_Check(slotnames));
+ if (required) {
+ Py_ssize_t basicsize = PyBaseObject_Type.tp_basicsize;
+ if (obj->ob_type->tp_dictoffset)
+ basicsize += sizeof(PyObject *);
+ if (obj->ob_type->tp_weaklistoffset)
+ basicsize += sizeof(PyObject *);
+ if (slotnames != Py_None)
+ basicsize += sizeof(PyObject *) * Py_SIZE(slotnames);
+ if (obj->ob_type->tp_basicsize > basicsize) {
+ Py_DECREF(slotnames);
+ Py_DECREF(state);
+ PyErr_Format(PyExc_TypeError,
+ "can't pickle %.200s objects",
+ Py_TYPE(obj)->tp_name);
+ return NULL;
+ }
+ }
+
if (slotnames != Py_None && Py_SIZE(slotnames) > 0) {
PyObject *slots;
Py_ssize_t slotnames_size, i;
@@ -3922,7 +3945,7 @@ _PyObject_GetState(PyObject *obj, int required)
}
/* If we found some slot attributes, pack them in a tuple along
- the orginal attribute dictionary. */
+ the original attribute dictionary. */
if (PyDict_Size(slots) > 0) {
PyObject *state2;
@@ -4091,7 +4114,7 @@ _PyObject_GetItemsIter(PyObject *obj, PyObject **listitems,
}
static PyObject *
-reduce_newobj(PyObject *obj, int proto)
+reduce_newobj(PyObject *obj)
{
PyObject *args = NULL, *kwargs = NULL;
PyObject *copyreg;
@@ -4144,7 +4167,7 @@ reduce_newobj(PyObject *obj, int proto)
}
Py_XDECREF(args);
}
- else if (proto >= 4) {
+ else {
_Py_IDENTIFIER(__newobj_ex__);
newobj = _PyObject_GetAttrId(copyreg, &PyId___newobj_ex__);
@@ -4162,16 +4185,6 @@ reduce_newobj(PyObject *obj, int proto)
return NULL;
}
}
- else {
- PyErr_SetString(PyExc_ValueError,
- "must use protocol 4 or greater to copy this "
- "object; since __getnewargs_ex__ returned "
- "keyword arguments.");
- Py_DECREF(args);
- Py_DECREF(kwargs);
- Py_DECREF(copyreg);
- return NULL;
- }
state = _PyObject_GetState(obj,
!hasargs && !PyList_Check(obj) && !PyDict_Check(obj));
@@ -4217,7 +4230,7 @@ _common_reduce(PyObject *self, int proto)
PyObject *copyreg, *res;
if (proto >= 2)
- return reduce_newobj(self, proto);
+ return reduce_newobj(self);
copyreg = import_copyreg();
if (!copyreg)
@@ -5344,7 +5357,7 @@ wrap_delitem(PyObject *self, PyObject *args, void *wrapped)
/* Helper to check for object.__setattr__ or __delattr__ applied to a type.
This is called the Carlo Verre hack after its discoverer. */
static int
-hackcheck(PyObject *self, setattrofunc func, char *what)
+hackcheck(PyObject *self, setattrofunc func, const char *what)
{
PyTypeObject *type = Py_TYPE(self);
while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE)
@@ -5764,8 +5777,8 @@ slot_sq_item(PyObject *self, Py_ssize_t i)
if (args != NULL) {
PyTuple_SET_ITEM(args, 0, ival);
retval = PyObject_Call(func, args, NULL);
- Py_XDECREF(args);
- Py_XDECREF(func);
+ Py_DECREF(args);
+ Py_DECREF(func);
return retval;
}
}