Skip to content

Release v0.8.0: Agent Property Setters and API Improvements

Latest

Choose a tag to compare

@Routhleck Routhleck released this 05 Jun 04:57

Release v0.8.0: Agent Property Setters and API Improvements

What's New

✨ Pythonic property assignment for Agent.pos and Agent.velocity

  • agent.pos = [...] and agent.velocity = [...] now work via PyO3 setters
  • Boundary projection, history sync, and head-direction normalization are preserved
  • Subtle consistency bug fixed: rotational velocity baseline is now kept in lock-step

🗺️ Top-level re-exports

  • from canns_lib import Agent, Environment no longer requires the spatial submodule

🔧 Deprecations of the legacy set_* methods

  • Agent.set_positionagent.pos = ...
  • Agent.set_velocityagent.velocity = ...
  • Agent.set_forced_next_positionagent.update(forced_next_position=...)

Major Features / Key Changes

Property Setters for Agent State (PR #3)

  • agent.pos = [...]: PyO3 setter delegates to the existing set_position logic, so boundary projection and history patching still apply.
  • agent.velocity = [...]: PyO3 setter delegates to the existing set_velocity logic, including head-direction normalization and history patching.
  • position alias stays read-only on purpose: allowing external writes would let callers bypass the projection in set_position.
  • Rotational baseline fix: set_velocity now also updates prev_measured_velocity, so the first update() after a velocity assignment does not record a bogus angular sample.
from canns_lib import Agent, Environment

env = Environment()
a = Agent(env, rng_seed=0)
a.update(dt=0.05)
a.pos = [0.3, 0.7]        # was: a.set_position([0.3, 0.7])
a.velocity = [0.0, 0.1]   # was: a.set_velocity([0.0, 0.1])

🗺️ Top-Level Re-exports (PR #3)

  • canns_lib.Agent and canns_lib.Environment are now the canonical way to import; the spatial submodule is still importable for backward compatibility.
  • canns_lib.__version__ now comes from importlib.metadata (the python/canns_lib/_version.py shadow has been removed).

🔧 Deprecations (PR #3)

  • Agent.set_position / Agent.set_velocity / Agent.set_forced_next_position all emit a DeprecationWarning and remain functional for one release cycle. The Rust pymethods are kept for source compatibility.
  • The Python @property setters on the wrapper class route through the real Rust set_position / set_velocity, so property assignment does not silently shadow the Rust getter via __getattr__.

🔧 Build & Test Fixes (PR #2, PR #3)

  • cargo test --release works out of the box on macOS/Linux. The PyO3 extension-module feature is now an optional Cargo feature; maturin enables it via [tool.maturin] features (PyO3 FAQ Option 1).
  • Fixed a ZeroDivisionError in tests/test_complex_topology.py (#2).

🚀 Performance Polish (PR #3)

  • apply_set_velocity now uses Vec::clone_from to avoid two redundant heap allocations on every call.

🧹 Cleanup (PR #3)

  • Removed 2,717-line dead file src/ripser/ripser_old.rs.
  • Removed 8 unused Cargo dependencies (sprs, indexmap, typed-arena, num-traits, thiserror, dev-approx, dev-criterion, dev-rand).
  • Removed python/canns_lib/_version.py; canns_lib.__version__ is read from installed package metadata.
  • Trimmed _ripser_core / _spatial_core from __all__ (still importable).
  • Fixed broken imports in example/try.py (it pointed at a non-existent canns_ripser package and unconditionally required the upstream ripser).

📖 Documentation (PR #3)

  • Shipped docs/SPATIAL_NAV_MODULE_DESIGN.md (no longer gitignored).
  • Updated module layout in the design doc to match the actual agent.rs / environment.rs / geometry.rs / state.rs / utils.rs files.
  • CLAUDE.md documents the new cargo test behavior and the extension-module feature flag.

Breaking Changes

None. All deprecations are soft — existing code continues to work, but the legacy set_* methods emit a DeprecationWarning. The PyO3 extension-module feature is now opt-in, which only affects callers who build the crate as a Rust library (none expected — it ships as a cdylib).

Technical Notes

  • Property setters in Rust use the PyO3 #[setter] macro, which requires the method name to follow the set_<field> pattern (set_pos, set_velocity). The original pub fn set_velocity is preserved as set_velocity_method with #[pyo3(name = "set_velocity")] so the Python API is unchanged.
  • The extension-module Cargo feature is added to the [features] table and gated by maturin; the PyO3 FAQ documents this as the recommended workaround for the __Py_TrueStruct linker error on macOS/Linux.

Full Changelog: v0.7.0...v0.8.0