Add PEP 3144: IP Address Manipulation Library for the Python Standard Library.

This commit is contained in:
Brett Cannon 2009-08-18 19:26:37 +00:00
parent 399631d0a3
commit 4b8dac5847
1 changed files with 153 additions and 0 deletions

153
pep-3144.txt Normal file
View File

@ -0,0 +1,153 @@
PEP: 3144
Title: IP Address Manipulation Library for the Python Standard Library
Version: $Revision$
Last-Modified: $Date$
Author: Peter Moody <peter@hda3.com>
Discussions-To: ipaddr-py-dev@googlegroups.com
Status: Draft
Type: Standards Track
Content-Type: text/plain
Created: 13-Aug-2009
Python-Version: 3.2
Abstract:
This PEP proposes a design for a lightweight ip address manipulation module
for python.
Motivation:
Many network administrators use python in their day to day jobs. Finding a
library to assist with the common ip address manipulation tasks is easy.
Finding a good library for performing those tasks can be somewhat more
difficult. For this reason, I (like many before me) scratched an itch and
wrote my own with an emphasis on being easy to understand and fast for the
most common operations.
For context, a previous version of this library was up for inclusion in
python 3.1, see issue 3959 [1] for more information.
Rationale:
ipaddr was designed with the goal of abstracting out as much of the common
functionality as possible. As mentioned earlier, the similarities between
addresses and networks, IPV6 and IPV4 allows much code to be reused since
python allows for easy (and clean) multiple inheritance. Methods which are
specific to IPV4 or IPV6, addresses or networks are inherited from
appropriately named classes (Basev4, Basev6, BaseNet, BaseIP, etc) to
provide the full functionality of IPv4Address, IPv4Network, IPv6Address and
IPv6Network.
- Distinct IPV4 and IPV6 objects.
While there are many similarities, IPV4 and IPV6 objects are fundamentally
different. The similarities allow for easy abstraction of certain
operations which affect the bits from both in the same manner, but their
differences mean attempts to combine them into one object would be like
trying to force a round peg into a square hole (or visa versa).
- Distinct network and address objects.
Many people think of IP addresses and IP networks as synonymous, while they
are however, distinct. An IPV4 address is a single 32 bit number while the
IPV4 address assigned to a networked computer is a 32 bit address and
associated network. Similarly, an IPV6 address is a 128 bit number while
an IPV6 address assigned to a networked computer is a 128 bit number and
associated network information. The similarities leads to easy abstraction
of some methods and properties, but there are obviously a number of
address/network specific properties which require they be distinct. For
instance, IP networks contain network address (the base address of the
network), broadcast addresses (the upper end of the network, also the
address to which every machine on a given network is supposed listen, hence
the name broadcast), supernetworks and subnetworks, etc. The individual
property addresses in an IP network obviously don't have the same
properties, they're simply 32 or 128 bit numbers.
- Lazy evaluation combined with aggressive caching of network elements.
(the following example is for IPv6Network objects but the exact same
properties apply to IPv6Network objects).
As mentioned, an IP network object is defined by a number of properties.
The object
>>> IPv4Network('1.1.1.0/24')
has a number of IPv4Address properties
>>> o = ipaddr.IPv4Network('1.1.1.0/24')
>>> o.network
IPv4Address('1.1.1.0')
>>> o.broadcast
IPv4Address('1.1.1.255')
>>> o.network
IPv4Address('1.1.1.0')
>>> o.hostmask
IPv4Address('0.0.0.255')
If we were to compute them all at object creation time, we would incur a
non-negligible performance hit. Since these properties are required to
define the object completely but their values aren't always of interest to
the programmer, their computation should be done only when requested.
However, in order to avoid the performance hit in the case where one
attribute for a particular object is requested repeatedly (and continuously
recomputed), the results of the first computation should be cached and only
re-generated should the object properties change. The network properties
would change if, for instance, the prefix length was changed, resulting in
either a larger (decreasing prefix length) or a smaller (increasing prefix
length) network.
- Treat network elements as lists (in so far as it's possible).
Treating IP networks as lists is a natural extension from viewing the
network as a series of individual ip addresses. Most of the standard list
methods should be implemented and should behave in a manner that would be
consistent if the IP network object were actually a list of strings or
integers. The methods which actually modify a lists contents don't extend
as well to this model (__add__, __iadd__, __sub__, __isub__, etc) but
others (__contains__, __iter__, etc) work quite nicely. It should be noted
that __len__ doesn't work as expected since python internals has this
limited to a 32 bit integer and it would need to be at least 128 bits to
work with IPV6.
- Lightweight.
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.
Reference Implementation:
A reference implementation is available at:
http://ipaddr-py.googlecode.com/svn/branches/2.0.x
References:
[1] http://bugs.python.org/issue3959
Copyright:
This document has been placed in the public domain.
Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
coding: utf-8
End: