[Python-Dev] Enum: subclassing?

Guido van Rossum guido at python.org
Wed May 1 19:48:45 CEST 2013


On Wed, May 1, 2013 at 10:21 AM, Ethan Furman <ethan at stoneleaf.us> 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.

> One consequence of the way it is now (IntEnum, StrEnum, etc., are allowed)
> is that one can put methods and other non-Enum item in a base class and then
> inherit from that for actual implemented Enum classes.
>
> --> class StrEnum(str, Enum):
> ...     def describe(self):
> ...         print("Hi!  I'm a %s widget!" % self.value)
> ...
>
> --> class Season(StrEnum):
> ...     spring = 'green'
> ...     summer = 'brown'
> ...     autumn = 'red'
> ...     winter = 'white'
> ...
>
> --> class Planet(StrEnum):
> ...     mars = 'red'
> ...     earth = 'blue'
> ...
>
> --> Season.summer.descripbe()
> Hi!  I'm a brown widget!
>
> --> Planet.earth.describe()
> Hi!  I'm a blue widget!

If the base class doesn't define any instances (and perhaps is marked
specifically for this purpose) I'm fine with that.

--
--Guido van Rossum (python.org/~guido)


More information about the Python-Dev mailing list