Feature Request : Autocomplete and docstring working when instantiating using class directly
Refer to the reproducer and gif below.
class Foo:
def __init__(self):
self.name = "My name"
def get_name(self):
'''
This is a sample doctring
'''
print(self.name)
As shown, both autocomplete and docstring features are working when we instantiate an object first. However, they stop working correctly when we instantiate using class directly.
Some further points :-
- In tab-completion, the intention is not to execute code so it makes sense that
Foo().<TAB>doesn't work. But in doingFoo().get_name??, we are executing that cell, and hence, expecting the resulting docstring. - Alternatively, is it possible to statically determine what
Foo()returns? In that case, we can use that result to fix both issues. - The autocomplete issue does fix itself when
%config IPCompleter.use_jediis set toTrue
In tab-completion, the intention is not to execute code so it makes sense that
Foo().<TAB>doesn't work.
Correct. Users may decide to set Completer.evaluation to 'unsafe' in which case this works, but it has side-effects.
Alternatively, is it possible to statically determine what
Foo()returns? In that case, we can use that result to fix both issues.
Yes, this was partially implemented in https://github.com/ipython/ipython/pull/14185. It works if you re-run the cell like this:
However, it does not work for stringified nor deferred annotations from PEP 649 yet:
We could make it work for the case of class initialisation even without the need to specify the type annotation as __init__ can be assumed to return the instance of class it is defined in (unless a meta class modifies it).
But in doing Foo().get_name??, we are executing that cell, and hence, expecting the resulting docstring.
In this case it is clear that you want to execute, but in general that might no be the case, in particular ?/?? will run multiple time if you do have a loop or anything else.
In general users get surprised either in completion or help when objects get executed, or if expressions are evaluated. In many case that is is ok, but in a few case where this is not, this can be devastating. From experience many user will tend to use ?/?? in the middle of a long black of code they are currently writing, forgetting that the rest of the code is also ran.
We can likely try to relax the regex that tries to capture what object we are getting help on, and add a flag, though it will likely not be perfect. You can use hist -t to see the history and that the () is seen as a delimiter leading to actually IPython asking info only on get_name.
get_ipython().run_line_magic('pinfo2', 'get_name')
Also as this is based on string transform and not proper parsing, it might not be as easy to properly detect which identifier or expression is targeted by ?/??, and recent changes is CPython make it harder and harder to do some of those transforms. So it might be a game of cat and mouse.
Conceptually I wonder if we could use guarded_eval for ?/?? inspections, the same way we use it for completions - the guards would prevent side effects. However, it might require some adjustments to ensure it is as reliable for docstring discovery as it is for attribute discovery.