[issue35899] '_is_sunder' function in 'enum' module fails on empty string

Maxwell report at bugs.python.org
Tue Feb 5 09:27:40 EST 2019


New submission from Maxwell <maxwellpxt at gmail.com>:

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'.

----------
components: Library (Lib)
messages: 334866
nosy: Maxpxt
priority: normal
severity: normal
status: open
title: '_is_sunder' function in 'enum' module fails on empty string
type: crash
versions: Python 3.7

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue35899>
_______________________________________


More information about the Python-bugs-list mailing list