diff --git a/IPython/core/tests/test_completer.py b/IPython/core/tests/test_completer.py index 61f1466..b3dd790 100644 --- a/IPython/core/tests/test_completer.py +++ b/IPython/core/tests/test_completer.py @@ -939,6 +939,34 @@ def test_object_key_completion(): nt.assert_in('qwick', matches) +class NamedInstanceMetaclass(type): + def __getitem__(cls, item): + return cls.get_instance(item) + +class NamedInstanceClass(object, metaclass=NamedInstanceMetaclass): + def __init__(self, name): + if not hasattr(self.__class__, 'instances'): + self.__class__.instances = {} + self.__class__.instances[name] = self + + @classmethod + def _ipython_key_completions_(cls): + return cls.instances.keys() + + @classmethod + def get_instance(cls, name): + return cls.instances[name] + +def test_class_key_completion(): + ip = get_ipython() + NamedInstanceClass('qwerty') + NamedInstanceClass('qwick') + ip.user_ns['named_instance_class'] = NamedInstanceClass + + _, matches = ip.Completer.complete(line_buffer="named_instance_class['qw") + nt.assert_in('qwerty', matches) + nt.assert_in('qwick', matches) + def test_tryimport(): """ Test that try-import don't crash on trailing dot, and import modules before diff --git a/IPython/utils/dir2.py b/IPython/utils/dir2.py index b50654f..9f19b2d 100644 --- a/IPython/utils/dir2.py +++ b/IPython/utils/dir2.py @@ -6,6 +6,7 @@ # Distributed under the terms of the Modified BSD License. import inspect +import types def safe_hasattr(obj, attr): @@ -53,16 +54,13 @@ def dir2(obj): def get_real_method(obj, name): """Like getattr, but with a few extra sanity checks: - - If obj is a class, ignore its methods + - If obj is a class, ignore everything except class methods - Check if obj is a proxy that claims to have all attributes - Catch attribute access failing with any exception - Check that the attribute is a callable object Returns the method or None. """ - if inspect.isclass(obj): - return None - try: canary = getattr(obj, '_ipython_canary_method_should_not_exist_', None) except Exception: @@ -77,6 +75,9 @@ def get_real_method(obj, name): except Exception: return None + if inspect.isclass(obj) and not isinstance(m, types.MethodType): + return None + if callable(m): return m