Repository navigation
fix(python): extract a decorated class nested in a class body - #2690
Merged
Merged
Conversation
RED on its own: push_nested_class_nodes does not look through decorated_definition. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
push_nested_class_nodes descended into field/template/declaration and conditional wrappers but not into Python's decorated_definition, so a decorated nested class (`@dataclass class Meta:` inside a class) was never extracted: no Class node, no Method nodes, and the calls in it fell to the FILE node. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
DeusData
added a commit
that referenced
this pull request
Oct 19, 2026
thugrock7
pushed a commit
to thugrock7/codebase-memory-mcp
that referenced
this pull request
Oct 19, 2026
…a#2680, DeusData#2690, DeusData#2695, DeusData#2696) py_lsp.c: the module-member lookup of this branch and the C3 super() lookup of DeusData#2696 were added at the same place; both are kept. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A Python class body can declare classes behind a decorator:
push_nested_class_nodes(extract_defs.c) descended into a class body's direct children only, so anested class wrapped in a
decorated_definitionwas never extracted. The class, its methods and every edgethey own were missing (matplotlib's
BoxStyle/ArrowStylestyles, wagtail'sPanel.BoundPanelfamily,textual's nested
Messagesubclasses, airflow's nested deadline models). For Python the walk now alsodescends into
decorated_definition, just as a top-level decorated class is handled. Plain nestedclasses are unchanged.
Builds on #2686 (#1548 nested defs, merged). No index-format change.
Evidence
Base #2686 @090580b3 vs this change @4d71327c, 26 Python repos (manifest v1), production builds, macOS
arm64,
--repeat 2, every repeat byte-identical (noise 0 on every type). The branch has since mergedmain (1346ac4, which includes #2686 and #2679); its diff against main is the two files of this change,
and PR CI tests the merged tree.
18 of the 26 repos are identical apart from SEMANTICALLY_RELATED noise. Sampled and read (271 edges,
seed 20261017):
correct DECORATES, OVERRIDE and INHERITS (to
_Base,_Curve,Message) and correct calls inside them(e.g.
BoxStyle.Ellipse.__call__ -> Path.unit_circle).inside a decorated nested class used to hang on the enclosing class or file. They now start at the
nested class's own methods.
registry, edges that are resolved by name alone pick a different candidate:
Input._watch_value -> Input.Changedinstead ofCheckbox.Changed, andTab.ClickedinheritsTab.TabMessageinstead ofTabs.TabMessage. wagtail'sMultiFieldPanel.BoundPanelinheritsPanelGroup.BoundPanel, andPanel.get_bound_panel -> Panel.BoundPanel. airflow's test calls throughSerializedReferenceModels.AverageRuntimeDeadline(...)reach that class instead of the task-sdknamesake, and textual's
TextAreamessage tests go toTextArea.Changed.classname,icon,attrs,classes: 88 USAGE, 81 WRITES) resolvedby name only move from one wrong candidate to another (
Table.Row.classnameor theicontemplatetag become
Panel.BoundPanel.classname/.icon).suffix_matchguesses. With more candidates, the guess can now pick a subclass override. Example:airflow
ReferenceModels.BaseDeadlineReference.evaluate_with'sself._evaluate_withused to reachthe class's own method and now reaches
AverageRuntimeDeadline._evaluate_with. A follow-up walksnested classes in the Python LSP under their outer class, which binds these self-calls.
Exposed approximation (documented, not changed here)
matplotlib's
patches.pydefines both the top-levelCircle/Ellipse/Wedgeand the decoratedstyle classes
BoxStyle.Circle,BoxStyle.EllipseandArrowStyle.Wedge. With matplotlib'slib/layout,from matplotlib.patches import Circlemisses the module-path strategy, and the symbol-name fallbackpicks the lexicographically smallest QN with that name. That is now
patches.BoxStyle.Circle(<
patches.Circle). Result: 30 IMPORTS are retargeted to the nested style class, 74 CALLS go toBoxStyle.Circle(40),BoxStyle.Ellipse(23) andArrowStyle.Wedge(11), and 30lsp_constructorplus53
unique_nameedges are lost becauseCircleis no longer unique. Two things cause this: thefallback can bind an import to a class member, and
lib/packages are not mapped. The new nodes only makeit visible. The follow-up fixes the fallback: an imported name is a module-level binding, never a class
member, and
lib/packages get a package map.Tests
pipeline_python_decorated_nested_class_extracted{,_parallel}: a decorated and a plain class nestedin one class body. Both classes and their methods are extracted, on the sequential and the parallel
pipeline. RED without the fix (
ASSERT(dec_class)).lsp_resolution_probe, incremental) pass on the merged tree.