From de4db79e5158017c002cc91c14fa9e58420e7774 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Fri, 13 Mar 2026 06:26:18 -0500 Subject: Bundle PBS Python 3.12 + PyQt6, restore Python plugins as .py files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 /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 --- libs/plugin_python/src/runner/pythonrunner.cpp | 76 +++----------------------- 1 file changed, 9 insertions(+), 67 deletions(-) (limited to 'libs/plugin_python/src/runner/pythonrunner.cpp') 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) /python (legacy bundled Python) - // 4) system Python (no PYTHONHOME needed) + // Priority: 1) /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 oldPythonHome; std::optional 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. -- cgit v1.3.1