From d4e1d4b55305414a18ba0a8ab0ffdc07d5149b4b Mon Sep 17 00:00:00 2001 From: Safi Date: Sat, 30 May 2026 13:12:59 +0100 Subject: [PATCH] fix pnpm-workspace.yaml packages:'.' crash on Python 3.10 (closes #1083) Co-Authored-By: Claude Sonnet 4.6 --- graphify/extract.py | 6 +++++- tests/test_js_import_resolution.py | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/graphify/extract.py b/graphify/extract.py index b51c4633..1d396a69 100644 --- a/graphify/extract.py +++ b/graphify/extract.py @@ -53,6 +53,9 @@ def _safe_extract(extractor: Callable, path: Path) -> dict: print(f" warning: skipped {path} (recursion limit exceeded)", file=sys.stderr, flush=True) return {"nodes": [], "edges": [], "error": "recursion_limit_exceeded"} except Exception as e: + if os.environ.get("GRAPHIFY_DEBUG"): + import traceback + traceback.print_exc(file=sys.stderr) print(f" warning: skipped {path} ({type(e).__name__}: {e})", file=sys.stderr, flush=True) return {"nodes": [], "edges": [], "error": f"{type(e).__name__}: {e}"} @@ -307,7 +310,8 @@ def _load_workspace_packages(start_dir: Path) -> dict[str, Path]: packages: dict[str, Path] = {} for pattern in _workspace_globs(root / "pnpm-workspace.yaml"): - for package_dir in root.glob(pattern): + package_dirs: list[Path] = [root] if pattern in (".", "./") else list(root.glob(pattern)) + for package_dir in package_dirs: manifest = package_dir / "package.json" if not manifest.is_file(): continue diff --git a/tests/test_js_import_resolution.py b/tests/test_js_import_resolution.py index e72cbaac..414cf8d8 100644 --- a/tests/test_js_import_resolution.py +++ b/tests/test_js_import_resolution.py @@ -425,6 +425,30 @@ def test_workspace_package_cache_refreshes_between_extract_calls(tmp_path: Path) assert _has_edge(second, "apps/web/src/page.ts", "packages/types/src/index.ts") +def test_pnpm_workspace_dot_package_does_not_crash(tmp_path: Path): + """packages: - '.' in pnpm-workspace.yaml must not raise IndexError on any Python version.""" + _write( + tmp_path / "pnpm-workspace.yaml", + "packages:\n - '.'\n - 'examples/*'\n", + ) + _write( + tmp_path / "package.json", + json.dumps({"name": "my-app"}), + ) + src = _write( + tmp_path / "index.ts", + "import { foo } from 'my-app';\n", + ) + + result = _extract_for([src], tmp_path) + + nodes = result.get("nodes", []) + assert isinstance(nodes, list) + for node in nodes: + error = node.get("error", "") if isinstance(node, dict) else "" + assert "IndexError" not in error + + def test_ts_type_relationships_and_contexts(tmp_path: Path): base = _write( tmp_path / "src/lib/base.ts",