Assert a value is an |nparray| of NumPy floats.

    Pass |None| to `varname` if `obj` itself is to be checked.
    Otherwise, `varname` is the string name of the attribute of `obj` to
    check.  In either case, `desc` is a string description of the
    object to be checked, for use in raising of exceptions.

    Raises the exception `exc` with typecode `tc` if the indicated
    object is determined not to be an |nparray|, with a NumPy float dtype.

    Intended primarily to serve as an early check for
    proper implementation of subclasses of
    :class:`~opan.grad.SuperOpanGrad` and
    :class:`~opan.hess.SuperOpanHess`. Early type-checking of key
    attributes will hopefully avoid confusing bugs downstream.

    Parameters
    ----------
    obj
        (arbitrary) --
        Object to be checked, or object with attribute to be checked.

    varname
        |str| or |None| --
        Name of the attribute of `obj` to be type-checked. |None|
        indicates to check `obj` itself.

    desc
        |str| --
        Description of the object being checked to be used in any
        raised exceptions.

    exc
        Subclass of :class:`~opan.error.OpanError` to be raised on
        a failed typecheck.

    tc
        Typecode of `exc` to be raised on a failed typecheck.

    errsrc
        |str| --
        String description of the source of the data leading to a
        failed typecheck.

def assert_npfloatarray(obj, varname, desc, exc, tc, errsrc):
    """ Assert a value is an |nparray| of NumPy floats.

    Pass |None| to `varname` if `obj` itself is to be checked.
    Otherwise, `varname` is the string name of the attribute of `obj` to
    check.  In either case, `desc` is a string description of the
    object to be checked, for use in raising of exceptions.

    Raises the exception `exc` with typecode `tc` if the indicated
    object is determined not to be an |nparray|, with a NumPy float dtype.

    Intended primarily to serve as an early check for
    proper implementation of subclasses of
    :class:`~opan.grad.SuperOpanGrad` and
    :class:`~opan.hess.SuperOpanHess`. Early type-checking of key
    attributes will hopefully avoid confusing bugs downstream.

    Parameters
    ----------
    obj
        (arbitrary) --
        Object to be checked, or object with attribute to be checked.

    varname
        |str| or |None| --
        Name of the attribute of `obj` to be type-checked. |None|
        indicates to check `obj` itself.

    desc
        |str| --
        Description of the object being checked to be used in any
        raised exceptions.

    exc
        Subclass of :class:`~opan.error.OpanError` to be raised on
        a failed typecheck.

    tc
        Typecode of `exc` to be raised on a failed typecheck.

    errsrc
        |str| --
        String description of the source of the data leading to a
        failed typecheck.

    """

    # Imports
    import numpy as np

    # Check for whether member or object is to be checked
    if varname is None:
        var = obj
    else:
        # Try to get the variable to be typechecked
        try:
            var = getattr(obj, varname)
        except AttributeError:
            raise exc(tc, "Attribute '{0}' not defined in '{1}'"
                    .format(varname, obj), errsrc)
        ## end try
    ## end if

    # Try to pull the np dtype off of it
    try:
        dt = var.dtype
    except AttributeError:
        raise exc(tc, "'{0}' is not an np.array (lacks a 'dtype' member)"
                    .format(desc), errsrc)
    else:
        if not var.shape:
            raise exc(tc, "'{0}' is not an np.array ('len(shape)' < 1)"
                    .format(desc), errsrc)
    ## end try

    # Confirm dtype inherits from np.float
    if not np.issubdtype(dt, np.float):
        raise exc(tc, "'{0}' is not an np.array of np.float".format(desc),
                errsrc)