This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: `help` ignores `__doc__` of descriptors
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.6, Python 3.5
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: berker.peksag, cool-RR, iritkatriel, r.david.murray, rhettinger, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2014-10-17 13:15 by cool-RR, last changed 2022-04-11 14:58 by admin. This issue is now closed.

File name Uploaded Description Edit
issue22656.diff berker.peksag, 2016-05-02 12:49 review
Messages (6)
msg229572 - (view) Author: Ram Rachum (cool-RR) * Date: 2014-10-17 13:15
The builtin `property` lets you specify a `doc` argument for your properties, which is great because then it shows up in `help`. So I figured that when I'm writing my own descriptor, I could set `__doc__` on it and have `help` use it. Not so, `help` ignores it. 

See this example:

    class Property(object):
        "Emulate PyProperty_Type() in Objects/descrobject.c"
        def __init__(self, fget=None, fset=None, fdel=None, doc=None):
            self.fget = fget
            self.fset = fset
            self.fdel = fdel
            if doc is None and fget is not None:
                doc = fget.__doc__
            self.__doc__ = doc
        def __get__(self, obj, objtype=None):
            if obj is None:
                return self
            if self.fget is None:
                raise AttributeError("unreadable attribute")
            return self.fget(obj)
        def __set__(self, obj, value):
            if self.fset is None:
                raise AttributeError("can't set attribute")
            self.fset(obj, value)
        def __delete__(self, obj):
            if self.fdel is None:
                raise AttributeError("can't delete attribute")
        def getter(self, fget):
            return type(self)(fget, self.fset, self.fdel, self.__doc__)
        def setter(self, fset):
            return type(self)(self.fget, fset, self.fdel, self.__doc__)
        def deleter(self, fdel):
            return type(self)(self.fget, self.fset, fdel, self.__doc__)
    class A:
        x = property(lambda self: 3,
                     doc='Helpful text')
        y = Property(lambda self: 7,
                     doc='More Helpful text')
    help(A.x) # Shows 'Helpful text'
    help(A.y) # Does not show 'More Helpful text'

It seems that `property` is special-cased or something. I want to be able to set a docstring on my own descriptors.
msg229579 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-10-17 16:27
You might find issue 5890 to be interesting reading.  It's been long enough that I forget the details, but I think the short answer is "yes, property is special cased".   So probably what you want to do is subclass property.

Given the knock-on issue that fix caused, I've always been a little bit uncomfortable with it.  Perhaps you will see a way to generalize things.
msg229604 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2014-10-17 21:07
Yeah, that was interesting. ;)

I think there are two different, yet related, issues:

  - which __doc__ should help display?

  - how should __doc__ be inherited?

The issue we should deal with here is the first, as what help displays does not have to follow the exact same rules as inheritence and magic-method lookup; specifically, help should be free to look for a __doc__ on the instance and incorporate it.
msg264644 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2016-05-02 12:49
The attached patch should solve this. We probably need to add more tests. test_property_subclass depends on issue 24766.
msg407343 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2021-11-30 00:30
I am unable to reproduce the problem on 3.11 (on a Mac). I get both help messages from Ram's code.
msg407347 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2021-11-30 01:22
This was fixed long ago in commit ac4bdcc80e986bdd5b9d10ab0bce35aabb790a3e

The code is in  See issue 25503.
Date User Action Args
2022-04-11 14:58:09adminsetgithub: 66846
2021-11-30 01:22:11rhettingersetstatus: open -> closed

nosy: + rhettinger
messages: + msg407347

resolution: out of date
stage: patch review -> resolved
2021-11-30 00:30:11iritkatrielsetnosy: + iritkatriel
messages: + msg407343
2016-05-02 15:10:39serhiy.storchakasetnosy: + serhiy.storchaka
2016-05-02 12:49:14berker.peksagsetfiles: + issue22656.diff

type: behavior
versions: + Python 3.5, Python 3.6, - Python 3.4
keywords: + patch
nosy: + berker.peksag

messages: + msg264644
stage: patch review
2015-07-21 07:56:45ethan.furmansetnosy: - ethan.furman
2014-10-17 21:07:37ethan.furmansetmessages: + msg229604
2014-10-17 18:04:24ethan.furmansetnosy: + ethan.furman
2014-10-17 16:27:05r.david.murraysetnosy: + r.david.murray
messages: + msg229579
2014-10-17 13:15:04cool-RRcreate