Retrieve the properties for a given data type.

    This is the main routine where most of the work is done. It converts
    Nani's data types into properties that can be used to define a new NumPy
    array and to wrap it into a view object.

    Use :func:`validate` to check if the input data type is well-formed.

    Parameters
    ----------
    data_type : nani data type
        Type of the array elements.
    name : str
        Name for the view to be generated for the array.
    listify_default : bool
        ``True`` to output the default values with lists in place of tuples.
        This might cause the output to be incompatible with array creation
        routines such as ``numpy.array`` but it should still work for
        element assignment.

    Returns
    -------
    nani.Nani
        The properties to use to initalize a NumPy array around the data type.

    Examples
    --------
    Create a NumPy array where each element represents a color:

    >>> import numpy
    >>> import nani
    >>> color_type = nani.Array(
    ...     element_type=nani.Number(type=numpy.uint8, default=255),
    ...     shape=3,
    ...     view=None)
    >>> dtype, default, view = nani.resolve(color_type, name='Color')
    >>> a = numpy.array([default] * element_count, dtype=dtype)
    >>> v = view(a)
    >>> type(v)
    <class 'nani.Color'>
    >>> for color in v:
    ...     color
    [255, 255, 255]
    [255, 255, 255]

def resolve(data_type, name=None, listify_default=False):
    """Retrieve the properties for a given data type.

    This is the main routine where most of the work is done. It converts
    Nani's data types into properties that can be used to define a new NumPy
    array and to wrap it into a view object.

    Use :func:`validate` to check if the input data type is well-formed.

    Parameters
    ----------
    data_type : nani data type
        Type of the array elements.
    name : str
        Name for the view to be generated for the array.
    listify_default : bool
        ``True`` to output the default values with lists in place of tuples.
        This might cause the output to be incompatible with array creation
        routines such as ``numpy.array`` but it should still work for
        element assignment.

    Returns
    -------
    nani.Nani
        The properties to use to initalize a NumPy array around the data type.

    Examples
    --------
    Create a NumPy array where each element represents a color:

    >>> import numpy
    >>> import nani
    >>> color_type = nani.Array(
    ...     element_type=nani.Number(type=numpy.uint8, default=255),
    ...     shape=3,
    ...     view=None)
    >>> dtype, default, view = nani.resolve(color_type, name='Color')
    >>> a = numpy.array([default] * element_count, dtype=dtype)
    >>> v = view(a)
    >>> type(v)
    <class 'nani.Color'>
    >>> for color in v:
    ...     color
    [255, 255, 255]
    [255, 255, 255]
    """
    data_type = _consolidate(data_type)
    return Nani(
        dtype=numpy.dtype(_resolve_dtype(data_type)),
        default=_resolve_default(data_type, listify=listify_default),
        view=_resolve_view(Array(element_type=data_type, shape=-1, name=name)))