# Buggy code
def _check_fill_value(fill_value, ndtype):
    """
    Private function validating the given `fill_value` for the given dtype.

    If fill_value is None, it is set to the default corresponding to the dtype
    if this latter is standard (no fields). If the datatype is flexible (named
    fields), fill_value is set to a tuple whose elements are the default fill
    values corresponding to each field.

    If fill_value is not None, its value is forced to the given dtype.

    """
    ndtype = np.dtype(ndtype)
    fields = ndtype.fields
    if fill_value is None:
        if fields:
            fill_value = np.array(
                _recursive_set_default_fill_value(ndtype), dtype=ndtype
            )
        else:
            fill_value = default_fill_value(ndtype)
    elif fields:
        fdtype = [(_[0], _[1]) for _ in ndtype.descr]
        if isinstance(fill_value, (ndarray, np.void)):
            try:
                fill_value = np.array(fill_value, copy=False, dtype=fdtype)
            except ValueError:
                err_msg = "Unable to transform %s to dtype %s"
                raise ValueError(err_msg % (fill_value, fdtype))
        else:
            fill_value = np.asarray(fill_value, dtype=object)
            fill_value = np.array(
                _recursive_set_fill_value(fill_value, ndtype), dtype=ndtype
            )
    else:
        if isinstance(fill_value, basestring) and (ndtype.char not in "OSVU"):
            err_msg = "Cannot set fill value of string with array of dtype %s"
            raise TypeError(err_msg % ndtype)
        else:
            # In case we want to convert 1e20 to int.
            try:
                fill_value = np.array(fill_value, copy=False, dtype=ndtype)
            except OverflowError:
                # Raise TypeError instead of OverflowError. OverflowError
                # is seldom used, and the real problem here is that the
                # passed fill_value is not compatible with the ndtype.
                err_msg = "Fill value %s overflows dtype %s"
                raise TypeError(err_msg % (fill_value, ndtype))
    return np.array(fill_value)


# Traceback (TypeError)
In [32]: A = np.arange(100, dtype='i8').view("(4)i4,(4)i4")

In [33]: Am = np.ma.MaskedArray(A, np.zeros_like(A))

In [34]: Am.sort()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-34-9b8a457bb910> in <module>()
----> 1 Am.sort()

/home/users/gholl/venv/stable-3.5/lib/python3.5/site-packages/numpy/ma/core.py in sort(self, axis, kind, order, endwith, fill_value)
5417                 filler = fill_value
5418
-> 5419             sidx = self.filled(filler).argsort(axis=axis, kind=kind,
5420                                                order=order)
5421             # save meshgrid memory for 1d arrays

/home/users/gholl/venv/stable-3.5/lib/python3.5/site-packages/numpy/ma/core.py in filled(self, fill_value)
3625             fill_value = self.fill_value
3626         else:
-> 3627             fill_value = _check_fill_value(fill_value, self.dtype)
3628
3629         if self is masked_singleton:

/home/users/gholl/venv/stable-3.5/lib/python3.5/site-packages/numpy/ma/core.py in _check_fill_value(fill_value, ndtype)
428             descr = ndtype.descr
429             fill_value = np.asarray(fill_value, dtype=object)
--> 430             fill_value = np.array(_recursive_set_fill_value(fill_value, descr),
431                                   dtype=ndtype)
432     else:

/home/users/gholl/venv/stable-3.5/lib/python3.5/site-packages/numpy/ma/core.py in _recursive_set_fill_value(fillvalue, dtypedescr)
392             output_value.append(tuple(_recursive_set_fill_value(fval, cdtype)))
393         else:
--> 394             output_value.append(np.array(fval, dtype=cdtype).item())
395     return tuple(output_value)
396

TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'

# Fixed code
def _check_fill_value(fill_value, ndtype):
    """
    Private function validating the given `fill_value` for the given dtype.

    If fill_value is None, it is set to the default corresponding to the dtype.

    If fill_value is not None, its value is forced to the given dtype.

    The result is always a 0d array.
    """
    ndtype = np.dtype(ndtype)
    fields = ndtype.fields
    if fill_value is None:
        fill_value = default_fill_value(ndtype)
    elif fields:
        fdtype = [(_[0], _[1]) for _ in ndtype.descr]
        if isinstance(fill_value, (ndarray, np.void)):
            try:
                fill_value = np.array(fill_value, copy=False, dtype=fdtype)
            except ValueError:
                err_msg = "Unable to transform %s to dtype %s"
                raise ValueError(err_msg % (fill_value, fdtype))
        else:
            fill_value = np.asarray(fill_value, dtype=object)
            fill_value = np.array(
                _recursive_set_fill_value(fill_value, ndtype), dtype=ndtype
            )
    else:
        if isinstance(fill_value, basestring) and (ndtype.char not in "OSVU"):
            err_msg = "Cannot set fill value of string with array of dtype %s"
            raise TypeError(err_msg % ndtype)
        else:
            # In case we want to convert 1e20 to int.
            try:
                fill_value = np.array(fill_value, copy=False, dtype=ndtype)
            except OverflowError:
                # Raise TypeError instead of OverflowError. OverflowError
                # is seldom used, and the real problem here is that the
                # passed fill_value is not compatible with the ndtype.
                err_msg = "Fill value %s overflows dtype %s"
                raise TypeError(err_msg % (fill_value, ndtype))
    return np.array(fill_value)