Skip to content

Commit d0f95fd

Browse files
msmygitMadhavanautofix-ci[bot]mendonk
authored
test: catch import errors upfront (#10632)
* Convert to async and ruff-friendly print * Implement the checking into existing test file itself * Remove the newly introduced lfx test which is now incorporated into existing tests * [autofix.ci] apply automated fixes * [autofix.ci] apply automated fixes (attempt 2/3) * [autofix.ci] apply automated fixes (attempt 3/3) * [autofix.ci] apply automated fixes * [autofix.ci] apply automated fixes * [autofix.ci] apply automated fixes * [autofix.ci] apply automated fixes (attempt 2/3) * [autofix.ci] apply automated fixes (attempt 3/3) * Run make build_component_index after merging latest from main * [autofix.ci] apply automated fixes * Revert "docs: update component documentation links to individual pages" This reverts commit 1da51d4. * build component index after origin/main merge into feature branch * [autofix.ci] apply automated fixes --------- Co-authored-by: Madhavan <cxo@ibm.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com>
1 parent 0bc27d6 commit d0f95fd

6 files changed

Lines changed: 393 additions & 105846 deletions

File tree

.pre-commit-config.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,9 @@ repos:
5555
files: ^src/backend/base/langflow/initial_setup/starter_projects/.*\.json$
5656
pass_filenames: false
5757
args: [--security-check]
58+
- id: check-deprecated-imports
59+
name: Check for deprecated langchain imports
60+
entry: uv run python scripts/check_deprecated_imports.py
61+
language: system
62+
files: ^src/lfx/src/lfx/components/.*\.py$
63+
pass_filenames: false
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#!/usr/bin/env python3
2+
"""Check for deprecated langchain import patterns in component files.
3+
4+
This script scans all Python files in the lfx/components directory for
5+
deprecated import patterns and reports them. It's designed to be used
6+
as a pre-commit hook to catch import issues early.
7+
8+
Exit codes:
9+
0: No deprecated imports found
10+
1: Deprecated imports found
11+
2: Error during execution
12+
"""
13+
14+
import ast
15+
import sys
16+
from pathlib import Path
17+
18+
19+
def check_deprecated_imports(components_path: Path) -> list[str]:
20+
"""Check for deprecated import patterns in component files.
21+
22+
Args:
23+
components_path: Path to the components directory
24+
25+
Returns:
26+
List of error messages for deprecated imports found
27+
"""
28+
deprecated_imports = []
29+
30+
# Known deprecated import patterns
31+
deprecated_patterns = [
32+
("langchain.embeddings.base", "langchain_core.embeddings"),
33+
("langchain.llms.base", "langchain_core.language_models.llms"),
34+
("langchain.chat_models.base", "langchain_core.language_models.chat_models"),
35+
("langchain.schema", "langchain_core.messages"),
36+
("langchain.vectorstores", "langchain_community.vectorstores"),
37+
("langchain.document_loaders", "langchain_community.document_loaders"),
38+
("langchain.text_splitter", "langchain_text_splitters"),
39+
]
40+
41+
# Walk through all Python files in components
42+
for py_file in components_path.rglob("*.py"):
43+
# Skip private modules
44+
if py_file.name.startswith("_"):
45+
continue
46+
47+
try:
48+
content = py_file.read_text(encoding="utf-8")
49+
tree = ast.parse(content, filename=str(py_file))
50+
51+
for node in ast.walk(tree):
52+
if isinstance(node, ast.ImportFrom):
53+
module = node.module or ""
54+
55+
# Check against deprecated patterns
56+
for deprecated, replacement in deprecated_patterns:
57+
if module.startswith(deprecated):
58+
relative_path = py_file.relative_to(components_path.parent)
59+
deprecated_imports.append(
60+
f"{relative_path}:{node.lineno}: "
61+
f"Uses deprecated '{deprecated}' - should use '{replacement}'"
62+
)
63+
64+
except Exception as e: # noqa: BLE001
65+
# Report parsing errors but continue - we want to check all files
66+
print(f"Warning: Could not parse {py_file}: {e}", file=sys.stderr)
67+
continue
68+
69+
return deprecated_imports
70+
71+
72+
def main() -> int:
73+
"""Main entry point for the script.
74+
75+
Returns:
76+
Exit code (0 for success, 1 for deprecated imports found, 2 for error)
77+
"""
78+
try:
79+
# Find the lfx components directory
80+
script_dir = Path(__file__).parent
81+
repo_root = script_dir.parent
82+
lfx_components = repo_root / "src" / "lfx" / "src" / "lfx" / "components"
83+
84+
if not lfx_components.exists():
85+
print(f"Error: Components directory not found at {lfx_components}", file=sys.stderr)
86+
return 2
87+
88+
# Check for deprecated imports
89+
deprecated_imports = check_deprecated_imports(lfx_components)
90+
91+
if deprecated_imports:
92+
print("❌ Found deprecated langchain imports:", file=sys.stderr)
93+
print(file=sys.stderr)
94+
for imp in deprecated_imports:
95+
print(f" • {imp}", file=sys.stderr)
96+
print(file=sys.stderr)
97+
print(
98+
"Please update these imports to use the current langchain import paths.",
99+
file=sys.stderr,
100+
)
101+
print("See: https://python.langchain.com/docs/versions/migrating_chains/", file=sys.stderr)
102+
return 1
103+
# No deprecated imports found
104+
print("✅ No deprecated imports found")
105+
except Exception as e: # noqa: BLE001
106+
# Catch-all for unexpected errors during script execution
107+
print(f"Error: {e}", file=sys.stderr)
108+
return 2
109+
else:
110+
# Success case - no exceptions and no deprecated imports
111+
return 0
112+
113+
114+
if __name__ == "__main__":
115+
sys.exit(main())
116+
117+
# Made with Bob

0 commit comments

Comments
 (0)