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

autodoc: fix detection of class methods implemented by extension modules #13200

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

picnixz
Copy link
Member

@picnixz picnixz commented Jan 1, 2025

Closes #13188.

cc @skirpichev

@AA-Turner do we have tests for this? I tested it locally but I'm not sure we're building a C extension module in Sphinx to test this.

@skirpichev
Copy link
Contributor

Works.

@picnixz picnixz requested a review from AA-Turner January 1, 2025 10:05
@picnixz
Copy link
Member Author

picnixz commented Jan 1, 2025

Btw, I'm not sure if this is something CPython wants to improve by adding some inspect.isclassmethod since isinstance(m, staticmethod) works both for @staticmethod in Python and METH_STATIC in C, but isinstance(m, classmethod) is only for @classmethod in Python (we need isinstance(m, types.ClassMethodDescriptorType) for those in C).

@skirpichev
Copy link
Contributor

I'm not sure we're building a C extension module in Sphinx to test this.

Can't you use CPython builtin classes (e.g. int) to test this?

BTW, there is no "official" way to describe signatures for extensions. The gmp module (as many CPython builtins) uses funny notation in __text_signature__, the gmpy2 module instead just uses PEP 7 -style "signature lines" in docstrings (currently classmethods displayed here incorrectly too: https://gmpy2.readthedocs.io/en/latest/mpz.html#gmpy2.mpz.from_bytes). The inspect module doesn't work in that case.

@picnixz
Copy link
Member Author

picnixz commented Jan 2, 2025

I can use built-in classes but I wanted some complex inheritance just in case. I guess I can write some tests with what I have already in hand though.

@skirpichev
Copy link
Contributor

I can use built-in classes but I wanted some complex inheritance just in case.

IIRC, multiple inheritance does not work for statically defined types.

@picnixz
Copy link
Member Author

picnixz commented Jan 2, 2025

Oh I see. Though, I thought about inheriting (in pure Python) from my custom built-in class just to check that we correctly pick up something written in C as well. What I didn't want to do is use a built-in whose signature rendering may change across versions for various reasons. It makes tests harder to maintain (something that usually happens for enums in general...)

# Conflicts:
#	CHANGES.rst
#	sphinx/ext/autodoc/__init__.py
@AA-Turner
Copy link
Member

I agree with Sergey that using e.g. int.from_bytes or a similar builtin classmethod descriptor would be good. We don't currently have any test infrastructure to build a C extension module.

A

@AA-Turner AA-Turner added this to the 8.2.0 milestone Jan 3, 2025
sphinx/util/inspect.py Outdated Show resolved Hide resolved
@picnixz picnixz requested a review from AA-Turner January 3, 2025 17:26
sphinx/util/inspect.py Outdated Show resolved Hide resolved
sphinx/util/inspect.py Outdated Show resolved Hide resolved
sphinx/util/inspect.py Outdated Show resolved Hide resolved
picnixz and others added 2 commits January 3, 2025 22:30
for basecls in getmro(cls):
meth = basecls.__dict__.get(name, sentinel)
if meth is not sentinel:
return is_builtin_classmethod(meth)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this still need to recurse? I'd prefer being explicit here (even if duplicative):

Suggested change
return is_builtin_classmethod(meth)
return is_classmethod_descriptor(obj, cls, name) or (
isbuiltin(obj)
and getattr(obj, '__self__', None) is not None
and isclass(obj.__self__)
)

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.

autodoc incorrectly displays class methods for builtin types
3 participants