pyBmodes 1.9.0
Security, release-integrity, and documentation hardening on top of 1.8.1. No numerical change; the only public-API change is one new opt-in keyword.
Security
- Legacy NPZ pickle loading is refused by default.
ModalResult.load/CampbellResult.loadraise on a legacy pre-1.0 pickled-object__meta__(object-array unpickling can execute arbitrary code;SECURITY.mdscopes NPZ deserialisation). Opt in for a trusted file withallow_legacy_pickle=True(still warns). Modern archives are pickle-free and unaffected.
Changed
- PyPI publishing is gated on external validation. A tag publishes only if the Validation (external data) workflow has a green run on that exact commit.
- Validation cloning is manifest-driven and
--strict-checks every required clone (r-test + IEA-3.4/10/15/22 + WISDEM); content hashes are line-ending-normalized for cross-platform reproducibility; the validation job pins BLAS threads so the integration suite is deterministic. - Source-quality ratchet: Ruff expanded to
UP/B/C4/SIM/PIE/RUF; mypy floor raised and the strict-typed surface grown from 10 to 29 modules.
Fixed
Tower.from_windio_floatinghonours a caller-suppliedrna_tipin the screening tier (no companion deck / no injected platform) instead of zeroing it (#83).- Citation-grade references — every reference in
VALIDATION.mdanddocs/theory.rstnow carries a DOI, an NREL PDF, or an OSTI link (textbooks marked "no DOI"). - Docs: corrected install guidance (pybmodes is on PyPI), reference-turbine sample count seven → eleven, validation-coverage wording (CI-gated public set vs maintainer-local BModes), and assorted metadata.
See CHANGELOG.md for the full [1.9.0] entry.
Install: pip install pybmodes==1.9.0