diff options
Diffstat (limited to 'Objects/object.c')
-rw-r--r-- | Objects/object.c | 113 |
1 files changed, 65 insertions, 48 deletions
diff --git a/Objects/object.c b/Objects/object.c index 57ed6eb..2e6ddfa 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -911,7 +911,7 @@ _PyObject_NextNotImplemented(PyObject *self) /* Generic GetAttr functions - put these in your tp_[gs]etattro slot */ PyObject * -PyObject_GenericGetAttr(PyObject *obj, PyObject *name) +_PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict) { PyTypeObject *tp = Py_TYPE(obj); PyObject *descr = NULL; @@ -971,36 +971,37 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name) } } - /* Inline _PyObject_GetDictPtr */ - dictoffset = tp->tp_dictoffset; - if (dictoffset != 0) { - PyObject *dict; - if (dictoffset < 0) { - Py_ssize_t tsize; - size_t size; - - tsize = ((PyVarObject *)obj)->ob_size; - if (tsize < 0) - tsize = -tsize; - size = _PyObject_VAR_SIZE(tp, tsize); - - dictoffset += (long)size; - assert(dictoffset > 0); - assert(dictoffset % SIZEOF_VOID_P == 0); - } - dictptr = (PyObject **) ((char *)obj + dictoffset); - dict = *dictptr; - if (dict != NULL) { - Py_INCREF(dict); - res = PyDict_GetItem(dict, name); - if (res != NULL) { - Py_INCREF(res); - Py_XDECREF(descr); - Py_DECREF(dict); - goto done; + if (dict == NULL) { + /* Inline _PyObject_GetDictPtr */ + dictoffset = tp->tp_dictoffset; + if (dictoffset != 0) { + if (dictoffset < 0) { + Py_ssize_t tsize; + size_t size; + + tsize = ((PyVarObject *)obj)->ob_size; + if (tsize < 0) + tsize = -tsize; + size = _PyObject_VAR_SIZE(tp, tsize); + + dictoffset += (long)size; + assert(dictoffset > 0); + assert(dictoffset % SIZEOF_VOID_P == 0); } + dictptr = (PyObject **) ((char *)obj + dictoffset); + dict = *dictptr; + } + } + if (dict != NULL) { + Py_INCREF(dict); + res = PyDict_GetItem(dict, name); + if (res != NULL) { + Py_INCREF(res); + Py_XDECREF(descr); Py_DECREF(dict); + goto done; } + Py_DECREF(dict); } if (f != NULL) { @@ -1023,8 +1024,15 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name) return res; } +PyObject * +PyObject_GenericGetAttr(PyObject *obj, PyObject *name) +{ + return _PyObject_GenericGetAttrWithDict(obj, name, NULL); +} + int -PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) +_PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, + PyObject *value, PyObject *dict) { PyTypeObject *tp = Py_TYPE(obj); PyObject *descr; @@ -1056,27 +1064,29 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) } } - dictptr = _PyObject_GetDictPtr(obj); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - if (dict == NULL && value != NULL) { - dict = PyDict_New(); - if (dict == NULL) - goto done; - *dictptr = dict; - } - if (dict != NULL) { - Py_INCREF(dict); - if (value == NULL) - res = PyDict_DelItem(dict, name); - else - res = PyDict_SetItem(dict, name, value); - if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) - PyErr_SetObject(PyExc_AttributeError, name); - Py_DECREF(dict); - goto done; + if (dict == NULL) { + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL) { + dict = *dictptr; + if (dict == NULL && value != NULL) { + dict = PyDict_New(); + if (dict == NULL) + goto done; + *dictptr = dict; + } } } + if (dict != NULL) { + Py_INCREF(dict); + if (value == NULL) + res = PyDict_DelItem(dict, name); + else + res = PyDict_SetItem(dict, name, value); + if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_SetObject(PyExc_AttributeError, name); + Py_DECREF(dict); + goto done; + } if (f != NULL) { res = f(descr, obj, value); @@ -1098,6 +1108,13 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) return res; } +int +PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) +{ + return _PyObject_GenericSetAttrWithDict(obj, name, value, NULL); +} + + /* Test a value used as condition, e.g., in a for or if statement. Return -1 if an error occurred */ |