diff options
author | Ethan Furman <ethan@stoneleaf.us> | 2014-09-17 03:35:55 (GMT) |
---|---|---|
committer | Ethan Furman <ethan@stoneleaf.us> | 2014-09-17 03:35:55 (GMT) |
commit | d9925a18ec1bc67d8835d0d29342c6c713c064af (patch) | |
tree | 1dbe43d9af32d8f7ae0fbab115d352076db4c4ac /Lib | |
parent | 52351c7037ca2e98d56907815f69e6441fcc5071 (diff) | |
download | cpython-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.py | 16 | ||||
-rw-r--r-- | Lib/test/test_enum.py | 66 |
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 |