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

bpo-38603: Inherit docstrings in dynamically generated subclasses if possible #16957

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

anntzer
Copy link
Contributor

@anntzer anntzer commented Oct 27, 2019

Currently, inspect.getdoc() fails to inherit docstrings in dynamically
generated subclasses, such as

class Base:
    def method(self): "some docstring"

def make_subclass():
    class subclass(Base):
        def method(self): return super().method()
    return subclass

subclass = make_subclass()
inspect.getdoc(subclass.method)  # => returns None

because inspect._findclass() tries to find the base
class by parsing subclass.method.__qualname__ which is
"make_subclass.<locals>.subclass.method" and chokes over
.<locals>..

In the case where the method does rely on super(), there is another
way we can go back to the "owning" class of the method: by looking up
the contents of the __class__ cell (which is set up to make 0-arg
super()). This approach is implemented by this PR.

Perhaps a __class__ cell could even be set up (in a separate patch)
for all methods defined in dynamically created subclasses (i.e. whose
__qualname__ includes .<locals>.), to help with introspection?

https://bugs.python.org/issue38603

Copy link
Sponsor Member

@isidentical isidentical left a comment

Can you add a news entry

…possible.

Currently, `inspect.getdoc()` fails to inherit docstrings in dynamically
generated subclasses, such as
```
class Base:
    def method(self): "some docstring"

def make_subclass():
    class subclass(Base):
        def method(self): return super().method()
    return subclass

subclass = make_subclass()
inspect.getdoc(subclass.method)  # => returns None
```
because `inspect._findclass()` tries to find the base
class by parsing `subclass.method.__qualname__` which is
`"make_subclass.<locals>.subclass.method"` and chokes over
`.<locals>.`.

In the case where the method does rely on `super()`, there is another
way we can go back to the "owning" class of the method: by looking up
the contents of the `__class__` cell (which is set up to make 0-arg
super()).  This approach is implemented by this PR.

Perhaps a `__class__` cell could even be set up (in a separate patch)
for *all* methods defined in dynamically created subclasses (i.e. whose
`__qualname__` includes `.<locals>.`), to help with introspection?
@anntzer anntzer force-pushed the getdoc-dynamic-subclass branch from 404ab04 to 58daf31 Compare Nov 24, 2019
@anntzer
Copy link
Contributor Author

anntzer commented Nov 24, 2019

done

@csabella csabella requested a review from 1st1 Jun 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants