Contributing¶
Quick Start¶
# 1. Fork and clone
git clone https://github.com/YOUR_USERNAME/quantsdk.git
cd quantsdk
# 2. Create a virtual environment
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
# 3. Install in development mode with all dev dependencies
pip install -e ".[dev,viz]"
# 4. Install pre-commit hooks
pre-commit install
# 5. Run tests
pytest
# 6. Check linting
ruff check src/ tests/
ruff format --check src/ tests/
Development Workflow¶
- Create an issue — Describe the feature or bug before starting work.
- Create a branch —
feature/QUANT-{issue_number}-short-descriptionorfix/QUANT-{issue_number}-short-description - Implement with tests — Every feature needs tests. Aim for 90%+ coverage.
- Open a Pull Request — Fill out the PR template. Link the issue.
- CI must pass — Lint, format, type check, and all tests must be green.
- Code review — At least one maintainer must approve.
Running Tests¶
# Run all tests
pytest
# Run with coverage
pytest --cov=quantsdk --cov-report=term-missing
# Run specific test file
pytest tests/test_circuit.py
# Run tests matching a pattern
pytest -k "test_bell"
# Skip slow/integration tests
pytest -m "not slow and not integration"
# Run only fast unit tests
pytest -m "not slow and not integration" -x
Code Quality¶
We use ruff for linting and formatting:
# Lint
ruff check src/ tests/
# Auto-fix lint issues
ruff check src/ tests/ --fix
# Format
ruff format src/ tests/
# Type checking
mypy src/quantsdk/ --ignore-missing-imports
Code Style¶
- Python 3.10+ — Use modern Python features (type hints,
match,|for unions). - Docstrings — Google style. Every public function/class needs a docstring.
- Type hints — All public APIs must have type annotations.
- Frozen dataclasses — Gates are immutable (
@dataclass(frozen=True)). - Fluent API — Circuit methods return
selffor chaining. - Line length — 100 characters max.
Project Structure¶
src/quantsdk/
__init__.py # Public API surface (Circuit, Result, run)
circuit.py # Circuit class with fluent gate methods (44+ gates)
gates.py # 44 gate classes, 54 GATE_MAP entries
result.py # Result dataclass (counts, probabilities, viz)
runner.py # qs.run() top-level API with backend routing
backend.py # Abstract Backend interface
simulators/
local.py # Pure NumPy statevector simulator (up to 24 qubits)
interop/
qiskit_interop.py # Qiskit <-> QuantSDK conversion
openqasm.py # OpenQASM 2.0 <-> QuantSDK conversion
backends/
ibm.py # IBM Quantum + Aer backend adapters
tests/
test_circuit.py # Circuit class tests
test_gates.py # Gate definition tests
test_simulator.py # Local simulator tests
test_qiskit_interop.py # Qiskit interop tests
test_openqasm.py # OpenQASM interop tests
test_aer_backend.py # Aer backend tests
test_api_surface.py # Public API surface tests
test_expanded_gates.py # Extended gate library tests
examples/ # 22 Jupyter notebooks
docs/ # MkDocs Material documentation
Adding a New Gate¶
- Add the gate class to
src/quantsdk/gates.pyas a frozen dataclass with a.matrix()method. - Add it to
GATE_MAPin the same file (can have aliases, e.g.,"toffoli"->CCX). - Add a convenience method to
Circuitinsrc/quantsdk/circuit.pythat returnsself. - Add Qiskit mapping in
src/quantsdk/interop/qiskit_interop.py(_QS_TO_QISKIT_MAPand_qiskit_gate_to_qs). - Add OpenQASM mapping in
src/quantsdk/interop/openqasm.py(_GATE_TO_QASMand_QASM_GATE_MAP). - Write tests in
tests/test_expanded_gates.py(matrix shape, unitarity, known values). - Update the gate table in
docs/api/gates.md.
Example gate class:
@dataclass(frozen=True)
class MyGate(Gate):
"""My custom gate."""
qubit: int
@property
def qubits(self) -> tuple[int, ...]:
return (self.qubit,)
@property
def name(self) -> str:
return "MyGate"
def matrix(self) -> np.ndarray:
return np.array([[1, 0], [0, 1]], dtype=complex)
Adding a New Backend¶
- Create a new file in
src/quantsdk/backends/(e.g.,ionq.py). - Implement the
BackendABC fromsrc/quantsdk/backend.py. - Implement
run(circuit, shots, **options)andinfo()methods. - Add backend alias resolution in
src/quantsdk/runner.py(_BACKEND_ALIASES). - Write tests (use simulators or mocks for CI — real hardware tests go in
tests/integration/). - Add docs page in
docs/backends/.
Commit Messages¶
We follow Conventional Commits:
feat: add IonQ backend adapter
fix: correct CZ gate matrix phase
docs: add tutorial for quantum teleportation
test: add roundtrip tests for OpenQASM
refactor: simplify gate dispatch in runner
perf: optimize statevector contraction for 2-qubit gates
chore: update ruff to v0.5.0
ci: add Python 3.13 to test matrix
Scope prefixes are optional but encouraged:
feat(gates): add RZX Ising coupling gate
fix(simulator): handle Reset gate for multi-qubit states
docs(api): update Circuit class docstrings
Reporting Bugs¶
Please include:
- QuantSDK version:
python -c "import quantsdk; print(quantsdk.__version__)" - Python version:
python --version - OS and architecture
- Minimal reproducible example
- Full error traceback
Suggesting Features¶
Open a GitHub issue with:
- Problem — What pain point does this solve?
- Proposed Solution — How should it work? (API sketch)
- Alternatives — What other approaches did you consider?
- Context — Any references, papers, or existing implementations?
Pull Request Guidelines¶
- Keep PRs focused — one feature or fix per PR.
- Update tests and docs alongside code changes.
- Ensure all CI checks pass before requesting review.
- Add a changelog entry in the PR description.
- Be responsive to review feedback.
Security¶
If you discover a security vulnerability, please do not open a public issue. Instead, see SECURITY.md for responsible disclosure instructions.
Community¶
- GitHub Issues — Bug reports and feature requests
- GitHub Discussions — Questions and general discussion
- Discord — Real-time chat with the team and community
License¶
By contributing, you agree that your contributions will be licensed under the Apache License 2.0.