Skip to content

Commit eb552ee

Browse files
committed
Add guardrails for cxx -print-search-dirs failure
1 parent 2bb847c commit eb552ee

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-5
lines changed

pytensor/link/c/cmodule.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2731,6 +2731,15 @@ def get_cxx_library_dirs():
27312731
shell=True,
27322732
)
27332733
(stdout, stderr) = p.communicate(input=b"")
2734+
if p.returncode != 0:
2735+
warnings.warn(
2736+
"Pytensor cxx failed to communicate its search dirs. As a consequence, "
2737+
"it might not be possible to automatically determine the blas link flags to use.\n"
2738+
f"Command that was run: {config.cxx} -print-search-dirs\n"
2739+
f"Output printed to stderr: {stderr.decode(sys.stderr.encoding)}"
2740+
)
2741+
return []
2742+
27342743
maybe_lib_dirs = [
27352744
[pathlib.Path(p).resolve() for p in line[len("libraries: =") :].split(":")]
27362745
for line in stdout.decode(sys.stdout.encoding).splitlines()

tests/link/c/test_cmodule.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""
77
import multiprocessing
88
import os
9+
import re
910
import sys
1011
import tempfile
1112
from unittest.mock import MagicMock, patch
@@ -207,23 +208,51 @@ def cxx_search_dirs(blas_libs, mock_system):
207208
yield f"libraries: ={d}".encode(sys.stdout.encoding), flags
208209

209210

211+
@pytest.fixture(
212+
scope="function", params=[False, True], ids=["Working_CXX", "Broken_CXX"]
213+
)
214+
def cxx_search_dirs_status(request):
215+
return request.param
216+
217+
210218
@patch("pytensor.link.c.cmodule.std_lib_dirs", return_value=[])
211219
@patch("pytensor.link.c.cmodule.check_mkl_openmp", return_value=None)
212220
def test_default_blas_ldflags(
213-
mock_std_lib_dirs, mock_check_mkl_openmp, cxx_search_dirs
221+
mock_std_lib_dirs, mock_check_mkl_openmp, cxx_search_dirs, cxx_search_dirs_status
214222
):
215223
cxx_search_dirs, expected_blas_ldflags = cxx_search_dirs
216224
mock_process = MagicMock()
217-
mock_process.communicate = lambda *args, **kwargs: (cxx_search_dirs, None)
225+
if cxx_search_dirs_status:
226+
error_message = ""
227+
mock_process.communicate = lambda *args, **kwargs: (cxx_search_dirs, b"")
228+
mock_process.returncode = 0
229+
else:
230+
error_message = "Unsupported argument -print-search-dirs"
231+
error_message_bytes = error_message.encode(sys.stderr.encoding)
232+
mock_process.communicate = lambda *args, **kwargs: (b"", error_message_bytes)
233+
mock_process.returncode = 1
218234
with patch("pytensor.link.c.cmodule.subprocess_Popen", return_value=mock_process):
219235
with patch.object(
220236
pytensor.link.c.cmodule.GCC_compiler,
221237
"try_compile_tmp",
222238
return_value=(True, True),
223239
):
224-
assert set(default_blas_ldflags().split(" ")) == set(
225-
expected_blas_ldflags.split(" ")
226-
)
240+
if cxx_search_dirs_status:
241+
assert set(default_blas_ldflags().split(" ")) == set(
242+
expected_blas_ldflags.split(" ")
243+
)
244+
else:
245+
expected_warning = re.escape(
246+
"Pytensor cxx failed to communicate its search dirs. As a consequence, "
247+
"it might not be possible to automatically determine the blas link flags to use.\n"
248+
f"Command that was run: {config.cxx} -print-search-dirs\n"
249+
f"Output printed to stderr: {error_message}"
250+
)
251+
with pytest.warns(
252+
UserWarning,
253+
match=expected_warning,
254+
):
255+
assert default_blas_ldflags() == ""
227256

228257

229258
def test_default_blas_ldflags_no_cxx():

0 commit comments

Comments
 (0)