diff options
Diffstat (limited to 'Objects/object.c')
-rw-r--r-- | Objects/object.c | 81 |
1 files changed, 36 insertions, 45 deletions
diff --git a/Objects/object.c b/Objects/object.c index 8024889008..e08f9a942f 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -22,12 +22,6 @@ _Py_GetRefTotal(void) { PyObject *o; Py_ssize_t total = _Py_RefTotal; - /* ignore the references to the dummy object of the dicts and sets - because they are not reliable and not useful (now that the - hash table code is well-tested) */ - o = _PyDict_Dummy(); - if (o != NULL) - total -= o->ob_refcnt; o = _PySet_Dummy; if (o != NULL) total -= o->ob_refcnt; @@ -109,6 +103,15 @@ void dump_counts(FILE* f) { PyTypeObject *tp; + PyObject *xoptions, *value; + _Py_IDENTIFIER(showalloccount); + + xoptions = PySys_GetXOptions(); + if (xoptions == NULL) + return; + value = _PyDict_GetItemId(xoptions, &PyId_showalloccount); + if (value != Py_True) + return; for (tp = type_list; tp; tp = tp->tp_next) fprintf(f, "%s alloc'd: %" PY_FORMAT_SIZE_T "d, " @@ -644,7 +647,7 @@ PyObject_Bytes(PyObject *v) /* Map rich comparison operators to their swapped version, e.g. LT <--> GT */ int _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE}; -static char *opstrings[] = {"<", "<=", "==", "!=", ">", ">="}; +static const char * const opstrings[] = {"<", "<=", "==", "!=", ">", ">="}; /* Perform a rich comparison, raising TypeError when the requested comparison operator is not supported. */ @@ -686,11 +689,10 @@ do_richcompare(PyObject *v, PyObject *w, int op) res = (v != w) ? Py_True : Py_False; break; default: - /* XXX Special-case None so it doesn't show as NoneType() */ PyErr_Format(PyExc_TypeError, - "unorderable types: %.100s() %s %.100s()", - v->ob_type->tp_name, + "'%s' not supported between instances of '%.100s' and '%.100s'", opstrings[op], + v->ob_type->tp_name, w->ob_type->tp_name); return NULL; } @@ -1041,8 +1043,7 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict) name->ob_type->tp_name); return NULL; } - else - Py_INCREF(name); + Py_INCREF(name); if (tp->tp_dict == NULL) { if (PyType_Ready(tp) < 0) @@ -1050,10 +1051,10 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict) } descr = _PyType_Lookup(tp, name); - Py_XINCREF(descr); f = NULL; if (descr != NULL) { + Py_INCREF(descr); f = descr->ob_type->tp_descr_get; if (f != NULL && PyDescr_IsData(descr)) { res = f(descr, obj, (PyObject *)obj->ob_type); @@ -1073,8 +1074,9 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict) if (tsize < 0) tsize = -tsize; size = _PyObject_VAR_SIZE(tp, tsize); + assert(size <= PY_SSIZE_T_MAX); - dictoffset += (long)size; + dictoffset += (Py_ssize_t)size; assert(dictoffset > 0); assert(dictoffset % SIZEOF_VOID_P == 0); } @@ -1142,12 +1144,11 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, Py_INCREF(name); descr = _PyType_Lookup(tp, name); - Py_XINCREF(descr); - f = NULL; if (descr != NULL) { + Py_INCREF(descr); f = descr->ob_type->tp_descr_set; - if (f != NULL && PyDescr_IsData(descr)) { + if (f != NULL) { res = f(descr, obj, value); goto done; } @@ -1155,40 +1156,32 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, if (dict == NULL) { dictptr = _PyObject_GetDictPtr(obj); - if (dictptr != NULL) { - res = _PyObjectDict_SetItem(Py_TYPE(obj), dictptr, name, value); - if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) - PyErr_SetObject(PyExc_AttributeError, name); + if (dictptr == NULL) { + if (descr == NULL) { + PyErr_Format(PyExc_AttributeError, + "'%.100s' object has no attribute '%U'", + tp->tp_name, name); + } + else { + PyErr_Format(PyExc_AttributeError, + "'%.50s' object attribute '%U' is read-only", + tp->tp_name, name); + } goto done; } + res = _PyObjectDict_SetItem(tp, dictptr, name, value); } - if (dict != NULL) { + else { Py_INCREF(dict); if (value == NULL) res = PyDict_DelItem(dict, name); else res = PyDict_SetItem(dict, name, value); Py_DECREF(dict); - if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) - PyErr_SetObject(PyExc_AttributeError, name); - goto done; - } - - if (f != NULL) { - res = f(descr, obj, value); - goto done; } + if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_SetObject(PyExc_AttributeError, name); - if (descr == NULL) { - PyErr_Format(PyExc_AttributeError, - "'%.100s' object has no attribute '%U'", - tp->tp_name, name); - goto done; - } - - PyErr_Format(PyExc_AttributeError, - "'%.50s' object attribute '%U' is read-only", - tp->tp_name, name); done: Py_XDECREF(descr); Py_DECREF(name); @@ -1204,7 +1197,7 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) int PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) { - PyObject *dict, **dictptr = _PyObject_GetDictPtr(obj); + PyObject **dictptr = _PyObject_GetDictPtr(obj); if (dictptr == NULL) { PyErr_SetString(PyExc_AttributeError, "This object has no __dict__"); @@ -1220,10 +1213,8 @@ PyObject_GenericSetDict(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_INCREF(value); + Py_XSETREF(*dictptr, value); return 0; } |