Base: Remove deprecated Py_GetPath call

Replace it with a piece of code that replicates the functionality. Also eliminate the round-trip through char * that this function was using (the final variable is stored as a std::string anyway).
This commit is contained in:
Chris Hennes
2025-03-22 17:10:54 -05:00
parent 9f9610076e
commit f0fc6ccde1
3 changed files with 36 additions and 8 deletions

View File

@@ -2635,8 +2635,8 @@ void Application::initConfig(int argc, char ** argv)
Py_DECREF(pyModule);
}
const char* pythonpath = Base::Interpreter().init(argc,argv);
if (pythonpath)
std::string pythonpath = Base::Interpreter().init(argc,argv);
if (!pythonpath.empty())
mConfig["PythonSearchPath"] = pythonpath;
else
Base::Console().Warning("Encoding of Python paths failed\n");

View File

@@ -538,8 +538,36 @@ void InterpreterSingleton::addPythonPath(const char* Path)
list.append(Py::String(Path));
}
std::string InterpreterSingleton::getPythonPath()
{
// Construct something that looks like the output of the now-deprecated Py_GetPath
PyGILStateLocker lock;
PyObject* path = PySys_GetObject("path");
std::string result;
const char* separator = ":"; // Use ":" on Unix-like systems, ";" on Windows
#ifdef FC_OS_WIN32
separator = ";";
#endif
Py_ssize_t length = PyList_Size(path);
for (Py_ssize_t i = 0; i < length; ++i) {
PyObject* item = PyList_GetItem(path, i); // Borrowed reference
if (!item) {
throw Base::RuntimeError("Failed to retrieve item from path");
}
const char* item_str = PyUnicode_AsUTF8(item);
if (!item_str) {
throw Base::RuntimeError("Failed to convert path item to UTF-8 string");
}
if (!result.empty()) {
result += separator;
}
result += item_str;
}
return result;
}
#if PY_VERSION_HEX < 0x030b0000
const char* InterpreterSingleton::init(int argc, char* argv[])
std::string InterpreterSingleton::init(int argc, char* argv[])
{
if (!Py_IsInitialized()) {
Py_SetProgramName(Py_DecodeLocale(argv[0], nullptr));
@@ -617,7 +645,7 @@ void initInterpreter(int argc, char* argv[])
Py_Initialize();
}
} // namespace
const char* InterpreterSingleton::init(int argc, char* argv[])
std::string InterpreterSingleton::init(int argc, char* argv[])
{
try {
if (!Py_IsInitialized()) {
@@ -626,9 +654,7 @@ const char* InterpreterSingleton::init(int argc, char* argv[])
PythonStdOutput::init_type();
this->_global = PyEval_SaveThread();
}
PyGILStateLocker lock;
return Py_EncodeLocale(Py_GetPath(), nullptr);
return getPythonPath();
}
catch (const Base::Exception& e) {
e.ReportException();

View File

@@ -285,6 +285,8 @@ public:
bool loadModule(const char* psModName);
/// Add an additional python path
void addPythonPath(const char* Path);
/// Get the path (replaces the deprecated Py_GetPath method)
std::string getPythonPath();
static void addType(PyTypeObject* Type, PyObject* Module, const char* Name);
/// Add a module and return a PyObject to it
PyObject* addModule(Py::ExtensionModuleBase*);
@@ -313,7 +315,7 @@ public:
*/
//@{
/// init the interpreter and returns the module search path
const char* init(int argc, char* argv[]);
std::string init(int argc, char* argv[]);
int runCommandLine(const char* prompt);
void replaceStdOutput();
static InterpreterSingleton& Instance();