summaryrefslogtreecommitdiffstats
path: root/third_party/python/enum34
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/python/enum34')
-rw-r--r--third_party/python/enum34/MANIFEST.in9
-rw-r--r--third_party/python/enum34/PKG-INFO62
-rw-r--r--third_party/python/enum34/README3
-rw-r--r--third_party/python/enum34/enum/LICENSE32
-rw-r--r--third_party/python/enum34/enum/README3
-rw-r--r--third_party/python/enum34/enum/__init__.py837
-rw-r--r--third_party/python/enum34/enum/doc/enum.pdf2237
-rw-r--r--third_party/python/enum34/enum/doc/enum.rst735
-rw-r--r--third_party/python/enum34/enum/test.py1820
-rw-r--r--third_party/python/enum34/setup.cfg5
-rw-r--r--third_party/python/enum34/setup.py99
11 files changed, 5842 insertions, 0 deletions
diff --git a/third_party/python/enum34/MANIFEST.in b/third_party/python/enum34/MANIFEST.in
new file mode 100644
index 0000000000..98fe77f55a
--- /dev/null
+++ b/third_party/python/enum34/MANIFEST.in
@@ -0,0 +1,9 @@
+exclude enum/*
+include setup.py
+include README
+include enum/__init__.py
+include enum/test.py
+include enum/LICENSE
+include enum/README
+include enum/doc/enum.pdf
+include enum/doc/enum.rst
diff --git a/third_party/python/enum34/PKG-INFO b/third_party/python/enum34/PKG-INFO
new file mode 100644
index 0000000000..98927c4d99
--- /dev/null
+++ b/third_party/python/enum34/PKG-INFO
@@ -0,0 +1,62 @@
+Metadata-Version: 1.1
+Name: enum34
+Version: 1.1.6
+Summary: Python 3.4 Enum backported to 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, and 2.4
+Home-page: https://bitbucket.org/stoneleaf/enum34
+Author: Ethan Furman
+Author-email: ethan@stoneleaf.us
+License: BSD License
+Description: enum --- support for enumerations
+ ========================================
+
+ An enumeration is a set of symbolic names (members) bound to unique, constant
+ values. Within an enumeration, the members can be compared by identity, and
+ the enumeration itself can be iterated over.
+
+ from enum import Enum
+
+ class Fruit(Enum):
+ apple = 1
+ banana = 2
+ orange = 3
+
+ list(Fruit)
+ # [<Fruit.apple: 1>, <Fruit.banana: 2>, <Fruit.orange: 3>]
+
+ len(Fruit)
+ # 3
+
+ Fruit.banana
+ # <Fruit.banana: 2>
+
+ Fruit['banana']
+ # <Fruit.banana: 2>
+
+ Fruit(2)
+ # <Fruit.banana: 2>
+
+ Fruit.banana is Fruit['banana'] is Fruit(2)
+ # True
+
+ Fruit.banana.name
+ # 'banana'
+
+ Fruit.banana.value
+ # 2
+
+ Repository and Issue Tracker at https://bitbucket.org/stoneleaf/enum34.
+
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Programming Language :: Python
+Classifier: Topic :: Software Development
+Classifier: Programming Language :: Python :: 2.4
+Classifier: Programming Language :: Python :: 2.5
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Provides: enum
diff --git a/third_party/python/enum34/README b/third_party/python/enum34/README
new file mode 100644
index 0000000000..aa2333d8df
--- /dev/null
+++ b/third_party/python/enum34/README
@@ -0,0 +1,3 @@
+enum34 is the new Python stdlib enum module available in Python 3.4
+backported for previous versions of Python from 2.4 to 3.3.
+tested on 2.6, 2.7, and 3.3+
diff --git a/third_party/python/enum34/enum/LICENSE b/third_party/python/enum34/enum/LICENSE
new file mode 100644
index 0000000000..9003b8850e
--- /dev/null
+++ b/third_party/python/enum34/enum/LICENSE
@@ -0,0 +1,32 @@
+Copyright (c) 2013, Ethan Furman.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+
+ Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ Neither the name Ethan Furman nor the names of any
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/python/enum34/enum/README b/third_party/python/enum34/enum/README
new file mode 100644
index 0000000000..aa2333d8df
--- /dev/null
+++ b/third_party/python/enum34/enum/README
@@ -0,0 +1,3 @@
+enum34 is the new Python stdlib enum module available in Python 3.4
+backported for previous versions of Python from 2.4 to 3.3.
+tested on 2.6, 2.7, and 3.3+
diff --git a/third_party/python/enum34/enum/__init__.py b/third_party/python/enum34/enum/__init__.py
new file mode 100644
index 0000000000..d6ffb3a40f
--- /dev/null
+++ b/third_party/python/enum34/enum/__init__.py
@@ -0,0 +1,837 @@
+"""Python Enumerations"""
+
+import sys as _sys
+
+__all__ = ['Enum', 'IntEnum', 'unique']
+
+version = 1, 1, 6
+
+pyver = float('%s.%s' % _sys.version_info[:2])
+
+try:
+ any
+except NameError:
+ def any(iterable):
+ for element in iterable:
+ if element:
+ return True
+ return False
+
+try:
+ from collections import OrderedDict
+except ImportError:
+ OrderedDict = None
+
+try:
+ basestring
+except NameError:
+ # In Python 2 basestring is the ancestor of both str and unicode
+ # in Python 3 it's just str, but was missing in 3.1
+ basestring = str
+
+try:
+ unicode
+except NameError:
+ # In Python 3 unicode no longer exists (it's just str)
+ unicode = str
+
+class _RouteClassAttributeToGetattr(object):
+ """Route attribute access on a class to __getattr__.
+
+ This is a descriptor, used to define attributes that act differently when
+ accessed through an instance and through a class. Instance access remains
+ normal, but access to an attribute through a class will be routed to the
+ class's __getattr__ method; this is done by raising AttributeError.
+
+ """
+ def __init__(self, fget=None):
+ self.fget = fget
+
+ def __get__(self, instance, ownerclass=None):
+ if instance is None:
+ raise AttributeError()
+ return self.fget(instance)
+
+ def __set__(self, instance, value):
+ raise AttributeError("can't set attribute")
+
+ def __delete__(self, instance):
+ raise AttributeError("can't delete attribute")
+
+
+def _is_descriptor(obj):
+ """Returns True if obj is a descriptor, False otherwise."""
+ return (
+ hasattr(obj, '__get__') or
+ hasattr(obj, '__set__') or
+ hasattr(obj, '__delete__'))
+
+
+def _is_dunder(name):
+ """Returns True if a __dunder__ name, False otherwise."""
+ return (name[:2] == name[-2:] == '__' and
+ name[2:3] != '_' and
+ name[-3:-2] != '_' and
+ len(name) > 4)
+
+
+def _is_sunder(name):
+ """Returns True if a _sunder_ name, False otherwise."""
+ return (name[0] == name[-1] == '_' and
+ name[1:2] != '_' and
+ name[-2:-1] != '_' and
+ len(name) > 2)
+
+
+def _make_class_unpicklable(cls):
+ """Make the given class un-picklable."""
+ def _break_on_call_reduce(self, protocol=None):
+ raise TypeError('%r cannot be pickled' % self)
+ cls.__reduce_ex__ = _break_on_call_reduce
+ cls.__module__ = '<unknown>'
+
+
+class _EnumDict(dict):
+ """Track enum member order and ensure member names are not reused.
+
+ EnumMeta will use the names found in self._member_names as the
+ enumeration member names.
+
+ """
+ def __init__(self):
+ super(_EnumDict, self).__init__()
+ self._member_names = []
+
+ def __setitem__(self, key, value):
+ """Changes anything not dundered or not a descriptor.
+
+ If a descriptor is added with the same name as an enum member, the name
+ is removed from _member_names (this may leave a hole in the numerical
+ sequence of values).
+
+ If an enum member name is used twice, an error is raised; duplicate
+ values are not checked for.
+
+ Single underscore (sunder) names are reserved.
+
+ Note: in 3.x __order__ is simply discarded as a not necessary piece
+ leftover from 2.x
+
+ """
+ if pyver >= 3.0 and key in ('_order_', '__order__'):
+ return
+ elif key == '__order__':
+ key = '_order_'
+ if _is_sunder(key):
+ if key != '_order_':
+ raise ValueError('_names_ are reserved for future Enum use')
+ elif _is_dunder(key):
+ pass
+ elif key in self._member_names:
+ # descriptor overwriting an enum?
+ raise TypeError('Attempted to reuse key: %r' % key)
+ elif not _is_descriptor(value):
+ if key in self:
+ # enum overwriting a descriptor?
+ raise TypeError('Key already defined as: %r' % self[key])
+ self._member_names.append(key)
+ super(_EnumDict, self).__setitem__(key, value)
+
+
+# Dummy value for Enum as EnumMeta explicity checks for it, but of course until
+# EnumMeta finishes running the first time the Enum class doesn't exist. This
+# is also why there are checks in EnumMeta like `if Enum is not None`
+Enum = None
+
+
+class EnumMeta(type):
+ """Metaclass for Enum"""
+ @classmethod
+ def __prepare__(metacls, cls, bases):
+ return _EnumDict()
+
+ def __new__(metacls, cls, bases, classdict):
+ # an Enum class is final once enumeration items have been defined; it
+ # cannot be mixed with other types (int, float, etc.) if it has an
+ # inherited __new__ unless a new __new__ is defined (or the resulting
+ # class will fail).
+ if type(classdict) is dict:
+ original_dict = classdict
+ classdict = _EnumDict()
+ for k, v in original_dict.items():
+ classdict[k] = v
+
+ member_type, first_enum = metacls._get_mixins_(bases)
+ __new__, save_new, use_args = metacls._find_new_(classdict, member_type,
+ first_enum)
+ # save enum items into separate mapping so they don't get baked into
+ # the new class
+ members = dict((k, classdict[k]) for k in classdict._member_names)
+ for name in classdict._member_names:
+ del classdict[name]
+
+ # py2 support for definition order
+ _order_ = classdict.get('_order_')
+ if _order_ is None:
+ if pyver < 3.0:
+ try:
+ _order_ = [name for (name, value) in sorted(members.items(), key=lambda item: item[1])]
+ except TypeError:
+ _order_ = [name for name in sorted(members.keys())]
+ else:
+ _order_ = classdict._member_names
+ else:
+ del classdict['_order_']
+ if pyver < 3.0:
+ _order_ = _order_.replace(',', ' ').split()
+ aliases = [name for name in members if name not in _order_]
+ _order_ += aliases
+
+ # check for illegal enum names (any others?)
+ invalid_names = set(members) & set(['mro'])
+ if invalid_names:
+ raise ValueError('Invalid enum member name(s): %s' % (
+ ', '.join(invalid_names), ))
+
+ # save attributes from super classes so we know if we can take
+ # the shortcut of storing members in the class dict
+ base_attributes = set([a for b in bases for a in b.__dict__])
+ # create our new Enum type
+ enum_class = super(EnumMeta, metacls).__new__(metacls, cls, bases, classdict)
+ enum_class._member_names_ = [] # names in random order
+ if OrderedDict is not None:
+ enum_class._member_map_ = OrderedDict()
+ else:
+ enum_class._member_map_ = {} # name->value map
+ enum_class._member_type_ = member_type
+
+ # Reverse value->name map for hashable values.
+ enum_class._value2member_map_ = {}
+
+ # instantiate them, checking for duplicates as we go
+ # we instantiate first instead of checking for duplicates first in case
+ # a custom __new__ is doing something funky with the values -- such as
+ # auto-numbering ;)
+ if __new__ is None:
+ __new__ = enum_class.__new__
+ for member_name in _order_:
+ value = members[member_name]
+ if not isinstance(value, tuple):
+ args = (value, )
+ else:
+ args = value
+ if member_type is tuple: # special case for tuple enums
+ args = (args, ) # wrap it one more time
+ if not use_args or not args:
+ enum_member = __new__(enum_class)
+ if not hasattr(enum_member, '_value_'):
+ enum_member._value_ = value
+ else:
+ enum_member = __new__(enum_class, *args)
+ if not hasattr(enum_member, '_value_'):
+ enum_member._value_ = member_type(*args)
+ value = enum_member._value_
+ enum_member._name_ = member_name
+ enum_member.__objclass__ = enum_class
+ enum_member.__init__(*args)
+ # If another member with the same value was already defined, the
+ # new member becomes an alias to the existing one.
+ for name, canonical_member in enum_class._member_map_.items():
+ if canonical_member.value == enum_member._value_:
+ enum_member = canonical_member
+ break
+ else:
+ # Aliases don't appear in member names (only in __members__).
+ enum_class._member_names_.append(member_name)
+ # performance boost for any member that would not shadow
+ # a DynamicClassAttribute (aka _RouteClassAttributeToGetattr)
+ if member_name not in base_attributes:
+ setattr(enum_class, member_name, enum_member)
+ # now add to _member_map_
+ enum_class._member_map_[member_name] = enum_member
+ try:
+ # This may fail if value is not hashable. We can't add the value
+ # to the map, and by-value lookups for this value will be
+ # linear.
+ enum_class._value2member_map_[value] = enum_member
+ except TypeError:
+ pass
+
+
+ # If a custom type is mixed into the Enum, and it does not know how
+ # to pickle itself, pickle.dumps will succeed but pickle.loads will
+ # fail. Rather than have the error show up later and possibly far
+ # from the source, sabotage the pickle protocol for this class so
+ # that pickle.dumps also fails.
+ #
+ # However, if the new class implements its own __reduce_ex__, do not
+ # sabotage -- it's on them to make sure it works correctly. We use
+ # __reduce_ex__ instead of any of the others as it is preferred by
+ # pickle over __reduce__, and it handles all pickle protocols.
+ unpicklable = False
+ if '__reduce_ex__' not in classdict:
+ if member_type is not object:
+ methods = ('__getnewargs_ex__', '__getnewargs__',
+ '__reduce_ex__', '__reduce__')
+ if not any(m in member_type.__dict__ for m in methods):
+ _make_class_unpicklable(enum_class)
+ unpicklable = True
+
+
+ # double check that repr and friends are not the mixin's or various
+ # things break (such as pickle)
+ for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'):
+ class_method = getattr(enum_class, name)
+ obj_method = getattr(member_type, name, None)
+ enum_method = getattr(first_enum, name, None)
+ if name not in classdict and class_method is not enum_method:
+ if name == '__reduce_ex__' and unpicklable:
+ continue
+ setattr(enum_class, name, enum_method)
+
+ # method resolution and int's are not playing nice
+ # Python's less than 2.6 use __cmp__
+
+ if pyver < 2.6:
+
+ if issubclass(enum_class, int):
+ setattr(enum_class, '__cmp__', getattr(int, '__cmp__'))
+
+ elif pyver < 3.0:
+
+ if issubclass(enum_class, int):
+ for method in (
+ '__le__',
+ '__lt__',
+ '__gt__',
+ '__ge__',
+ '__eq__',
+ '__ne__',
+ '__hash__',
+ ):
+ setattr(enum_class, method, getattr(int, method))
+
+ # replace any other __new__ with our own (as long as Enum is not None,
+ # anyway) -- again, this is to support pickle
+ if Enum is not None:
+ # if the user defined their own __new__, save it before it gets
+ # clobbered in case they subclass later
+ if save_new:
+ setattr(enum_class, '__member_new__', enum_class.__dict__['__new__'])
+ setattr(enum_class, '__new__', Enum.__dict__['__new__'])
+ return enum_class
+
+ def __bool__(cls):
+ """
+ classes/types should always be True.
+ """
+ return True
+
+ def __call__(cls, value, names=None, module=None, type=None, start=1):
+ """Either returns an existing member, or creates a new enum class.
+
+ This method is used both when an enum class is given a value to match
+ to an enumeration member (i.e. Color(3)) and for the functional API
+ (i.e. Color = Enum('Color', names='red green blue')).
+
+ When used for the functional API: `module`, if set, will be stored in
+ the new class' __module__ attribute; `type`, if set, will be mixed in
+ as the first base class.
+
+ Note: if `module` is not set this routine will attempt to discover the
+ calling module by walking the frame stack; if this is unsuccessful
+ the resulting class will not be pickleable.
+
+ """
+ if names is None: # simple value lookup
+ return cls.__new__(cls, value)
+ # otherwise, functional API: we're creating a new Enum type
+ return cls._create_(value, names, module=module, type=type, start=start)
+
+ def __contains__(cls, member):
+ return isinstance(member, cls) and member.name in cls._member_map_
+
+ def __delattr__(cls, attr):
+ # nicer error message when someone tries to delete an attribute
+ # (see issue19025).
+ if attr in cls._member_map_:
+ raise AttributeError(
+ "%s: cannot delete Enum member." % cls.__name__)
+ super(EnumMeta, cls).__delattr__(attr)
+
+ def __dir__(self):
+ return (['__class__', '__doc__', '__members__', '__module__'] +
+ self._member_names_)
+
+ @property
+ def __members__(cls):
+ """Returns a mapping of member name->value.
+
+ This mapping lists all enum members, including aliases. Note that this
+ is a copy of the internal mapping.
+
+ """
+ return cls._member_map_.copy()
+
+ def __getattr__(cls, name):
+ """Return the enum member matching `name`
+
+ We use __getattr__ instead of descriptors or inserting into the enum
+ class' __dict__ in order to support `name` and `value` being both
+ properties for enum members (which live in the class' __dict__) and
+ enum members themselves.
+
+ """
+ if _is_dunder(name):
+ raise AttributeError(name)
+ try:
+ return cls._member_map_[name]
+ except KeyError:
+ raise AttributeError(name)
+
+ def __getitem__(cls, name):
+ return cls._member_map_[name]
+
+ def __iter__(cls):
+ return (cls._member_map_[name] for name in cls._member_names_)
+
+ def __reversed__(cls):
+ return (cls._member_map_[name] for name in reversed(cls._member_names_))
+
+ def __len__(cls):
+ return len(cls._member_names_)
+
+ __nonzero__ = __bool__
+
+ def __repr__(cls):
+ return "<enum %r>" % cls.__name__
+
+ def __setattr__(cls, name, value):
+ """Block attempts to reassign Enum members.
+
+ A simple assignment to the class namespace only changes one of the
+ several possible ways to get an Enum member from the Enum class,
+ resulting in an inconsistent Enumeration.
+
+ """
+ member_map = cls.__dict__.get('_member_map_', {})
+ if name in member_map:
+ raise AttributeError('Cannot reassign members.')
+ super(EnumMeta, cls).__setattr__(name, value)
+
+ def _create_(cls, class_name, names=None, module=None, type=None, start=1):
+ """Convenience method to create a new Enum class.
+
+ `names` can be:
+
+ * A string containing member names, separated either with spaces or
+ commas. Values are auto-numbered from 1.
+ * An iterable of member names. Values are auto-numbered from 1.
+ * An iterable of (member name, value) pairs.
+ * A mapping of member name -> value.
+
+ """
+ if pyver < 3.0:
+ # if class_name is unicode, attempt a conversion to ASCII
+ if isinstance(class_name, unicode):
+ try:
+ class_name = class_name.encode('ascii')
+ except UnicodeEncodeError:
+ raise TypeError('%r is not representable in ASCII' % class_name)
+ metacls = cls.__class__
+ if type is None:
+ bases = (cls, )
+ else:
+ bases = (type, cls)
+ classdict = metacls.__prepare__(class_name, bases)
+ _order_ = []
+
+ # special processing needed for names?
+ if isinstance(names, basestring):
+ names = names.replace(',', ' ').split()
+ if isinstance(names, (tuple, list)) and isinstance(names[0], basestring):
+ names = [(e, i+start) for (i, e) in enumerate(names)]
+
+ # Here, names is either an iterable of (name, value) or a mapping.
+ item = None # in case names is empty
+ for item in names:
+ if isinstance(item, basestring):
+ member_name, member_value = item, names[item]
+ else:
+ member_name, member_value = item
+ classdict[member_name] = member_value
+ _order_.append(member_name)
+ # only set _order_ in classdict if name/value was not from a mapping
+ if not isinstance(item, basestring):
+ classdict['_order_'] = ' '.join(_order_)
+ enum_class = metacls.__new__(metacls, class_name, bases, classdict)
+
+ # TODO: replace the frame hack if a blessed way to know the calling
+ # module is ever developed
+ if module is None:
+ try:
+ module = _sys._getframe(2).f_globals['__name__']
+ except (AttributeError, ValueError):
+ pass
+ if module is None:
+ _make_class_unpicklable(enum_class)
+ else:
+ enum_class.__module__ = module
+
+ return enum_class
+
+ @staticmethod
+ def _get_mixins_(bases):
+ """Returns the type for creating enum members, and the first inherited
+ enum class.
+
+ bases: the tuple of bases that was given to __new__
+
+ """
+ if not bases or Enum is None:
+ return object, Enum
+
+
+ # double check that we are not subclassing a class with existing
+ # enumeration members; while we're at it, see if any other data
+ # type has been mixed in so we can use the correct __new__
+ member_type = first_enum = None
+ for base in bases:
+ if (base is not Enum and
+ issubclass(base, Enum) and
+ base._member_names_):
+ raise TypeError("Cannot extend enumerations")
+ # base is now the last base in bases
+ if not issubclass(base, Enum):
+ raise TypeError("new enumerations must be created as "
+ "`ClassName([mixin_type,] enum_type)`")
+
+ # get correct mix-in type (either mix-in type of Enum subclass, or
+ # first base if last base is Enum)
+ if not issubclass(bases[0], Enum):
+ member_type = bases[0] # first data type
+ first_enum = bases[-1] # enum type
+ else:
+ for base in bases[0].__mro__:
+ # most common: (IntEnum, int, Enum, object)
+ # possible: (<Enum 'AutoIntEnum'>, <Enum 'IntEnum'>,
+ # <class 'int'>, <Enum 'Enum'>,
+ # <class 'object'>)
+ if issubclass(base, Enum):
+ if first_enum is None:
+ first_enum = base
+ else:
+ if member_type is None:
+ member_type = base
+
+ return member_type, first_enum
+
+ if pyver < 3.0:
+ @staticmethod
+ def _find_new_(classdict, member_type, first_enum):
+ """Returns the __new__ to be used for creating the enum members.
+
+ classdict: the class dictionary given to __new__
+ member_type: the data type whose __new__ will be used by default
+ first_enum: enumeration to check for an overriding __new__
+
+ """
+ # now find the correct __new__, checking to see of one was defined
+ # by the user; also check earlier enum classes in case a __new__ was
+ # saved as __member_new__
+ __new__ = classdict.get('__new__', None)
+ if __new__:
+ return None, True, True # __new__, save_new, use_args
+
+ N__new__ = getattr(None, '__new__')
+ O__new__ = getattr(object, '__new__')
+ if Enum is None:
+ E__new__ = N__new__
+ else:
+ E__new__ = Enum.__dict__['__new__']
+ # check all possibles for __member_new__ before falling back to
+ # __new__
+ for method in ('__member_new__', '__new__'):
+ for possible in (member_type, first_enum):
+ try:
+ target = possible.__dict__[method]
+ except (AttributeError, KeyError):
+ target = getattr(possible, method, None)
+ if target not in [
+ None,
+ N__new__,
+ O__new__,
+ E__new__,
+ ]:
+ if method == '__member_new__':
+ classdict['__new__'] = target
+ return None, False, True
+ if isinstance(target, staticmethod):
+ target = target.__get__(member_type)
+ __new__ = target
+ break
+ if __new__ is not None:
+ break
+ else:
+ __new__ = object.__new__
+
+ # if a non-object.__new__ is used then whatever value/tuple was
+ # assigned to the enum member name will be passed to __new__ and to the
+ # new enum member's __init__
+ if __new__ is object.__new__:
+ use_args = False
+ else:
+ use_args = True
+
+ return __new__, False, use_args
+ else:
+ @staticmethod
+ def _find_new_(classdict, member_type, first_enum):
+ """Returns the __new__ to be used for creating the enum members.
+
+ classdict: the class dictionary given to __new__
+ member_type: the data type whose __new__ will be used by default
+ first_enum: enumeration to check for an overriding __new__
+
+ """
+ # now find the correct __new__, checking to see of one was defined
+ # by the user; also check earlier enum classes in case a __new__ was
+ # saved as __member_new__
+ __new__ = classdict.get('__new__', None)
+
+ # should __new__ be saved as __member_new__ later?
+ save_new = __new__ is not None
+
+ if __new__ is None:
+ # check all possibles for __member_new__ before falling back to
+ # __new__
+ for method in ('__member_new__', '__new__'):
+ for possible in (member_type, first_enum):
+ target = getattr(possible, method, None)
+ if target not in (
+ None,
+ None.__new__,
+ object.__new__,
+ Enum.__new__,
+ ):
+ __new__ = target
+ break
+ if __new__ is not None:
+ break
+ else:
+ __new__ = object.__new__
+
+ # if a non-object.__new__ is used then whatever value/tuple was
+ # assigned to the enum member name will be passed to __new__ and to the
+ # new enum member's __init__
+ if __new__ is object.__new__:
+ use_args = False
+ else:
+ use_args = True
+
+ return __new__, save_new, use_args
+
+
+########################################################
+# In order to support Python 2 and 3 with a single
+# codebase we have to create the Enum methods separately
+# and then use the `type(name, bases, dict)` method to
+# create the class.
+########################################################
+temp_enum_dict = {}
+temp_enum_dict['__doc__'] = "Generic enumeration.\n\n Derive from this class to define new enumerations.\n\n"
+
+def __new__(cls, value):
+ # all enum instances are actually created during class construction
+ # without calling this method; this method is called by the metaclass'
+ # __call__ (i.e. Color(3) ), and by pickle
+ if type(value) is cls:
+ # For lookups like Color(Color.red)
+ value = value.value
+ #return value
+ # by-value search for a matching enum member
+ # see if it's in the reverse mapping (for hashable values)
+ try:
+ if value in cls._value2member_map_:
+ return cls._value2member_map_[value]
+ except TypeError:
+ # not there, now do long search -- O(n) behavior
+ for member in cls._member_map_.values():
+ if member.value == value:
+ return member
+ raise ValueError("%s is not a valid %s" % (value, cls.__name__))
+temp_enum_dict['__new__'] = __new__
+del __new__
+
+def __repr__(self):
+ return "<%s.%s: %r>" % (
+ self.__class__.__name__, self._name_, self._value_)
+temp_enum_dict['__repr__'] = __repr__
+del __repr__
+
+def __str__(self):
+ return "%s.%s" % (self.__class__.__name__, self._name_)
+temp_enum_dict['__str__'] = __str__
+del __str__
+
+if pyver >= 3.0:
+ def __dir__(self):
+ added_behavior = [
+ m
+ for cls in self.__class__.mro()
+ for m in cls.__dict__
+ if m[0] != '_' and m not in self._member_map_
+ ]
+ return (['__class__', '__doc__', '__module__', ] + added_behavior)
+ temp_enum_dict['__dir__'] = __dir__
+ del __dir__
+
+def __format__(self, format_spec):
+ # mixed-in Enums should use the mixed-in type's __format__, otherwise
+ # we can get strange results with the Enum name showing up instead of
+ # the value
+
+ # pure Enum branch
+ if self._member_type_ is object:
+ cls = str
+ val = str(self)
+ # mix-in branch
+ else:
+ cls = self._member_type_
+ val = self.value
+ return cls.__format__(val, format_spec)
+temp_enum_dict['__format__'] = __format__
+del __format__
+
+
+####################################
+# Python's less than 2.6 use __cmp__
+
+if pyver < 2.6:
+
+ def __cmp__(self, other):
+ if type(other) is self.__class__:
+ if self is other:
+ return 0
+ return -1
+ return NotImplemented
+ raise TypeError("unorderable types: %s() and %s()" % (self.__class__.__name__, other.__class__.__name__))
+ temp_enum_dict['__cmp__'] = __cmp__
+ del __cmp__
+
+else:
+
+ def __le__(self, other):
+ raise TypeError("unorderable types: %s() <= %s()" % (self.__class__.__name__, other.__class__.__name__))
+ temp_enum_dict['__le__'] = __le__
+ del __le__
+
+ def __lt__(self, other):
+ raise TypeError("unorderable types: %s() < %s()" % (self.__class__.__name__, other.__class__.__name__))
+ temp_enum_dict['__lt__'] = __lt__
+ del __lt__
+
+ def __ge__(self, other):
+ raise TypeError("unorderable types: %s() >= %s()" % (self.__class__.__name__, other.__class__.__name__))
+ temp_enum_dict['__ge__'] = __ge__
+ del __ge__
+
+ def __gt__(self, other):
+ raise TypeError("unorderable types: %s() > %s()" % (self.__class__.__name__, other.__class__.__name__))
+ temp_enum_dict['__gt__'] = __gt__
+ del __gt__
+
+
+def __eq__(self, other):
+ if type(other) is self.__class__:
+ return self is other
+ return NotImplemented
+temp_enum_dict['__eq__'] = __eq__
+del __eq__
+
+def __ne__(self, other):
+ if type(other) is self.__class__:
+ return self is not other
+ return NotImplemented
+temp_enum_dict['__ne__'] = __ne__
+del __ne__
+
+def __hash__(self):
+ return hash(self._name_)
+temp_enum_dict['__hash__'] = __hash__
+del __hash__
+
+def __reduce_ex__(self, proto):
+ return self.__class__, (self._value_, )
+temp_enum_dict['__reduce_ex__'] = __reduce_ex__
+del __reduce_ex__
+
+# _RouteClassAttributeToGetattr is used to provide access to the `name`
+# and `value` properties of enum members while keeping some measure of
+# protection from modification, while still allowing for an enumeration
+# to have members named `name` and `value`. This works because enumeration
+# members are not set directly on the enum class -- __getattr__ is
+# used to look them up.
+
+@_RouteClassAttributeToGetattr
+def name(self):
+ return self._name_
+temp_enum_dict['name'] = name
+del name
+
+@_RouteClassAttributeToGetattr
+def value(self):
+ return self._value_
+temp_enum_dict['value'] = value
+del value
+
+@classmethod
+def _convert(cls, name, module, filter, source=None):
+ """
+ Create a new Enum subclass that replaces a collection of global constants
+ """
+ # convert all constants from source (or module) that pass filter() to
+ # a new Enum called name, and export the enum and its members back to
+ # module;
+ # also, replace the __reduce_ex__ method so unpickling works in
+ # previous Python versions
+ module_globals = vars(_sys.modules[module])
+ if source:
+ source = vars(source)
+ else:
+ source = module_globals
+ members = dict((name, value) for name, value in source.items() if filter(name))
+ cls = cls(name, members, module=module)
+ cls.__reduce_ex__ = _reduce_ex_by_name
+ module_globals.update(cls.__members__)
+ module_globals[name] = cls
+ return cls
+temp_enum_dict['_convert'] = _convert
+del _convert
+
+Enum = EnumMeta('Enum', (object, ), temp_enum_dict)
+del temp_enum_dict
+
+# Enum has now been created
+###########################
+
+class IntEnum(int, Enum):
+ """Enum where members are also (and must be) ints"""
+
+def _reduce_ex_by_name(self, proto):
+ return self.name
+
+def unique(enumeration):
+ """Class decorator that ensures only unique members exist in an enumeration."""
+ duplicates = []
+ for name, member in enumeration.__members__.items():
+ if name != member.name:
+ duplicates.append((name, member.name))
+ if duplicates:
+ duplicate_names = ', '.join(
+ ["%s -> %s" % (alias, name) for (alias, name) in duplicates]
+ )
+ raise ValueError('duplicate names found in %r: %s' %
+ (enumeration, duplicate_names)
+ )
+ return enumeration
diff --git a/third_party/python/enum34/enum/doc/enum.pdf b/third_party/python/enum34/enum/doc/enum.pdf
new file mode 100644
index 0000000000..8c1383a495
--- /dev/null
+++ b/third_party/python/enum34/enum/doc/enum.pdf
@@ -0,0 +1,2237 @@
+%PDF-1.4
+%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
+1 0 obj
+<< /F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R /F5 8 0 R /F6 15 0 R >>
+endobj
+2 0 obj
+<< /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >>
+endobj
+3 0 obj
+<< /BaseFont /Courier-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font >>
+endobj
+4 0 obj
+<< /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font >>
+endobj
+5 0 obj
+<< /BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font >>
+endobj
+6 0 obj
+<< /Border [ 0 0 0 ] /Contents () /Dest [ 22 0 R /XYZ 62.69291 639.3236 0 ] /Rect [ 335.1805 574.4272 405.2473 586.4272 ] /Subtype /Link /Type /Annot >>
+endobj
+7 0 obj
+<< /Border [ 0 0 0 ] /Contents () /Dest [ 22 0 R /XYZ 62.69291 639.3236 0 ] /Rect [ 255.9742 427.4272 321.5378 439.4272 ] /Subtype /Link /Type /Annot >>
+endobj
+8 0 obj
+<< /BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F5 /Subtype /Type1 /Type /Font >>
+endobj
+9 0 obj
+<< /Border [ 0 0 0 ] /Contents () /Dest [ 26 0 R /XYZ 62.69291 278.1236 0 ] /Rect [ 82.69291 182.2272 201.0729 194.2272 ] /Subtype /Link /Type /Annot >>
+endobj
+10 0 obj
+<< /Annots [ 6 0 R 7 0 R 9 0 R ] /Contents 56 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 55 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
+ /Trans << >> /Type /Page >>
+endobj
+11 0 obj
+<< /Contents 57 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 55 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
+ /Type /Page >>
+endobj
+12 0 obj
+<< /Contents 58 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 55 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
+ /Type /Page >>
+endobj
+13 0 obj
+<< /Contents 59 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 55 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
+ /Type /Page >>
+endobj
+14 0 obj
+<< /Border [ 0 0 0 ] /Contents () /Dest [ 22 0 R /XYZ 62.69291 157.2236 0 ] /Rect [ 101.6029 741.7736 141.6229 753.7736 ] /Subtype /Link /Type /Annot >>
+endobj
+15 0 obj
+<< /BaseFont /Helvetica-BoldOblique /Encoding /WinAnsiEncoding /Name /F6 /Subtype /Type1 /Type /Font >>
+endobj
+16 0 obj
+<< /Border [ 0 0 0 ] /Contents () /Dest [ 25 0 R /XYZ 62.69291 359.6236 0 ] /Rect [ 327.1529 585.5736 392.7329 597.5736 ] /Subtype /Link /Type /Annot >>
+endobj
+17 0 obj
+<< /Border [ 0 0 0 ] /Contents () /Dest [ 22 0 R /XYZ 62.69291 639.3236 0 ] /Rect [ 181.1917 312.1736 246.4634 324.1736 ] /Subtype /Link /Type /Annot >>
+endobj
+18 0 obj
+<< /Annots [ 14 0 R 16 0 R 17 0 R ] /Contents 60 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 55 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
+ /Trans << >> /Type /Page >>
+endobj
+19 0 obj
+<< /Border [ 0 0 0 ] /Contents () /Dest [ 26 0 R /XYZ 62.69291 610.8236 0 ] /Rect [ 326.1329 511.3736 357.2629 523.3736 ] /Subtype /Link /Type /Annot >>
+endobj
+20 0 obj
+<< /Border [ 0 0 0 ] /Contents () /Dest [ 25 0 R /XYZ 62.69291 359.6236 0 ] /Rect [ 241.1229 185.9736 306.7029 197.9736 ] /Subtype /Link /Type /Annot >>
+endobj
+21 0 obj
+<< /Annots [ 19 0 R 20 0 R ] /Contents 61 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 55 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
+ /Trans << >> /Type /Page >>
+endobj
+22 0 obj
+<< /Contents 62 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 55 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
+ /Type /Page >>
+endobj
+23 0 obj
+<< /Contents 63 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 55 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
+ /Type /Page >>
+endobj
+24 0 obj
+<< /Contents 64 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 55 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
+ /Type /Page >>
+endobj
+25 0 obj
+<< /Contents 65 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 55 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
+ /Type /Page >>
+endobj
+26 0 obj
+<< /Contents 66 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 55 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
+ /Type /Page >>
+endobj
+27 0 obj
+<< /Border [ 0 0 0 ] /Contents () /Dest [ 26 0 R /XYZ 62.69291 610.8236 0 ] /Rect [ 309.4094 299.5736 340.6461 311.5736 ] /Subtype /Link /Type /Annot >>
+endobj
+28 0 obj
+<< /Annots [ 27 0 R ] /Contents 67 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 55 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
+ /Trans << >> /Type /Page >>
+endobj
+29 0 obj
+<< /Outlines 31 0 R /PageLabels 68 0 R /PageMode /UseNone /Pages 55 0 R /Type /Catalog >>
+endobj
+30 0 obj
+<< /Author () /CreationDate (D:20160515202831+08'00') /Creator (\(unspecified\)) /Keywords () /Producer (ReportLab PDF Library - www.reportlab.com) /Subject (\(unspecified\))
+ /Title (enum --- support for enumerations) >>
+endobj
+31 0 obj
+<< /Count 27 /First 32 0 R /Last 51 0 R /Type /Outlines >>
+endobj
+32 0 obj
+<< /Dest [ 10 0 R /XYZ 62.69291 660.6772 0 ] /Next 33 0 R /Parent 31 0 R /Title (Module Contents) >>
+endobj
+33 0 obj
+<< /Dest [ 10 0 R /XYZ 62.69291 477.6772 0 ] /Next 34 0 R /Parent 31 0 R /Prev 32 0 R /Title (Creating an Enum) >>
+endobj
+34 0 obj
+<< /Dest [ 11 0 R /XYZ 62.69291 197.0236 0 ] /Next 35 0 R /Parent 31 0 R /Prev 33 0 R /Title (Programmatic access to enumeration members and their attributes) >>
+endobj
+35 0 obj
+<< /Dest [ 12 0 R /XYZ 62.69291 501.4236 0 ] /Next 36 0 R /Parent 31 0 R /Prev 34 0 R /Title (Duplicating enum members and values) >>
+endobj
+36 0 obj
+<< /Dest [ 13 0 R /XYZ 62.69291 215.0236 0 ] /Next 37 0 R /Parent 31 0 R /Prev 35 0 R /Title (Comparisons) >>
+endobj
+37 0 obj
+<< /Dest [ 18 0 R /XYZ 62.69291 362.4236 0 ] /Next 38 0 R /Parent 31 0 R /Prev 36 0 R /Title (Allowed members and attributes of enumerations) >>
+endobj
+38 0 obj
+<< /Dest [ 21 0 R /XYZ 62.69291 498.6236 0 ] /Next 39 0 R /Parent 31 0 R /Prev 37 0 R /Title (Restricted subclassing of enumerations) >>
+endobj
+39 0 obj
+<< /Dest [ 21 0 R /XYZ 62.69291 173.2236 0 ] /Next 40 0 R /Parent 31 0 R /Prev 38 0 R /Title (Pickling) >>
+endobj
+40 0 obj
+<< /Dest [ 22 0 R /XYZ 62.69291 635.8236 0 ] /Next 41 0 R /Parent 31 0 R /Prev 39 0 R /Title (Functional API) >>
+endobj
+41 0 obj
+<< /Count 2 /Dest [ 22 0 R /XYZ 62.69291 187.2236 0 ] /First 42 0 R /Last 43 0 R /Next 44 0 R /Parent 31 0 R
+ /Prev 40 0 R /Title (Derived Enumerations) >>
+endobj
+42 0 obj
+<< /Dest [ 22 0 R /XYZ 62.69291 154.2236 0 ] /Next 43 0 R /Parent 41 0 R /Title (IntEnum) >>
+endobj
+43 0 obj
+<< /Dest [ 23 0 R /XYZ 62.69291 217.4236 0 ] /Parent 41 0 R /Prev 42 0 R /Title (Others) >>
+endobj
+44 0 obj
+<< /Count 1 /Dest [ 24 0 R /XYZ 62.69291 567.0236 0 ] /First 45 0 R /Last 45 0 R /Next 46 0 R /Parent 31 0 R
+ /Prev 41 0 R /Title (Decorators) >>
+endobj
+45 0 obj
+<< /Dest [ 24 0 R /XYZ 62.69291 534.0236 0 ] /Parent 44 0 R /Title (unique) >>
+endobj
+46 0 obj
+<< /Count 4 /Dest [ 24 0 R /XYZ 62.69291 356.8236 0 ] /First 47 0 R /Last 50 0 R /Next 51 0 R /Parent 31 0 R
+ /Prev 44 0 R /Title (Interesting examples) >>
+endobj
+47 0 obj
+<< /Dest [ 24 0 R /XYZ 62.69291 281.8236 0 ] /Next 48 0 R /Parent 46 0 R /Title (AutoNumber) >>
+endobj
+48 0 obj
+<< /Dest [ 25 0 R /XYZ 62.69291 641.8236 0 ] /Next 49 0 R /Parent 46 0 R /Prev 47 0 R /Title (UniqueEnum) >>
+endobj
+49 0 obj
+<< /Dest [ 25 0 R /XYZ 62.69291 356.6236 0 ] /Next 50 0 R /Parent 46 0 R /Prev 48 0 R /Title (OrderedEnum) >>
+endobj
+50 0 obj
+<< /Dest [ 26 0 R /XYZ 62.69291 607.8236 0 ] /Parent 46 0 R /Prev 49 0 R /Title (Planet) >>
+endobj
+51 0 obj
+<< /Count 3 /Dest [ 26 0 R /XYZ 62.69291 274.6236 0 ] /First 52 0 R /Last 54 0 R /Parent 31 0 R /Prev 46 0 R
+ /Title (How are Enums different?) >>
+endobj
+52 0 obj
+<< /Dest [ 26 0 R /XYZ 62.69291 211.6236 0 ] /Next 53 0 R /Parent 51 0 R /Title (Enum Classes) >>
+endobj
+53 0 obj
+<< /Dest [ 28 0 R /XYZ 62.69291 664.0236 0 ] /Next 54 0 R /Parent 51 0 R /Prev 52 0 R /Title (Enum Members \(aka instances\)) >>
+endobj
+54 0 obj
+<< /Dest [ 28 0 R /XYZ 62.69291 592.0236 0 ] /Parent 51 0 R /Prev 53 0 R /Title (Finer Points) >>
+endobj
+55 0 obj
+<< /Count 12 /Kids [ 10 0 R 11 0 R 12 0 R 13 0 R 18 0 R 21 0 R 22 0 R 23 0 R 24 0 R 25 0 R
+ 26 0 R 28 0 R ] /Type /Pages >>
+endobj
+56 0 obj
+<< /Length 6458 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 741.0236 cm
+q
+BT 1 0 0 1 0 4 Tm 73.71488 0 Td 24 TL /F2 20 Tf 0 0 0 rg (enum ) Tj /F3 20 Tf 0 0 0 rg (--- support for enumerations) Tj T* -73.71488 0 Td ET
+Q
+Q
+q
+1 0 0 1 62.69291 702.6772 cm
+n 0 14.17323 m 469.8898 14.17323 l S
+Q
+q
+1 0 0 1 62.69291 672.6772 cm
+q
+BT 1 0 0 1 0 14 Tm 2.091318 Tw 12 TL /F1 10 Tf 0 0 0 rg (An enumeration is a set of symbolic names \(members\) bound to unique, constant values. Within an) Tj T* 0 Tw (enumeration, the members can be compared by identity, and the enumeration itself can be iterated over.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 639.6772 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Module Contents) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 609.6772 cm
+q
+BT 1 0 0 1 0 14 Tm 2.027485 Tw 12 TL /F1 10 Tf 0 0 0 rg (This module defines two enumeration classes that can be used to define unique sets of names and) Tj T* 0 Tw (values: ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F4 10 Tf 0 0 0 rg (IntEnum) Tj /F1 10 Tf 0 0 0 rg (. It also defines one decorator, ) Tj /F4 10 Tf 0 0 0 rg (unique) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 591.6772 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (Enum) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 561.6772 cm
+q
+BT 1 0 0 1 0 14 Tm 1.128443 Tw 12 TL /F1 10 Tf 0 0 0 rg (Base class for creating enumerated constants. See section ) Tj 0 0 .501961 rg (Functional API ) Tj 0 0 0 rg (for an alternate construction) Tj T* 0 Tw (syntax.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 543.6772 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (IntEnum) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 525.6772 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Base class for creating enumerated constants that are also subclasses of ) Tj /F4 10 Tf 0 0 0 rg (int) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 507.6772 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F4 10 Tf 12 TL (unique) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 489.6772 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Enum class decorator that ensures only one name is bound to any one value.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 456.6772 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Creating an Enum) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 414.6772 cm
+q
+BT 1 0 0 1 0 26 Tm 2.432651 Tw 12 TL /F1 10 Tf 0 0 0 rg (Enumerations are created using the ) Tj /F4 10 Tf 0 0 0 rg (class ) Tj /F1 10 Tf 0 0 0 rg (syntax, which makes them easy to read and write. An) Tj T* 0 Tw .533555 Tw (alternative creation method is described in ) Tj 0 0 .501961 rg (Functional API) Tj 0 0 0 rg (. To define an enumeration, subclass ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (as) Tj T* 0 Tw (follows:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 333.4772 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 72 re B*
+Q
+q
+BT 1 0 0 1 0 50 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( from enum import Enum) Tj T* (>) Tj (>) Tj (>) Tj ( class Color\(Enum\):) Tj T* (... red = 1) Tj T* (... green = 2) Tj T* (... blue = 3) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 313.4772 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Note: Nomenclature) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 307.4772 cm
+Q
+q
+1 0 0 1 62.69291 229.4772 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+BT 1 0 0 1 0 2 Tm T* ET
+q
+1 0 0 1 20 72 cm
+Q
+q
+1 0 0 1 20 72 cm
+Q
+q
+1 0 0 1 20 60 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The class ) Tj /F4 10 Tf 0 0 0 rg (Color ) Tj /F1 10 Tf 0 0 0 rg (is an ) Tj /F5 10 Tf (enumeration ) Tj /F1 10 Tf (\(or ) Tj /F5 10 Tf (enum) Tj /F1 10 Tf (\)) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 20 54 cm
+Q
+q
+1 0 0 1 20 30 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 9 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+BT 1 0 0 1 0 14 Tm 5.568863 Tw 12 TL /F1 10 Tf 0 0 0 rg (The attributes ) Tj /F4 10 Tf 0 0 0 rg (Color.red) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F4 10 Tf 0 0 0 rg (Color.green) Tj /F1 10 Tf 0 0 0 rg (, etc., are ) Tj /F5 10 Tf (enumeration members ) Tj /F1 10 Tf (\(or ) Tj /F5 10 Tf (enum) Tj T* 0 Tw (members) Tj /F1 10 Tf (\).) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 20 24 cm
+Q
+q
+1 0 0 1 20 0 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 9 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+BT 1 0 0 1 0 14 Tm 1.471318 Tw 12 TL /F1 10 Tf 0 0 0 rg (The enum members have ) Tj /F5 10 Tf (names ) Tj /F1 10 Tf (and ) Tj /F5 10 Tf (values ) Tj /F1 10 Tf (\(the name of ) Tj /F4 10 Tf 0 0 0 rg (Color.red ) Tj /F1 10 Tf 0 0 0 rg (is ) Tj /F4 10 Tf 0 0 0 rg (red) Tj /F1 10 Tf 0 0 0 rg (, the value of) Tj T* 0 Tw /F4 10 Tf 0 0 0 rg (Color.blue ) Tj /F1 10 Tf 0 0 0 rg (is ) Tj /F4 10 Tf 0 0 0 rg (3) Tj /F1 10 Tf 0 0 0 rg (, etc.\)) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 20 0 cm
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 229.4772 cm
+Q
+q
+1 0 0 1 62.69291 211.4772 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Note:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 205.4772 cm
+Q
+q
+1 0 0 1 62.69291 181.4772 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+BT 1 0 0 1 0 2 Tm T* ET
+q
+1 0 0 1 20 0 cm
+q
+BT 1 0 0 1 0 14 Tm .126235 Tw 12 TL /F1 10 Tf 0 0 0 rg (Even though we use the ) Tj /F4 10 Tf 0 0 0 rg (class ) Tj /F1 10 Tf 0 0 0 rg (syntax to create Enums, Enums are not normal Python classes. See) Tj T* 0 Tw 0 0 .501961 rg (How are Enums different? ) Tj 0 0 0 rg (for more details.) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 181.4772 cm
+Q
+q
+1 0 0 1 62.69291 163.4772 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Enumeration members have human readable string representations:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 118.2772 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 36 re B*
+Q
+q
+BT 1 0 0 1 0 14 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( print\(Color.red\)) Tj T* (Color.red) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 98.27717 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (...while their ) Tj /F4 10 Tf 0 0 0 rg (repr ) Tj /F1 10 Tf 0 0 0 rg (has more information:) Tj T* ET
+Q
+Q
+
+endstream
+endobj
+57 0 obj
+<< /Length 4174 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 727.8236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 36 re B*
+Q
+q
+BT 1 0 0 1 0 14 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( print\(repr\(Color.red\)\)) Tj T* (<) Tj (Color.red: 1) Tj (>) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 707.8236 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F5 10 Tf (type ) Tj /F1 10 Tf (of an enumeration member is the enumeration it belongs to:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 626.6236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 72 re B*
+Q
+q
+BT 1 0 0 1 0 50 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( type\(Color.red\)) Tj T* (<) Tj (enum 'Color') Tj (>) Tj T* (>) Tj (>) Tj (>) Tj ( isinstance\(Color.green, Color\)) Tj T* (True) Tj T* (>) Tj (>) Tj (>) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 606.6236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Enum members also have a property that contains just their item name:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 561.4236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 36 re B*
+Q
+q
+BT 1 0 0 1 0 14 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( print\(Color.red.name\)) Tj T* (red) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 529.4236 cm
+q
+BT 1 0 0 1 0 14 Tm .464985 Tw 12 TL /F1 10 Tf 0 0 0 rg (Enumerations support iteration. In Python 3.x definition order is used; in Python 2.x the definition order is) Tj T* 0 Tw (not available, but class attribute ) Tj /F4 10 Tf 0 0 0 rg (__order__ ) Tj /F1 10 Tf 0 0 0 rg (is supported; otherwise, value order is used:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 340.2236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 180 re B*
+Q
+q
+BT 1 0 0 1 0 158 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( class Shake\(Enum\):) Tj T* (... __order__ = 'vanilla chocolate cookies mint' # only needed in 2.x) Tj T* (... vanilla = 7) Tj T* (... chocolate = 4) Tj T* (... cookies = 9) Tj T* (... mint = 3) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( for shake in Shake:) Tj T* (... print\(shake\)) Tj T* (...) Tj T* (Shake.vanilla) Tj T* (Shake.chocolate) Tj T* (Shake.cookies) Tj T* (Shake.mint) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 308.2236 cm
+q
+BT 1 0 0 1 0 14 Tm 1.893735 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F4 10 Tf 0 0 0 rg (__order__ ) Tj /F1 10 Tf 0 0 0 rg (attribute is always removed, and in 3.x it is also ignored \(order is definition order\);) Tj T* 0 Tw (however, in the stdlib version it will be ignored but not removed.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 290.2236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Enumeration members are hashable, so they can be used in dictionaries and sets:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 209.0236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 72 re B*
+Q
+q
+BT 1 0 0 1 0 50 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( apples = {}) Tj T* (>) Tj (>) Tj (>) Tj ( apples[Color.red] = 'red delicious') Tj T* (>) Tj (>) Tj (>) Tj ( apples[Color.green] = 'granny smith') Tj T* (>) Tj (>) Tj (>) Tj ( apples == {Color.red: 'red delicious', Color.green: 'granny smith'}) Tj T* (True) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 155.0236 cm
+q
+BT 1 0 0 1 0 24.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Programmatic access to enumeration members and) Tj T* (their attributes) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 113.0236 cm
+q
+BT 1 0 0 1 0 26 Tm 3.541797 Tw 12 TL /F1 10 Tf 0 0 0 rg (Sometimes it's useful to access members in enumerations programmatically \(i.e. situations where) Tj T* 0 Tw .922651 Tw /F4 10 Tf 0 0 0 rg (Color.red ) Tj /F1 10 Tf 0 0 0 rg (won't do because the exact color is not known at program-writing time\). ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (allows such) Tj T* 0 Tw (access:) Tj T* ET
+Q
+Q
+
+endstream
+endobj
+58 0 obj
+<< /Length 3791 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 703.8236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 60 re B*
+Q
+q
+BT 1 0 0 1 0 38 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( Color\(1\)) Tj T* (<) Tj (Color.red: 1) Tj (>) Tj T* (>) Tj (>) Tj (>) Tj ( Color\(3\)) Tj T* (<) Tj (Color.blue: 3) Tj (>) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 683.8236 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If you want to access enum members by ) Tj /F5 10 Tf (name) Tj /F1 10 Tf (, use item access:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 614.6236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 60 re B*
+Q
+q
+BT 1 0 0 1 0 38 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( Color['red']) Tj T* (<) Tj (Color.red: 1) Tj (>) Tj T* (>) Tj (>) Tj (>) Tj ( Color['green']) Tj T* (<) Tj (Color.green: 2) Tj (>) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 594.6236 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If have an enum member and need its ) Tj /F4 10 Tf 0 0 0 rg (name ) Tj /F1 10 Tf 0 0 0 rg (or ) Tj /F4 10 Tf 0 0 0 rg (value) Tj /F1 10 Tf 0 0 0 rg (:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 513.4236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 72 re B*
+Q
+q
+BT 1 0 0 1 0 50 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( member = Color.red) Tj T* (>) Tj (>) Tj (>) Tj ( member.name) Tj T* ('red') Tj T* (>) Tj (>) Tj (>) Tj ( member.value) Tj T* (1) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 480.4236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Duplicating enum members and values) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 450.4236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .13832 Tw (Having two enum members \(or any other attribute\) with the same name is invalid; in Python 3.x this would) Tj T* 0 Tw (raise an error, but in Python 2.x the second member simply overwrites the first:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 249.2236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 192 re B*
+Q
+q
+BT 1 0 0 1 0 170 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( # python 2.x) Tj T* (>) Tj (>) Tj (>) Tj ( class Shape\(Enum\):) Tj T* (... square = 2) Tj T* (... square = 3) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( Shape.square) Tj T* (<) Tj (Shape.square: 3) Tj (>) Tj T* T* (>) Tj (>) Tj (>) Tj ( # python 3.x) Tj T* (>) Tj (>) Tj (>) Tj ( class Shape\(Enum\):) Tj T* (... square = 2) Tj T* (... square = 3) Tj T* (Traceback \(most recent call last\):) Tj T* (...) Tj T* (TypeError: Attempted to reuse key: 'square') Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 205.2236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL .384987 Tw (However, two enum members are allowed to have the same value. Given two members A and B with the) Tj T* 0 Tw .444772 Tw (same value \(and A defined first\), B is an alias to A. By-value lookup of the value of A and B will return A.) Tj T* 0 Tw (By-name lookup of B will also return A:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 88.02362 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 492 108 re B*
+Q
+q
+BT 1 0 0 1 0 86 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( class Shape\(Enum\):) Tj T* (... __order__ = 'square diamond circle alias_for_square' # only needed in 2.x) Tj T* (... square = 2) Tj T* (... diamond = 1) Tj T* (... circle = 3) Tj T* (... alias_for_square = 2) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( Shape.square) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+
+endstream
+endobj
+59 0 obj
+<< /Length 4406 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 691.8236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 72 re B*
+Q
+q
+BT 1 0 0 1 0 50 Tm 12 TL /F4 10 Tf 0 0 0 rg (<) Tj (Shape.square: 2) Tj (>) Tj T* (>) Tj (>) Tj (>) Tj ( Shape.alias_for_square) Tj T* (<) Tj (Shape.square: 2) Tj (>) Tj T* (>) Tj (>) Tj (>) Tj ( Shape\(2\)) Tj T* (<) Tj (Shape.square: 2) Tj (>) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 659.8236 cm
+q
+BT 1 0 0 1 0 14 Tm 1.074104 Tw 12 TL /F1 10 Tf 0 0 0 rg (Allowing aliases is not always desirable. ) Tj /F4 10 Tf 0 0 0 rg (unique ) Tj /F1 10 Tf 0 0 0 rg (can be used to ensure that none exist in a particular) Tj T* 0 Tw (enumeration:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 506.6236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 144 re B*
+Q
+q
+BT 1 0 0 1 0 122 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( from enum import unique) Tj T* (>) Tj (>) Tj (>) Tj ( @unique) Tj T* (... class Mistake\(Enum\):) Tj T* (... __order__ = 'one two three four' # only needed in 2.x) Tj T* (... one = 1) Tj T* (... two = 2) Tj T* (... three = 3) Tj T* (... four = 3) Tj T* (Traceback \(most recent call last\):) Tj T* (...) Tj T* (ValueError: duplicate names found in ) Tj (<) Tj (enum 'Mistake') Tj (>) Tj (: four -) Tj (>) Tj ( three) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 486.6236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Iterating over the members of an enum does not provide the aliases:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 441.4236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 36 re B*
+Q
+q
+BT 1 0 0 1 0 14 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( list\(Shape\)) Tj T* ([) Tj (<) Tj (Shape.square: 2) Tj (>) Tj (, ) Tj (<) Tj (Shape.diamond: 1) Tj (>) Tj (, ) Tj (<) Tj (Shape.circle: 3) Tj (>) Tj (]) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 409.4236 cm
+q
+BT 1 0 0 1 0 14 Tm 1.307126 Tw 12 TL /F1 10 Tf 0 0 0 rg (The special attribute ) Tj /F4 10 Tf 0 0 0 rg (__members__ ) Tj /F1 10 Tf 0 0 0 rg (is a dictionary mapping names to members. It includes all names) Tj T* 0 Tw (defined in the enumeration, including the aliases:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 304.2236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 96 re B*
+Q
+q
+BT 1 0 0 1 0 74 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( for name, member in sorted\(Shape.__members__.items\(\)\):) Tj T* (... name, member) Tj T* (...) Tj T* (\('alias_for_square', ) Tj (<) Tj (Shape.square: 2) Tj (>) Tj (\)) Tj T* (\('circle', ) Tj (<) Tj (Shape.circle: 3) Tj (>) Tj (\)) Tj T* (\('diamond', ) Tj (<) Tj (Shape.diamond: 1) Tj (>) Tj (\)) Tj T* (\('square', ) Tj (<) Tj (Shape.square: 2) Tj (>) Tj (\)) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 272.2236 cm
+q
+BT 1 0 0 1 0 14 Tm .080751 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F4 10 Tf 0 0 0 rg (__members__ ) Tj /F1 10 Tf 0 0 0 rg (attribute can be used for detailed programmatic access to the enumeration members.) Tj T* 0 Tw (For example, finding all the aliases:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 227.0236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 486 36 re B*
+Q
+q
+BT 1 0 0 1 0 14 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( [name for name, member in Shape.__members__.items\(\) if member.name != name]) Tj T* (['alias_for_square']) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 194.0236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Comparisons) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 176.0236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Enumeration members are compared by identity:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 82.82362 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 84 re B*
+Q
+q
+BT 1 0 0 1 0 62 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( Color.red is Color.red) Tj T* (True) Tj T* (>) Tj (>) Tj (>) Tj ( Color.red is Color.blue) Tj T* (False) Tj T* (>) Tj (>) Tj (>) Tj ( Color.red is not Color.blue) Tj T* (True) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+
+endstream
+endobj
+60 0 obj
+<< /Length 4521 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 741.0236 cm
+q
+BT 1 0 0 1 0 14 Tm 1.131647 Tw 12 TL /F1 10 Tf 0 0 0 rg (Ordered comparisons between enumeration values are ) Tj /F5 10 Tf (not ) Tj /F1 10 Tf (supported. Enum members are not integers) Tj T* 0 Tw (\(but see ) Tj 0 0 .501961 rg (IntEnum ) Tj 0 0 0 rg (below\):) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 671.8236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 60 re B*
+Q
+q
+BT 1 0 0 1 0 38 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( Color.red ) Tj (<) Tj ( Color.blue) Tj T* (Traceback \(most recent call last\):) Tj T* ( File ") Tj (<) Tj (stdin) Tj (>) Tj (", line 1, in ) Tj (<) Tj (module) Tj (>) Tj T* (TypeError: unorderable types: Color\(\) ) Tj (<) Tj ( Color\(\)) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 651.8236 cm
+Q
+q
+1 0 0 1 62.69291 568.8236 cm
+.960784 .960784 .862745 rg
+n 0 83 469.8898 -83 re f*
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+BT 1 0 0 1 6 57 Tm T* ET
+q
+1 0 0 1 16 52 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2.5 Tm /F6 12.5 Tf 15 TL (Warning) Tj T* ET
+Q
+Q
+q
+1 0 0 1 16 16 cm
+q
+BT 1 0 0 1 0 14 Tm .189398 Tw 12 TL /F1 10 Tf 0 0 0 rg (In Python 2 ) Tj /F5 10 Tf (everything ) Tj /F1 10 Tf (is ordered, even though the ordering may not make sense. If you want your) Tj T* 0 Tw (enumerations to have a sensible ordering check out the ) Tj 0 0 .501961 rg (OrderedEnum ) Tj 0 0 0 rg (recipe below.) Tj T* ET
+Q
+Q
+q
+1 J
+1 j
+.662745 .662745 .662745 RG
+.5 w
+n 0 83 m 469.8898 83 l S
+n 0 0 m 469.8898 0 l S
+n 0 0 m 0 83 l S
+n 469.8898 0 m 469.8898 83 l S
+Q
+Q
+q
+1 0 0 1 62.69291 562.8236 cm
+Q
+q
+1 0 0 1 62.69291 544.8236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Equality comparisons are defined though:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 451.6236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 84 re B*
+Q
+q
+BT 1 0 0 1 0 62 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( Color.blue == Color.red) Tj T* (False) Tj T* (>) Tj (>) Tj (>) Tj ( Color.blue != Color.red) Tj T* (True) Tj T* (>) Tj (>) Tj (>) Tj ( Color.blue == Color.blue) Tj T* (True) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 419.6236 cm
+q
+BT 1 0 0 1 0 14 Tm 2.582706 Tw 12 TL /F1 10 Tf 0 0 0 rg (Comparisons against non-enumeration values will always compare not equal \(again, ) Tj /F4 10 Tf 0 0 0 rg (IntEnum ) Tj /F1 10 Tf 0 0 0 rg (was) Tj T* 0 Tw (explicitly designed to behave differently, see below\):) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 374.4236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 36 re B*
+Q
+q
+BT 1 0 0 1 0 14 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( Color.blue == 2) Tj T* (False) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 341.4236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Allowed members and attributes of enumerations) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 287.4236 cm
+q
+BT 1 0 0 1 0 38 Tm 2.755697 Tw 12 TL /F1 10 Tf 0 0 0 rg (The examples above use integers for enumeration values. Using integers is short and handy \(and) Tj T* 0 Tw .241751 Tw (provided by default by the ) Tj 0 0 .501961 rg (Functional API) Tj 0 0 0 rg (\), but not strictly enforced. In the vast majority of use-cases, one) Tj T* 0 Tw .848221 Tw (doesn't care what the actual value of an enumeration is. But if the value ) Tj /F5 10 Tf (is ) Tj /F1 10 Tf (important, enumerations can) Tj T* 0 Tw (have arbitrary values.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 257.4236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .638735 Tw (Enumerations are Python classes, and can have methods and special methods as usual. If we have this) Tj T* 0 Tw (enumeration:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 80.22362 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 168 re B*
+Q
+q
+BT 1 0 0 1 0 146 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( class Mood\(Enum\):) Tj T* (... funky = 1) Tj T* (... happy = 3) Tj T* (...) Tj T* (... def describe\(self\):) Tj T* (... # self is the member here) Tj T* (... return self.name, self.value) Tj T* (...) Tj T* (... def __str__\(self\):) Tj T* (... return 'my custom str! {0}'.format\(self.value\)) Tj T* (...) Tj T* (... @classmethod) Tj T* (... def favorite_mood\(cls\):) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+
+endstream
+endobj
+61 0 obj
+<< /Length 4627 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 727.8236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 36 re B*
+Q
+q
+BT 1 0 0 1 0 14 Tm 12 TL /F4 10 Tf 0 0 0 rg (... # cls here is the enumeration) Tj T* (... return cls.happy) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 707.8236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Then:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 614.6236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 84 re B*
+Q
+q
+BT 1 0 0 1 0 62 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( Mood.favorite_mood\(\)) Tj T* (<) Tj (Mood.happy: 3) Tj (>) Tj T* (>) Tj (>) Tj (>) Tj ( Mood.happy.describe\(\)) Tj T* (\('happy', 3\)) Tj T* (>) Tj (>) Tj (>) Tj ( str\(Mood.funky\)) Tj T* ('my custom str! 1') Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 558.6236 cm
+q
+BT 1 0 0 1 0 38 Tm 3.14186 Tw 12 TL /F1 10 Tf 0 0 0 rg (The rules for what is allowed are as follows: _sunder_ names \(starting and ending with a single) Tj T* 0 Tw .310651 Tw (underscore\) are reserved by enum and cannot be used; all other attributes defined within an enumeration) Tj T* 0 Tw 2.199213 Tw (will become members of this enumeration, with the exception of ) Tj /F5 10 Tf (__dunder__ ) Tj /F1 10 Tf (names and descriptors) Tj T* 0 Tw (\(methods are also descriptors\).) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 540.6236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Note:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 534.6236 cm
+Q
+q
+1 0 0 1 62.69291 510.6236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+BT 1 0 0 1 0 2 Tm T* ET
+q
+1 0 0 1 20 0 cm
+q
+BT 1 0 0 1 0 14 Tm .979213 Tw 12 TL /F1 10 Tf 0 0 0 rg (If your enumeration defines ) Tj /F4 10 Tf 0 0 0 rg (__new__ ) Tj /F1 10 Tf 0 0 0 rg (and/or ) Tj /F4 10 Tf 0 0 0 rg (__init__ ) Tj /F1 10 Tf 0 0 0 rg (then whatever value\(s\) were given to the) Tj T* 0 Tw (enum member will be passed into those methods. See ) Tj 0 0 .501961 rg (Planet ) Tj 0 0 0 rg (for an example.) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 510.6236 cm
+Q
+q
+1 0 0 1 62.69291 477.6236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Restricted subclassing of enumerations) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 447.6236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .778735 Tw (Subclassing an enumeration is allowed only if the enumeration does not define any members. So this is) Tj T* 0 Tw (forbidden:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 366.4236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 72 re B*
+Q
+q
+BT 1 0 0 1 0 50 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( class MoreColor\(Color\):) Tj T* (... pink = 17) Tj T* (Traceback \(most recent call last\):) Tj T* (...) Tj T* (TypeError: Cannot extend enumerations) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 346.4236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (But this is allowed:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 229.2236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 108 re B*
+Q
+q
+BT 1 0 0 1 0 86 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( class Foo\(Enum\):) Tj T* (... def some_behavior\(self\):) Tj T* (... pass) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( class Bar\(Foo\):) Tj T* (... happy = 1) Tj T* (... sad = 2) Tj T* (...) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 185.2236 cm
+q
+BT 1 0 0 1 0 26 Tm .127984 Tw 12 TL /F1 10 Tf 0 0 0 rg (Allowing subclassing of enums that define members would lead to a violation of some important invariants) Tj T* 0 Tw 1.889985 Tw (of types and instances. On the other hand, it makes sense to allow sharing some common behavior) Tj T* 0 Tw (between a group of enumerations. \(See ) Tj 0 0 .501961 rg (OrderedEnum ) Tj 0 0 0 rg (for an example.\)) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 152.2236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Pickling) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 134.2236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Enumerations can be pickled and unpickled:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 89.02362 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 36 re B*
+Q
+q
+BT 1 0 0 1 0 14 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( from enum.test_enum import Fruit) Tj T* (>) Tj (>) Tj (>) Tj ( from pickle import dumps, loads) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+
+endstream
+endobj
+62 0 obj
+<< /Length 5372 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 727.8236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 36 re B*
+Q
+q
+BT 1 0 0 1 0 14 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( Fruit.tomato is loads\(dumps\(Fruit.tomato, 2\)\)) Tj T* (True) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 695.8236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.256457 Tw (The usual restrictions for pickling apply: picklable enums must be defined in the top level of a module,) Tj T* 0 Tw (since unpickling requires them to be importable from that module.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 677.8236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Note:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 671.8236 cm
+Q
+q
+1 0 0 1 62.69291 647.8236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+BT 1 0 0 1 0 2 Tm T* ET
+q
+1 0 0 1 20 0 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .081163 Tw (With pickle protocol version 4 \(introduced in Python 3.4\) it is possible to easily pickle enums nested in) Tj T* 0 Tw (other classes.) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 647.8236 cm
+Q
+q
+1 0 0 1 62.69291 614.8236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Functional API) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 596.8236 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (class is callable, providing the following functional API:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 467.6236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 120 re B*
+Q
+q
+BT 1 0 0 1 0 98 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( Animal = Enum\('Animal', 'ant bee cat dog'\)) Tj T* (>) Tj (>) Tj (>) Tj ( Animal) Tj T* (<) Tj (enum 'Animal') Tj (>) Tj T* (>) Tj (>) Tj (>) Tj ( Animal.ant) Tj T* (<) Tj (Animal.ant: 1) Tj (>) Tj T* (>) Tj (>) Tj (>) Tj ( Animal.ant.value) Tj T* (1) Tj T* (>) Tj (>) Tj (>) Tj ( list\(Animal\)) Tj T* ([) Tj (<) Tj (Animal.ant: 1) Tj (>) Tj (, ) Tj (<) Tj (Animal.bee: 2) Tj (>) Tj (, ) Tj (<) Tj (Animal.cat: 3) Tj (>) Tj (, ) Tj (<) Tj (Animal.dog: 4) Tj (>) Tj (]) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 435.6236 cm
+q
+BT 1 0 0 1 0 14 Tm .602209 Tw 12 TL /F1 10 Tf 0 0 0 rg (The semantics of this API resemble ) Tj /F4 10 Tf 0 0 0 rg (namedtuple) Tj /F1 10 Tf 0 0 0 rg (. The first argument of the call to ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (is the name of) Tj T* 0 Tw (the enumeration.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 369.6236 cm
+q
+BT 1 0 0 1 0 50 Tm 1.326412 Tw 12 TL /F1 10 Tf 0 0 0 rg (The second argument is the ) Tj /F5 10 Tf (source ) Tj /F1 10 Tf (of enumeration member names. It can be a whitespace-separated) Tj T* 0 Tw .993516 Tw (string of names, a sequence of names, a sequence of 2-tuples with key/value pairs, or a mapping \(e.g.) Tj T* 0 Tw 1.168555 Tw (dictionary\) of names to values. The last two options enable assigning arbitrary values to enumerations;) Tj T* 0 Tw .537485 Tw (the others auto-assign increasing integers starting with 1. A new class derived from ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (is returned. In) Tj T* 0 Tw (other words, the above assignment to ) Tj /F4 10 Tf 0 0 0 rg (Animal ) Tj /F1 10 Tf 0 0 0 rg (is equivalent to:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 288.4236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 72 re B*
+Q
+q
+BT 1 0 0 1 0 50 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( class Animals\(Enum\):) Tj T* (... ant = 1) Tj T* (... bee = 2) Tj T* (... cat = 3) Tj T* (... dog = 4) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 232.4236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 38 Tm /F1 10 Tf 12 TL 1.239984 Tw (Pickling enums created with the functional API can be tricky as frame stack implementation details are) Tj T* 0 Tw .937132 Tw (used to try and figure out which module the enumeration is being created in \(e.g. it will fail if you use a) Tj T* 0 Tw 1.321163 Tw (utility function in separate module, and also may not work on IronPython or Jython\). The solution is to) Tj T* 0 Tw (specify the module name explicitly as follows:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 199.2236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 24 re B*
+Q
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( Animals = Enum\('Animals', 'ant bee cat dog', module=__name__\)) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 166.2236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Derived Enumerations) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 136.2236 cm
+q
+BT 1 0 0 1 0 3 Tm 18 TL /F3 15 Tf 0 0 0 rg (IntEnum) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 94.22362 cm
+q
+BT 1 0 0 1 0 26 Tm 1.99832 Tw 12 TL /F1 10 Tf 0 0 0 rg (A variation of ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (is provided which is also a subclass of ) Tj /F4 10 Tf 0 0 0 rg (int) Tj /F1 10 Tf 0 0 0 rg (. Members of an ) Tj /F4 10 Tf 0 0 0 rg (IntEnum ) Tj /F1 10 Tf 0 0 0 rg (can be) Tj T* 0 Tw .087984 Tw (compared to integers; by extension, integer enumerations of different types can also be compared to each) Tj T* 0 Tw (other:) Tj T* ET
+Q
+Q
+
+endstream
+endobj
+63 0 obj
+<< /Length 4141 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 571.8236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 192 re B*
+Q
+q
+BT 1 0 0 1 0 170 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( from enum import IntEnum) Tj T* (>) Tj (>) Tj (>) Tj ( class Shape\(IntEnum\):) Tj T* (... circle = 1) Tj T* (... square = 2) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( class Request\(IntEnum\):) Tj T* (... post = 1) Tj T* (... get = 2) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( Shape == 1) Tj T* (False) Tj T* (>) Tj (>) Tj (>) Tj ( Shape.circle == 1) Tj T* (True) Tj T* (>) Tj (>) Tj (>) Tj ( Shape.circle == Request.post) Tj T* (True) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 551.8236 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (However, they still can't be compared to standard ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (enumerations:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 410.6236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 132 re B*
+Q
+q
+BT 1 0 0 1 0 110 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( class Shape\(IntEnum\):) Tj T* (... circle = 1) Tj T* (... square = 2) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( class Color\(Enum\):) Tj T* (... red = 1) Tj T* (... green = 2) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( Shape.circle == Color.red) Tj T* (False) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 390.6236 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F4 10 Tf 0 0 0 rg (IntEnum ) Tj /F1 10 Tf 0 0 0 rg (values behave like integers in other ways you'd expect:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 297.4236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 84 re B*
+Q
+q
+BT 1 0 0 1 0 62 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( int\(Shape.circle\)) Tj T* (1) Tj T* (>) Tj (>) Tj (>) Tj ( ['a', 'b', 'c'][Shape.circle]) Tj T* ('b') Tj T* (>) Tj (>) Tj (>) Tj ( [i for i in range\(Shape.square\)]) Tj T* ([0, 1]) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 229.4236 cm
+q
+BT 1 0 0 1 0 50 Tm 1.197126 Tw 12 TL /F1 10 Tf 0 0 0 rg (For the vast majority of code, ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (is strongly recommended, since ) Tj /F4 10 Tf 0 0 0 rg (IntEnum ) Tj /F1 10 Tf 0 0 0 rg (breaks some semantic) Tj T* 0 Tw .793318 Tw (promises of an enumeration \(by being comparable to integers, and thus by transitivity to other unrelated) Tj T* 0 Tw .554985 Tw (enumerations\). It should be used only in special cases where there's no other choice; for example, when) Tj T* 0 Tw .746136 Tw (integer constants are replaced with enumerations and backwards compatibility is required with code that) Tj T* 0 Tw (still expects integers.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 199.4236 cm
+q
+BT 1 0 0 1 0 3 Tm 18 TL /F3 15 Tf 0 0 0 rg (Others) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 181.4236 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (While ) Tj /F4 10 Tf 0 0 0 rg (IntEnum ) Tj /F1 10 Tf 0 0 0 rg (is part of the ) Tj /F4 10 Tf 0 0 0 rg (enum ) Tj /F1 10 Tf 0 0 0 rg (module, it would be very simple to implement independently:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 136.2236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 36 re B*
+Q
+q
+0 0 0 rg
+BT 1 0 0 1 0 14 Tm /F4 10 Tf 12 TL (class IntEnum\(int, Enum\):) Tj T* ( pass) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 104.2236 cm
+q
+BT 1 0 0 1 0 14 Tm .361412 Tw 12 TL /F1 10 Tf 0 0 0 rg (This demonstrates how similar derived enumerations can be defined; for example a ) Tj /F4 10 Tf 0 0 0 rg (StrEnum ) Tj /F1 10 Tf 0 0 0 rg (that mixes) Tj T* 0 Tw (in ) Tj /F4 10 Tf 0 0 0 rg (str ) Tj /F1 10 Tf 0 0 0 rg (instead of ) Tj /F4 10 Tf 0 0 0 rg (int) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 86.22362 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Some rules:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 80.22362 cm
+Q
+q
+1 0 0 1 62.69291 80.22362 cm
+Q
+
+endstream
+endobj
+64 0 obj
+<< /Length 7108 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 741.0236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 9 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (1.) Tj T* -5.66 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+BT 1 0 0 1 0 14 Tm .477318 Tw 12 TL /F1 10 Tf 0 0 0 rg (When subclassing ) Tj /F4 10 Tf 0 0 0 rg (Enum) Tj /F1 10 Tf 0 0 0 rg (, mix-in types must appear before ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (itself in the sequence of bases, as) Tj T* 0 Tw (in the ) Tj /F4 10 Tf 0 0 0 rg (IntEnum ) Tj /F1 10 Tf 0 0 0 rg (example above.) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 735.0236 cm
+Q
+q
+1 0 0 1 62.69291 699.0236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 21 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (2.) Tj T* -5.66 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+BT 1 0 0 1 0 26 Tm 1.147045 Tw 12 TL /F1 10 Tf 0 0 0 rg (While ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (can have members of any type, once you mix in an additional type, all the members) Tj T* 0 Tw .420574 Tw (must have values of that type, e.g. ) Tj /F4 10 Tf 0 0 0 rg (int ) Tj /F1 10 Tf 0 0 0 rg (above. This restriction does not apply to mix-ins which only) Tj T* 0 Tw (add methods and don't specify another data type such as ) Tj /F4 10 Tf 0 0 0 rg (int ) Tj /F1 10 Tf 0 0 0 rg (or ) Tj /F4 10 Tf 0 0 0 rg (str) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 693.0236 cm
+Q
+q
+1 0 0 1 62.69291 669.0236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 9 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (3.) Tj T* -5.66 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+BT 1 0 0 1 0 14 Tm .100542 Tw 12 TL /F1 10 Tf 0 0 0 rg (When another data type is mixed in, the ) Tj /F4 10 Tf 0 0 0 rg (value ) Tj /F1 10 Tf 0 0 0 rg (attribute is ) Tj /F5 10 Tf (not the same ) Tj /F1 10 Tf (as the enum member itself,) Tj T* 0 Tw (although it is equivalant and will compare equal.) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 663.0236 cm
+Q
+q
+1 0 0 1 62.69291 609.0236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 39 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (4.) Tj T* -5.66 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 27 cm
+q
+BT 1 0 0 1 0 14 Tm 1.85998 Tw 12 TL /F1 10 Tf 0 0 0 rg (%-style formatting: ) Tj /F4 10 Tf 0 0 0 rg (%s ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F4 10 Tf 0 0 0 rg (%r ) Tj /F1 10 Tf 0 0 0 rg (call ) Tj /F4 10 Tf 0 0 0 rg (Enum) Tj /F1 10 Tf 0 0 0 rg ('s ) Tj /F4 10 Tf 0 0 0 rg (__str__ ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F4 10 Tf 0 0 0 rg (__repr__ ) Tj /F1 10 Tf 0 0 0 rg (respectively; other codes) Tj T* 0 Tw (\(such as ) Tj /F4 10 Tf 0 0 0 rg (%i ) Tj /F1 10 Tf 0 0 0 rg (or ) Tj /F4 10 Tf 0 0 0 rg (%h ) Tj /F1 10 Tf 0 0 0 rg (for IntEnum\) treat the enum member as its mixed-in type.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+BT 1 0 0 1 0 14 Tm .067045 Tw 12 TL /F1 10 Tf 0 0 0 rg (Note: Prior to Python 3.4 there is a bug in ) Tj /F4 10 Tf 0 0 0 rg (str) Tj /F1 10 Tf 0 0 0 rg ('s %-formatting: ) Tj /F4 10 Tf 0 0 0 rg (int ) Tj /F1 10 Tf 0 0 0 rg (subclasses are printed as strings) Tj T* 0 Tw (and not numbers when the ) Tj /F4 10 Tf 0 0 0 rg (%d) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F4 10 Tf 0 0 0 rg (%i) Tj /F1 10 Tf 0 0 0 rg (, or ) Tj /F4 10 Tf 0 0 0 rg (%u ) Tj /F1 10 Tf 0 0 0 rg (codes are used.) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 603.0236 cm
+Q
+q
+1 0 0 1 62.69291 579.0236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 9 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 5.66 0 Td (5.) Tj T* -5.66 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+BT 1 0 0 1 0 14 Tm 1.880751 Tw 12 TL /F4 10 Tf 0 0 0 rg (str.__format__ ) Tj /F1 10 Tf 0 0 0 rg (\(or ) Tj /F4 10 Tf 0 0 0 rg (format) Tj /F1 10 Tf 0 0 0 rg (\) will use the mixed-in type's ) Tj /F4 10 Tf 0 0 0 rg (__format__) Tj /F1 10 Tf 0 0 0 rg (. If the ) Tj /F4 10 Tf 0 0 0 rg (Enum) Tj /F1 10 Tf 0 0 0 rg ('s ) Tj /F4 10 Tf 0 0 0 rg (str ) Tj /F1 10 Tf 0 0 0 rg (or) Tj T* 0 Tw /F4 10 Tf 0 0 0 rg (repr ) Tj /F1 10 Tf 0 0 0 rg (is desired use the ) Tj /F4 10 Tf 0 0 0 rg (!s ) Tj /F1 10 Tf 0 0 0 rg (or ) Tj /F4 10 Tf 0 0 0 rg (!r) Tj /F1 10 Tf 0 0 0 rg ( ) Tj /F4 10 Tf 0 0 0 rg (str ) Tj /F1 10 Tf 0 0 0 rg (format codes.) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 579.0236 cm
+Q
+q
+1 0 0 1 62.69291 546.0236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Decorators) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 516.0236 cm
+q
+BT 1 0 0 1 0 3 Tm 18 TL /F3 15 Tf 0 0 0 rg (unique) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 486.0236 cm
+q
+BT 1 0 0 1 0 14 Tm .287251 Tw 12 TL /F1 10 Tf 0 0 0 rg (A ) Tj /F4 10 Tf 0 0 0 rg (class ) Tj /F1 10 Tf 0 0 0 rg (decorator specifically for enumerations. It searches an enumeration's ) Tj /F4 10 Tf 0 0 0 rg (__members__ ) Tj /F1 10 Tf 0 0 0 rg (gathering) Tj T* 0 Tw (any aliases it finds; if any are found ) Tj /F4 10 Tf 0 0 0 rg (ValueError ) Tj /F1 10 Tf 0 0 0 rg (is raised with the details:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 368.8236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 108 re B*
+Q
+q
+BT 1 0 0 1 0 86 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( @unique) Tj T* (... class NoDupes\(Enum\):) Tj T* (... first = 'one') Tj T* (... second = 'two') Tj T* (... third = 'two') Tj T* (Traceback \(most recent call last\):) Tj T* (...) Tj T* (ValueError: duplicate names found in ) Tj (<) Tj (enum 'NoDupes') Tj (>) Tj (: third -) Tj (>) Tj ( second) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 335.8236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (Interesting examples) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 293.8236 cm
+q
+BT 1 0 0 1 0 26 Tm .593735 Tw 12 TL /F1 10 Tf 0 0 0 rg (While ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F4 10 Tf 0 0 0 rg (IntEnum ) Tj /F1 10 Tf 0 0 0 rg (are expected to cover the majority of use-cases, they cannot cover them all.) Tj T* 0 Tw .897045 Tw (Here are recipes for some different types of enumerations that can be used directly, or as examples for) Tj T* 0 Tw (creating one's own.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 263.8236 cm
+q
+BT 1 0 0 1 0 3 Tm 18 TL /F3 15 Tf 0 0 0 rg (AutoNumber) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 245.8236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Avoids having to specify the value for each enumeration member:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 80.62362 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 156 re B*
+Q
+q
+BT 1 0 0 1 0 134 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( class AutoNumber\(Enum\):) Tj T* (... def __new__\(cls\):) Tj T* (... value = len\(cls.__members__\) + 1) Tj T* (... obj = object.__new__\(cls\)) Tj T* (... obj._value_ = value) Tj T* (... return obj) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( class Color\(AutoNumber\):) Tj T* (... __order__ = "red green blue" # only needed in 2.x) Tj T* (... red = \(\)) Tj T* (... green = \(\)) Tj T* (... blue = \(\)) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+
+endstream
+endobj
+65 0 obj
+<< /Length 4158 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 715.8236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 48 re B*
+Q
+q
+BT 1 0 0 1 0 26 Tm 12 TL /F4 10 Tf 0 0 0 rg (...) Tj T* (>) Tj (>) Tj (>) Tj ( Color.green.value == 2) Tj T* (True) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 695.8236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Note:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 689.8236 cm
+Q
+q
+1 0 0 1 62.69291 653.8236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+BT 1 0 0 1 0 2 Tm T* ET
+q
+1 0 0 1 20 0 cm
+q
+BT 1 0 0 1 0 26 Tm .144104 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F5 10 Tf 0 0 0 rg (__new__ ) Tj /F1 10 Tf 0 0 0 rg (method, if defined, is used during creation of the Enum members; it is then replaced by) Tj T* 0 Tw .799985 Tw (Enum's ) Tj /F5 10 Tf 0 0 0 rg (__new__ ) Tj /F1 10 Tf 0 0 0 rg (which is used after class creation for lookup of existing members. Due to the way) Tj T* 0 Tw (Enums are supposed to behave, there is no way to customize Enum's ) Tj /F5 10 Tf 0 0 0 rg (__new__) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 653.8236 cm
+Q
+q
+1 0 0 1 62.69291 623.8236 cm
+q
+BT 1 0 0 1 0 3 Tm 18 TL /F3 15 Tf 0 0 0 rg (UniqueEnum) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 605.8236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Raises an error if a duplicate member name is found instead of creating an alias:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 368.6236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 228 re B*
+Q
+q
+BT 1 0 0 1 0 206 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( class UniqueEnum\(Enum\):) Tj T* (... def __init__\(self, *args\):) Tj T* (... cls = self.__class__) Tj T* (... if any\(self.value == e.value for e in cls\):) Tj T* (... a = self.name) Tj T* (... e = cls\(self.value\).name) Tj T* (... raise ValueError\() Tj T* (... "aliases not allowed in UniqueEnum: %r --) Tj (>) Tj ( %r") Tj T* (... % \(a, e\)\)) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( class Color\(UniqueEnum\):) Tj T* (... red = 1) Tj T* (... green = 2) Tj T* (... blue = 3) Tj T* (... grene = 2) Tj T* (Traceback \(most recent call last\):) Tj T* (...) Tj T* (ValueError: aliases not allowed in UniqueEnum: 'grene' --) Tj (>) Tj ( 'green') Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 338.6236 cm
+q
+BT 1 0 0 1 0 3 Tm 18 TL /F3 15 Tf 0 0 0 rg (OrderedEnum) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 308.6236 cm
+q
+BT 1 0 0 1 0 14 Tm 1.335984 Tw 12 TL /F1 10 Tf 0 0 0 rg (An ordered enumeration that is not based on ) Tj /F4 10 Tf 0 0 0 rg (IntEnum ) Tj /F1 10 Tf 0 0 0 rg (and so maintains the normal ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (invariants) Tj T* 0 Tw (\(such as not being comparable to other enumerations\):) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 83.42362 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 216 re B*
+Q
+q
+BT 1 0 0 1 0 194 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( class OrderedEnum\(Enum\):) Tj T* (... def __ge__\(self, other\):) Tj T* (... if self.__class__ is other.__class__:) Tj T* (... return self._value_ ) Tj (>) Tj (= other._value_) Tj T* (... return NotImplemented) Tj T* (... def __gt__\(self, other\):) Tj T* (... if self.__class__ is other.__class__:) Tj T* (... return self._value_ ) Tj (>) Tj ( other._value_) Tj T* (... return NotImplemented) Tj T* (... def __le__\(self, other\):) Tj T* (... if self.__class__ is other.__class__:) Tj T* (... return self._value_ ) Tj (<) Tj (= other._value_) Tj T* (... return NotImplemented) Tj T* (... def __lt__\(self, other\):) Tj T* (... if self.__class__ is other.__class__:) Tj T* (... return self._value_ ) Tj (<) Tj ( other._value_) Tj T* (... return NotImplemented) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+
+endstream
+endobj
+66 0 obj
+<< /Length 4039 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 619.8236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 144 re B*
+Q
+q
+BT 1 0 0 1 0 122 Tm 12 TL /F4 10 Tf 0 0 0 rg (...) Tj T* (>) Tj (>) Tj (>) Tj ( class Grade\(OrderedEnum\):) Tj T* (... __ordered__ = 'A B C D F') Tj T* (... A = 5) Tj T* (... B = 4) Tj T* (... C = 3) Tj T* (... D = 2) Tj T* (... F = 1) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( Grade.C ) Tj (<) Tj ( Grade.A) Tj T* (True) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 589.8236 cm
+q
+BT 1 0 0 1 0 3 Tm 18 TL /F3 15 Tf 0 0 0 rg (Planet) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 571.8236 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If ) Tj /F4 10 Tf 0 0 0 rg (__new__ ) Tj /F1 10 Tf 0 0 0 rg (or ) Tj /F4 10 Tf 0 0 0 rg (__init__ ) Tj /F1 10 Tf 0 0 0 rg (is defined the value of the enum member will be passed to those methods:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 286.6236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 276 re B*
+Q
+q
+BT 1 0 0 1 0 254 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( class Planet\(Enum\):) Tj T* (... MERCURY = \(3.303e+23, 2.4397e6\)) Tj T* (... VENUS = \(4.869e+24, 6.0518e6\)) Tj T* (... EARTH = \(5.976e+24, 6.37814e6\)) Tj T* (... MARS = \(6.421e+23, 3.3972e6\)) Tj T* (... JUPITER = \(1.9e+27, 7.1492e7\)) Tj T* (... SATURN = \(5.688e+26, 6.0268e7\)) Tj T* (... URANUS = \(8.686e+25, 2.5559e7\)) Tj T* (... NEPTUNE = \(1.024e+26, 2.4746e7\)) Tj T* (... def __init__\(self, mass, radius\):) Tj T* (... self.mass = mass # in kilograms) Tj T* (... self.radius = radius # in meters) Tj T* (... @property) Tj T* (... def surface_gravity\(self\):) Tj T* (... # universal gravitational constant \(m3 kg-1 s-2\)) Tj T* (... G = 6.67300E-11) Tj T* (... return G * self.mass / \(self.radius * self.radius\)) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( Planet.EARTH.value) Tj T* (\(5.976e+24, 6378140.0\)) Tj T* (>) Tj (>) Tj (>) Tj ( Planet.EARTH.surface_gravity) Tj T* (9.802652743337129) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 253.6236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F3 17.5 Tf 0 0 0 rg (How are Enums different?) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 223.6236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 2.090651 Tw (Enums have a custom metaclass that affects many aspects of both derived Enum classes and their) Tj T* 0 Tw (instances \(members\).) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 193.6236 cm
+q
+BT 1 0 0 1 0 3 Tm 18 TL /F3 15 Tf 0 0 0 rg (Enum Classes) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 127.6236 cm
+q
+BT 1 0 0 1 0 50 Tm 1.263615 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F4 10 Tf 0 0 0 rg (EnumMeta ) Tj /F1 10 Tf 0 0 0 rg (metaclass is responsible for providing the ) Tj /F4 10 Tf 0 0 0 rg (__contains__) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F4 10 Tf 0 0 0 rg (__dir__) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F4 10 Tf 0 0 0 rg (__iter__ ) Tj /F1 10 Tf 0 0 0 rg (and) Tj T* 0 Tw 2.264724 Tw (other methods that allow one to do things with an ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (class that fail on a typical class, such as) Tj T* 0 Tw 2.594147 Tw /F4 10 Tf 0 0 0 rg (list\(Color\) ) Tj /F1 10 Tf 0 0 0 rg (or ) Tj /F4 10 Tf 0 0 0 rg (some_var) Tj ( ) Tj (in) Tj ( ) Tj (Color) Tj /F1 10 Tf 0 0 0 rg (. ) Tj /F4 10 Tf 0 0 0 rg (EnumMeta ) Tj /F1 10 Tf 0 0 0 rg (is responsible for ensuring that various other) Tj T* 0 Tw 2.196905 Tw (methods on the final ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (class are correct \(such as ) Tj /F4 10 Tf 0 0 0 rg (__new__) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F4 10 Tf 0 0 0 rg (__getnewargs__) Tj /F1 10 Tf 0 0 0 rg (, ) Tj /F4 10 Tf 0 0 0 rg (__str__ ) Tj /F1 10 Tf 0 0 0 rg (and) Tj T* 0 Tw /F4 10 Tf 0 0 0 rg (__repr__) Tj /F1 10 Tf 0 0 0 rg (\).) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 115.6236 cm
+Q
+
+endstream
+endobj
+67 0 obj
+<< /Length 5453 >>
+stream
+1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 682.0236 cm
+.960784 .960784 .862745 rg
+n 0 83 469.8898 -83 re f*
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+BT 1 0 0 1 6 57 Tm T* ET
+q
+1 0 0 1 16 52 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2.5 Tm /F6 12.5 Tf 15 TL (Note) Tj T* ET
+Q
+Q
+q
+1 0 0 1 16 16 cm
+q
+BT 1 0 0 1 0 14 Tm .686654 Tw 12 TL /F4 10 Tf 0 0 0 rg (__dir__ ) Tj /F1 10 Tf 0 0 0 rg (is not changed in the Python 2 line as it messes up some of the decorators included in) Tj T* 0 Tw (the stdlib.) Tj T* ET
+Q
+Q
+q
+1 J
+1 j
+.662745 .662745 .662745 RG
+.5 w
+n 0 83 m 469.8898 83 l S
+n 0 0 m 469.8898 0 l S
+n 0 0 m 0 83 l S
+n 469.8898 0 m 469.8898 83 l S
+Q
+Q
+q
+1 0 0 1 62.69291 676.0236 cm
+Q
+q
+1 0 0 1 62.69291 646.0236 cm
+q
+BT 1 0 0 1 0 3 Tm 18 TL /F3 15 Tf 0 0 0 rg (Enum Members \(aka instances\)) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 604.0236 cm
+q
+BT 1 0 0 1 0 26 Tm .491984 Tw 12 TL /F1 10 Tf 0 0 0 rg (The most interesting thing about Enum members is that they are singletons. ) Tj /F4 10 Tf 0 0 0 rg (EnumMeta ) Tj /F1 10 Tf 0 0 0 rg (creates them all) Tj T* 0 Tw .084988 Tw (while it is creating the ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (class itself, and then puts a custom ) Tj /F4 10 Tf 0 0 0 rg (__new__ ) Tj /F1 10 Tf 0 0 0 rg (in place to ensure that no new) Tj T* 0 Tw (ones are ever instantiated by returning only the existing member instances.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 574.0236 cm
+q
+BT 1 0 0 1 0 3 Tm 18 TL /F3 15 Tf 0 0 0 rg (Finer Points) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 520.0236 cm
+q
+BT 1 0 0 1 0 38 Tm 5.488555 Tw 12 TL /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (members are instances of an ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (class, and even though they are accessible as) Tj T* 0 Tw 1.504147 Tw /F5 10 Tf 0 0 0 rg (EnumClass.member1.member2) Tj /F1 10 Tf 0 0 0 rg (, they should not be accessed directly from the member as that lookup) Tj T* 0 Tw .329985 Tw (may fail or, worse, return something besides the ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (member you were looking for \(changed in version) Tj T* 0 Tw (1.1.1\):) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 390.8236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 120 re B*
+Q
+q
+BT 1 0 0 1 0 98 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( class FieldTypes\(Enum\):) Tj T* (... name = 1) Tj T* (... value = 2) Tj T* (... size = 3) Tj T* (...) Tj T* (>) Tj (>) Tj (>) Tj ( FieldTypes.value.size) Tj T* (<) Tj (FieldTypes.size: 3) Tj (>) Tj T* (>) Tj (>) Tj (>) Tj ( FieldTypes.size.value) Tj T* (3) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 370.8236 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj /F4 10 Tf 0 0 0 rg (__members__ ) Tj /F1 10 Tf 0 0 0 rg (attribute is only available on the class.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 316.8236 cm
+q
+BT 1 0 0 1 0 38 Tm 1.374651 Tw 12 TL /F1 10 Tf 0 0 0 rg (In Python 3.x ) Tj /F4 10 Tf 0 0 0 rg (__members__ ) Tj /F1 10 Tf 0 0 0 rg (is always an ) Tj /F4 10 Tf 0 0 0 rg (OrderedDict) Tj /F1 10 Tf 0 0 0 rg (, with the order being the definition order. In) Tj T* 0 Tw 3.009213 Tw (Python 2.7 ) Tj /F4 10 Tf 0 0 0 rg (__members__ ) Tj /F1 10 Tf 0 0 0 rg (is an ) Tj /F4 10 Tf 0 0 0 rg (OrderedDict ) Tj /F1 10 Tf 0 0 0 rg (if ) Tj /F4 10 Tf 0 0 0 rg (__order__ ) Tj /F1 10 Tf 0 0 0 rg (was specified, and a plain ) Tj /F4 10 Tf 0 0 0 rg (dict) Tj T* 0 Tw 1.851318 Tw /F1 10 Tf 0 0 0 rg (otherwise. In all other Python 2.x versions ) Tj /F4 10 Tf 0 0 0 rg (__members__ ) Tj /F1 10 Tf 0 0 0 rg (is a plain ) Tj /F4 10 Tf 0 0 0 rg (dict ) Tj /F1 10 Tf 0 0 0 rg (even if ) Tj /F4 10 Tf 0 0 0 rg (__order__ ) Tj /F1 10 Tf 0 0 0 rg (was) Tj T* 0 Tw (specified as the ) Tj /F4 10 Tf 0 0 0 rg (OrderedDict ) Tj /F1 10 Tf 0 0 0 rg (type didn't exist yet.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 286.8236 cm
+q
+BT 1 0 0 1 0 14 Tm .106654 Tw 12 TL /F1 10 Tf 0 0 0 rg (If you give your ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (subclass extra methods, like the ) Tj 0 0 .501961 rg (Planet ) Tj 0 0 0 rg (class above, those methods will show up in) Tj T* 0 Tw (a ) Tj /F5 10 Tf 0 0 0 rg (dir ) Tj /F1 10 Tf 0 0 0 rg (of the member, but not of the class:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 205.6236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 72 re B*
+Q
+q
+BT 1 0 0 1 0 50 Tm 12 TL /F4 10 Tf 0 0 0 rg (>) Tj (>) Tj (>) Tj ( dir\(Planet\)) Tj T* (['EARTH', 'JUPITER', 'MARS', 'MERCURY', 'NEPTUNE', 'SATURN', 'URANUS',) Tj T* ('VENUS', '__class__', '__doc__', '__members__', '__module__']) Tj T* (>) Tj (>) Tj (>) Tj ( dir\(Planet.EARTH\)) Tj T* (['__class__', '__doc__', '__module__', 'name', 'surface_gravity', 'value']) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 161.6236 cm
+q
+BT 1 0 0 1 0 26 Tm .938935 Tw 12 TL /F1 10 Tf 0 0 0 rg (A ) Tj /F4 10 Tf 0 0 0 rg (__new__ ) Tj /F1 10 Tf 0 0 0 rg (method will only be used for the creation of the ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (members -- after that it is replaced.) Tj T* 0 Tw .949461 Tw (This means if you wish to change how ) Tj /F4 10 Tf 0 0 0 rg (Enum ) Tj /F1 10 Tf 0 0 0 rg (members are looked up you either have to write a helper) Tj T* 0 Tw (function or a ) Tj /F4 10 Tf 0 0 0 rg (classmethod) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET
+Q
+Q
+
+endstream
+endobj
+68 0 obj
+<< /Nums [ 0 69 0 R 1 70 0 R 2 71 0 R 3 72 0 R 4 73 0 R
+ 5 74 0 R 6 75 0 R 7 76 0 R 8 77 0 R 9 78 0 R
+ 10 79 0 R 11 80 0 R ] >>
+endobj
+69 0 obj
+<< /S /D /St 1 >>
+endobj
+70 0 obj
+<< /S /D /St 2 >>
+endobj
+71 0 obj
+<< /S /D /St 3 >>
+endobj
+72 0 obj
+<< /S /D /St 4 >>
+endobj
+73 0 obj
+<< /S /D /St 5 >>
+endobj
+74 0 obj
+<< /S /D /St 6 >>
+endobj
+75 0 obj
+<< /S /D /St 7 >>
+endobj
+76 0 obj
+<< /S /D /St 8 >>
+endobj
+77 0 obj
+<< /S /D /St 9 >>
+endobj
+78 0 obj
+<< /S /D /St 10 >>
+endobj
+79 0 obj
+<< /S /D /St 11 >>
+endobj
+80 0 obj
+<< /S /D /St 12 >>
+endobj
+xref
+0 81
+0000000000 65535 f
+0000000075 00000 n
+0000000160 00000 n
+0000000270 00000 n
+0000000383 00000 n
+0000000498 00000 n
+0000000606 00000 n
+0000000777 00000 n
+0000000948 00000 n
+0000001066 00000 n
+0000001237 00000 n
+0000001477 00000 n
+0000001687 00000 n
+0000001897 00000 n
+0000002107 00000 n
+0000002279 00000 n
+0000002402 00000 n
+0000002574 00000 n
+0000002746 00000 n
+0000002989 00000 n
+0000003161 00000 n
+0000003333 00000 n
+0000003569 00000 n
+0000003779 00000 n
+0000003989 00000 n
+0000004199 00000 n
+0000004409 00000 n
+0000004619 00000 n
+0000004791 00000 n
+0000005020 00000 n
+0000005129 00000 n
+0000005373 00000 n
+0000005451 00000 n
+0000005571 00000 n
+0000005705 00000 n
+0000005886 00000 n
+0000006039 00000 n
+0000006168 00000 n
+0000006332 00000 n
+0000006488 00000 n
+0000006614 00000 n
+0000006746 00000 n
+0000006924 00000 n
+0000007036 00000 n
+0000007147 00000 n
+0000007315 00000 n
+0000007413 00000 n
+0000007591 00000 n
+0000007706 00000 n
+0000007834 00000 n
+0000007963 00000 n
+0000008074 00000 n
+0000008243 00000 n
+0000008360 00000 n
+0000008508 00000 n
+0000008625 00000 n
+0000008771 00000 n
+0000015286 00000 n
+0000019517 00000 n
+0000023365 00000 n
+0000027828 00000 n
+0000032406 00000 n
+0000037090 00000 n
+0000042519 00000 n
+0000046717 00000 n
+0000053882 00000 n
+0000058097 00000 n
+0000062193 00000 n
+0000067703 00000 n
+0000067856 00000 n
+0000067893 00000 n
+0000067930 00000 n
+0000067967 00000 n
+0000068004 00000 n
+0000068041 00000 n
+0000068078 00000 n
+0000068115 00000 n
+0000068152 00000 n
+0000068189 00000 n
+0000068227 00000 n
+0000068265 00000 n
+trailer
+<< /ID
+ % ReportLab generated PDF document -- digest (http://www.reportlab.com)
+ [(<}|~gm\352\320\235=\001p\220v\224\336) (<}|~gm\352\320\235=\001p\220v\224\336)]
+ /Info 30 0 R /Root 29 0 R /Size 81 >>
+startxref
+68303
+%%EOF
diff --git a/third_party/python/enum34/enum/doc/enum.rst b/third_party/python/enum34/enum/doc/enum.rst
new file mode 100644
index 0000000000..3afc238210
--- /dev/null
+++ b/third_party/python/enum34/enum/doc/enum.rst
@@ -0,0 +1,735 @@
+``enum`` --- support for enumerations
+========================================
+
+.. :synopsis: enumerations are sets of symbolic names bound to unique, constant
+ values.
+.. :moduleauthor:: Ethan Furman <ethan@stoneleaf.us>
+.. :sectionauthor:: Barry Warsaw <barry@python.org>,
+.. :sectionauthor:: Eli Bendersky <eliben@gmail.com>,
+.. :sectionauthor:: Ethan Furman <ethan@stoneleaf.us>
+
+----------------
+
+An enumeration is a set of symbolic names (members) bound to unique, constant
+values. Within an enumeration, the members can be compared by identity, and
+the enumeration itself can be iterated over.
+
+
+Module Contents
+---------------
+
+This module defines two enumeration classes that can be used to define unique
+sets of names and values: ``Enum`` and ``IntEnum``. It also defines
+one decorator, ``unique``.
+
+``Enum``
+
+Base class for creating enumerated constants. See section `Functional API`_
+for an alternate construction syntax.
+
+``IntEnum``
+
+Base class for creating enumerated constants that are also subclasses of ``int``.
+
+``unique``
+
+Enum class decorator that ensures only one name is bound to any one value.
+
+
+Creating an Enum
+----------------
+
+Enumerations are created using the ``class`` syntax, which makes them
+easy to read and write. An alternative creation method is described in
+`Functional API`_. To define an enumeration, subclass ``Enum`` as
+follows::
+
+ >>> from enum import Enum
+ >>> class Color(Enum):
+ ... red = 1
+ ... green = 2
+ ... blue = 3
+
+Note: Nomenclature
+
+ - The class ``Color`` is an *enumeration* (or *enum*)
+ - The attributes ``Color.red``, ``Color.green``, etc., are
+ *enumeration members* (or *enum members*).
+ - The enum members have *names* and *values* (the name of
+ ``Color.red`` is ``red``, the value of ``Color.blue`` is
+ ``3``, etc.)
+
+Note:
+
+ Even though we use the ``class`` syntax to create Enums, Enums
+ are not normal Python classes. See `How are Enums different?`_ for
+ more details.
+
+Enumeration members have human readable string representations::
+
+ >>> print(Color.red)
+ Color.red
+
+...while their ``repr`` has more information::
+
+ >>> print(repr(Color.red))
+ <Color.red: 1>
+
+The *type* of an enumeration member is the enumeration it belongs to::
+
+ >>> type(Color.red)
+ <enum 'Color'>
+ >>> isinstance(Color.green, Color)
+ True
+ >>>
+
+Enum members also have a property that contains just their item name::
+
+ >>> print(Color.red.name)
+ red
+
+Enumerations support iteration. In Python 3.x definition order is used; in
+Python 2.x the definition order is not available, but class attribute
+``__order__`` is supported; otherwise, value order is used::
+
+ >>> class Shake(Enum):
+ ... __order__ = 'vanilla chocolate cookies mint' # only needed in 2.x
+ ... vanilla = 7
+ ... chocolate = 4
+ ... cookies = 9
+ ... mint = 3
+ ...
+ >>> for shake in Shake:
+ ... print(shake)
+ ...
+ Shake.vanilla
+ Shake.chocolate
+ Shake.cookies
+ Shake.mint
+
+The ``__order__`` attribute is always removed, and in 3.x it is also ignored
+(order is definition order); however, in the stdlib version it will be ignored
+but not removed.
+
+Enumeration members are hashable, so they can be used in dictionaries and sets::
+
+ >>> apples = {}
+ >>> apples[Color.red] = 'red delicious'
+ >>> apples[Color.green] = 'granny smith'
+ >>> apples == {Color.red: 'red delicious', Color.green: 'granny smith'}
+ True
+
+
+Programmatic access to enumeration members and their attributes
+---------------------------------------------------------------
+
+Sometimes it's useful to access members in enumerations programmatically (i.e.
+situations where ``Color.red`` won't do because the exact color is not known
+at program-writing time). ``Enum`` allows such access::
+
+ >>> Color(1)
+ <Color.red: 1>
+ >>> Color(3)
+ <Color.blue: 3>
+
+If you want to access enum members by *name*, use item access::
+
+ >>> Color['red']
+ <Color.red: 1>
+ >>> Color['green']
+ <Color.green: 2>
+
+If have an enum member and need its ``name`` or ``value``::
+
+ >>> member = Color.red
+ >>> member.name
+ 'red'
+ >>> member.value
+ 1
+
+
+Duplicating enum members and values
+-----------------------------------
+
+Having two enum members (or any other attribute) with the same name is invalid;
+in Python 3.x this would raise an error, but in Python 2.x the second member
+simply overwrites the first::
+
+ >>> # python 2.x
+ >>> class Shape(Enum):
+ ... square = 2
+ ... square = 3
+ ...
+ >>> Shape.square
+ <Shape.square: 3>
+
+ >>> # python 3.x
+ >>> class Shape(Enum):
+ ... square = 2
+ ... square = 3
+ Traceback (most recent call last):
+ ...
+ TypeError: Attempted to reuse key: 'square'
+
+However, two enum members are allowed to have the same value. Given two members
+A and B with the same value (and A defined first), B is an alias to A. By-value
+lookup of the value of A and B will return A. By-name lookup of B will also
+return A::
+
+ >>> class Shape(Enum):
+ ... __order__ = 'square diamond circle alias_for_square' # only needed in 2.x
+ ... square = 2
+ ... diamond = 1
+ ... circle = 3
+ ... alias_for_square = 2
+ ...
+ >>> Shape.square
+ <Shape.square: 2>
+ >>> Shape.alias_for_square
+ <Shape.square: 2>
+ >>> Shape(2)
+ <Shape.square: 2>
+
+
+Allowing aliases is not always desirable. ``unique`` can be used to ensure
+that none exist in a particular enumeration::
+
+ >>> from enum import unique
+ >>> @unique
+ ... class Mistake(Enum):
+ ... __order__ = 'one two three four' # only needed in 2.x
+ ... one = 1
+ ... two = 2
+ ... three = 3
+ ... four = 3
+ Traceback (most recent call last):
+ ...
+ ValueError: duplicate names found in <enum 'Mistake'>: four -> three
+
+Iterating over the members of an enum does not provide the aliases::
+
+ >>> list(Shape)
+ [<Shape.square: 2>, <Shape.diamond: 1>, <Shape.circle: 3>]
+
+The special attribute ``__members__`` is a dictionary mapping names to members.
+It includes all names defined in the enumeration, including the aliases::
+
+ >>> for name, member in sorted(Shape.__members__.items()):
+ ... name, member
+ ...
+ ('alias_for_square', <Shape.square: 2>)
+ ('circle', <Shape.circle: 3>)
+ ('diamond', <Shape.diamond: 1>)
+ ('square', <Shape.square: 2>)
+
+The ``__members__`` attribute can be used for detailed programmatic access to
+the enumeration members. For example, finding all the aliases::
+
+ >>> [name for name, member in Shape.__members__.items() if member.name != name]
+ ['alias_for_square']
+
+Comparisons
+-----------
+
+Enumeration members are compared by identity::
+
+ >>> Color.red is Color.red
+ True
+ >>> Color.red is Color.blue
+ False
+ >>> Color.red is not Color.blue
+ True
+
+Ordered comparisons between enumeration values are *not* supported. Enum
+members are not integers (but see `IntEnum`_ below)::
+
+ >>> Color.red < Color.blue
+ Traceback (most recent call last):
+ File "<stdin>", line 1, in <module>
+ TypeError: unorderable types: Color() < Color()
+
+.. warning::
+
+ In Python 2 *everything* is ordered, even though the ordering may not
+ make sense. If you want your enumerations to have a sensible ordering
+ check out the `OrderedEnum`_ recipe below.
+
+
+Equality comparisons are defined though::
+
+ >>> Color.blue == Color.red
+ False
+ >>> Color.blue != Color.red
+ True
+ >>> Color.blue == Color.blue
+ True
+
+Comparisons against non-enumeration values will always compare not equal
+(again, ``IntEnum`` was explicitly designed to behave differently, see
+below)::
+
+ >>> Color.blue == 2
+ False
+
+
+Allowed members and attributes of enumerations
+----------------------------------------------
+
+The examples above use integers for enumeration values. Using integers is
+short and handy (and provided by default by the `Functional API`_), but not
+strictly enforced. In the vast majority of use-cases, one doesn't care what
+the actual value of an enumeration is. But if the value *is* important,
+enumerations can have arbitrary values.
+
+Enumerations are Python classes, and can have methods and special methods as
+usual. If we have this enumeration::
+
+ >>> class Mood(Enum):
+ ... funky = 1
+ ... happy = 3
+ ...
+ ... def describe(self):
+ ... # self is the member here
+ ... return self.name, self.value
+ ...
+ ... def __str__(self):
+ ... return 'my custom str! {0}'.format(self.value)
+ ...
+ ... @classmethod
+ ... def favorite_mood(cls):
+ ... # cls here is the enumeration
+ ... return cls.happy
+
+Then::
+
+ >>> Mood.favorite_mood()
+ <Mood.happy: 3>
+ >>> Mood.happy.describe()
+ ('happy', 3)
+ >>> str(Mood.funky)
+ 'my custom str! 1'
+
+The rules for what is allowed are as follows: _sunder_ names (starting and
+ending with a single underscore) are reserved by enum and cannot be used;
+all other attributes defined within an enumeration will become members of this
+enumeration, with the exception of *__dunder__* names and descriptors (methods
+are also descriptors).
+
+Note:
+
+ If your enumeration defines ``__new__`` and/or ``__init__`` then
+ whatever value(s) were given to the enum member will be passed into
+ those methods. See `Planet`_ for an example.
+
+
+Restricted subclassing of enumerations
+--------------------------------------
+
+Subclassing an enumeration is allowed only if the enumeration does not define
+any members. So this is forbidden::
+
+ >>> class MoreColor(Color):
+ ... pink = 17
+ Traceback (most recent call last):
+ ...
+ TypeError: Cannot extend enumerations
+
+But this is allowed::
+
+ >>> class Foo(Enum):
+ ... def some_behavior(self):
+ ... pass
+ ...
+ >>> class Bar(Foo):
+ ... happy = 1
+ ... sad = 2
+ ...
+
+Allowing subclassing of enums that define members would lead to a violation of
+some important invariants of types and instances. On the other hand, it makes
+sense to allow sharing some common behavior between a group of enumerations.
+(See `OrderedEnum`_ for an example.)
+
+
+Pickling
+--------
+
+Enumerations can be pickled and unpickled::
+
+ >>> from enum.test_enum import Fruit
+ >>> from pickle import dumps, loads
+ >>> Fruit.tomato is loads(dumps(Fruit.tomato, 2))
+ True
+
+The usual restrictions for pickling apply: picklable enums must be defined in
+the top level of a module, since unpickling requires them to be importable
+from that module.
+
+Note:
+
+ With pickle protocol version 4 (introduced in Python 3.4) it is possible
+ to easily pickle enums nested in other classes.
+
+
+
+Functional API
+--------------
+
+The ``Enum`` class is callable, providing the following functional API::
+
+ >>> Animal = Enum('Animal', 'ant bee cat dog')
+ >>> Animal
+ <enum 'Animal'>
+ >>> Animal.ant
+ <Animal.ant: 1>
+ >>> Animal.ant.value
+ 1
+ >>> list(Animal)
+ [<Animal.ant: 1>, <Animal.bee: 2>, <Animal.cat: 3>, <Animal.dog: 4>]
+
+The semantics of this API resemble ``namedtuple``. The first argument
+of the call to ``Enum`` is the name of the enumeration.
+
+The second argument is the *source* of enumeration member names. It can be a
+whitespace-separated string of names, a sequence of names, a sequence of
+2-tuples with key/value pairs, or a mapping (e.g. dictionary) of names to
+values. The last two options enable assigning arbitrary values to
+enumerations; the others auto-assign increasing integers starting with 1. A
+new class derived from ``Enum`` is returned. In other words, the above
+assignment to ``Animal`` is equivalent to::
+
+ >>> class Animals(Enum):
+ ... ant = 1
+ ... bee = 2
+ ... cat = 3
+ ... dog = 4
+
+Pickling enums created with the functional API can be tricky as frame stack
+implementation details are used to try and figure out which module the
+enumeration is being created in (e.g. it will fail if you use a utility
+function in separate module, and also may not work on IronPython or Jython).
+The solution is to specify the module name explicitly as follows::
+
+ >>> Animals = Enum('Animals', 'ant bee cat dog', module=__name__)
+
+Derived Enumerations
+--------------------
+
+IntEnum
+^^^^^^^
+
+A variation of ``Enum`` is provided which is also a subclass of
+``int``. Members of an ``IntEnum`` can be compared to integers;
+by extension, integer enumerations of different types can also be compared
+to each other::
+
+ >>> from enum import IntEnum
+ >>> class Shape(IntEnum):
+ ... circle = 1
+ ... square = 2
+ ...
+ >>> class Request(IntEnum):
+ ... post = 1
+ ... get = 2
+ ...
+ >>> Shape == 1
+ False
+ >>> Shape.circle == 1
+ True
+ >>> Shape.circle == Request.post
+ True
+
+However, they still can't be compared to standard ``Enum`` enumerations::
+
+ >>> class Shape(IntEnum):
+ ... circle = 1
+ ... square = 2
+ ...
+ >>> class Color(Enum):
+ ... red = 1
+ ... green = 2
+ ...
+ >>> Shape.circle == Color.red
+ False
+
+``IntEnum`` values behave like integers in other ways you'd expect::
+
+ >>> int(Shape.circle)
+ 1
+ >>> ['a', 'b', 'c'][Shape.circle]
+ 'b'
+ >>> [i for i in range(Shape.square)]
+ [0, 1]
+
+For the vast majority of code, ``Enum`` is strongly recommended,
+since ``IntEnum`` breaks some semantic promises of an enumeration (by
+being comparable to integers, and thus by transitivity to other
+unrelated enumerations). It should be used only in special cases where
+there's no other choice; for example, when integer constants are
+replaced with enumerations and backwards compatibility is required with code
+that still expects integers.
+
+
+Others
+^^^^^^
+
+While ``IntEnum`` is part of the ``enum`` module, it would be very
+simple to implement independently::
+
+ class IntEnum(int, Enum):
+ pass
+
+This demonstrates how similar derived enumerations can be defined; for example
+a ``StrEnum`` that mixes in ``str`` instead of ``int``.
+
+Some rules:
+
+1. When subclassing ``Enum``, mix-in types must appear before
+ ``Enum`` itself in the sequence of bases, as in the ``IntEnum``
+ example above.
+2. While ``Enum`` can have members of any type, once you mix in an
+ additional type, all the members must have values of that type, e.g.
+ ``int`` above. This restriction does not apply to mix-ins which only
+ add methods and don't specify another data type such as ``int`` or
+ ``str``.
+3. When another data type is mixed in, the ``value`` attribute is *not the
+ same* as the enum member itself, although it is equivalant and will compare
+ equal.
+4. %-style formatting: ``%s`` and ``%r`` call ``Enum``'s ``__str__`` and
+ ``__repr__`` respectively; other codes (such as ``%i`` or ``%h`` for
+ IntEnum) treat the enum member as its mixed-in type.
+
+ Note: Prior to Python 3.4 there is a bug in ``str``'s %-formatting: ``int``
+ subclasses are printed as strings and not numbers when the ``%d``, ``%i``,
+ or ``%u`` codes are used.
+5. ``str.__format__`` (or ``format``) will use the mixed-in
+ type's ``__format__``. If the ``Enum``'s ``str`` or
+ ``repr`` is desired use the ``!s`` or ``!r`` ``str`` format codes.
+
+
+Decorators
+----------
+
+unique
+^^^^^^
+
+A ``class`` decorator specifically for enumerations. It searches an
+enumeration's ``__members__`` gathering any aliases it finds; if any are
+found ``ValueError`` is raised with the details::
+
+ >>> @unique
+ ... class NoDupes(Enum):
+ ... first = 'one'
+ ... second = 'two'
+ ... third = 'two'
+ Traceback (most recent call last):
+ ...
+ ValueError: duplicate names found in <enum 'NoDupes'>: third -> second
+
+
+Interesting examples
+--------------------
+
+While ``Enum`` and ``IntEnum`` are expected to cover the majority of
+use-cases, they cannot cover them all. Here are recipes for some different
+types of enumerations that can be used directly, or as examples for creating
+one's own.
+
+
+AutoNumber
+^^^^^^^^^^
+
+Avoids having to specify the value for each enumeration member::
+
+ >>> class AutoNumber(Enum):
+ ... def __new__(cls):
+ ... value = len(cls.__members__) + 1
+ ... obj = object.__new__(cls)
+ ... obj._value_ = value
+ ... return obj
+ ...
+ >>> class Color(AutoNumber):
+ ... __order__ = "red green blue" # only needed in 2.x
+ ... red = ()
+ ... green = ()
+ ... blue = ()
+ ...
+ >>> Color.green.value == 2
+ True
+
+Note:
+
+ The `__new__` method, if defined, is used during creation of the Enum
+ members; it is then replaced by Enum's `__new__` which is used after
+ class creation for lookup of existing members. Due to the way Enums are
+ supposed to behave, there is no way to customize Enum's `__new__`.
+
+
+UniqueEnum
+^^^^^^^^^^
+
+Raises an error if a duplicate member name is found instead of creating an
+alias::
+
+ >>> class UniqueEnum(Enum):
+ ... def __init__(self, *args):
+ ... cls = self.__class__
+ ... if any(self.value == e.value for e in cls):
+ ... a = self.name
+ ... e = cls(self.value).name
+ ... raise ValueError(
+ ... "aliases not allowed in UniqueEnum: %r --> %r"
+ ... % (a, e))
+ ...
+ >>> class Color(UniqueEnum):
+ ... red = 1
+ ... green = 2
+ ... blue = 3
+ ... grene = 2
+ Traceback (most recent call last):
+ ...
+ ValueError: aliases not allowed in UniqueEnum: 'grene' --> 'green'
+
+
+OrderedEnum
+^^^^^^^^^^^
+
+An ordered enumeration that is not based on ``IntEnum`` and so maintains
+the normal ``Enum`` invariants (such as not being comparable to other
+enumerations)::
+
+ >>> class OrderedEnum(Enum):
+ ... def __ge__(self, other):
+ ... if self.__class__ is other.__class__:
+ ... return self._value_ >= other._value_
+ ... return NotImplemented
+ ... def __gt__(self, other):
+ ... if self.__class__ is other.__class__:
+ ... return self._value_ > other._value_
+ ... return NotImplemented
+ ... def __le__(self, other):
+ ... if self.__class__ is other.__class__:
+ ... return self._value_ <= other._value_
+ ... return NotImplemented
+ ... def __lt__(self, other):
+ ... if self.__class__ is other.__class__:
+ ... return self._value_ < other._value_
+ ... return NotImplemented
+ ...
+ >>> class Grade(OrderedEnum):
+ ... __ordered__ = 'A B C D F'
+ ... A = 5
+ ... B = 4
+ ... C = 3
+ ... D = 2
+ ... F = 1
+ ...
+ >>> Grade.C < Grade.A
+ True
+
+
+Planet
+^^^^^^
+
+If ``__new__`` or ``__init__`` is defined the value of the enum member
+will be passed to those methods::
+
+ >>> class Planet(Enum):
+ ... MERCURY = (3.303e+23, 2.4397e6)
+ ... VENUS = (4.869e+24, 6.0518e6)
+ ... EARTH = (5.976e+24, 6.37814e6)
+ ... MARS = (6.421e+23, 3.3972e6)
+ ... JUPITER = (1.9e+27, 7.1492e7)
+ ... SATURN = (5.688e+26, 6.0268e7)
+ ... URANUS = (8.686e+25, 2.5559e7)
+ ... NEPTUNE = (1.024e+26, 2.4746e7)
+ ... def __init__(self, mass, radius):
+ ... self.mass = mass # in kilograms
+ ... self.radius = radius # in meters
+ ... @property
+ ... def surface_gravity(self):
+ ... # universal gravitational constant (m3 kg-1 s-2)
+ ... G = 6.67300E-11
+ ... return G * self.mass / (self.radius * self.radius)
+ ...
+ >>> Planet.EARTH.value
+ (5.976e+24, 6378140.0)
+ >>> Planet.EARTH.surface_gravity
+ 9.802652743337129
+
+
+How are Enums different?
+------------------------
+
+Enums have a custom metaclass that affects many aspects of both derived Enum
+classes and their instances (members).
+
+
+Enum Classes
+^^^^^^^^^^^^
+
+The ``EnumMeta`` metaclass is responsible for providing the
+``__contains__``, ``__dir__``, ``__iter__`` and other methods that
+allow one to do things with an ``Enum`` class that fail on a typical
+class, such as ``list(Color)`` or ``some_var in Color``. ``EnumMeta`` is
+responsible for ensuring that various other methods on the final ``Enum``
+class are correct (such as ``__new__``, ``__getnewargs__``,
+``__str__`` and ``__repr__``).
+
+.. note::
+
+ ``__dir__`` is not changed in the Python 2 line as it messes up some
+ of the decorators included in the stdlib.
+
+
+Enum Members (aka instances)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The most interesting thing about Enum members is that they are singletons.
+``EnumMeta`` creates them all while it is creating the ``Enum``
+class itself, and then puts a custom ``__new__`` in place to ensure
+that no new ones are ever instantiated by returning only the existing
+member instances.
+
+
+Finer Points
+^^^^^^^^^^^^
+
+``Enum`` members are instances of an ``Enum`` class, and even though they
+are accessible as `EnumClass.member1.member2`, they should not be
+accessed directly from the member as that lookup may fail or, worse,
+return something besides the ``Enum`` member you were looking for
+(changed in version 1.1.1)::
+
+ >>> class FieldTypes(Enum):
+ ... name = 1
+ ... value = 2
+ ... size = 3
+ ...
+ >>> FieldTypes.value.size
+ <FieldTypes.size: 3>
+ >>> FieldTypes.size.value
+ 3
+
+The ``__members__`` attribute is only available on the class.
+
+In Python 3.x ``__members__`` is always an ``OrderedDict``, with the order being
+the definition order. In Python 2.7 ``__members__`` is an ``OrderedDict`` if
+``__order__`` was specified, and a plain ``dict`` otherwise. In all other Python
+2.x versions ``__members__`` is a plain ``dict`` even if ``__order__`` was specified
+as the ``OrderedDict`` type didn't exist yet.
+
+If you give your ``Enum`` subclass extra methods, like the `Planet`_
+class above, those methods will show up in a `dir` of the member,
+but not of the class::
+
+ >>> dir(Planet)
+ ['EARTH', 'JUPITER', 'MARS', 'MERCURY', 'NEPTUNE', 'SATURN', 'URANUS',
+ 'VENUS', '__class__', '__doc__', '__members__', '__module__']
+ >>> dir(Planet.EARTH)
+ ['__class__', '__doc__', '__module__', 'name', 'surface_gravity', 'value']
+
+A ``__new__`` method will only be used for the creation of the
+``Enum`` members -- after that it is replaced. This means if you wish to
+change how ``Enum`` members are looked up you either have to write a
+helper function or a ``classmethod``.
diff --git a/third_party/python/enum34/enum/test.py b/third_party/python/enum34/enum/test.py
new file mode 100644
index 0000000000..d9edfaee40
--- /dev/null
+++ b/third_party/python/enum34/enum/test.py
@@ -0,0 +1,1820 @@
+from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL
+import sys
+import unittest
+pyver = float('%s.%s' % sys.version_info[:2])
+if pyver < 2.5:
+ sys.path.insert(0, '.')
+import enum
+from enum import Enum, IntEnum, unique, EnumMeta
+
+if pyver < 2.6:
+ from __builtin__ import enumerate as bltin_enumerate
+ def enumerate(thing, start=0):
+ result = []
+ for i, item in bltin_enumerate(thing):
+ i = i + start
+ result.append((i, item))
+ return result
+
+try:
+ any
+except NameError:
+ def any(iterable):
+ for element in iterable:
+ if element:
+ return True
+ return False
+
+try:
+ unicode
+except NameError:
+ unicode = str
+
+try:
+ from collections import OrderedDict
+except ImportError:
+ OrderedDict = None
+
+# for pickle tests
+try:
+ class Stooges(Enum):
+ LARRY = 1
+ CURLY = 2
+ MOE = 3
+except Exception:
+ Stooges = sys.exc_info()[1]
+
+try:
+ class IntStooges(int, Enum):
+ LARRY = 1
+ CURLY = 2
+ MOE = 3
+except Exception:
+ IntStooges = sys.exc_info()[1]
+
+try:
+ class FloatStooges(float, Enum):
+ LARRY = 1.39
+ CURLY = 2.72
+ MOE = 3.142596
+except Exception:
+ FloatStooges = sys.exc_info()[1]
+
+# for pickle test and subclass tests
+try:
+ class StrEnum(str, Enum):
+ 'accepts only string values'
+ class Name(StrEnum):
+ BDFL = 'Guido van Rossum'
+ FLUFL = 'Barry Warsaw'
+except Exception:
+ Name = sys.exc_info()[1]
+
+try:
+ Question = Enum('Question', 'who what when where why', module=__name__)
+except Exception:
+ Question = sys.exc_info()[1]
+
+try:
+ Answer = Enum('Answer', 'him this then there because')
+except Exception:
+ Answer = sys.exc_info()[1]
+
+try:
+ Theory = Enum('Theory', 'rule law supposition', qualname='spanish_inquisition')
+except Exception:
+ Theory = sys.exc_info()[1]
+
+# for doctests
+try:
+ class Fruit(Enum):
+ tomato = 1
+ banana = 2
+ cherry = 3
+except Exception:
+ pass
+
+def test_pickle_dump_load(assertion, source, target=None,
+ protocol=(0, HIGHEST_PROTOCOL)):
+ start, stop = protocol
+ failures = []
+ for protocol in range(start, stop+1):
+ try:
+ if target is None:
+ assertion(loads(dumps(source, protocol=protocol)) is source)
+ else:
+ assertion(loads(dumps(source, protocol=protocol)), target)
+ except Exception:
+ exc, tb = sys.exc_info()[1:]
+ failures.append('%2d: %s' %(protocol, exc))
+ if failures:
+ raise ValueError('Failed with protocols: %s' % ', '.join(failures))
+
+def test_pickle_exception(assertion, exception, obj,
+ protocol=(0, HIGHEST_PROTOCOL)):
+ start, stop = protocol
+ failures = []
+ for protocol in range(start, stop+1):
+ try:
+ assertion(exception, dumps, obj, protocol=protocol)
+ except Exception:
+ exc = sys.exc_info()[1]
+ failures.append('%d: %s %s' % (protocol, exc.__class__.__name__, exc))
+ if failures:
+ raise ValueError('Failed with protocols: %s' % ', '.join(failures))
+
+
+class TestHelpers(unittest.TestCase):
+ # _is_descriptor, _is_sunder, _is_dunder
+
+ def test_is_descriptor(self):
+ class foo:
+ pass
+ for attr in ('__get__','__set__','__delete__'):
+ obj = foo()
+ self.assertFalse(enum._is_descriptor(obj))
+ setattr(obj, attr, 1)
+ self.assertTrue(enum._is_descriptor(obj))
+
+ def test_is_sunder(self):
+ for s in ('_a_', '_aa_'):
+ self.assertTrue(enum._is_sunder(s))
+
+ for s in ('a', 'a_', '_a', '__a', 'a__', '__a__', '_a__', '__a_', '_',
+ '__', '___', '____', '_____',):
+ self.assertFalse(enum._is_sunder(s))
+
+ def test_is_dunder(self):
+ for s in ('__a__', '__aa__'):
+ self.assertTrue(enum._is_dunder(s))
+ for s in ('a', 'a_', '_a', '__a', 'a__', '_a_', '_a__', '__a_', '_',
+ '__', '___', '____', '_____',):
+ self.assertFalse(enum._is_dunder(s))
+
+
+class TestEnum(unittest.TestCase):
+ def setUp(self):
+ class Season(Enum):
+ SPRING = 1
+ SUMMER = 2
+ AUTUMN = 3
+ WINTER = 4
+ self.Season = Season
+
+ class Konstants(float, Enum):
+ E = 2.7182818
+ PI = 3.1415926
+ TAU = 2 * PI
+ self.Konstants = Konstants
+
+ class Grades(IntEnum):
+ A = 5
+ B = 4
+ C = 3
+ D = 2
+ F = 0
+ self.Grades = Grades
+
+ class Directional(str, Enum):
+ EAST = 'east'
+ WEST = 'west'
+ NORTH = 'north'
+ SOUTH = 'south'
+ self.Directional = Directional
+
+ from datetime import date
+ class Holiday(date, Enum):
+ NEW_YEAR = 2013, 1, 1
+ IDES_OF_MARCH = 2013, 3, 15
+ self.Holiday = Holiday
+
+ if pyver >= 3.0: # do not specify custom `dir` on previous versions
+ def test_dir_on_class(self):
+ Season = self.Season
+ self.assertEqual(
+ set(dir(Season)),
+ set(['__class__', '__doc__', '__members__', '__module__',
+ 'SPRING', 'SUMMER', 'AUTUMN', 'WINTER']),
+ )
+
+ def test_dir_on_item(self):
+ Season = self.Season
+ self.assertEqual(
+ set(dir(Season.WINTER)),
+ set(['__class__', '__doc__', '__module__', 'name', 'value']),
+ )
+
+ def test_dir_with_added_behavior(self):
+ class Test(Enum):
+ this = 'that'
+ these = 'those'
+ def wowser(self):
+ return ("Wowser! I'm %s!" % self.name)
+ self.assertEqual(
+ set(dir(Test)),
+ set(['__class__', '__doc__', '__members__', '__module__', 'this', 'these']),
+ )
+ self.assertEqual(
+ set(dir(Test.this)),
+ set(['__class__', '__doc__', '__module__', 'name', 'value', 'wowser']),
+ )
+
+ def test_dir_on_sub_with_behavior_on_super(self):
+ # see issue22506
+ class SuperEnum(Enum):
+ def invisible(self):
+ return "did you see me?"
+ class SubEnum(SuperEnum):
+ sample = 5
+ self.assertEqual(
+ set(dir(SubEnum.sample)),
+ set(['__class__', '__doc__', '__module__', 'name', 'value', 'invisible']),
+ )
+
+ if pyver >= 2.7: # OrderedDict first available here
+ def test_members_is_ordereddict_if_ordered(self):
+ class Ordered(Enum):
+ __order__ = 'first second third'
+ first = 'bippity'
+ second = 'boppity'
+ third = 'boo'
+ self.assertTrue(type(Ordered.__members__) is OrderedDict)
+
+ def test_members_is_ordereddict_if_not_ordered(self):
+ class Unordered(Enum):
+ this = 'that'
+ these = 'those'
+ self.assertTrue(type(Unordered.__members__) is OrderedDict)
+
+ if pyver >= 3.0: # all objects are ordered in Python 2.x
+ def test_members_is_always_ordered(self):
+ class AlwaysOrdered(Enum):
+ first = 1
+ second = 2
+ third = 3
+ self.assertTrue(type(AlwaysOrdered.__members__) is OrderedDict)
+
+ def test_comparisons(self):
+ def bad_compare():
+ Season.SPRING > 4
+ Season = self.Season
+ self.assertNotEqual(Season.SPRING, 1)
+ self.assertRaises(TypeError, bad_compare)
+
+ class Part(Enum):
+ SPRING = 1
+ CLIP = 2
+ BARREL = 3
+
+ self.assertNotEqual(Season.SPRING, Part.SPRING)
+ def bad_compare():
+ Season.SPRING < Part.CLIP
+ self.assertRaises(TypeError, bad_compare)
+
+ def test_enum_in_enum_out(self):
+ Season = self.Season
+ self.assertTrue(Season(Season.WINTER) is Season.WINTER)
+
+ def test_enum_value(self):
+ Season = self.Season
+ self.assertEqual(Season.SPRING.value, 1)
+
+ def test_intenum_value(self):
+ self.assertEqual(IntStooges.CURLY.value, 2)
+
+ def test_enum(self):
+ Season = self.Season
+ lst = list(Season)
+ self.assertEqual(len(lst), len(Season))
+ self.assertEqual(len(Season), 4, Season)
+ self.assertEqual(
+ [Season.SPRING, Season.SUMMER, Season.AUTUMN, Season.WINTER], lst)
+
+ for i, season in enumerate('SPRING SUMMER AUTUMN WINTER'.split()):
+ i += 1
+ e = Season(i)
+ self.assertEqual(e, getattr(Season, season))
+ self.assertEqual(e.value, i)
+ self.assertNotEqual(e, i)
+ self.assertEqual(e.name, season)
+ self.assertTrue(e in Season)
+ self.assertTrue(type(e) is Season)
+ self.assertTrue(isinstance(e, Season))
+ self.assertEqual(str(e), 'Season.' + season)
+ self.assertEqual(
+ repr(e),
+ '<Season.%s: %s>' % (season, i),
+ )
+
+ def test_value_name(self):
+ Season = self.Season
+ self.assertEqual(Season.SPRING.name, 'SPRING')
+ self.assertEqual(Season.SPRING.value, 1)
+ def set_name(obj, new_value):
+ obj.name = new_value
+ def set_value(obj, new_value):
+ obj.value = new_value
+ self.assertRaises(AttributeError, set_name, Season.SPRING, 'invierno', )
+ self.assertRaises(AttributeError, set_value, Season.SPRING, 2)
+
+ def test_attribute_deletion(self):
+ class Season(Enum):
+ SPRING = 1
+ SUMMER = 2
+ AUTUMN = 3
+ WINTER = 4
+
+ def spam(cls):
+ pass
+
+ self.assertTrue(hasattr(Season, 'spam'))
+ del Season.spam
+ self.assertFalse(hasattr(Season, 'spam'))
+
+ self.assertRaises(AttributeError, delattr, Season, 'SPRING')
+ self.assertRaises(AttributeError, delattr, Season, 'DRY')
+ self.assertRaises(AttributeError, delattr, Season.SPRING, 'name')
+
+ def test_bool_of_class(self):
+ class Empty(Enum):
+ pass
+ self.assertTrue(bool(Empty))
+
+ def test_bool_of_member(self):
+ class Count(Enum):
+ zero = 0
+ one = 1
+ two = 2
+ for member in Count:
+ self.assertTrue(bool(member))
+
+ def test_invalid_names(self):
+ def create_bad_class_1():
+ class Wrong(Enum):
+ mro = 9
+ def create_bad_class_2():
+ class Wrong(Enum):
+ _reserved_ = 3
+ self.assertRaises(ValueError, create_bad_class_1)
+ self.assertRaises(ValueError, create_bad_class_2)
+
+ def test_contains(self):
+ Season = self.Season
+ self.assertTrue(Season.AUTUMN in Season)
+ self.assertTrue(3 not in Season)
+
+ val = Season(3)
+ self.assertTrue(val in Season)
+
+ class OtherEnum(Enum):
+ one = 1; two = 2
+ self.assertTrue(OtherEnum.two not in Season)
+
+ if pyver >= 2.6: # when `format` came into being
+
+ def test_format_enum(self):
+ Season = self.Season
+ self.assertEqual('{0}'.format(Season.SPRING),
+ '{0}'.format(str(Season.SPRING)))
+ self.assertEqual( '{0:}'.format(Season.SPRING),
+ '{0:}'.format(str(Season.SPRING)))
+ self.assertEqual('{0:20}'.format(Season.SPRING),
+ '{0:20}'.format(str(Season.SPRING)))
+ self.assertEqual('{0:^20}'.format(Season.SPRING),
+ '{0:^20}'.format(str(Season.SPRING)))
+ self.assertEqual('{0:>20}'.format(Season.SPRING),
+ '{0:>20}'.format(str(Season.SPRING)))
+ self.assertEqual('{0:<20}'.format(Season.SPRING),
+ '{0:<20}'.format(str(Season.SPRING)))
+
+ def test_format_enum_custom(self):
+ class TestFloat(float, Enum):
+ one = 1.0
+ two = 2.0
+ def __format__(self, spec):
+ return 'TestFloat success!'
+ self.assertEqual('{0}'.format(TestFloat.one), 'TestFloat success!')
+
+ def assertFormatIsValue(self, spec, member):
+ self.assertEqual(spec.format(member), spec.format(member.value))
+
+ def test_format_enum_date(self):
+ Holiday = self.Holiday
+ self.assertFormatIsValue('{0}', Holiday.IDES_OF_MARCH)
+ self.assertFormatIsValue('{0:}', Holiday.IDES_OF_MARCH)
+ self.assertFormatIsValue('{0:20}', Holiday.IDES_OF_MARCH)
+ self.assertFormatIsValue('{0:^20}', Holiday.IDES_OF_MARCH)
+ self.assertFormatIsValue('{0:>20}', Holiday.IDES_OF_MARCH)
+ self.assertFormatIsValue('{0:<20}', Holiday.IDES_OF_MARCH)
+ self.assertFormatIsValue('{0:%Y %m}', Holiday.IDES_OF_MARCH)
+ self.assertFormatIsValue('{0:%Y %m %M:00}', Holiday.IDES_OF_MARCH)
+
+ def test_format_enum_float(self):
+ Konstants = self.Konstants
+ self.assertFormatIsValue('{0}', Konstants.TAU)
+ self.assertFormatIsValue('{0:}', Konstants.TAU)
+ self.assertFormatIsValue('{0:20}', Konstants.TAU)
+ self.assertFormatIsValue('{0:^20}', Konstants.TAU)
+ self.assertFormatIsValue('{0:>20}', Konstants.TAU)
+ self.assertFormatIsValue('{0:<20}', Konstants.TAU)
+ self.assertFormatIsValue('{0:n}', Konstants.TAU)
+ self.assertFormatIsValue('{0:5.2}', Konstants.TAU)
+ self.assertFormatIsValue('{0:f}', Konstants.TAU)
+
+ def test_format_enum_int(self):
+ Grades = self.Grades
+ self.assertFormatIsValue('{0}', Grades.C)
+ self.assertFormatIsValue('{0:}', Grades.C)
+ self.assertFormatIsValue('{0:20}', Grades.C)
+ self.assertFormatIsValue('{0:^20}', Grades.C)
+ self.assertFormatIsValue('{0:>20}', Grades.C)
+ self.assertFormatIsValue('{0:<20}', Grades.C)
+ self.assertFormatIsValue('{0:+}', Grades.C)
+ self.assertFormatIsValue('{0:08X}', Grades.C)
+ self.assertFormatIsValue('{0:b}', Grades.C)
+
+ def test_format_enum_str(self):
+ Directional = self.Directional
+ self.assertFormatIsValue('{0}', Directional.WEST)
+ self.assertFormatIsValue('{0:}', Directional.WEST)
+ self.assertFormatIsValue('{0:20}', Directional.WEST)
+ self.assertFormatIsValue('{0:^20}', Directional.WEST)
+ self.assertFormatIsValue('{0:>20}', Directional.WEST)
+ self.assertFormatIsValue('{0:<20}', Directional.WEST)
+
+ def test_hash(self):
+ Season = self.Season
+ dates = {}
+ dates[Season.WINTER] = '1225'
+ dates[Season.SPRING] = '0315'
+ dates[Season.SUMMER] = '0704'
+ dates[Season.AUTUMN] = '1031'
+ self.assertEqual(dates[Season.AUTUMN], '1031')
+
+ def test_enum_duplicates(self):
+ _order_ = "SPRING SUMMER AUTUMN WINTER"
+ class Season(Enum):
+ SPRING = 1
+ SUMMER = 2
+ AUTUMN = FALL = 3
+ WINTER = 4
+ ANOTHER_SPRING = 1
+ lst = list(Season)
+ self.assertEqual(
+ lst,
+ [Season.SPRING, Season.SUMMER,
+ Season.AUTUMN, Season.WINTER,
+ ])
+ self.assertTrue(Season.FALL is Season.AUTUMN)
+ self.assertEqual(Season.FALL.value, 3)
+ self.assertEqual(Season.AUTUMN.value, 3)
+ self.assertTrue(Season(3) is Season.AUTUMN)
+ self.assertTrue(Season(1) is Season.SPRING)
+ self.assertEqual(Season.FALL.name, 'AUTUMN')
+ self.assertEqual(
+ set([k for k,v in Season.__members__.items() if v.name != k]),
+ set(['FALL', 'ANOTHER_SPRING']),
+ )
+
+ if pyver >= 3.0:
+ cls = vars()
+ result = {'Enum':Enum}
+ exec("""def test_duplicate_name(self):
+ with self.assertRaises(TypeError):
+ class Color(Enum):
+ red = 1
+ green = 2
+ blue = 3
+ red = 4
+
+ with self.assertRaises(TypeError):
+ class Color(Enum):
+ red = 1
+ green = 2
+ blue = 3
+ def red(self):
+ return 'red'
+
+ with self.assertRaises(TypeError):
+ class Color(Enum):
+ @property
+
+ def red(self):
+ return 'redder'
+ red = 1
+ green = 2
+ blue = 3""",
+ result)
+ cls['test_duplicate_name'] = result['test_duplicate_name']
+
+ def test_enum_with_value_name(self):
+ class Huh(Enum):
+ name = 1
+ value = 2
+ self.assertEqual(
+ list(Huh),
+ [Huh.name, Huh.value],
+ )
+ self.assertTrue(type(Huh.name) is Huh)
+ self.assertEqual(Huh.name.name, 'name')
+ self.assertEqual(Huh.name.value, 1)
+
+ def test_intenum_from_scratch(self):
+ class phy(int, Enum):
+ pi = 3
+ tau = 2 * pi
+ self.assertTrue(phy.pi < phy.tau)
+
+ def test_intenum_inherited(self):
+ class IntEnum(int, Enum):
+ pass
+ class phy(IntEnum):
+ pi = 3
+ tau = 2 * pi
+ self.assertTrue(phy.pi < phy.tau)
+
+ def test_floatenum_from_scratch(self):
+ class phy(float, Enum):
+ pi = 3.1415926
+ tau = 2 * pi
+ self.assertTrue(phy.pi < phy.tau)
+
+ def test_floatenum_inherited(self):
+ class FloatEnum(float, Enum):
+ pass
+ class phy(FloatEnum):
+ pi = 3.1415926
+ tau = 2 * pi
+ self.assertTrue(phy.pi < phy.tau)
+
+ def test_strenum_from_scratch(self):
+ class phy(str, Enum):
+ pi = 'Pi'
+ tau = 'Tau'
+ self.assertTrue(phy.pi < phy.tau)
+
+ def test_strenum_inherited(self):
+ class StrEnum(str, Enum):
+ pass
+ class phy(StrEnum):
+ pi = 'Pi'
+ tau = 'Tau'
+ self.assertTrue(phy.pi < phy.tau)
+
+ def test_intenum(self):
+ class WeekDay(IntEnum):
+ SUNDAY = 1
+ MONDAY = 2
+ TUESDAY = 3
+ WEDNESDAY = 4
+ THURSDAY = 5
+ FRIDAY = 6
+ SATURDAY = 7
+
+ self.assertEqual(['a', 'b', 'c'][WeekDay.MONDAY], 'c')
+ self.assertEqual([i for i in range(WeekDay.TUESDAY)], [0, 1, 2])
+
+ lst = list(WeekDay)
+ self.assertEqual(len(lst), len(WeekDay))
+ self.assertEqual(len(WeekDay), 7)
+ target = 'SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY'
+ target = target.split()
+ for i, weekday in enumerate(target):
+ i += 1
+ e = WeekDay(i)
+ self.assertEqual(e, i)
+ self.assertEqual(int(e), i)
+ self.assertEqual(e.name, weekday)
+ self.assertTrue(e in WeekDay)
+ self.assertEqual(lst.index(e)+1, i)
+ self.assertTrue(0 < e < 8)
+ self.assertTrue(type(e) is WeekDay)
+ self.assertTrue(isinstance(e, int))
+ self.assertTrue(isinstance(e, Enum))
+
+ def test_intenum_duplicates(self):
+ class WeekDay(IntEnum):
+ __order__ = 'SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY'
+ SUNDAY = 1
+ MONDAY = 2
+ TUESDAY = TEUSDAY = 3
+ WEDNESDAY = 4
+ THURSDAY = 5
+ FRIDAY = 6
+ SATURDAY = 7
+ self.assertTrue(WeekDay.TEUSDAY is WeekDay.TUESDAY)
+ self.assertEqual(WeekDay(3).name, 'TUESDAY')
+ self.assertEqual([k for k,v in WeekDay.__members__.items()
+ if v.name != k], ['TEUSDAY', ])
+
+ def test_pickle_enum(self):
+ if isinstance(Stooges, Exception):
+ raise Stooges
+ test_pickle_dump_load(self.assertTrue, Stooges.CURLY)
+ test_pickle_dump_load(self.assertTrue, Stooges)
+
+ def test_pickle_int(self):
+ if isinstance(IntStooges, Exception):
+ raise IntStooges
+ test_pickle_dump_load(self.assertTrue, IntStooges.CURLY)
+ test_pickle_dump_load(self.assertTrue, IntStooges)
+
+ def test_pickle_float(self):
+ if isinstance(FloatStooges, Exception):
+ raise FloatStooges
+ test_pickle_dump_load(self.assertTrue, FloatStooges.CURLY)
+ test_pickle_dump_load(self.assertTrue, FloatStooges)
+
+ def test_pickle_enum_function(self):
+ if isinstance(Answer, Exception):
+ raise Answer
+ test_pickle_dump_load(self.assertTrue, Answer.him)
+ test_pickle_dump_load(self.assertTrue, Answer)
+
+ def test_pickle_enum_function_with_module(self):
+ if isinstance(Question, Exception):
+ raise Question
+ test_pickle_dump_load(self.assertTrue, Question.who)
+ test_pickle_dump_load(self.assertTrue, Question)
+
+ if pyver == 3.4:
+ def test_class_nested_enum_and_pickle_protocol_four(self):
+ # would normally just have this directly in the class namespace
+ class NestedEnum(Enum):
+ twigs = 'common'
+ shiny = 'rare'
+
+ self.__class__.NestedEnum = NestedEnum
+ self.NestedEnum.__qualname__ = '%s.NestedEnum' % self.__class__.__name__
+ test_pickle_exception(
+ self.assertRaises, PicklingError, self.NestedEnum.twigs,
+ protocol=(0, 3))
+ test_pickle_dump_load(self.assertTrue, self.NestedEnum.twigs,
+ protocol=(4, HIGHEST_PROTOCOL))
+
+ elif pyver == 3.5:
+ def test_class_nested_enum_and_pickle_protocol_four(self):
+ # would normally just have this directly in the class namespace
+ class NestedEnum(Enum):
+ twigs = 'common'
+ shiny = 'rare'
+
+ self.__class__.NestedEnum = NestedEnum
+ self.NestedEnum.__qualname__ = '%s.NestedEnum' % self.__class__.__name__
+ test_pickle_dump_load(self.assertTrue, self.NestedEnum.twigs,
+ protocol=(0, HIGHEST_PROTOCOL))
+
+ def test_exploding_pickle(self):
+ BadPickle = Enum('BadPickle', 'dill sweet bread-n-butter')
+ enum._make_class_unpicklable(BadPickle)
+ globals()['BadPickle'] = BadPickle
+ test_pickle_exception(self.assertRaises, TypeError, BadPickle.dill)
+ test_pickle_exception(self.assertRaises, PicklingError, BadPickle)
+
+ def test_string_enum(self):
+ class SkillLevel(str, Enum):
+ master = 'what is the sound of one hand clapping?'
+ journeyman = 'why did the chicken cross the road?'
+ apprentice = 'knock, knock!'
+ self.assertEqual(SkillLevel.apprentice, 'knock, knock!')
+
+ def test_getattr_getitem(self):
+ class Period(Enum):
+ morning = 1
+ noon = 2
+ evening = 3
+ night = 4
+ self.assertTrue(Period(2) is Period.noon)
+ self.assertTrue(getattr(Period, 'night') is Period.night)
+ self.assertTrue(Period['morning'] is Period.morning)
+
+ def test_getattr_dunder(self):
+ Season = self.Season
+ self.assertTrue(getattr(Season, '__hash__'))
+
+ def test_iteration_order(self):
+ class Season(Enum):
+ _order_ = 'SUMMER WINTER AUTUMN SPRING'
+ SUMMER = 2
+ WINTER = 4
+ AUTUMN = 3
+ SPRING = 1
+ self.assertEqual(
+ list(Season),
+ [Season.SUMMER, Season.WINTER, Season.AUTUMN, Season.SPRING],
+ )
+
+ def test_iteration_order_reversed(self):
+ self.assertEqual(
+ list(reversed(self.Season)),
+ [self.Season.WINTER, self.Season.AUTUMN, self.Season.SUMMER,
+ self.Season.SPRING]
+ )
+
+ def test_iteration_order_with_unorderable_values(self):
+ class Complex(Enum):
+ a = complex(7, 9)
+ b = complex(3.14, 2)
+ c = complex(1, -1)
+ d = complex(-77, 32)
+ self.assertEqual(
+ list(Complex),
+ [Complex.a, Complex.b, Complex.c, Complex.d],
+ )
+
+ def test_programatic_function_string(self):
+ SummerMonth = Enum('SummerMonth', 'june july august')
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split()):
+ i += 1
+ e = SummerMonth(i)
+ self.assertEqual(int(e.value), i)
+ self.assertNotEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_string_with_start(self):
+ SummerMonth = Enum('SummerMonth', 'june july august', start=10)
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split(), 10):
+ e = SummerMonth(i)
+ self.assertEqual(int(e.value), i)
+ self.assertNotEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_string_list(self):
+ SummerMonth = Enum('SummerMonth', ['june', 'july', 'august'])
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split()):
+ i += 1
+ e = SummerMonth(i)
+ self.assertEqual(int(e.value), i)
+ self.assertNotEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_string_list_with_start(self):
+ SummerMonth = Enum('SummerMonth', ['june', 'july', 'august'], start=20)
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split(), 20):
+ e = SummerMonth(i)
+ self.assertEqual(int(e.value), i)
+ self.assertNotEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_iterable(self):
+ SummerMonth = Enum(
+ 'SummerMonth',
+ (('june', 1), ('july', 2), ('august', 3))
+ )
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split()):
+ i += 1
+ e = SummerMonth(i)
+ self.assertEqual(int(e.value), i)
+ self.assertNotEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_from_dict(self):
+ SummerMonth = Enum(
+ 'SummerMonth',
+ dict((('june', 1), ('july', 2), ('august', 3)))
+ )
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ if pyver < 3.0:
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split()):
+ i += 1
+ e = SummerMonth(i)
+ self.assertEqual(int(e.value), i)
+ self.assertNotEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_type(self):
+ SummerMonth = Enum('SummerMonth', 'june july august', type=int)
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split()):
+ i += 1
+ e = SummerMonth(i)
+ self.assertEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_type_with_start(self):
+ SummerMonth = Enum('SummerMonth', 'june july august', type=int, start=30)
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split(), 30):
+ e = SummerMonth(i)
+ self.assertEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_type_from_subclass(self):
+ SummerMonth = IntEnum('SummerMonth', 'june july august')
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split()):
+ i += 1
+ e = SummerMonth(i)
+ self.assertEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_type_from_subclass_with_start(self):
+ SummerMonth = IntEnum('SummerMonth', 'june july august', start=40)
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split(), 40):
+ e = SummerMonth(i)
+ self.assertEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_unicode(self):
+ SummerMonth = Enum('SummerMonth', unicode('june july august'))
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate(unicode('june july august').split()):
+ i += 1
+ e = SummerMonth(i)
+ self.assertEqual(int(e.value), i)
+ self.assertNotEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_unicode_list(self):
+ SummerMonth = Enum('SummerMonth', [unicode('june'), unicode('july'), unicode('august')])
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate(unicode('june july august').split()):
+ i += 1
+ e = SummerMonth(i)
+ self.assertEqual(int(e.value), i)
+ self.assertNotEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_unicode_iterable(self):
+ SummerMonth = Enum(
+ 'SummerMonth',
+ ((unicode('june'), 1), (unicode('july'), 2), (unicode('august'), 3))
+ )
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate(unicode('june july august').split()):
+ i += 1
+ e = SummerMonth(i)
+ self.assertEqual(int(e.value), i)
+ self.assertNotEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_from_unicode_dict(self):
+ SummerMonth = Enum(
+ 'SummerMonth',
+ dict(((unicode('june'), 1), (unicode('july'), 2), (unicode('august'), 3)))
+ )
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ if pyver < 3.0:
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate(unicode('june july august').split()):
+ i += 1
+ e = SummerMonth(i)
+ self.assertEqual(int(e.value), i)
+ self.assertNotEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_unicode_type(self):
+ SummerMonth = Enum('SummerMonth', unicode('june july august'), type=int)
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate(unicode('june july august').split()):
+ i += 1
+ e = SummerMonth(i)
+ self.assertEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programatic_function_unicode_type_from_subclass(self):
+ SummerMonth = IntEnum('SummerMonth', unicode('june july august'))
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate(unicode('june july august').split()):
+ i += 1
+ e = SummerMonth(i)
+ self.assertEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_programmatic_function_unicode_class(self):
+ if pyver < 3.0:
+ class_names = unicode('SummerMonth'), 'S\xfcmm\xe9rM\xf6nth'.decode('latin1')
+ else:
+ class_names = 'SummerMonth', 'S\xfcmm\xe9rM\xf6nth'
+ for i, class_name in enumerate(class_names):
+ if pyver < 3.0 and i == 1:
+ self.assertRaises(TypeError, Enum, class_name, unicode('june july august'))
+ else:
+ SummerMonth = Enum(class_name, unicode('june july august'))
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate(unicode('june july august').split()):
+ i += 1
+ e = SummerMonth(i)
+ self.assertEqual(e.value, i)
+ self.assertEqual(e.name, month)
+ self.assertTrue(e in SummerMonth)
+ self.assertTrue(type(e) is SummerMonth)
+
+ def test_subclassing(self):
+ if isinstance(Name, Exception):
+ raise Name
+ self.assertEqual(Name.BDFL, 'Guido van Rossum')
+ self.assertTrue(Name.BDFL, Name('Guido van Rossum'))
+ self.assertTrue(Name.BDFL is getattr(Name, 'BDFL'))
+ test_pickle_dump_load(self.assertTrue, Name.BDFL)
+
+ def test_extending(self):
+ def bad_extension():
+ class Color(Enum):
+ red = 1
+ green = 2
+ blue = 3
+ class MoreColor(Color):
+ cyan = 4
+ magenta = 5
+ yellow = 6
+ self.assertRaises(TypeError, bad_extension)
+
+ def test_exclude_methods(self):
+ class whatever(Enum):
+ this = 'that'
+ these = 'those'
+ def really(self):
+ return 'no, not %s' % self.value
+ self.assertFalse(type(whatever.really) is whatever)
+ self.assertEqual(whatever.this.really(), 'no, not that')
+
+ def test_wrong_inheritance_order(self):
+ def wrong_inherit():
+ class Wrong(Enum, str):
+ NotHere = 'error before this point'
+ self.assertRaises(TypeError, wrong_inherit)
+
+ def test_intenum_transitivity(self):
+ class number(IntEnum):
+ one = 1
+ two = 2
+ three = 3
+ class numero(IntEnum):
+ uno = 1
+ dos = 2
+ tres = 3
+ self.assertEqual(number.one, numero.uno)
+ self.assertEqual(number.two, numero.dos)
+ self.assertEqual(number.three, numero.tres)
+
+ def test_introspection(self):
+ class Number(IntEnum):
+ one = 100
+ two = 200
+ self.assertTrue(Number.one._member_type_ is int)
+ self.assertTrue(Number._member_type_ is int)
+ class String(str, Enum):
+ yarn = 'soft'
+ rope = 'rough'
+ wire = 'hard'
+ self.assertTrue(String.yarn._member_type_ is str)
+ self.assertTrue(String._member_type_ is str)
+ class Plain(Enum):
+ vanilla = 'white'
+ one = 1
+ self.assertTrue(Plain.vanilla._member_type_ is object)
+ self.assertTrue(Plain._member_type_ is object)
+
+ def test_wrong_enum_in_call(self):
+ class Monochrome(Enum):
+ black = 0
+ white = 1
+ class Gender(Enum):
+ male = 0
+ female = 1
+ self.assertRaises(ValueError, Monochrome, Gender.male)
+
+ def test_wrong_enum_in_mixed_call(self):
+ class Monochrome(IntEnum):
+ black = 0
+ white = 1
+ class Gender(Enum):
+ male = 0
+ female = 1
+ self.assertRaises(ValueError, Monochrome, Gender.male)
+
+ def test_mixed_enum_in_call_1(self):
+ class Monochrome(IntEnum):
+ black = 0
+ white = 1
+ class Gender(IntEnum):
+ male = 0
+ female = 1
+ self.assertTrue(Monochrome(Gender.female) is Monochrome.white)
+
+ def test_mixed_enum_in_call_2(self):
+ class Monochrome(Enum):
+ black = 0
+ white = 1
+ class Gender(IntEnum):
+ male = 0
+ female = 1
+ self.assertTrue(Monochrome(Gender.male) is Monochrome.black)
+
+ def test_flufl_enum(self):
+ class Fluflnum(Enum):
+ def __int__(self):
+ return int(self.value)
+ class MailManOptions(Fluflnum):
+ option1 = 1
+ option2 = 2
+ option3 = 3
+ self.assertEqual(int(MailManOptions.option1), 1)
+
+ def test_no_such_enum_member(self):
+ class Color(Enum):
+ red = 1
+ green = 2
+ blue = 3
+ self.assertRaises(ValueError, Color, 4)
+ self.assertRaises(KeyError, Color.__getitem__, 'chartreuse')
+
+ def test_new_repr(self):
+ class Color(Enum):
+ red = 1
+ green = 2
+ blue = 3
+ def __repr__(self):
+ return "don't you just love shades of %s?" % self.name
+ self.assertEqual(
+ repr(Color.blue),
+ "don't you just love shades of blue?",
+ )
+
+ def test_inherited_repr(self):
+ class MyEnum(Enum):
+ def __repr__(self):
+ return "My name is %s." % self.name
+ class MyIntEnum(int, MyEnum):
+ this = 1
+ that = 2
+ theother = 3
+ self.assertEqual(repr(MyIntEnum.that), "My name is that.")
+
+ def test_multiple_mixin_mro(self):
+ class auto_enum(EnumMeta):
+ def __new__(metacls, cls, bases, classdict):
+ original_dict = classdict
+ classdict = enum._EnumDict()
+ for k, v in original_dict.items():
+ classdict[k] = v
+ temp = type(classdict)()
+ names = set(classdict._member_names)
+ i = 0
+ for k in classdict._member_names:
+ v = classdict[k]
+ if v == ():
+ v = i
+ else:
+ i = v
+ i += 1
+ temp[k] = v
+ for k, v in classdict.items():
+ if k not in names:
+ temp[k] = v
+ return super(auto_enum, metacls).__new__(
+ metacls, cls, bases, temp)
+
+ AutoNumberedEnum = auto_enum('AutoNumberedEnum', (Enum,), {})
+
+ AutoIntEnum = auto_enum('AutoIntEnum', (IntEnum,), {})
+
+ class TestAutoNumber(AutoNumberedEnum):
+ a = ()
+ b = 3
+ c = ()
+
+ class TestAutoInt(AutoIntEnum):
+ a = ()
+ b = 3
+ c = ()
+
+ def test_subclasses_with_getnewargs(self):
+ class NamedInt(int):
+ __qualname__ = 'NamedInt' # needed for pickle protocol 4
+ def __new__(cls, *args):
+ _args = args
+ if len(args) < 1:
+ raise TypeError("name and value must be specified")
+ name, args = args[0], args[1:]
+ self = int.__new__(cls, *args)
+ self._intname = name
+ self._args = _args
+ return self
+ def __getnewargs__(self):
+ return self._args
+ @property
+ def __name__(self):
+ return self._intname
+ def __repr__(self):
+ # repr() is updated to include the name and type info
+ return "%s(%r, %s)" % (type(self).__name__,
+ self.__name__,
+ int.__repr__(self))
+ def __str__(self):
+ # str() is unchanged, even if it relies on the repr() fallback
+ base = int
+ base_str = base.__str__
+ if base_str.__objclass__ is object:
+ return base.__repr__(self)
+ return base_str(self)
+ # for simplicity, we only define one operator that
+ # propagates expressions
+ def __add__(self, other):
+ temp = int(self) + int( other)
+ if isinstance(self, NamedInt) and isinstance(other, NamedInt):
+ return NamedInt(
+ '(%s + %s)' % (self.__name__, other.__name__),
+ temp )
+ else:
+ return temp
+
+ class NEI(NamedInt, Enum):
+ __qualname__ = 'NEI' # needed for pickle protocol 4
+ x = ('the-x', 1)
+ y = ('the-y', 2)
+
+ self.assertTrue(NEI.__new__ is Enum.__new__)
+ self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
+ globals()['NamedInt'] = NamedInt
+ globals()['NEI'] = NEI
+ NI5 = NamedInt('test', 5)
+ self.assertEqual(NI5, 5)
+ test_pickle_dump_load(self.assertTrue, NI5, 5)
+ self.assertEqual(NEI.y.value, 2)
+ test_pickle_dump_load(self.assertTrue, NEI.y)
+
+ if pyver >= 3.4:
+ def test_subclasses_with_getnewargs_ex(self):
+ class NamedInt(int):
+ __qualname__ = 'NamedInt' # needed for pickle protocol 4
+ def __new__(cls, *args):
+ _args = args
+ if len(args) < 2:
+ raise TypeError("name and value must be specified")
+ name, args = args[0], args[1:]
+ self = int.__new__(cls, *args)
+ self._intname = name
+ self._args = _args
+ return self
+ def __getnewargs_ex__(self):
+ return self._args, {}
+ @property
+ def __name__(self):
+ return self._intname
+ def __repr__(self):
+ # repr() is updated to include the name and type info
+ return "{}({!r}, {})".format(type(self).__name__,
+ self.__name__,
+ int.__repr__(self))
+ def __str__(self):
+ # str() is unchanged, even if it relies on the repr() fallback
+ base = int
+ base_str = base.__str__
+ if base_str.__objclass__ is object:
+ return base.__repr__(self)
+ return base_str(self)
+ # for simplicity, we only define one operator that
+ # propagates expressions
+ def __add__(self, other):
+ temp = int(self) + int( other)
+ if isinstance(self, NamedInt) and isinstance(other, NamedInt):
+ return NamedInt(
+ '({0} + {1})'.format(self.__name__, other.__name__),
+ temp )
+ else:
+ return temp
+
+ class NEI(NamedInt, Enum):
+ __qualname__ = 'NEI' # needed for pickle protocol 4
+ x = ('the-x', 1)
+ y = ('the-y', 2)
+
+
+ self.assertIs(NEI.__new__, Enum.__new__)
+ self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
+ globals()['NamedInt'] = NamedInt
+ globals()['NEI'] = NEI
+ NI5 = NamedInt('test', 5)
+ self.assertEqual(NI5, 5)
+ test_pickle_dump_load(self.assertEqual, NI5, 5, protocol=(4, HIGHEST_PROTOCOL))
+ self.assertEqual(NEI.y.value, 2)
+ test_pickle_dump_load(self.assertTrue, NEI.y, protocol=(4, HIGHEST_PROTOCOL))
+
+ def test_subclasses_with_reduce(self):
+ class NamedInt(int):
+ __qualname__ = 'NamedInt' # needed for pickle protocol 4
+ def __new__(cls, *args):
+ _args = args
+ if len(args) < 1:
+ raise TypeError("name and value must be specified")
+ name, args = args[0], args[1:]
+ self = int.__new__(cls, *args)
+ self._intname = name
+ self._args = _args
+ return self
+ def __reduce__(self):
+ return self.__class__, self._args
+ @property
+ def __name__(self):
+ return self._intname
+ def __repr__(self):
+ # repr() is updated to include the name and type info
+ return "%s(%r, %s)" % (type(self).__name__,
+ self.__name__,
+ int.__repr__(self))
+ def __str__(self):
+ # str() is unchanged, even if it relies on the repr() fallback
+ base = int
+ base_str = base.__str__
+ if base_str.__objclass__ is object:
+ return base.__repr__(self)
+ return base_str(self)
+ # for simplicity, we only define one operator that
+ # propagates expressions
+ def __add__(self, other):
+ temp = int(self) + int( other)
+ if isinstance(self, NamedInt) and isinstance(other, NamedInt):
+ return NamedInt(
+ '(%s + %s)' % (self.__name__, other.__name__),
+ temp )
+ else:
+ return temp
+
+ class NEI(NamedInt, Enum):
+ __qualname__ = 'NEI' # needed for pickle protocol 4
+ x = ('the-x', 1)
+ y = ('the-y', 2)
+
+
+ self.assertTrue(NEI.__new__ is Enum.__new__)
+ self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
+ globals()['NamedInt'] = NamedInt
+ globals()['NEI'] = NEI
+ NI5 = NamedInt('test', 5)
+ self.assertEqual(NI5, 5)
+ test_pickle_dump_load(self.assertEqual, NI5, 5)
+ self.assertEqual(NEI.y.value, 2)
+ test_pickle_dump_load(self.assertTrue, NEI.y)
+
+ def test_subclasses_with_reduce_ex(self):
+ class NamedInt(int):
+ __qualname__ = 'NamedInt' # needed for pickle protocol 4
+ def __new__(cls, *args):
+ _args = args
+ if len(args) < 1:
+ raise TypeError("name and value must be specified")
+ name, args = args[0], args[1:]
+ self = int.__new__(cls, *args)
+ self._intname = name
+ self._args = _args
+ return self
+ def __reduce_ex__(self, proto):
+ return self.__class__, self._args
+ @property
+ def __name__(self):
+ return self._intname
+ def __repr__(self):
+ # repr() is updated to include the name and type info
+ return "%s(%r, %s)" % (type(self).__name__,
+ self.__name__,
+ int.__repr__(self))
+ def __str__(self):
+ # str() is unchanged, even if it relies on the repr() fallback
+ base = int
+ base_str = base.__str__
+ if base_str.__objclass__ is object:
+ return base.__repr__(self)
+ return base_str(self)
+ # for simplicity, we only define one operator that
+ # propagates expressions
+ def __add__(self, other):
+ temp = int(self) + int( other)
+ if isinstance(self, NamedInt) and isinstance(other, NamedInt):
+ return NamedInt(
+ '(%s + %s)' % (self.__name__, other.__name__),
+ temp )
+ else:
+ return temp
+
+ class NEI(NamedInt, Enum):
+ __qualname__ = 'NEI' # needed for pickle protocol 4
+ x = ('the-x', 1)
+ y = ('the-y', 2)
+
+
+ self.assertTrue(NEI.__new__ is Enum.__new__)
+ self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
+ globals()['NamedInt'] = NamedInt
+ globals()['NEI'] = NEI
+ NI5 = NamedInt('test', 5)
+ self.assertEqual(NI5, 5)
+ test_pickle_dump_load(self.assertEqual, NI5, 5)
+ self.assertEqual(NEI.y.value, 2)
+ test_pickle_dump_load(self.assertTrue, NEI.y)
+
+ def test_subclasses_without_direct_pickle_support(self):
+ class NamedInt(int):
+ __qualname__ = 'NamedInt'
+ def __new__(cls, *args):
+ _args = args
+ name, args = args[0], args[1:]
+ if len(args) == 0:
+ raise TypeError("name and value must be specified")
+ self = int.__new__(cls, *args)
+ self._intname = name
+ self._args = _args
+ return self
+ @property
+ def __name__(self):
+ return self._intname
+ def __repr__(self):
+ # repr() is updated to include the name and type info
+ return "%s(%r, %s)" % (type(self).__name__,
+ self.__name__,
+ int.__repr__(self))
+ def __str__(self):
+ # str() is unchanged, even if it relies on the repr() fallback
+ base = int
+ base_str = base.__str__
+ if base_str.__objclass__ is object:
+ return base.__repr__(self)
+ return base_str(self)
+ # for simplicity, we only define one operator that
+ # propagates expressions
+ def __add__(self, other):
+ temp = int(self) + int( other)
+ if isinstance(self, NamedInt) and isinstance(other, NamedInt):
+ return NamedInt(
+ '(%s + %s)' % (self.__name__, other.__name__),
+ temp )
+ else:
+ return temp
+
+ class NEI(NamedInt, Enum):
+ __qualname__ = 'NEI'
+ x = ('the-x', 1)
+ y = ('the-y', 2)
+
+ self.assertTrue(NEI.__new__ is Enum.__new__)
+ self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
+ globals()['NamedInt'] = NamedInt
+ globals()['NEI'] = NEI
+ NI5 = NamedInt('test', 5)
+ self.assertEqual(NI5, 5)
+ self.assertEqual(NEI.y.value, 2)
+ test_pickle_exception(self.assertRaises, TypeError, NEI.x)
+ test_pickle_exception(self.assertRaises, PicklingError, NEI)
+
+ def test_subclasses_without_direct_pickle_support_using_name(self):
+ class NamedInt(int):
+ __qualname__ = 'NamedInt'
+ def __new__(cls, *args):
+ _args = args
+ name, args = args[0], args[1:]
+ if len(args) == 0:
+ raise TypeError("name and value must be specified")
+ self = int.__new__(cls, *args)
+ self._intname = name
+ self._args = _args
+ return self
+ @property
+ def __name__(self):
+ return self._intname
+ def __repr__(self):
+ # repr() is updated to include the name and type info
+ return "%s(%r, %s)" % (type(self).__name__,
+ self.__name__,
+ int.__repr__(self))
+ def __str__(self):
+ # str() is unchanged, even if it relies on the repr() fallback
+ base = int
+ base_str = base.__str__
+ if base_str.__objclass__ is object:
+ return base.__repr__(self)
+ return base_str(self)
+ # for simplicity, we only define one operator that
+ # propagates expressions
+ def __add__(self, other):
+ temp = int(self) + int( other)
+ if isinstance(self, NamedInt) and isinstance(other, NamedInt):
+ return NamedInt(
+ '(%s + %s)' % (self.__name__, other.__name__),
+ temp )
+ else:
+ return temp
+
+ class NEI(NamedInt, Enum):
+ __qualname__ = 'NEI'
+ x = ('the-x', 1)
+ y = ('the-y', 2)
+ def __reduce_ex__(self, proto):
+ return getattr, (self.__class__, self._name_)
+
+ self.assertTrue(NEI.__new__ is Enum.__new__)
+ self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
+ globals()['NamedInt'] = NamedInt
+ globals()['NEI'] = NEI
+ NI5 = NamedInt('test', 5)
+ self.assertEqual(NI5, 5)
+ self.assertEqual(NEI.y.value, 2)
+ test_pickle_dump_load(self.assertTrue, NEI.y)
+ test_pickle_dump_load(self.assertTrue, NEI)
+
+ def test_tuple_subclass(self):
+ class SomeTuple(tuple, Enum):
+ __qualname__ = 'SomeTuple'
+ first = (1, 'for the money')
+ second = (2, 'for the show')
+ third = (3, 'for the music')
+ self.assertTrue(type(SomeTuple.first) is SomeTuple)
+ self.assertTrue(isinstance(SomeTuple.second, tuple))
+ self.assertEqual(SomeTuple.third, (3, 'for the music'))
+ globals()['SomeTuple'] = SomeTuple
+ test_pickle_dump_load(self.assertTrue, SomeTuple.first)
+
+ def test_duplicate_values_give_unique_enum_items(self):
+ class AutoNumber(Enum):
+ __order__ = 'enum_m enum_d enum_y'
+ enum_m = ()
+ enum_d = ()
+ enum_y = ()
+ def __new__(cls):
+ value = len(cls.__members__) + 1
+ obj = object.__new__(cls)
+ obj._value_ = value
+ return obj
+ def __int__(self):
+ return int(self._value_)
+ self.assertEqual(int(AutoNumber.enum_d), 2)
+ self.assertEqual(AutoNumber.enum_y.value, 3)
+ self.assertTrue(AutoNumber(1) is AutoNumber.enum_m)
+ self.assertEqual(
+ list(AutoNumber),
+ [AutoNumber.enum_m, AutoNumber.enum_d, AutoNumber.enum_y],
+ )
+
+ def test_inherited_new_from_enhanced_enum(self):
+ class AutoNumber2(Enum):
+ def __new__(cls):
+ value = len(cls.__members__) + 1
+ obj = object.__new__(cls)
+ obj._value_ = value
+ return obj
+ def __int__(self):
+ return int(self._value_)
+ class Color(AutoNumber2):
+ _order_ = 'red green blue'
+ red = ()
+ green = ()
+ blue = ()
+ self.assertEqual(len(Color), 3, "wrong number of elements: %d (should be %d)" % (len(Color), 3))
+ self.assertEqual(list(Color), [Color.red, Color.green, Color.blue])
+ if pyver >= 3.0:
+ self.assertEqual(list(map(int, Color)), [1, 2, 3])
+
+ def test_inherited_new_from_mixed_enum(self):
+ class AutoNumber3(IntEnum):
+ def __new__(cls):
+ value = len(cls.__members__) + 1
+ obj = int.__new__(cls, value)
+ obj._value_ = value
+ return obj
+ class Color(AutoNumber3):
+ red = ()
+ green = ()
+ blue = ()
+ self.assertEqual(len(Color), 3, "wrong number of elements: %d (should be %d)" % (len(Color), 3))
+ Color.red
+ Color.green
+ Color.blue
+
+ def test_equality(self):
+ class AlwaysEqual:
+ def __eq__(self, other):
+ return True
+ class OrdinaryEnum(Enum):
+ a = 1
+ self.assertEqual(AlwaysEqual(), OrdinaryEnum.a)
+ self.assertEqual(OrdinaryEnum.a, AlwaysEqual())
+
+ def test_ordered_mixin(self):
+ class OrderedEnum(Enum):
+ def __ge__(self, other):
+ if self.__class__ is other.__class__:
+ return self._value_ >= other._value_
+ return NotImplemented
+ def __gt__(self, other):
+ if self.__class__ is other.__class__:
+ return self._value_ > other._value_
+ return NotImplemented
+ def __le__(self, other):
+ if self.__class__ is other.__class__:
+ return self._value_ <= other._value_
+ return NotImplemented
+ def __lt__(self, other):
+ if self.__class__ is other.__class__:
+ return self._value_ < other._value_
+ return NotImplemented
+ class Grade(OrderedEnum):
+ __order__ = 'A B C D F'
+ A = 5
+ B = 4
+ C = 3
+ D = 2
+ F = 1
+ self.assertEqual(list(Grade), [Grade.A, Grade.B, Grade.C, Grade.D, Grade.F])
+ self.assertTrue(Grade.A > Grade.B)
+ self.assertTrue(Grade.F <= Grade.C)
+ self.assertTrue(Grade.D < Grade.A)
+ self.assertTrue(Grade.B >= Grade.B)
+
+ def test_extending2(self):
+ def bad_extension():
+ class Shade(Enum):
+ def shade(self):
+ print(self.name)
+ class Color(Shade):
+ red = 1
+ green = 2
+ blue = 3
+ class MoreColor(Color):
+ cyan = 4
+ magenta = 5
+ yellow = 6
+ self.assertRaises(TypeError, bad_extension)
+
+ def test_extending3(self):
+ class Shade(Enum):
+ def shade(self):
+ return self.name
+ class Color(Shade):
+ def hex(self):
+ return '%s hexlified!' % self.value
+ class MoreColor(Color):
+ cyan = 4
+ magenta = 5
+ yellow = 6
+ self.assertEqual(MoreColor.magenta.hex(), '5 hexlified!')
+
+ def test_no_duplicates(self):
+ def bad_duplicates():
+ class UniqueEnum(Enum):
+ def __init__(self, *args):
+ cls = self.__class__
+ if any(self.value == e.value for e in cls):
+ a = self.name
+ e = cls(self.value).name
+ raise ValueError(
+ "aliases not allowed in UniqueEnum: %r --> %r"
+ % (a, e)
+ )
+ class Color(UniqueEnum):
+ red = 1
+ green = 2
+ blue = 3
+ class Color(UniqueEnum):
+ red = 1
+ green = 2
+ blue = 3
+ grene = 2
+ self.assertRaises(ValueError, bad_duplicates)
+
+ def test_init(self):
+ class Planet(Enum):
+ MERCURY = (3.303e+23, 2.4397e6)
+ VENUS = (4.869e+24, 6.0518e6)
+ EARTH = (5.976e+24, 6.37814e6)
+ MARS = (6.421e+23, 3.3972e6)
+ JUPITER = (1.9e+27, 7.1492e7)
+ SATURN = (5.688e+26, 6.0268e7)
+ URANUS = (8.686e+25, 2.5559e7)
+ NEPTUNE = (1.024e+26, 2.4746e7)
+ def __init__(self, mass, radius):
+ self.mass = mass # in kilograms
+ self.radius = radius # in meters
+ @property
+ def surface_gravity(self):
+ # universal gravitational constant (m3 kg-1 s-2)
+ G = 6.67300E-11
+ return G * self.mass / (self.radius * self.radius)
+ self.assertEqual(round(Planet.EARTH.surface_gravity, 2), 9.80)
+ self.assertEqual(Planet.EARTH.value, (5.976e+24, 6.37814e6))
+
+ def test_nonhash_value(self):
+ class AutoNumberInAList(Enum):
+ def __new__(cls):
+ value = [len(cls.__members__) + 1]
+ obj = object.__new__(cls)
+ obj._value_ = value
+ return obj
+ class ColorInAList(AutoNumberInAList):
+ _order_ = 'red green blue'
+ red = ()
+ green = ()
+ blue = ()
+ self.assertEqual(list(ColorInAList), [ColorInAList.red, ColorInAList.green, ColorInAList.blue])
+ self.assertEqual(ColorInAList.red.value, [1])
+ self.assertEqual(ColorInAList([1]), ColorInAList.red)
+
+ def test_conflicting_types_resolved_in_new(self):
+ class LabelledIntEnum(int, Enum):
+ def __new__(cls, *args):
+ value, label = args
+ obj = int.__new__(cls, value)
+ obj.label = label
+ obj._value_ = value
+ return obj
+
+ class LabelledList(LabelledIntEnum):
+ unprocessed = (1, "Unprocessed")
+ payment_complete = (2, "Payment Complete")
+
+ self.assertEqual(list(LabelledList), [LabelledList.unprocessed, LabelledList.payment_complete])
+ self.assertEqual(LabelledList.unprocessed, 1)
+ self.assertEqual(LabelledList(1), LabelledList.unprocessed)
+
+ def test_empty_with_functional_api(self):
+ empty = enum.IntEnum('Foo', {})
+ self.assertEqual(len(empty), 0)
+
+
+class TestUnique(unittest.TestCase):
+ """2.4 doesn't allow class decorators, use function syntax."""
+
+ def test_unique_clean(self):
+ class Clean(Enum):
+ one = 1
+ two = 'dos'
+ tres = 4.0
+ unique(Clean)
+ class Cleaner(IntEnum):
+ single = 1
+ double = 2
+ triple = 3
+ unique(Cleaner)
+
+ def test_unique_dirty(self):
+ try:
+ class Dirty(Enum):
+ __order__ = 'one two tres'
+ one = 1
+ two = 'dos'
+ tres = 1
+ unique(Dirty)
+ except ValueError:
+ exc = sys.exc_info()[1]
+ message = exc.args[0]
+ self.assertTrue('tres -> one' in message)
+
+ try:
+ class Dirtier(IntEnum):
+ _order_ = 'single double triple turkey'
+ single = 1
+ double = 1
+ triple = 3
+ turkey = 3
+ unique(Dirtier)
+ except ValueError:
+ exc = sys.exc_info()[1]
+ message = exc.args[0]
+ self.assertTrue('double -> single' in message)
+ self.assertTrue('turkey -> triple' in message)
+
+
+class TestMe(unittest.TestCase):
+
+ pass
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/third_party/python/enum34/setup.cfg b/third_party/python/enum34/setup.cfg
new file mode 100644
index 0000000000..861a9f5542
--- /dev/null
+++ b/third_party/python/enum34/setup.cfg
@@ -0,0 +1,5 @@
+[egg_info]
+tag_build =
+tag_date = 0
+tag_svn_revision = 0
+
diff --git a/third_party/python/enum34/setup.py b/third_party/python/enum34/setup.py
new file mode 100644
index 0000000000..8b28400348
--- /dev/null
+++ b/third_party/python/enum34/setup.py
@@ -0,0 +1,99 @@
+import os
+import sys
+import setuptools
+from distutils.core import setup
+
+
+if sys.version_info[:2] < (2, 7):
+ required = ['ordereddict']
+else:
+ required = []
+
+long_desc = '''\
+enum --- support for enumerations
+========================================
+
+An enumeration is a set of symbolic names (members) bound to unique, constant
+values. Within an enumeration, the members can be compared by identity, and
+the enumeration itself can be iterated over.
+
+ from enum import Enum
+
+ class Fruit(Enum):
+ apple = 1
+ banana = 2
+ orange = 3
+
+ list(Fruit)
+ # [<Fruit.apple: 1>, <Fruit.banana: 2>, <Fruit.orange: 3>]
+
+ len(Fruit)
+ # 3
+
+ Fruit.banana
+ # <Fruit.banana: 2>
+
+ Fruit['banana']
+ # <Fruit.banana: 2>
+
+ Fruit(2)
+ # <Fruit.banana: 2>
+
+ Fruit.banana is Fruit['banana'] is Fruit(2)
+ # True
+
+ Fruit.banana.name
+ # 'banana'
+
+ Fruit.banana.value
+ # 2
+
+Repository and Issue Tracker at https://bitbucket.org/stoneleaf/enum34.
+'''
+
+py2_only = ()
+py3_only = ()
+make = [
+ 'rst2pdf enum/doc/enum.rst --output=enum/doc/enum.pdf',
+ ]
+
+
+data = dict(
+ name='enum34',
+ version='1.1.6',
+ url='https://bitbucket.org/stoneleaf/enum34',
+ packages=['enum'],
+ package_data={
+ 'enum' : [
+ 'LICENSE',
+ 'README',
+ 'doc/enum.rst',
+ 'doc/enum.pdf',
+ 'test.py',
+ ]
+ },
+ license='BSD License',
+ description='Python 3.4 Enum backported to 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, and 2.4',
+ long_description=long_desc,
+ provides=['enum'],
+ install_requires=required,
+ author='Ethan Furman',
+ author_email='ethan@stoneleaf.us',
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: BSD License',
+ 'Programming Language :: Python',
+ 'Topic :: Software Development',
+ 'Programming Language :: Python :: 2.4',
+ 'Programming Language :: Python :: 2.5',
+ 'Programming Language :: Python :: 2.6',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3.3',
+ 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
+ ],
+ )
+
+if __name__ == '__main__':
+ setup(**data)