feat: implement Python source extractor#87
Conversation
📝 WalkthroughWalkthroughAdds ChangesPython Extractor Implementation and Tests
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant PythonExtractor
participant ast
participant NormalizedDocument
Caller->>PythonExtractor: extract(path)
PythonExtractor->>ast: parse(source)
ast-->>PythonExtractor: top-level AST nodes
PythonExtractor->>NormalizedDocument: build symbol or module documents
PythonExtractor-->>Caller: return extracted documents
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/anchor/extractors/python.py (1)
28-31: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winConsider handling
SyntaxErrorfromast.parse.When the extractor is eventually wired into the ingestion pipeline, a malformed
.pyfile will causeast.parseto raise an unhandledSyntaxError, crashing the extraction step. Since the PR objectives note this is not yet wired intodetect.py/ingestor.py, this is acceptable for now, but adding a try/except that either returns an empty list or logs and skips would make the extractor more resilient when integrated.🤖 Prompt for 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. In `@src/anchor/extractors/python.py` around lines 28 - 31, The PythonExtractor.extract method currently calls ast.parse directly, so a malformed .py file will raise an uncaught SyntaxError when this extractor is used. Update extract in PythonExtractor to catch SyntaxError around the ast.parse call and either return an empty list or log-and-skip the file so the ingestion pipeline can continue gracefully; use the extract method and ast.parse as the key locations to change.tests/fixtures/ingestion/sample.py (1)
1-28: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueFixture file is not referenced by any test in this PR.
All 15 tests in
test_python_extractor.pyuserun_extractwith inline string content rather than loading this fixture. Consider either adding a test that exercises the fixture (e.g., an integration-style test that reads and extracts it) or removing it to avoid dead code. If it's intended for future use, a brief comment explaining its purpose would help.🤖 Prompt for 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. In `@tests/fixtures/ingestion/sample.py` around lines 1 - 28, The sample Python fixture is currently unused, so either add a test in test_python_extractor.py that actually loads and runs extraction against sample.py (using run_extract or a similar helper) or remove the fixture if it is not needed. If you keep it, reference its purpose near the fixture or in the relevant test so its presence is clearly intentional and tied to the Python extractor coverage.
🤖 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.
Nitpick comments:
In `@src/anchor/extractors/python.py`:
- Around line 28-31: The PythonExtractor.extract method currently calls
ast.parse directly, so a malformed .py file will raise an uncaught SyntaxError
when this extractor is used. Update extract in PythonExtractor to catch
SyntaxError around the ast.parse call and either return an empty list or
log-and-skip the file so the ingestion pipeline can continue gracefully; use the
extract method and ast.parse as the key locations to change.
In `@tests/fixtures/ingestion/sample.py`:
- Around line 1-28: The sample Python fixture is currently unused, so either add
a test in test_python_extractor.py that actually loads and runs extraction
against sample.py (using run_extract or a similar helper) or remove the fixture
if it is not needed. If you keep it, reference its purpose near the fixture or
in the relevant test so its presence is clearly intentional and tied to the
Python extractor coverage.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: f0ed6754-f287-4337-9470-dfe77db38ddd
📒 Files selected for processing (3)
src/anchor/extractors/python.pytests/fixtures/ingestion/sample.pytests/unit/test_python_extractor.py
|
Thanks for opening your first pull request in this repository, @Shreyaaaash. Before review starts, make sure the PR checklist is complete and the fastest relevant local checks have been run. The expected workflow is documented in CONTRIBUTING.md. |
|
Potentially related open or recent pull requests:
If one of these replaces this PR, a maintainer can close this with |
|
Thanks for contributing! This looks good! Could you update the PR title so the CI for PR Hygiene passes? Also this issue from CodeRabbit is valid and needs a quick fix: Consider handling SyntaxError from ast.parse. When the extractor is eventually wired into the ingestion pipeline, a malformed .py file will cause ast.parse to raise an unhandled SyntaxError, crashing the extraction step. |
85de13b to
916b6a9
Compare
Add PythonExtractor, parsing .py files with the stdlib ast module into NormalizedDocuments. Handles malformed files by raising ValueError instead of an unhandled SyntaxError.
916b6a9 to
ce527fd
Compare
|
Thanks! Sorry for the delay, I've merged now. |
Pull Request
Summary
Adds
PythonExtractor, which parses.pysource files with the stdlibastmodule intoNormalizedDocuments, giving code ingestion its first source-format extractor.Linked context
Closes #84
Checked issue #84 and the open PR list before starting — no other contributor has claimed it and no competing PR exists. The only related item is #68 (Markdown extractor, merged), which is a different format and not a duplicate of this work.
PR Size
PR Type
Context / Motivation
The roadmap calls for source-code ingestion, and Python is the smallest useful first format since the standard library can parse Python structure via
astwithout adding a dependency. This establishes the extractor pattern for code (as opposed to prose formats like Markdown/text) ahead of any multi-language work.Changes
PythonExtractor(src/anchor/extractors/python.py), which walks top-levelastnodes and emits oneNormalizedDocumentper top-level function/class, plusmodule-typed documents for other top-level statements (docstring, imports, constants, top-level calls), in file order.line_start/line_end,char_start/char_end(exact round-trip offsets into the original file), and code-aware metadata:symbol_type(function/async_function/class/module) andsymbol_namefor defs/classes.tests/fixtures/ingestion/sample.py, a fixture with a module docstring, imports, a top-level function, a class, and a trailing top-level statement.tests/unit/test_python_extractor.pycovering functions, async functions, classes, decorators, nested methods, module docstring/imports, interleaved module/function ordering, empty files, and char-offset round-tripping.How to test
pip install -e ".[ingestion]"pytest -m "not eval"— full deterministic suite passes (135 passed, 36 deselected)pytest tests/unit/test_python_extractor.py -v -m unit— 15/15 pass in isolationruff check/ruff format --check/mypy src/anchor/extractors/python.pyall cleanPrompt Change Eval Results
N/A — no prompt changes in this PR.
Checklist
Notes for reviewers
detect.pyoringestor.py— public file-ingestion routing was explicitly out of scope for [task] Add Python source-code extractor #84, since format detection ([task] Add source-code format detection #83) landed separately and this issue is scoped to the extractor only.module-typed document(s) rather than dropped or merged into adjacent symbol docs, mirroring how the Markdown extractor handles pre-heading content — happy to discuss if a different grouping is preferred.Summary by CodeRabbit
New Features
Bug Fixes
Tests
ValueErrorwith the file path and aSyntaxErrorcause.