コード例 #1
0
ファイル: PyObjectBase.cpp プロジェクト: crobarcro/FreeCAD
int PyObjectBase::__setattr(PyObject *obj, char *attr, PyObject *value)
{
    //FIXME: In general we don't allow to delete attributes (i.e. value=0). However, if we want to allow
    //we must check then in _setattr() of all subclasses whether value is 0.
    if ( value==0 ) {
        PyErr_Format(PyExc_AttributeError, "Cannot delete attribute: '%s'", attr);
        return -1;
    }
    else if (!static_cast<PyObjectBase*>(obj)->isValid()){
        PyErr_Format(PyExc_ReferenceError, "Cannot access attribute '%s' of deleted object", attr);
        return -1;
    }

    // If an attribute references this as parent then reset it
    // before setting the new attribute
    PyObject* cur = static_cast<PyObjectBase*>(obj)->getTrackedAttribute(attr);
    if (cur) {
        if (PyObject_TypeCheck(cur, &(PyObjectBase::Type))) {
            PyObjectBase* base = static_cast<PyObjectBase*>(cur);
            base->resetAttribute();
            static_cast<PyObjectBase*>(obj)->untrackAttribute(attr);
        }
    }

    int ret = static_cast<PyObjectBase*>(obj)->_setattr(attr, value);
#if 1
    if (ret == 0) {
        static_cast<PyObjectBase*>(obj)->startNotify();
    }
#endif
    return ret;
}
コード例 #2
0
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;
}
コード例 #3
0
ファイル: PyObjectBase.cpp プロジェクト: crobarcro/FreeCAD
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;
}