c56bef871b
Sync docs with Docusaurus / sync (push) Waiting to run
Tests / Check if changed (push) Waiting to run
Tests / format (push) Blocked by required conditions
Tests / check-imports (push) Blocked by required conditions
Tests / Unit / macos-latest (push) Blocked by required conditions
Tests / Unit / ubuntu-latest (push) Blocked by required conditions
Tests / Unit / windows-latest (push) Blocked by required conditions
Tests / mypy (push) Blocked by required conditions
Tests / Integration / ubuntu-latest (push) Blocked by required conditions
Tests / Integration / macos-latest (push) Blocked by required conditions
Tests / Integration / windows-latest (push) Blocked by required conditions
Tests / notify-slack-on-failure (push) Blocked by required conditions
Tests / Mark tests as completed (push) Blocked by required conditions
Docker image release / Build base image (push) Waiting to run
CodeQL / Analyze (python) (push) Has been cancelled
Update Platform Components Table / update (push) Has been cancelled
86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
import importlib
|
|
import os
|
|
import sys
|
|
import traceback
|
|
from pathlib import Path
|
|
|
|
from haystack import logging # noqa: F401 # this is needed to avoid circular imports
|
|
|
|
|
|
def validate_module_imports(root_dir: str, exclude_subdirs: list[str] | None = None) -> tuple[list, list]:
|
|
"""
|
|
Recursively search for all Python modules and attempt to import them.
|
|
|
|
This includes both packages (directories with __init__.py) and individual Python files.
|
|
"""
|
|
imported = []
|
|
failed = []
|
|
exclude_subdirs = (exclude_subdirs or []) + ["__pycache__"]
|
|
|
|
# Add the root directory to the Python path
|
|
sys.path.insert(0, root_dir)
|
|
base_path = Path(root_dir)
|
|
|
|
for root, _, files in os.walk(root_dir):
|
|
if any(subdir in root for subdir in exclude_subdirs):
|
|
continue
|
|
|
|
# Convert path to module format
|
|
module_path = ".".join(Path(root).relative_to(base_path.parent).parts)
|
|
python_files = [f for f in files if f.endswith(".py")]
|
|
|
|
# Try importing package and individual files
|
|
for file in python_files:
|
|
try:
|
|
if file == "__init__.py":
|
|
module_to_import = module_path
|
|
else:
|
|
module_name = os.path.splitext(file)[0]
|
|
module_to_import = f"{module_path}.{module_name}" if module_path else module_name
|
|
|
|
importlib.import_module(module_to_import)
|
|
imported.append(module_to_import)
|
|
except Exception:
|
|
failed.append({"module": module_to_import, "traceback": traceback.format_exc()})
|
|
|
|
return imported, failed
|
|
|
|
|
|
def main() -> None:
|
|
"""
|
|
This script checks that all Haystack modules can be imported successfully.
|
|
|
|
This includes both packages and individual Python files.
|
|
This can detect several issues, such as:
|
|
- Syntax errors in Python files
|
|
- Missing dependencies
|
|
- Circular imports
|
|
- Incorrect type hints without forward references
|
|
"""
|
|
# Add any subdirectories you want to skip during import checks ("__pycache__" is skipped by default)
|
|
exclude_subdirs = ["testing"]
|
|
|
|
print("Checking imports from all Haystack modules...")
|
|
imported, failed = validate_module_imports(root_dir="haystack", exclude_subdirs=exclude_subdirs)
|
|
|
|
if not imported:
|
|
print("\nNO MODULES WERE IMPORTED")
|
|
sys.exit(1)
|
|
|
|
print(f"\nSUCCESSFULLY IMPORTED {len(imported)} MODULES")
|
|
|
|
if failed:
|
|
print(f"\nFAILED TO IMPORT {len(failed)} MODULES:")
|
|
for fail in failed:
|
|
print(f" - {fail['module']}")
|
|
|
|
print("\nERRORS:")
|
|
for fail in failed:
|
|
print(f" - {fail['module']}\n")
|
|
print(f" {fail['traceback']}\n\n")
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|