timmerk / ipaddr-py

Automatically exported from code.google.com/p/ipaddr-py
0 stars 0 forks source link

IPv*Interface objects in the same network but different addresses hash to the same value and compare as equal #104

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
Using python 2.7 with the 3144 branch of the ipaddr module on Linux:

>>> import ipaddr as ipaddress
>>> addr1 = ipaddress.ip_interface('10.1.1.1/24')
>>> addr2 = ipaddress.ip_interface('10.1.1.2/24')
>>> addr1 == addr2
True                                         <==== should be False
>>> hash(addr1)
4127129088
>>> hash(addr2)
4127129088                                   <==== should be different than 
hash(addr1)

What is the expected output? What do you see instead?
addr1 and addr2 should not hash to the same value because they represent 
different addresses.  The implementation for IPv4Interface.__hash__ and 
IPv6Interface.__hash__ in python 3.3 found at 
http://hg.python.org/cpython/file/default/Lib/ipaddress.py includes the IP in 
the calculation:

    def __hash__(self):
        return self._ip ^ self._prefixlen ^ int(self.network.network_address)

This would cause 10.1.1.1/24 and 10.1.1.2/24 to hash to different values.

The __eq__ method also incorporates the IP in the calculation:

    def __eq__(self, other):
        address_equal = IPv4Address.__eq__(self, other)
        if not address_equal or address_equal is NotImplemented:
            return address_equal
        try:
            return self.network == other.network
        except AttributeError:
            # An interface with an associated network is NOT the
            # same as an unassociated address. That's why the hash
            # takes the extra info into account.
            return False

The same goes for __lt__.

Using python 3.3.1:
>>> import ipaddress
>>> addr1 = ipaddress.ip_interface('10.1.1.1/24')
>>> addr2 = ipaddress.ip_interface('10.1.1.2/24')
>>> addr1 == addr2
False
>>> hash(addr1)
25
>>> hash(addr2)
26

Original issue reported on code.google.com by tbea...@gmail.com on 13 May 2013 at 8:03