diff options
| author | Philipp Hagemeister <phihag@phihag.de> | 2017-12-16 21:16:38 +0100 |
|---|---|---|
| committer | Philipp Hagemeister <phihag@phihag.de> | 2017-12-16 21:16:38 +0100 |
| commit | 6d0ace0bcf06d405bf57a70c28eec5d6895cad41 (patch) | |
| tree | 7bed28ec0fee8abcbc8cfccc383d9690ceb9130f | |
| parent | 4233f21f1b461899820626d493a8ad031d0e6fc7 (diff) | |
| parent | d17c2deb1298706ac6de07eab1926905a72360a4 (diff) | |
| download | platform_external_python_ipaddress-6d0ace0bcf06d405bf57a70c28eec5d6895cad41.tar.gz platform_external_python_ipaddress-6d0ace0bcf06d405bf57a70c28eec5d6895cad41.tar.bz2 platform_external_python_ipaddress-6d0ace0bcf06d405bf57a70c28eec5d6895cad41.zip | |
Merge branch 'upstream'
| -rw-r--r-- | ipaddress.py | 46 | ||||
| -rw-r--r-- | test_ipaddress.py | 63 |
2 files changed, 69 insertions, 40 deletions
diff --git a/ipaddress.py b/ipaddress.py index f602c71..801a5fb 100644 --- a/ipaddress.py +++ b/ipaddress.py @@ -1098,33 +1098,25 @@ class _BaseNetwork(_IPAddressBase): return (self.network_address.is_multicast and self.broadcast_address.is_multicast) + @staticmethod + def _is_subnet_of(a, b): + try: + # Always false if one is v4 and the other is v6. + if a._version != b._version: + raise TypeError("%s and %s are not of the same version" (a, b)) + return (b.network_address <= a.network_address and + b.broadcast_address >= a.broadcast_address) + except AttributeError: + raise TypeError("Unable to test subnet containment " + "between %s and %s" % (a, b)) + def subnet_of(self, other): - # always false if one is v4 and the other is v6. - if self._version != other._version: - return False - # dealing with another network. - if (hasattr(other, 'network_address') and - hasattr(other, 'broadcast_address')): - return (other.network_address <= self.network_address and - other.broadcast_address >= self.broadcast_address) - # dealing with another address - else: - raise TypeError('Unable to test subnet containment with element ' - 'of type %s' % type(other)) + """Return True if this network is a subnet of other.""" + return self._is_subnet_of(self, other) def supernet_of(self, other): - # always false if one is v4 and the other is v6. - if self._version != other._version: - return False - # dealing with another network. - if (hasattr(other, 'network_address') and - hasattr(other, 'broadcast_address')): - return (other.network_address >= self.network_address and - other.broadcast_address <= self.broadcast_address) - # dealing with another address - else: - raise TypeError('Unable to test subnet containment with element ' - 'of type %s' % type(other)) + """Return True if this network is a supernet of other.""" + return self._is_subnet_of(other, self) @property def is_reserved(self): @@ -1535,7 +1527,8 @@ class IPv4Interface(IPv4Address): if address_less is NotImplemented: return NotImplemented try: - return self.network < other.network + return (self.network < other.network or + self.network == other.network and address_less) except AttributeError: # We *do* allow addresses and interfaces to be sorted. The # unassociated address is considered less than all interfaces. @@ -2227,7 +2220,8 @@ class IPv6Interface(IPv6Address): if address_less is NotImplemented: return NotImplemented try: - return self.network < other.network + return (self.network < other.network or + self.network == other.network and address_less) except AttributeError: # We *do* allow addresses and interfaces to be sorted. The # unassociated address is considered less than all interfaces. diff --git a/test_ipaddress.py b/test_ipaddress.py index 199a970..145dc1a 100644 --- a/test_ipaddress.py +++ b/test_ipaddress.py @@ -135,7 +135,7 @@ class CommonTestMixin_v4(CommonTestMixin): def test_bad_packed_length(self): def assertBadLength(length): - addr = b'0' * length + addr = b'\0' * length msg = "%r (len %d != 4) is not permitted as an IPv4 address" with self.assertAddressError(re.escape(msg % (addr, length))): self.factory(addr) @@ -155,11 +155,11 @@ class CommonTestMixin_v6(CommonTestMixin): self.assertInstancesEqual(3232235521, "::c0a8:1") def test_packed(self): - addr = (b'\0' * 12) + _compat_bytes_fromhex("00000000") + addr = b'\0'*12 + _compat_bytes_fromhex("00000000") self.assertInstancesEqual(addr, "::") - addr = (b'\0' * 12) + _compat_bytes_fromhex("c0a80001") + addr = b'\0'*12 + _compat_bytes_fromhex("c0a80001") self.assertInstancesEqual(addr, "::c0a8:1") - addr = _compat_bytes_fromhex("c0a80001") + (b'\0' * 12) + addr = _compat_bytes_fromhex("c0a80001") + b'\0'*12 self.assertInstancesEqual(addr, "c0a8:1::") def test_negative_ints_rejected(self): @@ -174,7 +174,7 @@ class CommonTestMixin_v6(CommonTestMixin): def test_bad_packed_length(self): def assertBadLength(length): - addr = b'0' * length + addr = b'\0' * length msg = "%r (len %d != 16) is not permitted as an IPv6 address" with self.assertAddressError(re.escape(msg % (addr, length))): self.factory(addr) @@ -523,7 +523,7 @@ class NetworkTestCase_v4(BaseTestCase, NetmaskTestMixin_v4): self.factory('10.0.1.0/24'))) # containee larger than container self.assertFalse( - self.factory('10.0.0.0/24').subnet_of( + self.factory('10.0.1.0/24').subnet_of( self.factory('10.0.0.0/30'))) def test_supernet_of(self): @@ -544,6 +544,20 @@ class NetworkTestCase_v4(BaseTestCase, NetmaskTestMixin_v4): self.factory('10.0.0.0/24').supernet_of( self.factory('10.0.0.0/30'))) + def test_subnet_of_mixed_types(self): + with self.assertRaises(TypeError): + ipaddress.IPv4Network('10.0.0.0/30').supernet_of( + ipaddress.IPv6Network('::1/128')) + with self.assertRaises(TypeError): + ipaddress.IPv6Network('::1/128').supernet_of( + ipaddress.IPv4Network('10.0.0.0/30')) + with self.assertRaises(TypeError): + ipaddress.IPv4Network('10.0.0.0/30').subnet_of( + ipaddress.IPv6Network('::1/128')) + with self.assertRaises(TypeError): + ipaddress.IPv6Network('::1/128').subnet_of( + ipaddress.IPv4Network('10.0.0.0/30')) + class NetmaskTestMixin_v6(CommonTestMixin_v6): """Input validation on interfaces and networks is very similar""" @@ -1543,14 +1557,35 @@ class IpaddrUnitTest(unittest.TestCase): ipaddress.ip_address('::2')) def testInterfaceComparison(self): - self.assertTrue(ipaddress.ip_interface('1.1.1.1') <= - ipaddress.ip_interface('1.1.1.1')) - self.assertTrue(ipaddress.ip_interface('1.1.1.1') <= - ipaddress.ip_interface('1.1.1.2')) - self.assertTrue(ipaddress.ip_interface('::1') <= - ipaddress.ip_interface('::1')) - self.assertTrue(ipaddress.ip_interface('::1') <= - ipaddress.ip_interface('::2')) + self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') == + ipaddress.ip_interface('1.1.1.1/24')) + self.assertTrue(ipaddress.ip_interface('1.1.1.1/16') < + ipaddress.ip_interface('1.1.1.1/24')) + self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') < + ipaddress.ip_interface('1.1.1.2/24')) + self.assertTrue(ipaddress.ip_interface('1.1.1.2/16') < + ipaddress.ip_interface('1.1.1.1/24')) + self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') > + ipaddress.ip_interface('1.1.1.1/16')) + self.assertTrue(ipaddress.ip_interface('1.1.1.2/24') > + ipaddress.ip_interface('1.1.1.1/24')) + self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') > + ipaddress.ip_interface('1.1.1.2/16')) + + self.assertTrue(ipaddress.ip_interface('::1/64') == + ipaddress.ip_interface('::1/64')) + self.assertTrue(ipaddress.ip_interface('::1/64') < + ipaddress.ip_interface('::1/80')) + self.assertTrue(ipaddress.ip_interface('::1/64') < + ipaddress.ip_interface('::2/64')) + self.assertTrue(ipaddress.ip_interface('::2/48') < + ipaddress.ip_interface('::1/64')) + self.assertTrue(ipaddress.ip_interface('::1/80') > + ipaddress.ip_interface('::1/64')) + self.assertTrue(ipaddress.ip_interface('::2/64') > + ipaddress.ip_interface('::1/64')) + self.assertTrue(ipaddress.ip_interface('::1/64') > + ipaddress.ip_interface('::2/48')) def testNetworkComparison(self): # ip1 and ip2 have the same network address |
