import socket


def to_address(hostname, family=socket.AF_UNSPEC, socktype=socket.SOCK_STREAM):
    """
    Resolve a hostname to an address, preferring IPv4 addresses.

    Given a string containing a DNS hostname, this function resolves the
    hostname to an address, using an LRU cache to speed up repeat queries. The
    function prefers IPv4 addresses, but will return IPv6 addresses if no IPv4
    addresses are present in the result from getaddrinfo. If the hostname does
    not resolve, the function returns None rather than raise an exception (this
    is preferable as it provides a negative lookup cache).

    :param str hostname: The hostname to resolve to an address
    :returns: The resolved address
    """
    result = None
    try:
        for (family, _, _, _, sockaddr) in socket.getaddrinfo(
                hostname, None, family, socktype):
            if family == socket.AF_INET:
                result = sockaddr[0]
                break
            elif family == socket.AF_INET6 and not result:
                result = sockaddr[0]
    # XXX Workaround LP #1154599
    # This should be socket.gaierror instead of socket.error
    except socket.error:
        pass
    return result