From a33157afccdef53628ef7c4c039061d7f9385677 Mon Sep 17 00:00:00 2001 From: Vito Sansevero Date: Thu, 29 Oct 2026 08:57:10 -0700 Subject: [PATCH] test(autotag): hide installed ML backends from the autotag tests Five autotag tests assumed onnxruntime and llama_cpp were absent and failed in a venv that has them. The import check now runs in a fresh interpreter, and the missing-package tests hide onnxruntime with a None sys.modules entry, so they pass with or without the packages. Closes #472 --- tests/test_autotag_engine.py | 35 +++++++++++++++++++++++++++------- tests/test_autotag_packages.py | 12 +++++++++--- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/tests/test_autotag_engine.py b/tests/test_autotag_engine.py index ec3e468e..5f8b2bde 100644 --- a/tests/test_autotag_engine.py +++ b/tests/test_autotag_engine.py @@ -8,6 +8,7 @@ import contextlib import csv import os import shutil +import subprocess import sys import tempfile import types @@ -15,7 +16,18 @@ import unittest from pathlib import Path from unittest.mock import MagicMock, patch -sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +_REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(0, _REPO_ROOT) + +# Run in a child interpreter: import py.autotag with a stub ComfyUI ``server`` +# and print every ML backend that the import pulled in. +_IMPORT_AUTOTAG_REPORT_BACKENDS = """ +import sys +from unittest.mock import MagicMock +sys.modules["server"] = MagicMock() +import py.autotag +print(*sorted({"onnxruntime", "llama_cpp"} & set(sys.modules))) +""" from PIL import Image @@ -142,17 +154,26 @@ class TestModelInjection(EngineTestCase): self.assertEqual(service._model_loader, service._load_model) def test_importing_autotag_does_not_import_ml_backends(self): - for heavy in ("onnxruntime", "llama_cpp"): - self.assertNotIn(heavy, sys.modules) + # A fresh interpreter: earlier tests in this process may have imported + # an installed backend, so only a clean import can prove this (#472). + result = subprocess.run( + [sys.executable, "-c", _IMPORT_AUTOTAG_REPORT_BACKENDS], + cwd=_REPO_ROOT, + capture_output=True, + text=True, + timeout=120, + ) + self.assertEqual(result.returncode, 0, result.stderr) + self.assertEqual(result.stdout.split(), []) def test_default_wd14_loader_reports_missing_onnxruntime(self): _touch_model_files(self.models_dir, "wd14-vit") service = AutoTagService(models_dir=self.models_dir) - if "onnxruntime" in sys.modules: - self.skipTest("onnxruntime is installed in this environment") - with self.assertRaises(RuntimeError) as ctx: - service.load_model("wd14-vit") + # A None entry makes onnxruntime unimportable even where it is installed. + with _patch_modules({"onnxruntime": None}): + with self.assertRaises(RuntimeError) as ctx: + service.load_model("wd14-vit") self.assertIn("onnxruntime", str(ctx.exception)) self.assertFalse(service.is_model_loaded()) diff --git a/tests/test_autotag_packages.py b/tests/test_autotag_packages.py index fb910ce8..c5336439 100644 --- a/tests/test_autotag_packages.py +++ b/tests/test_autotag_packages.py @@ -1,6 +1,7 @@ """#424: each tagging backend reports the Python packages it cannot import. -``find_spec`` is patched throughout: no ML backend is installed or imported. +``find_spec`` is patched throughout, and a backend an earlier test imported is +hidden where it matters, so these pass with or without the ML packages (#472). """ import os @@ -75,8 +76,13 @@ class TestMissingPackages(unittest.TestCase): def test_find_spec_errors_count_as_missing(self): for error in (ValueError("no spec"), ImportError("broken"), OSError("io")): with self.subTest(error=type(error).__name__): - with patch.object( - autotag.importlib.util, "find_spec", side_effect=error + # Hide an onnxruntime an earlier test imported, so the check + # reaches find_spec (#472). + with ( + _patch_modules({"onnxruntime": None}), + patch.object( + autotag.importlib.util, "find_spec", side_effect=error + ), ): self.assertEqual(missing_packages("wd14-vit"), ["onnxruntime"])