Repository navigation
Description
What problem does this solve?
Python class bodies are not extracted: class-level field/attribute assignments produce no nodes, type annotations are not projected as edges, and enums are not typed. The internal object model of every Python codebase is invisible to the graph.
Evidence from an indexed Django project (~82.6k nodes):
Fieldlabel total = 9 across the entire graph — and all 9 are Rust struct fields; zero Python.MATCH (c:Class)-[:DEFINES]->(f:Field)-> 0 rows.- The core
Inventorymodel (base_api/observations/models/models_shared.py) has out_degree = 0 despite in_degree = 1235 — heavily referenced, but its own body (everyCharField/ForeignKey/etc.) contributes nothing. - Type annotations live only as string properties (
return_type/param_types): 219 methods carryreturn_typecontainingInventory, but there is no edge to thatClassnode — "who returns/acceptsX?" is not traversable. - Enums:
Enumlabel = 2 (both Rust); 493 Python enums (Enum/TextChoices/IntegerChoicesbases) are bareClassnodes with no member representation.
Functions, methods, decorators (DECORATES 11,773) and inheritance (INHERITS 5,712) are already well modeled — the missing layer is class fields + type-annotation edges + enum members.
Proposed solution
The tree-sitter Python grammar already exposes class-body assignments and typed_parameter/annotation nodes; the Rust path already emits Field. Extend the existing extractors (internal/cbm/extract_defs.c, extract_type_refs.c / extract_type_assigns.c):
Fieldnodes per class-level assignment / annotated attribute (plain assignment,@dataclass,attrs, Pydantic, Djangox = models.CharField(...)), withClass -[:DEFINES]-> Fieldandparent_class(label + prop already exist in the schema).- Generic symbol resolution (NOT framework-specific): when a field's RHS callable argument or its annotation resolves to a known
Class, emitField -[:REFERENCES]-> Class— e.g.ForeignKey(Inventory),x: Inventory,list[Target]. This is plain AST symbol resolution; the model-relationship graph people want emerges as a side effect, without modeling ORM semantics. - Type-annotation edges: project the already-parsed param/return annotation strings into
DEPENDS_ON/USAGEedges to theirClassnodes (today they are dead string props). - Enums: type enum classes as
Enumand emit their members asFields.
Scope note: this deliberately does NOT introduce Django-ORM-semantic FK/M2M/O2O edge types (framework-specific, out of scope for a generic AST tool) — only generic field nodes and symbol/type resolution. Relationship traversal falls out of (2) generically.
Public OSS test beds
django/django(its owntests/app models) andwagtail/wagtail— FK/M2M/O2O-heavy.pydantic/pydantic,tiangolo/sqlmodel,tiangolo/fastapi— annotated-attribute models and typed params.python/cpythonLib/enum.py+ tests — enum members.
Alternatives considered
- Treat field assignments as generic
Variables: loses parent-class scoping and the type target, so no reference/type edges — the key value. search_codegrep forForeignKey/type names: finds text, no graph edges;trace_pathcan't traverse.- LSP go-to-def on attributes: intra-symbol resolution only; does not populate field/type graph structure.
Confirmations
- I searched existing issues and this is not a duplicate. Framework-semantic ORM relationship edges are intentionally excluded (generic field + type resolution only). Distinct from Protocol-aware cross-repo intelligence: gRPC + typed-message + attribute-route matching (design proposal) #292 (cross-repo protocol matching).
Activity
[-]feat: Python class-field & ORM-relationship extraction (Django/Pydantic/dataclass) — Field nodes + FK/M2M/O2O edges[/-][+]feat(python): class-field nodes, type-annotation edges, and enum members[/+]DeusData commentedon Jun 12, 2026
Thanks — class-field nodes and type-annotation edges are a natural extension of the Python extractor; queued for triage.
DeusData commentedon Oct 2, 2026
Thanks for the detailed Python extraction proposal and the concrete examples, and for your patience while it waited in triage.
We’re keeping Issues focused on actionable defects. Please open a Discussion with this proposal and a link back here, so class-field representation, annotation relationships, and enum members can be explored together.
I’m closing this issue as an administrative redirect to that discussion venue. Feature acceptance, prioritization, and implementation timing remain undecided.