Finalizes the masked array.
(self, obj)
| 2976 | return |
| 2977 | |
| 2978 | def __array_finalize__(self, obj): |
| 2979 | """ |
| 2980 | Finalizes the masked array. |
| 2981 | |
| 2982 | """ |
| 2983 | # Get main attributes. |
| 2984 | self._update_from(obj) |
| 2985 | |
| 2986 | # We have to decide how to initialize self.mask, based on |
| 2987 | # obj.mask. This is very difficult. There might be some |
| 2988 | # correspondence between the elements in the array we are being |
| 2989 | # created from (= obj) and us. Or there might not. This method can |
| 2990 | # be called in all kinds of places for all kinds of reasons -- could |
| 2991 | # be empty_like, could be slicing, could be a ufunc, could be a view. |
| 2992 | # The numpy subclassing interface simply doesn't give us any way |
| 2993 | # to know, which means that at best this method will be based on |
| 2994 | # guesswork and heuristics. To make things worse, there isn't even any |
| 2995 | # clear consensus about what the desired behavior is. For instance, |
| 2996 | # most users think that np.empty_like(marr) -- which goes via this |
| 2997 | # method -- should return a masked array with an empty mask (see |
| 2998 | # gh-3404 and linked discussions), but others disagree, and they have |
| 2999 | # existing code which depends on empty_like returning an array that |
| 3000 | # matches the input mask. |
| 3001 | # |
| 3002 | # Historically our algorithm was: if the template object mask had the |
| 3003 | # same *number of elements* as us, then we used *it's mask object |
| 3004 | # itself* as our mask, so that writes to us would also write to the |
| 3005 | # original array. This is horribly broken in multiple ways. |
| 3006 | # |
| 3007 | # Now what we do instead is, if the template object mask has the same |
| 3008 | # number of elements as us, and we do not have the same base pointer |
| 3009 | # as the template object (b/c views like arr[...] should keep the same |
| 3010 | # mask), then we make a copy of the template object mask and use |
| 3011 | # that. This is also horribly broken but somewhat less so. Maybe. |
| 3012 | if isinstance(obj, ndarray): |
| 3013 | # XX: This looks like a bug -- shouldn't it check self.dtype |
| 3014 | # instead? |
| 3015 | if obj.dtype.names is not None: |
| 3016 | _mask = getmaskarray(obj) |
| 3017 | else: |
| 3018 | _mask = getmask(obj) |
| 3019 | |
| 3020 | # If self and obj point to exactly the same data, then probably |
| 3021 | # self is a simple view of obj (e.g., self = obj[...]), so they |
| 3022 | # should share the same mask. (This isn't 100% reliable, e.g. self |
| 3023 | # could be the first row of obj, or have strange strides, but as a |
| 3024 | # heuristic it's not bad.) In all other cases, we make a copy of |
| 3025 | # the mask, so that future modifications to 'self' do not end up |
| 3026 | # side-effecting 'obj' as well. |
| 3027 | if (_mask is not nomask and obj.__array_interface__["data"][0] |
| 3028 | != self.__array_interface__["data"][0]): |
| 3029 | # We should make a copy. But we could get here via astype, |
| 3030 | # in which case the mask might need a new dtype as well |
| 3031 | # (e.g., changing to or from a structured dtype), and the |
| 3032 | # order could have changed. So, change the mask type if |
| 3033 | # needed and use astype instead of copy. |
| 3034 | if self.dtype == obj.dtype: |
| 3035 | _mask_dtype = _mask.dtype |
no test coverage detected