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-44904: Fix classmethod property bug in doctest module #28838

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

@AlexWaygood
Copy link
Contributor

@AlexWaygood AlexWaygood commented Oct 9, 2021

The doctest module raised an error if a docstring contained an example that
attempted to access a classmethod property. (Stacking @classmethod on top of
@property has been supported since Python 3.9; see
https://docs.python.org/3/howto/descriptor.html#class-methods.)

https://bugs.python.org/issue44904

The doctest module raised an error if a docstring contained an example that
attempted to access a classmethod property. (Stacking '@classmethod' on top of
`@property` has been supported since Python 3.9; see
https://docs.python.org/3/howto/descriptor.html#class-methods.)
@AlexWaygood AlexWaygood changed the title bpo 44904: Fix classmethod property bug in doctest module bpo-44904: Fix classmethod property bug in doctest module Oct 9, 2021
@corona10 corona10 requested a review from serhiy-storchaka Oct 10, 2021
Lib/doctest.py Outdated
@@ -1037,7 +1037,9 @@ def _find(self, tests, obj, name, module, source_lines, globs, seen):
if isinstance(val, staticmethod):
val = getattr(obj, valname)
if isinstance(val, classmethod):
val = getattr(obj, valname).__func__
# Lookup via __dict__ instead of getattr
Copy link
Contributor

@rhettinger rhettinger Oct 10, 2021

This PR should not go forward until issue 45356 is resolved. Wrapping classmethod around property seems to have some intrinsic flaws that shouldn't be papered over.

Also, when replacing getattr with a dict lookup, we need to consider whether the entire __mro__ should be searched.

Lastly, any "solution" to this or the help() bug should probably share a standardized solution, perhaps some variant of hasattr() that doesn't have the __getattr__ hook and that doesn't trigger descriptor behavior.

Copy link
Contributor Author

@AlexWaygood AlexWaygood Oct 10, 2021

This all makes sense. Thanks for taking a look, anyhow!

Copy link
Member

@serhiy-storchaka serhiy-storchaka Oct 10, 2021

__mro__ is not related here. We iterate the class' __dict__ and look at methods defined in the class.

@bedevere-bot
Copy link

@bedevere-bot bedevere-bot commented Oct 10, 2021

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Lib/doctest.py Outdated Show resolved Hide resolved
Lib/doctest.py Outdated
@@ -1037,7 +1037,9 @@ def _find(self, tests, obj, name, module, source_lines, globs, seen):
if isinstance(val, staticmethod):
val = getattr(obj, valname)
if isinstance(val, classmethod):
val = getattr(obj, valname).__func__
# Lookup via __dict__ instead of getattr
Copy link
Member

@serhiy-storchaka serhiy-storchaka Oct 10, 2021

__mro__ is not related here. We iterate the class' __dict__ and look at methods defined in the class.

@serhiy-storchaka
Copy link
Member

@serhiy-storchaka serhiy-storchaka commented Oct 12, 2021

@rhettinger, I am going to merge this issue. Do you still have objections?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment