Compare commits

..
Author SHA1 Message Date
Hanif Koh 2896afa014 Keep the Plugin Tests' Python Packages Out of the Working Directory
The plugin test fixtures start the interpreter before the test points
data_dir at its temporary directory, so PythonInterpreter creates
{data_dir}/python/packages and {data_dir}/log with an empty data_dir: a
python/ and log/ folder in whatever directory the tests run from. When that
is the test binary's folder, the next run's embedded-interpreter tests took
the stray python/ as their home and failed to start Python.

Give each fixture that initializes the plugin manager its own temporary
data directory, set up before initialize(), and only use the python/ folder
next to the test binary as the interpreter's home when it holds a standard
library.
2026-09-29 14:20:57 +08:00
7 changed files with 33 additions and 3 deletions
+7 -2
View File
@@ -1019,9 +1019,14 @@ if (UNIX AND NOT APPLE)
find_package(GTK${SLIC3R_GTK} REQUIRED)
pkg_check_modules(LIBSECRET REQUIRED libsecret-1)
pkg_check_modules(webkit2gtk REQUIRED webkit2gtk-4.1)
find_package(X11 REQUIRED)
if (FLATPAK)
# I don't know why this is needed, but for whatever reason slic3r isn't
# linking to X11 and webkit2gtk. force it.
find_package(X11 REQUIRED)
target_link_libraries(libslic3r_gui ${X11_LIBRARIES} ${webkit2gtk_LIBRARIES})
endif()
target_include_directories(libslic3r_gui SYSTEM PRIVATE ${GTK${SLIC3R_GTK}_INCLUDE_DIRS} ${LIBSECRET_INCLUDE_DIRS} ${webkit2gtk_INCLUDE_DIRS})
target_link_libraries(libslic3r_gui ${GTK${SLIC3R_GTK}_LIBRARIES} fontconfig ${LIBSECRET_LIBRARIES} ${webkit2gtk_LIBRARIES} ${X11_LIBRARIES})
target_link_libraries(libslic3r_gui ${GTK${SLIC3R_GTK}_LIBRARIES} fontconfig ${LIBSECRET_LIBRARIES})
# Propagate GDK backend detection results as compile definitions so that
# LinuxDisplayBackend.cpp can include the right GDK headers.
+9 -1
View File
@@ -6,6 +6,7 @@
#include <boost/filesystem.hpp>
#include <memory.h>
#include <stdexcept>
#include <string>
#include <pybind11/embed.h>
#include <pybind11/pybind11.h>
@@ -25,8 +26,15 @@ void ensure_python_initialized()
config.parse_argv = 0;
const auto python_home = boost::dll::program_location().parent_path() / "python";
#ifdef _WIN32
const auto stdlib = python_home / "Lib";
#else
const auto stdlib = python_home / "lib" /
("python" + std::to_string(PY_MAJOR_VERSION) + "." + std::to_string(PY_MINOR_VERSION));
#endif
if (boost::filesystem::exists(python_home)) {
// Only a real runtime: a stray python/ folder (packages a test left behind) is not a home.
if (boost::filesystem::exists(stdlib / "encodings")) {
const std::string home = python_home.string();
const PyStatus status = PyConfig_SetBytesString(&config, &config.home, home.c_str());
@@ -38,6 +38,9 @@ namespace {
// before this destructor's shutdown() runs.
struct ScopedPluginManager
{
// Before initialize(): the interpreter creates {data_dir}/python/packages and {data_dir}/log,
// which would otherwise land in the working directory.
ScopedDataDir python_data_dir{"plugin-python"};
bool initialized = PluginManager::instance().initialize();
~ScopedPluginManager()
@@ -31,6 +31,9 @@ namespace {
// same as any other plugin.
struct ScopedManagerShutdown
{
// Before initialize(): the interpreter creates {data_dir}/python/packages and {data_dir}/log,
// which would otherwise land in the working directory.
ScopedDataDir python_data_dir{"plugin-python"};
bool initialized = PluginManager::instance().initialize();
~ScopedManagerShutdown()
@@ -41,6 +41,9 @@ namespace {
// Declare this FIRST in a test so it is destroyed last.
struct ScopedPluginManager
{
// Before initialize(): the interpreter creates {data_dir}/python/packages and {data_dir}/log,
// which would otherwise land in the working directory.
ScopedDataDir python_data_dir{"plugin-python"};
bool initialized = false;
ScopedPluginManager() { initialized = PluginManager::instance().initialize(); }
@@ -12,6 +12,8 @@
#include <memory>
#include <string>
#include "plugin_test_utils.hpp"
namespace py = pybind11;
using namespace Slic3r;
@@ -21,6 +23,9 @@ namespace {
// into Python unless PythonInterpreter::instance() reports initialized.
struct ScopedPluginManager
{
// Before initialize(): the interpreter creates {data_dir}/python/packages and {data_dir}/log,
// which would otherwise land in the working directory.
ScopedDataDir python_data_dir{"plugin-python"};
bool initialized = PluginManager::instance().initialize();
~ScopedPluginManager()
@@ -35,6 +35,9 @@ namespace {
struct ScopedPluginManager
{
// Before initialize(): the interpreter creates {data_dir}/python/packages and {data_dir}/log,
// which would otherwise land in the working directory.
ScopedDataDir python_data_dir{"plugin-python"};
bool initialized = false;
ScopedPluginManager() { initialized = PluginManager::instance().initialize(); }