diff --git a/src/App/FeaturePythonPyImp.inl b/src/App/FeaturePythonPyImp.inl index fb1d67c4e..58e2a3018 100644 --- a/src/App/FeaturePythonPyImp.inl +++ b/src/App/FeaturePythonPyImp.inl @@ -383,11 +383,18 @@ PyObject *FeaturePythonPyT::getCustomAttributes(const char* attr) co { PY_TRY{ if (Base::streq(attr, "__dict__")){ - PyObject* dict = FeaturePyT::getCustomAttributes(attr); - if (dict){ - std::vector Props = FeaturePyT::getDocumentObjectPtr()->getDynamicPropertyNames(); - for (std::vector::const_iterator it = Props.begin(); it != Props.end(); ++it) - PyDict_SetItem(dict, PyString_FromString(it->c_str()), PyString_FromString("")); + // Return the default dict + PyTypeObject *tp = this->ob_type; + PyObject* dict = PyDict_Copy(tp->tp_dict); + std::map Map; + FeaturePyT::getPropertyContainerPtr()->getPropertyMap(Map); + for (std::map::iterator it = Map.begin(); it != Map.end(); ++it) + PyDict_SetItem(dict, PyString_FromString(it->first.c_str()), PyString_FromString("")); + for (std::map::const_iterator it = dyn_methods.begin(); it != dyn_methods.end(); ++it) + PyDict_SetItem(dict, PyString_FromString(it->first.c_str()), PyString_FromString("")); + if (PyErr_Occurred()) { + Py_DECREF(dict); + dict = 0; } return dict; } diff --git a/src/Gui/CallTips.cpp b/src/Gui/CallTips.cpp index 72aa941c1..5d4418bdc 100644 --- a/src/Gui/CallTips.cpp +++ b/src/Gui/CallTips.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -232,8 +233,19 @@ QMap CallTipsList::extractTips(const QString& context) const Py::Object type(PyObject_Type(obj.ptr()), true); Py::Object inst = obj; // the object instance union PyType_Object typeobj = {&Base::PyObjectBase::Type}; - bool subclass = (PyObject_IsSubclass(type.ptr(), typeobj.o) == 1); - if (subclass) obj = type; + union PyType_Object typedoc = {&App::DocumentObjectPy::Type}; + if (PyObject_IsSubclass(type.ptr(), typedoc.o) == 1) { + // From the template Python object we don't query its type object because there we keep + // a list of additional methods that we won't see otherwise. But to get the correct doc + // strings we query the type's dict in the class itself. + // To see if we have a template Python object we check for the existence of supportedProperties + if (!type.hasAttr("supportedProperties")) { + obj = type; + } + } + else if (PyObject_IsSubclass(type.ptr(), typeobj.o) == 1) { + obj = type; + } // If we have an instance of PyObjectBase then determine whether it's valid or not if (PyObject_IsInstance(inst.ptr(), typeobj.o) == 1) {