MCPcopy Create free account
hub / github.com/FreeCAD/FreeCAD / getCustomAttributes

Method getCustomAttributes

src/App/ExtensionContainerPyImp.cpp:115–171  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

113}
114
115PyObject* ExtensionContainerPy::getCustomAttributes(const char* attr) const
116{
117 if (Base::streq(attr, "__dict__")) {
118 PyObject* dict = PyDict_New();
119 PyObject* props = PropertyContainerPy::getCustomAttributes("__dict__");
120 if (props && PyDict_Check(props)) {
121 PyDict_Merge(dict, props, 0);
122 Py_DECREF(props);
123 }
124
125 ExtensionContainer::ExtensionIterator it =
126 this->getExtensionContainerPtr()->extensionBegin();
127 for (; it != this->getExtensionContainerPtr()->extensionEnd(); ++it) {
128 // The PyTypeObject is shared by all instances of this type and therefore
129 // we have to add new methods only once.
130 PyObject* obj = (*it).second->getExtensionPyObject();
131 PyTypeObject* tp = Py_TYPE(obj);
132 if (tp && tp->tp_dict) {
133 Py_XINCREF(tp->tp_dict);
134 PyDict_Merge(dict, tp->tp_dict, 0);
135 Py_XDECREF(tp->tp_dict);
136 }
137 Py_DECREF(obj);
138 }
139
140 return dict;
141 }
142 // Search for the method called 'attr' in the extensions. If the search with
143 // Py_FindMethod is successful then a PyCFunction_New instance is returned
144 // with the PyObject pointer of the extension to make sure the method will
145 // be called for the correct instance.
146 PyObject* func = nullptr;
147 ExtensionContainer::ExtensionIterator it = this->getExtensionContainerPtr()->extensionBegin();
148 for (; it != this->getExtensionContainerPtr()->extensionEnd(); ++it) {
149 // The PyTypeObject is shared by all instances of this type and therefore
150 // we have to add new methods only once.
151 PyObject* obj = (*it).second->getExtensionPyObject();
152 PyObject* nameobj = PyUnicode_FromString(attr);
153 func = PyObject_GenericGetAttr(obj, nameobj);
154 Py_DECREF(nameobj);
155 Py_DECREF(obj);
156 if (func && PyCFunction_Check(func)) {
157 PyCFunctionObject* cfunc = reinterpret_cast<PyCFunctionObject*>(func);
158
159 // OK, that's what we wanted
160 if (cfunc->m_self == obj) {
161 break;
162 }
163 // otherwise cleanup the result again
164 Py_DECREF(func);
165 func = nullptr;
166 }
167 PyErr_Clear(); // clear the error set inside Py_FindMethod
168 }
169
170 return func;
171}
172

Callers

nothing calls this directly

Calls 2

streqFunction · 0.85
getExtensionPyObjectMethod · 0.45

Tested by

no test coverage detected