bpo-40529: rlcompleter with case insensitive
Incorporated review comments @ Lib/rlcompleter.py Added documentation @ Doc/library/rlcompleter.rst Added unit testcase test_case_insentive_matches() @ Lib/test/test_rlcompleter.py * skip news
This commit is contained in:
parent
e2a4f87879
commit
7a58345743
|
@ -5,6 +5,7 @@
|
|||
:synopsis: Python identifier completion, suitable for the GNU readline library.
|
||||
|
||||
.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
|
||||
.. sectionauthor:: Madhusudhan Kasula <kasula.madhusudhan@gmail.com>
|
||||
|
||||
**Source code:** :source:`Lib/rlcompleter.py`
|
||||
|
||||
|
@ -59,3 +60,19 @@ Completer objects have the following method:
|
|||
:func:`dir` function. Any exception raised during the evaluation of the
|
||||
expression is caught, silenced and :const:`None` is returned.
|
||||
|
||||
|
||||
.. _case-sensitivity:
|
||||
|
||||
Case Sensitivity
|
||||
-----------------
|
||||
|
||||
You can change the Completer's default case sensitive selection to case insensitive using the following method:
|
||||
|
||||
|
||||
.. function:: rlcompleter.set_case_insensitive(option)
|
||||
|
||||
Return the *None*.
|
||||
|
||||
If called with *True*, it will set rlcompleter for case insensitive completions.
|
||||
|
||||
If called with *False*, it will set to default case sensitive completions.
|
||||
|
|
|
@ -110,12 +110,13 @@ class Completer:
|
|||
defined in self.namespace that match.
|
||||
|
||||
"""
|
||||
import re
|
||||
import keyword
|
||||
matches = []
|
||||
seen = {"__builtins__"}
|
||||
n = len(text)
|
||||
for word in keyword.kwlist:
|
||||
if word[:n] == text:
|
||||
if re.match(text, word[:n], flags=_re_ignorecase_flags):
|
||||
seen.add(word)
|
||||
if word in {'finally', 'try'}:
|
||||
word = word + ':'
|
||||
|
@ -126,7 +127,8 @@ class Completer:
|
|||
matches.append(word)
|
||||
for nspace in [self.namespace, builtins.__dict__]:
|
||||
for word, val in nspace.items():
|
||||
if word[:n] == text and word not in seen:
|
||||
if (re.match(text, word[:n], flags=_re_ignorecase_flags) and
|
||||
word not in seen):
|
||||
seen.add(word)
|
||||
matches.append(self._callable_postfix(val, word))
|
||||
return matches
|
||||
|
@ -193,7 +195,7 @@ _re_ignorecase_flags = 0
|
|||
def set_case_insensitive(option):
|
||||
import re
|
||||
global _re_ignorecase_flags
|
||||
_re_ignorecase_flags = option and re.IGNORECASE or 0
|
||||
_re_ignorecase_flags = re.IGNORECASE if option else 0
|
||||
|
||||
def get_class_members(klass):
|
||||
ret = dir(klass)
|
||||
|
|
|
@ -137,5 +137,31 @@ class TestRlcompleter(unittest.TestCase):
|
|||
self.assertEqual(completer.complete('Ellipsis', 0), 'Ellipsis(')
|
||||
self.assertIsNone(completer.complete('Ellipsis', 1))
|
||||
|
||||
def test_case_insentive_matches(self):
|
||||
# add an additional attr for testing
|
||||
CompleteMe.SpAm = 2
|
||||
# enable the case insensitive option
|
||||
rlcompleter.set_case_insensitive(True)
|
||||
# test globals
|
||||
self.assertEqual(self.completer.global_matches('completem'),
|
||||
['CompleteMe('])
|
||||
# test attr
|
||||
self.assertNotEqual(self.completer.attr_matches('CompleteMe.spa'),
|
||||
['CompleteMe.spam', 'CompleteMe.SpAm'])
|
||||
# disable the case insensitive option
|
||||
rlcompleter.set_case_insensitive(False)
|
||||
# test globals
|
||||
self.assertNotEqual(self.completer.global_matches('completem'),
|
||||
['CompleteMe('])
|
||||
self.assertEqual(self.completer.global_matches('CompleteM'),
|
||||
['CompleteMe('])
|
||||
# test attr
|
||||
self.assertNotEqual(self.completer.attr_matches('CompleteMe.spa'),
|
||||
['CompleteMe.spam', 'CompleteMe.SpAm'])
|
||||
self.assertEqual(self.completer.attr_matches('CompleteMe.sp'),
|
||||
['CompleteMe.spam'])
|
||||
# delete the additional attr
|
||||
del(CompleteMe.SpAm)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in New Issue