From 347f05b703f01afa12a327080d8484ba8fa0eeb5 Mon Sep 17 00:00:00 2001 From: "E. Paine" <63801254+E-Paine@users.noreply.github.com> Date: Tue, 20 Apr 2021 17:11:54 +0100 Subject: [PATCH 1/5] Editor reformat --- Lib/idlelib/configdialog.py | 8 +- Lib/idlelib/editor.py | 254 ++++++++++++----------- Lib/idlelib/idle_test/template.py | 1 - Lib/idlelib/idle_test/test_debugger_r.py | 4 +- Lib/idlelib/idle_test/test_editor.py | 1 - Lib/idlelib/idle_test/test_squeezer.py | 1 - Lib/idlelib/iomenu.py | 1 - 7 files changed, 142 insertions(+), 128 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index c52a04b503adb4..d03c3102e8a117 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -225,7 +225,7 @@ def deactivate_current_config(self): # config must be done - remove the previous keybindings. win_instances = self.parent.instance_dict.keys() for instance in win_instances: - instance.RemoveKeybindings() + instance.remove_keybindings() def activate_config_changes(self): """Apply configuration changes to current windows. @@ -235,10 +235,10 @@ def activate_config_changes(self): """ win_instances = self.parent.instance_dict.keys() for instance in win_instances: - instance.ResetColorizer() - instance.ResetFont() + instance.reset_colors() + instance.reset_font() instance.set_notabs_indentwidth() - instance.ApplyKeybindings() + instance.apply_keybindings() instance.reset_help_menu_entries() instance.update_cursor_blink() for klass in reloadables: diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index b9cb50264ff06f..04286cc883d2d0 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -34,8 +34,9 @@ _py_version = ' (%s)' % platform.python_version() darwin = sys.platform == 'darwin' + def _sphinx_version(): - "Format sys.version_info to produce the Sphinx version string used to install the chm docs" + """Format sys.version_info to produce the Sphinx version string used to install the chm docs""" major, minor, micro, level, serial = sys.version_info release = '%s%s' % (major, minor) release += '%s' % (micro,) @@ -50,7 +51,7 @@ class EditorWindow: from idlelib.percolator import Percolator from idlelib.colorizer import ColorDelegator, color_config from idlelib.undo import UndoDelegator - from idlelib.iomenu import IOBinding, encoding + from idlelib.iomenu import IOBinding from idlelib import mainmenu from idlelib.statusbar import MultiStatusBar from idlelib.autocomplete import AutoComplete @@ -74,7 +75,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): from idlelib.runscript import ScriptBinding if EditorWindow.help_url is None: - dochome = os.path.join(sys.base_prefix, 'Doc', 'index.html') + dochome = os.path.join(sys.base_prefix, 'Doc', 'index.html') if sys.platform.count('linux'): # look for html docs in a couple of standard places pyver = 'python-docs-' + '%s.%s.%s' % sys.version_info[:3] @@ -92,7 +93,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): elif sys.platform == 'darwin': # documentation may be stored inside a python framework dochome = os.path.join(sys.base_prefix, - 'Resources/English.lproj/Documentation/index.html') + 'Resources/English.lproj/Documentation/index.html') dochome = os.path.normpath(dochome) if os.path.isfile(dochome): EditorWindow.help_url = dochome @@ -109,30 +110,30 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.top = top = window.ListedToplevel(root, menu=self.menubar) if flist: self.tkinter_vars = flist.vars - #self.top.instance_dict makes flist.inversedict available to - #configdialog.py so it can access all EditorWindow instances + # self.top.instance_dict makes flist.inversedict available to + # configdialog.py so it can access all EditorWindow instances self.top.instance_dict = flist.inversedict else: self.tkinter_vars = {} # keys: Tkinter event names # values: Tkinter variable instances self.top.instance_dict = {} self.recent_files_path = idleConf.userdir and os.path.join( - idleConf.userdir, 'recent-files.lst') + idleConf.userdir, 'recent-files.lst') self.prompt_last_line = '' # Override in PyShell self.text_frame = text_frame = Frame(top) self.vbar = vbar = Scrollbar(text_frame, name='vbar') width = idleConf.GetOption('main', 'EditorWindow', 'width', type='int') text_options = { - 'name': 'text', - 'padx': 5, - 'wrap': 'none', - 'highlightthickness': 0, - 'width': width, - 'tabstyle': 'wordprocessor', # new in 8.5 - 'height': idleConf.GetOption( - 'main', 'EditorWindow', 'height', type='int'), - } + 'name': 'text', + 'padx': 5, + 'wrap': 'none', + 'highlightthickness': 0, + 'width': width, + 'tabstyle': 'wordprocessor', # new in 8.5 + 'height': idleConf.GetOption( + 'main', 'EditorWindow', 'height', type='int'), + } self.text = text = MultiCallCreator(Text)(text_frame, **text_options) self.top.focused_widget = self.text @@ -147,11 +148,11 @@ def __init__(self, flist=None, filename=None, key=None, root=None): # Some OS X systems have only one mouse button, so use # control-click for popup context menus there. For two # buttons, AquaTk defines <2> as the right button, not <3>. - text.bind("",self.right_menu_event) + text.bind("", self.right_menu_event) text.bind("<2>", self.right_menu_event) else: # Elsewhere, use right-click for popup menus. - text.bind("<3>",self.right_menu_event) + text.bind("<3>", self.right_menu_event) text.bind('', wheel_event) text.bind('', wheel_event) @@ -175,9 +176,9 @@ def __init__(self, flist=None, filename=None, key=None, root=None): text.bind("<>", self.find_selection_event) text.bind("<>", self.replace_event) text.bind("<>", self.goto_line_event) - text.bind("<>",self.smart_backspace_event) - text.bind("<>",self.newline_and_indent_event) - text.bind("<>",self.smart_indent_event) + text.bind("<>", self.smart_backspace_event) + text.bind("<>", self.newline_and_indent_event) + text.bind("<>", self.smart_indent_event) self.fregion = fregion = self.FormatRegion(self) # self.fregion used in smart_indent_event to access indent_region. text.bind("<>", fregion.indent_region_event) @@ -235,7 +236,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): # tab setting causes it to use an entirely different tabbing algorithm, # treating tab stops as fixed distances from the left margin. # Nobody expects this, so for now tabwidth should never be changed. - self.tabwidth = 8 # must remain 8 until Tk is fixed. + self.tabwidth = 8 # must remain 8 until Tk is fixed. # indentwidth is the number of screen characters per indent level. # The recommended Python indentation is four spaces. @@ -266,9 +267,9 @@ def __init__(self, flist=None, filename=None, key=None, root=None): io.set_filename_change_hook(self.filename_change_hook) self.good_load = False self.set_indentation_params(False) - self.color = None # initialized below in self.ResetColorizer - self.code_context = None # optionally initialized later below - self.line_numbers = None # optionally initialized later below + self.color = None # initialized below in self.ResetColorizer + self.code_context = None # optionally initialized later below + self.line_numbers = None # optionally initialized later below if filename: if os.path.exists(filename) and not os.path.isdir(filename): if io.loadfile(filename): @@ -279,7 +280,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): io.set_filename(filename) self.good_load = True - self.ResetColorizer() + self.reset_colors() self.saved_change_hook() self.update_recent_files_list() self.load_extensions() @@ -330,7 +331,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): text.bind("<>", self.Rstrip(self).do_rstrip) self.ctip = ctip = self.Calltip(self) text.bind("<>", ctip.try_open_calltip_event) - #refresh-calltip must come after paren-closed to work right + # refresh-calltip must come after paren-closed to work right text.bind("<>", ctip.refresh_calltip_event) text.bind("<>", ctip.force_open_calltip_event) text.bind("<>", self.ZoomHeight(self).zoom_height_event) @@ -375,22 +376,22 @@ def home_callback(self, event): # state&4==Control. If , use the Tk binding. return None if self.text.index("iomark") and \ - self.text.compare("iomark", "<=", "insert lineend") and \ - self.text.compare("insert linestart", "<=", "iomark"): + self.text.compare("iomark", "<=", "insert lineend") and \ + self.text.compare("insert linestart", "<=", "iomark"): # In Shell on input line, go to just after prompt insertpt = int(self.text.index("iomark").split(".")[1]) else: line = self.text.get("insert linestart", "insert lineend") for insertpt in range(len(line)): - if line[insertpt] not in (' ','\t'): + if line[insertpt] not in (' ', '\t'): break else: - insertpt=len(line) + insertpt = len(line) lineat = int(self.text.index("insert").split('.')[1]) if insertpt == lineat: insertpt = 0 - dest = "insert linestart+"+str(insertpt)+"c" - if (event.state&1) == 0: + dest = "insert linestart+" + str(insertpt) + "c" + if (event.state & 1) == 0: # shift was not pressed self.text.tag_remove("sel", "1.0", "end") else: @@ -400,13 +401,13 @@ def home_callback(self, event): else: if self.text.compare(self.text.index("sel.first"), "<", self.text.index("insert")): - self.text.mark_set("my_anchor", "sel.first") # extend back + self.text.mark_set("my_anchor", "sel.first") # extend back else: - self.text.mark_set("my_anchor", "sel.last") # extend forward + self.text.mark_set("my_anchor", "sel.last") # extend forward first = self.text.index(dest) last = self.text.index("my_anchor") - if self.text.compare(first,">",last): - first,last = last,first + if self.text.compare(first, ">", last): + first, last = last, first self.text.tag_remove("sel", "1.0", "end") self.text.tag_add("sel", first, last) self.text.mark_set("insert", dest) @@ -444,7 +445,6 @@ def set_line_and_column(self, event=None): ("help", "_Help"), ] - def createmenubar(self): mbar = self.menubar self.menudict = menudict = {} @@ -474,21 +474,21 @@ def postwindowsmenu(self): if end is None: end = -1 if end > self.wmenu_end: - menu.delete(self.wmenu_end+1, end) + menu.delete(self.wmenu_end + 1, end) window.add_windows_to_menu(menu) def update_menu_label(self, menu, index, label): - "Update label for menu item at index." + """Update label for menu item at index.""" menuitem = self.menudict[menu] menuitem.entryconfig(index, label=label) def update_menu_state(self, menu, index, state): - "Update state for menu item at index." + """Update state for menu item at index.""" menuitem = self.menudict[menu] menuitem.entryconfig(index, state=state) def handle_yview(self, event, *args): - "Handle scrollbar." + """Handle scrollbar.""" if event == 'moveto': fraction = float(args[0]) lines = (round(self.getlineno('end') * fraction) - @@ -505,7 +505,7 @@ def right_menu_event(self, event): newdex = text.index(f'@{event.x},{event.y}') try: in_selection = (text.compare('sel.first', '<=', newdex) and - text.compare(newdex, '<=', 'sel.last')) + text.compare(newdex, '<=', 'sel.last')) except TclError: in_selection = False if not in_selection: @@ -522,7 +522,7 @@ def right_menu_event(self, event): for item in self.rmenu_specs: try: label, eventname, verify_state = item - except ValueError: # see issue1207589 + except ValueError: # see issue1207589 continue if verify_state is None: @@ -537,7 +537,7 @@ def right_menu_event(self, event): rmenu_specs = [ # ("Label", "<>", "statefuncname"), ... - ("Close", "<>", None), # Example + ("Close", "<>", None), # Example ] def make_rmenu(self): @@ -547,6 +547,7 @@ def make_rmenu(self): if label is not None: def command(text=self.text, eventname=eventname): text.event_generate(eventname) + rmenu.add_command(label=label, command=command) else: rmenu.add_separator() @@ -572,19 +573,19 @@ def rmenu_check_paste(self): return 'normal' def about_dialog(self, event=None): - "Handle Help 'About IDLE' event." + """Handle Help 'About IDLE' event.""" # Synchronize with macosx.overrideRootMenu.about_dialog. help_about.AboutDialog(self.top) return "break" def config_dialog(self, event=None): - "Handle Options 'Configure IDLE' event." + """Handle Options 'Configure IDLE' event.""" # Synchronize with macosx.overrideRootMenu.config_dialog. - configdialog.ConfigDialog(self.top,'Settings') + configdialog.ConfigDialog(self.top, 'Settings') return "break" def help_dialog(self, event=None): - "Handle Help 'IDLE Help' event." + """Handle Help 'IDLE Help' event.""" # Synchronize with macosx.overrideRootMenu.help_dialog. if self.root: parent = self.root @@ -598,24 +599,25 @@ def python_docs(self, event=None): try: os.startfile(self.help_url) except OSError as why: - messagebox.showerror(title='Document Start Failure', + messagebox.showerror( + title='Document Start Failure', message=str(why), parent=self.text) else: webbrowser.open(self.help_url) return "break" - def cut(self,event): + def cut(self, event): self.text.event_generate("<>") return "break" - def copy(self,event): + def copy(self, event): if not self.text.tag_ranges("sel"): # There is no selection, so do nothing and maybe interrupt. return None self.text.event_generate("<>") return "break" - def paste(self,event): + def paste(self, event): self.text.event_generate("<>") self.text.see("insert") return "break" @@ -642,13 +644,15 @@ def move_at_edge_if_selection(self, edge_index): self_text_index = self.text.index self_text_mark_set = self.text.mark_set edges_table = ("sel.first+1c", "sel.last-1c") + def move_at_edge(event): - if (event.state & 5) == 0: # no shift(==1) or control(==4) pressed + if (event.state & 5) == 0: # no shift(==1) or control(==4) pressed try: self_text_index("sel.first") self_text_mark_set("insert", edges_table[edge_index]) except TclError: pass + return move_at_edge def del_word_left(self, event): @@ -682,10 +686,10 @@ def replace_event(self, event): def goto_line_event(self, event): text = self.text lineno = query.Goto( - text, "Go To Line", - "Enter a positive integer\n" - "('big' = end of file):" - ).result + text, "Go To Line", + "Enter a positive integer\n" + "('big' = end of file):" + ).result if lineno is not None: text.tag_remove("sel", "1.0", "end") text.mark_set("insert", f'{lineno}.0') @@ -706,10 +710,10 @@ def open_module(self): except TclError: name = '' file_path = query.ModuleName( - self.text, "Open Module", - "Enter the name of a Python module\n" - "to search on sys.path and open:", - name).result + self.text, "Open Module", + "Enter the name of a Python module\n" + "to search on sys.path and open:", + name).result if file_path is not None: if self.flist: self.flist.open(file_path) @@ -737,7 +741,7 @@ def open_path_browser(self, event=None): pathbrowser.PathBrowser(self.root) return "break" - def open_turtle_demo(self, event = None): + def open_turtle_demo(self, event=None): import subprocess cmd = [sys.executable, @@ -775,10 +779,10 @@ def filename_change_hook(self): self.flist.filename_changed_edit(self) self.saved_change_hook() self.top.update_windowlist_registry(self) - self.ResetColorizer() + self.reset_colors() def _addcolorizer(self): - if self.color: + if self.color is not None: return if self.ispythonsource(self.io.filename): self.color = self.ColorDelegator() @@ -789,14 +793,14 @@ def _addcolorizer(self): self.per.insertfilter(self.undo) def _rmcolorizer(self): - if not self.color: + if self.color is None: return self.color.removecolors() self.per.removefilter(self.color) self.color = None - def ResetColorizer(self): - "Update the color theme" + def reset_colors(self): + """Update the color theme""" # Called from self.filename_change_hook and from configdialog.py self._rmcolorizer() self._addcolorizer() @@ -815,24 +819,24 @@ def colorize_syntax_error(self, text, pos): char = text.get(pos) if char and char in self.IDENTCHARS: text.tag_add("ERROR", pos + " wordstart", pos) - if '\n' == text.get(pos): # error at line end + if '\n' == text.get(pos): # error at line end text.mark_set("insert", pos) else: text.mark_set("insert", pos + "+1c") text.see(pos) def update_cursor_blink(self): - "Update the cursor blink configuration." + """Update the cursor blink configuration.""" cursorblink = idleConf.GetOption( - 'main', 'EditorWindow', 'cursor-blink', type='bool') + 'main', 'EditorWindow', 'cursor-blink', type='bool') if not cursorblink: self.text['insertofftime'] = 0 else: # Restore the original value self.text['insertofftime'] = idleConf.blink_off_time - def ResetFont(self): - "Update the text widgets' font if it is changed" + def reset_font(self): + """Update the text widgets' font if it is changed""" # Called from configdialog.py # Update the code context widget first, since its height affects @@ -848,8 +852,8 @@ def ResetFont(self): self.text['font'] = new_font self.set_width() - def RemoveKeybindings(self): - "Remove the keybindings before they are changed." + def remove_keybindings(self): + """Remove the keybindings before they are changed.""" # Called from configdialog.py self.mainmenu.default_keydefs = keydefs = idleConf.GetCurrentKeySet() for event, keylist in keydefs.items(): @@ -860,8 +864,8 @@ def RemoveKeybindings(self): for event, keylist in xkeydefs.items(): self.text.event_delete(event, *keylist) - def ApplyKeybindings(self): - "Update the keybindings after they are changed" + def apply_keybindings(self): + """Update the keybindings after they are changed""" # Called from configdialog.py self.mainmenu.default_keydefs = keydefs = idleConf.GetCurrentKeySet() self.apply_bindings() @@ -869,15 +873,15 @@ def ApplyKeybindings(self): xkeydefs = idleConf.GetExtensionBindings(extensionName) if xkeydefs: self.apply_bindings(xkeydefs) - #update menu accelerators - menuEventDict = {} + # update menu accelerators + menu_event_dict = {} for menu in self.mainmenu.menudefs: - menuEventDict[menu[0]] = {} + menu_event_dict[menu[0]] = {} for item in menu[1]: if item: - menuEventDict[menu[0]][prepstr(item[0])[1]] = item[1] - for menubarItem in self.menudict: - menu = self.menudict[menubarItem] + menu_event_dict[menu[0]][prepstr(item[0])[1]] = item[1] + for menubar_item in self.menudict: + menu = self.menudict[menubar_item] end = menu.index(END) if end is None: # Skip empty menus @@ -887,24 +891,24 @@ def ApplyKeybindings(self): if menu.type(index) == 'command': accel = menu.entrycget(index, 'accelerator') if accel: - itemName = menu.entrycget(index, 'label') + item_name = menu.entrycget(index, 'label') event = '' - if menubarItem in menuEventDict: - if itemName in menuEventDict[menubarItem]: - event = menuEventDict[menubarItem][itemName] + if menubar_item in menu_event_dict: + if item_name in menu_event_dict[menubar_item]: + event = menu_event_dict[menubar_item][item_name] if event: accel = get_accelerator(keydefs, event) menu.entryconfig(index, accelerator=accel) def set_notabs_indentwidth(self): - "Update the indentwidth if changed and not using tabs in this window" + """Update the indentwidth if changed and not using tabs in this window""" # Called from configdialog.py if not self.usetabs: - self.indentwidth = idleConf.GetOption('main', 'Indent','num-spaces', + self.indentwidth = idleConf.GetOption('main', 'Indent', 'num-spaces', type='int') def reset_help_menu_entries(self): - "Update the additional help entries on the Help menu" + """Update the additional help entries on the Help menu""" help_list = idleConf.GetAllExtraHelpSourcesList() helpmenu = self.menudict['help'] # first delete the extra help entries, if any @@ -921,7 +925,8 @@ def reset_help_menu_entries(self): self.menudict['help'] = helpmenu def __extra_help_callback(self, helpfile): - "Create a callback with the helpfile value frozen at definition time" + """Create a callback with the helpfile value frozen at definition time""" + def display_extra_help(helpfile=helpfile): if not helpfile.startswith(('www', 'http')): helpfile = os.path.normpath(helpfile) @@ -929,14 +934,16 @@ def display_extra_help(helpfile=helpfile): try: os.startfile(helpfile) except OSError as why: - messagebox.showerror(title='Document Start Failure', + messagebox.showerror( + title='Document Start Failure', message=str(why), parent=self.text) else: webbrowser.open(helpfile) + return display_extra_help def update_recent_files_list(self, new_file=None): - "Load and update the recent files list and menus" + """Load and update the recent files list and menus""" # TODO: move to iomenu. rf_list = [] file_path = self.recent_files_path @@ -965,7 +972,8 @@ def update_recent_files_list(self, new_file=None): except OSError as err: if not getattr(self.root, "recentfiles_message", False): self.root.recentfiles_message = True - messagebox.showwarning(title='IDLE Warning', + messagebox.showwarning( + title='IDLE Warning', message="Cannot save Recent Files list to disk.\n" f" {err}\n" "Select OK to continue.", @@ -984,6 +992,7 @@ def update_recent_files_list(self, new_file=None): def __recent_file_callback(self, file_name): def open_recent_file(fn_closure=file_name): self.io.open(editFile=fn_closure) + return open_recent_file def saved_change_hook(self): @@ -1029,7 +1038,7 @@ def center(self, mark="insert"): top, bot = self.getwindowlines() lineno = self.getlineno(mark) height = bot - top - newtop = max(1, lineno - height//2) + newtop = max(1, lineno - height // 2) text.yview(float(newtop)) def getwindowlines(self): @@ -1047,7 +1056,7 @@ def getlineno(self, mark="insert"): return int(float(text.index(mark))) def get_geometry(self): - "Return (width, height, x, y)" + """Return (width, height, x, y)""" geom = self.top.wm_geometry() m = re.match(r"(\d+)x(\d+)\+(-?\d+)\+(-?\d+)", geom) return list(map(int, m.groups())) @@ -1059,7 +1068,7 @@ def close_event(self, event): def maybesave(self): if self.io: if not self.get_saved(): - if self.top.state()!='normal': + if self.top.state() != 'normal': self.top.deiconify() self.top.lower() self.top.lift() @@ -1117,7 +1126,7 @@ def get_standard_extension_names(self): extfiles = { # Map built-in config-extension section names to file names. 'ZzDummy': 'zzdummy', - } + } def load_extension(self, name): fname = self.extfiles.get(name, name) @@ -1181,13 +1190,15 @@ def fill_menus(self, menudefs=None, keydefs=None): label = label[1:] underline, label = prepstr(label) accelerator = get_accelerator(keydefs, eventname) + def command(text=text, eventname=eventname): text.event_generate(eventname) + if checkbutton: var = self.get_var_obj(eventname, BooleanVar) menu.add_checkbutton(label=label, underline=underline, - command=command, accelerator=accelerator, - variable=var) + command=command, accelerator=accelerator, + variable=var) else: menu.add_command(label=label, underline=underline, command=command, @@ -1262,7 +1273,7 @@ def set_tk_tabwidth(self, newtabwidth): "n" * newtabwidth) text.configure(tabs=pixels) -### begin autoindent code ### (configuration was moved to beginning of class) + ### begin autoindent code ### (configuration was moved to beginning of class) def set_indentation_params(self, is_py_src, guess=True): if is_py_src and guess: @@ -1288,9 +1299,9 @@ def smart_backspace_event(self, event): # easy: delete preceding newline text.delete("insert-1c") else: - text.bell() # at start of buffer + text.bell() # at start of buffer return "break" - if chars[-1] not in " \t": + if chars[-1] not in " \t": # easy: delete preceding real char text.delete("insert-1c") return "break" @@ -1407,7 +1418,7 @@ def newline_and_indent_event(self, event): rawtext = text.get(startatindex, "insert") y.set_code(rawtext) bod = y.find_good_parse_start( - self._build_char_in_string_func(startatindex)) + self._build_char_in_string_func(startatindex)) if bod is not None or startat == 1: break y.set_lo(bod or 0) @@ -1474,6 +1485,7 @@ def _build_char_in_string_func(self, startindex): def inner(offset, _startindex=startindex, _icis=self.is_char_in_string): return _icis(_startindex + "+%dc" % offset) + return inner # XXX this isn't bound to anything -- see tabwidth comments @@ -1532,12 +1544,14 @@ def toggle_line_numbers_event(self, event=None): self.update_menu_label(menu='options', index='*ine*umbers', label=f'{menu_label} Line Numbers') + # "line.col" -> line, as an int def index2line(index): return int(float(index)) _line_indent_re = re.compile(r'[ \t]*') + def get_line_indent(line, tabwidth): """Return a line's indentation as (# chars, effective # of spaces). @@ -1571,14 +1585,14 @@ def readline(self): return self.text.get(mark, mark + " lineend+1c") def tokeneater(self, type, token, start, end, line, - INDENT=tokenize.INDENT, - NAME=tokenize.NAME, - OPENERS=('class', 'def', 'for', 'if', 'try', 'while')): + indent=tokenize.INDENT, + name=tokenize.NAME, + openers=('class', 'def', 'for', 'if', 'try', 'while')): if self.finished: pass - elif type == NAME and token in OPENERS: + elif type == name and token in openers: self.blkopenline = line - elif type == INDENT and self.blkopenline: + elif type == indent and self.blkopenline: self.indentedline = line self.finished = 1 @@ -1600,6 +1614,7 @@ def run(self): ### end autoindent code ### + def prepstr(s): # Helper to extract the underscore from a string, e.g. # prepstr("Co_py") returns (2, "Copy"). @@ -1610,25 +1625,27 @@ def prepstr(s): keynames = { - 'bracketleft': '[', - 'bracketright': ']', - 'slash': '/', + 'bracketleft': '[', + 'bracketright': ']', + 'slash': '/', } + def get_accelerator(keydefs, eventname): keylist = keydefs.get(eventname) # issue10940: temporary workaround to prevent hang with OS X Cocoa Tk 8.5 # if not keylist: - if (not keylist) or (macosx.isCocoaTk() and eventname in { - "<>", - "<>", - "<>"}): + if (not keylist) or ( + macosx.isCocoaTk() and eventname in { + "<>", + "<>", + "<>"}): return "" s = keylist[0] s = re.sub(r"-[a-z]\b", lambda m: m.group().upper(), s) s = re.sub(r"\b\w+\b", lambda m: keynames.get(m.group(), m.group()), s) s = re.sub("Key-", "", s) - s = re.sub("Cancel","Ctrl-Break",s) # dscherer@cmu.edu + s = re.sub("Cancel", "Ctrl-Break", s) # dscherer@cmu.edu s = re.sub("Control-", "Ctrl-", s) s = re.sub("-", "+", s) s = re.sub("><", " ", s) @@ -1641,7 +1658,7 @@ def fixwordbreaks(root): # On Windows, tcl/tk breaks 'words' only on spaces, as in Command Prompt. # We want Motif style everywhere. See #21474, msg218992 and followup. tk = root.tk - tk.call('tcl_wordBreakAfter', 'a b', 0) # make sure word.tcl is loaded + tk.call('tcl_wordBreakAfter', 'a b', 0) # make sure word.tcl is loaded tk.call('set', 'tcl_wordchars', r'\w') tk.call('set', 'tcl_nonwordchars', r'\W') @@ -1664,6 +1681,7 @@ def _editor_window(parent): # htest # # Does not stop error, neither does following # edit.text.bind("<>", edit.close_event) + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_editor', verbosity=2, exit=False) diff --git a/Lib/idlelib/idle_test/template.py b/Lib/idlelib/idle_test/template.py index 725a55b9c47230..6e98556458ec58 100644 --- a/Lib/idlelib/idle_test/template.py +++ b/Lib/idlelib/idle_test/template.py @@ -1,6 +1,5 @@ "Test , coverage %." -from idlelib import zzdummy import unittest from test.support import requires from tkinter import Tk diff --git a/Lib/idlelib/idle_test/test_debugger_r.py b/Lib/idlelib/idle_test/test_debugger_r.py index 638ebd36a7405d..afb9c040d285a1 100644 --- a/Lib/idlelib/idle_test/test_debugger_r.py +++ b/Lib/idlelib/idle_test/test_debugger_r.py @@ -2,8 +2,8 @@ from idlelib import debugger_r import unittest -from test.support import requires -from tkinter import Tk +## from test.support import requires +## from tkinter import Tk class Test(unittest.TestCase): diff --git a/Lib/idlelib/idle_test/test_editor.py b/Lib/idlelib/idle_test/test_editor.py index 443dcf021679fc..786a67d28c70b3 100644 --- a/Lib/idlelib/idle_test/test_editor.py +++ b/Lib/idlelib/idle_test/test_editor.py @@ -5,7 +5,6 @@ from collections import namedtuple from test.support import requires from tkinter import Tk -from idlelib.idle_test.mock_idle import Func Editor = editor.EditorWindow diff --git a/Lib/idlelib/idle_test/test_squeezer.py b/Lib/idlelib/idle_test/test_squeezer.py index ee1bbd76b50562..c9baea89f0bfa3 100644 --- a/Lib/idlelib/idle_test/test_squeezer.py +++ b/Lib/idlelib/idle_test/test_squeezer.py @@ -12,7 +12,6 @@ from idlelib import macosx from idlelib.textview import view_text from idlelib.tooltip import Hovertip -from idlelib.pyshell import PyShell SENTINEL_VALUE = sentinel.SENTINEL_VALUE diff --git a/Lib/idlelib/iomenu.py b/Lib/idlelib/iomenu.py index 5ebf7089fb9abe..8562dccf225588 100644 --- a/Lib/idlelib/iomenu.py +++ b/Lib/idlelib/iomenu.py @@ -9,7 +9,6 @@ from tkinter import messagebox from tkinter.simpledialog import askstring -import idlelib from idlelib.config import idleConf encoding = 'utf-8' From b0eb61ef08196c8b0d49396afc4b1691a4abdc4a Mon Sep 17 00:00:00 2001 From: "E. Paine" <63801254+E-Paine@users.noreply.github.com> Date: Fri, 23 Apr 2021 15:07:48 +0100 Subject: [PATCH 2/5] Make changes consistent #25479 (todo: conditional expressions) --- Lib/idlelib/editor.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 04286cc883d2d0..7bafba1edc2dc0 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -133,7 +133,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): 'tabstyle': 'wordprocessor', # new in 8.5 'height': idleConf.GetOption( 'main', 'EditorWindow', 'height', type='int'), - } + } self.text = text = MultiCallCreator(Text)(text_frame, **text_options) self.top.focused_widget = self.text @@ -390,8 +390,8 @@ def home_callback(self, event): lineat = int(self.text.index("insert").split('.')[1]) if insertpt == lineat: insertpt = 0 - dest = "insert linestart+" + str(insertpt) + "c" - if (event.state & 1) == 0: + dest = "insert linestart+"+str(insertpt)+"c" + if (event.state&1) == 0: # shift was not pressed self.text.tag_remove("sel", "1.0", "end") else: @@ -443,7 +443,7 @@ def set_line_and_column(self, event=None): ("options", "_Options"), ("window", "_Window"), ("help", "_Help"), - ] + ] def createmenubar(self): mbar = self.menubar @@ -474,7 +474,7 @@ def postwindowsmenu(self): if end is None: end = -1 if end > self.wmenu_end: - menu.delete(self.wmenu_end + 1, end) + menu.delete(self.wmenu_end+1, end) window.add_windows_to_menu(menu) def update_menu_label(self, menu, index, label): @@ -538,7 +538,7 @@ def right_menu_event(self, event): rmenu_specs = [ # ("Label", "<>", "statefuncname"), ... ("Close", "<>", None), # Example - ] + ] def make_rmenu(self): rmenu = Menu(self.text, tearoff=0) @@ -689,7 +689,7 @@ def goto_line_event(self, event): text, "Go To Line", "Enter a positive integer\n" "('big' = end of file):" - ).result + ).result if lineno is not None: text.tag_remove("sel", "1.0", "end") text.mark_set("insert", f'{lineno}.0') @@ -1126,7 +1126,7 @@ def get_standard_extension_names(self): extfiles = { # Map built-in config-extension section names to file names. 'ZzDummy': 'zzdummy', - } + } def load_extension(self, name): fname = self.extfiles.get(name, name) @@ -1628,7 +1628,7 @@ def prepstr(s): 'bracketleft': '[', 'bracketright': ']', 'slash': '/', -} + } def get_accelerator(keydefs, eventname): From 60981ac087b68352e41a35ad719fdce9ac58ee0a Mon Sep 17 00:00:00 2001 From: "E. Paine" <63801254+E-Paine@users.noreply.github.com> Date: Fri, 23 Apr 2021 17:44:29 +0100 Subject: [PATCH 3/5] Added explicit checks for None --- Lib/idlelib/editor.py | 73 +++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 7bafba1edc2dc0..00f6c4c74ab7bb 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -76,7 +76,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): if EditorWindow.help_url is None: dochome = os.path.join(sys.base_prefix, 'Doc', 'index.html') - if sys.platform.count('linux'): + if 'linux' in sys.platform: # look for html docs in a couple of standard places pyver = 'python-docs-' + '%s.%s.%s' % sys.version_info[:3] if os.path.isdir('/var/www/html/python/'): # "python2" rpm @@ -108,7 +108,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.root = root self.menubar = Menu(root) self.top = top = window.ListedToplevel(root, menu=self.menubar) - if flist: + if flist is not None: self.tkinter_vars = flist.vars # self.top.instance_dict makes flist.inversedict available to # configdialog.py so it can access all EditorWindow instances @@ -196,9 +196,9 @@ def __init__(self, flist=None, filename=None, key=None, root=None): text.bind("<>", self.del_word_right) text.bind("<>", self.home_callback) - if flist: + if flist is not None: flist.inversedict[self] = key - if key: + if key is not None: flist.dict[key] = self text.bind("<>", self.new_callback) text.bind("<>", self.flist.close_all_callback) @@ -270,7 +270,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.color = None # initialized below in self.ResetColorizer self.code_context = None # optionally initialized later below self.line_numbers = None # optionally initialized later below - if filename: + if filename is not None: if os.path.exists(filename) and not os.path.isdir(filename): if io.loadfile(filename): self.good_load = True @@ -285,7 +285,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.update_recent_files_list() self.load_extensions() menu = self.menudict.get('window') - if menu: + if menu is not None: end = menu.index("end") if end is None: end = -1 @@ -382,8 +382,8 @@ def home_callback(self, event): insertpt = int(self.text.index("iomark").split(".")[1]) else: line = self.text.get("insert linestart", "insert lineend") - for insertpt in range(len(line)): - if line[insertpt] not in (' ', '\t'): + for insertpt, char in enumerate(line): + if char not in (' ', '\t'): break else: insertpt = len(line) @@ -391,7 +391,7 @@ def home_callback(self, event): if insertpt == lineat: insertpt = 0 dest = "insert linestart+"+str(insertpt)+"c" - if (event.state&1) == 0: + if (event.state & 1) == 0: # shift was not pressed self.text.tag_remove("sel", "1.0", "end") else: @@ -511,7 +511,7 @@ def right_menu_event(self, event): if not in_selection: text.tag_remove("sel", "1.0", "end") text.mark_set("insert", newdex) - if not self.rmenu: + if self.rmenu is not None: self.make_rmenu() rmenu = self.rmenu self.event = event @@ -587,7 +587,7 @@ def config_dialog(self, event=None): def help_dialog(self, event=None): """Handle Help 'IDLE Help' event.""" # Synchronize with macosx.overrideRootMenu.help_dialog. - if self.root: + if self.root is not None: parent = self.root else: parent = self.top @@ -715,7 +715,7 @@ def open_module(self): "to search on sys.path and open:", name).result if file_path is not None: - if self.flist: + if self.flist is not None: self.flist.open(file_path) else: self.io.loadfile(file_path) @@ -767,7 +767,7 @@ def ispythonsource(self, filename): return line.startswith('#!') and 'python' in line def close_hook(self): - if self.flist: + if self.flist is not None: self.flist.unregister_maybe_terminate(self) self.flist = None @@ -775,7 +775,7 @@ def set_close_hook(self, close_hook): self.close_hook = close_hook def filename_change_hook(self): - if self.flist: + if self.flist is not None: self.flist.filename_changed_edit(self) self.saved_change_hook() self.top.update_windowlist_registry(self) @@ -787,7 +787,7 @@ def _addcolorizer(self): if self.ispythonsource(self.io.filename): self.color = self.ColorDelegator() # can add more colorizers here... - if self.color: + if self.color is not None: self.per.removefilter(self.undo) self.per.insertfilter(self.color) self.per.insertfilter(self.undo) @@ -819,7 +819,7 @@ def colorize_syntax_error(self, text, pos): char = text.get(pos) if char and char in self.IDENTCHARS: text.tag_add("ERROR", pos + " wordstart", pos) - if '\n' == text.get(pos): # error at line end + if char == '\n': # error at line end text.mark_set("insert", pos) else: text.mark_set("insert", pos + "+1c") @@ -858,8 +858,8 @@ def remove_keybindings(self): self.mainmenu.default_keydefs = keydefs = idleConf.GetCurrentKeySet() for event, keylist in keydefs.items(): self.text.event_delete(event, *keylist) - for extensionName in self.get_standard_extension_names(): - xkeydefs = idleConf.GetExtensionBindings(extensionName) + for extension_name in self.get_standard_extension_names(): + xkeydefs = idleConf.GetExtensionBindings(extension_name) if xkeydefs: for event, keylist in xkeydefs.items(): self.text.event_delete(event, *keylist) @@ -951,7 +951,7 @@ def update_recent_files_list(self, new_file=None): with open(file_path, 'r', encoding='utf_8', errors='replace') as rf_list_file: rf_list = rf_list_file.readlines() - if new_file: + if new_file is not None: new_file = os.path.abspath(new_file) + '\n' if new_file in rf_list: rf_list.remove(new_file) # move to top @@ -1066,7 +1066,7 @@ def close_event(self, event): return "break" def maybesave(self): - if self.io: + if self.io is not None: if not self.get_saved(): if self.top.state() != 'normal': self.top.deiconify() @@ -1091,7 +1091,7 @@ def _close(self): self.io.close() self.io = None self.undo = None - if self.color: + if self.color is not None: self.color.close() self.color = None self.text = None @@ -1178,14 +1178,14 @@ def fill_menus(self, menudefs=None, keydefs=None): text = self.text for mname, entrylist in menudefs: menu = menudict.get(mname) - if not menu: + if menu is None: continue for entry in entrylist: - if not entry: + if entry is None: menu.add_separator() else: label, eventname = entry - checkbutton = (label[:1] == '!') + checkbutton = label[:1] == '!' if checkbutton: label = label[1:] underline, label = prepstr(label) @@ -1206,22 +1206,21 @@ def command(text=text, eventname=eventname): def getvar(self, name): var = self.get_var_obj(name) - if var: + if var is not None: value = var.get() return value - else: - raise NameError(name) + raise NameError(name) def setvar(self, name, value, vartype=None): var = self.get_var_obj(name, vartype) - if var: + if var is not None: var.set(value) else: raise NameError(name) def get_var_obj(self, name, vartype=None): var = self.tkinter_vars.get(name) - if not var and vartype: + if var is None and vartype: # create a Tkinter variable object with self.text as master: self.tkinter_vars[name] = var = vartype(self.text) return var @@ -1236,14 +1235,13 @@ def get_var_obj(self, name, vartype=None): # platform's colorizer. def is_char_in_string(self, text_index): - if self.color: + if self.color is not None: # Return true iff colorizer hasn't (re)gotten this far # yet, or the character is tagged as being in a string return self.text.tag_prevrange("TODO", text_index) or \ "STRING" in self.text.tag_names(text_index) - else: - # The colorizer is missing: assume the worst - return 1 + # The colorizer is missing: assume the worst + return 1 # If a selection is defined in the text widget, return (start, # end) as Tkinter text indices, otherwise return (None, None) @@ -1287,7 +1285,7 @@ def set_indentation_params(self, is_py_src, guess=True): def smart_backspace_event(self, event): text = self.text first, last = self.get_selection_indices() - if first and last: + if first is not None and last is not None: text.delete(first, last) text.mark_set("insert", first) return "break" @@ -1339,7 +1337,7 @@ def smart_indent_event(self, event): first, last = self.get_selection_indices() text.undo_block_start() try: - if first and last: + if first is not None and last is not None: if index2line(first) != index2line(last): return self.fregion.indent_region_event(event) text.delete(first, last) @@ -1376,7 +1374,7 @@ def newline_and_indent_event(self, event): first, last = self.get_selection_indices() text.undo_block_start() try: # Close undo block and expose new line in finally clause. - if first and last: + if first is not None and last is not None: text.delete(first, last) text.mark_set("insert", first) line = text.get("insert linestart", "insert") @@ -1502,8 +1500,7 @@ def _make_blanks(self, n): if self.usetabs: ntabs, nspaces = divmod(n, self.tabwidth) return '\t' * ntabs + ' ' * nspaces - else: - return ' ' * n + return ' ' * n # Delete from beginning of line to insert point, then reinsert # column logical (meaning use tabs if appropriate) spaces. From c7ce03c885a4a5fe8621b22f10a7fdc9ac703bc5 Mon Sep 17 00:00:00 2001 From: "E. Paine" <63801254+E-Paine@users.noreply.github.com> Date: Fri, 23 Apr 2021 17:50:25 +0100 Subject: [PATCH 4/5] Minor 'not' correction --- Lib/idlelib/editor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 00f6c4c74ab7bb..e1ced17b83d9d1 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -511,7 +511,7 @@ def right_menu_event(self, event): if not in_selection: text.tag_remove("sel", "1.0", "end") text.mark_set("insert", newdex) - if self.rmenu is not None: + if self.rmenu is None: self.make_rmenu() rmenu = self.rmenu self.event = event From ce60769704460c548cb09af4103247521826d27f Mon Sep 17 00:00:00 2001 From: "E. Paine" <63801254+E-Paine@users.noreply.github.com> Date: Fri, 23 Apr 2021 18:00:45 +0100 Subject: [PATCH 5/5] Revert incorrect 'is Nones' --- Lib/idlelib/editor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index e1ced17b83d9d1..55960dee0ff7fd 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -951,7 +951,7 @@ def update_recent_files_list(self, new_file=None): with open(file_path, 'r', encoding='utf_8', errors='replace') as rf_list_file: rf_list = rf_list_file.readlines() - if new_file is not None: + if new_file: new_file = os.path.abspath(new_file) + '\n' if new_file in rf_list: rf_list.remove(new_file) # move to top @@ -1285,7 +1285,7 @@ def set_indentation_params(self, is_py_src, guess=True): def smart_backspace_event(self, event): text = self.text first, last = self.get_selection_indices() - if first is not None and last is not None: + if first and last: text.delete(first, last) text.mark_set("insert", first) return "break" @@ -1337,7 +1337,7 @@ def smart_indent_event(self, event): first, last = self.get_selection_indices() text.undo_block_start() try: - if first is not None and last is not None: + if first and last: if index2line(first) != index2line(last): return self.fregion.indent_region_event(event) text.delete(first, last) @@ -1374,7 +1374,7 @@ def newline_and_indent_event(self, event): first, last = self.get_selection_indices() text.undo_block_start() try: # Close undo block and expose new line in finally clause. - if first is not None and last is not None: + if first and last: text.delete(first, last) text.mark_set("insert", first) line = text.get("insert linestart", "insert")