flufl.enum-4.1.1/0000775000175000017500000000000013041670204014047 5ustar barrybarry00000000000000flufl.enum-4.1.1/setup.py0000664000175000017500000000421113041670136015563 0ustar barrybarry00000000000000# Copyright (C) 2004-2017 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.1/flufl/0000775000175000017500000000000013041670204015157 5ustar barrybarry00000000000000flufl.enum-4.1.1/flufl/__init__.py0000664000175000017500000000163413041670136017300 0ustar barrybarry00000000000000# Copyright (C) 2004-2017 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.1/flufl/enum/0000775000175000017500000000000013041670204016123 5ustar barrybarry00000000000000flufl.enum-4.1.1/flufl/enum/__init__.py0000664000175000017500000000175713041670136020252 0ustar barrybarry00000000000000# Copyright (C) 2004-2017 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.1' from ._enum import Enum, EnumValue, IntEnum, make flufl.enum-4.1.1/flufl/enum/docs/0000775000175000017500000000000013041670204017053 5ustar barrybarry00000000000000flufl.enum-4.1.1/flufl/enum/docs/__init__.py0000664000175000017500000000000013041667062021162 0ustar barrybarry00000000000000flufl.enum-4.1.1/flufl/enum/docs/using.rst0000664000175000017500000003416313041667062020751 0ustar barrybarry00000000000000============================ 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: ... >>> Colors.red <= Colors.blue Traceback (most recent call last): ... TypeError: ... >>> Colors.blue > Colors.green Traceback (most recent call last): ... TypeError: ... >>> Colors.blue >= Colors.green Traceback (most recent call last): ... TypeError: ... >>> Colors.red < 3 Traceback (most recent call last): ... TypeError: ... 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.1/flufl/enum/NEWS.rst0000664000175000017500000001176113041667062017447 0ustar barrybarry00000000000000=================== NEWS for flufl.enum =================== 4.1.1 (2017-01-24) ================== * Support Python 3.6. (Closes #1) 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.1/flufl/enum/_enum.py0000664000175000017500000003034213041670136017606 0ustar barrybarry00000000000000# Copyright (C) 2004-2017 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.1/flufl/enum/tests/0000775000175000017500000000000013041670204017265 5ustar barrybarry00000000000000flufl.enum-4.1.1/flufl/enum/tests/__init__.py0000664000175000017500000000000013041667062021374 0ustar barrybarry00000000000000flufl.enum-4.1.1/flufl/enum/tests/fruit.py0000664000175000017500000000172413041670136021000 0ustar barrybarry00000000000000# Copyright (C) 2010-2017 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.1/flufl/enum/tests/test_documentation.py0000664000175000017500000000512113041670136023552 0ustar barrybarry00000000000000# Copyright (C) 2004-2017 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.1/flufl/enum/tests/test_enum.py0000664000175000017500000003252413041670136021654 0ustar barrybarry00000000000000# Copyright (C) 2011-2017 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.1/flufl/enum/README.rst0000664000175000017500000000514013041670136017616 0ustar barrybarry00000000000000========================================= 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-2017 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.1/flufl/enum/conf.py0000664000175000017500000001533113041670136017431 0ustar barrybarry00000000000000# -*- 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-2017, 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.1/setup.cfg0000664000175000017500000000022113041670204015663 0ustar barrybarry00000000000000[build_sphinx] source_dir = flufl/enum [upload_docs] upload_dir = build/sphinx/html [egg_info] tag_date = 0 tag_build = tag_svn_revision = 0 flufl.enum-4.1.1/MANIFEST.in0000664000175000017500000000013113041667062015610 0ustar barrybarry00000000000000include *.py MANIFEST.in *.ini global-include *.txt *.rst exclude .bzrignore prune build flufl.enum-4.1.1/flufl.enum.egg-info/0000775000175000017500000000000013041670204017614 5ustar barrybarry00000000000000flufl.enum-4.1.1/flufl.enum.egg-info/SOURCES.txt0000664000175000017500000000105513041670204021501 0ustar barrybarry00000000000000MANIFEST.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.pyflufl.enum-4.1.1/flufl.enum.egg-info/PKG-INFO0000664000175000017500000002221013041670203020705 0ustar barrybarry00000000000000Metadata-Version: 1.1 Name: flufl.enum Version: 4.1.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-2017 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.1 (2017-01-24) ================== * Support Python 3.6. (Closes #1) 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.1/flufl.enum.egg-info/namespace_packages.txt0000664000175000017500000000000613041670203024142 0ustar barrybarry00000000000000flufl flufl.enum-4.1.1/flufl.enum.egg-info/dependency_links.txt0000664000175000017500000000000113041670203023661 0ustar barrybarry00000000000000 flufl.enum-4.1.1/flufl.enum.egg-info/top_level.txt0000664000175000017500000000000613041670203022341 0ustar barrybarry00000000000000flufl flufl.enum-4.1.1/template.py0000664000175000017500000000152713041670136016245 0ustar barrybarry00000000000000# Copyright (C) 2017 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.1/setup_helpers.py0000664000175000017500000001210313041670136017304 0ustar barrybarry00000000000000# Copyright (C) 2009-2017 Barry 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.1/PKG-INFO0000664000175000017500000002221013041670204015141 0ustar barrybarry00000000000000Metadata-Version: 1.1 Name: flufl.enum Version: 4.1.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-2017 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.1 (2017-01-24) ================== * Support Python 3.6. (Closes #1) 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.1/README.rst0000664000175000017500000000240013041670136015536 0ustar barrybarry00000000000000========== 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-2017 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.1/tox.ini0000664000175000017500000000011713041667062015371 0ustar barrybarry00000000000000[tox] envlist = py27,py34,py35,py36 [testenv] commands = python setup.py test