diff --git a/src/PythonConfig.cpp b/src/PythonConfig.cpp index 600ad66..8ed3051 100644 --- a/src/PythonConfig.cpp +++ b/src/PythonConfig.cpp @@ -141,7 +141,7 @@ const wchar_t *PythonConfigPaths::pythonPath() const //================================================================================ -static QString PathToPythonExecutableInEnv(PythonConfig::Type envType, const QString &envRoot) +static QString PathToPythonExecutableInEnv(const PythonConfig::Type envType, const QString &envRoot) { #if defined(Q_OS_WINDOWS) switch (envType) @@ -280,7 +280,7 @@ void PythonConfig::initVenv(const QString &venvPrefix) m_type = Type::Venv; m_pythonHome = venvPrefix; - m_pythonPath = QString("%1/Lib/site-packages;%3/DLLS;%3/lib").arg(venvPrefix, cfg.home); + m_pythonPath = QString("%1/Lib/site-packages;%2/DLLS;%2/Lib").arg(venvPrefix, cfg.home); if (cfg.includeSystemSitesPackages) { m_pythonPath.append(QString("%1/Lib/site-packages").arg(cfg.home)); @@ -291,6 +291,10 @@ void PythonConfig::initVenv(const QString &venvPrefix) #endif } +QString PythonConfig::pythonExecutable() const { + return PathToPythonExecutableInEnv(type(), m_pythonHome); +} + void PythonConfig::preparePythonProcess(QProcess &pythonProcess) const { const QString pythonExePath = PathToPythonExecutableInEnv(type(), m_pythonHome); diff --git a/src/PythonConfig.h b/src/PythonConfig.h index a75d154..65510fa 100644 --- a/src/PythonConfig.h +++ b/src/PythonConfig.h @@ -119,6 +119,13 @@ class PythonConfig final return m_pythonHome; } + const QString &pythonPath() const + { + return m_pythonPath; + } + + QString pythonExecutable() const; + /// Sets the necessary settings of the QProcess so that /// it uses the correct Python exe. void preparePythonProcess(QProcess &pythonProcess) const; diff --git a/src/PythonInterpreter.cpp b/src/PythonInterpreter.cpp index d085782..f242afa 100644 --- a/src/PythonInterpreter.cpp +++ b/src/PythonInterpreter.cpp @@ -29,13 +29,14 @@ #include #include +#include #ifdef Q_OS_LINUX #include #include #endif -// seems like gcc defines macro with these names +// it seems like gcc defines macro with these names #undef major #undef minor @@ -211,8 +212,7 @@ void PythonInterpreter::initialize(const PythonConfig &config) } } #endif - if (config.type() != PythonConfig::Type::System) - { + if (config.type() != PythonConfig::Type::System) { // We use PEP 0587 to init the interpreter. // The changes introduced in this PEP allows to handle the error // when the interpreter could not be initialized. @@ -226,12 +226,17 @@ void PythonInterpreter::initialize(const PythonConfig &config) PyStatus status; PyConfig pyConfig; + // I think, in theory, we should use PyConfig_InitIsolatedConfig + // byt non-isolated config is easier to setup PyConfig_InitPythonConfig(&pyConfig); - pyConfig.isolated = 1; - status = PyConfig_SetString(&pyConfig, &pyConfig.home, m_config.pythonHome()); - if (PyStatus_Exception(status)) - { + const QString qPythonExecutable = config.pythonExecutable(); + const wchar_t* pythonExecutable = QStringToWcharArray(qPythonExecutable); + status = PyConfig_SetString(&pyConfig, &pyConfig.executable, + pythonExecutable); + delete[] pythonExecutable; + + if (PyStatus_Exception(status)) { PyConfig_Clear(&pyConfig); throw std::runtime_error(status.err_msg); } @@ -243,13 +248,19 @@ void PythonInterpreter::initialize(const PythonConfig &config) throw std::runtime_error(status.err_msg); } - status = PyConfig_Read(&pyConfig); + status = PyConfig_SetString(&pyConfig, &pyConfig.home, m_config.pythonHome()); if (PyStatus_Exception(status)) { PyConfig_Clear(&pyConfig); throw std::runtime_error(status.err_msg); } + status = PyConfig_Read(&pyConfig); + if (PyStatus_Exception(status)) { + PyConfig_Clear(&pyConfig); + throw std::runtime_error(status.err_msg); + } + status = Py_InitializeFromConfig(&pyConfig); if (PyStatus_Exception(status)) {