# Buggy code
def _replace_nan(a, val):
    """
    If `a` is of inexact type, make a copy of `a`, replace NaNs with
    the `val` value, and return the copy together with a boolean mask
    marking the locations where NaNs were present. If `a` is not of
    inexact type, do nothing and return `a` together with a mask of None.

    Note that scalars will end up as array scalars, which is important
    for using the result as the value of the out argument in some
    operations.

    Parameters
    ----------
    a : array-like
        Input array.
    val : float
        NaN values are set to val before doing the operation.

    Returns
    -------
    y : ndarray
        If `a` is of inexact type, return a copy of `a` with the NaNs
        replaced by the fill value, otherwise return `a`.
    mask: {bool, None}
        If `a` is of inexact type, return a boolean mask marking locations of
        NaNs, otherwise return None.

    """
    a = np.array(a, subok=True, copy=True)

    if not issubclass(a.dtype.type, np.inexact):
        return a, None

    mask = np.isnan(a)
    np.copyto(a, val, where=mask)
    return a, mask


# Traceback (TypeError)
In [2]: import numpy as np

In [3]: np.__version__
Out[3]: '1.13.0.dev0+bca7922'

In [4]: a = np.array([[1.0, 2.0], [3.0, 4.0]], dtype=object)

In [5]: np.nanmax(a, axis=0)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-a020f98a2536> in <module>()
----> 1 np.nanmax(a, axis=0)

/Users/warren/miniconda3numpy/lib/python3.5/site-packages/numpy-1.13.0.dev0+bca7922-py3.5-macosx-10.6-x86_64.egg/numpy/lib/nanfunctions.py in nanmax(a, axis, out, keepdims)
343         # Fast, but not safe for subclasses of ndarray
344         res = np.fmax.reduce(a, axis=axis, out=out, **kwargs)
--> 345         if np.isnan(res).any():
346             warnings.warn("All-NaN slice encountered", RuntimeWarning, stacklevel=2)
347     else:

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

# Fixed code
def _replace_nan(a, val):
    """
    If `a` is of inexact type, make a copy of `a`, replace NaNs with
    the `val` value, and return the copy together with a boolean mask
    marking the locations where NaNs were present. If `a` is not of
    inexact type, do nothing and return `a` together with a mask of None.

    Note that scalars will end up as array scalars, which is important
    for using the result as the value of the out argument in some
    operations.

    Parameters
    ----------
    a : array-like
        Input array.
    val : float
        NaN values are set to val before doing the operation.

    Returns
    -------
    y : ndarray
        If `a` is of inexact type, return a copy of `a` with the NaNs
        replaced by the fill value, otherwise return `a`.
    mask: {bool, None}
        If `a` is of inexact type, return a boolean mask marking locations of
        NaNs, otherwise return None.

    """
    a = np.array(a, subok=True, copy=True)

    if a.dtype == np.object_:
        # object arrays do not support `isnan` (gh-9009), so make a guess
        mask = a != a
    elif issubclass(a.dtype.type, np.inexact):
        mask = np.isnan(a)
    else:
        mask = None

    if mask is not None:
        np.copyto(a, val, where=mask)

    return a, mask