[Python-checkins] r74557 - peps/trunk/pep-3144.txt
brett.cannon
python-checkins at python.org
Fri Aug 28 00:51:15 CEST 2009
Author: brett.cannon
Date: Fri Aug 28 00:51:15 2009
New Revision: 74557
Log:
Updates to PEP 3144 by Peter Moody.
Modified:
peps/trunk/pep-3144.txt
Modified: peps/trunk/pep-3144.txt
==============================================================================
--- peps/trunk/pep-3144.txt (original)
+++ peps/trunk/pep-3144.txt Fri Aug 28 00:51:15 2009
@@ -84,29 +84,85 @@
While some network programmers will undoubtedly want more than this library
provides, keeping the functionality to strictly what's required from a IP
address manipulation module is critical to keeping the code fast, easily
- comprehensible and extensible. It's important to note that this design
- doesn't prevent subclassing or otherwise extending to meet the unforseen
- needs.
+ comprehensible and extensible. I've tried to provide enough options in
+ terms of functionality to allow the developer to easily do their work
+ without needlessly cluttering the library. Finally, It's important to note
+ that this design doesn't prevent subclassing or otherwise extending to meet
+ the unforeseen needs.
Specification:
A slightly more detailed look at the library follows.
+ - Design
+
+ ipaddr has four main classes most people will use:
+
+ 1. IPv4Address. (eg, '192.168.1.1')
+ 2. IPv4Network (eg, '192.168.0.0/16')
+ 3. IPv6Address (eg, '::1')
+ 4. IPv6Network (eg, '2001::/32')
+
+ Most of the operations a network administrator performs on networks are
+ similar for both IPv4 and IPv6 networks. Ie. finding subnets, supernets,
+ determining if an address is contained in a given network, etc. Similarly,
+ both addresses and networks (of the same ip version!) have much in common;
+ the process for turning a given 32 or 128 bit number into a human readable
+ string notation, determining if the ip is within the valid specified range,
+ etc. Finally, there are some pythonic abstractions which are valid for all
+ addresses and networks, both IPv4 and IPv6. In short, there is common
+ functionality shared between (ipaddr class names in parentheses):
+
+ 1. all IP addresses and networks, both IPv4 and IPv6. (IPAddrBase)
+
+ 2. all IP addresses of both versions. (BaseIP)
+
+ 3. all IP networks of both version. (BaseNet)
+
+ 4. all IPv4 objects, both addresses and networks. (BaseV4)
+
+ 5. all IPv6 objects, both addresses and networks. (BaseV6)
+
+ Seeing this as a clear hierarchy is important for recognizing how much
+ code is common between the four main classes. For this reason, ipaddr uses
+ class inheritance to abstract out as much common code is possible and
+ appropriate. This lack of duplication and very clean layout also makes
+ the job of the developer much easier should they need to debug code (either
+ theirs or mine).
+
+ Knowing that there might be cases where the developer doesn't so much care
+ as to the types of IP they might be receiving, ipaddr comes with two
+ important helper functions, IPAddress() and IPNetwork(). These, as you
+ might guess, return the appropriately typed address or network objects for
+ the given argument.
+
+ Finally, this distinction between IPv4 and IPv6 IP versions means that
+ comparison operations on them return TypeError for py3k per Ordering
+ Comparisons [2]. In practice, this shouldn't pose a problem for the
+ developer who can easily write:
+
+ v4 = [x for x in mixed_list if x._version == 4]
+ v6 = [x for x in mixed_list if x._version == 6]
+
+ # perform operations on v4 and v6 here.
+
+ return v4_return + v6_return
+
- Multiple ways of displaying an IP Address.
Not everyone will want to display the same information in the same format;
IP addresses in cisco syntax are represented by network/hostmask, junipers
are (network/IP)/prefixlength and IPTables are (network/IP)/(prefixlength/
- netmask). The ipaddr library provides mulitple ways to display an address.
+ netmask). The ipaddr library provides multiple ways to display an address.
- In [1]: ipaddr.IP('1.1.1.1').with_prefixlen
+ In [1]: IPNetwork('1.1.1.1').with_prefixlen
Out[1]: '1.1.1.1/32'
- In [1]: ipaddr.IP('1.1.1.1').with_netmask
+ In [1]: IPNetwork('1.1.1.1').with_netmask
Out[1]: '1.1.1.1/255.255.255.255'
- In [1]: ipaddr.IP('1.1.1.1').with_hostmask
+ In [1]: IPNetwork('1.1.1.1').with_hostmask
Out[1]: '1.1.1.1/0.0.0.0'
the same applies to IPv6
@@ -123,7 +179,7 @@
has a number of IPv4Address properties
- In [1]: o = ipaddr.IPv4Network('1.1.1.0/24')
+ In [1]: o = IPv4Network('1.1.1.0/24')
In [2]: o.network
Out[2]: IPv4Address('1.1.1.0')
@@ -144,7 +200,7 @@
- Address list summarization.
- ipaddr supports easy summarization of lists of possibly contigious
+ ipaddr supports easy summarization of lists of possibly contiguous
addresses, as this is something network administrators constantly find
themselves doing. This currently works in a number of ways.
@@ -153,24 +209,24 @@
Given a list of networks, ipaddr will collapse the list into the smallest
possible list of networks that wholey contain the addresses supplied.
- In [1]: ipaddr.collapse_address_list([ipaddr.IP('1.1.0.0/24'),
- ...: ipaddr.IP('1.1.1.0/24')])
+ In [1]: collapse_address_list([IPNetwork('1.1.0.0/24'),
+ ...: IPNetwork('1.1.1.0/24')])
Out[1]: [IPv4Network('1.1.0.0/23')]
more elaborately:
- In [1]: ipaddr.collapse_address_list([ipaddr.IP(x) \
- ...: for x in ipaddr.IP('1.1.0.0/23')])
+ In [1]: collapse_address_list([IPNetwork(x) for x in
+ ...: IPNetwork('1.1.0.0/23')])
Out[1]: [IPv4Network('1.1.0.0/23')]
- 2. summarize_address_range(first, last). (in a pending change list [2])
+ 2. summarize_address_range(first, last).
Given a start and end address, ipaddr will provide the smallest number of
networks to cover the given range.
- In [1]: ipaddr.summarize_address_range(ipaddr.IPv4Address('1.1.1.0'),
- ...: ipaddr.IPv4Address('2.2.2.0'))
+ In [1]: summarize_address_range(IPv4Address('1.1.1.0'),
+ ...: IPv4Address('2.2.2.0'))
Out[1]:
[IPv4Network('1.1.1.0/24'),
IPv4Network('1.1.2.0/23'),
@@ -198,7 +254,7 @@
ipaddr performs this exclusion equally well for IPv4 and IPv6 networks
and collapses the resulting address list.
- In [1]: ipaddr.IP('1.1.0.0/15').address_exclude(ipaddr.IP('1.1.1.0/24'))
+ In [1]: IPNetwork('1.1.0.0/15').address_exclude(IPNetwork('1.1.1.0/24'))
Out[1]:
[IPv4Network('1.0.0.0/16'),
IPv4Network('1.1.0.0/24'),
@@ -210,7 +266,7 @@
IPv4Network('1.1.64.0/18'),
IPv4Network('1.1.128.0/17')]
- In [1]: ipaddr.IP('::1/96').address_exclude(ipaddr.IP('::1/112'))
+ In [1]: IPNewtork('::1/96').address_exclude(IPNetwork('::1/112'))
Out[1]:
[IPv6Network('::1:0/112'),
IPv6Network('::2:0/111'),
@@ -235,16 +291,16 @@
BaseV6._compress_hextets), but ipaddr makes both the compressed and the
exploded representations available.
- In [1]: ipaddr.IP('::1').compressed
+ In [1]: IPNetwork('::1').compressed
Out[1]: '::1/128'
- In [2]: ipaddr.IP('::1').exploded
+ In [2]: IPNetwork('::1').exploded
Out[2]: '0000:0000:0000:0000:0000:0000:0000:1/128'
- In [3]: ipaddr.IPv6Address('::1').exploded
+ In [3]: IPv6Address('::1').exploded
Out[3]: '0000:0000:0000:0000:0000:0000:0000:0001'
- In [4]: ipaddr.IPv6Address('::1').compressed
+ In [4]: IPv6Address('::1').compressed
Out[4]: '::1'
(the same methods exist for IPv4 networks and addresses, but they're
@@ -260,7 +316,7 @@
References:
[1] http://bugs.python.org/issue3959
- [2] http://codereview.appspot.com/67107
+ [2] http://docs.python.org/dev/3.0/whatsnew/3.0.html#ordering-comparisons
[3] http://codereview.appspot.com/110044
More information about the Python-checkins
mailing list