Reworked Python initialization

KLAYOUT_PYTHONPATH is copied into PYTHONPATH, so it
is essentially equivalent (no more copying of internally
generated paths).

The installation's pymod folder is added to the path, so
that we can put "klayout.db" etc. there.
This commit is contained in:
Matthias Koefferlein 2023-03-08 01:15:53 +01:00
parent 0204f293b5
commit 35d9cdb656
1 changed files with 40 additions and 23 deletions

View File

@ -34,6 +34,7 @@
#include "gsiDecl.h"
#include "gsiDeclBasic.h"
#include "tlLog.h"
#include "tlEnv.h"
#include "tlStream.h"
#include "tlTimer.h"
#include "tlFileUtils.h"
@ -223,21 +224,42 @@ PythonInterpreter::PythonInterpreter (bool embedded)
std::string app_path = tl::get_exe_file ();
#if PY_MAJOR_VERSION >= 3
// If set, use $KLAYOUT_PYTHONPATH to initialize the path.
// Otherwise there may be some conflict between external installations and KLayout.
// if set, use $KLAYOUT_PYTHONPATH to initialize the path
# if defined(_WIN32)
bool has_klayout_pythonpath = false;
// Python is not easily convinced to use an external path properly.
// So we simply redirect PYTHONPATH
std::string pythonpath_name ("PYTHONPATH");
std::string klayout_pythonpath_name ("KLAYOUT_PYTHONPATH");
if (tl::has_env (pythonpath_name)) {
tl::unset_env (pythonpath_name);
}
if (tl::has_env (klayout_pythonpath_name)) {
has_klayout_pythonpath = true;
tl::set_env (pythonpath_name, tl::get_env (klayout_pythonpath_name));
}
// If set, use $KLAYOUT_PYTHONHOME to initialize the path.
// Otherwise there may be some conflict between external installations and KLayout.
// Python is not easily convinced to use an external path properly.
// So we simply redirect PYTHONHOME
std::string pythonhome_name ("PYTHONHOME");
std::string klayout_pythonhome_name ("KLAYOUT_PYTHONHOME");
if (tl::has_env (pythonhome_name)) {
tl::unset_env (pythonhome_name);
}
if (tl::has_env (klayout_pythonhome_name)) {
tl::set_env (pythonhome_name, tl::get_env (klayout_pythonhome_name));
}
#if defined(_WIN32) && PY_MAJOR_VERSION >= 3
tl_assert (sizeof (wchar_t) == 2);
Py_SetPythonHome ((wchar_t *) L""); // really ignore $PYTHONHOME + without this, we get dummy error message about lacking path for libraries
const wchar_t *python_path = _wgetenv (L"KLAYOUT_PYTHONPATH");
if (python_path) {
Py_SetPath (python_path);
} else {
if (! has_klayout_pythonpath) {
// If present, read the paths from a file in INST_PATH/.python-paths.txt.
// The content of this file is evaluated as an expression and the result
@ -289,18 +311,6 @@ PythonInterpreter::PythonInterpreter (bool embedded)
}
# else
const char *python_path = getenv ("KLAYOUT_PYTHONPATH");
if (python_path) {
std::wstring path = tl::to_wstring (tl::to_string_from_local (python_path));
Py_SetPath (path.c_str ());
}
# endif
#endif
#if PY_MAJOR_VERSION < 3
@ -366,6 +376,13 @@ PythonInterpreter::PythonInterpreter (bool embedded)
m_pya_module.reset (new pya::PythonModule ());
m_pya_module->init (pya_module_name, module);
m_pya_module->make_classes ();
// Add a reference to the "pymod" directory close to our own library.
// We can put build-in modules there.
std::string module_path = tl::get_module_path ((void *) &reset_interpreter);
if (! module_path.empty ()) {
add_path (tl::combine_path (tl::absolute_path (module_path), "pymod"));
}
}
PythonInterpreter::~PythonInterpreter ()