Contributing#
Development#
This package is in active development and welcomes contributions!
Feel free to bring up any questions/comments on the Zulip chat or open an issue.
All feedback is welcome and encouraged, it’s great to hear about anything that works well or could be improved.
Getting Started#
To get started locally developing with this project, fork it and clone it to your local machine.
Using the Github CLI this would be:
brew install gh
gh repo fork egraphs-good/egglog-python --clone
cd egglog-python
Then install Rust and get a Python environment set up with a compatible version. Using uv this would be:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
curl -LsSf https://astral.sh/uv/install.sh | sh
Then install the package in editable mode with the development dependencies:
uv sync --all-extras
Anytime you change the rust code, you can run uv sync --reinstall-package egglog --all-extras to force recompiling the rust code.
If you would like to download a new version of the visualizer source, run make clean; make. This will download
the most recent released version from the github actions artifact in the egraph-visualizer repo. It is checked in because it’s a pain to get cargo to include only one git ignored file while ignoring the rest of the files that were ignored.
Running Tests#
To run the tests, you can use the pytest command:
uv run pytest
All code must pass ruff linters and formaters. This will be checked automatically by the pre-commit if you run pre-commit install.
To run it manually, you can use:
uv run pre-commit run --all-files ruff
If you make changes to the rust bindings, you can check that the stub files accurately reflect the rust code by running:
make stubtest
All code must all pass MyPy type checking. To run that locally use:
make mypy
Finally, to build the docs locally and test that they work, you can run:
make docs
Debugging#
To debug the Rust parts of this project, follow the PyO3 debugging guide. Debug symbols are turned on by default.
Performance#
py-spy is installed as a development dependency and can be used to profile Python code.
If there is a performance sensitive piece of code, you could isolate it in a file and profile it locally with:
uv run py-spy record --format speedscope -- python -O tmp.py
Tracing#
pytest can also configure OpenTelemetry tracing for local debugging. For the full host-application setup and the
Jaeger startup command, see Tracing. The pytest plugin configures both the Python tracer
provider and egglog.bindings.setup_tracing(...) for you.
To print both Python and Rust spans to the console during a test run:
uv run pytest python/tests/test_tracing.py --benchmark-disable -q -s --otel-traces=console
Console mode is intentionally verbose. It works best for short runs or a single targeted test.
For a targeted test, pass the same flag to the test you are debugging:
uv run pytest python/tests/test_array_api.py::test_jit[lda] -vv --benchmark-disable -s --otel-traces=console
To send spans to Jaeger over OTLP/HTTP, start Jaeger as shown in Tracing, then run pytest with the Jaeger tracing mode:
uv run pytest python/tests/test_array_api.py::test_jit[lda] -vv --benchmark-disable --otel-traces=jaeger
Then open http://localhost:16686.
For a longer-running or performance-sensitive test, prefer --otel-traces=jaeger over console mode.
If you need a non-default OTLP endpoint, add --otel-otlp-endpoint=http://host:4318/v1/traces.
Making changes#
All changes that impact users should be documented in the docs/changelog.md file. Please also add tests for any new features
or bug fixes.
When you are ready to submit your changes, please open a pull request. The CI will run the tests and check the code style.
Changelog Automation#
When you open a pull request, a GitHub Action automatically adds an entry to the UNRELEASED section of the changelog using your PR title and number. This ensures the changelog stays up-to-date without manual intervention.
Documentation#
We use the Diátaxis framework to organize our documentation. The “explanation” section has been renamed to “Blog” since most of the content there is more like a blog post than a reference manual. It uses the ABlog extension.
Governance#
The governance is currently informal, with Saul Shanabrook as the lead maintainer. If the project grows and there are more contributors, we will formalize the governance structure in a way to allow it to be multi-stakeholder and to spread out the power and responsibility.