Skip to content

fix: normalize path separators for import graph on Windows#2

Open
hamb3r wants to merge 1 commit intoMikeRecognex:mainfrom
hamb3r:fix/windows-import-graph-path-separators
Open

fix: normalize path separators for import graph on Windows#2
hamb3r wants to merge 1 commit intoMikeRecognex:mainfrom
hamb3r:fix/windows-import-graph-path-separators

Conversation

@hamb3r
Copy link

@hamb3r hamb3r commented Feb 26, 2026

Problem

On Windows, os.path.relpath() returns paths with backslashes (src\myproject\core.py), but all import resolution methods (_resolve_python_import, _resolve_ts_import, _resolve_rust_import, _resolve_go_import, _resolve_csharp_import) normalize candidate paths to forward slashes before looking them up in the all_files set.

This means every lookup fails on Windows:

all_files = {'src\myproject\utils.py', 'src\myproject\core.py'}   # backslashes from os.path.relpath
candidate = 'src/myproject/utils.py'                                # forward slashes from resolvers
candidate in all_files → False                                      # always misses

As a result, import_graph and reverse_import_graph are always empty {} on Windows. This silently breaks:

  • get_file_dependencies / get_file_dependents MCP tools
  • get_change_impact analysis (misses cross-file impact via imports)
  • The integration test test_index_mcp_codebase_index_source

CI runs on ubuntu-latest where os.sep is /, so the bug was never caught.

Root cause

Four calls to os.path.relpath() in project_indexer.py produce OS-native separators that become dict keys in ProjectIndex.files. The import resolvers already normalize candidates to /, but the keys they search against still contain \ on Windows.

Fix

Append .replace(os.sep, "/") to every os.path.relpath() call in project_indexer.py, so that file path keys are always forward-slash-normalized regardless of platform:

  • Line 116index() main loop
  • Line 191reindex_file()
  • Line 284remove_file()
  • Line 347_discover_files()

This is a one-character-class fix (4 lines changed), zero new logic. All existing import resolvers already expect forward-slash paths, so they start working correctly with no further changes.

Test plan

  • All 4 previously failing tests now pass on Windows:
    • TestImportGraph::test_python_import_resolution
    • TestImportGraph::test_reverse_import_graph
    • TestImportGraph::test_typescript_relative_import
    • TestIntegration::test_index_mcp_codebase_index_source
  • Full test suite: 375 passed, 0 failed
  • ruff check src/ tests/ — all checks passed
  • No behavior change on Linux/Mac (os.sep is already /, so .replace("/", "/") is a no-op)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant