8000 BUG: Tweak memmap __array_*__ calls to avoid possible regressions · seberg/numpy@e33b664 · GitHub
[go: up one dir, main page]

Skip to content

Commit e33b664

Browse files
committed
BUG: Tweak memmap __array_*__ calls to avoid possible regressions
Need to call the underlying __array_*__ function to look exactly the same to a class subclassing memmap. To make sure that multiply inheritence would keep working exactly the same, need to do the try/excepts. However __array_finalize__ does not really support multiple inheritences well in any case.
1 parent d86c8bd commit e33b664

File tree

2 files changed

+24
-13
lines changed

2 files changed

+24
-13
lines changed

numpy/core/memmap.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -283,24 +283,30 @@ def __array_finalize__(self, obj):
283283
self.mode = None
284284

285285
def __array_wrap__(self, arr, context=None):
286-
# If the type is not memmap, then a user subclass may have some special
287-
# functions that should be preserved to avoid a regression
288-
if type(self) is not memmap:
289-
r 10000 eturn arr.view(type=type(self))
290-
return arr
286+
# If the type is not memmap, then a user subclass may do some more
287+
# things that need to be preserved. Otherwise, return a base array
288+
# since it should not p
289+
if type(self) is memmap and not np.may_share_memory(self, arr):
290+
return arr
291+
try:
292+
return super(memmap, self).__array_wrap__(arr, context=context)
293+
except TypeError:
294+
return super(memmap, self).__array_wrap__(arr)
291295

292296
def __array_prepare__(self, arr, context=None):
293-
if type(self) is not memmap:
294-
return arr.view(type=type(self))
295-
# There is no use in making an array a memmap, since it does not own
296-
# its memory.
297-
return arr
297+
# There is no need to make an array a memmap, but we still have to do
298+
# it in case this is not of memmap type.
299+
if type(self) is memmap and not np.may_share_memory(self, arr):
300+
return arr
301+
try:
302+
return super(memmap, self).__array_prepare__(arr, context=context)
303+
except TypeError:
304+
return super(memmap, self).__array_prepare__(arr)
298305

299306
def __getitem__(self, index):
300-
# return an array if the result does not point to self's memory
301307
res = super(memmap, self).__getitem__(index)
302308
if type(res) is memmap and res._mmap is None:
303-
return res.view(ndarray)
309+
return res.view(type=ndarray)
304310
return res
305311

306312
def flush(self):

numpy/core/tests/test_memmap.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,11 @@ def test_view(self):
116116
assert(new_array.base is fp)
117117

118118
def test_to_array_conversions(self):
119-
class MMSubclass(memmap):
119+
class DummyInerhitance(np.ndarray):
120+
def __array_wrap__(self, arr):
121+
arr = super(DummyInerhitance, self).__array_wrap__(arr)
122+
arr.info = 'set'
123+
class MMSubclass(memmap, DummyInerhitance):
120124
pass
121125
m = memmap(self.tmpfp, dtype=self.dtype, shape=self.shape)
122126
r = m + 1
@@ -128,6 +132,7 @@ class MMSubclass(memmap):
128132
m = MMSubclass(self.tmpfp, dtype=self.dtype, shape=self.shape)
129133
r = m + 1
130134
assert_(isinstance(r, MMSubclass))
135+
assert_(hasattr(r, 'info'))
131136
assert_(isinstance(m[:,[0,1]], MMSubclass))
132137

133138
if __name__ == "__main__":

0 commit comments

Comments
 (0)
0