MCPcopy Index your code
hub / github.com/numpy/numpy / __array_finalize__

Method __array_finalize__

numpy/ma/core.py:3050–3141  ·  view source on GitHub ↗

Finalizes the masked array.

(self, obj)

Source from the content-addressed store, hash-verified

3048 self.__dict__.update(_optinfo)
3049
3050 def __array_finalize__(self, obj):
3051 """
3052 Finalizes the masked array.
3053
3054 """
3055 # Get main attributes.
3056 self._update_from(obj)
3057
3058 # We have to decide how to initialize self.mask, based on
3059 # obj.mask. This is very difficult. There might be some
3060 # correspondence between the elements in the array we are being
3061 # created from (= obj) and us. Or there might not. This method can
3062 # be called in all kinds of places for all kinds of reasons -- could
3063 # be empty_like, could be slicing, could be a ufunc, could be a view.
3064 # The numpy subclassing interface simply doesn't give us any way
3065 # to know, which means that at best this method will be based on
3066 # guesswork and heuristics. To make things worse, there isn't even any
3067 # clear consensus about what the desired behavior is. For instance,
3068 # most users think that np.empty_like(marr) -- which goes via this
3069 # method -- should return a masked array with an empty mask (see
3070 # gh-3404 and linked discussions), but others disagree, and they have
3071 # existing code which depends on empty_like returning an array that
3072 # matches the input mask.
3073 #
3074 # Historically our algorithm was: if the template object mask had the
3075 # same *number of elements* as us, then we used *it's mask object
3076 # itself* as our mask, so that writes to us would also write to the
3077 # original array. This is horribly broken in multiple ways.
3078 #
3079 # Now what we do instead is, if the template object mask has the same
3080 # number of elements as us, and we do not have the same base pointer
3081 # as the template object (b/c views like arr[...] should keep the same
3082 # mask), then we make a copy of the template object mask and use
3083 # that. This is also horribly broken but somewhat less so. Maybe.
3084 if isinstance(obj, ndarray):
3085 # XX: This looks like a bug -- shouldn't it check self.dtype
3086 # instead?
3087 if obj.dtype.names is not None:
3088 _mask = getmaskarray(obj)
3089 else:
3090 _mask = getmask(obj)
3091
3092 # If self and obj point to exactly the same data, then probably
3093 # self is a simple view of obj (e.g., self = obj[...]), so they
3094 # should share the same mask. (This isn't 100% reliable, e.g. self
3095 # could be the first row of obj, or have strange strides, but as a
3096 # heuristic it's not bad.) In all other cases, we make a copy of
3097 # the mask, so that future modifications to 'self' do not end up
3098 # side-effecting 'obj' as well.
3099 if (_mask is not nomask and obj.__array_interface__["data"][0]
3100 != self.__array_interface__["data"][0]):
3101 # We should make a copy. But we could get here via astype,
3102 # in which case the mask might need a new dtype as well
3103 # (e.g., changing to or from a structured dtype), and the
3104 # order could have changed. So, change the mask type if
3105 # needed and use astype instead of copy.
3106 if self.dtype == obj.dtype:
3107 _mask_dtype = _mask.dtype

Callers 1

__array_finalize__Method · 0.45

Calls 8

_update_fromMethod · 0.95
getmaskarrayFunction · 0.85
getmaskFunction · 0.85
make_mask_descrFunction · 0.85
_check_fill_valueFunction · 0.85
astypeMethod · 0.80
reshapeMethod · 0.80
viewMethod · 0.45

Tested by

no test coverage detected