inheriting docstrings and mutable docstings for classes

I noticed that __doc__ for classes is immutable:
That is on 3.3, but apparently it's the case all the way back to 2.2. I mentioned this on python-list and several people indicated that it should be an unnecessary restriction [1]. Someone else pointed out that docstrings also behave this way for method objects [2]. I want too see if it would be okay to make __doc__ writable for classes. I am not sure about for method objects, since I've never thought to do that, but it is analogous to class instances, where __doc__ is mutable and distinct from the class docstring. I just don't have any use cases that would dictate changing the docstring of the method object, the wrapped function, or neither when changing __doc__. Someone else on the thread indicated that perhaps docstrings should be inherited and got some support [3][4]. It makes sense to me for many, but not necessarily all, cases. However, if you don't want to inherit you can simply set an empty docstring. Docstrings impact help(), doctests, and some DSLs. I'm +1 on having __doc__ be inherited. Thanks, -eric [1] http://mail.python.org/pipermail/python-list/2011-June/1274079.html [2] http://mail.python.org/pipermail/python-list/2011-June/1274080.html [3] http://mail.python.org/pipermail/python-list/2011-June/1274099.html [4] http://mail.python.org/pipermail/python-list/2011-June/1274105.html

On Fri, Jun 10, 2011 at 9:54 AM, Eric Snow <ericsnowcurrently@gmail.com> wrote:
I'm +1 on having __doc__ be inherited.
-1. Subclasses are not the same thing as the original class so docstring inheritance should be requested explicitly. Agreed that docstrings should be writeable after the fact, though (e.g. functions already work that way - functools.wraps wouldn't work otherwise). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Thu, Jun 9, 2011 at 7:05 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
Yeah, this one was mostly auxiliary to my main concern, __doc__ mutability for classes. Other than doctests and documentation/help(), I haven't used docstrings for much so the idea of it did not seem like a big deal. I certainly find myself inheriting docstrings from my abstract base classes explicitly all the time so that help() will show the info that is still applicable.
Would this be a very controversial change? I ask because it's been this way since 2.2 and no one's changed it. Thanks. -eric

On Fri, Jun 10, 2011 at 11:45 AM, Eric Snow <ericsnowcurrently@gmail.com> wrote:
More likely a matter of nobody needing the functionality enough to question the behaviour (there are a variety of arbitrary restrictions still floating around that don't really have a *reason*, it's just that it was easier to do it that way initially and nobody has cared enough to change it). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

Nick Coghlan wrote:
-1. Subclasses are not the same thing as the original class so docstring inheritance should be requested explicitly.
The docstring of the class itself probably shouldn't be inherited automatically. But if you override a method without changing the API or user-visible behaviour, the inherited docstring still applies. Maybe the best thing would be for the inherited docstring to get put into a different property, such as __basedoc__. Then tools that examine docstrings can decide for themselves whether using inherited docstrings makes sense. -- Greg

On Fri, Jun 10, 2011 at 5:04 PM, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
I believe Eric created a class decorator recipe on the cookbook site that does exactly that for methods without their own docstrings. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On 10 June 2011 08:04, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote: [...]
Given that Python supports multiple inheritance, which parent class's __doc__ would the __basedoc__ contain? Also, what would the __basedoc__ contain if the parent's __doc__ is empty but not its __basedoc__? -- Arnaud

On Fri, Jun 10, 2011 at 3:28 AM, Arnaud Delobelle <arnodel@gmail.com> wrote:
You would not need a __basedoc__ magic attribute, you can just do class C(object): pass docs = [c.__doc__ for c in C.__mro__] and you get the docs for all bases in the proper mro order Though I guess __basedocs__ mapping to [c.__doc__ for c in C.__mro__ if c != C] could be handy

On Fri, Jun 10, 2011 at 3:04 AM, Greg Ewing <greg.ewing@canterbury.ac.nz>wrote:
How would a tool know if the behavior of a method changed without analyzing the code? I think this could very easily lead to a situation where a project's generated documentation is incorrect. -- David blog: http://www.traceback.org twitter: http://twitter.com/dstanek www: http://dstanek.com

David Stanek wrote:
That's the developer's problem, and no different from any other case where you inherit data without ensuring it is the correct data. class Parrot: colour = 'green' def speak(self): return "Polly wants a cracker." class NorwegianBlue(Parrot): def speak(self): return "I'm pining for the fjords." assert NorwegianBlue().colour == 'blue' # oops! -- Steven

On Fri, Jun 10, 2011 at 7:22 AM, Steven D'Aprano <steve@pearwood.info>wrote:
This means that a significant amount of existing code may/will have problems with this type of change. If Sphinx did this automatically I'm sure there would be lots of incorrect documentation. I think the developer should explicitly carry over and modify the documentation if necessary. -- David blog: http://www.traceback.org twitter: http://twitter.com/dstanek www: http://dstanek.com

David Stanek wrote:
Oh, I'm sorry if I gave the impression that we should inherit docstrings by default. That wasn't my intention. I was merely suggesting that we shouldn't let the risk of misuse discourage us from a potential change. -- Steven

On Fri, Jun 10, 2011 at 9:54 AM, Eric Snow <ericsnowcurrently@gmail.com> wrote:
I'm +1 on having __doc__ be inherited.
-1. Subclasses are not the same thing as the original class so docstring inheritance should be requested explicitly. Agreed that docstrings should be writeable after the fact, though (e.g. functions already work that way - functools.wraps wouldn't work otherwise). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Thu, Jun 9, 2011 at 7:05 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
Yeah, this one was mostly auxiliary to my main concern, __doc__ mutability for classes. Other than doctests and documentation/help(), I haven't used docstrings for much so the idea of it did not seem like a big deal. I certainly find myself inheriting docstrings from my abstract base classes explicitly all the time so that help() will show the info that is still applicable.
Would this be a very controversial change? I ask because it's been this way since 2.2 and no one's changed it. Thanks. -eric

On Fri, Jun 10, 2011 at 11:45 AM, Eric Snow <ericsnowcurrently@gmail.com> wrote:
More likely a matter of nobody needing the functionality enough to question the behaviour (there are a variety of arbitrary restrictions still floating around that don't really have a *reason*, it's just that it was easier to do it that way initially and nobody has cared enough to change it). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

Nick Coghlan wrote:
-1. Subclasses are not the same thing as the original class so docstring inheritance should be requested explicitly.
The docstring of the class itself probably shouldn't be inherited automatically. But if you override a method without changing the API or user-visible behaviour, the inherited docstring still applies. Maybe the best thing would be for the inherited docstring to get put into a different property, such as __basedoc__. Then tools that examine docstrings can decide for themselves whether using inherited docstrings makes sense. -- Greg

On Fri, Jun 10, 2011 at 5:04 PM, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
I believe Eric created a class decorator recipe on the cookbook site that does exactly that for methods without their own docstrings. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On 10 June 2011 08:04, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote: [...]
Given that Python supports multiple inheritance, which parent class's __doc__ would the __basedoc__ contain? Also, what would the __basedoc__ contain if the parent's __doc__ is empty but not its __basedoc__? -- Arnaud

On Fri, Jun 10, 2011 at 3:28 AM, Arnaud Delobelle <arnodel@gmail.com> wrote:
You would not need a __basedoc__ magic attribute, you can just do class C(object): pass docs = [c.__doc__ for c in C.__mro__] and you get the docs for all bases in the proper mro order Though I guess __basedocs__ mapping to [c.__doc__ for c in C.__mro__ if c != C] could be handy

On Fri, Jun 10, 2011 at 3:04 AM, Greg Ewing <greg.ewing@canterbury.ac.nz>wrote:
How would a tool know if the behavior of a method changed without analyzing the code? I think this could very easily lead to a situation where a project's generated documentation is incorrect. -- David blog: http://www.traceback.org twitter: http://twitter.com/dstanek www: http://dstanek.com

David Stanek wrote:
That's the developer's problem, and no different from any other case where you inherit data without ensuring it is the correct data. class Parrot: colour = 'green' def speak(self): return "Polly wants a cracker." class NorwegianBlue(Parrot): def speak(self): return "I'm pining for the fjords." assert NorwegianBlue().colour == 'blue' # oops! -- Steven

On Fri, Jun 10, 2011 at 7:22 AM, Steven D'Aprano <steve@pearwood.info>wrote:
This means that a significant amount of existing code may/will have problems with this type of change. If Sphinx did this automatically I'm sure there would be lots of incorrect documentation. I think the developer should explicitly carry over and modify the documentation if necessary. -- David blog: http://www.traceback.org twitter: http://twitter.com/dstanek www: http://dstanek.com

David Stanek wrote:
Oh, I'm sorry if I gave the impression that we should inherit docstrings by default. That wasn't my intention. I was merely suggesting that we shouldn't let the risk of misuse discourage us from a potential change. -- Steven
participants (7)
-
Arnaud Delobelle
-
David Stanek
-
Dj Gilcrease
-
Eric Snow
-
Greg Ewing
-
Nick Coghlan
-
Steven D'Aprano