flufl.enum-4.1/ 0000775 0001750 0001750 00000000000 12606034371 013715 5 ustar barry barry 0000000 0000000 flufl.enum-4.1/MANIFEST.in 0000664 0001750 0001750 00000000131 12476403363 015454 0 ustar barry barry 0000000 0000000 include *.py MANIFEST.in *.ini
global-include *.txt *.rst
exclude .bzrignore
prune build
flufl.enum-4.1/setup.py 0000664 0001750 0001750 00000004211 12606033531 015422 0 ustar barry barry 0000000 0000000 # Copyright (C) 2004-2015 Barry Warsaw
#
# This file is part of flufl.enum.
#
# flufl.enum is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# flufl.enum is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with flufl.enum. If not, see .
#
# Author: Barry Warsaw
from setup_helpers import (
description, get_version, long_description, require_python)
from setuptools import setup, find_packages
require_python(0x20700f0)
__version__ = get_version('flufl/enum/__init__.py')
setup(
name='flufl.enum',
version=__version__,
namespace_packages=['flufl'],
packages=find_packages(),
include_package_data=True,
maintainer='Barry Warsaw',
maintainer_email='barry@python.org',
description=description('README.rst'),
long_description=long_description('README.rst', 'flufl/enum/NEWS.rst'),
license='LGPLv3',
url='http://launchpad.net/flufl.enum',
download_url='https://launchpad.net/flufl.enum/+download',
test_suite='flufl.enum.tests',
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: '
'GNU Lesser General Public License v3 or later (LGPLv3+)',
'Operating System :: POSIX',
'Operating System :: Microsoft :: Windows',
'Operating System :: MacOS :: MacOS X',
'Programming Language :: Python',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Topic :: Software Development :: Libraries',
'Topic :: Software Development :: Libraries :: Python Modules',
]
)
flufl.enum-4.1/setup.cfg 0000664 0001750 0001750 00000000221 12606034371 015531 0 ustar barry barry 0000000 0000000 [build_sphinx]
source_dir = flufl/enum
[upload_docs]
upload_dir = build/sphinx/html
[egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
flufl.enum-4.1/setup_helpers.py 0000664 0001750 0001750 00000012106 12606033630 017146 0 ustar barry barry 0000000 0000000 # Copyright (C) 2009-2015 Barry A. Warsaw
#
# This file is part of setup_helpers.py
#
# setup_helpers.py is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, version 3 of the License.
#
# setup_helpers.py is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with setup_helpers.py. If not, see .
"""setup.py helper functions."""
from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
'description',
'find_doctests',
'get_version',
'long_description',
'require_python',
]
import os
import re
import sys
DEFAULT_VERSION_RE = re.compile(
r'(?P\d+\.\d+(?:\.\d+)?(?:(?:a|b|rc)\d+)?)')
EMPTYSTRING = ''
__version__ = '2.3'
def require_python(minimum):
"""Require at least a minimum Python version.
The version number is expressed in terms of `sys.hexversion`. E.g. to
require a minimum of Python 2.6, use::
>>> require_python(0x206000f0)
:param minimum: Minimum Python version supported.
:type minimum: integer
"""
if sys.hexversion < minimum:
hversion = hex(minimum)[2:]
if len(hversion) % 2 != 0:
hversion = '0' + hversion
split = list(hversion)
parts = []
while split:
parts.append(int(''.join((split.pop(0), split.pop(0))), 16))
major, minor, micro, release = parts
if release == 0xf0:
print('Python {0}.{1}.{2} or better is required'.format(
major, minor, micro))
else:
print('Python {0}.{1}.{2} ({3}) or better is required'.format(
major, minor, micro, hex(release)[2:]))
sys.exit(1)
def get_version(filename, pattern=None):
"""Extract the __version__ from a file without importing it.
While you could get the __version__ by importing the module, the very act
of importing can cause unintended consequences. For example, Distribute's
automatic 2to3 support will break. Instead, this searches the file for a
line that starts with __version__, and extract the version number by
regular expression matching.
By default, two or three dot-separated digits are recognized, but by
passing a pattern parameter, you can recognize just about anything. Use
the `version` group name to specify the match group.
:param filename: The name of the file to search.
:type filename: string
:param pattern: Optional alternative regular expression pattern to use.
:type pattern: string
:return: The version that was extracted.
:rtype: string
"""
if pattern is None:
cre = DEFAULT_VERSION_RE
else:
cre = re.compile(pattern)
with open(filename) as fp:
for line in fp:
if line.startswith('__version__'):
mo = cre.search(line)
assert mo, 'No valid __version__ string found'
return mo.group('version')
raise AssertionError('No __version__ assignment found')
def find_doctests(start='.', extension='.rst'):
"""Find separate-file doctests in the package.
This is useful for Distribute's automatic 2to3 conversion support. The
`setup()` keyword argument `convert_2to3_doctests` requires file names,
which may be difficult to track automatically as you add new doctests.
:param start: Directory to start searching in (default is cwd)
:type start: string
:param extension: Doctest file extension (default is .txt)
:type extension: string
:return: The doctest files found.
:rtype: list
"""
doctests = []
for dirpath, dirnames, filenames in os.walk(start):
doctests.extend(os.path.join(dirpath, filename)
for filename in filenames
if filename.endswith(extension))
return doctests
def long_description(*filenames):
"""Provide a long description."""
res = ['']
for filename in filenames:
with open(filename) as fp:
for line in fp:
res.append(' ' + line)
res.append('')
res.append('\n')
return EMPTYSTRING.join(res)
def description(filename):
"""Provide a short description."""
# This ends up in the Summary header for PKG-INFO and it should be a
# one-liner. It will get rendered on the package page just below the
# package version header but above the long_description, which ironically
# gets stuff into the Description header. It should not include reST, so
# pick out the first single line after the double header.
with open(filename) as fp:
for lineno, line in enumerate(fp):
if lineno < 3:
continue
line = line.strip()
if len(line) > 0:
return line
flufl.enum-4.1/flufl/ 0000775 0001750 0001750 00000000000 12606034371 015025 5 ustar barry barry 0000000 0000000 flufl.enum-4.1/flufl/enum/ 0000775 0001750 0001750 00000000000 12606034371 015771 5 ustar barry barry 0000000 0000000 flufl.enum-4.1/flufl/enum/docs/ 0000775 0001750 0001750 00000000000 12606034371 016721 5 ustar barry barry 0000000 0000000 flufl.enum-4.1/flufl/enum/docs/using.rst 0000664 0001750 0001750 00000034474 12476403363 020622 0 ustar barry barry 0000000 0000000 ============================
Using the flufl.enum library
============================
Author: `Barry Warsaw`_
The ``flufl.enum`` package provides an enumeration data type for Python. This
package was the inspiration for `PEP 435`_. ``flufl.enum`` provides similar
functionality compatible with versions of Python from Python 2.7, 3.2, 3.3,
and beyond.
An enumeration is a set of symbolic names bound to unique, constant values,
called *enumeration items*. Within an enumeration, the items can be compared
by identity, and the enumeration itself can be iterated over. The underlying
values can be retrieved from the enumeration items. An integer based variant
is provided which allows items to be used as slices, to interoperate with
C-based APIs, and for logical operations.
Motivation
==========
[Lifted from `PEP 354`_ - the original rejected enumeration PEP]
The properties of an enumeration are useful for defining an immutable, related
set of constant values that have a defined sequence but no inherent semantic
meaning. Classic examples are days of the week (Sunday through Saturday) and
school assessment grades ('A' through 'D', and 'F'). Other examples include
error status values and states within a defined process.
It is possible to simply define a sequence of values of some other basic type,
such as ``int`` or ``str``, to represent discrete arbitrary values. However,
an enumeration ensures that such values are distinct from any others, and that
operations without meaning ("Wednesday times two") are not defined for these
values.
Creating an Enumeration
=======================
Class syntax
------------
Enumerations can be created using the class syntax, which makes them easy to
read and write. Every enumeration item must have a unique value and the only
restriction on their names is that they must be valid Python identifiers. To
define an enumeration, derive from the ``Enum`` class and add attributes with
assignment to their values. Values may not be duplicated.
::
>>> from flufl.enum import Enum
>>> class Colors(Enum):
... red = 1
... green = 2
... blue = 3
Enumeration items have nice, human readable string representations.
>>> print(Colors.red)
Colors.red
The ``reprs`` have additional detail.
>>> print(repr(Colors.red))
Integer Enumerations
--------------------
A special subclass of ``Enum`` can be used when the enumeration items need to
act like integers. In fact, the items in this ``IntEnum`` class *are*
integers and can be used any place an integer needs to be used, including when
interfacing with C APIs.
::
>>> from flufl.enum import IntEnum
>>> class Animals(IntEnum):
... ant = 1
... bee = 2
... cat = 3
These enumeration items can be converted to integers.
>>> int(Animals.bee)
2
These enumeration items can also be used as slice indexes.
>>> list(range(10)[Animals.ant:Animals.cat])
[1, 2]
Convenience API
---------------
For convenience, you can create an enumeration by calling the ``Enum`` class.
The first argument is the name of the new enumeration, and the second is
provides the enumeration items. There are several ways to specify the items
-- see the section `Functional API`_ for details -- but the easiest way is to
provide a string of space separated attribute names. The values for these
items are auto-assigned integers starting from 1.
>>> Rush = Enum('Rush', 'geddy alex neil')
The ``str`` and ``repr`` provide details.
>>> print(Rush.geddy)
Rush.geddy
>>> print(repr(Rush.geddy))
See the section on the `Functional API`_ for more options and information.
Values
------
Enumeration items can have any value you choose, but typically they will be
integer or string values, and it is recommended that all the values be of the
same type, although this is not enforced.
::
>>> class Rush(Enum):
... geddy = 'bass'
... alex = 'guitar'
... neil = 'drums'
>>> print(repr(Rush.alex))
Inspecting Enumerations
=======================
``dir()`` returns the enumeration item names.
>>> for member in sorted(dir(Colors)):
... print(member)
blue
green
red
The str and repr of the enumeration class also provides useful information.
The items are always sorted by attribute name.
>>> print(Colors)
>>> print(repr(Colors))
You can get the enumeration class object from an enumeration item.
>>> cls = Colors.red.enum
>>> print(cls.__name__)
Colors
Enumerations also have a property that contains just their item name.
>>> print(Colors.red.name)
red
>>> print(Colors.green.name)
green
>>> print(Colors.blue.name)
blue
The underlying item value can also be retrieved via the ``.value`` attribute.
>>> print(Rush.geddy.value)
bass
Integer enumerations can also be explicitly convert to their integer value
using the ``int()`` built-in.
>>> int(Animals.ant)
1
>>> int(Animals.bee)
2
>>> int(Animals.cat)
3
Comparison
==========
Enumeration items are compared by identity.
>>> Colors.red is Colors.red
True
>>> Colors.blue is Colors.blue
True
>>> Colors.red is not Colors.blue
True
>>> Colors.blue is Colors.red
False
Standard Enumerations
---------------------
The standard ``Enum`` class does not allow comparisons against the integer
equivalent values, and if you define an enumeration with similar item
names and integer values, they will not be identical.
>>> class OtherColors(Enum):
... red = 1
... blue = 2
... yellow = 3
>>> Colors.red is OtherColors.red
False
>>> Colors.blue is not OtherColors.blue
True
These enumeration items are not equal, nor do they hash equally.
>>> Colors.red == OtherColors.red
False
>>> len(set((Colors.red, OtherColors.red)))
2
Ordered comparisons between enumeration items are *not* supported. The base
enumeration values are not integers!
>>> Colors.red < Colors.blue
Traceback (most recent call last):
...
TypeError: unorderable types: EnumValue() < EnumValue()
>>> Colors.red <= Colors.blue
Traceback (most recent call last):
...
TypeError: unorderable types: EnumValue() <= EnumValue()
>>> Colors.blue > Colors.green
Traceback (most recent call last):
...
TypeError: unorderable types: EnumValue() > EnumValue()
>>> Colors.blue >= Colors.green
Traceback (most recent call last):
...
TypeError: unorderable types: EnumValue() >= EnumValue()
>>> Colors.red < 3
Traceback (most recent call last):
...
TypeError: unorderable types: EnumValue() < int()
Equality comparisons are defined though.
>>> Colors.blue == Colors.blue
True
>>> Colors.green != Colors.blue
True
While equality comparisons are allowed, comparisons against non-enumeration
items will always compare not equal.
>>> Colors.green == 2
False
>>> Colors.blue == 3
False
>>> Colors.green != 3
True
>>> Colors.green == 'green'
False
Integer enumerations
--------------------
With the ``IntEnum`` class though, enumeration items *are* integers, so all
the ordered comparisons work as expected.
>>> Animals.ant < Animals.bee
True
>>> Animals.cat > Animals.ant
True
Comparisons against other numbers also work as expected.
>>> Animals.ant <= 1.0
True
>>> Animals.bee == 2
True
You can even compare integer enumeration items against other unrelated integer
enumeration items, since the comparisons use the standard integer operators.
::
>>> class Toppings(IntEnum):
... anchovies = 1
... black_olives = 2
... cheese = 4
... dried_tomatoes = 8
... eggplant = 16
>>> Toppings.black_olives == Animals.bee
True
Conversions
===========
You can convert back to the enumeration item by using the ``Enum`` class's
``getitem`` syntax, passing in the value for the item you want.
>>> Colors[2]
>>> Rush['bass']
>>> Colors[1] is Colors.red
True
If instead you have the enumeration name (i.e. the attribute name), just use
Python's normal ``getattr()`` function.
>>> getattr(Colors, 'red')
>>> getattr(Rush, Rush.alex.name)
>>> getattr(Colors, 'blue') is Colors.blue
True
Iteration
=========
The ``Enum`` class support iteration. Items are returned in order, sorted by
their attribute name.
>>> from operator import attrgetter
>>> by_value = attrgetter('value')
>>> [v.name for v in sorted(Colors, key=by_value)]
['red', 'green', 'blue']
>>> [v.value for v in sorted(Colors, key=by_value)]
[1, 2, 3]
>>> [v.name for v in sorted(Rush, key=by_value)]
['geddy', 'neil', 'alex']
>>> for v in sorted(Rush, key=by_value):
... print(v.value)
bass
drums
guitar
Iteration over ``IntEnum`` is sorted in the order of the enumeration item
values.
::
>>> class Toppings(IntEnum):
... anchovies = 4
... black_olives = 8
... cheese = 2
... dried_tomatoes = 16
... eggplant = 1
>>> for value in Toppings:
... print(value.name, '=', value.value)
eggplant = 1
cheese = 2
anchovies = 4
black_olives = 8
dried_tomatoes = 16
Enumeration items can be used in dictionaries and sets.
>>> from operator import attrgetter
>>> getvalue = attrgetter('value')
>>> apples = {}
>>> apples[Colors.red] = 'red delicious'
>>> apples[Colors.green] = 'granny smith'
>>> for color in sorted(apples, key=getvalue):
... print(color.name, '->', apples[color])
red -> red delicious
green -> granny smith
Extending an enumeration through subclassing
============================================
You can extend previously defined enumerations by subclassing. Just as
before, items cannot be duplicated in either the base class or subclass.
>>> class MoreColors(Colors):
... pink = 4
... cyan = 5
When extended in this way, the base enumeration's items are identical to the
same named items in the derived class.
>>> Colors.red is MoreColors.red
True
>>> Colors.blue is MoreColors.blue
True
Pickling
========
Enumerations created with the class syntax can also be pickled and unpickled:
>>> from flufl.enum.tests.fruit import Fruit
>>> from pickle import dumps, loads
>>> Fruit.tomato is loads(dumps(Fruit.tomato))
True
Functional API
==============
As described above, you can create enumerations functionally by calling
``Enum`` or ``IntEnum``.
The first argument is always the name of the new enumeration. The second
argument describes the enumeration item names and values. As mentioned
previously, the easiest way to create new enumerations is to provide a single
string with space-separated attribute names. In this case, the values are
auto-assigned integers starting from 1.
>>> Enum('Animals', 'ant bee cat dog')
The second argument can also be a sequence of strings. In this case too, the
values are auto-assigned integers starting from 1.
>>> Enum('People', ('anne', 'bart', 'cate', 'dave'))
The items can also be specified by using a sequence of 2-tuples, where the
first item is the enumeration item name and the second is the value to use.
If 2-tuples are given, all items must be 2-tuples.
>>> def enumiter():
... start = 1
... while True:
... yield start
... start <<= 1
>>> Enum('Flags', zip(list('abcdefg'), enumiter()))
You can also provide the enumeration items as a dictionary mapping names to
values. Remember that the ``repr`` is sorted by attribute name.
>>> bassists = dict(geddy='rush', chris='yes', flea='rhcp', jack='cream')
>>> Enum('Bassists', bassists)
If you want to create an ``IntEnum`` where the values are integer subclasses,
call that class instead. This has the same signature as calling ``Enum`` but
the items of the returned enumeration are int subclasses.
>>> Numbers = IntEnum('Numbers', 'one two three four'.split())
>>> Numbers.three == 3
True
Customization protocol
======================
You can define your own enumeration value types by using the
``__value_factory__`` protocol. This is how the ``IntEnum`` type is
defined. As an example, let's say you want to define a new type of
enumeration where the values were subclasses of ``str``. First, define your
enumeration value subclass.
>>> from flufl.enum import EnumValue
>>> class StrEnumValue(str, EnumValue):
... def __new__(cls, enum, value, attr):
... return super(StrEnumValue, cls).__new__(cls, value)
And then define your enumeration class. You must set the class attribute
``__value_factory__`` to the class of the values you want to create.
>>> class StrEnum(Enum):
... __value_factory__ = StrEnumValue
Now, when you define your enumerations, the values will be ``str`` subclasses.
::
>>> class Noises(StrEnum):
... dog = 'bark'
... cat = 'meow'
... cow = 'moo'
>>> isinstance(Noises.cow, str)
True
Acknowledgments
===============
The ``flufl.enum`` implementation is based on an example by Jeremy Hylton. It
has been modified and extended by Barry Warsaw for use in the `GNU Mailman`_
project. Ben Finney is the author of the earlier enumeration PEP 354. Eli
Bendersky is the co-author of PEP 435. Numerous people on the `python-ideas`_
and `python-dev`_ mailing lists have provided valuable feedback.
.. _`PEP 435`: http://www.python.org/dev/peps/pep-0435/
.. _`Python 3.4`: http://www.python.org/dev/peps/pep-0429/
.. _`PEP 354`: http://www.python.org/dev/peps/pep-0354/
.. _enum: http://cheeseshop.python.org/pypi/enum/
.. _`GNU Mailman`: http://www.list.org
.. _`python-ideas`: http://mail.python.org/mailman/listinfo/python-ideas
.. _`python-dev`: http://mail.python.org/mailman/listinfo/python-dev
.. _`Barry Warsaw`: http://barry.warsaw.us
flufl.enum-4.1/flufl/enum/docs/__init__.py 0000664 0001750 0001750 00000000000 12476403363 021026 0 ustar barry barry 0000000 0000000 flufl.enum-4.1/flufl/enum/NEWS.rst 0000664 0001750 0001750 00000011646 12606034022 017300 0 ustar barry barry 0000000 0000000 ===================
NEWS for flufl.enum
===================
4.1 (2015-10-09)
================
* Fix the regexp that matches identifiers in the functional API.
(LP: #1167052)
* Deprecate using getitem syntax for accessing enum values by attribute
name. Use ``getattr(Enum, name)`` instead. (LP: #1167091)
* Duplicate enum values error now provides information on the attribute names
that produced the conflict. Given by Eli Bendersky.
* The documentation now makes it clear that iteration sort order is not
guaranteed for ``Enum`` but *is* guaranteed for ``IntEnum``.
* Comparison operators now return ``NotImplemented`` which cause their use to
raise ``TypeError`` instead of ``NotImplementedError``. This is for
consistency with Python 3. In Python 2, we raise the ``TypeError``
explicitly.
* ``repr(Enum)`` now sorts in attribute name order, as does iteration over
``Enum``. Iteration over ``IntEnum`` is sorted by the enumeration item
values (which must be integers).
* ``Enum.__getattr__()`` and special treatment for ``__members__`` is
removed. A ``__dir__()`` is provided to limit ``dir(Enum)`` to just the
enumeration item names.
* As per BDFL request, document the ``__value_factory__`` API.
* Add support for Python 3.5 and drop support for Python 2.6.
4.0.1 (2014-06-11)
==================
* Include MANIFEST.in and tox.ini in the sdist tarball, otherwise the Debian
package won't built correctly.
* Drop use of distribute.
* Narrow tox supported environments.
* Bump copyright years.
4.0 (2013-04-05)
================
* Fix documentation bugs. (LP: #1026403, LP: #1132830)
* Deprecate ``EnumValue.__int__()``; use ``IntEnumValue`` (via ``IntEnum``)
instead.
* Add ``IntEnum`` class which returns int-subclass enum values. (LP: #1132976)
- Add ``__index__()`` method to support slicing. (LP: #1132972)
- Add non-deprecated ``__int__()`` method.
* Deprecate ``make()``; use ``Enum()`` instead.
- Call ``IntEnum()`` to create integer valued enums. (LP: #1162375)
- Accept a space-separate string of enum values which are auto-split.
- Accept a dictionary of enumeration name/value pairs.
* Add ``.value`` attribute to enum values. (LP: #1132859)
* For ``__getitem__()`` and ``__call__()``, fall back to using the ``.value``
attribute if the argument has one. (LP: #1124596)
* Previously deprecated APIs ``EnumValue.enumclass``, ``EnumValue.enumname``,
and ``enum.make_enum()`` are removed. (LP: #1132951)
* Small change to the ``repr`` of enum values; they now say "value=" instead
of "int=".
* Multiple enum values now raise a `ValueError` instead of a `TypeError`.
3.3.2 (2012-04-19)
==================
* Add classifiers to setup.py and make the long description more compatible
with the Cheeseshop.
* Other changes to make the Cheeseshop page look nicer. (LP: #680136)
* setup_helper.py version 2.1.
3.3.1 (2012-01-19)
==================
* Fix Python 3 compatibility with Sphinx's conf.py ($python setup.py install).
3.3 (2012-01-19)
================
* Remove the dependency on 2to3 for Python 3 support; support Python 3
directly with a single code base.
* flufl.enum.make_enum() is deprecated in favor of flufl.enum.make() which
provides a better API. (LP: #839529)
* Updated to distribute 0.6.19.
* Moved all documentation to .rst suffix.
* Make test_deprecations() compatible with Python 3 and Python 2.
* Removed markup for pylint.
* Improve documentation to illustrate that enum values with similar names and
integer representations still do not hash equally. (Found by Jeroen
Vermeulen).
3.2 (2011-08-19)
================
* make_enum() accepts an optional `iterable` argument to provide the values
for the enums.
* The .enumclass and .enumname attributes are deprecated. Use .enum and
.name instead, respectively.
* Improve the documentation regarding ordered comparisons and equality
tests. (LP: #794853)
* make_enum() now enforces the use of valid Python identifiers. (LP: #803570)
3.1 (2011-03-01)
================
* New convenience function `make_enum()`. (Contributed by Michael Foord)
* Fix `from flufl.enum import *`.
* Enums created with the class syntax can be pickled and unpickled.
(Suggestion and basic implementation idea by Phillip Eby).
3.0.1 (2010-06-07)
==================
* Fixed typo which caused the package to break.
3.0 (2010-04-24)
================
* Package renamed to flufl.enum.
2.0.2 (2010-01-29)
==================
* Fixed some test failures when running under 2to3.
2.0.1 (2010-01-08)
==================
* Fix the manifest and clarify license.
2.0 (2010-01-07)
================
* Use Sphinx to build the documentation.
* Updates to better package Debian/Ubuntu.
* Use distribute_setup instead of ez_setup.
* Rename pep-xxxx.txt; this won't be submitted as a PEP.
* Remove dependencies on nose and setuptools_bzr
* Support Python 3 via 2to3.
Earlier
=======
Try `bzr log lp:flufl.enum` for details.
flufl.enum-4.1/flufl/enum/__init__.py 0000664 0001750 0001750 00000001755 12606033543 020112 0 ustar barry barry 0000000 0000000 # Copyright (C) 2004-2015 Barry Warsaw
#
# This file is part of flufl.enum
#
# flufl.enum is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# flufl.enum is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with flufl.enum. If not, see .
#
# Author: Barry Warsaw
"""Package init."""
from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
'Enum',
'EnumValue',
'IntEnum',
'__version__',
'make',
]
__version__ = '4.1'
from ._enum import Enum, EnumValue, IntEnum, make
flufl.enum-4.1/flufl/enum/conf.py 0000664 0001750 0001750 00000015331 12476403363 017301 0 ustar barry barry 0000000 0000000 # -*- coding: utf-8 -*-
#
# flufl.enum documentation build configuration file, created by
# sphinx-quickstart on Thu Jan 7 18:41:30 2010.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
from __future__ import print_function
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.append(os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['../../_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'README'
# General information about the project.
project = 'flufl.enum'
copyright = '2004-2015, Barry A. Warsaw'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
from flufl.enum import __version__
# The short X.Y version.
version = __version__
# The full version, including alpha/beta/rc tags.
release = __version__
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
#unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = ['_build', 'build', 'flufl.enum.egg-info', 'distribute-0.6.10']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# " v documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['../../_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_use_modindex = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'fluflenumdoc'
# -- Options for LaTeX output --------------------------------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('README.rst', 'fluflenum.tex', 'flufl.enum Documentation',
'Barry A. Warsaw', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True
import errno
def index_html():
cwd = os.getcwd()
try:
os.chdir('build/sphinx/html')
try:
os.symlink('README.html', 'index.html')
except OSError as error:
if error.errno != errno.EEXIST:
raise
print('index.html -> README.html')
finally:
os.chdir(cwd)
import atexit
atexit.register(index_html)
flufl.enum-4.1/flufl/enum/_enum.py 0000664 0001750 0001750 00000030342 12476403363 017456 0 ustar barry barry 0000000 0000000 # Copyright (C) 2004-2015 Barry Warsaw
#
# This file is part of flufl.enum
#
# flufl.enum is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# flufl.enum is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with flufl.enum. If not, see .
#
# Author: Barry Warsaw
"""Python enumerations."""
from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
'Enum',
'EnumValue',
'IntEnum',
'make',
]
import re
import sys
import warnings
from operator import itemgetter
COMMASPACE = ', '
SPACE = ' '
IDENTIFIER_RE = r'^[a-zA-Z_][a-zA-Z0-9_]*$'
class EnumMetaclass(type):
"""Meta class for Enums."""
def __init__(cls, name, bases, attributes):
"""Create an Enum class.
:param cls: The class being defined.
:param name: The name of the class.
:param bases: The class's base classes.
:param attributes: The class attributes.
"""
super(EnumMetaclass, cls).__init__(name, bases, attributes)
# Store EnumValues here for easy access.
cls._enums = {}
# Figure out if this class has a custom factory for building enum
# values. The default is EnumValue, but the class (or one of its
# bases) can declare a custom one with a special attribute.
factory = attributes.get('__value_factory__')
# Figure out the set of enum values on the base classes, to ensure
# that we don't get any duplicate values. At the same time, check the
# base classes for the special attribute.
for basecls in cls.__mro__:
if hasattr(basecls, '_enums'):
cls._enums.update(basecls._enums)
if hasattr(basecls, '__value_factory__'):
basecls_factory = basecls.__value_factory__
if factory is not None and basecls_factory != factory:
raise TypeError(
'Conflicting enum factory in base class: {}'.format(
basecls_factory))
factory = basecls_factory
# Set the factory default if necessary.
if factory is None:
factory = EnumValue
# For each class attribute, create an enum value and store that back
# on the class instead of the original value. Skip Python reserved
# names. Also add a mapping from the original value to the enum value
# instance so we can return the same object on conversion.
for attr in attributes:
if not (attr.startswith('__') and attr.endswith('__')):
value = attributes[attr]
enumval = factory(cls, value, attr)
if value in cls._enums:
other = cls._enums[value]
# Without this, sort order is undefined and causes
# unpredictable results for the test suite.
first = (attr if attr < other else other)
second = (other if attr < other else attr)
raise ValueError("Conflicting enum value '{}' "
"for names: '{}' and '{}'".format(
value, first, second))
# Store as an attribute on the class, and save the attr name.
setattr(cls, attr, enumval)
cls._enums[value] = attr
def __dir__(cls):
# For Python 3.2, we must explicitly convert the dict view to a list.
# Order is not guaranteed, so don't sort it.
return list(cls._enums.values())
def __repr__(cls):
# We want predictable reprs. Because base Enum items can have any
# value, the only reliable way to sort the keys for the repr is based
# on the attribute name, which must be Python identifiers.
return '<{0} {{{1}}}>'.format(cls.__name__, COMMASPACE.join(
'{0}: {1}'.format(value, key)
for key, value in sorted(cls._enums.items(), key=itemgetter(1))))
def __iter__(cls):
for value in sorted(cls._enums.values()):
yield getattr(cls, value)
def __getitem__(cls, item):
attr = cls._enums.get(item)
if attr is None:
# If this is an EnumValue, try it's .value attribute.
if hasattr(item, 'value'):
attr = cls._enums.get(item.value)
if attr is None:
# It wasn't value-ish -- try the attribute name. This was
# deprecated in LP: #1167091.
try:
warnings.warn('Enum[item_name] is deprecated; '
'use getattr(Enum, item_name)',
DeprecationWarning, 2)
return getattr(cls, item)
except (AttributeError, TypeError):
raise ValueError(item)
return getattr(cls, attr)
def __call__(cls, *args):
# One-argument calling is a deprecated synonym for getitem.
if len(args) == 1:
warnings.warn('MyEnum(arg) is deprecated; use MyEnum[arg]',
DeprecationWarning, 2)
return cls.__getitem__(args[0])
name, source = args
return _make(cls, name, source)
class EnumValue:
"""Class to represent an enumeration value.
EnumValue('Color', 'red', 12) prints as 'Color.red' and can be converted
to the integer 12.
"""
def __init__(self, enum, value, name):
self._enum = enum
self._value = value
self._name = name
def __repr__(self):
return ''.format(
self._enum.__name__, self._name, self._value)
def __str__(self):
return '{0}.{1}'.format(self._enum.__name__, self._name)
def __int__(self):
warnings.warn('int() is deprecated; use IntEnums',
DeprecationWarning, 2)
return self._value
def __reduce__(self):
return getattr, (self._enum, self._name)
@property
def enum(self):
"""Return the class associated with the enum value."""
return self._enum
@property
def name(self):
"""Return the name of the enum value."""
return self._name
@property
def value(self):
"""Return the underlying value."""
return self._value
# Support only comparison by identity and equality. Ordered comparisions
# are not supported.
def __eq__(self, other):
return self is other
def __ne__(self, other):
return self is not other
def __lt__(self, other):
# In Python 3, returning NotImplemented from an ordered comparison
# operator will cause a TypeError to be raised. This doesn't work in
# Python 2 though, and you'd end up with working, but incorrect,
# ordered comparisons. In Python 2 we raise the TypeError explicitly.
if sys.version_info[0] < 3:
raise TypeError(
'unorderable types: {}() < {}()'.format(
self.__class__.__name__, other.__class__.__name__))
return NotImplemented
def __gt__(self, other):
if sys.version_info[0] < 3:
raise TypeError(
'unorderable types: {}() > {}()'.format(
self.__class__.__name__, other.__class__.__name__))
return NotImplemented
def __le__(self, other):
if sys.version_info[0] < 3:
raise TypeError(
'unorderable types: {}() <= {}()'.format(
self.__class__.__name__, other.__class__.__name__))
return NotImplemented
def __ge__(self, other):
if sys.version_info[0] < 3:
raise TypeError(
'unorderable types: {}() >= {}()'.format(
self.__class__.__name__, other.__class__.__name__))
return NotImplemented
__hash__ = object.__hash__
# Define the Enum class using metaclass syntax compatible with both Python 2
# and Python 3.
Enum = EnumMetaclass(str('Enum'), (), {
'__doc__': 'The public API Enum class.',
})
class IntEnumValue(int, EnumValue):
"""An EnumValue that is also an integer."""
def __new__(cls, enum, value, attr):
return super(IntEnumValue, cls).__new__(cls, value)
__repr__ = EnumValue.__repr__
__str__ = EnumValue.__str__
# For Python 2 (Python 3 doesn't need this to work).
__eq__ = int.__eq__
__ne__ = int.__ne__
__le__ = int.__le__
__lt__ = int.__lt__
__gt__ = int.__gt__
__ge__ = int.__ge__
# The non-deprecated version of this method.
def __int__(self):
return self._value
# For slices and index().
__index__ = __int__
class IntEnumMetaclass(EnumMetaclass):
# Define an iteration over the integer values instead of the attribute
# names.
def __iter__(cls):
for key in sorted(cls._enums):
yield getattr(cls, cls._enums[key])
IntEnum = IntEnumMetaclass(str('IntEnum'), (Enum,), {
'__doc__': 'A specialized enumeration with values that are also integers.',
'__value_factory__': IntEnumValue,
})
if str is bytes:
# Python 2
STRING_TYPE = basestring
else:
# Python 3
STRING_TYPE = str
def _swap(sequence):
for key, value in sequence:
yield value, key
def _make(enum_class, name, source):
"""The common implementation for `Enum()` and `IntEnum()`."""
namespace = {}
illegals = []
have_strings = None
# Auto-splitting of strings.
if isinstance(source, STRING_TYPE):
source = source.split()
# Look for dict-like arguments. Specifically, it must have a callable
# .items() attribute. Because of the way enumerate() works, here we have
# to swap the key/values.
try:
source = _swap(source.items())
except (TypeError, AttributeError):
source = enumerate(source, start=1)
for i, item in source:
if isinstance(item, STRING_TYPE):
if have_strings is None:
have_strings = True
elif not have_strings:
raise ValueError('heterogeneous source')
namespace[item] = i
if re.match(IDENTIFIER_RE, item) is None:
illegals.append(item)
else:
if have_strings is None:
have_strings = False
elif have_strings:
raise ValueError('heterogeneous source')
item_name, item_value = item
namespace[item_name] = item_value
if re.match(IDENTIFIER_RE, item_name) is None:
illegals.append(item_name)
if len(illegals) > 0:
raise ValueError('non-identifiers: {0}'.format(SPACE.join(illegals)))
return EnumMetaclass(str(name), (enum_class,), namespace)
def make(name, source):
"""Return an Enum class from a name and source.
This is a convenience function for defining a new enumeration given an
existing sequence. When an sequence is used, it is iterated over to get
the enumeration value items. The sequence iteration can either return
strings or 2-tuples. When strings are used, values are automatically
assigned starting from 1. When 2-tuples are used, the first item of the
tuple is a string and the second item is the integer value.
`source` must be homogeneous. You cannot mix string-only and 2-tuple
items in the sequence.
:param name: The resulting enum's class name.
:type name: byte string (or ASCII-only unicode string)
:param source: An object giving the enumeration value items.
:type source: A sequence of strings or 2-tuples.
:return: The new enumeration class.
:rtype: instance of `EnumMetaClass`
:raises ValueError: when a heterogeneous source is given, or when
non-identifiers are used as enumeration value names.
"""
warnings.warn('make() is deprecated; use Enum(name, source)',
DeprecationWarning, 2)
return _make(Enum, name, source)
flufl.enum-4.1/flufl/enum/README.rst 0000664 0001750 0001750 00000005140 12527516317 017467 0 ustar barry barry 0000000 0000000 =========================================
flufl.enum - A Python enumeration package
=========================================
This package is called ``flufl.enum``, a Python enumeration package.
The goals of ``flufl.enum`` are to produce simple, specific, concise semantics
in an easy to read and write syntax. ``flufl.enum`` has just enough of the
features needed to make enumerations useful, but without a lot of extra
baggage to weigh them down. This work grew out of the Mailman 3.0 project and
it is the enum package used there. This package was previously called
``munepy``.
**Note: This package is deprecated!** Python 3.4 added an enum package to its
`standard library`_ which is also available as a `third party package`_ on
PyPI for older versions of Python. If you are using `flufl.enum` you should
switch to the standard enum package.
Requirements
============
``flufl.enum`` requires Python 2.7 or newer, and is compatible with Python 3.
Documentation
=============
A `simple guide`_ to using the library is available within this package.
Project details
===============
* Project home: https://gitlab.com/warsaw/flufl.enum
* Report bugs at: https://gitlab.com/warsaw/flufl.enum/issues
* Code hosting: git@gitlab.com:warsaw/flufl.enum.git
* Documentation: http://fluflenum.readthedocs.org/
You can install it with `pip`::
% pip install flufl.enum
You can grab the latest development copy of the code using git. The master
repository is hosted on GitLab. If you have git installed, you can grab
your own branch of the code like this::
$ git clone git@gitlab.com:warsaw/flufl.enum.git
You may contact the author via barry@python.org.
Copyright
=========
Copyright (C) 2004-2015 Barry A. Warsaw
This file is part of flufl.enum.
flufl.enum is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option) any
later version.
flufl.enum is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along
with flufl.enum. If not, see .
Table of Contents
=================
.. toctree::
docs/using.rst
NEWS.rst
.. _`simple guide`: docs/using.html
.. `standard library`: https://docs.python.org/3/library/enum.html
.. `third party package`: https://pypi.python.org/pypi/enum34
flufl.enum-4.1/flufl/enum/tests/ 0000775 0001750 0001750 00000000000 12606034371 017133 5 ustar barry barry 0000000 0000000 flufl.enum-4.1/flufl/enum/tests/fruit.py 0000664 0001750 0001750 00000001724 12476403363 020650 0 ustar barry barry 0000000 0000000 # Copyright (C) 2010-2015 Barry Warsaw
#
# This file is part of flufl.enum
#
# flufl.enum is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# flufl.enum is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with flufl.enum. If not, see .
#
# Author: Barry Warsaw
"""A class for testing pickling."""
from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
'Fruit',
]
from flufl.enum import Enum
class Fruit(Enum):
kiwi = 1
banana = 2
tomato = 3
flufl.enum-4.1/flufl/enum/tests/__init__.py 0000664 0001750 0001750 00000000000 12476403363 021240 0 ustar barry barry 0000000 0000000 flufl.enum-4.1/flufl/enum/tests/test_enum.py 0000664 0001750 0001750 00000032524 12476403363 021524 0 ustar barry barry 0000000 0000000 # Copyright (C) 2011-2015 Barry Warsaw
#
# This file is part of flufl.enum.
#
# flufl.enum is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# flufl.enum is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with flufl.enum. If not, see .
#
# Author: Barry Warsaw
"""Additional package tests."""
from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
'TestBasic',
'TestIntEnum',
]
import warnings
import unittest
from flufl.enum import Enum, IntEnum, make
from itertools import combinations
from operator import attrgetter, index
SPACE = ' '
class TestBasic(unittest.TestCase):
"""Basic functionality tests"""
class Colors(Enum):
red = 1
green = 2
blue = 3
all_colors = ['red', 'green', 'blue']
def test_basic_reprs(self):
self.assertEqual(str(self.Colors.red), 'Colors.red')
self.assertEqual(str(self.Colors.green), 'Colors.green')
self.assertEqual(str(self.Colors.blue), 'Colors.blue')
self.assertEqual(str(self.Colors['red']), 'Colors.red')
self.assertEqual(
repr(self.Colors.red),
'')
def test_string_value(self):
class Rush(Enum):
geddy = 'bass'
alex = 'guitar'
neil = 'drums'
self.assertEqual(
repr(Rush.alex),
'')
def test_factory_single_string(self):
Color = Enum('Color', SPACE.join(self.all_colors))
for c in self.all_colors:
self.assertEqual(str(Color[c]), 'Color.' + c)
def test_enum_dir(self):
# dir() returns the list of enumeration item names.
self.assertEqual(sorted(dir(self.Colors)), sorted(self.all_colors))
def test_enumclass_getitem(self):
self.assertEqual(self.Colors[2], self.Colors.green)
self.assertEqual(self.Colors['red'], self.Colors.red)
self.assertEqual(self.Colors[self.Colors.red], self.Colors.red)
def test_iteration(self):
# Iteration over basic Enums is by attribute name.
A = Enum('A', 'a b c')
self.assertEqual(list(v.name for v in A), ['a', 'b', 'c'])
B = Enum('B', 'c b a')
self.assertEqual(list(v.name for v in B), ['a', 'b', 'c'])
# If iteration sorted over values, this would give a TypeError.
C = Enum('C', dict(a='7', b=7))
self.assertEqual(list(v.name for v in C), ['a', 'b'])
def test_hashing(self):
getvalue = attrgetter('value')
apples = {}
apples[self.Colors.red] = 'red delicious'
apples[self.Colors.green] = 'granny smith'
self.assertEqual(
[(c.name, apples[c]) for c in sorted(apples, key=getvalue)],
[('red', 'red delicious'), ('green', 'granny smith')])
def test_value_enum_attributes(self):
for i, c in enumerate(self.all_colors, 1):
# enum attribute
self.assertEqual(self.Colors[c].enum, self.Colors)
# name attribute
self.assertEqual(self.Colors[c].name, c)
# value attribute
self.assertEqual(self.Colors[c].value, i)
def test_enum_class_name(self):
self.assertEqual(self.Colors.__name__, 'Colors')
def test_comparisons(self):
r, g, b = self.Colors.red, self.Colors.green, self.Colors.blue
for c in r, g, b:
self.assertIs(c, c)
self.assertEqual(c, c)
for first, second in combinations([r, g, b], 2):
self.assertIsNot(first, second)
self.assertNotEqual(first, second)
with self.assertRaises(TypeError):
self.Colors.red < self.Colors.blue
with self.assertRaises(TypeError):
self.Colors.red <= self.Colors.blue
with self.assertRaises(TypeError):
self.Colors.red > self.Colors.green
with self.assertRaises(TypeError):
self.Colors.green >= self.Colors.blue
def test_comparison_with_int(self):
with self.assertRaises(TypeError):
self.Colors.red < 3
with self.assertRaises(TypeError):
self.Colors.red <= 3
with self.assertRaises(TypeError):
self.Colors.blue > 2
with self.assertRaises(TypeError):
self.Colors.green >= 1
self.assertNotEqual(self.Colors.green, 2)
self.assertNotEqual(self.Colors.blue, 3)
self.assertNotEqual(self.Colors.green, 3)
def test_comparison_with_other_enum(self):
class OtherColors(Enum):
red = 1
blue = 2
yellow = 3
self.assertIsNot(OtherColors.red, self.Colors.red)
self.assertNotEqual(OtherColors.red, self.Colors.red)
self.assertNotEqual(hash(OtherColors.red), hash(self.Colors.red))
def test_subclass(self):
class MoreColors(self.Colors):
pink = 4
cyan = 5
self.assertIs(self.Colors.red, MoreColors.red)
self.assertIs(self.Colors.blue, MoreColors.blue)
def test_pickle(self):
from flufl.enum.tests.fruit import Fruit
from pickle import dumps, loads
self.assertIs(Fruit.tomato, loads(dumps(Fruit.tomato)))
def test_functional_api_single_string(self):
animals = Enum('Animals', 'ant bee cat dog')
self.assertEqual(
repr(animals),
'')
def test_functional_api_sequence(self):
people = Enum('People', ('anne', 'bart', 'cate', 'dave'))
self.assertEqual(
repr(people),
'')
def test_functional_api_2_tuples(self):
def enumiter():
start = 1
while True:
yield start
start <<= 1
flags = Enum('Flags', zip(list('abcdefg'), enumiter()))
self.assertEqual(
repr(flags),
'')
def test_functional_api_dict(self):
# Note: repr is sorted by attribute name
bassists = dict(geddy='rush', chris='yes', flea='rhcp', jack='cream')
self.assertEqual(
repr(Enum('Bassists', bassists)),
'')
def test_invalid_getitem_arguments(self):
# getitem on an Enum with invalid value raises an exception.
class Colors(Enum):
red = 1
green = 2
blue = 3
with self.assertRaises(ValueError) as cm:
Colors['magenta']
self.assertEqual(cm.exception.args, ('magenta',))
def test_no_duplicates(self):
with self.assertRaises(ValueError) as cm:
class Bad(Enum):
cartman = 1
stan = 2
kyle = 3
kenny = 3 # Oops!
butters = 4
self.assertEqual(
str(cm.exception),
"Conflicting enum value '3' for names: 'kenny' and 'kyle'")
def test_no_duplicates_in_subclass(self):
class Colors(Enum):
red = 1
green = 2
blue = 3
with self.assertRaises(ValueError) as cm:
class MoreColors(Colors):
yellow = 4
magenta = 2 # Oops!
self.assertEqual(
str(cm.exception),
"Conflicting enum value '2' for names: 'green' and 'magenta'")
def test_no_duplicates_in_dict(self):
with self.assertRaises(ValueError) as cm:
Enum('Things', dict(a='yes', b='no', c='maybe', d='yes'))
self.assertEqual(
cm.exception.args[0],
"Conflicting enum value 'yes' for names: 'a' and 'd'")
def test_functional_api_not_all_2_tuples(self):
# If 2-tuples are used, all items must be 2-tuples.
self.assertRaises(ValueError, Enum, 'Animals', (
('ant', 1),
('bee', 2),
'cat',
('dog', 4),
))
self.assertRaises(ValueError, Enum, 'Animals', (
('ant', 1),
('bee', 2),
('cat',),
('dog', 4),
))
self.assertRaises(ValueError, Enum, 'Animals', (
('ant', 1),
('bee', 2),
('cat', 3, 'oops'),
('dog', 4),
))
def test_functional_api_identifiers(self):
# Ensure that the functional API enforces identifiers.
with self.assertRaises(ValueError) as cm:
Enum('Foo', ('1', '2', '3'))
self.assertEqual(cm.exception.args[0], 'non-identifiers: 1 2 3')
with self.assertRaises(ValueError) as cm:
Enum('Foo', (('ant', 1), ('bee', 2), ('3', 'cat')))
self.assertEqual(cm.exception.args[0], 'non-identifiers: 3')
def test_functional_api_identifiers_lp1167052(self):
# LP: #1167052
self.assertRaises(ValueError, Enum, 'X', 'a-1')
def test_functional_api_identifiers_numbers(self):
# There was a typo in IDENTIFIER_RE where the range 0-0 was used.
MyEnum = Enum('X', 'a9')
self.assertEqual(MyEnum.a9.name, 'a9')
def test_deprecate_make(self):
# LP: #1162375 -- use Enum() calling syntax instead.
with warnings.catch_warnings(record=True) as seen:
# In Python 3.3+ we can use self.assertWarns()
warnings.simplefilter('always')
Animals = make('Animals', 'ant bee cat'.split())
self.assertEqual(len(seen), 1)
self.assertEqual(seen[0].category, DeprecationWarning)
# We don't need to assert the deprecation message.
self.assertEqual(Animals.ant.value, 1)
def test_deprecate_getitem_by_name(self):
# LP: #1167091
# Enum[item_name] should be deprecated.
Fruit = Enum('Fruit', dict(
apple='red', banana='yellow', tangerine='orange',
orange='reddish yellow'))
with warnings.catch_warnings(record=True) as seen:
# In Python 3.3+ we can use self.assertWarns()
warnings.simplefilter('always')
item = Fruit['banana']
self.assertEqual(len(seen), 1)
self.assertEqual(seen[0].category, DeprecationWarning)
# But for now it still works.
self.assertIs(item, Fruit.banana)
# getitem() should still access by value, without deprecation warning.
with warnings.catch_warnings(record=True) as seen:
# In Python 3.3+ we can use self.assertWarns()
warnings.simplefilter('always')
item = Fruit['yellow']
self.assertEqual(len(seen), 0)
self.assertIs(item, Fruit.banana)
def test_explicit_getattr(self):
Fruit = Enum('Fruit', 'apple banana tangerine orange')
self.assertIs(getattr(Fruit, 'banana'), Fruit.banana)
self.assertIs(getattr(Fruit, Fruit.banana.name), Fruit.banana)
class TestIntEnum(unittest.TestCase):
"""Tests of the IntEnums."""
class Animals(IntEnum):
ant = 1
bee = 2
cat = 3
def test_issue_17576(self):
# http://bugs.python.org/issue17576
#
# The problem is that despite the documentation, operator.index() is
# *not* equivalent to calling obj.__index__() when the object in
# question is an int subclass.
# Test that while the actual type returned by operator.index() and
# obj.__index__() are not the same (because the former returns the
# subclass instance, but the latter returns the .value attribute) they
# are equal.
self.assertEqual(index(self.Animals.bee), self.Animals.bee.__index__())
def test_basic_intenum(self):
animal_list = [self.Animals.ant, self.Animals.bee, self.Animals.cat]
self.assertEqual(animal_list, [1, 2, 3])
self.assertEqual([int(a) for a in animal_list], [1, 2, 3])
self.assertEqual(
list(range(10)[self.Animals.ant:self.Animals.cat]),
[1, 2])
def test_int_enums_type(self):
# IntEnum() enum values are ints.
Toppings = IntEnum(
'Toppings',
dict(olives=1, onions=2, mushrooms=4, cheese=8, garlic=16).items())
self.assertEqual(Toppings.garlic, 16)
self.assertIsInstance(Toppings.mushrooms, int)
def test_comparisons(self):
self.assertTrue(self.Animals.ant < self.Animals.bee)
self.assertTrue(self.Animals.cat > self.Animals.ant)
self.assertTrue(self.Animals.ant <= 1.0)
self.assertEqual(self.Animals.bee, 2)
class Toppings(IntEnum):
anchovies = 1
black_olives = 2
self.assertEqual(self.Animals.bee, Toppings.black_olives)
def test_iteration(self):
# Iteration over IntEnums is by value.
A = IntEnum('A', 'a b c')
self.assertEqual(list(v.name for v in A), ['a', 'b', 'c'])
B = IntEnum('B', 'c b a')
# Iteration over this enum is different than if it were an Enum.
self.assertEqual(list(v.name for v in B), ['c', 'b', 'a'])
flufl.enum-4.1/flufl/enum/tests/test_documentation.py 0000664 0001750 0001750 00000005121 12476403363 023422 0 ustar barry barry 0000000 0000000 # Copyright (C) 2004-2015 Barry Warsaw
#
# This file is part of flufl.enum.
#
# flufl.enum is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# flufl.enum is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with flufl.enum. If not, see .
#
# Author: Barry Warsaw
"""Test harness for doctests."""
from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
'additional_tests',
]
import os
import atexit
import doctest
import unittest
from pkg_resources import (
resource_filename, resource_exists, resource_listdir, cleanup_resources)
COMMASPACE = ', '
DOT = '.'
DOCTEST_FLAGS = (
doctest.ELLIPSIS |
doctest.NORMALIZE_WHITESPACE |
doctest.REPORT_NDIFF)
def stop():
"""Call into pdb.set_trace()"""
# Do the import here so that you get the wacky special hacked pdb instead
# of Python's normal pdb.
import pdb
pdb.set_trace()
def setup(testobj):
"""Test setup."""
# Make sure future statements in our doctests match the Python code. When
# run with 2to3, the future import gets removed and these names are not
# defined.
try:
testobj.globs['absolute_import'] = absolute_import
testobj.globs['print_function'] = print_function
testobj.globs['unicode_literals'] = unicode_literals
except NameError:
pass
testobj.globs['stop'] = stop
def additional_tests():
"Run the doc tests (README.rst and docs/*, if any exist)"
doctest_files = [
os.path.abspath(resource_filename('flufl.enum', 'README.rst'))]
if resource_exists('flufl.enum', 'docs'):
for name in resource_listdir('flufl.enum', 'docs'):
if name.endswith('.rst'):
doctest_files.append(
os.path.abspath(
resource_filename('flufl.enum', 'docs/%s' % name)))
kwargs = dict(module_relative=False,
optionflags=DOCTEST_FLAGS,
setUp=setup,
)
atexit.register(cleanup_resources)
return unittest.TestSuite((
doctest.DocFileSuite(*doctest_files, **kwargs)))
flufl.enum-4.1/flufl/__init__.py 0000664 0001750 0001750 00000001634 12476403363 017150 0 ustar barry barry 0000000 0000000 # Copyright (C) 2004-2015 Barry Warsaw
#
# This file is part of flufl.enum.
#
# flufl.enum is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# flufl.enum is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with flufl.enum. If not, see .
#
# Author: Barry Warsaw
# this is a namespace package
try:
import pkg_resources
pkg_resources.declare_namespace(__name__)
except ImportError:
import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
flufl.enum-4.1/tox.ini 0000664 0001750 0001750 00000000112 12606033335 015221 0 ustar barry barry 0000000 0000000 [tox]
envlist = py27,py34,py35
[testenv]
commands = python setup.py test
flufl.enum-4.1/PKG-INFO 0000664 0001750 0001750 00000022017 12606034371 015014 0 ustar barry barry 0000000 0000000 Metadata-Version: 1.1
Name: flufl.enum
Version: 4.1
Summary: A Python enumeration package.
Home-page: http://launchpad.net/flufl.enum
Author: Barry Warsaw
Author-email: barry@python.org
License: LGPLv3
Download-URL: https://launchpad.net/flufl.enum/+download
Description: ==========
flufl.enum
==========
A Python enumeration package.
The `flufl.enum` library is a Python enumeration package. Its goal is to
provide simple, specific, concise semantics in an easy to read and write
syntax. `flufl.enum` has just enough of the features needed to make
enumerations useful, but without a lot of extra baggage to weigh them down.
This work grew out of the Mailman 3.0 project.
**Note: This package is deprecated!** Python 3.4 added an enum package to its
`standard library`_ which is also available as a `third party package`_ on
PyPI for older versions of Python. If you are using `flufl.enum` you should
switch to the standard enum package.
Author
======
`flufl.enum` is Copyright (C) 2004-2015 Barry Warsaw
Licensed under the terms of the GNU Lesser General Public License, version 3
or later. See the COPYING.LESSER file for details.
Project details
===============
* Project home: https://gitlab.com/warsaw/flufl.enum
* Report bugs at: https://gitlab.com/warsaw/flufl.enum/issues
* Code hosting: git@gitlab.com:warsaw/flufl.enum.git
* Documentation: http://fluflenum.readthedocs.org/
.. `standard library`: https://docs.python.org/3/library/enum.html
.. `third party package`: https://pypi.python.org/pypi/enum34
===================
NEWS for flufl.enum
===================
4.1 (2015-10-09)
================
* Fix the regexp that matches identifiers in the functional API.
(LP: #1167052)
* Deprecate using getitem syntax for accessing enum values by attribute
name. Use ``getattr(Enum, name)`` instead. (LP: #1167091)
* Duplicate enum values error now provides information on the attribute names
that produced the conflict. Given by Eli Bendersky.
* The documentation now makes it clear that iteration sort order is not
guaranteed for ``Enum`` but *is* guaranteed for ``IntEnum``.
* Comparison operators now return ``NotImplemented`` which cause their use to
raise ``TypeError`` instead of ``NotImplementedError``. This is for
consistency with Python 3. In Python 2, we raise the ``TypeError``
explicitly.
* ``repr(Enum)`` now sorts in attribute name order, as does iteration over
``Enum``. Iteration over ``IntEnum`` is sorted by the enumeration item
values (which must be integers).
* ``Enum.__getattr__()`` and special treatment for ``__members__`` is
removed. A ``__dir__()`` is provided to limit ``dir(Enum)`` to just the
enumeration item names.
* As per BDFL request, document the ``__value_factory__`` API.
* Add support for Python 3.5 and drop support for Python 2.6.
4.0.1 (2014-06-11)
==================
* Include MANIFEST.in and tox.ini in the sdist tarball, otherwise the Debian
package won't built correctly.
* Drop use of distribute.
* Narrow tox supported environments.
* Bump copyright years.
4.0 (2013-04-05)
================
* Fix documentation bugs. (LP: #1026403, LP: #1132830)
* Deprecate ``EnumValue.__int__()``; use ``IntEnumValue`` (via ``IntEnum``)
instead.
* Add ``IntEnum`` class which returns int-subclass enum values. (LP: #1132976)
- Add ``__index__()`` method to support slicing. (LP: #1132972)
- Add non-deprecated ``__int__()`` method.
* Deprecate ``make()``; use ``Enum()`` instead.
- Call ``IntEnum()`` to create integer valued enums. (LP: #1162375)
- Accept a space-separate string of enum values which are auto-split.
- Accept a dictionary of enumeration name/value pairs.
* Add ``.value`` attribute to enum values. (LP: #1132859)
* For ``__getitem__()`` and ``__call__()``, fall back to using the ``.value``
attribute if the argument has one. (LP: #1124596)
* Previously deprecated APIs ``EnumValue.enumclass``, ``EnumValue.enumname``,
and ``enum.make_enum()`` are removed. (LP: #1132951)
* Small change to the ``repr`` of enum values; they now say "value=" instead
of "int=".
* Multiple enum values now raise a `ValueError` instead of a `TypeError`.
3.3.2 (2012-04-19)
==================
* Add classifiers to setup.py and make the long description more compatible
with the Cheeseshop.
* Other changes to make the Cheeseshop page look nicer. (LP: #680136)
* setup_helper.py version 2.1.
3.3.1 (2012-01-19)
==================
* Fix Python 3 compatibility with Sphinx's conf.py ($python setup.py install).
3.3 (2012-01-19)
================
* Remove the dependency on 2to3 for Python 3 support; support Python 3
directly with a single code base.
* flufl.enum.make_enum() is deprecated in favor of flufl.enum.make() which
provides a better API. (LP: #839529)
* Updated to distribute 0.6.19.
* Moved all documentation to .rst suffix.
* Make test_deprecations() compatible with Python 3 and Python 2.
* Removed markup for pylint.
* Improve documentation to illustrate that enum values with similar names and
integer representations still do not hash equally. (Found by Jeroen
Vermeulen).
3.2 (2011-08-19)
================
* make_enum() accepts an optional `iterable` argument to provide the values
for the enums.
* The .enumclass and .enumname attributes are deprecated. Use .enum and
.name instead, respectively.
* Improve the documentation regarding ordered comparisons and equality
tests. (LP: #794853)
* make_enum() now enforces the use of valid Python identifiers. (LP: #803570)
3.1 (2011-03-01)
================
* New convenience function `make_enum()`. (Contributed by Michael Foord)
* Fix `from flufl.enum import *`.
* Enums created with the class syntax can be pickled and unpickled.
(Suggestion and basic implementation idea by Phillip Eby).
3.0.1 (2010-06-07)
==================
* Fixed typo which caused the package to break.
3.0 (2010-04-24)
================
* Package renamed to flufl.enum.
2.0.2 (2010-01-29)
==================
* Fixed some test failures when running under 2to3.
2.0.1 (2010-01-08)
==================
* Fix the manifest and clarify license.
2.0 (2010-01-07)
================
* Use Sphinx to build the documentation.
* Updates to better package Debian/Ubuntu.
* Use distribute_setup instead of ez_setup.
* Rename pep-xxxx.txt; this won't be submitted as a PEP.
* Remove dependencies on nose and setuptools_bzr
* Support Python 3 via 2to3.
Earlier
=======
Try `bzr log lp:flufl.enum` for details.
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)
Classifier: Operating System :: POSIX
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
flufl.enum-4.1/template.py 0000664 0001750 0001750 00000001527 12476403363 016115 0 ustar barry barry 0000000 0000000 # Copyright (C) 2015 Barry Warsaw
#
# This file is part of flufl.enum
#
# flufl.enum is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# flufl.enum is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with flufl.enum. If not, see .
#
# Author: Barry Warsaw
"""Module contents."""
from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
]
flufl.enum-4.1/README.rst 0000664 0001750 0001750 00000002400 12527516275 015412 0 ustar barry barry 0000000 0000000 ==========
flufl.enum
==========
A Python enumeration package.
The `flufl.enum` library is a Python enumeration package. Its goal is to
provide simple, specific, concise semantics in an easy to read and write
syntax. `flufl.enum` has just enough of the features needed to make
enumerations useful, but without a lot of extra baggage to weigh them down.
This work grew out of the Mailman 3.0 project.
**Note: This package is deprecated!** Python 3.4 added an enum package to its
`standard library`_ which is also available as a `third party package`_ on
PyPI for older versions of Python. If you are using `flufl.enum` you should
switch to the standard enum package.
Author
======
`flufl.enum` is Copyright (C) 2004-2015 Barry Warsaw
Licensed under the terms of the GNU Lesser General Public License, version 3
or later. See the COPYING.LESSER file for details.
Project details
===============
* Project home: https://gitlab.com/warsaw/flufl.enum
* Report bugs at: https://gitlab.com/warsaw/flufl.enum/issues
* Code hosting: git@gitlab.com:warsaw/flufl.enum.git
* Documentation: http://fluflenum.readthedocs.org/
.. `standard library`: https://docs.python.org/3/library/enum.html
.. `third party package`: https://pypi.python.org/pypi/enum34
flufl.enum-4.1/flufl.enum.egg-info/ 0000775 0001750 0001750 00000000000 12606034371 017462 5 ustar barry barry 0000000 0000000 flufl.enum-4.1/flufl.enum.egg-info/SOURCES.txt 0000664 0001750 0001750 00000001055 12606034371 021347 0 ustar barry barry 0000000 0000000 MANIFEST.in
README.rst
setup.cfg
setup.py
setup_helpers.py
template.py
tox.ini
flufl/__init__.py
flufl.enum.egg-info/PKG-INFO
flufl.enum.egg-info/SOURCES.txt
flufl.enum.egg-info/dependency_links.txt
flufl.enum.egg-info/namespace_packages.txt
flufl.enum.egg-info/top_level.txt
flufl/enum/NEWS.rst
flufl/enum/README.rst
flufl/enum/__init__.py
flufl/enum/_enum.py
flufl/enum/conf.py
flufl/enum/docs/__init__.py
flufl/enum/docs/using.rst
flufl/enum/tests/__init__.py
flufl/enum/tests/fruit.py
flufl/enum/tests/test_documentation.py
flufl/enum/tests/test_enum.py flufl.enum-4.1/flufl.enum.egg-info/top_level.txt 0000664 0001750 0001750 00000000006 12606034371 022210 0 ustar barry barry 0000000 0000000 flufl
flufl.enum-4.1/flufl.enum.egg-info/dependency_links.txt 0000664 0001750 0001750 00000000001 12606034371 023530 0 ustar barry barry 0000000 0000000
flufl.enum-4.1/flufl.enum.egg-info/namespace_packages.txt 0000664 0001750 0001750 00000000006 12606034371 024011 0 ustar barry barry 0000000 0000000 flufl
flufl.enum-4.1/flufl.enum.egg-info/PKG-INFO 0000664 0001750 0001750 00000022017 12606034371 020561 0 ustar barry barry 0000000 0000000 Metadata-Version: 1.1
Name: flufl.enum
Version: 4.1
Summary: A Python enumeration package.
Home-page: http://launchpad.net/flufl.enum
Author: Barry Warsaw
Author-email: barry@python.org
License: LGPLv3
Download-URL: https://launchpad.net/flufl.enum/+download
Description: ==========
flufl.enum
==========
A Python enumeration package.
The `flufl.enum` library is a Python enumeration package. Its goal is to
provide simple, specific, concise semantics in an easy to read and write
syntax. `flufl.enum` has just enough of the features needed to make
enumerations useful, but without a lot of extra baggage to weigh them down.
This work grew out of the Mailman 3.0 project.
**Note: This package is deprecated!** Python 3.4 added an enum package to its
`standard library`_ which is also available as a `third party package`_ on
PyPI for older versions of Python. If you are using `flufl.enum` you should
switch to the standard enum package.
Author
======
`flufl.enum` is Copyright (C) 2004-2015 Barry Warsaw
Licensed under the terms of the GNU Lesser General Public License, version 3
or later. See the COPYING.LESSER file for details.
Project details
===============
* Project home: https://gitlab.com/warsaw/flufl.enum
* Report bugs at: https://gitlab.com/warsaw/flufl.enum/issues
* Code hosting: git@gitlab.com:warsaw/flufl.enum.git
* Documentation: http://fluflenum.readthedocs.org/
.. `standard library`: https://docs.python.org/3/library/enum.html
.. `third party package`: https://pypi.python.org/pypi/enum34
===================
NEWS for flufl.enum
===================
4.1 (2015-10-09)
================
* Fix the regexp that matches identifiers in the functional API.
(LP: #1167052)
* Deprecate using getitem syntax for accessing enum values by attribute
name. Use ``getattr(Enum, name)`` instead. (LP: #1167091)
* Duplicate enum values error now provides information on the attribute names
that produced the conflict. Given by Eli Bendersky.
* The documentation now makes it clear that iteration sort order is not
guaranteed for ``Enum`` but *is* guaranteed for ``IntEnum``.
* Comparison operators now return ``NotImplemented`` which cause their use to
raise ``TypeError`` instead of ``NotImplementedError``. This is for
consistency with Python 3. In Python 2, we raise the ``TypeError``
explicitly.
* ``repr(Enum)`` now sorts in attribute name order, as does iteration over
``Enum``. Iteration over ``IntEnum`` is sorted by the enumeration item
values (which must be integers).
* ``Enum.__getattr__()`` and special treatment for ``__members__`` is
removed. A ``__dir__()`` is provided to limit ``dir(Enum)`` to just the
enumeration item names.
* As per BDFL request, document the ``__value_factory__`` API.
* Add support for Python 3.5 and drop support for Python 2.6.
4.0.1 (2014-06-11)
==================
* Include MANIFEST.in and tox.ini in the sdist tarball, otherwise the Debian
package won't built correctly.
* Drop use of distribute.
* Narrow tox supported environments.
* Bump copyright years.
4.0 (2013-04-05)
================
* Fix documentation bugs. (LP: #1026403, LP: #1132830)
* Deprecate ``EnumValue.__int__()``; use ``IntEnumValue`` (via ``IntEnum``)
instead.
* Add ``IntEnum`` class which returns int-subclass enum values. (LP: #1132976)
- Add ``__index__()`` method to support slicing. (LP: #1132972)
- Add non-deprecated ``__int__()`` method.
* Deprecate ``make()``; use ``Enum()`` instead.
- Call ``IntEnum()`` to create integer valued enums. (LP: #1162375)
- Accept a space-separate string of enum values which are auto-split.
- Accept a dictionary of enumeration name/value pairs.
* Add ``.value`` attribute to enum values. (LP: #1132859)
* For ``__getitem__()`` and ``__call__()``, fall back to using the ``.value``
attribute if the argument has one. (LP: #1124596)
* Previously deprecated APIs ``EnumValue.enumclass``, ``EnumValue.enumname``,
and ``enum.make_enum()`` are removed. (LP: #1132951)
* Small change to the ``repr`` of enum values; they now say "value=" instead
of "int=".
* Multiple enum values now raise a `ValueError` instead of a `TypeError`.
3.3.2 (2012-04-19)
==================
* Add classifiers to setup.py and make the long description more compatible
with the Cheeseshop.
* Other changes to make the Cheeseshop page look nicer. (LP: #680136)
* setup_helper.py version 2.1.
3.3.1 (2012-01-19)
==================
* Fix Python 3 compatibility with Sphinx's conf.py ($python setup.py install).
3.3 (2012-01-19)
================
* Remove the dependency on 2to3 for Python 3 support; support Python 3
directly with a single code base.
* flufl.enum.make_enum() is deprecated in favor of flufl.enum.make() which
provides a better API. (LP: #839529)
* Updated to distribute 0.6.19.
* Moved all documentation to .rst suffix.
* Make test_deprecations() compatible with Python 3 and Python 2.
* Removed markup for pylint.
* Improve documentation to illustrate that enum values with similar names and
integer representations still do not hash equally. (Found by Jeroen
Vermeulen).
3.2 (2011-08-19)
================
* make_enum() accepts an optional `iterable` argument to provide the values
for the enums.
* The .enumclass and .enumname attributes are deprecated. Use .enum and
.name instead, respectively.
* Improve the documentation regarding ordered comparisons and equality
tests. (LP: #794853)
* make_enum() now enforces the use of valid Python identifiers. (LP: #803570)
3.1 (2011-03-01)
================
* New convenience function `make_enum()`. (Contributed by Michael Foord)
* Fix `from flufl.enum import *`.
* Enums created with the class syntax can be pickled and unpickled.
(Suggestion and basic implementation idea by Phillip Eby).
3.0.1 (2010-06-07)
==================
* Fixed typo which caused the package to break.
3.0 (2010-04-24)
================
* Package renamed to flufl.enum.
2.0.2 (2010-01-29)
==================
* Fixed some test failures when running under 2to3.
2.0.1 (2010-01-08)
==================
* Fix the manifest and clarify license.
2.0 (2010-01-07)
================
* Use Sphinx to build the documentation.
* Updates to better package Debian/Ubuntu.
* Use distribute_setup instead of ez_setup.
* Rename pep-xxxx.txt; this won't be submitted as a PEP.
* Remove dependencies on nose and setuptools_bzr
* Support Python 3 via 2to3.
Earlier
=======
Try `bzr log lp:flufl.enum` for details.
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)
Classifier: Operating System :: POSIX
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules