Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IPython auto completion is calling __getattr__

thanks for taking the time to read this. Hope everything is alright with you on these strange times.

I'm implementing a class and started looking how to provide auto-completion on its attributes. From my research online i reached the conclusion that ipython completions come from the __dir__ method.

__getattr__ is normally called when you access an attribute that doesn't exist. In my project if that happens, an operation that takes a while runs. Why is ipython trying to access the attributes instead of just displaying what __dir__ returned?

In cell 2 i hit tab after the dot to ask for completions.

enter image description here

like image 497
André Alves Avatar asked Sep 13 '25 22:09

André Alves


2 Answers

I think the issue is that you need an instance of your class. Those methods are instance methods.

I added logging for easier debugging. I am getting output in the ipython console when I example.something or example.<tab>.

  • Python version 3.8.2
  • IPython version 7.14.0

This is my observation: On <tab> __dir__ is called and the returned collection of items are displayed in IPython console. If the item chosen after <tab> is not an attribute of the object, then __getattr__ is called in an attempt to look it up.

import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)


class Example:
    def __init__(self):
        logging.info("init")
        self._attrs = ("foo", "bar", "baz")
        for attr in self._attrs:
            setattr(self, attr, attr)

    def __getattr__(self, attr):
        logging.info(f"__getattr__ called: {attr}")

    def __dir__(self):
        logging.info("__dir__ called")
        return ("extra", *self._attrs)


# Create an instance of Example.
# The instance methods can then be called on the instance.
example = Example()

if __name__ == "__main__":
    logging.info(example)

enter image description here

like image 148
dmmfll Avatar answered Sep 15 '25 12:09

dmmfll


So I figured out a workaround for this. Provided that you know the attribute name that takes a long time, only do the custom getattr code when that attribute name is passed, else just raise an attribute error. This worked for me.

like image 31
Paul Nation Avatar answered Sep 15 '25 10:09

Paul Nation