Welcome! We're excited you're interested in contributing to py7zz. This guide will help you get started.
- Getting Started
- Development Setup
- Making Changes
- Testing
- Code Style
- Commit Guidelines
- Pull Request Process
- Community
- Python 3.8 or higher
- Git
- uv (for dependency management)
We welcome:
- 🐛 Bug fixes
- ✨ New features
- 📚 Documentation improvements
- 🧪 Test additions
- 🎨 Code refactoring
- 💡 Ideas and suggestions
-
Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/py7zz.git cd py7zz -
Install uv (if not installed)
curl -LsSf https://astral.sh/uv/install.sh | sh -
Set up development environment
uv sync --dev source .venv/bin/activate # On Windows: .venv\Scripts\activate
git checkout -b feature/your-feature-nameUse descriptive branch names:
feature/add-encryption-supportfix/windows-path-handlingdocs/update-api-reference
Follow the existing code structure and patterns.
Before committing, run all checks:
# Format code
uv run ruff format .
# Fix linting issues
uv run ruff check --fix .
# Type checking
uv run mypy .
# Run tests
uv run pytestOr use the local CI script:
./scripts/ci-local.sh# Run all tests
uv run pytest
# Run specific test file
uv run pytest tests/test_core.py
# Run with coverage
uv run pytest --cov=py7zz- Add tests for all new functionality
- Ensure tests work on Python 3.8-3.13
- Use descriptive test names
- Include both positive and negative test cases
Example:
def test_extract_with_invalid_path_raises_error():
"""Test that extracting to invalid path raises appropriate error."""
with pytest.raises(py7zz.FileNotFoundError):
py7zz.extract_archive('nonexistent.7z')- Style: PEP 8 with Black formatting (via Ruff)
- Line length: 88 characters
- Imports: Sorted by
isort(via Ruff) - Type hints: Required for all functions
- Docstrings: Google style for all public APIs
Example:
def create_archive(
archive_path: Union[str, Path],
files: List[Union[str, Path]],
preset: str = "balanced"
) -> None:
"""Create an archive with specified files.
Args:
archive_path: Path to create the archive
files: List of files/directories to include
preset: Compression preset ('fast', 'balanced', 'ultra')
Raises:
FileNotFoundError: If any input file doesn't exist
CompressionError: If compression fails
"""- Clear and concise
- Include code examples
- Update if changing behavior
- Check spelling and grammar
We follow Conventional Commits:
<type>(<scope>): <description>
[optional body]
[optional footer(s)]
feat: New featurefix: Bug fixdocs: Documentation onlystyle: Code style (formatting, missing semicolons, etc)refactor: Code change that neither fixes a bug nor adds a featureperf: Performance improvementtest: Adding or updating testschore: Maintenance tasks
# Feature
git commit -m "feat: add async progress callbacks for large archives"
# Bug fix
git commit -m "fix: resolve Windows path handling for reserved names"
# Documentation
git commit -m "docs: add migration guide from zipfile to py7zz"
# With scope
git commit -m "feat(api): add batch extraction support"
# Breaking change
git commit -m "feat!: change extract() to return list of extracted files
BREAKING CHANGE: extract() now returns a list instead of None"- All tests pass locally
- Code follows style guidelines
- Documentation is updated
- Commits follow convention
- Branch is up to date with main
IMPORTANT: PR titles must follow the same convention as commits:
feat: add async progress callbacks
fix: resolve Windows path handling
docs: update migration guide
This is critical because:
- PR titles appear in release notes
- Determines version bumps (feat = minor, fix = patch)
- Enables automatic labeling
Use the template to provide:
- Clear description of changes
- Related issue numbers
- Testing performed
- Breaking changes (if any)
- CI checks must pass
- Code review by maintainers
- Address feedback constructively
- Squash commits if requested
- 💬 GitHub Discussions - Ask questions
- 🐛 GitHub Issues - Report bugs
- 📚 Documentation - Read the docs
- Be respectful and inclusive
- Welcome newcomers
- Provide constructive feedback
- Focus on what's best for the community
Contributors are recognized in:
- GitHub contributors page
- Release notes
- Project documentation
For testing with custom 7zz binary:
export PY7ZZ_BINARY=/path/to/7zzEnable debug output:
import py7zz
py7zz.setup_logging("DEBUG")For performance-critical changes:
import timeit
import py7zz
# Measure performance
time = timeit.timeit(
lambda: py7zz.create_archive('test.7z', ['data/']),
number=10
)
print(f"Average time: {time/10:.2f}s")Feel free to:
- Open a Discussion for questions
- Reach out to maintainers
- Check existing issues and PRs
Thank you for contributing to py7zz! 🎉