From 1acc15b6d213d431957f43319fad8b055b7ad960 Mon Sep 17 00:00:00 2001 From: Alyssa Coghlan Date: Tue, 5 Nov 2024 20:54:15 +1000 Subject: [PATCH] Handle missing dir skip in dynlib tests --- src/venvstacks/_injected/postinstall.py | 14 +++++++++---- tests/test_postinstall.py | 28 +++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/venvstacks/_injected/postinstall.py b/src/venvstacks/_injected/postinstall.py index 14c5cee..07dff83 100644 --- a/src/venvstacks/_injected/postinstall.py +++ b/src/venvstacks/_injected/postinstall.py @@ -100,7 +100,10 @@ def generate_pyvenv_cfg(base_python_path: Path, py_version: str) -> str: def generate_sitecustomize( - pylib_paths: Sequence[Path], dynlib_paths: Sequence[Path] + pylib_paths: Sequence[Path], + dynlib_paths: Sequence[Path], + *, + skip_missing_dynlib_paths: bool = True, ) -> str | None: """Generate `sitecustomize.py` contents for given linked environment directories""" sc_contents = [_SITE_CUSTOMIZE_HEADER] @@ -119,10 +122,13 @@ def generate_sitecustomize( "from os import add_dll_directory", ] for dynlib_path in dynlib_paths: - if not dynlib_path.exists(): + if skip_missing_dynlib_paths and not dynlib_path.exists(): # Nothing added DLLs to this folder at build time, so skip it - continue - dynlib_contents.append(f"add_dll_directory({str(dynlib_path)!r})") + # (add_dll_directory fails if the specified folder doesn't exist) + dynlib_entry = f"# Skipping {str(dynlib_path)!r} (no such directory)" + else: + dynlib_entry = f"add_dll_directory({str(dynlib_path)!r})" + dynlib_contents.append(dynlib_entry) dynlib_contents.append("") sc_contents.extend(dynlib_contents) if len(sc_contents) == 1: diff --git a/tests/test_postinstall.py b/tests/test_postinstall.py index 992f472..3c4ff93 100644 --- a/tests/test_postinstall.py +++ b/tests/test_postinstall.py @@ -47,6 +47,15 @@ def _make_dynlib_paths() -> tuple[list[Path], str]: return dynlib_paths, expected_lines +def _make_missing_dynlib_paths() -> tuple[list[Path], str]: + dynlib_dirs = [f"dynlib{n}" for n in range(5)] + dynlib_paths = [Path(d) for d in dynlib_dirs] + expected_lines = "\n".join( + f"# Skipping {d!r} (no such directory)" for d in dynlib_dirs + ) + return dynlib_paths, expected_lines + + def test_sitecustomize() -> None: pylib_paths, expected_lines = _make_pylib_paths() sc_text = postinstall.generate_sitecustomize(pylib_paths, []) @@ -54,12 +63,30 @@ def test_sitecustomize() -> None: assert sc_text.startswith(postinstall._SITE_CUSTOMIZE_HEADER) assert expected_lines in sc_text assert "add_dll_directory(" not in sc_text + assert "# Skipping" not in sc_text assert compile(sc_text, "_sitecustomize.py", "exec") is not None def test_sitecustomize_with_dynlib() -> None: pylib_paths, expected_pylib_lines = _make_pylib_paths() dynlib_paths, expected_dynlib_lines = _make_dynlib_paths() + sc_text = postinstall.generate_sitecustomize( + pylib_paths, dynlib_paths, skip_missing_dynlib_paths=False + ) + assert sc_text is not None + assert sc_text.startswith(postinstall._SITE_CUSTOMIZE_HEADER) + assert expected_pylib_lines in sc_text + if hasattr(os, "add_dll_directory"): + assert expected_dynlib_lines in sc_text + else: + assert "add_dll_directory(" not in sc_text + assert "# Skipping" not in sc_text + assert compile(sc_text, "_sitecustomize.py", "exec") is not None + + +def test_sitecustomize_with_missing_dynlib() -> None: + pylib_paths, expected_pylib_lines = _make_pylib_paths() + dynlib_paths, expected_dynlib_lines = _make_missing_dynlib_paths() sc_text = postinstall.generate_sitecustomize(pylib_paths, dynlib_paths) assert sc_text is not None assert sc_text.startswith(postinstall._SITE_CUSTOMIZE_HEADER) @@ -68,4 +95,5 @@ def test_sitecustomize_with_dynlib() -> None: assert expected_dynlib_lines in sc_text else: assert "add_dll_directory(" not in sc_text + assert "# Skipping" not in sc_text assert compile(sc_text, "_sitecustomize.py", "exec") is not None