|
14 | 14 |
|
15 | 15 | import inspect |
16 | 16 | from importlib import import_module |
17 | | -from pathlib import Path |
18 | 17 |
|
19 | 18 | import pytest |
20 | 19 |
|
@@ -53,44 +52,34 @@ def test_pipeline_imports(self): |
53 | 52 | _ = import_module(pipeline_folder_module, str(cls_name)) |
54 | 53 |
|
55 | 54 | def test_pipeline_module_imports(self): |
56 | | - """Import every pipeline submodule whose folder-level dependency guards |
57 | | - are satisfied, to catch unguarded optional-dep imports. |
| 55 | + """Import every pipeline submodule whose dependencies are satisfied, |
| 56 | + to catch unguarded optional-dep imports (e.g., torchvision). |
58 | 57 |
|
59 | | - Each pipeline folder's __init__.py evaluates guards like |
60 | | - is_torch_available() and populates _import_structure only for submodules |
61 | | - whose deps are met. We use _import_structure as the source of truth: |
62 | | - if a submodule is listed there, its declared deps are installed, so any |
63 | | - ImportError from importing it is a real bug (e.g., unguarded torchvision). |
| 58 | + Uses inspect.getmembers to discover classes that the lazy loader can |
| 59 | + actually resolve (same self-filtering as test_pipeline_imports), then |
| 60 | + imports the full module path instead of truncating to the folder level. |
64 | 61 | """ |
| 62 | + import diffusers |
65 | 63 | import diffusers.pipelines |
66 | 64 |
|
67 | | - pipelines_dir = Path(diffusers.pipelines.__file__).parent |
68 | 65 | failures = [] |
| 66 | + all_classes = inspect.getmembers(diffusers, inspect.isclass) |
69 | 67 |
|
70 | | - for subdir in sorted(pipelines_dir.iterdir()): |
71 | | - if not subdir.is_dir() or not (subdir / "__init__.py").exists(): |
| 68 | + for cls_name, cls_module in all_classes: |
| 69 | + if not hasattr(diffusers.pipelines, cls_name): |
| 70 | + continue |
| 71 | + if "dummy_" in cls_module.__module__: |
72 | 72 | continue |
73 | 73 |
|
74 | | - # Import the pipeline package to trigger its guard evaluation |
75 | | - package_module_path = f"diffusers.pipelines.{subdir.name}" |
| 74 | + full_module_path = cls_module.__module__ |
76 | 75 | try: |
77 | | - package_module = import_module(package_module_path) |
| 76 | + import_module(full_module_path) |
| 77 | + except ImportError as e: |
| 78 | + failures.append(f"{full_module_path}: {e}") |
78 | 79 | except Exception: |
79 | | - continue |
80 | | - |
81 | | - # _import_structure keys are the submodules whose deps are satisfied |
82 | | - import_structure = getattr(package_module, "_import_structure", {}) |
83 | | - |
84 | | - for submodule_name in import_structure: |
85 | | - full_module_path = f"{package_module_path}.{submodule_name}" |
86 | | - try: |
87 | | - import_module(full_module_path) |
88 | | - except ImportError as e: |
89 | | - failures.append(f"{full_module_path}: {e}") |
90 | | - except Exception: |
91 | | - # Non-import errors (e.g., missing config) are fine; we only |
92 | | - # care about unguarded import statements. |
93 | | - pass |
| 80 | + # Non-import errors (e.g., missing config) are fine; we only |
| 81 | + # care about unguarded import statements. |
| 82 | + pass |
94 | 83 |
|
95 | 84 | if failures: |
96 | 85 | pytest.fail("Unguarded optional-dependency imports found:\n" + "\n".join(failures)) |
0 commit comments