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,7 +740,7 @@ class _BaseNetwork(_IPAddressBase): ...@@ -740,7 +740,7 @@ class _BaseNetwork(_IPAddressBase):
addr1 = ip_network('192.0.2.0/28') addr1 = ip_network('192.0.2.0/28')
addr2 = ip_network('192.0.2.1/32') 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.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')]
...@@ -748,7 +748,7 @@ class _BaseNetwork(_IPAddressBase): ...@@ -748,7 +748,7 @@ class _BaseNetwork(_IPAddressBase):
addr1 = ip_network('2001:db8::1/32') addr1 = ip_network('2001:db8::1/32')
addr2 = ip_network('2001:db8::1/128') 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::1/128'),
ip_network('2001:db8::2/127'), ip_network('2001:db8::2/127'),
ip_network('2001:db8::4/126'), ip_network('2001:db8::4/126'),
...@@ -916,7 +916,7 @@ class _BaseNetwork(_IPAddressBase): ...@@ -916,7 +916,7 @@ class _BaseNetwork(_IPAddressBase):
new_prefixlen, self)) new_prefixlen, self))
start = int(self.network_address) start = int(self.network_address)
end = int(self.broadcast_address) end = int(self.broadcast_address) + 1
step = (int(self.hostmask) + 1) >> prefixlen_diff step = (int(self.hostmask) + 1) >> prefixlen_diff
for new_addr in range(start, end, step): for new_addr in range(start, end, step):
current = self.__class__((new_addr, new_prefixlen)) current = self.__class__((new_addr, new_prefixlen))
......
...@@ -1066,6 +1066,26 @@ class IpaddrUnitTest(unittest.TestCase): ...@@ -1066,6 +1066,26 @@ class IpaddrUnitTest(unittest.TestCase):
'2001:658:22a:cafe:8000::/66', '2001:658:22a:cafe:8000::/66',
'2001:658:22a:cafe:c000::/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): def testSubnetFailsForLargeCidrDiff(self):
self.assertRaises(ValueError, list, self.assertRaises(ValueError, list,
self.ipv4_interface.network.subnets(9)) self.ipv4_interface.network.subnets(9))
...@@ -1670,6 +1690,7 @@ class IpaddrUnitTest(unittest.TestCase): ...@@ -1670,6 +1690,7 @@ class IpaddrUnitTest(unittest.TestCase):
addr3 = ipaddress.ip_network('10.2.1.0/24') addr3 = ipaddress.ip_network('10.2.1.0/24')
addr4 = ipaddress.ip_address('10.1.1.0') addr4 = ipaddress.ip_address('10.1.1.0')
addr5 = ipaddress.ip_network('2001:db8::0/32') 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))), self.assertEqual(sorted(list(addr1.address_exclude(addr2))),
[ipaddress.ip_network('10.1.1.64/26'), [ipaddress.ip_network('10.1.1.64/26'),
ipaddress.ip_network('10.1.1.128/25')]) ipaddress.ip_network('10.1.1.128/25')])
...@@ -1677,6 +1698,15 @@ class IpaddrUnitTest(unittest.TestCase): ...@@ -1677,6 +1698,15 @@ class IpaddrUnitTest(unittest.TestCase):
self.assertRaises(TypeError, list, addr1.address_exclude(addr4)) self.assertRaises(TypeError, list, addr1.address_exclude(addr4))
self.assertRaises(TypeError, list, addr1.address_exclude(addr5)) self.assertRaises(TypeError, list, addr1.address_exclude(addr5))
self.assertEqual(list(addr1.address_exclude(addr1)), []) 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): def testHash(self):
self.assertEqual(hash(ipaddress.ip_interface('10.1.1.0/24')), self.assertEqual(hash(ipaddress.ip_interface('10.1.1.0/24')),
......
...@@ -84,6 +84,10 @@ Core and Builtins ...@@ -84,6 +84,10 @@ Core and Builtins
Library 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 - Issue #26385: Remove the file if the internal open() call in
NamedTemporaryFile() fails. Patch by Silent Ghost. 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