Generator which yields possible type names to look up in the conversion
    dictionary.

    Parameters
    ----------
    python_type_representation : object
        Any Python object which represents a type, such as `int`,
        `dtype('int8')`, `np.int8`, or `"int8"`.

def _candidate_type_names(python_type_representation):
    """Generator which yields possible type names to look up in the conversion
    dictionary.

    Parameters
    ----------
    python_type_representation : object
        Any Python object which represents a type, such as `int`,
        `dtype('int8')`, `np.int8`, or `"int8"`.
    """
    # if we get a single character code we should normalize to a NumPy type
    # using np.typeDict, which maps string representations of types to NumPy
    # type objects
    if python_type_representation in np.typeDict:
        python_type_representation = np.typeDict[python_type_representation]
        yield python_type_representation.__name__

    # if we get a dtype object i.e. dtype('int16'), then pull out its name
    if hasattr(python_type_representation, 'name'):
        yield python_type_representation.name

    # convert Python types by adding their type's name
    if hasattr(python_type_representation, '__name__'):
        yield python_type_representation.__name__

    # for a dtype like dtype('S3') need to access dtype.type.__name__
    # to get 'string_'
    if hasattr(python_type_representation, 'type'):
        if hasattr(python_type_representation.type, '__name__'):
            yield python_type_representation.type.__name__

    yield str(python_type_representation)