Skip to content

feat(graph): add Python code graph extractor#103

Open
abhinav-phi wants to merge 1 commit into
mex-memory:code-graph-previewfrom
abhinav-phi:feat/python-code-graph-extractor
Open

feat(graph): add Python code graph extractor#103
abhinav-phi wants to merge 1 commit into
mex-memory:code-graph-previewfrom
abhinav-phi:feat/python-code-graph-extractor

Conversation

@abhinav-phi

Copy link
Copy Markdown

What

  • Add a Python LanguageExtractor for the code graph.
  • Register Python extraction and .py file detection.
  • Vendor and register the Tree-sitter Python WASM grammar.
  • Add representative Python fixtures and focused extractor tests.
  • Emit file, class, function, method, module variable, constant, import, call, inheritance, instantiation, and containment graph information while preserving unresolved cross-file references via targetName.

Why

Closes #94.

This adds first-class Python language support to the code-graph preview branch while preserving the frozen LanguageExtractor interface and existing graph semantics.

Type of change

  • Bug fix
  • New feature
  • Refactor
  • Docs
  • CI/Tooling

How to test

  1. Run:
    npm run typecheck
  2. Run:
    npm test
  3. Run:
    npm run build
  4. Verify:
    • Python files (.py) are detected correctly.
    • Python extractor emits file, class, function, method, import, call, inheritance, instantiation, and containment nodes/edges.
    • Cross-file references remain unresolved through targetName.
    • The Python grammar WASM is bundled into the build output.

Checklist

  • Tests pass (npm test)
  • No breaking changes (or documented below)
  • Tested locally with a real project

Code-graph preview

  • This PR targets code-graph-preview, not main
  • The linked issue states Target branch: code-graph-preview
  • The change follows the frozen LanguageExtractor or FrameworkResolver interface
  • A focused fixture and assertions for the expected node/edge shape are included
  • Any new grammar WASM, extension mapping, extractor, or resolver is registered
  • No graph identity, reconciliation, schema, or drift-semantics changes are included, or a core / discuss-first issue is linked above

@abhinav-phi
abhinav-phi changed the base branch from main to code-graph-preview July 15, 2026 19:43

@theDakshJaitly theDakshJaitly left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking on the first community language extractor. The implementation is cleanly registered and the current suite/typecheck/build pass, but a few #94 acceptance criteria are not met yet—most importantly instantiation references and bindable cross-file Python imports. I also found two AST-walk correctness issues below. Please address the inline comments, document the vendored grammar's source/version/license, and remove or split out the unrelated setup.sh / Windows CLI-test changes.

calleeName = getNodeText(fn, this.source);
}
}
// We treat all calls as 'calls', since Python has no 'new' keyword to distinguish 'instantiates'.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: #94 explicitly requires instantiates references, but this path emits every constructor-shaped call as calls. That also prevents Car(...) from ever binding, because the resolver only allows calls to target functions/methods while instantiates can target classes. Please emit and test an instantiates reference for the supported constructor heuristic (and preserve calls only where appropriate).

}
}
} else if (node.type === "import_from_statement") {
const moduleNameNode = getChildByField(node, "module_name") ?? node.namedChild(0);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: these Python module names are not currently bindable by the existing resolution pass. The resolver only tries JS/TS extensions and JS-style relative paths; additionally, from . import local becomes only targetName: ".", losing local. Please add an end-to-end two-file Python fixture/test and preserve a specifier the resolver can bind, including the necessary Python resolution support.

private extractHeritage(node: TSNode, fromId: string): void {
const superclasses = getChildByField(node, "superclasses");
if (!superclasses) return;
for (const child of superclasses.namedChildren) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please filter the superclass argument list to actual base expressions. As written, class Child(Base, metaclass=type) emits both extends Base and the invalid extends metaclass=type. A focused test covering a metaclass keyword would protect this.

// We treat all calls as 'calls', since Python has no 'new' keyword to distinguish 'instantiates'.
if (calleeName) this.addRef(ownerId, calleeName, "calls", node);

const args = getChildByField(node, "arguments");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nested argument calls are walked twice: once here and again when walkBody continues through all of the call node's children. For outer(inner()), the extractor emits two identical inner references. Please make one traversal path responsible for arguments and add a regression assertion.

tsx: "tree-sitter-tsx.wasm",
javascript: "tree-sitter-javascript.wasm",
jsx: "tree-sitter-javascript.wasm",
python: "tree-sitter-python.wasm",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The vendored Python WASM needs provenance documentation before merge. #94 and docs/extractors.md require the grammar source, exact version/commit, and license; none is included in this diff. Please add that documentation alongside the registration.

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.

[Python] Add code-graph extractor

2 participants