PythonScript python 3k is not compatible with virtual environment under windows 11
Hi, I have to apologize for rather a fragmented issue / bug description.
Background. I'm using notepad++ in two different environments Home npp.8.4.2.portable.x64 Windows 11 Portable WinPython 3.8 PythonScript manual build against 3.8 link
Work npp.8.4.2.portable.x64 Windows 10 Pre-installed Python 3.8 by IT department PythonScript manual build against 3.8 [link] (https://github.com/stier08/PythonScript/tree/vs2019_toolset_v140_boost_1_74_0_wp38_x64_v2)
Problem PythonScript does not work in Home environment under python virtual environment
In Work environment , everything is fine.
Analysis With built in debug logging I was able to nail down issues to broken PyConfig. I.e. when executed under python virtual environment following PyConfig members got uninitialized
prefix, base_prefix, exec_prefix, base_exec_prefix,
and Py_InitializeFromConfig returns status:
"failed to get the Python codec of the filesystem encoding" in "init_fs_encoding"
Workaround
I was able to make a quick dirty fix to solve the issue by explicitly setting prefix, base_prefix, exec_prefix, base_exec_prefix, and appending missing paths to module_search_paths.
Unfortunately I did See more tech details down below and under https://github.com/stier08/PythonScript/tree/vs2019_toolset_v140_boost_1_74_0_wp38_x64_v2.
Workaround solution based on explicit parsing environment and pyvenv.cfg
` void venv_update_py_config(PyConfig& cfg) { const char* virtual_env; if (virtual_env = std::getenv("VIRTUAL_ENV")) { output_debug_string("VIRTUAL_ENV : " + std::string(virtual_env));
std::string pyvenv_cfg = std::string(virtual_env) + "\\" + std::string("pyvenv.cfg");
std::ifstream ifile;
ifile.open(pyvenv_cfg);
if (ifile) {
std::map<std::string, std::string> properties = read_key_values(ifile);
std::map<std::string, std::string>::iterator homeit = properties.find("home");
std::map<std::string, std::string>::iterator versionit = properties.find("version");
if (homeit != properties.end() && versionit != properties.end())
{
std::string home = homeit->second;
std::wstring whome;
std::wstring w_virtual_env;
{
std::wstringstream cls;
cls << home.c_str();
whome = cls.str();
}
{
std::wstringstream cls;
cls << virtual_env;
w_virtual_env = cls.str();
}
PyConfig_SetString(&cfg, & ( cfg.base_exec_prefix ), whome.c_str());
PyConfig_SetString(&cfg, & ( cfg.base_prefix) , whome.c_str());
PyConfig_SetString(&cfg, & ( cfg.exec_prefix) , w_virtual_env.c_str());
PyConfig_SetString(&cfg, & ( cfg.prefix ) , w_virtual_env.c_str());
PyWideStringList_Append(&cfg.module_search_paths,
(whome + std::wstring(L"\\") + std::wstring(L"python") + extract_python_suffix( versionit->second ) + std::wstring(L"python") ).c_str()
);
PyWideStringList_Append(&cfg.module_search_paths,
(whome + std::wstring(L"\\") + std::wstring(L"DLLs")).c_str()
);
PyWideStringList_Append(&cfg.module_search_paths,
(whome + std::wstring(L"\\") + std::wstring(L"lib")).c_str()
);
PyWideStringList_Append(&cfg.module_search_paths,
(whome ).c_str()
);
PyWideStringList_Append(&cfg.module_search_paths,
(w_virtual_env).c_str()
);
PyWideStringList_Append(&cfg.module_search_paths,
(w_virtual_env + std::wstring(L"\\") + std::wstring(L"site - packages")).c_str()
);
}
else {
if (homeit != properties.end())
output_debug_string(pyvenv_cfg + std::string(" home does not exist"));
if (versionit != properties.end())
output_debug_string(pyvenv_cfg + std::string(" version does not exist"));
}
}
else {
output_debug_string(pyvenv_cfg + std::string(" does not exist"));
}
}
else {
output_debug_string( "VIRTUAL_ENV " + std::string(" does not exist"));
}
} `