diff --git a/docfilekcm/docfilewizard.cpp b/docfilekcm/docfilewizard.cpp --- a/docfilekcm/docfilewizard.cpp +++ b/docfilekcm/docfilewizard.cpp @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include #include @@ -148,8 +150,8 @@ // process already running return false; } - QString scriptUrl = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kdevpythonsupport/scripts/introspect.py"); - if ( scriptUrl.isEmpty() ) { + const KDevelop::Path scriptPath(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kdevpythonsupport/scripts/introspect.py")); + if ( scriptPath.isEmpty() ) { KMessageBox::error(this, i18n("Couldn't find the introspect.py script; check your installation!")); return false; } @@ -177,21 +179,24 @@ worker = new QProcess(this); QObject::connect(worker, &QProcess::readyReadStandardError, this, &DocfileWizard::processScriptOutput); QObject::connect(worker, &QProcess::readyReadStandardOutput, this, &DocfileWizard::processScriptOutput); - QObject::connect(worker, SIGNAL(finished(int)), this, SLOT(processFinished(int))); + QObject::connect(worker, static_cast(&QProcess::finished), this, &DocfileWizard::processFinished); // can never have too many slashes outputFile.setFileName(workingDirectory + "/" + outputFilename); + const auto runtime = KDevelop::ICore::self()->runtimeController()->currentRuntime(); QList projs = KDevelop::ICore::self()->projectController()->projects(); QStringList args; - args << scriptUrl; + args << runtime->pathInRuntime(scriptPath).toLocalFile(); foreach(const KDevelop::IProject* proj, projs) { if ( proj ) - args << proj->path().toLocalFile(); + args << runtime->pathInRuntime(proj->path()).toLocalFile(); } args << module; - worker->start(interpreter, args); + worker->setArguments(args); + worker->setProgram(interpreter); + runtime->startProcess(worker); return true; } diff --git a/duchain/contextbuilder.cpp b/duchain/contextbuilder.cpp --- a/duchain/contextbuilder.cpp +++ b/duchain/contextbuilder.cpp @@ -393,6 +393,7 @@ } } } + qCWarning(KDEV_PYTHON_DUCHAIN) << "Could not find" << name << currentDocument << "in" << searchPaths; return {}; } diff --git a/duchain/helpers.cpp b/duchain/helpers.cpp --- a/duchain/helpers.cpp +++ b/duchain/helpers.cpp @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include #include @@ -375,16 +377,23 @@ } } + const auto runtime = ICore::self()->runtimeController()->currentRuntime(); + const auto pEnv = runtime->getenv("PATH"); + QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QDir::listSeparator(), QString::SkipEmptyParts); + for(auto &path: paths) { + path = runtime->pathInHost(Path(path)).toLocalFile(); + } + // Find python 3 (https://www.python.org/dev/peps/pep-0394/) - auto result = QStandardPaths::findExecutable("python" PYTHON_VERSION_STR); + auto result = QStandardPaths::findExecutable("python" PYTHON_VERSION_STR, paths); if ( ! result.isEmpty() ) { return result; } - result = QStandardPaths::findExecutable("python" PYTHON_VERSION_MAJOR_STR); + result = QStandardPaths::findExecutable("python" PYTHON_VERSION_MAJOR_STR, paths); if ( ! result.isEmpty() ) { return result; } - result = QStandardPaths::findExecutable("python"); + result = QStandardPaths::findExecutable("python", paths); if ( ! result.isEmpty() ) { return result; } @@ -419,66 +428,76 @@ } #endif // fallback - return PYTHON_EXECUTABLE; + return QStringLiteral("python"); } QVector Helper::getSearchPaths(const QUrl& workingOnDocument) { + static bool first = true; + if (first) { + first = false; + QObject::connect(ICore::self()->runtimeController(), &IRuntimeController::currentRuntimeChanged, ICore::self()->runtimeController(), []( IRuntime* r){ + QMutexLocker lock(&Helper::cacheMutex); + cachedSearchPaths.clear(); + qDebug() << "runtime changed!" << r; + }); + } + QMutexLocker lock(&Helper::cacheMutex); QVector searchPaths; // search in the projects, as they're packages and likely to be installed or added to PYTHONPATH later // and also add custom include paths that are defined in the projects auto project = ICore::self()->projectController()->findProjectForUrl(workingOnDocument); - { + if (project) { QMutexLocker lock(&Helper::projectPathLock); searchPaths << Helper::projectSearchPaths; searchPaths << Helper::cachedCustomIncludes.value(project); } - + foreach ( const QString& path, getDataDirs() ) { searchPaths.append(QUrl::fromLocalFile(path)); } if ( !cachedSearchPaths.contains(project) ) { + auto runtime = ICore::self()->runtimeController()->currentRuntime(); QVector cachedForProject; qCDebug(KDEV_PYTHON_DUCHAIN) << "*** Collecting search paths..."; - QStringList getpath; - getpath << "-c" << "import sys; sys.stdout.write('$|$'.join(sys.path))"; - + QProcess python; - python.start(getPythonExecutablePath(project), getpath); + python.setProgram(getPythonExecutablePath(project)); + python.setArguments({"-c", "import sys; sys.stdout.write('$|$'.join(sys.path))"}); + runtime->startProcess(&python); python.waitForFinished(1000); QString pythonpath = QString::fromUtf8(python.readAllStandardOutput()); - auto paths = pythonpath.split("$|$"); - paths.removeAll(""); - + if ( ! pythonpath.isEmpty() ) { + const auto paths = pythonpath.split("$|$", QString::SkipEmptyParts); foreach ( const QString& path, paths ) { - cachedForProject.append(QUrl::fromLocalFile(path)); + cachedForProject.append(runtime->pathInHost(KDevelop::Path(path)).toUrl()); } } else { - qCWarning(KDEV_PYTHON_DUCHAIN) << "Could not get search paths! Defaulting to stupid stuff."; - searchPaths.append(QUrl::fromLocalFile("/usr/lib/python" PYTHON_VERSION_STR)); - searchPaths.append(QUrl::fromLocalFile("/usr/lib/python" PYTHON_VERSION_STR "/site-packages")); - QString path = qgetenv("PYTHONPATH"); + qCWarning(KDEV_PYTHON_DUCHAIN) << "Could not get search paths! Defaulting to stupid stuff." << python.exitCode() << python.readAllStandardError(); + cachedForProject.append(runtime->pathInHost(Path("/usr/lib/python" PYTHON_VERSION_STR)).toUrl()); + cachedForProject.append(runtime->pathInHost(Path("/usr/lib/python" PYTHON_VERSION_STR "/site-packages")).toUrl()); + QString path = runtime->getenv("PYTHONPATH"); QStringList paths = path.split(':'); foreach ( const QString& path, paths ) { - cachedForProject.append(QUrl::fromLocalFile(path)); + cachedForProject.append(runtime->pathInHost(Path(path)).toUrl()); } } - qCDebug(KDEV_PYTHON_DUCHAIN) << " *** Done. Got search paths: " << cachedSearchPaths; cachedSearchPaths.insert(project, cachedForProject); } - + searchPaths.append(cachedSearchPaths.value(project)); - + auto dir = workingOnDocument.adjusted(QUrl::RemoveFilename); if ( ! dir.isEmpty() ) { // search in the current packages searchPaths.append(dir); } + qCDebug(KDEV_PYTHON_DUCHAIN) << " *** Done. Got search paths: " << searchPaths << project << cachedSearchPaths.value(project); return searchPaths; } diff --git a/kdevpythonversion.h.cmake b/kdevpythonversion.h.cmake --- a/kdevpythonversion.h.cmake +++ b/kdevpythonversion.h.cmake @@ -31,6 +31,6 @@ #define PYTHON_VERSION_MAJOR_STR "@PYTHON_VERSION_MAJOR@" #define PYTHON_VERSION QT_VERSION_CHECK(@PYTHON_VERSION_MAJOR@, @PYTHON_VERSION_MINOR@, @PYTHON_VERSION_PATCH@) #define PYTHON_VERSION_STR "@PYTHON_VERSION_MAJOR@.@PYTHON_VERSION_MINOR@" -#define PYTHON_EXECUTABLE "@PYTHON_EXEC@" +#define PYTHON_EXECUTABLE "@PYTHON_EXECUTABLE@" #endif diff --git a/pythonparsejob.cpp b/pythonparsejob.cpp --- a/pythonparsejob.cpp +++ b/pythonparsejob.cpp @@ -55,7 +55,6 @@ #include #include -#include #include #include #include