Vedran Čačić added the comment:

I don't think the problem is with (Auto)Enum at all. Problem is in a different 
place, and this is just a symptom.

Problem is that people make too many assumptions about `class` suite. Yes, type 
is default metaclass. But not every class should be constructed by type's rules 
- Python provides a very detailed and powerful mechanism for specifying a 
different set of rules, should you need it. This is what metaclass keyword 
argument should be all about. And that is the true reason why metaclass 
conflict is an issue: every metaclass is a DSL specification, and the same 
suite cannot be interpreted according to two different DSLs at the same time.

But since there's a widespread myth that users don't like to type, implementors 
use a trick, "class Spam(metaclass=SpamMeta): pass", and say to their users: 
"there, just inherit from Spam like you inherit from ordinary classes". That 
way, we spare them a few keystrokes, sparing them also of opportunity to learn 
that metaclasses _do_ change the semantics of what they see indented after the 
colon.

I wonder what Raymond's poll result would be if a normal way to write such code 
would expose the metaclass

    class Color(metaclass=AutoEnum):
        blue
        yellow

? Raymond has many valid objections, but they all apply to "ordinary" classes, 
instances of type. Color is not an instance of type, or at least conceptually 
it isn't. type (as a metaclass in Python) means a blueprint, a way to construct 
new instances via __call__, and every instance of it has that behavior, some of 
which even customize it by defining __new__ and/or __init__. type is also 
special because its power of creation is transitive: its instances know how to 
produce their instances in almost the same way it does.

But nothing of it is mandatory, and in fact it just stands in the way when we 
try to define Enum (or singletons, or database models, or... whatever that is 
not really a Python type). We do inherit from type because it's easier, and 
then usurp and override its __call__ behavior to do something almost entirely 
different. (Don't you feel something is wrong when your __new__ method doesn't 
construct a new object at all?:) It's completely possible, but it's not the 
only way.

Maybe class is just too tainted a keyword. There was a thread on python-ideas, 
that we should have a new keyword, "make". "make m n(...)" would be a clearer 
way to write what's currently written "class n(..., metaclass=m)", with a much 
more prominent position for the metaclass, obviating the need for "just inherit 
from Spam" trick, and dissociating in people's minds the connections of 
arbitrary metaobjects with type. ("class" keyword could be just a shortcut for 
"make type" in that syntax.) But of course, a new keyword is probably too much 
to ask. (A mild effect can be gained by reusing keywords "class" and "from", 
but it looks much less nice.)

However, there is _another_ underused way metaclasses can communicate with the 
external world of users of their instances: keyword arguments. I wonder if 
Raymond's objections would be as strong if the autovivification was explicitly 
documented?

    class Color(Enum, style='declarative'):
        blue
        yellow

Of course we can bikeshed about exact keyword argument names and values, but my 
point is that there is an unused communication channel for converting typical 
Python user's surprise "why does this code even work" into "hey, what does that 
style='declarative' mean?"

----------
nosy: +veky

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue26988>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to