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
Fix #7422: autodoc: fails with ValueError when using autodoc_mock_imports #7431
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -17,7 +17,7 @@ | |||||||
import warnings | ||||||||
from functools import partial, partialmethod | ||||||||
from inspect import ( # NOQA | ||||||||
Parameter, isclass, ismethod, ismethoddescriptor, unwrap | ||||||||
Parameter, isclass, ismethod, ismethoddescriptor | ||||||||
) | ||||||||
from io import StringIO | ||||||||
from typing import Any, Callable, Mapping, List, Tuple | ||||||||
|
@@ -116,6 +116,15 @@ def getargspec(func: Callable) -> Any: | |||||||
kwonlyargs, kwdefaults, annotations) | ||||||||
|
||||||||
|
||||||||
def unwrap(obj: Any) -> Any: | ||||||||
"""Get an original object from wrapped object (wrapped functions).""" | ||||||||
try: | ||||||||
return inspect.unwrap(obj) | ||||||||
except ValueError: | ||||||||
# might be a mock object | ||||||||
return obj | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tk0miya this looks good, but maybe log DEBUG/INFO?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I doubt the log will be helpful. Do you want to see it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine not seeing it, I was just thinking it could be useful if you were already debugging. |
||||||||
|
||||||||
|
||||||||
def unwrap_all(obj: Any) -> Any: | ||||||||
""" | ||||||||
Get an original object from wrapped object (unwrapping partials, wrapped | ||||||||
|
@@ -217,7 +226,7 @@ def isattributedescriptor(obj: Any) -> bool: | |||||||
return True | ||||||||
elif isdescriptor(obj): | ||||||||
# non data descriptor | ||||||||
unwrapped = inspect.unwrap(obj) | ||||||||
unwrapped = unwrap(obj) | ||||||||
if isfunction(unwrapped) or isbuiltin(unwrapped) or inspect.ismethod(unwrapped): | ||||||||
# attribute must not be either function, builtin and method | ||||||||
return False | ||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about providing some callback to
unwrap
to check if wrapped object (if there is any) id is equal to the object itself. Like (based on https://github.com/python/cpython/blob/master/Lib/inspect.py#L509):I guess that you may get
ValueError
for an object that is not mock and miss the real error.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JanuszL
ValueError
is being thrown from https://github.com/python/cpython/blob/master/Lib/inspect.py#L524 and it's catching exactly the error you're looking for this to catch.see: https://github.com/python/cpython/blob/master/Lib/inspect.py#L506
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, ValueError means "a cycle is encountered". It's a real error in this case. I think it is an abnormal case. So let's talk if we encountered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I was only thinking about the situation where the cycle is encountered and this is not due to mocking. In such a case it should really throw, so maybe there is an easier way to check if this is a moc or some valid object.