Skip to content

Feat/python dependency integration#203

Open
christian-spahn-mw wants to merge 3 commits into
mainfrom
feat/python-dependency-integration
Open

Feat/python dependency integration#203
christian-spahn-mw wants to merge 3 commits into
mainfrom
feat/python-dependency-integration

Conversation

@christian-spahn-mw

@christian-spahn-mw christian-spahn-mw commented May 18, 2026

Copy link
Copy Markdown
Collaborator

Migrate python analysis to TSE

Summary by CodeRabbit

  • New Features

    • Added support for analyzing function and variable declarations in Python code.
  • Refactor

    • Streamlined Python analysis pipeline for improved dependency detection and classification across import types and declarations.

Review Change Stack

christian-spahn-mw and others added 3 commits May 6, 2026 15:52
…ionType cases

Temporary composite-build wiring lets DC consume TSE changes from the
sibling worktree during the Python migration iteration. Reverts before
the DC PR, per plans/add-python-dependency-support.md Task 7.

The newer TSE adds FUNCTION and VARIABLE to DeclarationType for Python's
top-level shapes; TseMappings.toNodeType() gains the corresponding
branches so the when-expression stays exhaustive.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the legacy PythonAnalyzer body (TSQuery walks +
PythonImportQuery / PythonTypeIdentifierQuery / PythonTypeAttributeQuery
/ PythonDefinitionsQuery) with a thin adapter over
TreeSitterDependencies.analyze(content, Language.PYTHON).

The adapter:
- Derives modulePath from FileInfo.physicalPath (ADR-0001).
- Resolves leading-dots relative IMPORT_FROM paths against modulePath
  (ADR-0003).
- Synthesizes the canonical/__init__ twin pair per IMPORT_FROM and
  per matched STANDARD-import attribute access (ADR-0004).
- Pre-loads non-aliased and wildcard FROM-import twins on every
  CLASS/FUNCTION declaration; conditionally pre-loads aliased
  FROM-import twins when the resolved tail name appears in the
  identifier stream (ADR-0006).
- Emits VARIABLE declarations as isolated leaves with empty
  dependencies and empty usedTypes, mirroring DC main's early return
  at PythonAnalyzer.kt:94-103 (Q10).
- For __init__.py files, emits one re-export Node per non-aliased
  IMPORT_FROM with dependencies = the regular FROM-import twin set.
- Maps usedTypes by partitioning on UsedType.namespacePrefix.isEmpty()
  (ADR-0005): identifier-stream entries become Node.usedTypes;
  attribute-stream entries drive STANDARD-import attribute matching
  into Node.dependencies.

Legacy queries and PythonUtils.kt are intentionally kept on disk
unused — they will be deleted only after dc-compare parity is
established (Task 6).

All 12 existing PythonAnalyzerTest cases pass against the rewrite.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PythonAnalyzer was rewritten as a thin TSE adapter in de3c509; the
TSQuery-based extraction it used to delegate to is now dead code.
Remove PythonUtils.kt and the four query classes plus the now-empty
queries/ directory:

- PythonUtils.kt
- queries/PythonDefinitionsQuery.kt
- queries/PythonImportQuery.kt
- queries/PythonTypeAttributeQuery.kt
- queries/PythonTypeIdentifierQuery.kt

Verified zero references remain in main and test sources, and
./gradlew ktlintCheck build (which runs the full test suite) passes
green with TSE wired via composite build.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR consolidates Python analysis from multiple dedicated tree-sitter query classes into a unified TreeSitterDependencies.analyze() flow, adds temporary build wiring for TreeSitterExcavationSite, and extends type mapping to support FUNCTION and VARIABLE declarations. The refactored analyzer now derives module paths, classifies imports, precomputes dependency variants, and constructs nodes with explicit handling for variables and __init__ module reexports.

Changes

Python Analyzer Migration to TreeSitterExcavationSite

Layer / File(s) Summary
Build infrastructure setup
analysis/build.gradle.kts, analysis/settings.gradle.kts
Temporary composite-build wiring adds local TreeSitterExcavationSite resolution via includeBuild("../../TreeSitterExcavationSite") and updates the dependency coordinate from published version 0.8.0 to composite-build coordinate, with explicit reversion comments.
Declaration type mapping extension
analysis/src/main/kotlin/.../TseMappings.kt
Extends DeclarationType.toNodeType() to map FUNCTION and VARIABLE types to their corresponding NodeType values, enabling the refactored analyzer to classify these declaration kinds.
Python analyzer core refactoring
analysis/src/main/kotlin/.../python/PythonAnalyzer.kt
Replaces tree-sitter query-driven pipeline with unified TreeSitterDependencies.analyze() entry point; computes module path, classifies imports into regular/from/wildcard-from/aliased-from categories, and precomputes base dependency variants.
Declaration node construction and init handling
analysis/src/main/kotlin/.../python/PythonAnalyzer.kt
Implements buildDeclarationNode to transform declarations into Node outputs with special handling for VARIABLE type (no dependencies/used types) and initFileReexportNodes helper for __init__ module reexport synthesis using precomputed twin dependencies.
Import resolution and dependency path handling
analysis/src/main/kotlin/.../python/PythonAnalyzer.kt
Provides resolveRelative extension for dot-prefixed import path rewriting, twinPair helper to generate canonical and __init__-adjusted dependency variants, and matchStandardImportAttribute logic to map used type attributes to standard imports with both routing variants; removes PythonUtils.trimFileEnding() and consolidates logic previously split across PythonImportQuery, PythonDefinitionsQuery, PythonTypeAttributeQuery, and PythonTypeIdentifierQuery query classes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • MaibornWolff/DependaCharta#191: Both PRs modify the Gradle setup to integrate TreeSitterExcavationSite by updating analysis/build.gradle.kts dependency coordinates and adding includeBuild(...) wiring in analysis/settings.gradle.kts.
  • MaibornWolff/DependaCharta#192: Both PRs are tied to the TreeSitterExcavationSite integration by adding/using TSE→DependaCharta mapping logic (notably the TseMappings.kt type mapping extensions used by the new analyzer).
  • MaibornWolff/DependaCharta#195: The PR's Gradle wiring for TreeSitterExcavationSite aligns with TSE-based migration work for C# analysis, as both directly modify how the TreeSitterExcavationSite library is integrated.

🐰 A refactor hops with glee,
Old queries now consolidated be,
Twin paths wind through __init__'s door,
Attributes matched to imports once more,
Python analysis, streamlined and free! 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feat/python dependency integration' directly relates to the main objective of migrating Python analysis to use TreeSitterDependencies, which is the core theme of this PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/python-dependency-integration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@analysis/build.gradle.kts`:
- Around line 23-24: The temporary composite-build coordinate and its broken
plan reference cause missing-plan and build-on-other-machines failures: either
(A) add the missing plan file plans/add-python-dependency-support.md with
explicit Task 7 revert instructions that state restoring
implementation("com.github.MaibornWolff:TreeSitterExcavationSite:<tag>") and
removing includeBuild("../../TreeSitterExcavationSite"), (B) add a CI pre-merge
check that validates includeBuild("../../TreeSitterExcavationSite") is
resolvable (fail the job with a clear message if the external repo is absent),
or (C) document the local checkout requirement for TreeSitterExcavationSite in
CLAUDE.md and the developer setup steps so builds are reproducible; update
references to
implementation("de.maibornwolff.treesitter.excavationsite:treesitter-excavationsite")
and includeBuild("../../TreeSitterExcavationSite") accordingly.

In `@analysis/settings.gradle.kts`:
- Around line 6-8: The settings.gradle.kts currently force-includes a local
composite build via includeBuild("../../TreeSitterExcavationSite") which breaks
builds for devs without that repo; also build.gradle.kts still references the
TSE composite dependency. Fix by either removing the composite wiring entirely
and reverting the dependency in build.gradle.kts to a published, pinned
coordinate (replace
implementation("de.maibornwolff.treesitter.excavationsite:treesitter-excavationsite")
with a stable group:artifact:version), or make the composite conditional: in
settings.gradle.kts check for the local path (File(...).exists()) before calling
includeBuild and otherwise do nothing so the published dependency in
build.gradle.kts is used as a fallback; update the inline REVERT comments to
reflect the chosen approach and ensure implementation(...) points to the
published coordinate when the composite is not included.

In
`@analysis/src/main/kotlin/de/maibornwolff/dependacharta/pipeline/analysis/analyzers/python/PythonAnalyzer.kt`:
- Line 47: The current call
nodes.addAll(initFileReexportNodes(regularFromImports, regularFromTwins.toSet(),
modulePath)) makes every synthetic __init__ re-export node depend on the entire
regularFromTwins set; change the logic so each re-export node is tied to exactly
one source import: iterate over regularFromTwins (or map over it) and call
initFileReexportNodes (or a new helper) with a singleton twin (or a parameter
for the single twin) along with regularFromImports and modulePath so each
produced node references only its originating twin; update equivalent calls in
the same file (the 55–69 region) to follow the same per-twin/singleton pattern.
- Around line 93-114: The current code builds usedTypes from identifierStream
(losing qualified types like pkg.Foo); instead keep the partition logic for
dependency matching but set usedTypes to declaration.usedTypes (as a Set)
instead of identifierStream.map { Type.simple(...) }, so the Node(...) uses the
full set of used types from declaration.usedTypes; leave the deps construction
(basePreloadedDeps, aliasedFromImports.forEach, attributeStream.forEach calling
matchStandardImportAttribute) unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9b76d155-20a5-492e-b7e8-5593c959eb26

📥 Commits

Reviewing files that changed from the base of the PR and between 4ee2ac2 and be4ae05.

📒 Files selected for processing (9)
  • analysis/build.gradle.kts
  • analysis/settings.gradle.kts
  • analysis/src/main/kotlin/de/maibornwolff/dependacharta/pipeline/analysis/analyzers/TseMappings.kt
  • analysis/src/main/kotlin/de/maibornwolff/dependacharta/pipeline/analysis/analyzers/python/PythonAnalyzer.kt
  • analysis/src/main/kotlin/de/maibornwolff/dependacharta/pipeline/analysis/analyzers/python/PythonUtils.kt
  • analysis/src/main/kotlin/de/maibornwolff/dependacharta/pipeline/analysis/analyzers/python/queries/PythonDefinitionsQuery.kt
  • analysis/src/main/kotlin/de/maibornwolff/dependacharta/pipeline/analysis/analyzers/python/queries/PythonImportQuery.kt
  • analysis/src/main/kotlin/de/maibornwolff/dependacharta/pipeline/analysis/analyzers/python/queries/PythonTypeAttributeQuery.kt
  • analysis/src/main/kotlin/de/maibornwolff/dependacharta/pipeline/analysis/analyzers/python/queries/PythonTypeIdentifierQuery.kt
💤 Files with no reviewable changes (5)
  • analysis/src/main/kotlin/de/maibornwolff/dependacharta/pipeline/analysis/analyzers/python/queries/PythonTypeAttributeQuery.kt
  • analysis/src/main/kotlin/de/maibornwolff/dependacharta/pipeline/analysis/analyzers/python/queries/PythonDefinitionsQuery.kt
  • analysis/src/main/kotlin/de/maibornwolff/dependacharta/pipeline/analysis/analyzers/python/queries/PythonTypeIdentifierQuery.kt
  • analysis/src/main/kotlin/de/maibornwolff/dependacharta/pipeline/analysis/analyzers/python/queries/PythonImportQuery.kt
  • analysis/src/main/kotlin/de/maibornwolff/dependacharta/pipeline/analysis/analyzers/python/PythonUtils.kt

Comment thread analysis/build.gradle.kts
Comment thread analysis/settings.gradle.kts
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