Add PEP 3144: IP Address Manipulation Library for the Python Standard Library.
This commit is contained in:
parent
399631d0a3
commit
4b8dac5847
|
@ -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:
|
Loading…
Reference in New Issue