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..55960dee0ff7fd 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,8 +75,8 @@ 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') - if sys.platform.count('linux'): + dochome = os.path.join(sys.base_prefix, 'Doc', 'index.html') + 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 @@ -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 @@ -107,32 +108,32 @@ 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 + # 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) @@ -195,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) @@ -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,10 +267,10 @@ 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 - if filename: + 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 is not None: if os.path.exists(filename) and not os.path.isdir(filename): if io.loadfile(filename): self.good_load = True @@ -279,12 +280,12 @@ 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() menu = self.menudict.get('window') - if menu: + if menu is not None: end = menu.index("end") if end is None: end = -1 @@ -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'): + for insertpt, char in enumerate(line): + if char 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: + 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) @@ -442,8 +443,7 @@ def set_line_and_column(self, event=None): ("options", "_Options"), ("window", "_Window"), ("help", "_Help"), - ] - + ] def createmenubar(self): mbar = self.menubar @@ -478,17 +478,17 @@ def postwindowsmenu(self): 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,13 +505,13 @@ 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: text.tag_remove("sel", "1.0", "end") text.mark_set("insert", newdex) - if not self.rmenu: + if self.rmenu is None: self.make_rmenu() rmenu = self.rmenu self.event = event @@ -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,8 +537,8 @@ def right_menu_event(self, event): rmenu_specs = [ # ("Label", "<>", "statefuncname"), ... - ("Close", "<>", None), # Example - ] + ("Close", "<>", None), # Example + ] def make_rmenu(self): rmenu = Menu(self.text, tearoff=0) @@ -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,21 +573,21 @@ 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: + if self.root is not None: parent = self.root else: parent = self.top @@ -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,12 +710,12 @@ 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: + if self.flist is not None: self.flist.open(file_path) else: self.io.loadfile(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, @@ -763,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 @@ -771,32 +775,32 @@ 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) - 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() # 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) 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 char == '\n': # 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,20 +852,20 @@ 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(): 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) - 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())) @@ -1057,9 +1066,9 @@ 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': + if self.top.state() != 'normal': self.top.deiconify() self.top.lower() self.top.lift() @@ -1082,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 @@ -1169,25 +1178,27 @@ 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) 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, @@ -1195,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 @@ -1225,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) @@ -1262,7 +1271,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 +1297,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 +1416,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 +1483,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 @@ -1490,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. @@ -1532,12 +1541,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 +1582,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 +1611,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 +1622,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 +1655,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 +1678,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'