Commit bb0dbd58 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #26457: Fixed the subnets() methods in IP network classes for the case

when resulting prefix length is equal to maximal prefix length.
Based on patch by Xiang Zhang.
parent 5f582bde
......@@ -740,21 +740,21 @@ class _BaseNetwork(_IPAddressBase):
addr1 = ip_network('192.0.2.0/28')
addr2 = ip_network('192.0.2.1/32')
addr1.address_exclude(addr2) =
list(addr1.address_exclude(addr2)) =
[IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'),
IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')]
IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')]
or IPv6:
addr1 = ip_network('2001:db8::1/32')
addr2 = ip_network('2001:db8::1/128')
addr1.address_exclude(addr2) =
list(addr1.address_exclude(addr2)) =
[ip_network('2001:db8::1/128'),
ip_network('2001:db8::2/127'),
ip_network('2001:db8::4/126'),
ip_network('2001:db8::8/125'),
...
ip_network('2001:db8:8000::/33')]
ip_network('2001:db8::2/127'),
ip_network('2001:db8::4/126'),
ip_network('2001:db8::8/125'),
...
ip_network('2001:db8:8000::/33')]
Args:
other: An IPv4Network or IPv6Network object of the same type.
......@@ -916,7 +916,7 @@ class _BaseNetwork(_IPAddressBase):
new_prefixlen, self))
start = int(self.network_address)
end = int(self.broadcast_address)
end = int(self.broadcast_address) + 1
step = (int(self.hostmask) + 1) >> prefixlen_diff
for new_addr in range(start, end, step):
current = self.__class__((new_addr, new_prefixlen))
......
......@@ -1066,6 +1066,26 @@ class IpaddrUnitTest(unittest.TestCase):
'2001:658:22a:cafe:8000::/66',
'2001:658:22a:cafe:c000::/66'])
def testGetSubnets3(self):
subnets = [str(x) for x in self.ipv4_network.subnets(8)]
self.assertEqual(subnets[:3],
['1.2.3.0/32', '1.2.3.1/32', '1.2.3.2/32'])
self.assertEqual(subnets[-3:],
['1.2.3.253/32', '1.2.3.254/32', '1.2.3.255/32'])
self.assertEqual(len(subnets), 256)
ipv6_network = ipaddress.IPv6Network('2001:658:22a:cafe::/120')
subnets = [str(x) for x in ipv6_network.subnets(8)]
self.assertEqual(subnets[:3],
['2001:658:22a:cafe::/128',
'2001:658:22a:cafe::1/128',
'2001:658:22a:cafe::2/128'])
self.assertEqual(subnets[-3:],
['2001:658:22a:cafe::fd/128',
'2001:658:22a:cafe::fe/128',
'2001:658:22a:cafe::ff/128'])
self.assertEqual(len(subnets), 256)
def testSubnetFailsForLargeCidrDiff(self):
self.assertRaises(ValueError, list,
self.ipv4_interface.network.subnets(9))
......@@ -1670,6 +1690,7 @@ class IpaddrUnitTest(unittest.TestCase):
addr3 = ipaddress.ip_network('10.2.1.0/24')
addr4 = ipaddress.ip_address('10.1.1.0')
addr5 = ipaddress.ip_network('2001:db8::0/32')
addr6 = ipaddress.ip_network('10.1.1.5/32')
self.assertEqual(sorted(list(addr1.address_exclude(addr2))),
[ipaddress.ip_network('10.1.1.64/26'),
ipaddress.ip_network('10.1.1.128/25')])
......@@ -1677,6 +1698,15 @@ class IpaddrUnitTest(unittest.TestCase):
self.assertRaises(TypeError, list, addr1.address_exclude(addr4))
self.assertRaises(TypeError, list, addr1.address_exclude(addr5))
self.assertEqual(list(addr1.address_exclude(addr1)), [])
self.assertEqual(sorted(list(addr1.address_exclude(addr6))),
[ipaddress.ip_network('10.1.1.0/30'),
ipaddress.ip_network('10.1.1.4/32'),
ipaddress.ip_network('10.1.1.6/31'),
ipaddress.ip_network('10.1.1.8/29'),
ipaddress.ip_network('10.1.1.16/28'),
ipaddress.ip_network('10.1.1.32/27'),
ipaddress.ip_network('10.1.1.64/26'),
ipaddress.ip_network('10.1.1.128/25')])
def testHash(self):
self.assertEqual(hash(ipaddress.ip_interface('10.1.1.0/24')),
......
......@@ -84,6 +84,10 @@ Core and Builtins
Library
-------
- Issue #26457: Fixed the subnets() methods in IP network classes for the case
when resulting prefix length is equal to maximal prefix length.
Based on patch by Xiang Zhang.
- Issue #26385: Remove the file if the internal open() call in
NamedTemporaryFile() fails. Patch by Silent Ghost.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment