summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpmoody@google.com <pmoody@google.com@09200d28-7f98-11dd-ad27-0f66e57d2035>2009-11-02 19:25:53 +0000
committerpmoody@google.com <pmoody@google.com@09200d28-7f98-11dd-ad27-0f66e57d2035>2009-11-02 19:25:53 +0000
commit8dcd78d2918b49cd03ea3020ca0c841c474f358f (patch)
tree26d8cf1c22b9adbfd782160bec0c35d1b279fdc1
parentf82ffdc8d295d88375b73fc4e673bfb2b5a5dde4 (diff)
downloadipaddr-py-8dcd78d2918b49cd03ea3020ca0c841c474f358f.tar.gz
+ provide an iterator for looping through subnets. most useful
for *large* subnets, like v6 subnets. patch by Marco Giutsi. git-svn-id: https://ipaddr-py.googlecode.com/svn@124 09200d28-7f98-11dd-ad27-0f66e57d2035
-rw-r--r--trunk/ipaddr.py22
-rwxr-xr-xtrunk/ipaddr_test.py3
2 files changed, 17 insertions, 8 deletions
diff --git a/trunk/ipaddr.py b/trunk/ipaddr.py
index b395bc4..8b46200 100644
--- a/trunk/ipaddr.py
+++ b/trunk/ipaddr.py
@@ -867,11 +867,12 @@ class _BaseNet(_IPAddrBase):
prefixlen = self._prefixlen
return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen))
- def subnet(self, prefixlen_diff=1, new_prefix=None):
+ def iter_subnets(self, prefixlen_diff=1, new_prefix=None):
"""The subnets which join to make the current subnet.
In the case that self contains only one IP
- (self._prefixlen == 32), return a list with just ourself.
+ (self._prefixlen == 32 for IPv4 or self._prefixlen == 128
+ for IPv6), return a list with just ourself.
Args:
prefixlen_diff: An integer, the amount the prefix length
@@ -882,7 +883,7 @@ class _BaseNet(_IPAddrBase):
This should not be set if prefixlen_diff is also set.
Returns:
- A list of IPv6 objects.
+ An iterator of IPv(4|6) objects.
Raises:
PrefixlenDiffInvalidError: The prefixlen_diff is too small
@@ -893,7 +894,8 @@ class _BaseNet(_IPAddrBase):
"""
if self._prefixlen == self._max_prefixlen:
- return [self]
+ yield self
+ return
if new_prefix is not None:
if new_prefix < self._prefixlen:
@@ -914,18 +916,22 @@ class _BaseNet(_IPAddrBase):
first = IPNetwork('%s/%s' % (str(self.network),
str(self._prefixlen + prefixlen_diff)),
version=self._version)
- subnets = [first]
+
+ yield first
current = first
while True:
broadcast = current.broadcast
if broadcast == self.broadcast:
- break
+ return
new_addr = IPAddress(int(broadcast) + 1, version=self._version)
current = IPNetwork('%s/%s' % (str(new_addr), str(new_prefixlen)),
version=self._version)
- subnets.append(current)
- return subnets
+ yield current
+
+ def subnet(self, prefixlen_diff=1, new_prefix=None):
+ """Return a list of subnets, rather than an interator."""
+ return list(self.iter_subnets(prefixlen_diff, new_prefix))
def supernet(self, prefixlen_diff=1, new_prefix=None):
"""The supernet containing the current network.
diff --git a/trunk/ipaddr_test.py b/trunk/ipaddr_test.py
index 5dab626..19a371e 100755
--- a/trunk/ipaddr_test.py
+++ b/trunk/ipaddr_test.py
@@ -215,6 +215,9 @@ class IpaddrUnitTest(unittest.TestCase):
self.assertEqual(self.ipv6.supernet(prefixlen_diff=2),
self.ipv6.supernet(new_prefix=62))
+ def testIterSubnets(self):
+ self.assertEqual(self.ipv4.subnet(), list(self.ipv4.iter_subnets()))
+ self.assertEqual(self.ipv6.subnet(), list(self.ipv6.iter_subnets()))
def testFancySubnetting(self):
self.assertEqual(sorted(self.ipv4.subnet(prefixlen_diff=3)),