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.
This commit is contained in:
Serhiy Storchaka 2016-03-01 10:25:45 +02:00
parent 5f582bdec8
commit bb0dbd583b
3 changed files with 43 additions and 9 deletions

View File

@ -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))

View File

@ -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')),

View File

@ -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.