summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorEthan Furman <ethan@stoneleaf.us>2014-09-17 03:35:55 (GMT)
committerEthan Furman <ethan@stoneleaf.us>2014-09-17 03:35:55 (GMT)
commitd9925a18ec1bc67d8835d0d29342c6c713c064af (patch)
tree1dbe43d9af32d8f7ae0fbab115d352076db4c4ac /Lib
parent52351c7037ca2e98d56907815f69e6441fcc5071 (diff)
downloadcpython-d9925a18ec1bc67d8835d0d29342c6c713c064af.zip
cpython-d9925a18ec1bc67d8835d0d29342c6c713c064af.tar.gz
cpython-d9925a18ec1bc67d8835d0d29342c6c713c064af.tar.bz2
Close issue21706: add 'start' parameter to functional API
Diffstat (limited to 'Lib')
-rw-r--r--Lib/enum.py16
-rw-r--r--Lib/test/test_enum.py66
2 files changed, 74 insertions, 8 deletions
diff --git a/Lib/enum.py b/Lib/enum.py
index 84fa20e..b9e42ae 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -193,7 +193,7 @@ class EnumMeta(type):
enum_class.__new__ = Enum.__new__
return enum_class
- def __call__(cls, value, names=None, *, module=None, qualname=None, type=None):
+ def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1):
"""Either returns an existing member, or creates a new enum class.
This method is used both when an enum class is given a value to match
@@ -205,7 +205,7 @@ class EnumMeta(type):
`value` will be the name of the new class.
`names` should be either a string of white-space/comma delimited names
- (values will start at 1), or an iterator/mapping of name, value pairs.
+ (values will start at `start`), or an iterator/mapping of name, value pairs.
`module` should be set to the module this class is being created in;
if it is not set, an attempt to find that module will be made, but if
@@ -221,7 +221,7 @@ class EnumMeta(type):
if names is None: # simple value lookup
return cls.__new__(cls, value)
# otherwise, functional API: we're creating a new Enum type
- return cls._create_(value, names, module=module, qualname=qualname, type=type)
+ return cls._create_(value, names, module=module, qualname=qualname, type=type, start=start)
def __contains__(cls, member):
return isinstance(member, cls) and member._name_ in cls._member_map_
@@ -292,16 +292,16 @@ class EnumMeta(type):
raise AttributeError('Cannot reassign members.')
super().__setattr__(name, value)
- def _create_(cls, class_name, names=None, *, module=None, qualname=None, type=None):
+ def _create_(cls, class_name, names=None, *, module=None, qualname=None, type=None, start=1):
"""Convenience method to create a new Enum class.
`names` can be:
* A string containing member names, separated either with spaces or
- commas. Values are auto-numbered from 1.
- * An iterable of member names. Values are auto-numbered from 1.
+ commas. Values are incremented by 1 from `start`.
+ * An iterable of member names. Values are incremented by 1 from `start`.
* An iterable of (member name, value) pairs.
- * A mapping of member name -> value.
+ * A mapping of member name -> value pairs.
"""
metacls = cls.__class__
@@ -312,7 +312,7 @@ class EnumMeta(type):
if isinstance(names, str):
names = names.replace(',', ' ').split()
if isinstance(names, (tuple, list)) and isinstance(names[0], str):
- names = [(e, i) for (i, e) in enumerate(names, 1)]
+ names = [(e, i) for (i, e) in enumerate(names, start)]
# Here, names is either an iterable of (name, value) or a mapping.
for item in names:
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index f1f8063..bf9d633 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -634,6 +634,23 @@ class TestEnum(unittest.TestCase):
self.assertIn(e, SummerMonth)
self.assertIs(type(e), SummerMonth)
+ def test_programatic_function_string_with_start(self):
+ SummerMonth = Enum('SummerMonth', 'june july august', start=10)
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split(), 10):
+ e = SummerMonth(i)
+ self.assertEqual(int(e.value), i)
+ self.assertNotEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertIn(e, SummerMonth)
+ self.assertIs(type(e), SummerMonth)
+
def test_programatic_function_string_list(self):
SummerMonth = Enum('SummerMonth', ['june', 'july', 'august'])
lst = list(SummerMonth)
@@ -651,6 +668,23 @@ class TestEnum(unittest.TestCase):
self.assertIn(e, SummerMonth)
self.assertIs(type(e), SummerMonth)
+ def test_programatic_function_string_list_with_start(self):
+ SummerMonth = Enum('SummerMonth', ['june', 'july', 'august'], start=20)
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split(), 20):
+ e = SummerMonth(i)
+ self.assertEqual(int(e.value), i)
+ self.assertNotEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertIn(e, SummerMonth)
+ self.assertIs(type(e), SummerMonth)
+
def test_programatic_function_iterable(self):
SummerMonth = Enum(
'SummerMonth',
@@ -707,6 +741,22 @@ class TestEnum(unittest.TestCase):
self.assertIn(e, SummerMonth)
self.assertIs(type(e), SummerMonth)
+ def test_programatic_function_type_with_start(self):
+ SummerMonth = Enum('SummerMonth', 'june july august', type=int, start=30)
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split(), 30):
+ e = SummerMonth(i)
+ self.assertEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertIn(e, SummerMonth)
+ self.assertIs(type(e), SummerMonth)
+
def test_programatic_function_type_from_subclass(self):
SummerMonth = IntEnum('SummerMonth', 'june july august')
lst = list(SummerMonth)
@@ -723,6 +773,22 @@ class TestEnum(unittest.TestCase):
self.assertIn(e, SummerMonth)
self.assertIs(type(e), SummerMonth)
+ def test_programatic_function_type_from_subclass_with_start(self):
+ SummerMonth = IntEnum('SummerMonth', 'june july august', start=40)
+ lst = list(SummerMonth)
+ self.assertEqual(len(lst), len(SummerMonth))
+ self.assertEqual(len(SummerMonth), 3, SummerMonth)
+ self.assertEqual(
+ [SummerMonth.june, SummerMonth.july, SummerMonth.august],
+ lst,
+ )
+ for i, month in enumerate('june july august'.split(), 40):
+ e = SummerMonth(i)
+ self.assertEqual(e, i)
+ self.assertEqual(e.name, month)
+ self.assertIn(e, SummerMonth)
+ self.assertIs(type(e), SummerMonth)
+
def test_subclassing(self):
if isinstance(Name, Exception):
raise Name