def _fcall_out_type(fcall):
    """Check if ``fcall`` has (optional) output argument.

    This function is intended to work with all types of callables
    that are used as input to `FunctionSpace.element`.
    """
    if isinstance(fcall, FunctionSpaceElement):
        call_has_out = fcall._call_has_out
        call_out_optional = fcall._call_out_optional

    # Numpy Ufuncs and similar objects (e.g. Numba DUfuncs)
    elif hasattr(fcall, 'nin') and hasattr(fcall, 'nout'):
        if fcall.nin != 1:
            raise ValueError('ufunc {} has {} input parameter(s), '
                             'expected 1'
                             ''.format(fcall.__name__, fcall.nin))
        if fcall.nout > 1:
            raise ValueError('ufunc {} has {} output parameter(s), '
                             'expected at most 1'
                             ''.format(fcall.__name__, fcall.nout))
        call_has_out = call_out_optional = (fcall.nout == 1)
    elif inspect.isfunction(fcall):
        call_has_out, call_out_optional = _check_out_arg(fcall)
    elif callable(fcall):
        call_has_out, call_out_optional = _check_out_arg(fcall.__call__)
    else:
        raise TypeError('object {!r} not callable'.format(fcall))

    return call_has_out, call_out_optional
Check if ``fcall`` has (optional) output argument.

    This function is intended to work with all types of callables
    that are used as input to `FunctionSpace.element`.