From 08d6d7a6b72f05cfae57264b9b05f820f04cd66a Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Fri, 15 May 2026 19:24:19 +0100 Subject: [PATCH 1/5] fix exe path for container pythons --- src/ducktools/pythonfinder/shared.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ducktools/pythonfinder/shared.py b/src/ducktools/pythonfinder/shared.py index 3048329..9aebbc2 100644 --- a/src/ducktools/pythonfinder/shared.py +++ b/src/ducktools/pythonfinder/shared.py @@ -278,6 +278,10 @@ def query_install( if metadata: output["metadata"].update(metadata) + if exe_path != output["executable"]: + output["metadata"]["sys_executable"] = output["executable"] + output["executable"] = exe_path + install = PythonInstall.from_json(**output, managed_by=managed_by) return install From e53c4bcdccf164176c73e618cf8c76e74bb0a329 Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Fri, 15 May 2026 19:33:50 +0100 Subject: [PATCH 2/5] Tweak test that shows difference between pyenv pypy and python --- tests/test_pyenv.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/test_pyenv.py b/tests/test_pyenv.py index 5dfc436..4b41a16 100644 --- a/tests/test_pyenv.py +++ b/tests/test_pyenv.py @@ -249,6 +249,7 @@ def test_pypy_version(fs, temp_finder): ver_folder = "pypy3.10-7.3.15" tmpdir = os.path.expanduser("~/.pyenv/versions") + homedir = os.path.expanduser("~") mock_output = textwrap.dedent( """ @@ -282,10 +283,13 @@ def test_pypy_version(fs, temp_finder): out_version = PythonInstall( version=(3, 10, 13, "final", 0), - executable="~/.pyenv/versions/pypy3.10-7.3.15/bin/pypy", + executable=f"{homedir}/.pyenv/versions/pypy3.10-7.3.15/bin/python", architecture="64bit", implementation="pypy", - metadata={"pypy_version": (7, 3, 15, "final", 0)}, + metadata={ + "pypy_version": (7, 3, 15, "final", 0), + "sys_executable": "~/.pyenv/versions/pypy3.10-7.3.15/bin/pypy" + }, managed_by="pyenv", ) From 85191fb8032daacdec83328c423e0abda9de7c76 Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Fri, 15 May 2026 19:47:28 +0100 Subject: [PATCH 3/5] name a specific windows path to attempt to fix windows tests --- tests/test_cache.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/tests/test_cache.py b/tests/test_cache.py index 5e5bb1e..ee20049 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -1,18 +1,18 @@ # ducktools-pythonfinder # MIT License -# +# # Copyright (c) 2025 David C Ellis -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,6 +20,7 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import sys import os.path from types import SimpleNamespace from unittest.mock import patch @@ -28,15 +29,15 @@ from ducktools.pythonfinder.shared import DetailFinder, PythonInstall -fake_python_path = "/path/to/python" -example_json = """ -{ - "version": [3, 13, 2, "final", 0], - "executable": "/path/to/python", - "architecture": "64bit", - "implementation": "cpython", - "metadata": {"freethreaded": false} -} +fake_python_path = "/path/to/python" if sys.platform != "win32" else r"X:\path\to\python" +example_json = f""" +{{ + "version": [3, 13, 2, "final", 0], + "executable": "{fake_python_path}", + "architecture": "64bit", + "implementation": "cpython", + "metadata": {{"freethreaded": false}} +}} """.strip() example_install = PythonInstall( @@ -160,7 +161,7 @@ def test_clear_invalid_runtimes(run_mock, stat_mock, temp_finder): with temp_finder, patch("os.path.exists") as exists_patch: exists_patch.return_value = True temp_finder.clear_invalid_runtimes() - + save_mock.assert_not_called() assert os.path.abspath(fake_python_path) in temp_finder.raw_cache @@ -224,4 +225,4 @@ def test_changed_stat_invalidates(run_mock, temp_finder): details = temp_finder.get_install_details(fake_python_path) assert temp_finder.raw_cache[fake_abspath]["mtime"] == 1739886572 - querymock.assert_called() \ No newline at end of file + querymock.assert_called() From fdb98c77d308a4a28b7eab26e4878ec9c07f12c1 Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Fri, 15 May 2026 20:44:30 +0100 Subject: [PATCH 4/5] Fix windows tests --- tests/test_cache.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_cache.py b/tests/test_cache.py index ee20049..3176958 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -20,6 +20,7 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import re import sys import os.path from types import SimpleNamespace @@ -30,6 +31,7 @@ from ducktools.pythonfinder.shared import DetailFinder, PythonInstall fake_python_path = "/path/to/python" if sys.platform != "win32" else r"X:\path\to\python" +json_python_path = re.escape(fake_python_path) example_json = f""" {{ "version": [3, 13, 2, "final", 0], From d5431fd9848970c856bfdb0689ca0d3dfd4e7ed6 Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Fri, 15 May 2026 20:46:10 +0100 Subject: [PATCH 5/5] actually fix the windows tests --- tests/test_cache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cache.py b/tests/test_cache.py index 3176958..b7492b3 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -35,7 +35,7 @@ example_json = f""" {{ "version": [3, 13, 2, "final", 0], - "executable": "{fake_python_path}", + "executable": "{json_python_path}", "architecture": "64bit", "implementation": "cpython", "metadata": {{"freethreaded": false}}