pdoc
pdoc copied to clipboard
Dataclass member documentation issues
Problem Description
When using the @dataclass
decorator from the dataclasses
module, pdoc seems to think that member (instance) variables with default values are actually class variables.
Furthermore, when using the typing.ClassVar
hint, the class variable is not picked up by the parser (unless it has a default, but apparently specifying a default isn't a requirement for the code to run).
Steps to reproduce the behavior:
A minimal example is provided below:
from dataclasses import dataclass
from typing import ClassVar
@dataclass
class Example:
value: float
n: int = 1
m: int = 2
asdf: ClassVar
class OldExample:
n: int = 2
m: int = 2
asdf: ClassVar
def __init__(self):
pass
Generating the documentation gives:
Note that neither
n
nor m
should be shown in the docs for Example
(unless they have docstrings attached, as per the docs), while asdf
should always be shown in the docs as it is a class variable (as specified by its type hint), even if it has no value assigned (the code runs fine as long as one doesn't try to access asdf
).
System Information
pdoc: 12.0.2
Python: 3.9.13
Platform: Linux-5.16.0-1-amd64-x86_64-with-glibc2.33
Hi there!
pdoc seems to think that member (instance) variables with default values are actually class variables.
What would you have expected to happen? From pdoc's perspective (and from Python's perspective) there is no real distinction between instance and class variables, so they all display the same. You can document you intent by using typing.ClassVar
, which should show up in the type annotation.
the class variable is not picked up by the parser
I think this refers to an unrelated issue, namely the rules by which we pick up elements to document. Right now pdoc does not document variables if they only have an annotation but neither a docstring nor a default value (refs #280). I'm open to changes here. I'm not sure if it makes more sense to unconditionally display members in lieu of a docstring (nudging maintainers to add one), or to only display members if they have a docstring.
Hi there!
pdoc seems to think that member (instance) variables with default values are actually class variables.
What would you have expected to happen? From pdoc's perspective (and from Python's perspective) there is no real distinction between instance and class variables, so they all display the same. You can document you intent by using
typing.ClassVar
, which should show up in the type annotation.
I'm expecting that the instance variables of a dataclass
with default values won't be displayed in the docs (unless I document them explicitly, as per the docs), because otherwise they are displayed twice, which is redundant and needlessly clutters the docs (I haven't found a way to remove them from the docs without ugly hacks, such as making the variables private, or rewriting the code so it doesn't use a dataclass
at all).
the class variable is not picked up by the parser
I think this refers to an unrelated issue, namely the rules by which we pick up elements to document. Right now pdoc does not document variables if they only have an annotation but neither a docstring nor a default value (refs #280). I'm open to changes here. I'm not sure if it makes more sense to unconditionally display members in lieu of a docstring (nudging maintainers to add one), or to only display members if they have a docstring.
This is totally fine by me, if someone wishes to document a variable without a default value, they should explicitly specify a docstring, it's the (overzealous) documentation of variables that do have default values (but no docstrings) I have an issue with. The adage "Explicit is better than implicit" should apply in this case IMHO.
Side note: perhaps a new CLI option like --no-implicit-default-values
could be introduced to maintain backwards compatibility? This way, users wanting this feature would need to just change one line in their doc-building scripts, and not touch their existing codebase.
because otherwise they are displayed twice
To clarify: You mean once as part of the constructor and once as a variable?
because otherwise they are displayed twice
To clarify: You mean once as part of the constructor and once as a variable?
Yes.
Any updates on this?
Fixed in #436!