PEP: 3144 Title: IP Address Manipulation Library for the Python Standard
Library Version: $Revision$ Last-Modified: $Date$ Author: Peter Moody
<pmoody@google.com> BDFL-Delegate: Alyssa Coghlan Discussions-To:
ipaddr-py-dev@googlegroups.com Status: Final Type: Standards Track
Content-Type: text/x-rst Created: 06-Feb-2012 Python-Version: 3.3
Resolution:
https://mail.python.org/pipermail/python-dev/2012-May/119474.html

Abstract

This PEP proposes a design and for an IP address manipulation module for
python.

PEP Acceptance

This PEP was accepted by Alyssa Coghlan on the 15th of May, 2012.

Motivation

Several very good IP address modules for python already exist. The truth
is that all of them struggle with the balance between adherence to
Pythonic principals and the shorthand upon which network engineers and
administrators rely. ipaddress aims to strike the right balance.

Rationale

The existence of several Python IP address manipulation modules is
evidence of an outstanding need for the functionality this module seeks
to provide.

Background

PEP 3144 and ipaddr have been up for inclusion before. The version of
the library specified here is backwards incompatible with the version on
PyPI and the one which was discussed before. In order to avoid confusing
users of the current ipaddr, I've renamed this version of the library
ipaddress.

The main differences between ipaddr and ipaddress are:

-   ipaddress *Network classes are equivalent to the ipaddr *Network
    class counterparts with the strict flag set to True.
-   ipaddress *Interface classes are equivalent to the ipaddr *Network
    class counterparts with the strict flag set to False.
-   The factory functions in ipaddress were renamed to disambiguate them
    from classes.
-   A few attributes were renamed to disambiguate their purpose as well.
    (eg. network, network_address)
-   A number of methods and functions which returned containers in
    ipaddr now return iterators. This includes subnets, address_exclude,
    summarize_address_range and collapse_address_list.

Due to the backwards incompatible API changes between ipaddress and
ipaddr, the proposal is to add the module using the new provisional API
status:

-   http://docs.python.org/dev/glossary.html#term-provisional-package

Relevant messages on python-dev:

-   https://mail.python.org/pipermail/python-dev/2012-January/116016.html
-   https://mail.python.org/pipermail/python-dev/2012-February/116656.html
-   https://mail.python.org/pipermail/python-dev/2012-February/116688.html

Specification

The ipaddr module defines a total of 6 new public classes, 3 for
manipulating IPv4 objects and 3 for manipulating IPv6 objects. The
classes are as follows:

-   IPv4Address/IPv6Address - These define individual addresses, for
    example the IPv4 address returned by an A record query for
    www.google.com (74.125.224.84) or the IPv6 address returned by a
    AAAA record query for ipv6.google.com (2001:4860:4001:801::1011).
-   IPv4Network/IPv6Network - These define networks or groups of
    addresses, for example the IPv4 network reserved for multicast use
    (224.0.0.0/4) or the IPv6 network reserved for multicast (ff00::/8,
    wow, that's big).
-   IPv4Interface/IPv6Interface - These hybrid classes refer to an
    individual address on a given network. For example, the IPV4 address
    192.0.2.1 on the network 192.0.2.0/24 could be referred to as
    192.0.2.1/24. Likewise, the IPv6 address 2001:DB8::1 on the network
    2001:DB8::/96 could be referred to as 2001:DB8::1/96. It's very
    common to refer to addresses assigned to computer network interfaces
    like this, hence the Interface name.

All IPv4 classes share certain characteristics and methods; the number
of bits needed to represent them, whether or not they belong to certain
special IPv4 network ranges, etc. Similarly, all IPv6 classes share
characteristics and methods.

ipaddr makes extensive use of inheritance to avoid code duplication as
much as possible. The parent classes are private, but they are outlined
here:

-   _IPAddrBase - Provides methods common to all ipaddr objects.
-   _BaseAddress - Provides methods common to IPv4Address and
    IPv6Address.
-   _BaseInterface - Provides methods common to IPv4Interface and
    IPv6Interface, as well as IPv4Network and IPv6Network (ipaddr treats
    the Network classes as a special case of Interface).
-   _BaseV4 - Provides methods and variables (eg, _max_prefixlen) common
    to all IPv4 classes.
-   _BaseV6 - Provides methods and variables common to all IPv6 classes.

Comparisons between objects of differing IP versions results in a
TypeError[1]. Additionally, comparisons of objects with different _Base
parent classes results in a TypeError. The effect of the _Base parent
class limitation is that IPv4Interface's can be compared to
IPv4Network's and IPv6Interface's can be compared to IPv6Network's.

Reference Implementation

The current reference implementation can be found at:

http://code.google.com/p/ipaddress-py/source/browse/ipaddress.py

Or see the tarball to include the README and unittests.
http://code.google.com/p/ipaddress-py/downloads/detail?name=ipaddress-1.0.tar.gz

More information about using the reference implementation can be found
at: http://code.google.com/p/ipaddr-py/wiki/Using3144

References

Copyright

This document has been placed in the public domain.

[1] Appealing to authority is a logical fallacy, but Vint Cerf is an
authority who can't be ignored. Full text of the email follows:

  I have seen a substantial amount of traffic about IPv4 and IPv6
  comparisons and the general consensus is that these are not
  comparable.

  If we were to take a very simple minded view, we might treat these as
  pure integers in which case there is an ordering but not a useful one.

  In the IPv4 world, "length" is important because we take longest (most
  specific) address first for routing. Length is determine by the mask,
  as you know.

  Assuming that the same style of argument works in IPv6, we would have
  to conclude that treating an IPv6 value purely as an integer for
  comparison with IPv4 would lead to some really strange results.

  All of IPv4 space would lie in the host space of 0::0/96 prefix of
  IPv6. For any useful interpretation of IPv4, this is a non-starter.

  I think the only sensible conclusion is that IPv4 values and IPv6
  values should be treated as non-comparable.

  Vint