bpo-19903: IDLE: Change to inspect.signature for calltips#1382
bpo-19903: IDLE: Change to inspect.signature for calltips#1382louisom wants to merge 10 commits into
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. |
| argspec = "" | ||
| try: | ||
| ob_call = ob.__call__ | ||
| except AttributeError: |
There was a problem hiding this comment.
Could you left this change for separate issue?
| 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.
What if the first parameter have a different name?
There was a problem hiding this comment.
Yes, you are right. I'll still need to figure out how it does different from getfullargspec
There was a problem hiding this comment.
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 |
| def m2(**kwds): pass | ||
| 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.
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.
This test borrow from test_signature
| raise BaseException | ||
| class Call(NoCall): | ||
| class CallA(NoCall): | ||
| def __call__(oui, a, b, c): |
There was a problem hiding this comment.
Add corner case for first param not self
| for obj in (0, 0.0, '0', b'0', [], {}): | ||
| self.assertEqual(signature(obj), '') | ||
|
|
||
|
|
| @@ -145,10 +148,16 @@ def get_argspec(ob): | |||
| else: | |||
| fob = ob | |||
| if isinstance(fob, (types.FunctionType, types.MethodType)): | |||
| argspec = inspect.formatargspec(*inspect.getfullargspec(fob)) | ||
| try: | ||
| argspec = str(inspect.signature(fob)) | ||
| except ValueError: |
There was a problem hiding this comment.
Must get and test error message.
| try: | ||
| argspec = str(inspect.signature(fob)) | ||
| except ValueError: | ||
| argspec = "This function has an invalid method signature" |
There was a problem hiding this comment.
Add _invalid_signature to global defs before function so can access for testing without repeating string.
| argspec = inspect.formatargspec(*inspect.getfullargspec(fob)) | ||
| try: | ||
| argspec = str(inspect.signature(fob)) | ||
| except ValueError: |
There was a problem hiding this comment.
Condition return on error message
| argspec = "This function has an invalid method signature" | ||
| return argspec | ||
|
|
||
| if (isinstance(ob, (type, types.MethodType)) or |
There was a problem hiding this comment.
Add argspec != '' to later revised condition
terryjreedy
left a comment
There was a problem hiding this comment.
See msg292964 on issue for explanations and comment on what test addition is needed.
| @@ -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.
??? Docstrings are not bytes.
There was a problem hiding this comment.
A typo..., I'm using trackpoint on laptop, sometime when scrolling down, it will unexpectedly
pressing "b"
| except BaseException: | ||
| return argspec | ||
| if isinstance(ob, type): | ||
| fob = ob.__init__ |
There was a problem hiding this comment.
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.
As you said on msg, this will automatically done by signature.
| if '/' in argspec: | ||
| """Argument Clinic positional-only mark, ignore the result of signature | ||
| """ | ||
| argspec = '' |
There was a problem hiding this comment.
Why? '/' is used in legitimate signatures, and appear, I believe, in the docs.
|
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.