PyObject* PyObjectBase::__getattr(PyObject * obj, char *attr) { // This should be the entry in Type PyObjectBase* pyObj = static_cast<PyObjectBase*>(obj); if (!pyObj->isValid()){ PyErr_Format(PyExc_ReferenceError, "Cannot access attribute '%s' of deleted object", attr); return NULL; } // If an attribute references this as parent then reset it (bug #0002902) PyObject* cur = pyObj->getTrackedAttribute(attr); if (cur) { if (PyObject_TypeCheck(cur, &(PyObjectBase::Type))) { PyObjectBase* base = static_cast<PyObjectBase*>(cur); base->resetAttribute(); pyObj->untrackAttribute(attr); } } PyObject* value = pyObj->_getattr(attr); #if 1 if (value && PyObject_TypeCheck(value, &(PyObjectBase::Type))) { if (!static_cast<PyObjectBase*>(value)->isConst()) { static_cast<PyObjectBase*>(value)->setAttributeOf(attr, pyObj); pyObj->trackAttribute(attr, value); } } else if (value && PyCFunction_Check(value)) { // ExtensionContainerPy::initialization() transfers the methods of an // extension object by creating PyCFunction objects. // At this point no 'self' object is passed but is handled and determined // in ExtensionContainerPy::getCustomAttributes(). // So, if we come through this section then it's an indication that // something is wrong with the Python types. For example, a C++ class // that adds an extension uses the same Python type as a wrapper than // another C++ class without this extension. PyCFunctionObject* cfunc = reinterpret_cast<PyCFunctionObject*>(value); if (!cfunc->m_self) { Py_DECREF(cfunc); value = 0; PyErr_Format(PyExc_AttributeError, "<no object bound to built-in method %s>", attr); } } #endif return value; }
PyObject* PyObjectBase::__getattr(PyObject * obj, char *attr) { // This should be the entry in Type PyObjectBase* pyObj = static_cast<PyObjectBase*>(obj); if (!pyObj->isValid()){ PyErr_Format(PyExc_ReferenceError, "Cannot access attribute '%s' of deleted object", attr); return NULL; } PyObject* value = pyObj->_getattr(attr); #if 1 if (value && PyObject_TypeCheck(value, &(PyObjectBase::Type))) { if (!static_cast<PyObjectBase*>(value)->isConst()) static_cast<PyObjectBase*>(value)->setAttributeOf(attr, pyObj); } #endif return value; }