Contributing¶
Contributing to UnitFlow¶
Thank you for your interest in contributing to UnitFlow. This document covers the expectations and practices for contributing to the project.
Code of Conduct¶
Be respectful, constructive, and professional. Engineering is a collaborative discipline and this project reflects that.
Getting Started¶
Fork the repository and clone your fork.
Install development dependencies:
uv sync
Run the test suite to confirm your environment is working:
uv run pytest tests/ -v
Create a feature branch from
main:
git checkout -b feature/your-feature-name
Development Expectations¶
Code Quality¶
Follow existing code style and conventions. The codebase uses type annotations throughout.
Keep functions focused. Each function should do one thing.
Prefer immutable data structures where possible.
Do not introduce new dependencies without discussion.
NumPy remains an optional dependency. The semantic core must import and run without it.
Testing¶
All new functionality must include tests.
Unit tests go in
tests/unit/under the appropriate subpackage.Integration tests go in
tests/integration/.System-level examples go in
tests/system/.Run the full suite before submitting:
uv run pytest tests/ -v
Tests should be written in pytest style (plain functions, not unittest classes).
Use descriptive test names that explain what behavior is being verified.
Commits¶
Write clear, concise commit messages.
Each commit should represent a single logical change.
Do not bundle unrelated changes in one commit.
Pull Requests¶
Keep pull requests focused on a single concern.
Describe what your PR does and why.
Reference any related issues.
Ensure all tests pass before requesting review.
Be prepared to respond to feedback and iterate.
Architecture Guidelines¶
UnitFlow is built in clean layers with strict dependency rules:
coreowns the semantic model (dimensions, scales, units, quantities).exprowns symbolic expressions and constraints.defineowns extensibility primitives (unit definitions, namespaces, registries, prefix generation).catalogsships curated unit packs.serializationhandles structural serialization for all core objects.backendscontains optional integration layers (e.g. NumPy).
Dependencies flow downward only:
Dimensionmust not depend onUnit.Unitmay depend onDimension.Quantitymay depend onUnit.ExprandConstraintmay depend onQuantity,Unit, andDimension.Catalogs may depend on the semantic core but not on expression or backend layers.
Backends depend on the semantic core, not the other way around.
If your contribution changes the dependency direction between layers, it will not be accepted without a thorough design discussion first.
Adding New Units¶
To add new units to an existing catalog:
Define the unit using
define_unit()with keyword arguments.Use exact
intorFractionmagnitudes. Do not usefloatin unit definitions.Register the unit in the appropriate namespace.
Add tests verifying the unit’s semantic correctness and conversion factors.
To add SI prefix variants, use generate_prefixes() rather than hand-coding each one.
Adding New Catalogs¶
New domain catalogs (e.g. electrical, thermal, fluids) are welcome. Each catalog should:
Live in
unitflow/catalogs/as a separate module.Define a
UnitNamespacefor the domain.Use only exact definitions.
Include tests in
tests/unit/catalogs/.Be re-exported through
unitflow/catalogs/__init__.py.
Reporting Issues¶
When reporting a bug:
Include a minimal reproducible example.
State what you expected to happen and what actually happened.
Include the Python version and UnitFlow version.
When requesting a feature:
Describe the use case, not just the desired API.
Explain which engineering domain or workflow would benefit.
License¶
By contributing to UnitFlow, you agree that your contributions will be licensed under the Apache 2.0 License.
If the include path fails in your build environment, open CONTRIBUTING.md at the repository root.