Author Maxpxt
Recipients Maxpxt
Date 2019-02-05.14:27:38
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1549376859.01.0.998806898699.issue35899@roundup.psfhosted.org>
In-reply-to
Content
This is a really minor bug.

In enum.py the function _is_sunder(name) fails on empty string with an IndexError.

As a result, attempting to create an Enum with an empty string fails.

>>> from enum import Enum
>>> Yay = Enum('Yay', ('', 'B', 'C'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Python37\lib\enum.py", line 311, in __call__
    return cls._create_(value, names, module=module, qualname=qualname, type=type, start=start)
  File "C:\Program Files\Python37\lib\enum.py", line 422, in _create_
    classdict[member_name] = member_value
  File "C:\Program Files\Python37\lib\enum.py", line 78, in __setitem__
    if _is_sunder(key):
  File "C:\Program Files\Python37\lib\enum.py", line 36, in _is_sunder
    return (name[0] == name[-1] == '_' and
IndexError: string index out of range
>>>



Expected behavior is for it to not fail, as Enum accepts wierd strings. Example:

>>> from enum import Enum
>>> Yay = Enum('Yay', ('!', 'B', 'C'))
>>> getattr(Yay, '!')
<Yay.!: 1>
>>>



Transcript of lines 26 to 39 of enum.py:

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)


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



Solution 1: Replace with:

def _is_dunder(name):
    """Returns True if a __dunder__ name, False otherwise."""
    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 (len(name) > 2 and
            name[0] == name[-1] == '_' and
            name[1:2] != '_' and
            name[-2:-1] != '_')

In this solution, function '_is_dunder' was also altered for consistency.
Altering '_is_dunder' is not necessary, though.



Solution 2: Replace with:

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)


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

In this solution, function '_is_sunder' was altered to follow
the style used in function '_is_dunder'.
History
Date User Action Args
2019-02-05 14:27:42Maxpxtsetrecipients: + Maxpxt
2019-02-05 14:27:39Maxpxtsetmessageid: <1549376859.01.0.998806898699.issue35899@roundup.psfhosted.org>
2019-02-05 14:27:38Maxpxtlinkissue35899 messages
2019-02-05 14:27:38Maxpxtcreate