OGS
ApplicationsLib::anonymous_namespace{ogs_embedded_python.cpp} Namespace Reference

Functions

std::vector< std::filesystem::path > findAlternativeSitePackagesPaths (std::filesystem::path const &venv_path)
std::filesystem::path findSitePackagesPath (std::filesystem::path const &venv_path, int const emb_major, int const emb_minor)
 Finds site-packages path in the virtual environment.

Function Documentation

◆ findAlternativeSitePackagesPaths()

std::vector< std::filesystem::path > ApplicationsLib::anonymous_namespace{ogs_embedded_python.cpp}::findAlternativeSitePackagesPaths ( std::filesystem::path const & venv_path)

Definition at line 121 of file ogs_embedded_python.cpp.

123{
124 namespace fs = std::filesystem;
125
126 std::vector<fs::path> alternatives;
127 fs::path const lib_path = venv_path / "lib";
128
129 if (!fs::exists(lib_path) || !fs::is_directory(lib_path))
130 {
131 // Should not happen, i.e. if venv directory is not valid
132 return {};
133 }
134
135 for (auto const& entry : fs::directory_iterator(lib_path))
136 {
137 if (!entry.is_directory())
138 {
139 continue;
140 }
141
142 std::string const dirname = entry.path().filename().string();
143 if (!dirname.starts_with("python"))
144 {
145 continue;
146 }
147
148 fs::path const candidate = entry.path() / "site-packages";
149 if (fs::exists(candidate) && fs::is_directory(candidate))
150 {
151 alternatives.push_back(candidate);
152 }
153 }
154
155 return alternatives;
156}

References findAlternativeSitePackagesPaths().

Referenced by findAlternativeSitePackagesPaths(), and findSitePackagesPath().

◆ findSitePackagesPath()

std::filesystem::path ApplicationsLib::anonymous_namespace{ogs_embedded_python.cpp}::findSitePackagesPath ( std::filesystem::path const & venv_path,
int const emb_major,
int const emb_minor )

Finds site-packages path in the virtual environment.

Definition at line 159 of file ogs_embedded_python.cpp.

162{
163 namespace fs = std::filesystem;
164
165#ifdef _WIN32
166 // On Windows only: compare embedded python interpreter version with the
167 // version of the python executable in the virtual environment.
168 auto const venv_version = getPythonVersionFromVenv(venv_path);
169 if (!venv_version.has_value())
170 {
171 OGS_FATAL(
172 "Failed to determine Python version from virtual environment at "
173 "'{}'.",
174 venv_path.string());
175 }
176
177 if (venv_version->first != emb_major || venv_version->second != emb_minor)
178 {
179 OGS_FATAL(
180 "Python version mismatch: embedded interpreter is {}.{}, but "
181 "virtual environment at '{}' uses {}.{}.",
182 emb_major, emb_minor, venv_path.string(), venv_version->first,
183 venv_version->second);
184 }
185
186 fs::path const site_packages = venv_path / "Lib" / "site-packages";
187#else
188 // On Linux / macOS: Construct path to site-packages directory where the
189 // Python version is embedded in the path. Then check for compatibility.
190 // E.g.: .venv/lib/python3.14/site-packages.
191 // Executing the virtual environment's Python interpreter may not possible
192 // when executing Python BCs from within a container environment, i.e.
193 // this would execute Python from the host inside the container.
194 fs::path const site_packages = venv_path / "lib" /
195 ("python" + std::to_string(emb_major) + "." +
196 std::to_string(emb_minor)) /
197 "site-packages";
198#endif // _WIN32
199
200 if (!fs::exists(site_packages))
201 {
202#ifndef _WIN32
203 // If correct site-packages directory is not found, check for
204 // directories for other Python versions, indicating a Python version
205 // mismatch. Possible on Linux / macOS only.
206 auto const alternatives = findAlternativeSitePackagesPaths(venv_path);
207 if (!alternatives.empty())
208 {
209 std::string alternative_paths;
210 for (std::size_t i = 0; i < alternatives.size(); ++i)
211 {
212 if (i > 0)
213 {
214 alternative_paths += ", ";
215 }
216 alternative_paths += "'" + alternatives[i].string() + "'";
217 }
218
219 WARN(
220 "Expected site-packages directory '{}' was not found. "
221 "Found other site-packages directory/directories: {}. This "
222 "may indicate a Python version mismatch between the embedded "
223 "interpreter {}.{} and the virtual environment.",
224 site_packages.string(), alternative_paths, emb_major,
225 emb_minor);
226 }
227#endif // _WIN32
228 OGS_FATAL("site-packages directory not found at '{}'",
229 site_packages.string());
230 }
231
232 return site_packages;
233}
#define OGS_FATAL(...)
Definition Error.h:10
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
std::vector< std::filesystem::path > findAlternativeSitePackagesPaths(std::filesystem::path const &venv_path)

References findAlternativeSitePackagesPaths(), findSitePackagesPath(), OGS_FATAL, and WARN().

Referenced by findSitePackagesPath().