3

I'm implementing a python class that contains a 2d numpy array (self.data) that I have set up for column access with a string key. The keys are contained in a dict that maps names to column indices (e.g., self.coldict={'col0':0,...,'colN':N}), and I've defined

def __getitem__(self,key):
   if isinstance(key,str):
       return self.data[:,self.coldict[key]]
   elif isinstance(key,int):
       return self.data[:,key]

This works as intended for column retrieval.

I'd like to be able to use tab complete for the key so that I can type myObject['c+TAB during an iPython session to get completion options.

I think a solution should rely on readline or prompt_toolkit, but it's not clear to me how to implement a completer function without overriding the already-active functionality in iPython.

Any help is much appreciated. Thanks!

2 Answers2

1

I'm not sure if you can tab complete a string for __getitem__. Tab completion is usually for object attribtues. Tab completion uses the items defined in the __dict__ instance dictionary and the __dir__(self) method.

If you want tab completion for the accessing an attribute you can.

class MyArray:
    ...
    def __dir__(self):
        return super().__dir__() + list(self.coldict.keys())

    def __getattr__(self, name):
        if name in self.coldict:
            return self.data[:,self.coldict[name]]
        return super().__getattr__(name)

You would then access your column with

arr = MyArray() # My numpy array
print(arr.col0) # col0 should allow for tab complete.
justengel
  • 6,132
  • 4
  • 26
  • 42
  • 1
    Thanks! That's an excellent workaround. Pandas has the behavior I'm looking for implemented for dataframes, but I haven't managed to find that code in the source yet. That does indicate that it is possible (though it doesn't mean it's easy!). – ExperimentalPhysicist Mar 13 '17 at 19:47
1

It was hard to track down, but this is how it's done (reference 1 and 2):

You can also customize key completions for your objects, e.g. pressing tab after obj["a. To do so, define a method _ipython_key_completions_(), which returns a list of objects which are possible keys in a subscript expression obj[key].

I got this working by simply adding a method called _ipython_key_completions_ to a custom class that returns all the possible string keys that can be used when calling __getitem__. What I didn't realize is that Python dicts already do this as well as Pandas DataFrames.

  • Note that if you also define `__getattr__()` of the class, then the `_ipython_key_completions_` somehow won't work. – Louis Yang May 10 '20 at 02:08