[Python-checkins] peps: PEP 435, Adding an Enum type to the Python standard library, Bendersky/Warsaw
barry.warsaw
python-checkins at python.org
Mon Feb 25 16:15:07 CET 2013
http://hg.python.org/peps/rev/102cbc9b1b29
changeset: 4775:102cbc9b1b29
user: Barry Warsaw <barry at python.org>
date: Mon Feb 25 10:15:03 2013 -0500
summary:
PEP 435, Adding an Enum type to the Python standard library, Bendersky/Warsaw
files:
pepdraft-0435.txt | 118 ++++++++++++++++++---------------
1 files changed, 63 insertions(+), 55 deletions(-)
diff --git a/pepdraft-0435.txt b/pep-0435.txt
rename from pepdraft-0435.txt
rename to pep-0435.txt
--- a/pepdraft-0435.txt
+++ b/pep-0435.txt
@@ -16,52 +16,51 @@
========
This PEP proposes adding an enumeration type to the Python standard library.
-Specifically, it proposes moving the existing ``flufl.enum`` package by
-Barry Warsaw into the standard library. Much of this PEP is based on the
-"using" document from the documentation of ``flufl.enum``.
+Specifically, it proposes moving the existing ``flufl.enum`` package by Barry
+Warsaw into the standard library. Much of this PEP is based on the "using"
+[1]_ document from the documentation of ``flufl.enum``.
An enumeration is a set of symbolic names bound to unique, constant integer
-values. Within an enumeration, the values can be compared by identity, and
-the enumeration itself can be iterated over. Enumeration items can be
-converted to and from their integer equivalents, supporting use cases such as
-storing enumeration values in a database.
+values. Within an enumeration, the values can be compared by identity, and the
+enumeration itself can be iterated over. Enumeration items can be converted to
+and from their integer equivalents, supporting use cases such as storing
+enumeration values in a database.
Status of discussions
=====================
-The idea of adding an enum type to Python is not new - PEP 354 is a previous
-attempt that was rejected in 2005. Recently a new set of discussions was
-initiated [#]_ on the ``python-ideas`` mailing list. Many new ideas were
-proposed in several threads; after a lengthy discussion Guido proposed
-adding ``flufl.enum`` to the standard library [#]_. This PEP is an attempt to
-formalize this decision as well as discuss a number of variations that can
-be considered for inclusion.
+The idea of adding an enum type to Python is not new - PEP 354 [2]_ is a
+previous attempt that was rejected in 2005. Recently a new set of discussions
+was initiated [3]_ on the ``python-ideas`` mailing list. Many new ideas were
+proposed in several threads; after a lengthy discussion Guido proposed adding
+``flufl.enum`` to the standard library [4]_. This PEP is an attempt to
+formalize this decision as well as discuss a number of variations that can be
+considered for inclusion.
+
Motivation
==========
*[Based partly on the Motivation stated in PEP 354]*
-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.
+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.
-It is possible to simply define a sequence of values of some other
-basic type, such as ``int`` or ``str``, to represent discrete
-arbitrary values. However, an enumeration ensures that such values
-are distinct from any others including, importantly, values within other
-enumerations, and that operations without meaning ("Wednesday times two")
-are not defined for these values. It also provides a convenient printable
-representation of enum values without requiring tedious repetition while
-defining them (i.e. no ``GREEN = 'green'``).
+It is possible to simply define a sequence of values of some other basic type,
+such as ``int`` or ``str``, to represent discrete arbitrary values. However,
+an enumeration ensures that such values are distinct from any others including,
+importantly, values within other enumerations, and that operations without
+meaning ("Wednesday times two") are not defined for these values. It also
+provides a convenient printable representation of enum values without requiring
+tedious repetition while defining them (i.e. no ``GREEN = 'green'``).
-Module & type name
-==================
+Module and type name
+====================
We propose to add a module named ``enum`` to the standard library. The main
type exposed by this module is ``Enum``. Hence, to import the ``Enum`` type
@@ -69,6 +68,7 @@
>>> from enum import Enum
+
Proposed semantics for the new enumeration type
===============================================
@@ -78,8 +78,8 @@
Enumerations are created using the class syntax, which makes them easy to read
and write. Every enumeration value must have a unique integer value and the
only restriction on their names is that they must be valid Python identifiers.
-To define an enumeration, derive from the ``Enum`` class and add attributes with
-assignment to their integer values::
+To define an enumeration, derive from the ``Enum`` class and add attributes
+with assignment to their integer values::
>>> from enum import Enum
>>> class Colors(Enum):
@@ -247,8 +247,8 @@
>>> int(Colors.blue)
3
-You can also convert back to the enumeration value by calling the Enum subclass,
-passing in the integer value for the item you want::
+You can also convert back to the enumeration value by calling the Enum
+subclass, passing in the integer value for the item you want::
>>> Colors(1)
<EnumValue: Colors.red [int=1]>
@@ -358,7 +358,7 @@
You can also create enumerations using the convenience function ``make()``,
which takes an iterable object or dictionary to provide the item names and
-values. ``make()`` is a static method.
+values. ``make()`` is a module-level function.
The first argument to ``make()`` is the name of the enumeration, and it returns
the so-named `Enum` subclass. The second argument is a *source* which can be
@@ -382,11 +382,13 @@
>>> enum.make('Flags', zip(list('abcdefg'), enumiter()))
<Flags {a: 1, b: 2, c: 4, d: 8, e: 16, f: 32, g: 64}>
+
Proposed variations
===================
Some variations were proposed during the discussions in the mailing list.
-Here's some of the more popular:
+Here's some of the more popular ones.
+
Not having to specify values for enums
--------------------------------------
@@ -400,11 +402,12 @@
The values get actually assigned only when first looked up.
Pros: cleaner syntax that requires less typing for a very common task (just
-listing enumertion names without caring about the values).
+listing enumeration names without caring about the values).
Cons: involves much magic in the implementation, which makes even the
-definition of such enums baffling when first seen. Besides, explicit is better
-than implicit.
+definition of such enums baffling when first seen. Besides, explicit is
+better than implicit.
+
Using special names or forms to auto-assign enum values
-------------------------------------------------------
@@ -434,8 +437,9 @@
Pros: no need to manually enter values. Makes it easier to change the enum and
extend it, especially for large enumerations.
-Cons: actually longer to type in many simple cases. The argument of
-explicit vs. implicit applies here as well.
+Cons: actually longer to type in many simple cases. The argument of explicit
+vs. implicit applies here as well.
+
Use-cases in the standard library
=================================
@@ -447,8 +451,8 @@
User-code facing constants like ``os.SEEK_*``, ``socket`` module constants,
decimal rounding modes, HTML error codes could benefit from being enums had
-they been implemented this way from the beginning. At this point, however,
-at the risk of breaking user code (that relies on the constants' actual values
+they been implemented this way from the beginning. At this point, however, at
+the risk of breaking user code (that relies on the constants' actual values
rather than their meaning) such a change cannot be made. This does not mean
that future uses in the stdlib can't use an enum for defining new user-code
facing constants.
@@ -457,12 +461,13 @@
stdlib modules. It appears that nothing should stand in the way of
implementing such constants with enums. Some examples uncovered by a very
partial skim through the stdlib: ``binhex``, ``imaplib``, ``http/client``,
-``urllib/robotparser``, ``idlelib``, ``concurrent.futures``, ``turledemo``.
+``urllib/robotparser``, ``idlelib``, ``concurrent.futures``, ``turtledemo``.
In addition, looking at the code of the Twisted library, there are many use
-cases for replacing internal state constants with enums. The same can be
-said about a lot of networking code (especially implementation of protocols)
-and can be seen in test protocols written with the Tulip library as well.
+cases for replacing internal state constants with enums. The same can be said
+about a lot of networking code (especially implementation of protocols) and
+can be seen in test protocols written with the Tulip library as well.
+
Differences from PEP 354
========================
@@ -486,8 +491,8 @@
complexity, though minimal, is hidden from users of the enumeration.
Unlike PEP 354, enumeration values can only be tested by identity comparison.
-This is to emphasise the fact that enumeration values are singletons, much like
-``None``.
+This is to emphasize the fact that enumeration values are singletons, much
+like ``None``.
Acknowledgments
@@ -495,28 +500,31 @@
This PEP describes the ``flufl.enum`` package by Barry Warsaw. ``flufl.enum``
is based on an example by Jeremy Hylton. It has been modified and extended
-by Barry Warsaw for use in the GNU Mailman [#]_ project. Ben Finney is the
+by Barry Warsaw for use in the GNU Mailman [5]_ project. Ben Finney is the
author of the earlier enumeration PEP 354.
+
References
==========
-.. [#] http://mail.python.org/pipermail/python-ideas/2013-January/019003.html
-.. [#] http://mail.python.org/pipermail/python-ideas/2013-February/019373.html
-.. [#] http://www.list.org
+.. [1] http://pythonhosted.org/flufl.enum/docs/using.html
+.. [2] http://www.python.org/dev/peps/pep-0354/
+.. [3] http://mail.python.org/pipermail/python-ideas/2013-January/019003.html
+.. [4] http://mail.python.org/pipermail/python-ideas/2013-February/019373.html
+.. [5] http://www.list.org
+
Copyright
=========
This document has been placed in the public domain.
+
Todo
====
* Mark PEP 354 "superseded by" this one, if accepted
* New package name within stdlib - enum? (top-level)
- * "Convenience API" says "make() is a static method" - what does this mean?
- make seems to be a simple module-level function in the implementation.
* For make, can we add an API like namedtuple's?
make('Animals, 'ant bee cat dog')
I.e. when make sees a string argument it splits it, making it similar to a
--
Repository URL: http://hg.python.org/peps
More information about the Python-checkins
mailing list