BlockLayout2D.to_dense: require floats when the layout has holes

Holes are filled with NaN, which bool/str silently mangled and integers
rejected with a conversion error. Sparse layouts now raise a clear
ValueError for non-floating arrays; full layouts keep any dtype.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-16 03:16:52 +00:00
1 parent aecee19c19
commit cc64abcafe
2 files changed
+19 -3

No files matched your search

+12
View File
@@ -422,6 +422,18 @@ class SparseBlockLayoutTests(unittest.TestCase):
self.assertEqual(layout.block_cell(0, 0, 0), address)
self.assertEqual(address, layout.owner[0, 0])
def test_to_dense_dtype_contract(self):
full = BlockLayout2D.build(6, 8, 3, 4)
blocked = np.arange(np.prod(full.blocked_shape), dtype=np.int64).reshape(full.blocked_shape)
dense = full.to_dense(blocked) # legacy: full layouts keep any dtype
self.assertEqual(dense.dtype, np.int64)
np.testing.assert_array_equal(dense, full.to_dense(blocked.astype(np.float64)))
sparse = BlockLayout2D.build(6, 8, 3, 4, origins=[(0, 0), (3, 4)])
for dtype in (np.int64, np.uint16, np.bool_):
with self.subTest(dtype=dtype), self.assertRaises(ValueError):
sparse.to_dense(np.zeros(sparse.blocked_shape, dtype=dtype))
self.assertEqual(sparse.to_dense(np.zeros(sparse.blocked_shape, np.float32)).dtype, np.float32)
def test_invalid_origins_rejected(self):
for origins in ([(0, 4), (0, 0)], # not row-major
[(3, 0), (0, 4)], # not row-major across rows