Extract source file skeletons using tree-sitter queries
Project description
Loppers
Simplified library for extracting source file skeletons using tree-sitter queries.
Removes function implementations while preserving structure and signatures.
Requires tree-sitter >= 0.25
Features
- ✅ Functions & Methods - All regular and async functions
- ✅ Constructors - Python
__init__, Java/TSconstructor() - ✅ Arrow Functions - JavaScript/TypeScript arrow functions
- ✅ Class Methods - Instance, static, class methods
- ✅ Docstrings - Python docstrings preserved
- ✅ Decorators - Preserved (Python, Java)
- ✅ Type Hints - Fully typed library
- ✅ 11 Languages - Python, JS/TS, Java, Go, Rust, C/C++, C#, Ruby, PHP
See HANDLED_CASES.md for comprehensive list of supported cases.
Installation
With uv (recommended)
# Install from source
uv pip install -e .
# Or sync with pyproject.toml
uv sync
# Install with dev dependencies
uv sync --extra dev
With pip
pip install tree-sitter>=0.25.0 tree-sitter-language-pack
Usage
from loppers import extract
source: str = '''
def calculate(x: int, y: int) -> int:
"""Calculate sum."""
result: int = x + y
return result
'''
skeleton: str = extract(source, "python")
print(skeleton)
Output:
def calculate(x: int, y: int) -> int:
"""Calculate sum."""
Supported Languages
- Python (with docstring preservation)
- JavaScript / TypeScript (including arrow functions)
- Java (including constructors)
- Go
- Rust
- C / C++
- C#
- Ruby
- PHP
Development
Setup
# Create environment and install dev dependencies
uv sync --extra dev
Testing with pytest
# Run all tests
uv run pytest
# Run with verbose output
uv run pytest -v
# Run with coverage
uv run pytest --cov=loppers --cov-report=html
# Run specific test
uv run pytest test_loppers.py::TestSkeletonExtractor::test_python_extraction
# Run with markers
uv run pytest -m "not slow"
Code Quality with ruff
# Check code style
uv run ruff check .
# Fix issues automatically
uv run ruff check . --fix
# Format code (included in check --fix)
uv run ruff format .
# Run all checks
uv run ruff check . && uv run ruff format .
Release & Publishing
This project uses Python Semantic Release for automated versioning and publishing to PyPI.
Prerequisites
- GitHub repository with branch protection rules (if desired)
- PyPI account with a token
- GitHub token (for pushing version commits)
Publish to PyPI
# Requires: GITHUB_TOKEN and PYPI_TOKEN environment variables set
# The command will:
# 1. Analyze commits since last release using conventional commits
# 2. Bump version automatically (major/minor/patch)
# 3. Build package distributions (sdist + wheel)
# 4. Publish to PyPI
uv run semantic-release publish
Manual Build (without publishing)
# Build distributions locally (creates dist/ folder)
uv run python -m build
# View built files
ls -lh dist/
Configuration
Release settings are in pyproject.toml under [tool.semantic_release]:
- Version pattern, branch, build command, etc.
- See DEVELOPMENT.md for detailed configuration
Commit Message Format
Uses Conventional Commits:
feat:- New feature (bumps minor version)fix:- Bug fix (bumps patch version)BREAKING CHANGE:- Major version bumpdocs:,chore:,refactor:- No version bump
How It Works
Uses tree-sitter queries to find and remove function/method body nodes while keeping:
- Function signatures
- Class definitions
- Import statements
- Python docstrings
- Comments
API
extract(source_code: str, language: str) -> str
Extract skeleton from source code.
Args:
source_code: Source code to processlanguage: Programming language
Returns: Skeleton with implementations removed
Raises:
ValueError: If language not supported
SkeletonExtractor(language: str)
Create extractor for a specific language.
Methods:
extract(source_code: str) -> str: Extract skeleton
Raises:
ValueError: If language not supported
Adding Languages
To add a new language, extend LANGUAGE_CONFIGS with a tree-sitter query:
LANGUAGE_CONFIGS["newlang"] = LanguageConfig(
name="newlang",
body_query="(function_definition body: (block) @body)",
)
Find the correct query for your language by exploring the tree-sitter grammar.
Type Hints
This project uses comprehensive type hints throughout. All functions are fully typed.
# Example of type hints in use
def extract(source_code: str, language: str) -> str:
"""Extract skeleton from source code."""
extractor: SkeletonExtractor = SkeletonExtractor(language)
return extractor.extract(source_code)
Configuration Files
- pyproject.toml: Project metadata, dependencies, pytest, and ruff configuration
- HANDLED_CASES.md: Comprehensive list of supported cases
- .gitignore: Git ignore rules
- UV_GUIDE.md: uv package manager quick reference
- DEVELOPMENT.md: Detailed development guide
.
├── loppers.py # Core library (typed)
├── examples.py # Usage examples (typed)
├── test_loppers.py # Unit tests (typed)
├── pyproject.toml # uv/pip + pytest + ruff config
├── .gitignore # Git ignore rules
├── README.md # This file
├── UV_GUIDE.md # uv quick reference
└── requirements.txt # Legacy requirements
tree-sitter API Changes (>= 0.25)
Key changes in the code for tree-sitter >= 0.25:
- Language wrapping:
Language(tree_sitter_language_pack.get_language(...)) - Parser language assignment:
parser.language = lang(property instead ofset_language())
References
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file loppers-1.0.1.tar.gz.
File metadata
- Download URL: loppers-1.0.1.tar.gz
- Upload date:
- Size: 86.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0f65e4803b707008893d883983731414bb32b637fad7e0dc343cfaefefdb6659
|
|
| MD5 |
6864565cc0e2205e49a55478eb0c3b7d
|
|
| BLAKE2b-256 |
54a6ec4f495b935bda3a3e69cdf3529909ccec59b24eebf62ae05255404eac3d
|
Provenance
The following attestation bundles were made for loppers-1.0.1.tar.gz:
Publisher:
publish.yml on undo76/loppers
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loppers-1.0.1.tar.gz -
Subject digest:
0f65e4803b707008893d883983731414bb32b637fad7e0dc343cfaefefdb6659 - Sigstore transparency entry: 612131148
- Sigstore integration time:
-
Permalink:
undo76/loppers@d5b8dc22c6e781c550b21cd69f1de3976b5273f5 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/undo76
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d5b8dc22c6e781c550b21cd69f1de3976b5273f5 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file loppers-1.0.1-py3-none-any.whl.
File metadata
- Download URL: loppers-1.0.1-py3-none-any.whl
- Upload date:
- Size: 8.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
10697999475b25821c4ac2e46772b8467ded64af53580f20ae0cd1a02bf4e246
|
|
| MD5 |
798800c30783889a26fd340a451dee28
|
|
| BLAKE2b-256 |
9cff8d0d301accd9fea6467f1d3561bfd8b0902291d0d23fa0b116311909a657
|
Provenance
The following attestation bundles were made for loppers-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on undo76/loppers
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loppers-1.0.1-py3-none-any.whl -
Subject digest:
10697999475b25821c4ac2e46772b8467ded64af53580f20ae0cd1a02bf4e246 - Sigstore transparency entry: 612131157
- Sigstore integration time:
-
Permalink:
undo76/loppers@d5b8dc22c6e781c550b21cd69f1de3976b5273f5 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/undo76
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d5b8dc22c6e781c550b21cd69f1de3976b5273f5 -
Trigger Event:
workflow_dispatch
-
Statement type: