[issue26988] Add AutoNumberedEnum to stdlib

Raymond Hettinger report at bugs.python.org
Wed Aug 17 00:52:02 EDT 2016


Raymond Hettinger added the comment:

The use of a bare identifier as a self-assigning statement is unprecedented in the world of Python.  PyFlakes flags it as an error (because prior to now, a bare identifier in a class statement was almost always an error).  I suspect this will cause issues with other static analysis and refactoring tools as well:

    --- tmp_enum_example.py -----
    from enum import AutoEnum

    class Color(AutoEnum):
        red
        green = 5
        blue

    print(list(Color))

    --- bash session ------------
    $ py -m pyflakes tmp_enum_example.py
    tmp_enum_example.py:4: undefined name 'red'
    tmp_enum_example.py:6: undefined name 'blue'
    tmp_enum_example.py:11: undefined name 'yellow'


Also, the usual technique of commenting out blocks with triple quotes introduces unexpected breakage:

    --- tmp_enum_example2.py -----
    from enum import AutoEnum

    class Color(AutoEnum):
        red
        green = 5
        blue
        ''' XXX temporarily comment these out
        brown
        orange
        '''
        yellow

    print(list(Color))

    --- bash session ------------
    $ py -m tmp_enum_example.py
    [<Color.red: 1>, <Color.green: 5>, <Color.blue: 6>, <Color.yellow: 7>]
    /Users/raymond/cpython/python.exe: Error while finding spec for
    'tmp_enum_example.py' (AttributeError: module 'tmp_enum_example'
    has no attribute '__path__')

I worry that this proposal is worse than just being non-idiomatic Python.  In a way, it undermines pillars of the language and conflict everyone's mental model of how the language works.  Historically, a bare variable name raised a NameError if undefined and would otherwise act as a expression who's result was discarded.  However, as used here, it fiats an attribute into existence and assigns it a value.  That to my eyes looks like a new language that isn't Python.  This is really weird and undermines my expectations.

The need for the "ignore" parameter for the "shielded set" is a hint that the patch is working against the grain of the language and is not in harmony with Python as a coherent whole.  It is a harbinger of problems to come.

Lastly, I question whether there is any real problem being solved.  You already have "Color = IntEnum('Animal', 'red green blue')" that works well enough, doesn't mess with language norms, that works nicely with triple quotes for multiline entries, and that extends easily to hundreds of constants.

It seems to me that too much magic and unidiomatic weirdness are being leveled at too small of a problem.  Plus we already have one way to do it.

In teaching people to make effective use of the language, a key learning point is learning the portents of trouble to come and recognizing that that not everything that can be made to work should actually be done.

Please reconsider whether you really want to open this Pandora's box.  Right now, it's not too late.  No doubt that you will find some people who like this (it reminds them of C), but you will also find some very experienced developers who are made queasy by the bare identifier transforming from an expression into an assigning statement.  This more than an "if you don't like it, don't use it" decision, I think an important and invisible line is being crossed that we will regret.

P.S.  A lesson I learned from maintaining the itertools module is that adding more variants of a single idea tends to make the overall toolkit harder to learn and impairs usability.  Users suffer when given too many choices for closely related tasks.  The "one way to do it" line in the Zen of Python is there for a reason.

----------
nosy: +rhettinger

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue26988>
_______________________________________


More information about the Python-bugs-list mailing list