Skip to main content
The Python extractor covers .py files. Python has a single grammar construct for functions. Async functions parse as the same function_definition node, with the async keyword folded into it. Both sync and async def become Function.

What it detects

  • Functions: def (sync and async) becomes Function
  • Classes: class_definition becomes Class; methods are Function nodes nested inside
  • Decorators: decorator becomes Decorator; a decorated definition becomes a DecoratedDef wrapper around the underlying function or class
  • Imports: import_statement, import_from_statement, and future_import_statement all become Import
  • Assignments: assignment and augmented_assignment become Assignment / AugmentedAssignment. Assignment labels come from the left-hand expression; there is no separate Variable concept
  • Control flow: if / elif / else, for / while, try / except / finally, with, match / case
  • Comprehensions and lambdas: list / dict / set comprehensions, generator expressions, lambda
  • Type annotations: type, generic_type, and union_type become TypeAnnotation / GenericType / UnionType

Node type mapping

Node types without a mapping keep their raw tree-sitter type name. Function and class labels come from the definition’s name field. A DecoratedDef wrapper keeps the underlying definition’s name. Assignments use their left-hand expression as a label. Human reports retain class assignments, while local assignment details are grouped under their function.

Example: decorated functions and class assignments

Change a class setting, rename a decorated function, and edit its return value:
before.py
after.py
Running differens before.py after.py:
The class assignment keeps its name, and the decorated function keeps its class scope. Local assignment edits are grouped with their containing function in human reports. JSON retains the underlying assignment actions.

Example: move and edit a helper across files

Compare two directory snapshots. The destination module already exists, and the helper keeps its name while its body changes. This separates a modified move from the within-file rename example above:
old/pricing.py
new/pricing.py
old/discounts.py
new/discounts.py
Terminal output names the move; LLM output adds edited for a modified declaration move, and JSON exposes modified: true. The move summary pairs the supported declaration edits. Other edits, such as a new import, remain in the report. Renaming the helper during the move can prevent that pairing; use the original per-file JSON actions when investigating it.

Known limitations

  • Methods are not distinct: there is no Method concept; a method is a Function nested in a Class.
  • Assignments use Assignment, not Variable; their labels contain the left-hand expression.
  • Decorators and bodies have separate tree nodes; human reports may group their edits under the named definition.
  • Lambdas have no label: lambda becomes Lambda with no name.
  • Unmapped node types pass through: anything outside the map keeps its raw tree-sitter type name.