[3.11] gh-103737: IDLE - Remove unneeded .keys() for dict iteration (GH-110960) (#111027)

gh-103737: IDLE - Remove unneeded .keys() for dict iteration (GH-110960)

Add comments where .keys() is needed.
Leave debugger usages along because situation is unclear as indicated in expanded comment.
Most testing is manual.
(cherry picked from commit baefbb21d9)

Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
This commit is contained in:
Miss Islington (bot) 2023-10-18 10:40:39 +02:00 committed by GitHub
parent 50d936a125
commit 7c308f4c64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 28 additions and 26 deletions

View file

@ -597,7 +597,9 @@ class IdleConf:
problem getting any core binding there will be an 'ultimate last problem getting any core binding there will be an 'ultimate last
resort fallback' to the CUA-ish bindings defined here. resort fallback' to the CUA-ish bindings defined here.
""" """
# TODO: = dict(sorted([(v-event, keys), ...]))?
keyBindings={ keyBindings={
# vitual-event: list of key events.
'<<copy>>': ['<Control-c>', '<Control-C>'], '<<copy>>': ['<Control-c>', '<Control-C>'],
'<<cut>>': ['<Control-x>', '<Control-X>'], '<<cut>>': ['<Control-x>', '<Control-X>'],
'<<paste>>': ['<Control-v>', '<Control-V>'], '<<paste>>': ['<Control-v>', '<Control-V>'],
@ -880,7 +882,7 @@ def _dump(): # htest # (not really, but ignore in coverage)
line, crc = 0, 0 line, crc = 0, 0
def sprint(obj): def sprint(obj):
global line, crc nonlocal line, crc
txt = str(obj) txt = str(obj)
line += 1 line += 1
crc = crc32(txt.encode(encoding='utf-8'), crc) crc = crc32(txt.encode(encoding='utf-8'), crc)
@ -889,7 +891,7 @@ def _dump(): # htest # (not really, but ignore in coverage)
def dumpCfg(cfg): def dumpCfg(cfg):
print('\n', cfg, '\n') # Cfg has variable '0xnnnnnnnn' address. print('\n', cfg, '\n') # Cfg has variable '0xnnnnnnnn' address.
for key in sorted(cfg.keys()): for key in sorted(cfg):
sections = cfg[key].sections() sections = cfg[key].sections()
sprint(key) sprint(key)
sprint(sections) sprint(sections)
@ -908,4 +910,6 @@ if __name__ == '__main__':
from unittest import main from unittest import main
main('idlelib.idle_test.test_config', verbosity=2, exit=False) main('idlelib.idle_test.test_config', verbosity=2, exit=False)
# Run revised _dump() as htest? _dump()
# Run revised _dump() (700+ lines) as htest? More sorting.
# Perhaps as window with tabs for textviews, making it config viewer.

View file

@ -211,14 +211,8 @@ class ConfigDialog(Toplevel):
contents=help_common+help_pages.get(page, '')) contents=help_common+help_pages.get(page, ''))
def deactivate_current_config(self): def deactivate_current_config(self):
"""Remove current key bindings. """Remove current key bindings in current windows."""
Iterate over window instances defined in parent and remove for instance in self.parent.instance_dict:
the keybindings.
"""
# Before a config is saved, some cleanup of current
# config must be done - remove the previous keybindings.
win_instances = self.parent.instance_dict.keys()
for instance in win_instances:
instance.RemoveKeybindings() instance.RemoveKeybindings()
def activate_config_changes(self): def activate_config_changes(self):
@ -227,8 +221,7 @@ class ConfigDialog(Toplevel):
Dynamically update the current parent window instances Dynamically update the current parent window instances
with some of the configuration changes. with some of the configuration changes.
""" """
win_instances = self.parent.instance_dict.keys() for instance in self.parent.instance_dict:
for instance in win_instances:
instance.ResetColorizer() instance.ResetColorizer()
instance.ResetFont() instance.ResetFont()
instance.set_notabs_indentwidth() instance.set_notabs_indentwidth()
@ -583,6 +576,8 @@ class HighPage(Frame):
(*)theme_message: Label (*)theme_message: Label
""" """
self.theme_elements = { self.theme_elements = {
# Display_name: ('internal_name, sort_number').
# TODO: remove sort_number unneeded with dict ordering.
'Normal Code or Text': ('normal', '00'), 'Normal Code or Text': ('normal', '00'),
'Code Context': ('context', '01'), 'Code Context': ('context', '01'),
'Python Keywords': ('keyword', '02'), 'Python Keywords': ('keyword', '02'),
@ -765,7 +760,7 @@ class HighPage(Frame):
self.builtinlist.SetMenu(item_list, item_list[0]) self.builtinlist.SetMenu(item_list, item_list[0])
self.set_theme_type() self.set_theme_type()
# Load theme element option menu. # Load theme element option menu.
theme_names = list(self.theme_elements.keys()) theme_names = list(self.theme_elements)
theme_names.sort(key=lambda x: self.theme_elements[x][1]) theme_names.sort(key=lambda x: self.theme_elements[x][1])
self.targetlist.SetMenu(theme_names, theme_names[0]) self.targetlist.SetMenu(theme_names, theme_names[0])
self.paint_theme_sample() self.paint_theme_sample()
@ -1477,12 +1472,13 @@ class KeysPage(Frame):
reselect = True reselect = True
list_index = self.bindingslist.index(ANCHOR) list_index = self.bindingslist.index(ANCHOR)
keyset = idleConf.GetKeySet(keyset_name) keyset = idleConf.GetKeySet(keyset_name)
bind_names = list(keyset.keys()) # 'set' is dict mapping virtual event to list of key events.
bind_names = list(keyset)
bind_names.sort() bind_names.sort()
self.bindingslist.delete(0, END) self.bindingslist.delete(0, END)
for bind_name in bind_names: for bind_name in bind_names:
key = ' '.join(keyset[bind_name]) key = ' '.join(keyset[bind_name])
bind_name = bind_name[2:-2] # Trim off the angle brackets. bind_name = bind_name[2:-2] # Trim double angle brackets.
if keyset_name in changes['keys']: if keyset_name in changes['keys']:
# Handle any unsaved changes to this key set. # Handle any unsaved changes to this key set.
if bind_name in changes['keys'][keyset_name]: if bind_name in changes['keys'][keyset_name]:

View file

@ -509,7 +509,7 @@ class NamespaceViewer:
# There is also an obscure bug in sorted(dict) where the # There is also an obscure bug in sorted(dict) where the
# interpreter gets into a loop requesting non-existing dict[0], # interpreter gets into a loop requesting non-existing dict[0],
# dict[1], dict[2], etc from the debugger_r.DictProxy. # dict[1], dict[2], etc from the debugger_r.DictProxy.
### # TODO recheck above; see debugger_r 159ff, debugobj 60.
keys_list = dict.keys() keys_list = dict.keys()
names = sorted(keys_list) names = sorted(keys_list)
### ###

View file

@ -93,7 +93,8 @@ class SequenceTreeItem(ObjectTreeItem):
class DictTreeItem(SequenceTreeItem): class DictTreeItem(SequenceTreeItem):
def keys(self): def keys(self):
keys = list(self.object.keys()) # TODO return sorted(self.object)
keys = list(self.object)
try: try:
keys.sort() keys.sort()
except: except:

View file

@ -274,8 +274,8 @@ class IdleConfTest(unittest.TestCase):
conf.CreateConfigHandlers() conf.CreateConfigHandlers()
# Check keys are equal # Check keys are equal
self.assertCountEqual(conf.defaultCfg.keys(), conf.config_types) self.assertCountEqual(conf.defaultCfg, conf.config_types)
self.assertCountEqual(conf.userCfg.keys(), conf.config_types) self.assertCountEqual(conf.userCfg, conf.config_types)
# Check conf parser are correct type # Check conf parser are correct type
for default_parser in conf.defaultCfg.values(): for default_parser in conf.defaultCfg.values():

View file

@ -37,7 +37,7 @@ class SequenceTreeItemTest(unittest.TestCase):
def test_keys(self): def test_keys(self):
ti = debugobj.SequenceTreeItem('label', 'abc') ti = debugobj.SequenceTreeItem('label', 'abc')
self.assertEqual(list(ti.keys()), [0, 1, 2]) self.assertEqual(list(ti.keys()), [0, 1, 2]) # keys() is a range.
class DictTreeItemTest(unittest.TestCase): class DictTreeItemTest(unittest.TestCase):
@ -50,7 +50,7 @@ class DictTreeItemTest(unittest.TestCase):
def test_keys(self): def test_keys(self):
ti = debugobj.DictTreeItem('label', {1:1, 0:0, 2:2}) ti = debugobj.DictTreeItem('label', {1:1, 0:0, 2:2})
self.assertEqual(ti.keys(), [0, 1, 2]) self.assertEqual(ti.keys(), [0, 1, 2]) # keys() is a sorted list.
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -747,10 +747,11 @@ class ModifiedInterpreter(InteractiveInterpreter):
self.tkconsole.open_stack_viewer() self.tkconsole.open_stack_viewer()
def checklinecache(self): def checklinecache(self):
c = linecache.cache "Remove keys other than '<pyshell#n>'."
for key in list(c.keys()): cache = linecache.cache
for key in list(cache): # Iterate list because mutate cache.
if key[:1] + key[-1:] != "<>": if key[:1] + key[-1:] != "<>":
del c[key] del cache[key]
def runcommand(self, code): def runcommand(self, code):
"Run the code without invoking the debugger" "Run the code without invoking the debugger"

View file

@ -99,7 +99,7 @@ class VariablesTreeItem(ObjectTreeItem):
def GetSubList(self): def GetSubList(self):
sublist = [] sublist = []
for key in self.object.keys(): for key in self.object.keys(): # self.object not necessarily dict.
try: try:
value = self.object[key] value = self.object[key]
except KeyError: except KeyError: