New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rlcompleter.Completer does not use __dir__ magic method #49312
Comments
The documentation at http://docs.python.org/library/rlcompleter.html Completer.complete(text, state)¶ Return the state*th completion for *text. If called for text that doesn’t include a period character ('.'), it If called for a dotted name, it will try to evaluate anything without In other words, it claims to use dir(obj) as part of the tab completion >>> class B(object):
... def __dir__(self): return dir(u"") #Makes B objects look like strings
...
>>> b = B()
>>> dir(b)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',
'__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__',
'__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__',
'__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'_formatter_field_name_split', '_formatter_parser', 'capitalize',
'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find',
'format', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit',
'islower', 'isnumeric', 'isspace', 'istitle', 'isupper', 'join',
'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex',
'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines',
'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
>>> c = rlcompleter.Completer()
>>> c.complete("b.", 0) #Notice that it does NOT return __add__
u'b.__class__('
>>> c.matches #Notice that this list is completely different from the
list given by dir(b)
[u'b.__class__(', u'b.__delattr__(', u'b.__doc__', u'b.__format__(',
u'b.__getattribute__(', u'b.__hash__(', u'b.__init__(', u'b.__new__(',
u'b.__reduce__(', u'b.__reduce_ex__(', u'b.__repr__(',
u'b.__setattr__(', u'b.__sizeof__(', u'b.__str__(',
u'b.__subclasshook__(', u'b.__class__(', u'b.__class__(',
u'b.__delattr__(', u'b.__dict__', u'b.__dir__(', u'b.__doc__',
u'b.__format__(', u'b.__getattribute__(', u'b.__hash__(',
u'b.__init__(', u'b.__module__', u'b.__new__(', u'b.__reduce__(',
u'b.__reduce_ex__(', u'b.__repr__(', u'b.__setattr__(',
u'b.__sizeof__(', u'b.__str__(', u'b.__subclasshook__(',
u'b.__weakref__', u'b.__class__(', u'b.__delattr__(', u'b.__doc__',
u'b.__format__(', u'b.__getattribute__(', u'b.__hash__(',
u'b.__init__(', u'b.__new__(', u'b.__reduce__(', u'b.__reduce_ex__(',
u'b.__repr__(', u'b.__setattr__(', u'b.__sizeof__(', u'b.__str__(',
u'b.__subclasshook__('] Suggested course of action:
See |
This is not a bug in rlcompleter; __dir__ is returning bogus items, and Defining __getattr__ (or __getattribute__) and a matching __dir__ works >>> class B(object):
... def __dir__(self):
... return dir(object) + ["xa","xb","xc"]
... def __getattr__(self, name):
... if name in ["xa","xb","xc"]:
... return None
... raise AttributeError, name
...
>>> b = B()
>>> import rlcompleter
>>> c = rlcompleter.Completer()
>>> c.complete("b.", 0)
'b.__class__('
>>> c.matches
['b.__class__(', 'b.__delattr__(', 'b.__doc__', 'b.__format__(',
'b.__getattribute__(',
...
'b.xa', 'b.xb', 'b.xc', 'b.__class__(', 'b.__class__(',
...]
>>> c.complete("b.x", 0)
'b.xa'
>>> c.matches
['b.xa', 'b.xb', 'b.xc'] Now, looking at this I saw there *is* a bug in rlcompleter, as it may >>> c.complete("b.__c", 0)
'b.__class__('
>>> c.matches
['b.__class__(', 'b.__class__(', 'b.__class__(', 'b.__class__('] The attached patch fixes that. |
It seems to me that it isn't tab completion's place to out think the |
This is what rlcompleter does; it uses dir() to find out what names to |
I think that checking to see which things really exist with |
The check is made to decide whether the attribute is a method or not rlcompleter does nothing special with __dir__, it always uses dir() |
Ah, I see. It does a dir(obj) then tests things to see which are Actually, can we go back to the Python 2.5 behavior? I really hate those |
The current behaviour is actually a requested feature: see bpo-449227 I see your point, it may be annoying sometimes -- but calling a method |
Patched code produces identical output to unpatched code. This doesn't really surprise me as word is reused within the for loop. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: