Bumps the Python binding from pyo3 0.22 / numpy 0.22 to 0.28 / 0.28,
which resolves RUSTSEC-2025-0020 — a buffer overflow in
`PyString::from_object` that affected every published Python wheel.
Migration:
- `into_pyarray_bound(py)` → `into_pyarray(py)` (numpy 0.23 dropped the
`_bound` transitional suffix; the method now returns `Bound<'py, _>`
directly).
- `downcast::<PyDict>` → `cast::<PyDict>` (pyo3 renamed the method on
`PyAnyMethods`).
- Every `#[pyclass]` declares `skip_from_py_object` to opt out of the
now-deprecated automatic `FromPyObject` derive for `Clone` types.
Indicators are stateful — silently extracting them by value-clone is
never the intended FFI semantics.
- Workspace clippy gains `unused_self = "allow"` on the python crate
only: Python's `__repr__` protocol forces `&self` even for parameter-
less indicators where the body does not read state.
- `map_err` arms collapsed into a single `PyValueError` arm
(clippy::match_same_arms).
`deny.toml` no longer suppresses RUSTSEC-2025-0020; `cargo deny check`
is green on advisories, bans, licenses and sources without exceptions.
The repository had no supply-chain auditing — no deny.toml and no CI
job to catch vulnerable, unmaintained, wrongly-licensed, or
unexpectedly-sourced dependencies.
Add deny.toml covering advisories, bans, licenses and sources:
- licenses: an allow-list of the permissive licenses the dependency
tree actually uses, plus the workspace's own PolyForm-Noncommercial
license and a scoped LLVM-exception for target-lexicon.
- bans: warn on duplicate versions, deny external wildcard deps
(internal path deps are allowed).
- sources: only crates.io.
- advisories: RUSTSEC-2025-0020 (pyo3 0.22) is ignored with a documented
reason — it is reachable only through bindings/python and the pyo3
upgrade is tracked separately; the published crates do not use pyo3.
Add a `supply-chain` CI job running cargo-deny-action (SHA-pinned).
`cargo deny check` passes locally: advisories/bans/licenses/sources ok.