aboutsummaryrefslogtreecommitdiff
path: root/libs/plugin_python
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-03-13 06:26:18 -0500
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-03-13 06:26:18 -0500
commitde4db79e5158017c002cc91c14fa9e58420e7774 (patch)
tree74f8781aef49afa4e1cc3ba94c5a08876cadab0f /libs/plugin_python
parent84a43a2e6afbdfab92c610d47aa75e3876ffacd6 (diff)
Bundle PBS Python 3.12 + PyQt6, restore Python plugins as .py files
- Replace portable Python approach with python-build-standalone 3.12.13 (20260310 release) bundled directly in the distribution. Python is now always available without user setup — removes the Python settings tab. - PyQt6 staged to plugins/libs/PyQt6/ with bundled Qt stripped out; patchelf'd to use our existing bundled Qt in lib/ instead of duplicating it. - Restored native-converted plugins back to .py files: Form43Checker, ScriptExtenderPluginChecker, DDSPreview, basic_games, rootbuilder, installer_omod. Removed all *_native CMake targets. - pythonrunner.cpp: removed venv/MO2_PYTHON_DIR lookup; always uses bundled Python at <exe_dir>/python, system Python as last-resort fallback. - plugincontainer.cpp: removed fluorine/python_enabled gate (Python always loads), demoted proxy loading log messages from warn to debug, silenced [plugin-diag] stderr spam. - Dockerfile: switched from uv venv to PBS install_only tarball; PBS Python used for both build-time pybind11 compilation and runtime distribution. - build-inner.sh: aggressive Python staging (strip test/tkinter/ensurepip/ distutils/lib2to3/idlelib; wipe build-time site-packages, restore psutil+vdf). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'libs/plugin_python')
-rw-r--r--libs/plugin_python/src/runner/pythonrunner.cpp76
1 files changed, 9 insertions, 67 deletions
diff --git a/libs/plugin_python/src/runner/pythonrunner.cpp b/libs/plugin_python/src/runner/pythonrunner.cpp
index 0e6d596..c630530 100644
--- a/libs/plugin_python/src/runner/pythonrunner.cpp
+++ b/libs/plugin_python/src/runner/pythonrunner.cpp
@@ -148,64 +148,21 @@ namespace mo2::python {
#endif
// Determine Python home directory.
- // Priority: 1) venv at ~/.local/share/fluorine/python-venv/
- // 2) MO2_PYTHON_DIR env var (legacy bundled Python)
- // 3) <exe_dir>/python (legacy bundled Python)
- // 4) system Python (no PYTHONHOME needed)
+ // Priority: 1) <exe_dir>/python (bundled PBS Python)
+ // 2) system Python (no PYTHONHOME — last resort fallback)
QString pythonHome;
- QString venvPath;
- bool usingVenv = false;
- // Check for user-created venv
{
- QString dataDir = QDir::homePath() + "/.local/share/fluorine";
- QString venvDir = dataDir + "/python-venv";
- if (QDir(venvDir).exists() && QFile::exists(venvDir + "/bin/python3")) {
- venvPath = venvDir;
- // Read pyvenv.cfg to find the base Python prefix
- QFile cfg(venvDir + "/pyvenv.cfg");
- if (cfg.open(QIODevice::ReadOnly | QIODevice::Text)) {
- while (!cfg.atEnd()) {
- QString line = QString::fromUtf8(cfg.readLine()).trimmed();
- if (line.startsWith("home")) {
- // "home = /usr/bin" → base prefix is parent of bin dir
- int eq = line.indexOf('=');
- if (eq >= 0) {
- QString binDir = line.mid(eq + 1).trimmed();
- QDir parent(binDir);
- parent.cdUp();
- pythonHome = parent.absolutePath();
- usingVenv = true;
- MOBase::log::info("python: using venv at '{}', base prefix '{}'",
- venvPath, pythonHome);
- }
- break;
- }
- }
- }
- }
- }
-
- // Fallback: legacy bundled Python
- if (pythonHome.isEmpty()) {
- const char* envPy = std::getenv("MO2_PYTHON_DIR");
- if (envPy && envPy[0] != '\0') {
- pythonHome = QString::fromUtf8(envPy);
+ QString bundled = QCoreApplication::applicationDirPath() + "/python";
+ if (QDir(bundled).exists()) {
+ pythonHome = bundled;
+ MOBase::log::info("python: using bundled Python at '{}'", pythonHome);
} else {
- QString bundled = QCoreApplication::applicationDirPath() + "/python";
- if (QDir(bundled).exists()) {
- pythonHome = bundled;
- }
+ MOBase::log::warn("python: bundled Python not found at '{}', "
+ "falling back to system Python", bundled);
}
}
- // If no bundled Python, use system Python (don't set PYTHONHOME)
- if (!pythonHome.isEmpty() && !QDir(pythonHome).exists()) {
- MOBase::log::warn("python: PYTHONHOME dir '{}' does not exist, "
- "falling back to system Python", pythonHome);
- pythonHome.clear();
- }
-
std::optional<QByteArray> oldPythonHome;
std::optional<QByteArray> oldPythonPath;
auto restorePythonEnv = [&]() {
@@ -259,29 +216,14 @@ namespace mo2::python {
setenv("PYTHONHOME", pythonHome.toUtf8().constData(), 1);
}
- // If using a venv, prepend its site-packages so venv packages
- // (PyQt6, etc.) take priority over system site-packages.
- if (usingVenv && !venvPath.isEmpty()) {
- const QDir venvLibDir(venvPath + "/lib");
- const auto venvPyDirs =
- venvLibDir.entryList({"python3.*"}, QDir::Dirs | QDir::NoDotAndDotDot);
- if (!venvPyDirs.isEmpty()) {
- QString venvSite = venvPath + "/lib/" + venvPyDirs.first() + "/site-packages";
- if (QDir(venvSite).exists()) {
- corePaths.prepend(venvSite);
- }
- }
- }
-
if (!corePaths.isEmpty()) {
setenv("PYTHONPATH", corePaths.join(":").toUtf8().constData(), 1);
}
MOBase::log::debug(
"python: calling Py_InitializeFromConfig, PYTHONHOME='{}', "
- "venv='{}', Py_IsInitialized before={}",
+ "Py_IsInitialized before={}",
pythonHome.isEmpty() ? "(system)" : pythonHome,
- venvPath.isEmpty() ? "(none)" : venvPath,
Py_IsInitialized());
// Use Py_InitializeFromConfig (Python 3.8+) for explicit error reporting.