Skip to content

Contributing to py2max

Thank you for your interest in contributing to py2max! This document provides guidelines and instructions for contributing to the project.

Code of Conduct

  • Be respectful and inclusive in all interactions
  • Focus on constructive feedback
  • Help create a welcoming environment for all contributors

Getting Started

Development Setup

  1. Clone the repository:
git clone https://github.com/shakfu/py2max.git
cd py2max
  1. Install uv (if not already installed):
curl -LsSf https://astral.sh/uv/install.sh | sh
  1. Set up development environment:
uv sync
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
  1. Verify installation:
make test

Development Workflow

Before You Start

  1. Check existing issues to see if your feature/bug is already being worked on
  2. Open an issue to discuss major changes before implementing them
  3. Fork the repository and create a feature branch

Making Changes

  1. Create a feature branch:
git checkout -b feature/your-feature-name
  1. Make your changes following our coding standards (see below)

  2. Run quality checks:

make qa  # Lint, format, typecheck, and test
  1. Run tests:
make test  # Run all tests
make coverage  # Generate coverage report
  1. Commit your changes:
git add .
git commit -m "Add concise commit message"

Coding Standards

Code Style

  • Linter: We use ruff for linting
  • Auto-fix: Run make lint to automatically fix issues
  • Line length: Maximum 100 characters (configured in pyproject.toml)

Type Hints

  • Required: All function signatures must have type hints
  • Type checker: We use mypy for static type checking
  • Run: make typecheck or mypy py2max

Testing

  • Coverage requirement: Maintain > 80% test coverage (current: 82%)
  • Test framework: pytest
  • Test location: tests/ directory
  • Naming: Test files must start with test_

Writing Tests

"""tests/test_my_feature.py"""

from py2max import Patcher

def test_my_feature():
    """Test description."""
    p = Patcher('test.maxpat')
    # ... test code ...
    assert expected == actual

Running Tests

# Run all tests
make test

# Run specific test file
uv run pytest tests/test_my_feature.py

# Run with verbose output
uv run pytest -v

# Generate coverage report
make coverage

Documentation

  • Docstrings: All public classes, methods, and functions must have docstrings
  • Format: Google-style docstrings
  • Examples: Include usage examples in docstrings

Docstring Example

def add_textbox(self, text: str, maxclass: Optional[str] = None) -> Box:
    """Add a text-based Max object to the patch.

    Creates a Max object from a text specification (e.g., 'cycle~ 440').

    Args:
        text: Max object specification (e.g., 'cycle~ 440', 'gain~').
        maxclass: Override the automatically determined maxclass.

    Returns:
        The created Box object.

    Example:
        >>> p = Patcher('patch.maxpat')
        >>> osc = p.add_textbox('cycle~ 440')
        >>> gain = p.add_textbox('gain~')
        >>> p.add_line(osc, gain)
    """
    # ... implementation ...

Pull Request Process

Checklist

Before submitting a pull request, ensure:

  • [ ] Code follows project style guidelines
  • [ ] All tests pass (make test)
  • [ ] Type checking passes (make typecheck)
  • [ ] Linting passes (make lint)
  • [ ] Test coverage remains > 80% (make coverage)
  • [ ] Documentation is updated (if applicable)
  • [ ] CHANGELOG.md is updated (for user-facing changes)
  • [ ] Commit messages are clear and descriptive

Submitting

  1. Push your branch:
git push origin feature/your-feature-name
  1. Create a pull request on GitHub with:
  2. Clear title describing the change
  3. Description explaining:
    • What changed
    • Why it changed
    • How to test it
  4. Link to related issues

  5. Respond to feedback from reviewers

  6. Ensure CI passes - All GitHub Actions checks must pass

Commit Message Guidelines

Format

<type>: <subject>

<body>

<footer>

Types

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Code style changes (formatting, no logic change)
  • refactor: Code refactoring
  • test: Adding or updating tests
  • chore: Maintenance tasks

Examples

feat: add find_by_text method for searching boxes

Adds case-insensitive text search across all boxes in a patcher.
Includes comprehensive test coverage.

Closes #123
fix: resolve type error in db.py

Fixed incompatible types in db_path assignment by adding Union type.

Project Structure

py2max/
├── py2max/                    # Main package
│   ├── __init__.py            # Public API exports
│   ├── cli.py                 # Command-line interface
│   ├── exceptions.py          # Exception hierarchy
│   ├── log.py                 # Logging utilities
│   ├── utils.py               # Utility functions
│   ├── transformers.py        # Patch transformers
│   │
│   ├── core/                  # Core patcher functionality
│   │   ├── patcher.py         # Patcher class
│   │   ├── box.py             # Box class
│   │   ├── patchline.py       # Patchline class
│   │   ├── abstract.py        # Abstract base classes
│   │   └── common.py          # Rect class
│   │
│   ├── maxref/                # Max object reference system
│   │   ├── parser.py          # XML parsing
│   │   ├── db.py              # SQLite database
│   │   ├── category.py        # Object categorization
│   │   └── legacy.py          # MAXCLASS_DEFAULTS
│   │
│   ├── layout/                # Layout managers
│   │   ├── base.py            # LayoutManager base class
│   │   ├── grid.py            # GridLayoutManager
│   │   ├── flow.py            # FlowLayoutManager
│   │   └── matrix.py          # MatrixLayoutManager
│   │
│   ├── server/                # Interactive server & REPL
│   │   ├── websocket.py       # WebSocket server
│   │   ├── repl.py            # REPL core
│   │   ├── client.py          # REPL client
│   │   ├── inline.py          # Inline REPL
│   │   └── rpc.py             # RPC server
│   │
│   └── export/                # Export functionality
│       ├── svg.py             # SVG export
│       └── converters.py      # Format converters
├── tests/                     # Test suite
├── docs/                      # Documentation
├── .github/workflows/         # CI/CD configuration
├── Makefile                   # Development commands
└── pyproject.toml             # Project configuration

Common Tasks

Running Quality Checks

# Run all quality checks
make qa

# Individual checks
make lint          # Code linting with auto-fix
make typecheck     # Type checking

Building Documentation

# Build the MkDocs documentation
make docs

# Serve documentation locally with live reload
make docs-serve

# Deploy to GitHub Pages
make docs-deploy

Building Package

# Build wheel
make build

# Creates dist/py2max-*.whl

Getting Help

  • Issues: Open an issue on GitHub for bugs or feature requests
  • Discussions: Use GitHub Discussions for questions
  • Documentation: Check the docs directory

License

By contributing to py2max, you agree that your contributions will be licensed under the MIT License.

Recognition

Contributors will be recognized in:

  • CHANGELOG.md (for significant contributions)
  • GitHub contributors page
  • Project documentation (for major features)

Questions?

If you have questions about contributing, please:

  1. Check existing issues and documentation
  2. Open a GitHub Discussion
  3. Reach out to maintainers

Thank you for contributing to py2max!