[IPython-User] Tab completion doesn't work on class/instance where __getattr__ has been overridden
Jeremy Conlin
jlconlin@gmail....
Wed Mar 2 08:28:35 CST 2011
On Tue, Mar 1, 2011 at 4:43 PM, Robert Kern <robert.kern@gmail.com> wrote:
> On 3/1/11 1:58 PM, Jeremy Conlin wrote:
>> I have a class (subclassed from list) where I have overwridden the
>> __getattr__ method as:
>>
>> def __getattr__(self, name):
>> if name.startswith("__"): raise AttributeError
>> def _multiplexed(*args, **kwargs):
>> return [getattr(R, name)(*args, **kwargs) for R in self]
>> return _multiplexed
>>
>> Now when I try to use tab completion, iPython just beeps at me and
>> doesn't complete anything. If I remove this method from my class, I
>> can do tab completion.
>>
>> Does the tab completion use __getattr__ somewhere? Can I add
>> something to my definition to make tab completion work in iPython?
>
> It works for me with the HEAD of IPython. What version are you using?
>
> [~]
> |8> class A(list):
> ..> def __getattr__(self, name):
> ..> if name.startswith('__'): raise AttributeError
> ..> return 10
> ..>
>
> [~]
> |9> a = A()
>
> [~]
> |10> a.
> a.append a.extend a.insert a.remove a.sort
> a.count a.index a.pop a.reverse
I am using iPython 0.10.1 with Python 2.7.1. I have created a minimal
example which is copied below. On my system, iPython does not tab
complete the instance of myList.
Jeremy
class myList(list):
def __init__(self, items):
super(myList, self).__init__(items)
self.name = 'myList'
def __getattr__(self, name):
if name.startswith("__"): raise AttributeError
def _multiplexed(*args, **kwargs):
return [getattr(R, name)(*args, **kwargs) for R in self]
return _multiplexed
def __dir__(self):
heritage = dir(super(self.__class__, self)) # inherited attributes
return sorted(heritage + self.__class__.__dict__.keys() +
self.__dict__.keys())
def __getslice__(self, begin, end):
return self.__getitem__(slice(begin, end))
def __getitem__(self, index):
if isinstance(index, slice):
return self.__class__([self[x] for x in range(
*index.indices( len(self) ) ) ] )
elif isinstance(index, int):
return super(myList, self).__getitem__(index)
else:
return self[self.index(index)]
if __name__ == "__main__":
import string
import random
print("\nI'm tesing out custom slicing.\n")
N = 10
L = myList([random.choice(string.ascii_letters) for L in range(N)])
Lupper = L.upper()
More information about the IPython-User
mailing list