Contributingο
Thank you for your interest in contributing to WindMouse! This document provides guidelines and instructions for contributing to the project.
We welcome contributions of all kinds:
π Bug reports and fixes
β¨ New features and enhancements
π Documentation improvements
π§ͺ Tests and test coverage improvements
π‘ Ideas and suggestions
Getting Startedο
Development Setupο
Fork and Clone
Fork the repository on GitHub and clone your fork:
git clone https://github.com/YOUR_AsfhtgkDavid/windmouse.git cd windmouse
Install Dependencies
Using pip:
pip install -e .[all,dev,docs]
Or using uv (recommended):
uv sync --all-groups
Verify Installation
Run a quick test to ensure everything is working:
python -c "from windmouse.pyautogui_controller import PyautoguiMouseController; print('Success!')"
Code Styleο
WindMouse follows strict code quality standards to maintain consistency and readability.
Formattingο
We use Black for code formatting with a line length of 79 characters:
# Format your code before committing
black src/
Black configuration is in pyproject.toml:
[tool.black]
line-length = 79
Type Checkingο
We use mypy with strict mode enabled. All code must pass type checking:
# Run type checker
mypy src/
Mypy configuration is in pyproject.toml:
[tool.mypy]
strict = true
Key type checking requirements:
All function parameters must have type hints
All return types must be annotated
No
Anytypes without explicit justificationUse
Optional[T]for nullable valuesUse
NewTypefor semantic type safety (likeCoordinate)
Code Guidelinesο
Follow these guidelines when writing code:
Docstrings: Use Google or NumPy style docstrings for all public APIs:
def example_function(param1: int, param2: str) -> bool: """ Brief description of the function. Args: param1: Description of param1. param2: Description of param2. Returns: Description of return value. Raises: ValueError: When invalid input is provided. """ pass
Import Order: Follow standard Python import conventions:
# Standard library import enum import time from abc import ABC, abstractmethod # Third-party import numpy as np # Local from .core import Coordinate
Naming Conventions:
Classes:
PascalCase(e.g.,PyautoguiMouseController)Functions/methods:
snake_case(e.g.,move_to_target)Constants:
UPPER_SNAKE_CASE(e.g.,GRAVITY_MAGNITUDE_DEFAULT)Private methods:
_leading_underscore(e.g.,_get_next_point)
Abstract Methods: Use
@abstractmethoddecorator for interface definitionsType Safety: Prefer
NewTypefor semantic clarity (likeCoordinate)
Making Changesο
Branch Namingο
Use descriptive branch names with prefixes:
feature/- New features (e.g.,feature/add-bezier-mode)fix/- Bug fixes (e.g.,fix/velocity-clamp-issue)docs/- Documentation (e.g.,docs/improve-api-reference)refactor/- Code refactoring (e.g.,refactor/simplify-tick-logic)test/- Test additions/improvements (e.g.,test/add-ahk-tests)
Commit Messagesο
Write clear, descriptive commit messages using conventional commits format:
<type>: <short description>
<optional longer description>
<optional footer>
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Formatting, missing semicolons, etc.refactor: Code restructuring without behavior changetest: Adding or updating testschore: Maintenance tasks
Examples:
feat: Add support for circular mouse paths
Implements a new CircularPathController that moves the mouse
in circular trajectories instead of WindMouse paths.
fix: Correct velocity clamping calculation
The max_step parameter was not being applied correctly in
close-range scenarios. This fixes the clamping logic.
docs: Add troubleshooting section for Linux permissions
Testingο
Running Testsο
Before submitting a pull request, ensure all tests pass:
# Run all tests
pytest
# Run with coverage
pytest --cov=src --cov-report=html
# Run specific test file
pytest tests/test_core.py
Writing Testsο
When adding new features, include appropriate tests:
import pytest
from windmouse.core import wind_mouse, Coordinate
def test_wind_mouse_convergence():
"""Test that wind_mouse reaches the target."""
start_x, start_y = Coordinate(0), Coordinate(0)
dest_x, dest_y = Coordinate(100), Coordinate(100)
path = list(wind_mouse(start_x, start_y, dest_x, dest_y))
# Check that we have a path
assert len(path) > 0
# Check that final position is close to target
final_x, final_y = path[-1]
assert abs(final_x - dest_x) <= 1
assert abs(final_y - dest_y) <= 1
Test guidelines:
Test both success and failure cases
Use descriptive test names
Include docstrings explaining what the test verifies
Mock external dependencies (like
pyautoguiorahk)Aim for high code coverage (target: >80%)
Documentationο
Building Documentationο
Build the documentation locally to preview changes:
cd docs
make html
# View in browser
open _build/html/index.html # macOS
xdg-open _build/html/index.html # Linux
start _build/html/index.html # Windows
Or use Sphinx directly:
sphinx-build -b html docs docs/_build/html
Documentation Guidelinesο
When updating documentation:
Use reStructuredText (.rst) format for all documentation files
Include code examples that are tested and working
Cross-reference related sections using
:doc:directivesUpdate API documentation if you change function signatures
Add new pages to the
toctreeinindex.rst
Example of good documentation:
Advanced Usage
==============
This section covers advanced usage patterns.
Custom Physics
--------------
You can customize the physics parameters:
.. code-block:: python
from windmouse.pyautogui_controller import PyautoguiMouseController
mouse = PyautoguiMouseController(
gravity_magnitude=12,
wind_magnitude=5
)
See :doc:`algorithm` for details on parameter effects.
Pull Request Processο
Create a Feature Branch
git checkout -b feature/your-feature-name
Make Your Changes
Write code following the style guidelines
Add tests for new functionality
Update documentation as needed
Format and Check
# Format code black src/ # Type check mypy src/ # Run tests pytest
Commit Your Changes
git add . git commit -m "feat: Add your feature description"
Push to Your Fork
git push origin feature/your-feature-name
Open a Pull Request
Go to the original repository on GitHub
Click βNew Pull Requestβ
Select your fork and branch
Fill out the PR template with:
Description of changes
Motivation and context
Testing performed
Screenshots (if applicable)
Respond to Review
Address reviewer feedback promptly
Make requested changes
Push updates to the same branch
Pull Request Checklistο
Before submitting, ensure:
[ ] Code follows style guidelines (Black, mypy)
[ ] All tests pass
[ ] New features have tests
[ ] Documentation is updated
[ ] Commit messages are clear and descriptive
[ ] PR description explains the changes
[ ] No unnecessary files are included
[ ] Branch is up to date with main
Reporting Issuesο
Bug Reportsο
When reporting a bug, include:
Clear Title: Descriptive summary of the issue
Environment:
Python version
Operating system
WindMouse version
Backend (PyAutoGUI or AHK)
Steps to Reproduce: Minimal code example
Expected Behavior: What you expected to happen
Actual Behavior: What actually happened
Screenshots/Logs: If applicable
Example bug report:
Title: ValueError when using None as start_position
**Environment:**
- Python 3.11
- Windows 11
- WindMouse 1.0.0
- PyAutoGUI backend
**Steps to Reproduce:**
```python
from windmouse.pyautogui_controller import PyautoguiMouseController
from windmouse import Coordinate
mouse = PyautoguiMouseController()
mouse.start_position = (None, Coordinate(100))
mouse.dest_position = (Coordinate(500), Coordinate(500))
mouse.move_to_target()
```
**Expected:** Should use current x position
**Actual:** Raises ValueError
**Traceback:**
```
ValueError: start_x cannot be None when start_y is set
```
Feature Requestsο
When requesting a feature:
Describe the feature clearly
Explain the use case - why is it needed?
Provide examples - how would it be used?
Consider alternatives - are there existing solutions?
Community Guidelinesο
Code of Conductο
This project adheres to a Code of Conduct. By participating, you agree to:
Be respectful and inclusive
Welcome newcomers
Accept constructive criticism gracefully
Focus on whatβs best for the community
Show empathy towards others
Communicationο
GitHub Issues: For bugs, features, and questions
Pull Requests: For code contributions
Discussions: For general questions and ideas
Recognitionο
Contributors will be:
Listed in the projectβs contributors list
Credited in release notes for significant contributions
Thanked in documentation and README
Development Tipsο
Debuggingο
Use the manual tick system for debugging:
mouse = PyautoguiMouseController()
mouse.dest_position = (Coordinate(800), Coordinate(600))
step = 0
while mouse.tick(step_duration=0.1):
step += 1
print(f"Step {step}: Current position")
time.sleep(0.1)
Testing Locallyο
Test with different parameters:
test_configs = [
{"gravity_magnitude": 5, "wind_magnitude": 8},
{"gravity_magnitude": 12, "wind_magnitude": 1},
{"max_step": 5, "damped_distance": 30},
]
for config in test_configs:
mouse = PyautoguiMouseController(**config)
mouse.dest_position = (Coordinate(500), Coordinate(500))
mouse.move_to_target()
Virtual Environmentο
Always use a virtual environment:
# Create venv
python -m venv venv
# Activate
source venv/bin/activate # Linux/macOS
venv\\Scripts\\activate # Windows
# Install in development mode
pip install -e .[all,dev,docs]
Questions?ο
If you have questions about contributing:
Check existing issues and discussions
Review this contributing guide
Ask in a GitHub discussion
Open an issue with the βquestionβ label
Thank you for contributing to WindMouse! π
See Alsoο
Installation - Setup instructions
Usage Guide - Usage examples
API Reference - API reference