Thank you for considering contributing to pycd48! This document provides guidelines and instructions for contributing.
- Code of Conduct
- Getting Started
- Development Setup
- Making Changes
- Testing
- Code Style
- Submitting Changes
- Reporting Bugs
- Suggesting Enhancements
This project adheres to a code of conduct that all contributors are expected to follow. Please be respectful and constructive in all interactions.
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR-USERNAME/pycd48.git cd pycd48 - Add the upstream repository:
git remote add upstream https://github.com/OpenPhysics/pycd48.git
- Python 3.12 or higher (3.13 recommended for development)
- uv (recommended) or pip
Using uv (recommended):
# Install all dependencies including dev tools
uv sync --extra dev
# Run commands with uv
uv run pytest
uv run black pycd48/ tests/Using pip:
# Create a virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install package in editable mode with dev dependencies
pip install -e ".[dev]"-
Create a new branch for your feature or bugfix:
git checkout -b feature/your-feature-name
-
Make your changes following the code style guidelines
-
Add or update tests as needed
-
Update documentation if you're changing functionality
We use pytest for testing. All new features should include tests.
# Run all tests
pytest
# Run with coverage
pytest --cov=pycd48 --cov-report=html
# Run specific test file
pytest tests/test_cd48.py
# Run specific test
pytest tests/test_cd48.py::TestCD48::test_set_channel- Place tests in the
tests/directory - Name test files with
test_prefix - Use descriptive test names that explain what is being tested
- Mock hardware dependencies (serial port) in unit tests
- Include both positive and negative test cases
Example:
def test_set_trigger_level_valid_range(self):
"""Test that valid voltage range works correctly."""
cd48.set_trigger_level(2.0)
# Assert expected behavior
def test_set_trigger_level_out_of_range(self):
"""Test that out-of-range voltages are clamped."""
cd48.set_trigger_level(10.0)
# Assert voltage was clamped to maximumWe follow PEP 8 with some modifications:
- Maximum line length: 100 characters
- Use Black for code formatting
- Use ruff for linting
- Use type hints where possible
Before committing, format your code:
# Format code
uv run black pycd48/ tests/
# Check linting
uv run ruff check pycd48/ tests/
# Type checking
uv run mypy pycd48/ --ignore-missing-imports- Use docstrings for all public functions, classes, and modules
- Follow Google-style docstrings
- Include parameter types, return types, and examples where helpful
Example:
def set_trigger_level(self, voltage: float) -> str:
"""
Set trigger level voltage.
Parameters:
-----------
voltage : float
Voltage threshold (0.0 to 4.08V)
Returns:
--------
str
Device response
Example:
--------
>>> cd48.set_trigger_level(0.5)
'OK'
"""Write clear, descriptive commit messages:
Short (50 chars or less) summary
More detailed explanatory text, if necessary. Wrap it to
about 72 characters. The blank line separating the summary
from the body is critical.
- Bullet points are okay
- Use imperative mood ("Add feature" not "Added feature")
- Reference issues and PRs: "Fixes #123", "See #456"
-
Update your branch with the latest upstream changes:
git fetch upstream git rebase upstream/main
-
Push your changes to your fork:
git push origin feature/your-feature-name
-
Create a pull request on GitHub
-
Ensure all CI checks pass
-
Wait for review and address any feedback
- Include a clear description of the changes
- Reference any related issues
- Add tests for new features
- Update documentation as needed
- Keep PRs focused - one feature/fix per PR
- Ensure CI passes before requesting review
- Check if the bug has already been reported in Issues
- Try to reproduce the bug with the latest version
- Collect information about your environment (OS, Python version, etc.)
Create an issue with:
- Clear title describing the bug
- Steps to reproduce the problem
- Expected behavior
- Actual behavior
- Environment details (OS, Python version, library version)
- Code samples if applicable
- Error messages or logs
Example:
## Bug: Device auto-detection fails on Windows
**Environment:**
- OS: Windows 11
- Python: 3.13.7
- pycd48: 0.1.0
**Steps to Reproduce:**
1. Connect CD48 to USB
2. Run `CD48()` without specifying port
3. Error occurs
**Expected:** Device should be auto-detected
**Actual:** ValueError raised
**Error message:**ValueError: Could not find CD48
**Workaround:** Specify port manually: `CD48(port='COM3')`
We welcome suggestions for new features or improvements!
- Check if the enhancement has already been suggested
- Consider if it fits the project scope
- Think about how it would benefit other users
Create an issue with:
- Clear title describing the enhancement
- Use case - why is this needed?
- Proposed solution - how should it work?
- Alternatives considered
- Additional context - examples, mockups, etc.
- Pick an issue or create one for your planned work
- Create a branch from
main - Make changes following style guidelines
- Write tests for new functionality
- Run tests locally
- Update docs if needed
- Commit changes with clear messages
- Push to your fork
- Create PR and wait for review
- Address feedback if any
- Merge after approval
feature/- New featuresbugfix/- Bug fixesdocs/- Documentation updatestest/- Test improvementsrefactor/- Code refactoring
Examples:
feature/add-voltage-sweepbugfix/fix-overflow-detectiondocs/update-readme
If you have questions about contributing:
- Check existing documentation
- Look at closed issues/PRs for similar questions
- Open a discussion on GitHub
- Contact maintainers
Thank you for contributing to pycd48! 🎉