Development Guide¶
Comprehensive guide for developing and contributing to Ezpl.
Prerequisites¶
- Python 3.10 or higher
- Git
- Understanding of Python logging, Rich, and loguru
Development Setup¶
1. Clone the Repository¶
2. Create Virtual Environment¶
# Create virtual environment
python -m venv .venv
# Activate (Windows)
.venv\Scripts\activate
# Activate (Unix/Linux/macOS)
source .venv/bin/activate
3. Install Development Dependencies¶
This installs:
- Development tools: ruff, pyright
- Testing: pytest, pytest-cov, pytest-mock, pytest-xdist
- Build: build, twine
- Security: bandit
4. Install Git Hooks¶
# Activate custom hooks
git config core.hooksPath .hooks
# Or use pre-commit (alternative)
pre-commit install
Project Structure¶
ezplog/
├── .github/
│ ├── instructions/ # Development instructions
│ └── workflows/ # CI/CD workflows
├── .hooks/ # Custom Git hooks
├── docs/ # Documentation (mkdocs)
├── src/ # Source code
│ └── ezpl/
│ ├── cli/ # CLI commands
│ ├── config/ # Configuration management
│ ├── core/ # Core interfaces and exceptions
│ ├── handlers/ # Printer and logger handlers
│ │ └── wizard/ # RichWizard components
│ ├── types/ # Type definitions and enums
│ └── utils/ # Utilities
├── tests/ # Test suite
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ └── robustness/ # Robustness tests
├── examples/ # Example scripts
├── pyproject.toml # Project configuration
└── mkdocs.yml # Documentation configuration
Coding Standards¶
Python Style¶
Follow the project's coding standards defined in .github/instructions/:
- PEP 8 compliance
- Line length: 88 characters (Ruff default)
- Type hints: Required for all public APIs
- Docstrings: Google style
- Imports: Standard library → Third-party → Local
Type Hints¶
from __future__ import annotations
# Use modern type syntax
def process(data: list[str]) -> dict[str, int]:
...
# Prefer | over Union
def get_value(key: str) -> str | None:
...
# Use collections.abc
from collections.abc import Sequence
def handle_items(items: Sequence[str]) -> None:
...
Docstrings¶
def example_function(param1: str, param2: int | None = None) -> bool:
"""Brief description.
Detailed explanation of behavior.
Args:
param1: Description of param1
param2: Description of param2
Returns:
bool: Description of return value
Raises:
ValidationError: When validation fails
Example:
>>> result = example_function("test", 42)
>>> print(result)
True
"""
Development Workflow¶
1. Create a Feature Branch¶
2. Make Changes¶
Follow the coding standards and add tests for new features.
3. Run Code Quality Tools¶
# Format code
ruff format src/ezpl/
# Lint
ruff check src/ezpl/ --fix
# Type check
pyright src/ezpl/
# Security scan
bandit -r src/ezpl/
4. Run Tests¶
# All tests
pytest tests/
# With coverage
pytest tests/ --cov=ezpl --cov-report=html
# Specific test type
pytest tests/unit/
pytest tests/integration/
pytest tests/robustness/
# Parallel execution
pytest tests/ -n auto
5. Commit Changes¶
The pre-commit hook will automatically:
- Format and lint code with ruff
- Run linting checks
- Update version badge in README
- Auto-stage reformatted files
6. Push and Create PR¶
Then create a Pull Request on GitHub.
Git Hooks¶
Pre-commit Hook¶
Runs before each commit:
- Lint & Format: Ruff
- Update Version Badge: In README.md
- Auto-stage: Reformatted files
Post-commit Hook¶
Runs after each commit:
- Read Version: From pyproject.toml
- Create/Update Tags:
v<version>andv<major>-latest - Build Package: Via build script
Pre-commit Framework¶
Additional hooks via .pre-commit-config.yaml:
- File hygiene checks
- YAML/TOML validation
- Security checks
- Debug statement detection
Testing¶
Test Structure¶
tests/
├── conftest.py # Fixtures and hooks
├── run_tests.py # CLI test runner
├── unit/ # 10 test files
├── integration/ # 3 test files
└── robustness/ # 3 test files
Writing Tests¶
import pytest
from ezpl import Ezpl
def test_should_create_singleton_when_first_call():
"""Test that Ezpl creates singleton on first call."""
ezpl1 = Ezpl()
ezpl2 = Ezpl()
assert ezpl1 is ezpl2
def test_should_log_message_when_info_called(ezpl_instance):
"""Test that printer logs info message."""
printer = ezpl_instance.get_printer()
printer.info("Test message")
# Assertions...
Test Naming Convention¶
Running Tests¶
# All tests
python tests/run_tests.py --type all
# Unit tests only
python tests/run_tests.py --type unit
# With coverage
python tests/run_tests.py --type all --coverage
# Parallel execution
python tests/run_tests.py --parallel
# Exclude slow tests
python tests/run_tests.py --fast
# Specific marker
python tests/run_tests.py --marker wizard
Test Markers¶
@pytest.mark.unit- Unit tests@pytest.mark.integration- Integration tests@pytest.mark.robustness- Robustness tests@pytest.mark.slow- Slow tests@pytest.mark.wizard- RichWizard tests@pytest.mark.config- Configuration tests@pytest.mark.cli- CLI tests
Building¶
Build Package¶
# Clean previous builds
rm -rf build/ dist/ *.egg-info/
# Build
python -m build
# Check package
twine check dist/*
Test Installation¶
# Install from wheel
pip install dist/*.whl --force-reinstall
# Test import
python -c "import ezpl; print(ezpl.__version__)"
Documentation¶
Building Docs Locally¶
# Install docs dependencies
pip install -e ".[docs]"
# Serve docs locally
mkdocs serve
# Build docs
mkdocs build
Deploying Docs¶
Docs are automatically deployed via GitHub Actions on push to main:
# .github/workflows/docs.yml
on:
push:
branches: [main]
paths:
- "docs/**"
- "mkdocs.yml"
- "src/ezpl/**"
CI/CD¶
GitHub Actions Workflows¶
PyPI Publication¶
Triggered on version tag push (v*.*.*):
- Validate: Version consistency, tag on main branch
- Test: Run full test suite
- Build: Create wheel and source distribution
- Publish: Upload to PyPI
Documentation Deployment¶
Triggered on docs changes:
- Install: Package with docs dependencies
- Build: Generate documentation with mkdocs
- Deploy: Deploy to GitHub Pages
Release Process¶
1. Update Version¶
2. Update CHANGELOG¶
Document changes in CHANGELOG.md (if exists).
3. Commit and Push¶
git add pyproject.toml src/ezpl/__init__.py
git commit -m "chore: bump version to 1.5.2"
git push origin main
The post-commit hook will automatically:
- Create tag
v1.5.2 - Create/update tag
v1-latest - Build package
4. Verify and Push Tags¶
# Verify tags
git tag -l
# Push tags (triggers PyPI workflow)
git push origin v1.5.2
git push origin v1-latest --force
Troubleshooting¶
Common Issues¶
Import Errors in Tests¶
Type Check Failures¶
Test Failures on Windows¶
Some tests may fail on Windows due to file locking:
- The test suite includes Windows-specific teardown handling
- Use
gc.collect()and delays in fixtures
Git Hooks Not Running¶
# Verify hooks path
git config core.hooksPath
# Set hooks path
git config core.hooksPath .hooks
# Make hooks executable (Unix)
chmod +x .hooks/*
Best Practices¶
Code Quality¶
- Always run tests before committing
- Use type hints for all public APIs
- Write docstrings for all public functions/classes
- Keep functions small (max complexity: 10)
- Avoid global state (except singleton)
Test Practices¶
- Test behavior, not implementation
- Use descriptive test names
- Include edge cases
- Mock external dependencies
- Maintain high coverage (target: 65%+)
Git Commits¶
Follow conventional commits:
feat:- New featurefix:- Bug fixdocs:- Documentation changeschore:- Maintenance tasksrefactor:- Code refactoringtest:- Test changesstyle:- Code style changes
Pull Requests¶
- Clear title and description
- Reference issues (#123)
- Include tests for new features
- Update documentation if needed
- Ensure CI passes
Contributing Guidelines¶
Before Contributing¶
- Check existing issues and PRs
- Discuss major changes in an issue first
- Read
.github/instructions/for project guidelines
Contribution Process¶
- Fork the repository
- Create a feature branch
- Make changes following coding standards
- Add tests for new features
- Run full test suite
- Submit Pull Request
Code Review¶
- Be respectful and constructive
- Address all review comments
- Keep discussions focused on code
- Be patient during the review process
Resources¶
Internal Documentation¶
.github/instructions/README.md- Project instructions.github/instructions/core/- Core principles.github/instructions/languages/python/- Python standardsCLAUDE.md- Claude-specific instructions
External Resources¶
- Ruff Documentation
- pytest Documentation
- mkdocs Documentation
- Rich Documentation
- loguru Documentation
Need Help?¶
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Repository: https://github.com/neuraaak/ezplog