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 120 of file ogs_embedded_python.cpp.

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

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 158 of file ogs_embedded_python.cpp.

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