[Python-checkins] cpython (3.5): Issue #26457: Fixed the subnets() methods in IP network classes for the case

serhiy.storchaka python-checkins at python.org
Tue Mar 1 03:26:29 EST 2016


https://hg.python.org/cpython/rev/6d6c0a7b71f5
changeset:   100377:6d6c0a7b71f5
branch:      3.5
parent:      100375:ca81e799960c
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Tue Mar 01 10:25:45 2016 +0200
summary:
  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.

files:
  Lib/ipaddress.py           |  18 +++++++-------
  Lib/test/test_ipaddress.py |  30 ++++++++++++++++++++++++++
  Misc/NEWS                  |   4 +++
  3 files changed, 43 insertions(+), 9 deletions(-)


diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py
--- a/Lib/ipaddress.py
+++ b/Lib/ipaddress.py
@@ -740,21 +740,21 @@
 
             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 @@
                     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))
diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py
--- a/Lib/test/test_ipaddress.py
+++ b/Lib/test/test_ipaddress.py
@@ -1066,6 +1066,26 @@
              '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 @@
         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 @@
         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')),
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -84,6 +84,10 @@
 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.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list