Contributing to Recursivist¶
Thank you for your interest in contributing to Recursivist! This document provides guidelines and instructions for contributing to this project.
Table of Contents¶
- Contributing to Recursivist
- Table of Contents
- Getting Started
- Development Workflow
- Coding Standards
- Testing
- Bug Reports and Feature Requests
- Release Process
- Community
Getting Started¶
Setting Up Your Development Environment¶
- Fork the repository:
-
Visit the Recursivist repository and click the "Fork" button to create your own copy.
-
Clone your fork:
- Install uv (used for all environment and dependency management):
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
- Create a virtual environment and install development dependencies:
- Install pre-commit hooks:
The pre-commit hooks will automatically run Ruff (lint + format) and mypy/pyright type checks on every commit.
Development Workflow¶
Creating a Branch¶
- Create a new branch for your feature or bugfix:
Making Changes¶
-
Make your changes to the codebase according to our coding standards.
-
Commit your changes with clear and descriptive commit messages:
Pre-commit hooks will run automatically on commit. If they flag issues, fix them and commit again.
- Keep your branch updated with the upstream repository by syncing your fork on GitHub and pulling locally:
Testing Your Changes¶
We use Nox as the task runner. All sessions run inside isolated uv-managed virtual environments.
- Run the full test suite across all supported Python versions:
- Run linting and type checks:
- Build and preview the documentation:
- Test the CLI to verify it works as expected:
Submitting a Pull Request¶
- Push your branch to your fork:
- Create a Pull Request from your fork to the main repository:
- Go to the Recursivist repository
- Click "Pull Requests" > "New Pull Request"
- Select "compare across forks" and choose your fork and branch
-
Click "Create Pull Request"
-
Describe your changes in the PR:
- What problem does it solve?
- How can it be tested?
-
Any dependencies or breaking changes?
-
Address review feedback if requested by maintainers.
Coding Standards¶
Code Style¶
We use Ruff for both linting and formatting. You can run it directly or via Nox:
Ruff is also run automatically by the pre-commit hooks on every commit.
Documentation¶
- Write docstrings for all public modules, functions, classes, and methods.
- Follow the Google docstring style as shown in existing code.
Example docstring:
def function(arg1: str, arg2: int) -> bool:
"""A short description of the function.
A more detailed description explaining the behavior, edge cases,
and implementation details if relevant.
Args:
arg1: Description of the first argument
arg2: Description of the second argument
Returns:
Description of the return value
Raises:
ValueError: When the input is invalid
"""
Type Annotations¶
All code must pass both mypy (strict mode) and pyright type checks. Use standard type hints:
def process_data(
data: dict[str, list[str]],
options: set[str] | None = None,
) -> bool:
return True
Run type checks via Nox:
This will run both mypy --strict and pyright against the codebase.
Testing¶
Running Tests¶
We use pytest via Nox. Coverage reporting is enabled by default (configured in pyproject.toml).
# Run tests across all supported Python versions (3.10–3.14)
nox -s tests
# Pass extra arguments to pytest (e.g. run a specific test)
nox -s tests -- -k test_something
# Run pytest directly in your active environment
pytest
Writing Tests¶
- Write tests for all new features and bug fixes.
- Place tests in the
tests/directory with a name matching the module being tested (e.g.tests/test_colors.py). - Follow the test style used in existing tests.
Example test:
# tests/test_colors.py
from recursivist.colors import generate_color_for_extension
def test_generate_color_for_extension():
# Given
extension = ".py"
# When
color = generate_color_for_extension(extension)
# Then
assert isinstance(color, str)
assert color.startswith("#")
assert len(color) == 7
Bug Reports and Feature Requests¶
Reporting Bugs¶
Please report bugs by opening an issue on GitHub with the following information:
- A clear and descriptive title
- Steps to reproduce the issue
- Expected behavior
- Actual behavior
- Environment details (OS, Python version, etc.)
- Any relevant logs or screenshots
Suggesting Features¶
We welcome feature requests! Please open an issue with:
- A clear and descriptive title
- A detailed description of the proposed feature
- Any relevant examples or use cases
- Information about why this feature would be useful
Release Process¶
Releases are largely automated via GitHub Actions.
- Bump the version in
pyproject.toml:
- Commit and push to
main:
-
Automatic tagging: The
tag-releaseworkflow detects the version change inpyproject.toml, checks that the tag doesn't already exist, and creates and pushes the Git tag automatically. No manual tagging is required. -
Publish to PyPI (maintainers only):
Community¶
- GitHub Discussions Use this for questions and general discussion.
- Issues Bug reports and feature requests.
- Pull Requests Submit changes to the codebase.
Thank you for contributing to Recursivist! Your efforts help make this project better for everyone.