From 5cf6f520256ebada88de43ec7bc56e78b21e1c54 Mon Sep 17 00:00:00 2001 From: llllllllll Date: Sun, 15 Mar 2015 19:42:27 -0400 Subject: [PATCH 1/3] Makes old style classes and instances show __dict__ in the autocomplete. --- bpython/autocomplete.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bpython/autocomplete.py b/bpython/autocomplete.py index 6e3ddb900..b2011674a 100644 --- a/bpython/autocomplete.py +++ b/bpython/autocomplete.py @@ -33,6 +33,7 @@ import re import rlcompleter import sys +from types import InstanceType, ClassType from six.moves import range, builtins from six import string_types, iteritems @@ -539,6 +540,9 @@ def attr_lookup(obj, expr, attr): words.remove('__abstractmethods__') except ValueError: pass + if isinstance(obj, (InstanceType, ClassType)): + # Account for the __dict__ in an old-style class. + words.append('__dict__') matches = [] n = len(attr) From cb908722ac73c1aac0873039921e149276faba32 Mon Sep 17 00:00:00 2001 From: llllllllll Date: Sun, 15 Mar 2015 19:43:09 -0400 Subject: [PATCH 2/3] Adds tests to validate that __dict__ is in the autocomplete of an old style class or instance. --- bpython/test/test_autocomplete.py | 33 +++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/bpython/test/test_autocomplete.py b/bpython/test/test_autocomplete.py index cad960e33..3b87ce720 100644 --- a/bpython/test/test_autocomplete.py +++ b/bpython/test/test_autocomplete.py @@ -215,13 +215,42 @@ def method(self, x): pass +class OldStyleFoo: + a = 10 + + def __init__(self): + self.b = 20 + + def method(self, x): + pass + + +skip_old_style = unittest.skipIf(py3, + 'In Python 3 there are no old style classes') + + class TestAttrCompletion(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.com = autocomplete.AttrCompletion() def test_att_matches_found_on_instance(self): - com = autocomplete.AttrCompletion() - self.assertSetEqual(com.matches(2, 'a.', locals_={'a': Foo()}), + self.assertSetEqual(self.com.matches(2, 'a.', locals_={'a': Foo()}), set(['a.method', 'a.a', 'a.b'])) + @skip_old_style + def test_att_matches_found_on_old_style_instance(self): + self.assertSetEqual(self.com.matches(2, 'a.', + locals_={'a': OldStyleFoo()}), + {'a.method', 'a.a', 'a.b'}) + self.assertIn(u'a.__dict__', + self.com.matches(3, 'a._', locals_={'a': OldStyleFoo()})) + + @skip_old_style + def test_att_matches_found_on_old_style_class_object(self): + self.assertIn(u'A.__dict__', + self.com.matches(3, 'A._', locals_={'A': OldStyleFoo})) + class TestMagicMethodCompletion(unittest.TestCase): From a82b4b5dba14a3a497560c583410f058a93a779f Mon Sep 17 00:00:00 2001 From: llllllllll Date: Sun, 15 Mar 2015 19:58:42 -0400 Subject: [PATCH 3/3] Makes the old-style class autocomplete work in 2.6 and 3.x --- bpython/autocomplete.py | 6 ++++-- bpython/test/test_autocomplete.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/bpython/autocomplete.py b/bpython/autocomplete.py index b2011674a..3b64d0b2f 100644 --- a/bpython/autocomplete.py +++ b/bpython/autocomplete.py @@ -33,7 +33,6 @@ import re import rlcompleter import sys -from types import InstanceType, ClassType from six.moves import range, builtins from six import string_types, iteritems @@ -43,6 +42,9 @@ from bpython._py3compat import py3, try_decode from bpython.lazyre import LazyReCompile +if not py3: + from types import InstanceType, ClassType + # Autocomplete modes SIMPLE = 'simple' @@ -540,7 +542,7 @@ def attr_lookup(obj, expr, attr): words.remove('__abstractmethods__') except ValueError: pass - if isinstance(obj, (InstanceType, ClassType)): + if not py3 and isinstance(obj, (InstanceType, ClassType)): # Account for the __dict__ in an old-style class. words.append('__dict__') diff --git a/bpython/test/test_autocomplete.py b/bpython/test/test_autocomplete.py index 3b87ce720..a6f2f153a 100644 --- a/bpython/test/test_autocomplete.py +++ b/bpython/test/test_autocomplete.py @@ -242,7 +242,7 @@ def test_att_matches_found_on_instance(self): def test_att_matches_found_on_old_style_instance(self): self.assertSetEqual(self.com.matches(2, 'a.', locals_={'a': OldStyleFoo()}), - {'a.method', 'a.a', 'a.b'}) + set(['a.method', 'a.a', 'a.b'])) self.assertIn(u'a.__dict__', self.com.matches(3, 'a._', locals_={'a': OldStyleFoo()}))