Project
Contributing¶
Clear math, minimal API, no hacks. The full text lives in CONTRIBUTING.md; this page is the short version.
Dev setup¶
You need Python ≥ 3.12, a C compiler (see Install), and uv:
git clone https://github.com/El3ssar/TSDynamics.git
cd TSDynamics
uv sync --group dev # editable install + pytest, ruff, mypy, pre-commit
uv run pre-commit install # optional: style enforced at commit time
Quality gates¶
Run before pushing — CI rejects PRs that fail any of these:
uv run ruff check src/ tests/ # lint (zero errors)
uv run ruff format --check src/ tests/ # formatting (line length 100)
uv run pytest -m "not slow" --no-cov # fast suite, ~2 s — no C compilation
uv run pytest --no-cov # full suite, ~35 s — compiles + Lyapunov
Docstrings follow the NumPy convention; commits follow
Conventional Commits
(feat:, fix:, docs:, refactor:, test:, ci:).
Releases¶
PRs are squash-merged, and the PR title becomes the commit message —
so write PR titles as conventional commits too. Releases are automated
with python-semantic-release: feat: bumps minor, fix:/perf: bump
patch, BREAKING CHANGE:/! bumps major. The version is rewritten in
src/tsdynamics/__init__.py, tagged, published to PyPI, and the release
notes are generated — nothing to do by hand.
Adding a system, end to end¶
The whole pipeline is driven by the class definition:
- Write the class in the right module under
src/tsdynamics/systems/continuous/or.../discrete/, following the subclass contract for its family. Add the name to the module's__all__. - The registry picks it up automatically at import
(
registry.get("MyAttractor")now works, and the class is re-exported from the top level). - The test suite sweeps it — the bulk tests iterate the registry, so
your system gets smoke, signature, and Jacobian checks without writing
a test. Add literature Lyapunov values via
known_lyapunovto opt in to the known-value tests. - Its docs page auto-generates — equations rendered from the symbolic definition, defaults, and a figure, on the next docs build.
Optional metadata that improves everything downstream¶
class MyAttractor(ContinuousSystem):
params = {"a": 0.2, "b": 0.2, "c": 5.7}
dim = 3
variables = ("x", "y", "z") # named traj["x"] access + labelled figures
reference = "Rössler (1976), Phys. Lett. A 57, 397-398" # surfaced in the docs
default_ic = (1.0, 0.0, 0.0) # only if random ICs miss the basin
known_lyapunov = { # opt in to known-value tests
"spectrum": (0.0714, 0.0, -5.39),
"atol": (0.06, 0.06, 1.5),
"kwargs": {"dt": 0.1, "burn_in": 100.0, "final_time": 500.0},
"source": "Sprott (2003), Chaos and Time-Series Analysis",
}
Checklist for the PR
- Class follows the family contract (symbolic ops only for flows; positional param order for maps)
- Added to the module
__all__ -
variablesandreferencedeclared -
uv run pytest --no-covgreen locally - PR title is a conventional commit