Skip to content

Commit 5b5223f

Browse files
committed
[Fix] use 2d empty arrays instead of 1d empty arrays as defaults
1 parent c923d08 commit 5b5223f

4 files changed

Lines changed: 20 additions & 24 deletions

File tree

spm/__wrapper__.py

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,6 @@ def _import_initialize():
157157
# ----------------------------------------------------------------------
158158

159159

160-
_NP_VERSION = tuple(map(int, np.__version__.split(".")[:2]))
161-
_NP_HAS_COPY = not (_NP_VERSION < (2, 1))
162-
163-
164160
def _copy_if_needed(out, inp, copy=None) -> np.ndarray:
165161
"""Fallback implementation for asarray(*, copy: bool)"""
166162
if (
@@ -212,6 +208,11 @@ def _matlab_array_types():
212208
return {}
213209

214210

211+
def _empty_array() -> "Array":
212+
"""Matlab's default cell/struct elements are 0x0 arrays."""
213+
return Array.from_shape([0, 0])
214+
215+
215216
# ----------------------------------------------------------------------
216217
# Types
217218
# ----------------------------------------------------------------------
@@ -534,7 +535,7 @@ def _finalize(self):
534535

535536
if self._future is None:
536537
# FIXME: I am not entirely sure this should ever happen
537-
self._future = Array.from_any([])
538+
self._future = _empty_array()
538539

539540
# if future array is wrapped, unwrap it
540541
if isinstance(self._future, WrappedDelayedArray):
@@ -1704,19 +1705,14 @@ class Cell(_ListMixin, WrappedArray):
17041705

17051706
@classmethod
17061707
def _DEFAULT(cls, shape: list = ()) -> np.ndarray:
1707-
# if len(shape) == 0:
1708-
# out = np.array(None)
1709-
# out[()] = Array.from_any([])
1710-
# return out
1711-
17121708
data = np.empty(shape, dtype=object)
17131709
opt = dict(
17141710
flags=['refs_ok', 'zerosize_ok'],
17151711
op_flags=['writeonly', 'no_broadcast']
17161712
)
17171713
with np.nditer(data, **opt) as iter:
17181714
for elem in iter:
1719-
elem[()] = Array.from_any([])
1715+
elem[()] = _empty_array()
17201716
return data
17211717

17221718
def _fill_default(self):
@@ -1725,7 +1721,7 @@ def _fill_default(self):
17251721
op_flags=['writeonly', 'no_broadcast'])
17261722
with np.nditer(arr, **opt) as iter:
17271723
for elem in iter:
1728-
elem[()] = Array.from_any([])
1724+
elem[()] = _empty_array()
17291725
return self
17301726

17311727
def __new__(cls, *args, **kwargs) -> "Cell":
@@ -2111,7 +2107,7 @@ def __getitem__(self, key):
21112107
opt = dict(flags=['refs_ok', 'zerosize_ok'], op_flags=['readonly'])
21122108
with np.nditer(arr, **opt) as iter:
21132109
for elem in iter:
2114-
elem.item().setdefault(key, Array.from_any([]))
2110+
elem.item().setdefault(key, _empty_array())
21152111

21162112
# NOTE
21172113
# We then defer to `as_dict`
@@ -2206,7 +2202,7 @@ def setdefault(self, key, value=None):
22062202
for elem in iter:
22072203
item = elem.item()
22082204
if value is None:
2209-
value = Array.from_any([])
2205+
value = _empty_array()
22102206
else:
22112207
value = MatlabType.from_any(value)
22122208
item.setdefault(key, value)
@@ -2604,7 +2600,7 @@ def _ensure_defaults_are_set(self, keys=None):
26042600
if keys:
26052601
item: dict = arr.item()
26062602
for key in keys:
2607-
item.setdefault(key, Array.from_any([]))
2603+
item.setdefault(key, _empty_array())
26082604

26092605
if keys is None:
26102606
keys = self._allkeys()
@@ -2616,7 +2612,7 @@ def _ensure_defaults_are_set(self, keys=None):
26162612
for elem in iter:
26172613
item: dict = elem.item()
26182614
for key in keys:
2619-
item.setdefault(key, Array.from_any([]))
2615+
item.setdefault(key, _empty_array())
26202616

26212617
# --------------
26222618
# Bracket syntax

tests/test_cell.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ def test_cell_indexing_1d(self):
463463
c[3] = 9 # insert new element
464464
self.assertEqual(c.tolist(), [7, 2, 8, 9])
465465
c[5] = 11 # insert new element
466-
self.assertTrue(isinstance(c[4], Array) and c[4].shape == (0,))
466+
self.assertTrue(isinstance(c[4], Array) and c[4].size == 0)
467467
self.assertTrue(c[5] == 11)
468468

469469
# __delitem__

tests/test_implicit.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ def test_array(self):
1919
def test_cell(self):
2020
x = Cell()
2121
x[2] = 3
22-
self.assertEqual(x[0].shape, (0,))
23-
self.assertEqual(x[1].shape, (0,))
22+
self.assertEqual(x[0].shape, (0, 0))
23+
self.assertEqual(x[1].shape, (0, 0))
2424
self.assertEqual(x[2], 3)
2525

2626
x = Cell()
2727
x[1:3] = [2, 3]
28-
self.assertEqual(x[0].shape, (0,))
28+
self.assertEqual(x[0].shape, (0, 0))
2929
self.assertListEqual(x[1:3].tolist(), [2, 3])
3030

3131
self.assertRaises(IndexError, lambda: Cell()[2] * 2)
@@ -39,7 +39,7 @@ def test_struct(self):
3939
x[1] = {"a": 3}
4040
self.assertTrue(x.shape == (2,))
4141
self.assertEqual(x[1].a, 3)
42-
self.assertTrue(x[0].a.shape == (0,))
42+
self.assertTrue(x[0].a.shape == (0, 0))
4343

4444
self.assertRaises(AttributeError, lambda: Struct().a * 2)
4545
self.assertRaises(KeyError, lambda: Struct()["a"] * 2)

tests/test_struct.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,11 @@ def test_struct_as_array_after_initialization(self):
124124

125125
# Unspecified elements are empty arrays
126126
self.assertIsInstance(self.struct[0].baz, Array)
127-
self.assertTupleEqual(self.struct[0].baz.shape, (0,))
127+
self.assertTupleEqual(self.struct[0].baz.shape, (0, 0))
128128
self.assertIsInstance(self.struct[1].foo, Array)
129-
self.assertTupleEqual(self.struct[1].foo.shape, (0,))
129+
self.assertTupleEqual(self.struct[1].foo.shape, (0, 0))
130130
self.assertIsInstance(self.struct[1].bar, Array)
131-
self.assertTupleEqual(self.struct[1].bar.shape, (0,))
131+
self.assertTupleEqual(self.struct[1].bar.shape, (0, 0))
132132

133133
def test_struct_from_matlab(self):
134134
# Construct a struct in Matlab

0 commit comments

Comments
 (0)