CINXE.COM
PEP 354 – Enumerations in Python | 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 354 – Enumerations in Python | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-0354/"> <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 354 – Enumerations in Python | peps.python.org'> <meta property="og:description" content="This PEP specifies an enumeration data type for Python."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-0354/"> <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 specifies an enumeration data type 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 354</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 354 – Enumerations in Python</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Ben Finney <ben+python at benfinney.id.au></dd> <dt class="field-even">Status<span class="colon">:</span></dt> <dd class="field-even"><abbr title="Replaced by another succeeding PEP">Superseded</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">20-Dec-2005</dd> <dt class="field-odd">Python-Version<span class="colon">:</span></dt> <dd class="field-odd">2.6</dd> <dt class="field-even">Post-History<span class="colon">:</span></dt> <dd class="field-even">20-Dec-2005</dd> <dt class="field-odd">Superseded-By<span class="colon">:</span></dt> <dd class="field-odd"><a class="reference external" href="../pep-0435/">435</a></dd> </dl> <hr class="docutils" /> <section id="contents"> <details><summary>Table of Contents</summary><ul class="simple"> <li><a class="reference internal" href="#rejection-notice">Rejection Notice</a></li> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#motivation">Motivation</a></li> <li><a class="reference internal" href="#specification">Specification</a></li> <li><a class="reference internal" href="#rationale-other-designs-considered">Rationale – Other designs considered</a><ul> <li><a class="reference internal" href="#all-in-one-class">All in one class</a></li> <li><a class="reference internal" href="#metaclass-for-creating-enumeration-classes">Metaclass for creating enumeration classes</a></li> <li><a class="reference internal" href="#values-related-to-other-types">Values related to other types</a></li> <li><a class="reference internal" href="#hiding-attributes-of-enumerated-values">Hiding attributes of enumerated values</a></li> </ul> </li> <li><a class="reference internal" href="#implementation">Implementation</a></li> <li><a class="reference internal" href="#references-and-footnotes">References and Footnotes</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> </details></section> <section id="rejection-notice"> <h2><a class="toc-backref" href="#rejection-notice" role="doc-backlink">Rejection Notice</a></h2> <p>This PEP has been rejected. This doesn’t slot nicely into any of the existing modules (like collections), and the Python standard library eschews having lots of individual data structures in their own modules. Also, the PEP has generated no widespread interest. For those who need enumerations, there are cookbook recipes and PyPI packages that meet these needs.</p> <p><em>Note: this PEP was superseded by</em> <a class="pep reference internal" href="../pep-0435/" title="PEP 435 – Adding an Enum type to the Python standard library">PEP 435</a>, <em>which has been accepted in May 2013.</em></p> </section> <section id="abstract"> <h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2> <p>This PEP specifies an enumeration data type for Python.</p> <p>An enumeration is an exclusive set of symbolic names bound to arbitrary unique values. Values within an enumeration can be iterated and compared, but the values have no inherent relationship to values outside the enumeration.</p> </section> <section id="motivation"> <h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2> <p>The properties of an enumeration are useful for defining an immutable, related set of constant values that have a defined sequence but no inherent semantic meaning. Classic examples are days of the week (Sunday through Saturday) and school assessment grades (‘A’ through ‘D’, and ‘F’). Other examples include error status values and states within a defined process.</p> <p>It is possible to simply define a sequence of values of some other basic type, such as <code class="docutils literal notranslate"><span class="pre">int</span></code> or <code class="docutils literal notranslate"><span class="pre">str</span></code>, to represent discrete arbitrary values. However, an enumeration ensures that such values are distinct from any others, and that operations without meaning (“Wednesday times two”) are not defined for these values.</p> </section> <section id="specification"> <h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2> <p>An enumerated type is created from a sequence of arguments to the type’s constructor:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">Weekdays</span> <span class="o">=</span> <span class="n">enum</span><span class="p">(</span><span class="s1">'sun'</span><span class="p">,</span> <span class="s1">'mon'</span><span class="p">,</span> <span class="s1">'tue'</span><span class="p">,</span> <span class="s1">'wed'</span><span class="p">,</span> <span class="s1">'thu'</span><span class="p">,</span> <span class="s1">'fri'</span><span class="p">,</span> <span class="s1">'sat'</span><span class="p">)</span> <span class="gp">>>> </span><span class="n">Grades</span> <span class="o">=</span> <span class="n">enum</span><span class="p">(</span><span class="s1">'A'</span><span class="p">,</span> <span class="s1">'B'</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">,</span> <span class="s1">'D'</span><span class="p">,</span> <span class="s1">'F'</span><span class="p">)</span> </pre></div> </div> <p>Enumerations with no values are meaningless. The exception <code class="docutils literal notranslate"><span class="pre">EnumEmptyError</span></code> is raised if the constructor is called with no value arguments.</p> <p>The values are bound to attributes of the new enumeration object:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">today</span> <span class="o">=</span> <span class="n">Weekdays</span><span class="o">.</span><span class="n">mon</span> </pre></div> </div> <p>The values can be compared:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">if</span> <span class="n">today</span> <span class="o">==</span> <span class="n">Weekdays</span><span class="o">.</span><span class="n">fri</span><span class="p">:</span> <span class="gp">... </span> <span class="nb">print</span> <span class="s2">"Get ready for the weekend"</span> </pre></div> </div> <p>Values within an enumeration cannot be meaningfully compared except with values from the same enumeration. The comparison operation functions return <code class="docutils literal notranslate"><span class="pre">NotImplemented</span></code> <a class="footnote-reference brackets" href="#cmp-notimplemented" id="id1">[1]</a> when a value from an enumeration is compared against any value not from the same enumeration or of a different type:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">gym_night</span> <span class="o">=</span> <span class="n">Weekdays</span><span class="o">.</span><span class="n">wed</span> <span class="gp">>>> </span><span class="n">gym_night</span><span class="o">.</span><span class="n">__cmp__</span><span class="p">(</span><span class="n">Weekdays</span><span class="o">.</span><span class="n">mon</span><span class="p">)</span> <span class="go">1</span> <span class="gp">>>> </span><span class="n">gym_night</span><span class="o">.</span><span class="n">__cmp__</span><span class="p">(</span><span class="n">Weekdays</span><span class="o">.</span><span class="n">wed</span><span class="p">)</span> <span class="go">0</span> <span class="gp">>>> </span><span class="n">gym_night</span><span class="o">.</span><span class="n">__cmp__</span><span class="p">(</span><span class="n">Weekdays</span><span class="o">.</span><span class="n">fri</span><span class="p">)</span> <span class="go">-1</span> <span class="gp">>>> </span><span class="n">gym_night</span><span class="o">.</span><span class="n">__cmp__</span><span class="p">(</span><span class="mi">23</span><span class="p">)</span> <span class="go">NotImplemented</span> <span class="gp">>>> </span><span class="n">gym_night</span><span class="o">.</span><span class="n">__cmp__</span><span class="p">(</span><span class="s2">"wed"</span><span class="p">)</span> <span class="go">NotImplemented</span> <span class="gp">>>> </span><span class="n">gym_night</span><span class="o">.</span><span class="n">__cmp__</span><span class="p">(</span><span class="n">Grades</span><span class="o">.</span><span class="n">B</span><span class="p">)</span> <span class="go">NotImplemented</span> </pre></div> </div> <p>This allows the operation to succeed, evaluating to a boolean value:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">gym_night</span> <span class="o">=</span> <span class="n">Weekdays</span><span class="o">.</span><span class="n">wed</span> <span class="gp">>>> </span><span class="n">gym_night</span> <span class="o"><</span> <span class="n">Weekdays</span><span class="o">.</span><span class="n">mon</span> <span class="go">False</span> <span class="gp">>>> </span><span class="n">gym_night</span> <span class="o"><</span> <span class="n">Weekdays</span><span class="o">.</span><span class="n">wed</span> <span class="go">False</span> <span class="gp">>>> </span><span class="n">gym_night</span> <span class="o"><</span> <span class="n">Weekdays</span><span class="o">.</span><span class="n">fri</span> <span class="go">True</span> <span class="gp">>>> </span><span class="n">gym_night</span> <span class="o"><</span> <span class="mi">23</span> <span class="go">False</span> <span class="gp">>>> </span><span class="n">gym_night</span> <span class="o">></span> <span class="mi">23</span> <span class="go">True</span> <span class="gp">>>> </span><span class="n">gym_night</span> <span class="o">></span> <span class="s2">"wed"</span> <span class="go">True</span> <span class="gp">>>> </span><span class="n">gym_night</span> <span class="o">></span> <span class="n">Grades</span><span class="o">.</span><span class="n">B</span> <span class="go">True</span> </pre></div> </div> <p>Coercing a value from an enumeration to a <code class="docutils literal notranslate"><span class="pre">str</span></code> results in the string that was specified for that value when constructing the enumeration:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">gym_night</span> <span class="o">=</span> <span class="n">Weekdays</span><span class="o">.</span><span class="n">wed</span> <span class="gp">>>> </span><span class="nb">str</span><span class="p">(</span><span class="n">gym_night</span><span class="p">)</span> <span class="go">'wed'</span> </pre></div> </div> <p>The sequence index of each value from an enumeration is exported as an integer via that value’s <code class="docutils literal notranslate"><span class="pre">index</span></code> attribute:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">gym_night</span> <span class="o">=</span> <span class="n">Weekdays</span><span class="o">.</span><span class="n">wed</span> <span class="gp">>>> </span><span class="n">gym_night</span><span class="o">.</span><span class="n">index</span> <span class="go">3</span> </pre></div> </div> <p>An enumeration can be iterated, returning its values in the sequence they were specified when the enumeration was created:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">print</span> <span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">day</span><span class="p">)</span> <span class="k">for</span> <span class="n">day</span> <span class="ow">in</span> <span class="n">Weekdays</span><span class="p">]</span> <span class="go">['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']</span> </pre></div> </div> <p>Values from an enumeration are hashable, and can be used as dict keys:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">plans</span> <span class="o">=</span> <span class="p">{}</span> <span class="gp">>>> </span><span class="n">plans</span><span class="p">[</span><span class="n">Weekdays</span><span class="o">.</span><span class="n">sat</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"Feed the horse"</span> </pre></div> </div> <p>The normal usage of enumerations is to provide a set of possible values for a data type, which can then be used to map to other information about the values:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">for</span> <span class="n">report_grade</span> <span class="ow">in</span> <span class="n">Grades</span><span class="p">:</span> <span class="gp">... </span> <span class="n">report_students</span><span class="p">[</span><span class="n">report_grade</span><span class="p">]</span> <span class="o">=</span> \ <span class="gp">... </span> <span class="p">[</span><span class="n">s</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">students</span> <span class="k">if</span> <span class="n">students</span><span class="o">.</span><span class="n">grade</span> <span class="o">==</span> <span class="n">report_grade</span><span class="p">]</span> </pre></div> </div> </section> <section id="rationale-other-designs-considered"> <h2><a class="toc-backref" href="#rationale-other-designs-considered" role="doc-backlink">Rationale – Other designs considered</a></h2> <section id="all-in-one-class"> <h3><a class="toc-backref" href="#all-in-one-class" role="doc-backlink">All in one class</a></h3> <p>Some implementations have the enumeration and its values all as attributes of a single object or class.</p> <p>This PEP specifies a design where the enumeration is a container, and the values are simple comparables. It was felt that attempting to place all the properties of enumeration within a single class complicates the design without apparent benefit.</p> </section> <section id="metaclass-for-creating-enumeration-classes"> <h3><a class="toc-backref" href="#metaclass-for-creating-enumeration-classes" role="doc-backlink">Metaclass for creating enumeration classes</a></h3> <p>The enumerations specified in this PEP are instances of an <code class="docutils literal notranslate"><span class="pre">enum</span></code> type. Some alternative designs implement each enumeration as its own class, and a metaclass to define common properties of all enumerations.</p> <p>One motivation for having a class (rather than an instance) for each enumeration is to allow subclasses of enumerations, extending and altering an existing enumeration. A class, though, implies that instances of that class will be created; it is difficult to imagine what it means to have separate instances of a “days of the week” class, where each instance contains all days. This usually leads to having each class follow the Singleton pattern, further complicating the design.</p> <p>In contrast, this PEP specifies enumerations that are not expected to be extended or modified. It is, of course, possible to create a new enumeration from the string values of an existing one, or even subclass the <code class="docutils literal notranslate"><span class="pre">enum</span></code> type if desired.</p> </section> <section id="values-related-to-other-types"> <h3><a class="toc-backref" href="#values-related-to-other-types" role="doc-backlink">Values related to other types</a></h3> <p>Some designs express a strong relationship to some other value, such as a particular integer or string, for each enumerated value.</p> <p>This results in using such values in contexts where the enumeration has no meaning, and unnecessarily complicates the design. The enumerated values specified in this PEP export the values used to create them, and can be compared for equality with any other value, but sequence comparison with values outside the enumeration is explicitly not implemented.</p> </section> <section id="hiding-attributes-of-enumerated-values"> <h3><a class="toc-backref" href="#hiding-attributes-of-enumerated-values" role="doc-backlink">Hiding attributes of enumerated values</a></h3> <p>A previous design had the enumerated values hiding as much as possible about their implementation, to the point of not exporting the string key and sequence index.</p> <p>The design in this PEP acknowledges that programs will often find it convenient to know the enumerated value’s enumeration type, sequence index, and string key specified for the value. These are exported by the enumerated value as attributes.</p> </section> </section> <section id="implementation"> <h2><a class="toc-backref" href="#implementation" role="doc-backlink">Implementation</a></h2> <p>This design is based partly on a recipe <a class="footnote-reference brackets" href="#enum-recipe" id="id2">[2]</a> from the Python Cookbook.</p> <p>The PyPI package <code class="docutils literal notranslate"><span class="pre">enum</span></code> <a class="footnote-reference brackets" href="#enum-package" id="id3">[3]</a> provides a Python implementation of the data types described in this PEP.</p> </section> <section id="references-and-footnotes"> <h2><a class="toc-backref" href="#references-and-footnotes" role="doc-backlink">References and Footnotes</a></h2> <aside class="footnote-list brackets"> <aside class="footnote brackets" id="cmp-notimplemented" role="doc-footnote"> <dt class="label" id="cmp-notimplemented">[<a href="#id1">1</a>]</dt> <dd>The <code class="docutils literal notranslate"><span class="pre">NotImplemented</span></code> return value from comparison operations signals the Python interpreter to attempt alternative comparisons or other fallbacks. <<a class="reference external" href="http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy">http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy</a>></aside> <aside class="footnote brackets" id="enum-recipe" role="doc-footnote"> <dt class="label" id="enum-recipe">[<a href="#id2">2</a>]</dt> <dd>“First Class Enums in Python”, Zoran Isailovski, Python Cookbook recipe 413486 <<a class="reference external" href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/413486">http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/413486</a>></aside> <aside class="footnote brackets" id="enum-package" role="doc-footnote"> <dt class="label" id="enum-package">[<a href="#id3">3</a>]</dt> <dd>Python Package Index, package <code class="docutils literal notranslate"><span class="pre">enum</span></code> <<a class="reference external" href="http://cheeseshop.python.org/pypi/enum/">http://cheeseshop.python.org/pypi/enum/</a>></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-0354.rst">https://github.com/python/peps/blob/main/peps/pep-0354.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0354.rst">2025-02-01 08:59:27 GMT</a></p> </article> <nav id="pep-sidebar"> <h2>Contents</h2> <ul> <li><a class="reference internal" href="#rejection-notice">Rejection Notice</a></li> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#motivation">Motivation</a></li> <li><a class="reference internal" href="#specification">Specification</a></li> <li><a class="reference internal" href="#rationale-other-designs-considered">Rationale – Other designs considered</a><ul> <li><a class="reference internal" href="#all-in-one-class">All in one class</a></li> <li><a class="reference internal" href="#metaclass-for-creating-enumeration-classes">Metaclass for creating enumeration classes</a></li> <li><a class="reference internal" href="#values-related-to-other-types">Values related to other types</a></li> <li><a class="reference internal" href="#hiding-attributes-of-enumerated-values">Hiding attributes of enumerated values</a></li> </ul> </li> <li><a class="reference internal" href="#implementation">Implementation</a></li> <li><a class="reference internal" href="#references-and-footnotes">References and Footnotes</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-0354.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>