X Tutup
Skip to content

Commit a194976

Browse files
committed
Use sets in bpython.importcompletion
Also avoid multiple evaluation of the same input Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
1 parent 64dd9de commit a194976

File tree

2 files changed

+39
-27
lines changed

2 files changed

+39
-27
lines changed

bpython/importcompletion.py

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ def catch_warnings():
5959
def module_matches(cw, prefix=''):
6060
"""Modules names to replace cw with"""
6161
full = '%s.%s' % (prefix, cw) if prefix else cw
62-
matches = [name for name in modules
63-
if (name.startswith(full) and
64-
name.find('.', len(full)) == -1)]
62+
matches = set(name for name in modules
63+
if (name.startswith(full) and
64+
name.find('.', len(full)) == -1))
6565
if prefix:
66-
return [match[len(prefix)+1:] for match in matches]
66+
return set(match[len(prefix)+1:] for match in matches)
6767
else:
6868
return matches
6969

@@ -72,19 +72,20 @@ def attr_matches(cw, prefix='', only_modules=False):
7272
full = '%s.%s' % (prefix, cw) if prefix else cw
7373
module_name, _, name_after_dot = full.rpartition('.')
7474
if module_name not in sys.modules:
75-
return []
75+
return set()
7676
module = sys.modules[module_name]
7777
if only_modules:
78-
matches = [name for name in dir(module)
79-
if name.startswith(name_after_dot) and
80-
'%s.%s' % (module_name, name) in sys.modules]
78+
matches = set(name for name in dir(module)
79+
if (name.startswith(name_after_dot) and
80+
'%s.%s' % (module_name, name)) in sys.modules)
8181
else:
82-
matches = [name for name in dir(module) if name.startswith(name_after_dot)]
82+
matches = set(name for name in dir(module)
83+
if name.startswith(name_after_dot))
8384
module_part, _, _ = cw.rpartition('.')
8485
if module_part:
85-
return ['%s.%s' % (module_part, m) for m in matches]
86-
return matches
86+
matches = set('%s.%s' % (module_part, m) for m in matches)
8787

88+
return matches
8889
def module_attr_matches(name):
8990
"""Only attributes which are modules to replace name with"""
9091
return attr_matches(name, prefix='', only_modules=True)
@@ -99,21 +100,27 @@ def complete(cursor_offset, line):
99100
if result is None:
100101
return None
101102

102-
if lineparts.current_from_import_from(cursor_offset, line) is not None:
103-
if lineparts.current_from_import_import(cursor_offset, line) is not None:
103+
from_import_from = lineparts.current_from_import_from(cursor_offset, line)
104+
if from_import_from is not None:
105+
from_import_import = lineparts.current_from_import_import(cursor_offset,
106+
line)
107+
if from_import_import is not None:
104108
# `from a import <b|>` completion
105-
return (module_matches(lineparts.current_from_import_import(cursor_offset, line)[2],
106-
lineparts.current_from_import_from(cursor_offset, line)[2]) +
107-
attr_matches(lineparts.current_from_import_import(cursor_offset, line)[2],
108-
lineparts.current_from_import_from(cursor_offset, line)[2]))
109+
matches = module_matches(from_import_import[2], from_import_from[2])
110+
matches.update(attr_matches(from_import_import[2],
111+
from_import_from[2]))
109112
else:
110113
# `from <a|>` completion
111-
return (module_attr_matches(lineparts.current_from_import_from(cursor_offset, line)[2]) +
112-
module_matches(lineparts.current_from_import_from(cursor_offset, line)[2]))
113-
elif lineparts.current_import(cursor_offset, line):
114+
matches = module_attr_matches(from_import_from[2])
115+
matches.update(module_matches(from_import_from[2]))
116+
return matches
117+
118+
current_import = lineparts.current_import(cursor_offset, line)
119+
if current_import is not None:
114120
# `import <a|>` completion
115-
return (module_matches(lineparts.current_import(cursor_offset, line)[2]) +
116-
module_attr_matches(lineparts.current_import(cursor_offset, line)[2]))
121+
matches = module_matches(current_import[2])
122+
matches.update(module_attr_matches(current_import[2]))
123+
return matches
117124
else:
118125
return None
119126

bpython/test/test_importcompletion.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ def tearDown(self):
1212
importcompletion.modules = self.original_modules
1313

1414
def test_simple_completion(self):
15-
self.assertEqual(importcompletion.complete(10, 'import zza'), ['zzabc', 'zzabd'])
15+
self.assertEqual(sorted(importcompletion.complete(10, 'import zza')),
16+
['zzabc', 'zzabd'])
1617

1718
def test_package_completion(self):
18-
self.assertEqual(importcompletion.complete(13, 'import zzabc.'), ['zzabc.e', 'zzabc.f', ])
19+
self.assertEqual(sorted(importcompletion.complete(13, 'import zzabc.')),
20+
['zzabc.e', 'zzabc.f', ])
1921

2022

2123
class TestRealComplete(unittest.TestCase):
@@ -32,11 +34,14 @@ def tearDownClass(cls):
3234
importcompletion.modules = set()
3335

3436
def test_from_attribute(self):
35-
self.assertEqual(importcompletion.complete(19, 'from sys import arg'), ['argv'])
37+
self.assertEqual(sorted(importcompletion.complete(19, 'from sys import arg')),
38+
['argv'])
3639

3740
def test_from_attr_module(self):
38-
self.assertEqual(importcompletion.complete(9, 'from os.p'), ['os.path'])
41+
self.assertEqual(sorted(importcompletion.complete(9, 'from os.p')),
42+
['os.path'])
3943

4044
def test_from_package(self):
41-
self.assertEqual(importcompletion.complete(17, 'from xml import d'), ['dom'])
45+
self.assertEqual(sorted(importcompletion.complete(17, 'from xml import d')),
46+
['dom'])
4247

0 commit comments

Comments
 (0)
X Tutup