On Wed, May 1, 2013 at 10:48 AM, Guido van Rossum
On Wed, May 1, 2013 at 10:21 AM, Ethan Furman
wrote: We may not want to /completely/ disallow subclassing. Consider:
--> class StrEnum(str, Enum): ... '''string enums for Business Basic variable names''' ... --> class Vendors(StrEnum): EnumError: subclassing not allowed
My point is that IntEnum, StrEnum, ListEnum, FloatEnum are all "subclasses" of Enum. To then have a subclass of that, such as Season(StrEnum), is subclassing a subclass.
True, and Enum itself also falls in this category. Maybe there could be a special marker that you have to set in the class body (or a keyword arg in the class statement) to flag that a class is meant as a "category of enums" rather than a specific enum type. Such categorical classes should not define any instances. (And maybe "defines no instances" is enough to flag an Enum class as subclassable.)
Now, if we do want to completely disallow it, we can ditch IntEnum and force the user to always specify the mixin type:
--> class Season(str, Enum): . . .
--> class Names(str, Enum): . . .
But that's not very user friendly... although it's not too bad, either.
Indeed, given that we mostly want IntEnum as a last-resort backward compatibility thing for os and socket, it may not be so bad.
Actually, in flufl.enum, IntEnum had to define a magic __value_factory__ attribute, but in the current ref435 implementation this isn't needed, so IntEnum is just: class IntEnum(int, Enum): ''' Class where every instance is a subclass of int. ''' So why don't we just drop IntEnum from the API and tell users they should do the above explicitly, i.e.: class SocketFamily(int, Enum): AF_UNIX = 1 AF_INET = 2 As opposed to having an IntEnum explicitly, this just saves 2 characters (comma+space), but is more explicit (zen!) and helps us avoid the special-casing the subclass restriction implementation. Eli