Changeset View
Changeset View
Standalone View
Standalone View
plugins/extensions/pykrita/plugin/utilities.cpp
Context not available. | |||||
143 | QLibrary* s_pythonLibrary = 0; | 143 | QLibrary* s_pythonLibrary = 0; | ||
---|---|---|---|---|---|
144 | #endif | 144 | #endif | ||
145 | PyThreadState* s_pythonThreadState = 0; | 145 | PyThreadState* s_pythonThreadState = 0; | ||
146 | bool isPythonPathSet = false; | ||||
146 | } // anonymous namespace | 147 | } // anonymous namespace | ||
147 | 148 | | |||
148 | const char* Python::PYKRITA_ENGINE = "pykrita"; | 149 | const char* Python::PYKRITA_ENGINE = "pykrita"; | ||
Context not available. | |||||
278 | return true; | 279 | return true; | ||
279 | } | 280 | } | ||
280 | 281 | | |||
281 | bool Python::setPath(const QStringList& paths) | 282 | namespace | ||
282 | { | 283 | { | ||
283 | if (Py_IsInitialized()) { | 284 | | ||
284 | warnScript << "Setting paths when Python interpreter is already initialized"; | 285 | QString findKritaPythonLibsPath() | ||
286 | { | ||||
287 | QDir rootDir(KoResourcePaths::getApplicationRoot()); | ||||
288 | //Q_FOREACH (const QFileInfo &entry, rootDir.entryInfoList(QStringList() << "lib*", QDir::Dirs)) { | ||||
289 | Q_FOREACH (const QFileInfo &entry, rootDir.entryInfoList(QStringList() << "lib*", QDir::Dirs | QDir::NoDotAndDotDot)) { | ||||
290 | QDir libDir(entry.absoluteFilePath()); | ||||
291 | if (libDir.cd("krita-python-libs")) { | ||||
292 | return libDir.absolutePath(); | ||||
293 | } else { | ||||
294 | // Handle cases like Linux where libs are placed in a sub-dir | ||||
295 | // with the ABI name | ||||
296 | Q_FOREACH (const QFileInfo &subEntry, libDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) { | ||||
297 | QDir subDir(subEntry.absoluteFilePath()); | ||||
298 | if (subDir.cd("krita-python-libs")) { | ||||
299 | return subDir.absolutePath(); | ||||
300 | } | ||||
301 | } | ||||
302 | } | ||||
285 | } | 303 | } | ||
304 | return QString(); | ||||
305 | } | ||||
306 | | ||||
307 | } // namespace | ||||
308 | | ||||
309 | bool Python::setPath(const QStringList& scriptPaths) | ||||
310 | { | ||||
311 | KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!Py_IsInitialized(), false); | ||||
312 | KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!isPythonPathSet, false); | ||||
286 | #ifdef Q_OS_WIN | 313 | #ifdef Q_OS_WIN | ||
287 | constexpr char pathSeparator = ';'; | 314 | constexpr char pathSeparator = ';'; | ||
288 | #else | 315 | #else | ||
289 | constexpr char pathSeparator = ':'; | 316 | constexpr char pathSeparator = ':'; | ||
290 | #endif | 317 | #endif | ||
291 | QString joinedPaths = paths.join(pathSeparator); | 318 | QString originalPaths; | ||
292 | // Append the default search path | 319 | // Start with the script paths | ||
293 | // TODO: Properly handle embedded Python | 320 | QStringList paths(scriptPaths); | ||
321 | | ||||
322 | // Append the Krita libraries path | ||||
323 | QString pythonLibsPath = findKritaPythonLibsPath(); | ||||
324 | if (pythonLibsPath.isEmpty()) { | ||||
325 | errScript << "Cannot find krita-python-libs"; | ||||
326 | return false; | ||||
327 | } | ||||
328 | dbgScript << "Found krita-python-libs at" << pythonLibsPath; | ||||
329 | paths.append(pythonLibsPath); | ||||
330 | | ||||
294 | #ifdef Q_OS_WIN | 331 | #ifdef Q_OS_WIN | ||
295 | QString currentPaths; | 332 | // Find embeddable Python at <root>/python | ||
296 | // Find embeddable Python | | |||
297 | // TODO: Don't hard-code the paths | | |||
298 | QDir pythonDir(KoResourcePaths::getApplicationRoot()); | 333 | QDir pythonDir(KoResourcePaths::getApplicationRoot()); | ||
299 | if (pythonDir.cd("python")) { | 334 | if (pythonDir.cd("python")) { | ||
300 | dbgScript << "Found embeddable Python at" << pythonDir.absolutePath(); | 335 | dbgScript << "Found bundled Python at" << pythonDir.absolutePath(); | ||
301 | currentPaths = pythonDir.absolutePath() + pathSeparator | 336 | // The default paths for Windows embeddable Python is ./python36.zip;./ | ||
302 | + pythonDir.absoluteFilePath("python36.zip"); | 337 | // HACK: Assuming bundled Python is version 3.6.* | ||
338 | // FIXME: Should we read python36._pth for the paths or use Py_GetPath? | ||||
339 | paths.append(pythonDir.absoluteFilePath("python36.zip")); | ||||
340 | paths.append(pythonDir.absolutePath()); | ||||
303 | } else { | 341 | } else { | ||
304 | # if 1 | 342 | errScript << "Bundled Python not found, cannot set Python library paths"; | ||
305 | // Use local Python??? | | |||
306 | currentPaths = QString::fromWCharArray(Py_GetPath()); | | |||
307 | warnScript << "Embeddable Python not found."; | | |||
308 | warnScript << "Default paths:" << currentPaths; | | |||
309 | # else | | |||
310 | // Or should we fail? | | |||
311 | errScript << "Embeddable Python not found, not setting Python paths"; | | |||
312 | return false; | 343 | return false; | ||
313 | # endif | | |||
314 | } | 344 | } | ||
315 | #else | 345 | #else | ||
316 | QString currentPaths = QString::fromLocal8Bit(qgetenv("PYTHONPATH")); | 346 | // TODO: Handle embedded Python or virtualenv | ||
347 | // If using a system Python install, respect the current PYTHONPATH | ||||
348 | originalPaths = QString::fromLocal8Bit(qgetenv("PYTHONPATH")); | ||||
317 | #endif | 349 | #endif | ||
318 | if (!currentPaths.isEmpty()) { | 350 | | ||
319 | joinedPaths = joinedPaths + pathSeparator + currentPaths; | 351 | QString joinedPaths = paths.join(pathSeparator); | ||
352 | if (!originalPaths.isEmpty()) { | ||||
353 | joinedPaths = joinedPaths + pathSeparator + originalPaths; | ||||
320 | } | 354 | } | ||
321 | dbgScript << "Setting paths:" << joinedPaths; | 355 | infoScript << "Setting python paths:" << joinedPaths; | ||
322 | #ifdef Q_OS_WIN | 356 | #ifdef Q_OS_WIN | ||
323 | QVector<wchar_t> joinedPathsWChars(joinedPaths.size() + 1, 0); | 357 | QVector<wchar_t> joinedPathsWChars(joinedPaths.size() + 1, 0); | ||
324 | joinedPaths.toWCharArray(joinedPathsWChars.data()); | 358 | joinedPaths.toWCharArray(joinedPathsWChars.data()); | ||
Context not available. | |||||
326 | #else | 360 | #else | ||
327 | qputenv("PYTHONPATH", joinedPaths.toLocal8Bit()); | 361 | qputenv("PYTHONPATH", joinedPaths.toLocal8Bit()); | ||
328 | #endif | 362 | #endif | ||
363 | isPythonPathSet = true; | ||||
329 | return true; | 364 | return true; | ||
330 | } | 365 | } | ||
331 | 366 | | |||
Context not available. |