1

I want to use autocomplete in ipython and jupyter for the following code with read-only class attributes (using @property):

class A(object):
    def __init__(self):
        self.__value = 1

    @property
    def value(self):
        return self.__value

class B(object):
    def __init__(self):
        self.a = A()

class C(object):
    def __init__(self):
        self.__a = A()

    @property
    def a(self):
        return self.__a

b = B()
c = C()

Both

>>> b.a.value

and

>>> c.a.value

work well. But autocomplete for ipython and jupyter notebook works only for

>>> b.a.value

and

>>> c.a.

without tab-autocomplete.

How to rewrite the code to achieve c.a.<tab> -> c.a.value autocomplete in ipython and jupyter notebook?

gdlmx
  • 6,479
  • 1
  • 21
  • 39
dinya
  • 1,563
  • 1
  • 16
  • 30
  • 1
    I think that's not possible because the autocompletor will not execute the expression `c.a` when you hit ``. It cannot know whether the `property` function has side effect. – gdlmx Mar 01 '19 at 16:49
  • `x=c.a`, `x.` may work – hpaulj Mar 01 '19 at 19:46
  • **UPD** IPython console launched from Spyder completes ``c.a. -> c.a.value`` well. Maybe Spyder uses rope but vanilla ipython and jupyter use jedi for this one? – dinya Mar 03 '19 at 10:40

1 Answers1

1

Because of problems with IPython (6.x to 7.2) + jedi my temporary hack is

def fix_ipython_autocomplete(enable=True):
    """Change autocomplete behavior for IPython > 6.x

    Parameter
    ---------
    enable : bool (default True)
        Is use the trick.

    Notes
    -----
    Since IPython > 6.x the ``jedi`` package is using for autocomplete by default.
    But in some cases, the autocomplete doesn't work correctly wrong (see e.g.
    `here <https://github.com/ipython/ipython/issues/11653>`_).

    To set the correct behaviour we should use in IPython environment::

        %config Completer.use_jedi = False

    or add to IPython config (``<HOME>\.ipython\profile_default\ipython_config.py``)::

        c.Completer.use_jedi = False
    """

    try:
        __IPYTHON__
    except NameError:
        pass
    else:
        from IPython import __version__      
        major = int(__version__.split('.')[0])
        if major >= 6:
            from IPython import get_ipython
            get_ipython().Completer.use_jedi = not enable

See also https://github.com/ipython/ipython/issues/11653

dinya
  • 1,563
  • 1
  • 16
  • 30