Commit 168e2fcd authored by Raymond Hettinger's avatar Raymond Hettinger

Convert docstring examples to doctests and fix

any errors that were found.  Add a usage note
to compare_networks() showing how to do the
ordering with modern python.
parent 9aaef2da
...@@ -135,16 +135,17 @@ def _collapse_address_list_recursive(addresses): ...@@ -135,16 +135,17 @@ def _collapse_address_list_recursive(addresses):
Example: Example:
ip1 = IPv4('1.1.0.0/24') >>> ip1 = IPv4('1.1.0.0/24')
ip2 = IPv4('1.1.1.0/24') >>> ip2 = IPv4('1.1.1.0/24')
ip3 = IPv4('1.1.2.0/24') >>> ip3 = IPv4('1.1.2.0/24')
ip4 = IPv4('1.1.3.0/24') >>> ip4 = IPv4('1.1.3.0/24')
ip5 = IPv4('1.1.4.0/24') >>> ip5 = IPv4('1.1.4.0/24')
ip6 = IPv4('1.1.0.1/22') >>> ip6 = IPv4('1.1.0.1/22')
_collapse_address_list_recursive([ip1, ip2, ip3, ip4, ip5, ip6]) -> >>> _collapse_address_list_recursive([ip1, ip2, ip3, ip4, ip5, ip6])
[IPv4('1.1.0.0/22'), IPv4('1.1.4.0/24')] [IPv4('1.1.0.0/22'), IPv4('1.1.4.0/24'), IPv4('1.1.0.1/22')]
Notes:
This shouldn't be called directly; it is called via This shouldn't be called directly; it is called via
collapse_address_list([]). collapse_address_list([]).
...@@ -180,7 +181,8 @@ def collapse_address_list(addresses): ...@@ -180,7 +181,8 @@ def collapse_address_list(addresses):
"""Collapse a list of IP objects. """Collapse a list of IP objects.
Example: Example:
collapse_address_list([IPv4('1.1.0.0/24'), IPv4('1.1.1.0/24')]) ->
>>> collapse_address_list([IPv4('1.1.0.0/24'), IPv4('1.1.1.0/24')])
[IPv4('1.1.0.0/23')] [IPv4('1.1.0.0/23')]
Args: Args:
...@@ -270,21 +272,20 @@ class BaseIP(object): ...@@ -270,21 +272,20 @@ class BaseIP(object):
For example: For example:
addr1 = IP('10.1.1.0/24') >>> addr1 = IP('10.1.1.0/24')
addr2 = IP('10.1.1.0/26') >>> addr2 = IP('10.1.1.0/26')
addr1.address_exclude(addr2) = >>> addr1.address_exclude(addr2)
[IP('10.1.1.64/26'), IP('10.1.1.128/25')] [IPv4('10.1.1.64/26'), IPv4('10.1.1.128/25')]
or IPv6: or IPv6:
addr1 = IP('::1/32') >>> addr1 = IP('::1/32')
addr2 = IP('::1/128') >>> addr2 = IP('::1/128')
addr1.address_exclude(addr2) = [IP('::0/128'), >>> s = addr1.address_exclude(addr2)
IP('::2/127'), >>> s[:4]
IP('::4/126'), [IPv6('::/128'), IPv6('::2/127'), IPv6('::4/126'), IPv6('::8/125')]
IP('::8/125'), >>> s[-1]
... IPv6('0:0:8000::/33')
IP('0:0:8000::/33')]
Args: Args:
other: An IP object of the same type. other: An IP object of the same type.
...@@ -373,6 +374,15 @@ class BaseIP(object): ...@@ -373,6 +374,15 @@ class BaseIP(object):
1 if self.version > other.version 1 if self.version > other.version
eg: IPv6('::1/128') > IPv4('255.255.255.0/24') eg: IPv6('::1/128') > IPv4('255.255.255.0/24')
To sort networks with sorted(), min(), max() and other tools with a
*key* argument, use the operator.attrgetter() function to extract the
relevant fields:
>>> from operator import attrgetter
>>> s = [IPv6('::1/128'), IPv4('255.255.255.0/24')]
>>> sorted(s, key=attrgetter('version', 'network', 'netmask'))
[IPv4('255.255.255.0/24'), IPv6('::1/128')]
""" """
if self.version < other.version: if self.version < other.version:
return -1 return -1
...@@ -521,19 +531,23 @@ class IPv4(BaseIP): ...@@ -521,19 +531,23 @@ class IPv4(BaseIP):
"""This class represents and manipulates 32-bit IPv4 addresses. """This class represents and manipulates 32-bit IPv4 addresses.
Attributes: [examples for IPv4('1.2.3.4/27')] >>> addr = IPv4('1.2.3.4/27')
.ip: 16909060 >>> for attr in ['ip', 'ip_ext', 'ip_ext_full', 'network', 'network_ext',
.ip_ext: '1.2.3.4' ... 'hostmask', 'hostmask_ext', 'broadcast', 'broadcast_ext',
.ip_ext_full: '1.2.3.4' ... 'netmask', 'netmask_ext', 'prefixlen']:
.network: 16909056L ... print(attr, '=', getattr(addr, attr))
.network_ext: '1.2.3.0' ip = 16909060
.hostmask: 31L (0x1F) ip_ext = 1.2.3.4
.hostmask_ext: '0.0.0.31' ip_ext_full = 1.2.3.4
.broadcast: 16909087L (0x102031F) network = 16909056
.broadcast_ext: '1.2.3.31' network_ext = 1.2.3.0
.netmask: 4294967040L (0xFFFFFFE0) hostmask = 31
.netmask_ext: '255.255.255.224' hostmask_ext = 0.0.0.31
.prefixlen: 27 broadcast = 16909087
broadcast_ext = 1.2.3.31
netmask = 4294967264
netmask_ext = 255.255.255.224
prefixlen = 27
""" """
...@@ -863,19 +877,23 @@ class IPv6(BaseIP): ...@@ -863,19 +877,23 @@ class IPv6(BaseIP):
"""This class respresents and manipulates 128-bit IPv6 addresses. """This class respresents and manipulates 128-bit IPv6 addresses.
Attributes: [examples for IPv6('2001:658:22A:CAFE:200::1/64')] >>> addr = IPv6('2001:658:22A:CAFE:200::1/64')
.ip: 42540616829182469433547762482097946625L >>> for attr in ['ip', 'ip_ext', 'ip_ext_full', 'network', 'network_ext',
.ip_ext: '2001:658:22a:cafe:200::1' ... 'hostmask', 'hostmask_ext', 'broadcast', 'broadcast_ext',
.ip_ext_full: '2001:0658:022a:cafe:0200:0000:0000:0001' ... 'netmask', 'netmask_ext', 'prefixlen']:
.network: 42540616829182469433403647294022090752L ... print(attr, '=', getattr(addr, attr))
.network_ext: '2001:658:22a:cafe::' ip = 42540616829182469433547762482097946625
.hostmask: 18446744073709551615L ip_ext = 2001:658:22a:cafe:200::1
.hostmask_ext: '::ffff:ffff:ffff:ffff' ip_ext_full = 2001:0658:022a:cafe:0200:0000:0000:0001
.broadcast: 42540616829182469451850391367731642367L network = 42540616829182469433403647294022090752
.broadcast_ext: '2001:658:22a:cafe:ffff:ffff:ffff:ffff' network_ext = 2001:658:22a:cafe::
.netmask: 340282366920938463444927863358058659840L hostmask = 18446744073709551615
.netmask_ext: 64 hostmask_ext = ::ffff:ffff:ffff:ffff
.prefixlen: 64 broadcast = 42540616829182469451850391367731642367
broadcast_ext = 2001:658:22a:cafe:ffff:ffff:ffff:ffff
netmask = 340282366920938463444927863358058659840
netmask_ext = 64
prefixlen = 64
""" """
...@@ -1367,3 +1385,8 @@ _IPV6_RFC2373_LOOPBACK = IPv6('::1') ...@@ -1367,3 +1385,8 @@ _IPV6_RFC2373_LOOPBACK = IPv6('::1')
_IPV6_RFC4291_LINK_LOCAL = IPv6('fe80::/10') _IPV6_RFC4291_LINK_LOCAL = IPv6('fe80::/10')
_IPV6_RFC3513_SITE_LOCAL = IPv6('fec0::/10') # Deprecated by RFC3879. _IPV6_RFC3513_SITE_LOCAL = IPv6('fec0::/10') # Deprecated by RFC3879.
_IPV6_RFC4193_PRIVATE = IPv6('fc00::/7') _IPV6_RFC4193_PRIVATE = IPv6('fc00::/7')
if __name__ == '__main__':
import doctest
print(doctest.testmod())
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