-
-
Notifications
You must be signed in to change notification settings - Fork 31.4k
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-19903: IDLE: Change to inspect.signature for calltips #1382
Conversation
This commit change the get_argspec from using inspect.getfullargspec to inspect.signature. It will improve the tip message for use. Also, if object is not callable, now will return this message for user, not blank tips. If the methods has an invalid method signature, it will also return message to user.
@lulouie, thanks for your PR! By analyzing the history of the files in this pull request, we identified @terryjreedy, @kbkaiser and @serhiy-storchaka to be potential reviewers. |
Lib/idlelib/calltips.py
Outdated
@@ -136,6 +136,9 @@ def get_argspec(ob): | |||
argspec = "" | |||
try: | |||
ob_call = ob.__call__ | |||
except AttributeError: |
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.
Could you left this change for separate issue?
Lib/idlelib/calltips.py
Outdated
if (isinstance(ob, (type, types.MethodType)) or | ||
isinstance(ob_call, types.MethodType)): | ||
argspec = _first_param.sub("", argspec) | ||
if argspec.startswith("(self,"): |
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.
What if the first parameter have a different name?
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, you are right. I'll still need to figure out how it does different from getfullargspec
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.
Find out that signature
will deal correctly with MethodType, but will not handle __init__
correctly.
Fix the condition of trim first param.
@serhiy-storchaka @terryjreedy Also add the test for first param not |
c = C() | ||
for meth, mtip in ((C.m1, '(*args)'), (c.m1, "(*args)"), | ||
(C.m2, "(**kwds)"), (c.m2, "(**kwds)"),): |
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.
Remove invalid method signature, move to test_invalid_method_signature
|
||
mtip = "This function has an invalid method signature" | ||
self.assertEqual(signature(C().m2), mtip) | ||
self.assertEqual(signature(Test()), mtip) |
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.
This test borrow from test_signature
@@ -156,17 +164,22 @@ def test_attribute_exception(self): | |||
class NoCall: | |||
def __getattr__(self, name): | |||
raise BaseException | |||
class Call(NoCall): | |||
class CallA(NoCall): | |||
def __call__(oui, a, b, c): |
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.
Add corner case for first param not self
self.assertEqual(signature(meth), mtip) | ||
|
||
def test_non_callables(self): | ||
for obj in (0, 0.0, '0', b'0', [], {}): | ||
self.assertEqual(signature(obj), '') | ||
|
||
|
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.
PEP8
Lib/idlelib/calltips.py
Outdated
@@ -145,10 +148,16 @@ def get_argspec(ob): | |||
else: | |||
fob = ob | |||
if isinstance(fob, (types.FunctionType, types.MethodType)): |
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.
Remove and dedent block.
Lib/idlelib/calltips.py
Outdated
argspec = inspect.formatargspec(*inspect.getfullargspec(fob)) | ||
try: | ||
argspec = str(inspect.signature(fob)) | ||
except ValueError: |
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.
Must get and test error message.
Lib/idlelib/calltips.py
Outdated
try: | ||
argspec = str(inspect.signature(fob)) | ||
except ValueError: | ||
argspec = "This function has an invalid method signature" |
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.
Add _invalid_signature to global defs before function so can access for testing without repeating string.
Lib/idlelib/calltips.py
Outdated
argspec = inspect.formatargspec(*inspect.getfullargspec(fob)) | ||
try: | ||
argspec = str(inspect.signature(fob)) | ||
except ValueError: |
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.
Condition return on error message
Lib/idlelib/calltips.py
Outdated
except ValueError: | ||
argspec = "This function has an invalid method signature" | ||
return argspec | ||
|
||
if (isinstance(ob, (type, types.MethodType)) or |
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.
Add argspec != '' to later revised condition
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.
See msg292964 on issue for explanations and comment on what test addition is needed.
Lib/idlelib/calltips.py
Outdated
@@ -1,4 +1,4 @@ | |||
"""calltips.py - An IDLE Extension to Jog Your Memory | |||
b"""calltips.py - An IDLE Extension to Jog Your Memory |
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.
??? Docstrings are not bytes.
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.
A typo..., I'm using trackpoint on laptop, sometime when scrolling down, it will unexpectedly
pressing "b"
@@ -139,21 +139,32 @@ def get_argspec(ob): | |||
ob_call = ob.__call__ | |||
except BaseException: | |||
return argspec | |||
if isinstance(ob, type): | |||
fob = ob.__init__ |
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.
Why remove this? It worked before. Does signature() do this automatically? Such a change should be explained on the issue with examples, both for Python and C coded classed. And yes, I wish I had added comments here or in test file or, by reference, an issue, when I revised this and and added test file.
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.
As you said on msg, this will automatically done by signature
.
Lib/idlelib/calltips.py
Outdated
if '/' in argspec: | ||
"""Argument Clinic positional-only mark, ignore the result of signature | ||
""" | ||
argspec = '' |
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.
Why? '/' is used in legitimate signatures, and appear, I believe, in the docs.
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.
I'll use your method in msg293008
Replaced by #2822 with new account name. LEAVE THIS OPEN FOR NOW. Since it will not be merged, I am using it as one example of not being able to edit the code due to lack permission. |
Edit by others being turned off seems to be resolved for now. |
This commit change the get_argspec from using inspect.getfullargspec
to inspect.signature. It will improve the tip message for use.