From d5e73e086ce63103f3e1a6eba46e7b7a38737c42 Mon Sep 17 00:00:00 2001 From: swf1996120 <1247155045@qq.com> Date: Fri, 30 Oct 2026 04:05:24 +0800 Subject: [PATCH] Reject negative unit cell lengths --- package/MDAnalysis/coordinates/timestep.pyx | 5 +++++ .../MDAnalysisTests/coordinates/test_timestep_api.py | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/package/MDAnalysis/coordinates/timestep.pyx b/package/MDAnalysis/coordinates/timestep.pyx index 09e44c0f551..dec5c84e5f5 100644 --- a/package/MDAnalysis/coordinates/timestep.pyx +++ b/package/MDAnalysis/coordinates/timestep.pyx @@ -468,6 +468,11 @@ cdef class Timestep: if new_dimensions is None: self._unitcell[:] = 0 else: + new_dimensions = np.asarray(new_dimensions, dtype=np.float32) + if new_dimensions.ndim == 0 and new_dimensions < 0: + raise ValueError("Unit cell lengths must be non-negative") + if new_dimensions.size == 6 and (new_dimensions.reshape(-1)[:3] < 0).any(): + raise ValueError("Unit cell lengths must be non-negative") self._unitcell[:] = new_dimensions @property diff --git a/testsuite/MDAnalysisTests/coordinates/test_timestep_api.py b/testsuite/MDAnalysisTests/coordinates/test_timestep_api.py index 1b2bc468b3e..2d26fb7fe52 100644 --- a/testsuite/MDAnalysisTests/coordinates/test_timestep_api.py +++ b/testsuite/MDAnalysisTests/coordinates/test_timestep_api.py @@ -828,6 +828,17 @@ def test_set_zero_box(self, ts): assert ts.dimensions is None assert ts.triclinic_dimenions is None + @pytest.mark.parametrize("value", [-1.0, -np.inf]) + def test_set_negative_length_rejected(self, ts, value): + with pytest.raises(ValueError, match="non-negative"): + ts.dimensions = [value, 2, 3, 90, 90, 90] + + def test_scalar_dimensions_broadcast_is_preserved(self, ts): + ts.dimensions = 7 + assert np.all(ts.dimensions == 7) + with pytest.raises(ValueError, match="non-negative"): + ts.dimensions = -1 + def test_set_zero_box_triclinic(self, ts): ts.triclinic_dimensions = np.zeros((3, 3))