Contributing
Prerequisites
- Python 3.12+
uv(preferred) or plainpip- ROS2 Jazzy or later — optional; only needed for the
osm_cloudnode
Getting the code
Setting up the development environment
Install the package in editable mode together with the documentation and tooling dependencies:
Use uv pip, not plain pip
The project uses uv for package management. Plain pip may install into the wrong interpreter on machines with multiple Python environments.
Running the tests
All tests are standalone — no ROS2 context or network access is required. See the Testing page for a full breakdown of test files, design principles, and guidance on adding new tests.
Running the docs locally
The site is served at http://127.0.0.1:8000 with live reload.
To build a static copy:
Code style
The project uses Ruff for both formatting and linting. Configuration lives in pyproject.toml.
Before submitting a pull request, run:
Key style rules enforced:
- Line length — 100 characters.
- Import order — isort-compatible,
map_datais treated as first-party. - Type annotations — modern PEP 585/604 style (
list[str],X | None). Add return annotations to all new functions; parameter annotations are required for public API methods. - Docstrings — public methods use NumPy-style docstrings (matches the
mkdocstringsconfiguration). Internal helpers can omit docstrings when the name is self-explanatory. - Comments — only add a comment when the why is non-obvious. Do not annotate what the code does.
Editor integration
If you use Neovim with LazyVim, enable the lazyvim.plugins.extras.lang.python extra and add a conform.nvim plugin spec with ruff_format to get format-on-save automatically.
Type checking
The project uses mypy for static type checking. Configuration lives in pyproject.toml under [tool.mypy].
Third-party libraries without complete type stubs (numpy, shapely, overpy, flask_socketio, rclpy, etc.) are covered by ignore_missing_imports. A small number of remaining false positives — mostly from numpy/shapely returning loosely-typed values, or from patterns mypy can't narrow (e.g. Flask's nonlocal-captured variables) — are silenced with targeted # type: ignore[<code>] comments that include a short reason. New code should be fully typed rather than relying on ignores.
Submitting changes
- Create a feature branch from
master. - Make your changes and add or update tests where relevant.
- Run
pytest tests/and ensure all tests pass. - Run
ruff check . && ruff format --check .andmypy map_data/and ensure both are clean. - Open a pull request against
masterwith a clear description of what changed and why.