Skip to content

[3.6] bpo-35899: Fix Enum handling of empty and weird strings (GH-11891) #12151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions Lib/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,19 @@ def _is_descriptor(obj):

def _is_dunder(name):
"""Returns True if a __dunder__ name, False otherwise."""
return (name[:2] == name[-2:] == '__' and
name[2:3] != '_' and
name[-3:-2] != '_' and
len(name) > 4)
return (len(name) > 4 and
name[:2] == name[-2:] == '__' and
name[2] != '_' and
name[-3] != '_')


def _is_sunder(name):
"""Returns True if a _sunder_ name, False otherwise."""
return (name[0] == name[-1] == '_' and
return (len(name) > 2 and
name[0] == name[-1] == '_' and
name[1:2] != '_' and
name[-2:-1] != '_' and
len(name) > 2)
name[-2:-1] != '_')


def _make_class_unpicklable(cls):
"""Make the given class un-picklable."""
Expand Down Expand Up @@ -140,7 +141,7 @@ def __new__(metacls, cls, bases, classdict):
_order_ = classdict.pop('_order_', None)

# check for illegal enum names (any others?)
invalid_names = set(enum_members) & {'mro', }
invalid_names = set(enum_members) & {'mro', ''}
if invalid_names:
raise ValueError('Invalid enum member name: {0}'.format(
','.join(invalid_names)))
Expand Down
17 changes: 17 additions & 0 deletions Lib/test/test_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -2396,6 +2396,23 @@ def cycle_enum():
self.assertEqual(256, len(seen), 'too many composite members created')


class TestEmptyAndNonLatinStrings(unittest.TestCase):

def test_empty_string(self):
with self.assertRaises(ValueError):
empty_abc = Enum('empty_abc', ('', 'B', 'C'))

def test_non_latin_character_string(self):
greek_abc = Enum('greek_abc', ('\u03B1', 'B', 'C'))
item = getattr(greek_abc, '\u03B1')
self.assertEqual(item.value, 1)

def test_non_latin_number_string(self):
hebrew_123 = Enum('hebrew_123', ('\u05D0', '2', '3'))
item = getattr(hebrew_123, '\u05D0')
self.assertEqual(item.value, 1)


class TestUnique(unittest.TestCase):

def test_unique_clean(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enum has been fixed to correctly handle empty strings and strings with non-Latin characters (ie. 'α', 'א') without crashing. Original patch contributed by Maxwell. Assisted by Stéphane Wirtel.