Skip to content

Commit b0f141e

Browse files
spethischoegl
authored andcommitted
Replace usage of internal '_PyNamespace_New' function
This function was removed from Python.h in Python 3.11. See python/cpython#28970
1 parent 577455c commit b0f141e

File tree

1 file changed

+35
-32
lines changed

1 file changed

+35
-32
lines changed

src/extensions/PythonExtensionManager.cpp

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ std::string getPythonExceptionInfo()
6363
return message;
6464
}
6565

66+
void checkPythonError(bool condition, const std::string& message) {
67+
if (condition) {
68+
if (PyErr_Occurred()) {
69+
PyErr_PrintEx(0);
70+
}
71+
throw Cantera::CanteraError(
72+
"PythonExtensionManager::PythonExtensionManager",
73+
message
74+
);
75+
}
76+
}
77+
6678
} // end anonymous namespace
6779

6880
namespace Cantera
@@ -115,40 +127,31 @@ PythonExtensionManager::PythonExtensionManager()
115127
"Failed to import 'pythonExtensions' module");
116128
}
117129

118-
// Following example creation of minimal ModuleSpec from Python's import.c
119-
PyObject *attrs = Py_BuildValue("{ss}", "name", "pythonExtensions");
120-
if (attrs == nullptr) {
121-
if (PyErr_Occurred()) {
122-
PyErr_PrintEx(0);
123-
}
124-
throw CanteraError("PythonExtensionManager::PythonExtensionManager",
125-
"Py_BuildValue failed");
126-
}
127-
PyObject *spec = _PyNamespace_New(attrs);
128-
Py_DECREF(attrs);
129-
if (spec == nullptr) {
130-
if (PyErr_Occurred()) {
131-
PyErr_PrintEx(0);
132-
}
133-
throw CanteraError("PythonExtensionManager::PythonExtensionManager",
134-
"_PyNamespace_New failed");
135-
}
130+
// Create a minimal ModuleSpec
131+
PyObject* typesModule = PyImport_ImportModule("types");
132+
checkPythonError(typesModule == nullptr, "'import types' failed");
133+
PyObject* simpleNamespaceType = PyObject_GetAttrString(typesModule,
134+
"SimpleNamespace");
135+
checkPythonError(simpleNamespaceType == nullptr,
136+
"'Get SimpleNamespace type failed");
137+
Py_DecRef(simpleNamespaceType);
138+
Py_DecRef(typesModule);
139+
PyObject* empty_tuple = PyTuple_New(0);
140+
PyObject* kwargs = PyDict_New();
141+
PyObject* strArg = PyUnicode_FromString("pythonExtensions");
142+
PyDict_SetItemString(kwargs, "name", strArg);
143+
PyObject* spec = PyObject_Call(simpleNamespaceType, empty_tuple, kwargs);
144+
checkPythonError(spec == nullptr, "Creating SimpleNamespace failed");
145+
Py_DecRef(empty_tuple);
146+
Py_DecRef(kwargs);
147+
Py_DecRef(empty_tuple);
148+
Py_DecRef(strArg);
149+
150+
// Build the module definition and execute it
136151
PyObject* pyModule = PyModule_FromDefAndSpec(modDef, spec);
137-
if (pyModule == nullptr) {
138-
if (PyErr_Occurred()) {
139-
PyErr_PrintEx(0);
140-
}
141-
CanteraError("PythonExtensionManager::PythonExtensionManager",
142-
"PyModule_FromDefAndSpec failed");
143-
}
152+
checkPythonError(pyModule == nullptr, "PyModule_FromDefAndSpec failed");
144153
int code = PyModule_ExecDef(pyModule, modDef);
145-
if (code) {
146-
if (PyErr_Occurred()) {
147-
PyErr_PrintEx(0);
148-
}
149-
CanteraError("PythonExtensionManager::PythonExtensionManager",
150-
"PyModule_ExecDef failed");
151-
}
154+
checkPythonError(code, "PyModule_ExecDef failed");
152155
Py_DECREF(spec);
153156
Py_DECREF(pyModule);
154157
s_imported = true;

0 commit comments

Comments
 (0)