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.
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>
.
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With