[Python-checkins] cpython (merge 3.5 -> default): Issue #25663: Merge rlcompleter fix from 3.5

martin.panter python-checkins at python.org
Mon Nov 23 19:40:31 EST 2015


https://hg.python.org/cpython/rev/96fb9daf64a5
changeset: 99318:96fb9daf64a5
parent: 99315:ebec1a98ab81
parent: 99317:4ed70c568baf
user: Martin Panter <vadmium+py at gmail.com>
date: Tue Nov 24 00:19:10 2015 +0000
summary:
 Issue #25663: Merge rlcompleter fix from 3.5
files:
 Lib/rlcompleter.py | 7 +++++--
 Lib/test/test_rlcompleter.py | 21 +++++++++++++++++++++
 Misc/NEWS | 3 +++
 3 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py
--- a/Lib/rlcompleter.py
+++ b/Lib/rlcompleter.py
@@ -103,9 +103,11 @@
 """
 import keyword
 matches = []
+ seen = {"__builtins__"}
 n = len(text)
 for word in keyword.kwlist:
 if word[:n] == text:
+ seen.add(word)
 if word in {'finally', 'try'}:
 word = word + ':'
 elif word not in {'False', 'None', 'True',
@@ -113,9 +115,10 @@
 'else'}:
 word = word + ' '
 matches.append(word)
- for nspace in [builtins.__dict__, self.namespace]:
+ for nspace in [self.namespace, builtins.__dict__]:
 for word, val in nspace.items():
- if word[:n] == text and word != "__builtins__":
+ if word[:n] == text and word not in seen:
+ seen.add(word)
 matches.append(self._callable_postfix(val, word))
 return matches
 
diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py
--- a/Lib/test/test_rlcompleter.py
+++ b/Lib/test/test_rlcompleter.py
@@ -113,5 +113,26 @@
 self.assertEqual(completer.complete('el', 1), 'else')
 self.assertEqual(completer.complete('tr', 0), 'try:')
 
+ def test_duplicate_globals(self):
+ namespace = {
+ 'False': None, # Keyword vs builtin vs namespace
+ 'assert': None, # Keyword vs namespace
+ 'try': lambda: None, # Keyword vs callable
+ 'memoryview': None, # Callable builtin vs non-callable
+ 'Ellipsis': lambda: None, # Non-callable builtin vs callable
+ }
+ completer = rlcompleter.Completer(namespace)
+ self.assertEqual(completer.complete('False', 0), 'False')
+ self.assertIsNone(completer.complete('False', 1)) # No duplicates
+ self.assertEqual(completer.complete('assert', 0), 'assert')
+ self.assertIsNone(completer.complete('assert', 1))
+ self.assertEqual(completer.complete('try', 0), 'try')
+ self.assertIsNone(completer.complete('try', 1))
+ # No opening bracket "(" because we overrode the built-in class
+ self.assertEqual(completer.complete('memoryview', 0), 'memoryview')
+ self.assertIsNone(completer.complete('memoryview', 1))
+ self.assertEqual(completer.complete('Ellipsis', 0), 'Ellipsis(')
+ self.assertIsNone(completer.complete('Ellipsis', 1))
+
 if __name__ == '__main__':
 unittest.main()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -95,6 +95,9 @@
 Library
 -------
 
+- Issue #25663: In the Readline completer, avoid listing duplicate global
+ names, and search the global namespace before searching builtins.
+
 - Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error.
 
 - Issue #23914: Fixed SystemError raised by unpickler on broken pickle data.
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /