From f29e8f663df76947c547fad5ac56b21f53881ff2 Mon Sep 17 00:00:00 2001 From: Prajval Arora Date: Tue, 13 Oct 2026 17:00:00 -0700 Subject: [PATCH 1/2] fix: narrow file picker data fallback errors --- src/machinevisiontoolbox/base/imageio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machinevisiontoolbox/base/imageio.py b/src/machinevisiontoolbox/base/imageio.py index 53b28641..25975f94 100644 --- a/src/machinevisiontoolbox/base/imageio.py +++ b/src/machinevisiontoolbox/base/imageio.py @@ -54,7 +54,7 @@ def _pick_imagefile() -> Path: """ try: initialdir = mvtb_path_to_datafile("images") - except Exception: + except (ModuleNotFoundError, ValueError): initialdir = Path.home() try: From 312e212c5cde4a7b6983db1a7a7402329643791a Mon Sep 17 00:00:00 2001 From: Prajval Arora Date: Tue, 13 Oct 2026 17:00:21 -0700 Subject: [PATCH 2/2] test: cover file picker fallback and resolver failures --- tests/base/test_file_picker.py | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 tests/base/test_file_picker.py diff --git a/tests/base/test_file_picker.py b/tests/base/test_file_picker.py new file mode 100644 index 00000000..64d9595b --- /dev/null +++ b/tests/base/test_file_picker.py @@ -0,0 +1,48 @@ +"""The file picker only falls back for unavailable toolbox data.""" + +from pathlib import Path +from types import SimpleNamespace +from unittest.mock import Mock + +import pytest + +from machinevisiontoolbox.base import imageio + + +@pytest.fixture +def picker(monkeypatch): + dialog = Mock(return_value="selected.png") + root = Mock() + tk = SimpleNamespace( + Tk=Mock(return_value=root), filedialog=SimpleNamespace(askopenfilename=dialog) + ) + monkeypatch.setitem(__import__("sys").modules, "tkinter", tk) + return dialog, root + + +@pytest.mark.parametrize( + "error", [ModuleNotFoundError("mvtbdata"), ValueError("missing images")] +) +def test_missing_data_uses_home(monkeypatch, picker, error): + monkeypatch.setattr(imageio, "mvtb_path_to_datafile", Mock(side_effect=error)) + dialog, root = picker + assert imageio._pick_imagefile() == Path("selected.png") + assert dialog.call_args.kwargs["initialdir"] == str(Path.home()) + root.destroy.assert_called_once() + + +def test_data_directory_is_used(monkeypatch, picker, tmp_path): + monkeypatch.setattr(imageio, "mvtb_path_to_datafile", Mock(return_value=tmp_path)) + dialog, _ = picker + assert imageio._pick_imagefile() == Path("selected.png") + assert dialog.call_args.kwargs["initialdir"] == str(tmp_path) + + +@pytest.mark.parametrize( + "error", [RuntimeError("broken resolver"), KeyboardInterrupt()] +) +def test_unexpected_resolver_errors_propagate(monkeypatch, picker, error): + monkeypatch.setattr(imageio, "mvtb_path_to_datafile", Mock(side_effect=error)) + with pytest.raises(type(error)): + imageio._pick_imagefile() + picker[0].assert_not_called()