diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index f096dc6eb6..522e00884e 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -109,6 +109,8 @@ RenameSet methodRenameDictionary[] = { { "__reduce_persist__", "__reduce_persist__", 0 }, { "__copy__" , "__copy__", 0 }, { "__deepcopy__" , "__deepcopy__", 0 }, + { "__getstate__" , "__getstate__", 0 }, + { "__setstate__" , "__setstate__", 0 }, { "print" , "Cprint", 0 }, { "CInterval.set_t", "_priv__cSetT", 0 }, { nullptr, nullptr, -1 } @@ -3595,17 +3597,28 @@ write_function_for_name(ostream &out, Object *obj, std::string cClassName = obj->_itype.get_true_name(); // string class_name = remap->_cpptype->get_simple_name(); - // Extract pointer from 'self' parameter. - out << " " << cClassName << " *local_this = nullptr;\n"; - - if (all_nonconst) { + // If this is a non-static __setstate__, we run the default constructor. + if (remap->_cppfunc->get_local_name() == "__setstate__") { + out << " if (DtoolInstance_VOID_PTR(self) != nullptr) {\n" + << " Dtool_Raise_TypeError(\"C++ object is already constructed.\");\n"; + error_return(out, 4, return_flags); + out << " }\n" + << " " << cClassName << " *local_this = new " << cClassName << ";\n" + << " DTool_PyInit_Finalize(self, local_this, &Dtool_" << ClassName + << ", false, false);\n" + << " if (local_this == nullptr) {\n" + << " PyErr_NoMemory();\n"; + } + else if (all_nonconst) { // All remaps are non-const. Also check that this object isn't const. - out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", " + out << " " << cClassName << " *local_this = nullptr;\n" + << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", " << "(void **)&local_this, \"" << classNameFromCppName(cClassName, false) << "." << methodNameFromCppName(remap, cClassName, false) << "\")) {\n"; - - } else { - out << " if (!DtoolInstance_GetPointer(self, local_this, Dtool_" << ClassName << ")) {\n"; + } + else { + out << " " << cClassName << " *local_this = nullptr;\n" + << " if (!DtoolInstance_GetPointer(self, local_this, Dtool_" << ClassName << ")) {\n"; } error_return(out, 4, return_flags);