classification
Title: unable to document fields of dataclass
Type: enhancement Stage: test needed
Components: Versions: Python 3.10
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: eric.smith Nosy List: eric.smith, jmg, rhettinger, terry.reedy
Priority: normal Keywords:

Created on 2020-11-19 20:36 by jmg, last changed 2020-11-21 03:50 by terry.reedy.

Messages (6)
msg381455 - (view) Author: John-Mark Gurney (jmg) Date: 2020-11-19 20:36
per: https://bugs.python.org/issue38401

There is not a way to document fields of a dataclass.

I propose that instead of making a language change, that an additional parameter to the field be added in similar vein to property.

This currently works:
```
class Foo:
 def getx(self):
  return 5
 x = property(getx, doc='document the x property')
```

So, I propose this:
```
@dataclass
class Bar:
 x : int = field(doc='document what x is')
```

This should be easy to support as I believe that the above would not require any changes to the core language.
msg381486 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2020-11-20 15:57
How would you expect to extract this docstring?

I'm not sure how this would work in practice, since both of these are errors:

>>> class A:
...    def __init__(self):
...        self.x = 3
...        self.x.__doc__ = 'foo'
...
>>> A()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __init__
AttributeError: 'int' object attribute '__doc__' is read-only
>>> class B:
...    x: int = 0
...    x.__doc__ = 'foo'
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in B
AttributeError: 'int' object attribute '__doc__' is read-only

It could be stored in the dataclass-specific data attached to a class, but then you'd have to use a dataclass-specific function to get access to it. I'm not sure that's a great improvement.

I also note that attrs doesn't have this feature, probably for the same reason.
msg381492 - (view) Author: John-Mark Gurney (jmg) Date: 2020-11-20 18:18
As I said, I expect it to work similar to how property works:
```
>>> class Foo:
...  def getx(self):
...   return 5
...  x = property(getx, doc='document the x property')
... 
>>> help(Foo)
Help on class Foo in module __main__:

class Foo(builtins.object)
 |  Methods defined here:
 |  
 |  getx(self)
 |  
 |  ----------------------------------------------------------------------
 |  Readonly properties defined here:
 |  
 |  x
 |      document the x property
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)
```

The pure python implementation of property is at: https://docs.python.org/3/howto/descriptor.html#properties

which uses the descriptor protocal as documented in: https://docs.python.org/3/howto/descriptor.html

Which uses an object w/ __get__/__set__/__delete__ to emulate attribute access, and that object can have the __doc__ property set on it to provide documentation.
msg381503 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2020-11-20 20:09
@property has a place to attach the docstring, dataclasses in general do not. I wouldn't want to add a descriptor just to have the ability to add a docstring. There are performance issues involved, and I'm sure some corner cases where functionality would change.

Maybe if you bring this up on python-ideas you can get some more ideas.
msg381515 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2020-11-21 01:24
> There is not a way to document fields of a dataclass.

I don't think there is an easy way to do this without a custom descriptor and that would add a lot of overhead.
msg381521 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2020-11-21 03:50
Documenting dataclass fields strikes me as a reasonable request.  Since most most field values cannot have a  .__doc__ attribute...

> It could be stored in the dataclass-specific data attached to a class, 

The obvious place.

> but then you'd have to use a dataclass-specific function to get access to it. 

There are already at least 2 functions for getting docstrings for objects without .__doc__.  They could be enhanced with a dataclass-specific clause.

If ob.__doc__ is None, inspect.getdoc(ob) looks for a docstring elsewhere and sometimes succeeds.  For this reason, I just changed IDLE calltips to use getdoc for calltips.  If dataclasses.is_dataclass(ob.__class__), then I presume getdoc could retrieve the docstring from ob.__class__.__dataclass_fields__.

help(ob) uses pydoc, which gets docstrings with _getowndoc and if needed, _finddoc.  Perhaps these should be replaced with inspect.getdoc, but until then, _finddoc could have an elif clause added for dataclass fields.
History
Date User Action Args
2020-11-21 03:50:02terry.reedysetnosy: + terry.reedy

messages: + msg381521
stage: test needed
2020-11-21 01:24:37rhettingersetnosy: + rhettinger
messages: + msg381515
2020-11-20 20:09:34eric.smithsetmessages: + msg381503
2020-11-20 18:18:30jmgsetmessages: + msg381492
2020-11-20 15:57:14eric.smithsettype: enhancement
messages: + msg381486
versions: + Python 3.10
2020-11-20 06:59:09eric.smithsetassignee: eric.smith
2020-11-20 02:29:00xtreaksetnosy: + eric.smith
2020-11-19 20:36:18jmgcreate