forked from qt-creator/qt-creator
Python: optimize the pip and venv checks
Those checks can take an considerable amount of time. So instead of running them the first time we want to check this info run them in the background as soon as we have loaded the python settings. Change-Id: I287acd2a5fd7b053873257238f7dfbaa9cf00170 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -855,11 +855,18 @@ QString PythonSettings::pylsConfiguration()
|
|||||||
return settingsInstance->m_pylsConfiguration;
|
return settingsInstance->m_pylsConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cacheVenvAndPipUsability(const Interpreter &interpreter)
|
||||||
|
{
|
||||||
|
Utils::asyncRun(&venvIsUsable, interpreter.command);
|
||||||
|
Utils::asyncRun(&pipIsUsable, interpreter.command);
|
||||||
|
}
|
||||||
|
|
||||||
void PythonSettings::addInterpreter(const Interpreter &interpreter, bool isDefault)
|
void PythonSettings::addInterpreter(const Interpreter &interpreter, bool isDefault)
|
||||||
{
|
{
|
||||||
if (Utils::anyOf(settingsInstance->m_interpreters, Utils::equal(&Interpreter::id, interpreter.id)))
|
if (Utils::anyOf(settingsInstance->m_interpreters, Utils::equal(&Interpreter::id, interpreter.id)))
|
||||||
return;
|
return;
|
||||||
settingsInstance->m_interpreters.append(interpreter);
|
settingsInstance->m_interpreters.append(interpreter);
|
||||||
|
cacheVenvAndPipUsability(interpreter);
|
||||||
if (isDefault)
|
if (isDefault)
|
||||||
settingsInstance->m_defaultInterpreterId = interpreter.id;
|
settingsInstance->m_defaultInterpreterId = interpreter.id;
|
||||||
saveSettings();
|
saveSettings();
|
||||||
@@ -1026,8 +1033,12 @@ void PythonSettings::initFromSettings(QtcSettings *settings)
|
|||||||
const auto [valid, outdatedInterpreters] = Utils::partition(m_interpreters, keepInterpreter);
|
const auto [valid, outdatedInterpreters] = Utils::partition(m_interpreters, keepInterpreter);
|
||||||
m_interpreters = valid;
|
m_interpreters = valid;
|
||||||
|
|
||||||
if (!settings->value(kitsGeneratedKey, false).toBool()) {
|
const bool kitsGenerated = settings->value(kitsGeneratedKey, false).toBool();
|
||||||
for (const Interpreter &interpreter : m_interpreters) {
|
if (kitsGenerated)
|
||||||
|
fixupPythonKits();
|
||||||
|
for (const Interpreter &interpreter : std::as_const(m_interpreters)) {
|
||||||
|
cacheVenvAndPipUsability(interpreter);
|
||||||
|
if (!kitsGenerated) {
|
||||||
if (interpreter.autoDetected) {
|
if (interpreter.autoDetected) {
|
||||||
const FilePath &cmd = interpreter.command;
|
const FilePath &cmd = interpreter.command;
|
||||||
if (!cmd.isLocal() || cmd.parentDir().pathAppended("activate").exists())
|
if (!cmd.isLocal() || cmd.parentDir().pathAppended("activate").exists())
|
||||||
@@ -1035,8 +1046,6 @@ void PythonSettings::initFromSettings(QtcSettings *settings)
|
|||||||
}
|
}
|
||||||
addKitsForInterpreter(interpreter, false);
|
addKitsForInterpreter(interpreter, false);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fixupPythonKits();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const Interpreter &outdated : outdatedInterpreters)
|
for (const Interpreter &outdated : outdatedInterpreters)
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/mimeutils.h>
|
#include <utils/mimeutils.h>
|
||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
|
#include <utils/synchronizedvalue.h>
|
||||||
|
|
||||||
#include <QReadLocker>
|
#include <QReadLocker>
|
||||||
|
|
||||||
@@ -192,31 +193,37 @@ bool isVenvPython(const FilePath &python)
|
|||||||
return python.parentDir().parentDir().pathAppended("pyvenv.cfg").exists();
|
return python.parentDir().parentDir().pathAppended("pyvenv.cfg").exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isUsableHelper(QHash<FilePath, bool> *cache, const QString &keyString,
|
static bool isUsableHelper(
|
||||||
const QString &commandArg, const FilePath &python)
|
SynchronizedValue<QHash<FilePath, bool>> *cache,
|
||||||
|
const QString &commandArg,
|
||||||
|
const FilePath &python)
|
||||||
{
|
{
|
||||||
auto it = cache->find(python);
|
std::optional<bool> result;
|
||||||
if (it == cache->end()) {
|
cache->read([&result, python](const QHash<FilePath, bool> &cache) {
|
||||||
const Key key = keyFromString(keyString);
|
if (auto it = cache.find(python); it != cache.end())
|
||||||
Process process;
|
result = it.value();
|
||||||
process.setCommand({python, {"-m", commandArg, "-h"}});
|
});
|
||||||
process.runBlocking();
|
if (result)
|
||||||
const bool usable = process.result() == ProcessResult::FinishedWithSuccess;
|
return *result;
|
||||||
it = cache->insert(python, usable);
|
|
||||||
}
|
Process process;
|
||||||
return *it;
|
process.setCommand({python, {"-m", commandArg, "-h"}});
|
||||||
|
process.runBlocking();
|
||||||
|
const bool usable = process.result() == ProcessResult::FinishedWithSuccess;
|
||||||
|
cache->writeLocked()->insert(python, usable);
|
||||||
|
return usable;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool venvIsUsable(const FilePath &python)
|
bool venvIsUsable(const FilePath &python)
|
||||||
{
|
{
|
||||||
static QHash<FilePath, bool> cache;
|
static SynchronizedValue<QHash<FilePath, bool>> cache;
|
||||||
return isUsableHelper(&cache, "pyVenvIsUsable", "venv", python);
|
return isUsableHelper(&cache, "venv", python);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pipIsUsable(const FilePath &python)
|
bool pipIsUsable(const FilePath &python)
|
||||||
{
|
{
|
||||||
static QHash<FilePath, bool> cache;
|
static SynchronizedValue<QHash<FilePath, bool>> cache;
|
||||||
return isUsableHelper(&cache, "pyPipIsUsable", "pip", python);
|
return isUsableHelper(&cache, "pip", python);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString pythonVersion(const FilePath &python)
|
QString pythonVersion(const FilePath &python)
|
||||||
|
Reference in New Issue
Block a user