summaryrefslogtreecommitdiff
path: root/modules/language/python/module/enum.py
diff options
context:
space:
mode:
authorStefan Israelsson Tampe <stefan.itampe@gmail.com>2018-04-15 22:29:50 +0200
committerStefan Israelsson Tampe <stefan.itampe@gmail.com>2018-04-15 22:29:50 +0200
commit77e4e51a919c50e2847527aaffe67e8e19b970ae (patch)
tree61a261e5b053da07493610b947fd8b51e1a8c2f4 /modules/language/python/module/enum.py
parent7c0c098b89dc33ad1018b6542def4e2d34ddd2a8 (diff)
progressively imporoving the conformance with python3
Diffstat (limited to 'modules/language/python/module/enum.py')
-rw-r--r--modules/language/python/module/enum.py50
1 files changed, 32 insertions, 18 deletions
diff --git a/modules/language/python/module/enum.py b/modules/language/python/module/enum.py
index 89047cd..1549862 100644
--- a/modules/language/python/module/enum.py
+++ b/modules/language/python/module/enum.py
@@ -11,7 +11,6 @@ try:
except ImportError:
from collections import OrderedDict
-
__all__ = [
'EnumMeta',
'Enum', 'IntEnum', 'Flag', 'IntFlag',
@@ -50,6 +49,8 @@ def _make_class_unpicklable(cls):
cls.__module__ = '<unknown>'
_auto_null = object()
+
+
class auto:
"""
Instances are replaced with an appropriate value in Enum class suites.
@@ -117,10 +118,14 @@ class EnumMeta(type):
def __prepare__(metacls, cls, bases):
# create the namespace dict
enum_dict = _EnumDict()
+ pk('got dict')
+
# inherit previous flags and _generate_next_value_ function
member_type, first_enum = metacls._get_mixins_(bases)
+
if first_enum is not None:
enum_dict['_generate_next_value_'] = getattr(first_enum, '_generate_next_value_', None)
+
return enum_dict
def __new__(metacls, cls, bases, classdict):
@@ -128,42 +133,45 @@ class EnumMeta(type):
# cannot be mixed with other types (int, float, etc.) if it has an
# inherited __new__ unless a new __new__ is defined (or the resulting
# class will fail).
+ pk('new enum meta')
member_type, first_enum = metacls._get_mixins_(bases)
__new__, save_new, use_args = metacls._find_new_(classdict, member_type,
first_enum)
-
+ pk(1)
# save enum items into separate mapping so they don't get baked into
# the new class
enum_members = {k: classdict[k] for k in classdict._member_names}
for name in classdict._member_names:
del classdict[name]
-
+ pk(2)
# adjust the sunders
_order_ = classdict.pop('_order_', None)
-
+ pk(3)
# check for illegal enum names (any others?)
invalid_names = set(enum_members) & {'mro', }
if invalid_names:
raise ValueError('Invalid enum member name: {0}'.format(
','.join(invalid_names)))
-
+ pk(4)
# create a default docstring if one has not been provided
if '__doc__' not in classdict:
classdict['__doc__'] = 'An enumeration.'
-
+ pk(5)
# create our new Enum type
enum_class = super().__new__(metacls, cls, bases, classdict)
+
enum_class._member_names_ = [] # names in definition order
enum_class._member_map_ = OrderedDict() # name->value map
enum_class._member_type_ = member_type
-
+ pk(6)
# save attributes from super classes so we know if we can take
# the shortcut of storing members in the class dict
+
base_attributes = {a for b in enum_class.mro() for a in b.__dict__}
# Reverse value->name map for hashable values.
enum_class._value2member_map_ = {}
-
+ pk(7)
# If a custom type is mixed into the Enum, and it does not know how
# to pickle itself, pickle.dumps will succeed but pickle.loads will
# fail. Rather than have the error show up later and possibly far
@@ -180,7 +188,7 @@ class EnumMeta(type):
'__reduce_ex__', '__reduce__')
if not any(m in member_type.__dict__ for m in methods):
_make_class_unpicklable(enum_class)
-
+ pk(8)
# instantiate them, checking for duplicates as we go
# we instantiate first instead of checking for duplicates first in case
# a custom __new__ is doing something funky with the values -- such as
@@ -230,7 +238,7 @@ class EnumMeta(type):
enum_class._value2member_map_[value] = enum_member
except TypeError:
pass
-
+ pk(9)
# double check that repr and friends are not the mixin's or various
# things break (such as pickle)
for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'):
@@ -239,7 +247,7 @@ class EnumMeta(type):
enum_method = getattr(first_enum, name, None)
if obj_method is not None and obj_method is class_method:
setattr(enum_class, name, enum_method)
-
+ pk(10)
# replace any other __new__ with our own (as long as Enum is not None,
# anyway) -- again, this is to support pickle
if Enum is not None:
@@ -248,14 +256,14 @@ class EnumMeta(type):
if save_new:
enum_class.__new_member__ = __new__
enum_class.__new__ = Enum.__new__
-
+ pk(11)
# py3 support for definition order (helps keep py2/py3 code in sync)
if _order_ is not None:
if isinstance(_order_, str):
_order_ = _order_.replace(',', ' ').split()
if _order_ != enum_class._member_names_:
raise TypeError('member order does not match _order_')
-
+ pk(12)
return enum_class
def __bool__(self):
@@ -424,9 +432,10 @@ class EnumMeta(type):
bases: the tuple of bases that was given to __new__
"""
+ pk('bases',bases)
if not bases:
return object, Enum
-
+ pk(2)
# double check that we are not subclassing a class with existing
# enumeration members; while we're at it, see if any other data
# type has been mixed in so we can use the correct __new__
@@ -436,6 +445,9 @@ class EnumMeta(type):
issubclass(base, Enum) and
base._member_names_):
raise TypeError("Cannot extend enumerations")
+ pk(3)
+ pk(base)
+ pk(bases)
# base is now the last base in bases
if not issubclass(base, Enum):
raise TypeError("new enumerations must be created as "
@@ -473,11 +485,12 @@ class EnumMeta(type):
# now find the correct __new__, checking to see of one was defined
# by the user; also check earlier enum classes in case a __new__ was
# saved as __new_member__
+ pk(0)
__new__ = classdict.get('__new__', None)
-
+ pk(1)
# should __new__ be saved as __new_member__ later?
save_new = __new__ is not None
-
+ pk(2)
if __new__ is None:
# check all possibles for __new_member__ before falling back to
# __new__
@@ -496,7 +509,7 @@ class EnumMeta(type):
break
else:
__new__ = object.__new__
-
+ pk(3)
# if a non-object.__new__ is used then whatever value/tuple was
# assigned to the enum member name will be passed to __new__ and to the
# new enum member's __init__
@@ -504,7 +517,7 @@ class EnumMeta(type):
use_args = False
else:
use_args = True
-
+ pk(4)
return __new__, save_new, use_args
class Enum(metaclass=EnumMeta):
@@ -636,6 +649,7 @@ class Enum(metaclass=EnumMeta):
module_globals[name] = cls
return cls
+pk(6)
class IntEnum(int, Enum):
"""Enum where members are also (and must be) ints"""