CINXE.COM
PEP 3144 – IP Address Manipulation Library for the Python Standard Library | peps.python.org
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="color-scheme" content="light dark"> <title>PEP 3144 – IP Address Manipulation Library for the Python Standard Library | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-3144/"> <link rel="stylesheet" href="../_static/style.css" type="text/css"> <link rel="stylesheet" href="../_static/mq.css" type="text/css"> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light"> <link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark"> <link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss"> <meta property="og:title" content='PEP 3144 – IP Address Manipulation Library for the Python Standard Library | peps.python.org'> <meta property="og:description" content="This PEP proposes a design and for an IP address manipulation module for python."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-3144/"> <meta property="og:site_name" content="Python Enhancement Proposals (PEPs)"> <meta property="og:image" content="https://peps.python.org/_static/og-image.png"> <meta property="og:image:alt" content="Python PEPs"> <meta property="og:image:width" content="200"> <meta property="og:image:height" content="200"> <meta name="description" content="This PEP proposes a design and for an IP address manipulation module for python."> <meta name="theme-color" content="#3776ab"> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all"> <title>Following system colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="9"></circle> <path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path> </svg> </symbol> <symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all"> <title>Selected dark colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path> </svg> </symbol> <symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all"> <title>Selected light colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="5"></circle> <line x1="12" y1="1" x2="12" y2="3"></line> <line x1="12" y1="21" x2="12" y2="23"></line> <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line> <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line> <line x1="1" y1="12" x2="3" y2="12"></line> <line x1="21" y1="12" x2="23" y2="12"></line> <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line> <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line> </svg> </symbol> </svg> <script> document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto" </script> <section id="pep-page-section"> <header> <h1>Python Enhancement Proposals</h1> <ul class="breadcrumbs"> <li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> » </li> <li><a href="../pep-0000/">PEP Index</a> » </li> <li>PEP 3144</li> </ul> <button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())"> <svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg> <svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg> <svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg> <span class="visually-hidden">Toggle light / dark / auto colour theme</span> </button> </header> <article> <section id="pep-content"> <h1 class="page-title">PEP 3144 – IP Address Manipulation Library for the Python Standard Library</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Peter Moody <pmoody at google.com></dd> <dt class="field-even">BDFL-Delegate<span class="colon">:</span></dt> <dd class="field-even">Alyssa Coghlan</dd> <dt class="field-odd">Discussions-To<span class="colon">:</span></dt> <dd class="field-odd"><a class="reference external" href="https://groups.google.com/g/ipaddr-py-dev">ipaddr-py-dev@googlegroups.com</a></dd> <dt class="field-even">Status<span class="colon">:</span></dt> <dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd> <dt class="field-odd">Type<span class="colon">:</span></dt> <dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd> <dt class="field-even">Created<span class="colon">:</span></dt> <dd class="field-even">06-Feb-2012</dd> <dt class="field-odd">Python-Version<span class="colon">:</span></dt> <dd class="field-odd">3.3</dd> <dt class="field-even">Resolution<span class="colon">:</span></dt> <dd class="field-even"><a class="reference external" href="https://mail.python.org/pipermail/python-dev/2012-May/119474.html">Python-Dev message</a></dd> </dl> <hr class="docutils" /> <section id="contents"> <details><summary>Table of Contents</summary><ul class="simple"> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#pep-acceptance">PEP Acceptance</a></li> <li><a class="reference internal" href="#motivation">Motivation</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#background">Background</a></li> <li><a class="reference internal" href="#specification">Specification</a></li> <li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li> <li><a class="reference internal" href="#references">References</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> </details></section> <section id="abstract"> <h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2> <p>This PEP proposes a design and for an IP address manipulation module for python.</p> </section> <section id="pep-acceptance"> <h2><a class="toc-backref" href="#pep-acceptance" role="doc-backlink">PEP Acceptance</a></h2> <p>This PEP was accepted by Alyssa Coghlan on the 15th of May, 2012.</p> </section> <section id="motivation"> <h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2> <p>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. <code class="docutils literal notranslate"><span class="pre">ipaddress</span></code> aims to strike the right balance.</p> </section> <section id="rationale"> <h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2> <p>The existence of several Python IP address manipulation modules is evidence of an outstanding need for the functionality this module seeks to provide.</p> </section> <section id="background"> <h2><a class="toc-backref" href="#background" role="doc-backlink">Background</a></h2> <p><a class="pep reference internal" href="../pep-3144/" title="PEP 3144 – IP Address Manipulation Library for the Python Standard Library">PEP 3144</a> and <code class="docutils literal notranslate"><span class="pre">ipaddr</span></code> 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 <code class="docutils literal notranslate"><span class="pre">ipaddr</span></code>, I’ve renamed this version of the library <code class="docutils literal notranslate"><span class="pre">ipaddress</span></code>.</p> <p>The main differences between ipaddr and ipaddress are:</p> <ul class="simple"> <li><code class="docutils literal notranslate"><span class="pre">ipaddress</span></code> *Network classes are equivalent to the <code class="docutils literal notranslate"><span class="pre">ipaddr</span></code> *Network class counterparts with the <code class="docutils literal notranslate"><span class="pre">strict</span></code> flag set to <code class="docutils literal notranslate"><span class="pre">True</span></code>.</li> <li><code class="docutils literal notranslate"><span class="pre">ipaddress</span></code> *Interface classes are equivalent to the <code class="docutils literal notranslate"><span class="pre">ipaddr</span></code> *Network class counterparts with the <code class="docutils literal notranslate"><span class="pre">strict</span></code> flag set to <code class="docutils literal notranslate"><span class="pre">False</span></code>.</li> <li>The factory functions in <code class="docutils literal notranslate"><span class="pre">ipaddress</span></code> were renamed to disambiguate them from classes.</li> <li>A few attributes were renamed to disambiguate their purpose as well. (eg. <code class="docutils literal notranslate"><span class="pre">network</span></code>, <code class="docutils literal notranslate"><span class="pre">network_address</span></code>)</li> <li>A number of methods and functions which returned containers in <code class="docutils literal notranslate"><span class="pre">ipaddr</span></code> now return iterators. This includes <code class="docutils literal notranslate"><span class="pre">subnets</span></code>, <code class="docutils literal notranslate"><span class="pre">address_exclude</span></code>, <code class="docutils literal notranslate"><span class="pre">summarize_address_range</span></code> and <code class="docutils literal notranslate"><span class="pre">collapse_address_list</span></code>.</li> </ul> <p>Due to the backwards incompatible API changes between <code class="docutils literal notranslate"><span class="pre">ipaddress</span></code> and <code class="docutils literal notranslate"><span class="pre">ipaddr</span></code>, the proposal is to add the module using the new provisional API status:</p> <ul class="simple"> <li><a class="reference external" href="http://docs.python.org/dev/glossary.html#term-provisional-package">http://docs.python.org/dev/glossary.html#term-provisional-package</a></li> </ul> <p>Relevant messages on python-dev:</p> <ul class="simple"> <li><a class="reference external" href="https://mail.python.org/pipermail/python-dev/2012-January/116016.html">https://mail.python.org/pipermail/python-dev/2012-January/116016.html</a></li> <li><a class="reference external" href="https://mail.python.org/pipermail/python-dev/2012-February/116656.html">https://mail.python.org/pipermail/python-dev/2012-February/116656.html</a></li> <li><a class="reference external" href="https://mail.python.org/pipermail/python-dev/2012-February/116688.html">https://mail.python.org/pipermail/python-dev/2012-February/116688.html</a></li> </ul> </section> <section id="specification"> <h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2> <p>The <code class="docutils literal notranslate"><span class="pre">ipaddr</span></code> 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:</p> <ul class="simple"> <li><code class="docutils literal notranslate"><span class="pre">IPv4Address</span></code>/<code class="docutils literal notranslate"><span class="pre">IPv6Address</span></code> - 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).</li> <li><code class="docutils literal notranslate"><span class="pre">IPv4Network</span></code>/<code class="docutils literal notranslate"><span class="pre">IPv6Network</span></code> - 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).</li> <li><code class="docutils literal notranslate"><span class="pre">IPv4Interface</span></code>/<code class="docutils literal notranslate"><span class="pre">IPv6Interface</span></code> - 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.</li> </ul> <p>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.</p> <p><code class="docutils literal notranslate"><span class="pre">ipaddr</span></code> makes extensive use of inheritance to avoid code duplication as much as possible. The parent classes are private, but they are outlined here:</p> <ul class="simple"> <li><code class="docutils literal notranslate"><span class="pre">_IPAddrBase</span></code> - Provides methods common to all <code class="docutils literal notranslate"><span class="pre">ipaddr</span></code> objects.</li> <li><code class="docutils literal notranslate"><span class="pre">_BaseAddress</span></code> - Provides methods common to <code class="docutils literal notranslate"><span class="pre">IPv4Address</span></code> and <code class="docutils literal notranslate"><span class="pre">IPv6Address</span></code>.</li> <li><code class="docutils literal notranslate"><span class="pre">_BaseInterface</span></code> - Provides methods common to <code class="docutils literal notranslate"><span class="pre">IPv4Interface</span></code> and <code class="docutils literal notranslate"><span class="pre">IPv6Interface</span></code>, as well as <code class="docutils literal notranslate"><span class="pre">IPv4Network</span></code> and <code class="docutils literal notranslate"><span class="pre">IPv6Network</span></code> (<code class="docutils literal notranslate"><span class="pre">ipaddr</span></code> treats the Network classes as a special case of Interface).</li> <li><code class="docutils literal notranslate"><span class="pre">_BaseV4</span></code> - Provides methods and variables (eg, <code class="docutils literal notranslate"><span class="pre">_max_prefixlen</span></code>) common to all IPv4 classes.</li> <li><code class="docutils literal notranslate"><span class="pre">_BaseV6</span></code> - Provides methods and variables common to all IPv6 classes.</li> </ul> <p>Comparisons between objects of differing IP versions results in a <code class="docutils literal notranslate"><span class="pre">TypeError</span></code> <a class="footnote-reference brackets" href="#id2" id="id1">[1]</a>. Additionally, comparisons of objects with different _Base parent classes results in a <code class="docutils literal notranslate"><span class="pre">TypeError</span></code>. The effect of the _Base parent class limitation is that <code class="docutils literal notranslate"><span class="pre">IPv4Interface</span></code>’s can be compared to <code class="docutils literal notranslate"><span class="pre">IPv4Network</span></code>’s and <code class="docutils literal notranslate"><span class="pre">IPv6Interface</span></code>’s can be compared to <code class="docutils literal notranslate"><span class="pre">IPv6Network</span></code>’s.</p> </section> <section id="reference-implementation"> <h2><a class="toc-backref" href="#reference-implementation" role="doc-backlink">Reference Implementation</a></h2> <p>The current reference implementation can be found at:</p> <p><a class="reference external" href="http://code.google.com/p/ipaddress-py/source/browse/ipaddress.py">http://code.google.com/p/ipaddress-py/source/browse/ipaddress.py</a></p> <p>Or see the tarball to include the README and unittests. <a class="reference external" href="http://code.google.com/p/ipaddress-py/downloads/detail?name=ipaddress-1.0.tar.gz">http://code.google.com/p/ipaddress-py/downloads/detail?name=ipaddress-1.0.tar.gz</a></p> <p>More information about using the reference implementation can be found at: <a class="reference external" href="http://code.google.com/p/ipaddr-py/wiki/Using3144">http://code.google.com/p/ipaddr-py/wiki/Using3144</a></p> </section> <section id="references"> <h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2> <aside class="footnote-list brackets"> <aside class="footnote brackets" id="id2" role="doc-footnote"> <dt class="label" id="id2">[<a href="#id1">1</a>]</dt> <dd>Appealing to authority is a logical fallacy, but Vint Cerf is an authority who can’t be ignored. Full text of the email follows:<blockquote> <div>I have seen a substantial amount of traffic about IPv4 and IPv6 comparisons and the general consensus is that these are not comparable.<p>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.</p> <p>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.</p> <p>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.</p> <p>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.</p> <p>I think the only sensible conclusion is that IPv4 values and IPv6 values should be treated as non-comparable.</p> <p>Vint</p> </div></blockquote> </aside> </aside> </section> <section id="copyright"> <h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2> <p>This document has been placed in the public domain.</p> </section> </section> <hr class="docutils" /> <p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-3144.rst">https://github.com/python/peps/blob/main/peps/pep-3144.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-3144.rst">2023-10-11 12:05:51 GMT</a></p> </article> <nav id="pep-sidebar"> <h2>Contents</h2> <ul> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#pep-acceptance">PEP Acceptance</a></li> <li><a class="reference internal" href="#motivation">Motivation</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#background">Background</a></li> <li><a class="reference internal" href="#specification">Specification</a></li> <li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li> <li><a class="reference internal" href="#references">References</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> <br> <a id="source" href="https://github.com/python/peps/blob/main/peps/pep-3144.rst">Page Source (GitHub)</a> </nav> </section> <script src="../_static/colour_scheme.js"></script> <script src="../_static/wrap_tables.js"></script> <script src="../_static/sticky_banner.js"></script> </body> </html>