classification
Title: allow Python code to determine class help text
Type: behavior Stage:
Components: Argument Clinic Versions: Python 3.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: ethan.furman, larry, ncoghlan, rhettinger, serhiy.storchaka, xiang.zhang, yselivanov
Priority: normal Keywords:

Created on 2017-01-24 18:06 by ethan.furman, last changed 2017-01-24 20:27 by ethan.furman.

Messages (6)
msg286199 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2017-01-24 18:06
From issue29338, msg286139:
--------------------------
It is easy to fix the [pydoc] test by adding missed lines. But I'm not sure that output the (correct) signature of enum classes makes the help better.

    Color(value, names=None, *, module=None, qualname=None, type=None, start=1)

Ethan, what are your thoughts?
msg286200 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2017-01-24 18:08
That that is very unhelpful help text.  :(

Better would be:

    Color(value)

So how do we allow Python code to determine the help text?
msg286202 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-01-24 18:40
This line is came from the signature of the __call__ method.

>>> import enum, inspect
>>> class A(enum.Enum):
...    x = 1
... 
>>> inspect.signature(A)
<Signature (value, names=None, *, module=None, qualname=None, type=None, start=1)>
>>> inspect.signature(A.__call__)
<Signature (value, names=None, *, module=None, qualname=None, type=None, start=1)>
>>> inspect.signature(enum.EnumMeta.__call__)
<Signature (cls, value, names=None, *, module=None, qualname=None, type=None, start=1)>

But calling A with optional arguments doesn't work.

>>> A(1)
<A.x: 1>
>>> A('B', {'y': 2})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/serhiy/py/cpython/Lib/enum.py", line 293, in __call__
    return cls._create_(value, names, module=module, qualname=qualname, type=type, start=start)
  File "/home/serhiy/py/cpython/Lib/enum.py", line 378, in _create_
    _, first_enum = cls._get_mixins_(bases)
  File "/home/serhiy/py/cpython/Lib/enum.py", line 436, in _get_mixins_
    raise TypeError("Cannot extend enumerations")
TypeError: Cannot extend enumerations
msg286210 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2017-01-24 19:43
There are actually two signatures:

EnumCls(value) --> return member with value `value`

EnumCls(name, members, module, qualname, type, start) --> create new Enum

An example of the first:

class A(Enum):
    x = 1
A(1) --> <A.x: 1>

an example of the second:

class A(Enum):
    pass
B = A('B', {'y':2})
B(2) --> <B.y: 2>

The reason for the error you see is that Enums with members cannot be further subclassed.
msg286211 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-01-24 19:48
I'm wondering is it worth to set different __call__ methods for enum types with and without members?
msg286214 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2017-01-24 20:27
Probably not because an enum class' __call__ comes from the type EnumMeta -- so having two different __call__ methods would mean two different metaclasses, and I'm pretty sure I don't want to go there.  ;)

There is a __doc__ defined for the __call__ method, though -- is there a reason inspect isn't using that?
History
Date User Action Args
2017-01-24 20:27:11ethan.furmansetmessages: + msg286214
2017-01-24 19:48:49serhiy.storchakasetmessages: + msg286211
2017-01-24 19:43:24ethan.furmansetmessages: + msg286210
2017-01-24 18:40:07serhiy.storchakasetmessages: + msg286202
2017-01-24 18:08:21ethan.furmansetmessages: + msg286200
2017-01-24 18:06:33ethan.furmancreate