Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to add a doc string to attr.ib #8

Closed
econchick opened this issue Feb 28, 2015 · 12 comments
Closed

Ability to add a doc string to attr.ib #8

econchick opened this issue Feb 28, 2015 · 12 comments

Comments

@econchick
Copy link
Contributor

Current behavior:

In [17]: @attr.s()
   ....: class Bar(object):
   ....:     x = attr.ib()
   ....:

In [18]: b = Bar(x="foo")

In [19]: b.x
Out[19]: 'foo'

In [20]: help(b.x)
no Python documentation found for 'foo'

Desired behavior:

In [17]: @attr.s()
   ....: class Bar(object):
   ....:     x = attr.ib(help="The x of bar")  # or doc="The x of bar" or whatever
   ....:

In [18]: b = Bar(x="foo")

In [19]: b.x
Out[19]: 'foo'

In [20]: help(b.x)
Help on attribute:

    The x of bar

(or something like that)

Similar to doing:

n [21]: class Foo(object):
   ....:     def __init__(self):
   ....:         self._x = None
   ....:     @property
   ....:     def x(self):
   ....:         """The x of Foo"""
   ....:         return self._x
   ....:

In [22]: f = Foo

In [23]: f.x
Out[23]: <property at 0x10a097940>

In [24]: help(f.x)
Help on property:

    The x of Foo
@hynek
Copy link
Member

hynek commented Mar 1, 2015

I’ve played with it a bit but I’m not sure it’s possible when not using properties that are pretty special. :-/ Gotta dig deeper…

@hynek
Copy link
Member

hynek commented Mar 23, 2015

Reading the answers of http://stackoverflow.com/questions/5793306/python-get-doc-documentation-for-instance-variable#5793396 it seems to me that the only reason it work with your properties is they’re methods underneath.

So unless you find a way to add doc strings to data attributes without wrapping them using properties, I’m afraid this is impossible.

@radix
Copy link
Contributor

radix commented Jun 2, 2015

Have you considered appending documentation for attributes to the class's docstring? Or the __init__ docstring?

One other thing I noticed is that if you set default to an attr.Factory, sphinx shows the default as NOTHING which is slightly misleading (the reader would have to look down to the class attribute showing the Attribute instance, which will be unfamiliar to most people).

@hynek
Copy link
Member

hynek commented Jun 3, 2015

does that work? care to provide a PR/PoC? 😇

@radix
Copy link
Contributor

radix commented Jun 3, 2015

I've actually just started documenting the attributes as :param: in the class docstring, which sphinx renders pretty nicely: http://effect.readthedocs.org/en/latest/apidocs.html#effect.Effect

This seems like probably the best solution, since if attrs were to modify the docstring, it'd have to assume a documentation format, which may be wrong (e.g. older projects still use epytext).

@hynek
Copy link
Member

hynek commented Jun 3, 2015

Yes, that’s why my init has no docstring. I removed it on Lynn’s request for this very reason. :)

@Delengowski
Copy link

Delengowski commented Jan 1, 2021

Reading the answers of http://stackoverflow.com/questions/5793306/python-get-doc-documentation-for-instance-variable#5793396 it seems to me that the only reason it work with your properties is they’re methods underneath.

So unless you find a way to add doc strings to data attributes without wrapping them using properties, I’m afraid this is impossible.

You can add docstrings using descriptors.

I suppose that's not different enough from properties though?

class Descriptor:

   def __init__(self, doc_str):
       self.__doc__ = doc_str

   def __set_name__(self, owner, attr):
       self.attr = attr

   def __get__(self, instance, inst_type):
       return getattr(instance, f"_{self.attr}")

   def __set__(self, instance, value):
        setattr(instance, f"_{self.attr}", value)

class Foo:
   bar = Descriptor("Example Docstring")

foo = Foo()

help(foo)

You'll have to excuse me as I just discovered your library after trying out dataclasses for the first time. I was adding my own validators and docstrings to dataclass fields using descriptors. Then someone told me about attrs :)

Edit: I suppose what I did is not exactly what OP is doing.

@bwoodsend
Copy link

bwoodsend commented Mar 19, 2021

This is semi-possible now because of the auto_attribs option. With it you can just put the docstring beneath the attribute declaration:

@attr.s(auto_attribs=True)
class SomeClass:
    a_number: int = 42
    """Something descriptive about ``a_number``."""

It's still ignored by Python so help(SomeClass.a_number) doesn't work (in this case it'll just run help(42)) but Sphinx picks it up happily enough which was my main motivation for landing on this page.

@relativistic
Copy link

Somehow param does this. See the "doc" keyword: https://param.holoviz.org/user_guide/Parameters.html#parameter-metadata

@hynek
Copy link
Member

hynek commented Nov 24, 2021

Somehow param does this. See the "doc" keyword: https://param.holoviz.org/user_guide/Parameters.html#parameter-metadata

If I read the docs correctly, it just appends a doc attribute to the params. It doesn't sound like it would work with help etc.


And since it came up the other day on StackOverflow to reinforce: the canonical way of documenting attributes of a class in Python is currently in the __init__ docstring. Until a new standard emerges, attrs is following 100% the community ways.

@cjw296
Copy link

cjw296 commented May 27, 2022

@hynek - what's the best way to specify the doc/help for a particular attribute when using @define and new-style type annotation/etc interface that ends up being in the __init__ docstring in the way you describe?

My specific use case is trying to get this somewhere better:

    time_limit: int = None  # in minutes

@hynek
Copy link
Member

hynek commented May 28, 2022

There is none; the community way is to put all your docs into the class docstring by hand. Adding templating magic would list likely break along the various consumers of it. 😐

To be fair, there's no boilerplate of repetition. It's just about the position where you put your docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants