# Buggy code
def __lt__(self, other):
    """This function helps sorted to decide how to sort.

    It just checks itself against the other and decides on some key values
    if it should be sorted higher or lower in the list.
    The way it works:
    For networks, every 1 in 'netmask in binary' makes the subnet more specific.
    Therefore I chose to use prefix as the weight.
    So a single IP (/32) should have twice the weight of a /16 network.
    To keep everything in the same weight scale,
    - for ipv6, we use a weight scale of 0 (all possible ipv6 addresses) to 128 (single ip)
    - for ipv4, we use a weight scale of 0 (all possible ipv4 addresses) to 128 (single ip)
    Therefore for ipv4, we use prefixlen (0-32) * 4 for weight,
    which corresponds to ipv6 (0-128).
    """
    myweight = self.source_weight()
    hisweight = other.source_weight()
    if myweight != hisweight:
        return myweight > hisweight

    myweight = self.db_weight()
    hisweight = other.db_weight()
    if myweight != hisweight:
        return myweight < hisweight

    myweight = self.user_weight()
    hisweight = other.user_weight()
    if myweight != hisweight:
        return myweight < hisweight
    try:
        return self["src"] < other["src"]
    except TypeError:
        return self.source_type_weight() < other.source_type_weight()
    errormessage = "We have two rules ({1}, {2})".format(self, other)
    errormessage += " with exact same weight. Please file a bug."
    raise PgHbaValueError(errormessage)


# Traceback (nTypeError)
(venv3.6) ubuntu@ubuntu-GB-BXi3-5010:~/ansible$ ansible-playbook ~/ansible/renderworker/postgres/ansible/setup_postgres_pg_hba.yml

PLAY [192.168.1.110] ************************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************************
ok: [192.168.1.110]

TASK [Grant postgres access from home] ******************************************************************************************************************************************************************************
fatal: [192.168.1.110]: FAILED! => {"changed": false, "module_stderr": "Shared connection to 192.168.1.110 closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n  File \"/home/ubuntu/.ansible/tmp/ansible-tmp-1557891828.8283231-200022434247587/AnsiballZ_postgresql_pg_hba.py\", line 125, in <module>\r\n    _ansiballz_main()\r\n  File \"/home/ubuntu/.ansible/tmp/ansible-tmp-1557891828.8283231-200022434247587/AnsiballZ_postgresql_pg_hba.py\", line 117, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n  File \"/home/ubuntu/.ansible/tmp/ansible-tmp-1557891828.8283231-200022434247587/AnsiballZ_postgresql_pg_hba.py\", line 51, in invoke_module\r\n    spec.loader.exec_module(module)\r\n  File \"<frozen importlib._bootstrap_external>\", line 678, in exec_module\r\n  File \"<frozen importlib._bootstrap>\", line 219, in _call_with_frames_removed\r\n  File \"/tmp/ansible_postgresql_pg_hba_payload_y9useyqu/__main__.py\", line 709, in <module>\r\n  File \"/tmp/ansible_postgresql_pg_hba_payload_y9useyqu/__main__.py\", line 696, in main\r\n  File \"/tmp/ansible_postgresql_pg_hba_payload_y9useyqu/__main__.py\", line 319, in write\r\n  File \"/tmp/ansible_postgresql_pg_hba_payload_y9useyqu/__main__.py\", line 390, in render\r\n  File \"/tmp/ansible_postgresql_pg_hba_payload_y9useyqu/__main__.py\", line 390, in <listcomp>\r\n  File \"/tmp/ansible_postgresql_pg_hba_payload_y9useyqu/__main__.py\", line 371, in get_rules\r\n  File \"/usr/lib/python3.6/ipaddress.py\", line 652, in __lt__\r\n    self, other))\r\nTypeError: 127.0.0.1/32 and ::1/128 are not of the same version\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

PLAY RECAP **********************************************************************************************************************************************************************************************************
192.168.1.110              : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

# Fixed code
def __lt__(self, other):
    """This function helps sorted to decide how to sort.

    It just checks itself against the other and decides on some key values
    if it should be sorted higher or lower in the list.
    The way it works:
    For networks, every 1 in 'netmask in binary' makes the subnet more specific.
    Therefore I chose to use prefix as the weight.
    So a single IP (/32) should have twice the weight of a /16 network.
    To keep everything in the same weight scale,
    - for ipv6, we use a weight scale of 0 (all possible ipv6 addresses) to 128 (single ip)
    - for ipv4, we use a weight scale of 0 (all possible ipv4 addresses) to 128 (single ip)
    Therefore for ipv4, we use prefixlen (0-32) * 4 for weight,
    which corresponds to ipv6 (0-128).
    """
    for orderpart in self.order:
        if orderpart == "s":
            myweight = self.source_weight()
            hisweight = other.source_weight()
            if myweight != hisweight:
                return myweight > hisweight
        elif orderpart == "d":
            myweight = self.db_weight()
            hisweight = other.db_weight()
            if myweight != hisweight:
                return myweight < hisweight
        elif orderpart == "u":
            myweight = self.user_weight()
            hisweight = other.user_weight()
            if myweight != hisweight:
                return myweight < hisweight

    try:
        return self["src"] < other["src"]
    except TypeError:
        return self.source_type_weight() < other.source_type_weight()

    errormessage = "We have two rules ({1}, {2})".format(self, other)
    errormessage += " with exact same weight. Please file a bug."
    raise PgHbaValueError(errormessage)