Source code for PyDvi.Tools.EnumFactory

####################################################################################################
# 
# PyDvi - A Python Library to Process DVI Stream
# Copyright (C) 2014 Fabrice Salvaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program 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 General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 
####################################################################################################

####################################################################################################
#
# Audit
#
# - 27/11/2011 fabrice
#   - check metaclass protocol
#
####################################################################################################

""" This module provides an implementation for enumerate.

The enum factory :func:`EnumFactory` builds a enumerate from a list of names and assigns to these
constants a value from 0 to ``N-1``, where ``N`` is the number of constants::

  enum1 = EnumFactory('Enum1', ('cst1', 'cst2'))
   
then we can get a constant's value with::
     
  enum1.cst1

and the number of constants using::

  len(enum1)

The enum factory :func:`ExplicitEnumFactory` permits to specify the values of the constants::
        
  enum2 = ExplicitEnumFactory('Enum2', {'cst1':1, 'cst2':3})

We can test if a value is in the enum using::

  constant_value in enum2

"""

####################################################################################################

__all__ = ['EnumFactory', 'ExplicitEnumFactory']

####################################################################################################

class ReadOnlyMetaClass(type):

    """ This meta class implements a class where the attributes are read only. """

    ##############################################

    def __setattr__(self, name, value):

        raise NotImplementedError

####################################################################################################

class EnumMetaClass(ReadOnlyMetaClass):

    """ This meta class implements the function :func:`len`. """

    ##############################################

    def __len__(self):

        return self._size

####################################################################################################

class ExplicitEnumMetaClass(ReadOnlyMetaClass):

    """ This meta class implements the operator ``in``. """

    ##############################################

    def __contains__(self, item):

        return item in self.constants

#################################################################################

[docs]def EnumFactory(cls_name, constant_names): """ Return an :class:`EnumMetaClass` instance, where *cls_name* is the class name and *constant_names* is an iterable of constant's names. """ dict_ = {} dict_['_size'] = len(constant_names) for index, name in enumerate(constant_names): dict_[str(name)] = index return EnumMetaClass(cls_name, (), dict_)
#################################################################################
[docs]def ExplicitEnumFactory(cls_name, constant_dict): """ Return an :class:`ExplicitEnumMetaClass` instance, where *cls_name* is the class name and *constant_dict* is a dict of constant's names and their values. """ dict_ = {} dict_['constants'] = constant_dict.values() for name, value in constant_dict.items(): dict_[name] = value return ExplicitEnumMetaClass(cls_name, (), dict_)
#################################################################################################### # # End # ####################################################################################################