[Python-Dev] PEP 435 -- Adding an Enum type to the Python standard library

Antoine Pitrou solipsis at pitrou.net
Tue Apr 23 16:57:23 CEST 2013


Le Wed, 24 Apr 2013 00:22:40 +1000,
Nick Coghlan <ncoghlan at gmail.com> a écrit :
> 
> Looking at the source
> (https://bazaar.launchpad.net/~barry/flufl.enum/trunk/view/head:/flufl/enum/_enum.py),
> I'm not seeing any fundamental technical issues with merging the Enum
> and EnumValue class definitions, and then using "cls" where the
> metaclass code currently uses "cls.__value_factory__"  (even for the
> backwards compatible variant, the 2v3 metaclass issue isn't a problem,
> you can just define a _BaseEnum class with the right metaclass using
> the 2 & 3 compatible notation and inherit from that in a normal class
> definition)
> 
> However, there's one non-technical aspect of such a merger which does
> concern me, which is the fact that you would lose the distinct
> docstrings for the class and the values:

You can work it around by making __doc__ a descriptor that behaves
differently when called on a class or an instance. There is a slight
metaclass complication because __doc__ is not writable on a class (but
I suppose enums are already using a metaclass, so it's not much of an
issue):


class docwrapper:
    def __init__(self, class_doc, instance_doc_func):
        self.class_doc = class_doc
        self.instance_doc_func = instance_doc_func

    def __get__(self, instance, owner):
        if instance is None:
            return self.class_doc
        else:
            return self.instance_doc_func(instance)

def instancedocwrapper(instance_doc_func):
    class metaclass(type):
        def __new__(meta, name, bases, dct):
            dct['__doc__'] = docwrapper(dct['__doc__'],
                                        instance_doc_func)
            return type.__new__(meta, name, bases, dct)
    return metaclass

class D(metaclass=instancedocwrapper(
           lambda self: "My instance:{}".format(self.x))):
    """My beautiful, documented class."""
    def __init__(self, x):
        self.x = x

class E(D):
    """My magnificent subclass."""

print("class doc:", D.__doc__)
print("subclass doc:", E.__doc__)
print("instance doc:", E(5).__doc__)


Note that the builtin help() function always displays the class's
__doc__, even when called on an instance which has its own __doc__.

Regards

Antoine.




More information about the Python-Dev mailing list