ipython / ipython

Official repository for IPython itself. Other repos in the IPython organization contain things like the website, documentation builds, etc.

Home Page:https://ipython.readthedocs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Tab completion not working for class when it has property with typing.Literal annotated return value

wenjuno opened this issue · comments

Here is an example class:

import typing
class A:
    @property
    def value(self) -> typing.Literal['a']:
        return 'a'
    def get(self) -> typing.Literal['a']:
        return 'a'
a = A()

Now if I type a.<Tab> in IPython console, nothing will show up. If I put the same code in Python console, the second Tab will display the two methods.

I can confirm that this does not work by default in 8.23.0 which looks like a jedi problem.
After executing %config c.IPCompleter.use_jedi = False it works well.

@wenjuno can you confirm that your setup used the default completer and that disabling jedi with the config command as per above fixes it for you?

Hi @krassowski Thanks for the reply. Sorry I'm not familiar with the IPython configuration, I'm not sure how to confirm my configuration. I tried the command but it raised exception:

In [1]: %config c.IPCompleter.use_jedi = False
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[1], line 1
----> 1 get_ipython().run_line_magic('config', 'c.IPCompleter.use_jedi = False')

File IPython/core/interactiveshell.py:2480, in InteractiveShell.run_line_magic(self, magic_name, line, _stack_depth)
   2478     kwargs['local_ns'] = self.get_local_scope(stack_depth)
   2479 with self.builtin_trap:
-> 2480     result = fn(*args, **kwargs)
   2482 # The code below prevents the output from being displayed
   2483 # when using magics with decorator @output_can_be_silenced
   2484 # when the last Python token in the expression is a ';'.
   2485 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):

File IPython/core/magics/config.py:134, in ConfigMagics.config(self, s)
    130 # otherwise, assume we are setting configurables.
    131 # leave quotes on args when splitting, because we want
    132 # unquoted args to eval in user_ns
    133 cfg = Config()
--> 134 exec("cfg."+line, self.shell.user_ns, locals())
    136 for configurable in configurables:
    137     try:

File <string>:1

AttributeError: 'LazyConfigValue' object has no attribute 'IPCompleter'

I might have a different configuration?
I look at ~/.ipython/profile_default/ipython_config.py, the only things not commented out are:

c.InteractiveShell.colors = 'Linux'
c.TerminalInteractiveShell.colors = 'Linux'

I follow the instruction here (https://ipython.readthedocs.io/en/stable/config/intro.html) to create a new profile. In the ipython_config.py file, I add c.IPCompleter.use_jedi = False. After relaunch IPython with the profile, the tab completion works. (But FYI with the new profile the %config magic command still gives me the same exception).

So, should we report this to jedi instead? Thanks.

@wenjuno whoops, sorry typo! I meant: %config IPCompleter.use_jedi = False

After relaunch IPython with the profile, the tab completion works.

Great to hear!

So, should we report this to jedi instead? Thanks.

Let's see:

import jedi
code = """import typing
class A:
    @property
    def value(self) -> typing.Literal['a']:
        return 'a'
    def get(self) -> typing.Literal['a']:
        return 'a'
a = A()
a."""
script = jedi.Script(code)
script.complete(line=len(code.splitlines()), column=2)

[<Completion: get>,
<Completion: value>,
...]

Well, this works with script what about Interpreter:

import jedi
code = """import typing
class A:
    @property
    def value(self) -> typing.Literal['a']:
        return 'a'
    def get(self) -> typing.Literal['a']:
        return 'a'
a = A()
a."""
script = jedi.Interpreter(code, [])
script.complete(line=len(code.splitlines()), column=2)

Also works. Maybe this is an integration problem?

script = jedi.Interpreter(code, [])
script.complete(line=len(code.splitlines()), column=2)

that's an improper use of Interpreter.

import jedi
import typing


class A:
    @property
    def value(self) -> typing.Literal["a"]:
        return "a"

    def get(self) -> typing.Literal["a"]:
        return "a"


a = A()

interp = jedi.Interpreter("a.", [{"a": a}])
interp.complete(line=1, column=2)

Raises with AttributeError: 'TreeInstance' object has no attribute 'with_generics'. So it is likely an upstream jedi. Unclear it will be fixed.