Repository: numpy/numpy
File: numpy/ma/core.py (Python)

Code before:

max_filler = _minvals
max_filler.update([(k, -np.inf) for k in float_types_list[:4]])
max_filler.update([(k, complex(-np.inf, -np.inf)) for k in float_types_list[-3:]])

min_filler = _maxvals
min_filler.update([(k, +np.inf) for k in float_types_list[:4]])
min_filler.update([(k, complex(+np.inf, +np.inf)) for k in float_types_list[-3:]])

del float_types_list

def _recursive_fill_value(dtype, f):
    """
    Recursively produce a fill value for `dtype`, calling f on scalar dtypes
    """
    if dtype.names is not None:
        # We wrap into `array` here, which ensures we use NumPy cast rules
        # for integer casts, this allows the use of 99999 as a fill value
        # for int8.
        # TODO: This is probably a mess, but should best preserve behavior?
        vals = []
        for name in dtype.names:
            field_dtype = dtype[name]
            val = _recursive_fill_value(field_dtype, f)
            if np.issubdtype(field_dtype, np.datetime64):
                if isinstance(val, (datetime.date, datetime.datetime)):
                    val = np.datetime64(val)
                elif isinstance(val, (int, np.integer)):
                    val = np.array(val).astype(field_dtype)
            vals.append(np.array(val))
        return np.array(tuple(vals), dtype=dtype)[()]  # decay to void scalar from 0d
    elif dtype.subdtype:
        subtype, shape = dtype.subdtype
        subval = _recursive_fill_value(subtype, f)
        return np.full(shape, subval)
    else:
        return f(dtype)


def _get_dtype_of(obj):
    """ Convert the argument for *_fill_value into a dtype """
    if isinstance(obj, np.dtype):
        return obj
    elif hasattr(obj, 'dtype'):
        return obj.dtype
    else:
        return np.asanyarray(obj).dtype


def default_fill_value(obj):
    """

Review comment (suggestion):
`datetime.datetime` is a subclass of `datetime.date`:

```suggestion
                if isinstance(val, datetime.date):
```

Code after:

max_filler = _minvals
max_filler.update([(k, -np.inf) for k in float_types_list[:4]])
max_filler.update([(k, complex(-np.inf, -np.inf)) for k in float_types_list[-3:]])

min_filler = _maxvals
min_filler.update([(k, +np.inf) for k in float_types_list[:4]])
min_filler.update([(k, complex(+np.inf, +np.inf)) for k in float_types_list[-3:]])

del float_types_list

def _recursive_fill_value(dtype, f):
    """
    Recursively produce a fill value for `dtype`, calling f on scalar dtypes
    """
    if dtype.names is not None:
        # We wrap into `array` here, which ensures we use NumPy cast rules
        # for integer casts, this allows the use of 99999 as a fill value
        # for int8.
        vals = []
        for name in dtype.names:
            field_dtype = dtype[name]
            val = _recursive_fill_value(field_dtype, f)
            if np.issubdtype(field_dtype, np.datetime64):
                if isinstance(val, dt.date):
                    val = np.datetime64(val)
                    val = np.array(val)
                elif isinstance(val, (int, np.integer)):
                    val = np.array(val).astype(field_dtype)
                else:
                    val = np.array(val)
            else:
                val = np.array(val)
            vals.append(val)
        return np.array(tuple(vals), dtype=dtype)[()]  # decay to void scalar from 0d
    elif dtype.subdtype:
        subtype, shape = dtype.subdtype
        subval = _recursive_fill_value(subtype, f)
        return np.full(shape, subval)
    else:
        return f(dtype)


def _get_dtype_of(obj):
    """ Convert the argument for *_fill_value into a dtype """
    if isinstance(obj, np.dtype):
        return obj
    elif hasattr(obj, 'dtype'):
        return obj.dtype
    else:
        return np.asanyarray(obj).dtype