Fix: crash iterating through frozen matrices

Row and column access used `BaseMath_ReadCallback_ForWrite`
which fails on frozen matrices, returning NULL.

Use the read-only `BaseMath_ReadCallback`, rely on the write
checks on the vectors to ensure the frozen matrix isn't modified.

Also correct invalid ROW/COL comments.

Ref !158183
This commit is contained in:
Campbell Barton 2026-05-06 04:24:35 +00:00
parent 6cf7667199
commit 4a741dfa2e
2 changed files with 30 additions and 5 deletions

View file

@ -416,6 +416,19 @@ class MatrixTesting(unittest.TestCase):
with self.assertRaises(TypeError):
mat[0][0] = 0.0
def test_matrix_freeze_iter(self):
rows = (
(1.0, 2.0, 3.0),
(4.0, 5.0, 6.0),
(7.0, 8.0, 9.0),
)
cols = tuple(zip(*rows))
mat = Matrix(rows)
mat.freeze()
self.assertEqual(tuple(tuple(v) for v in mat), rows)
self.assertEqual(tuple(tuple(v) for v in mat.row), rows)
self.assertEqual(tuple(tuple(v) for v in mat.col), cols)
def test_buffer_protocol(self):
expected = [list(range(i * 4, (i * 4) + 4)) for i in range(4)]
m = Matrix(expected)
@ -487,6 +500,16 @@ class MatrixSliceMixIn:
self.assertEqual(obj[-1:], base[-1:])
self.assertEqual(obj[1:1], ())
def test_slice_set_frozen(self):
n = self.matrix_size
base = tuple(self._make_value(i + 1) for i in range(n))
mat, obj = self._make_obj(base)
# `MatrixAccess` has no `freeze()`; freezing the matrix is enough either way.
mat.freeze()
with self.assertRaises(TypeError):
obj[:] = base
self.assertEqual(tuple(obj), base)
class Matrix3x3TestingSlice(MatrixSliceMixIn, unittest.TestCase):
matrix_size = 3