diff -r ab6209ce77b6 Lib/idlelib/AutoComplete.py --- a/Lib/idlelib/AutoComplete.py Fri Jun 20 17:34:44 2014 +0200 +++ b/Lib/idlelib/AutoComplete.py Fri Jun 20 14:07:56 2014 -0300 @@ -13,7 +13,7 @@ ID_CHARS = string.ascii_letters + string.digits + "_" # These constants represent the two different types of completions -COMPLETE_ATTRIBUTES, COMPLETE_FILES = range(1, 2+1) +COMPLETE_ATTRIBUTES, COMPLETE_FILES, COMPLETE_DICTIONARY = range(1, 3+1) from idlelib import AutoCompleteWindow from idlelib.HyperParser import HyperParser @@ -120,7 +120,18 @@ hp = HyperParser(self.editwin, "insert") curline = self.text.get("insert linestart", "insert") i = j = len(curline) - if hp.is_in_string() and (not mode or mode==COMPLETE_FILES): + if hp.is_in_subscript_string() and (not mode or mode==COMPLETE_DICTIONARY): + self._remove_autocomplete_window() + mode = COMPLETE_DICTIONARY + while i and (curline[i-1] not in "'"): + i -= 1 + comp_start = curline[i:j] + if i > 1 and curline[i-2] == '[': + hp.set_index("insert-%dc" % (len(curline)-(i-2))) + comp_what = hp.get_expression() + else: + comp_what = "" + elif hp.is_in_string() and (not mode or mode==COMPLETE_FILES): # Find the beginning of the string # fetch_completions will look at the file system to determine whether the # string value constitutes an actual file name @@ -184,6 +195,7 @@ return rpcclt.remotecall("exec", "get_the_completion_list", (what, mode), {}) else: + smalll = bigl = None if mode == COMPLETE_ATTRIBUTES: if what == "": namespace = __main__.__dict__.copy() @@ -217,6 +229,14 @@ except OSError: return [], [] + elif mode == COMPLETE_DICTIONARY: + try: + entity = self.get_entity(what) + bigl = [s for s in entity.keys() if isinstance(s,str)] + bigl.sort() + except: + return [], [] + if not smalll: smalll = bigl return smalll, bigl diff -r ab6209ce77b6 Lib/idlelib/HyperParser.py --- a/Lib/idlelib/HyperParser.py Fri Jun 20 17:34:44 2014 +0200 +++ b/Lib/idlelib/HyperParser.py Fri Jun 20 14:07:56 2014 -0300 @@ -87,6 +87,15 @@ not self.isopener[self.indexbracket+1]): self.indexbracket += 1 + def is_in_subscript_string(self): + """Is the index given to the HyperParser in a string inside + a subscript? + """ + return (self.indexbracket and + self.is_in_string() and + self.isopener[self.indexbracket-1] and + self.rawtext[self.bracketing[self.indexbracket-1][0]] == '[') + def is_in_string(self): """Is the index given to the HyperParser in a string?""" # The bracket to which we belong should be an opener. diff -r ab6209ce77b6 Lib/idlelib/idle_test/test_hyperparser.py --- a/Lib/idlelib/idle_test/test_hyperparser.py Fri Jun 20 17:34:44 2014 +0200 +++ b/Lib/idlelib/idle_test/test_hyperparser.py Fri Jun 20 14:07:56 2014 -0300 @@ -30,6 +30,9 @@ "z = ((r'asdf')+('a')))\n" '[x for x in\n' 'for = False\n' + "d['a']\n" + 'd["a"]\n' + "d[1]\n" ) @classmethod @@ -78,6 +81,24 @@ self.text.insert('end', self.text.get('1.0', 'end')*4) p = self.get_parser('54.5') + def test_is_in_subscript_string(self): + get = self.get_parser + + p = get('12.0') + self.assertFalse(p.is_in_subscript_string()) + p = get('12.2') + self.assertFalse(p.is_in_subscript_string()) + p = get('12.3') + self.assertTrue(p.is_in_subscript_string()) + p = get('12.5') + self.assertFalse(p.is_in_subscript_string()) + p = get('13.2') + self.assertFalse(p.is_in_subscript_string()) + p = get('13.3') + self.assertTrue(p.is_in_subscript_string()) + p = get('14.2') + self.assertFalse(p.is_in_subscript_string()) + def test_is_in_string(self): get = self.get_parser