-
-
Notifications
You must be signed in to change notification settings - Fork 30.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IDLE: update code, mostly by cleanups of 2.x or 2to3 artifacts #87179
Comments
I've been waiting for years to do these until most PRs were closed. Has not happened, and annoyances continue. Since there is no search option I can find to search for PRs with a merge conflict, I assume that they are not discovered until a PR is accessed. So when some of these are done, I will search with 'idle in:title', open, scroll down, and fix.
Edited into task list 9/16/2022; revised most recently 10/18/2023. |
just noticed this PR -- you might be interested in pyupgrade which automates some of these things: diffdiff --git a/Lib/idlelib/calltip_w.py b/Lib/idlelib/calltip_w.py
index 1e0404aa49..278546064a 100644
--- a/Lib/idlelib/calltip_w.py
+++ b/Lib/idlelib/calltip_w.py
@@ -25,7 +25,7 @@ def __init__(self, text_widget):
text_widget: a Text widget with code for which call-tips are desired
"""
# Note: The Text widget will be accessible as self.anchor_widget
- super(CalltipWindow, self).__init__(text_widget)
+ super().__init__(text_widget)
self.label = self.text = None
self.parenline = self.parencol = self.lastline = None
@@ -54,7 +54,7 @@ def position_window(self):
return
self.lastline = curline
self.anchor_widget.see("insert")
- super(CalltipWindow, self).position_window()
+ super().position_window()
def showtip(self, text, parenleft, parenright):
"""Show the call-tip, bind events which will close it and reposition it.
@@ -73,7 +73,7 @@ def showtip(self, text, parenleft, parenright):
self.parenline, self.parencol = map(
int, self.anchor_widget.index(parenleft).split("."))
- super(CalltipWindow, self).showtip()
+ super().showtip()
self._bind_events()
@@ -143,7 +143,7 @@ def hidetip(self):
# ValueError may be raised by MultiCall
pass
- super(CalltipWindow, self).hidetip()
+ super().hidetip()
def _bind_events(self):
"""Bind event handlers."""
diff --git a/Lib/idlelib/debugger.py b/Lib/idlelib/debugger.py
index ccd03e46e1..53dba376af 100644
--- a/Lib/idlelib/debugger.py
+++ b/Lib/idlelib/debugger.py
@@ -49,9 +49,9 @@ def __frame2message(self, frame):
filename = code.co_filename
lineno = frame.f_lineno
basename = os.path.basename(filename)
- message = "%s:%s" % (basename, lineno)
+ message = f"{basename}:{lineno}"
if code.co_name != "?":
- message = "%s: %s()" % (message, code.co_name)
+ message = f"{message}: {code.co_name}()"
return message
@@ -213,7 +213,7 @@ def interaction(self, message, frame, info=None):
m1 = "%s" % str(type)
if value is not None:
try:
- m1 = "%s: %s" % (m1, str(value))
+ m1 = "{}: {}".format(m1, str(value))
except:
pass
bg = "yellow"
diff --git a/Lib/idlelib/debugobj.py b/Lib/idlelib/debugobj.py
index 5a4c997884..71d01c7070 100644
--- a/Lib/idlelib/debugobj.py
+++ b/Lib/idlelib/debugobj.py
@@ -87,7 +87,7 @@ def GetSubList(self):
continue
def setfunction(value, key=key, object=self.object):
object[key] = value
- item = make_objecttreeitem("%r:" % (key,), value, setfunction)
+ item = make_objecttreeitem(f"{key!r}:", value, setfunction)
sublist.append(item)
return sublist
diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py
index a4d0c95362..5faebb5742 100644
--- a/Lib/idlelib/editor.py
+++ b/Lib/idlelib/editor.py
@@ -37,12 +37,12 @@
def _sphinx_version():
"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,)
+ release = f'{major}{minor}'
+ release += f'{micro}'
if level == 'candidate':
- release += 'rc%s' % (serial,)
+ release += f'rc{serial}'
elif level != 'final':
- release += '%s%s' % (level[0], serial)
+ release += '{}{}'.format(level[0], serial)
return release
@@ -939,7 +939,7 @@ def update_recent_files_list(self, new_file=None):
rf_list = []
file_path = self.recent_files_path
if file_path and os.path.exists(file_path):
- with open(file_path, 'r',
+ with open(file_path,
encoding='utf_8', errors='replace') as rf_list_file:
rf_list = rf_list_file.readlines()
if new_file:
@@ -1446,7 +1446,7 @@ def newline_and_indent_event(self, event):
else:
self.reindent_to(y.compute_backslash_indent())
else:
- assert 0, "bogus continuation type %r" % (c,)
+ assert 0, f"bogus continuation type {c!r}"
return "break"
# This line starts a brand new statement; indent relative to
diff --git a/Lib/idlelib/filelist.py b/Lib/idlelib/filelist.py
index 0d200854ef..9b863698a0 100644
--- a/Lib/idlelib/filelist.py
+++ b/Lib/idlelib/filelist.py
@@ -22,7 +22,7 @@ def open(self, filename, action=None):
# This can happen when bad filename is passed on command line:
tkMessageBox.showerror(
"File Error",
- "%r is a directory." % (filename,),
+ f"{filename!r} is a directory.",
master=self.root)
return None
key = os.path.normcase(filename)
@@ -90,7 +90,7 @@ def filename_changed_edit(self, edit):
self.inversedict[conflict] = None
tkMessageBox.showerror(
"Name Conflict",
- "You now have multiple edit windows open for %r" % (filename,),
+ f"You now have multiple edit windows open for {filename!r}",
master=self.root)
self.dict[newkey] = edit
self.inversedict[edit] = newkey
diff --git a/Lib/idlelib/idle_test/test_config.py b/Lib/idlelib/idle_test/test_config.py
index 697fda5279..08ed76fe28 100644
--- a/Lib/idlelib/idle_test/test_config.py
+++ b/Lib/idlelib/idle_test/test_config.py
@@ -191,7 +191,7 @@ def setUpClass(cls):
idle_dir = os.path.abspath(sys.path[0])
for ctype in conf.config_types:
config_path = os.path.join(idle_dir, '../config-%s.def' % ctype)
- with open(config_path, 'r') as f:
+ with open(config_path) as f:
cls.config_string[ctype] = f.read()
cls.orig_warn = config._warn
diff --git a/Lib/idlelib/idle_test/test_text.py b/Lib/idlelib/idle_test/test_text.py
index 0f31179e04..43a9ba02c3 100644
--- a/Lib/idlelib/idle_test/test_text.py
+++ b/Lib/idlelib/idle_test/test_text.py
@@ -6,7 +6,7 @@
from test.support import requires
from _tkinter import TclError
-class TextTest(object):
+class TextTest:
"Define items common to both sets of tests."
hw = 'hello\nworld' # Several tests insert this after initialization.
diff --git a/Lib/idlelib/macosx.py b/Lib/idlelib/macosx.py
index eeaab59ae8..fbc6499faa 100644
--- a/Lib/idlelib/macosx.py
+++ b/Lib/idlelib/macosx.py
@@ -81,7 +81,7 @@ def tkVersionWarning(root):
patchlevel = root.tk.call('info', 'patchlevel')
if patchlevel not in ('8.5.7', '8.5.9'):
return False
- return ("WARNING: The version of Tcl/Tk ({0}) in use may"
+ return ("WARNING: The version of Tcl/Tk ({}) in use may"
" be unstable.\n"
"Visit http://www.python.org/download/mac/tcltk/"
" for current information.".format(patchlevel))
diff --git a/Lib/idlelib/multicall.py b/Lib/idlelib/multicall.py
index dc02001292..0200f445cc 100644
--- a/Lib/idlelib/multicall.py
+++ b/Lib/idlelib/multicall.py
@@ -52,9 +52,9 @@
_modifier_masks = (MC_CONTROL, MC_ALT, MC_SHIFT, MC_META)
# a dictionary to map a modifier name into its number
-_modifier_names = dict([(name, number)
+_modifier_names = {name: number
for number in range(len(_modifiers))
- for name in _modifiers[number]])
+ for name in _modifiers[number]}
# In 3.4, if no shell window is ever open, the underlying Tk widget is
# destroyed before .__del__ methods here are called. The following
@@ -134,7 +134,7 @@ def nbits(n):
return nb
statelist = []
for state in states:
- substates = list(set(state & x for x in states))
+ substates = list({state & x for x in states})
substates.sort(key=nbits, reverse=True)
statelist.append(substates)
return statelist
@@ -258,9 +258,9 @@ def __del__(self):
_binder_classes = (_ComplexBinder,) * 4 + (_SimpleBinder,) * (len(_types)-4)
# A dictionary to map a type name into its number
-_type_names = dict([(name, number)
+_type_names = {name: number
for number in range(len(_types))
- for name in _types[number]])
+ for name in _types[number]}
_keysym_re = re.compile(r"^\w+$")
_button_re = re.compile(r"^[1-5]$")
diff --git a/Lib/idlelib/outwin.py b/Lib/idlelib/outwin.py
index 5ab08bbaf4..ac67c904ab 100644
--- a/Lib/idlelib/outwin.py
+++ b/Lib/idlelib/outwin.py
@@ -42,7 +42,7 @@ def file_line_helper(line):
if match:
filename, lineno = match.group(1, 2)
try:
- f = open(filename, "r")
+ f = open(filename)
f.close()
break
except OSError:
diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py
index abe8a85952..6cae951698 100755
--- a/Lib/idlelib/pyshell.py
+++ b/Lib/idlelib/pyshell.py
@@ -245,7 +245,7 @@ def store_file_breaks(self):
breaks = self.breakpoints
filename = self.io.filename
try:
- with open(self.breakpointPath, "r") as fp:
+ with open(self.breakpointPath) as fp:
lines = fp.readlines()
except OSError:
lines = []
@@ -275,7 +275,7 @@ def restore_file_breaks(self):
if filename is None:
return
if os.path.isfile(self.breakpointPath):
- with open(self.breakpointPath, "r") as fp:
+ with open(self.breakpointPath) as fp:
lines = fp.readlines()
for line in lines:
if line.startswith(filename + '='):
@@ -431,7 +431,7 @@ def build_subprocess_arglist(self):
# run from the IDLE source directory.
del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc',
default=False, type='bool')
- command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,)
+ command = f"__import__('idlelib.run').run.main({del_exitf!r})"
return [sys.executable] + w + ["-c", command, str(self.port)]
def start_subprocess(self):
@@ -564,9 +564,9 @@ def transfer_path(self, with_cwd=False):
self.runcommand("""if 1:
import sys as _sys
- _sys.path = %r
+ _sys.path = {!r}
del _sys
- \n""" % (path,))
+ \n""".format(path))
active_seq = None
@@ -693,14 +693,14 @@ def stuffsource(self, source):
def prepend_syspath(self, filename):
"Prepend sys.path with file's directory if not already included"
self.runcommand("""if 1:
- _filename = %r
+ _filename = {!r}
import sys as _sys
from os.path import dirname as _dirname
_dir = _dirname(_filename)
if not _dir in _sys.path:
_sys.path.insert(0, _dir)
del _filename, _sys, _dirname, _dir
- \n""" % (filename,))
+ \n""".format(filename))
def showsyntaxerror(self, filename=None):
"""Override Interactive Interpreter method: Use Colorizing
@@ -1407,7 +1407,7 @@ def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
except getopt.error as msg:
- print("Error: %s\n%s" % (msg, usage_msg), file=sys.stderr)
+ print(f"Error: {msg}\n{usage_msg}", file=sys.stderr)
sys.exit(2)
for o, a in opts:
if o == '-c':
@@ -1539,9 +1539,9 @@ def main():
if cmd or script:
shell.interp.runcommand("""if 1:
import sys as _sys
- _sys.argv = %r
+ _sys.argv = {!r}
del _sys
- \n""" % (sys.argv,))
+ \n""".format(sys.argv))
if cmd:
shell.interp.execsource(cmd)
elif script:
diff --git a/Lib/idlelib/redirector.py b/Lib/idlelib/redirector.py
index 9ab34c5acf..9891d256f7 100644
--- a/Lib/idlelib/redirector.py
+++ b/Lib/idlelib/redirector.py
@@ -47,7 +47,7 @@ def __init__(self, widget):
tk.createcommand(w, self.dispatch)
def __repr__(self):
- return "%s(%s<%s>)" % (self.__class__.__name__,
+ return "{}({}<{}>)".format(self.__class__.__name__,
self.widget.__class__.__name__,
self.widget._w)
@@ -143,7 +143,7 @@ def __init__(self, redir, operation):
self.orig_and_operation = (redir.orig, operation)
def __repr__(self):
- return "%s(%r, %r)" % (self.__class__.__name__,
+ return "{}({!r}, {!r})".format(self.__class__.__name__,
self.redir, self.operation)
def __call__(self, *args):
diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py
index 8efcf048fa..062e2502de 100644
--- a/Lib/idlelib/rpc.py
+++ b/Lib/idlelib/rpc.py
@@ -174,7 +174,7 @@ def localcall(self, seq, request):
except TypeError:
return ("ERROR", "Bad request format")
if oid not in self.objtable:
- return ("ERROR", "Unknown object id: %r" % (oid,))
+ return ("ERROR", f"Unknown object id: {oid!r}")
obj = self.objtable[oid]
if methodname == "__methods__":
methods = {}
@@ -185,7 +185,7 @@ def localcall(self, seq, request):
_getattributes(obj, attributes)
return ("OK", attributes)
if not hasattr(obj, methodname):
- return ("ERROR", "Unsupported method name: %r" % (methodname,))
+ return ("ERROR", f"Unsupported method name: {methodname!r}")
method = getattr(obj, methodname)
try:
if how == 'CALL':
diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py
index ec575c3d48..099240d56b 100644
--- a/Lib/idlelib/run.py
+++ b/Lib/idlelib/run.py
@@ -43,13 +43,13 @@ def idle_formatwarning(message, category, filename, lineno, line=None):
"""Format warnings the IDLE way."""
s = "\nWarning (from warnings module):\n"
- s += ' File \"%s\", line %s\n' % (filename, lineno)
+ s += f' File \"{filename}\", line {lineno}\n'
if line is None:
line = linecache.getline(filename, lineno)
line = line.strip()
if line:
s += " %s\n" % line
- s += "%s: %s\n" % (category.__name__, message)
+ s += f"{category.__name__}: {message}\n"
return s
def idle_showwarning_subproc(
diff --git a/Lib/idlelib/textview.py b/Lib/idlelib/textview.py
index a66c1a4309..23f0f4cb50 100644
--- a/Lib/idlelib/textview.py
+++ b/Lib/idlelib/textview.py
@@ -169,7 +169,7 @@ def view_file(parent, title, filename, encoding, modal=True, wrap='word',
with contents of the file.
"""
try:
- with open(filename, 'r', encoding=encoding) as file:
+ with open(filename, encoding=encoding) as file:
contents = file.read()
except OSError:
showerror(title='File Load Error',
diff --git a/Lib/idlelib/tooltip.py b/Lib/idlelib/tooltip.py
index d714318dae..3983690dd4 100644
--- a/Lib/idlelib/tooltip.py
+++ b/Lib/idlelib/tooltip.py
@@ -92,7 +92,7 @@ def __init__(self, anchor_widget, hover_delay=1000):
e.g. after hovering over the anchor widget with the mouse for enough
time.
"""
- super(OnHoverTooltipBase, self).__init__(anchor_widget)
+ super().__init__(anchor_widget)
self.hover_delay = hover_delay
self._after_id = None
@@ -107,7 +107,7 @@ def __del__(self):
self.anchor_widget.unbind("<Button>", self._id3) # pragma: no cover
except TclError:
pass
- super(OnHoverTooltipBase, self).__del__()
+ super().__del__()
def _show_event(self, event=None):
"""event handler to display the tooltip"""
@@ -139,7 +139,7 @@ def hidetip(self):
self.unschedule()
except TclError: # pragma: no cover
pass
- super(OnHoverTooltipBase, self).hidetip()
+ super().hidetip()
class Hovertip(OnHoverTooltipBase):
@@ -154,7 +154,7 @@ def __init__(self, anchor_widget, text, hover_delay=1000):
e.g. after hovering over the anchor widget with the mouse for enough
time.
"""
- super(Hovertip, self).__init__(anchor_widget, hover_delay=hover_delay)
+ super().__init__(anchor_widget, hover_delay=hover_delay)
self.text = text
def showcontents(self):
diff --git a/Lib/idlelib/tree.py b/Lib/idlelib/tree.py
index 5947268f5c..5f30f0f609 100644
--- a/Lib/idlelib/tree.py
+++ b/Lib/idlelib/tree.py
@@ -32,7 +32,7 @@
if os.path.isdir(_icondir):
ICONDIR = _icondir
elif not os.path.isdir(ICONDIR):
- raise RuntimeError("can't find icon directory (%r)" % (ICONDIR,))
+ raise RuntimeError(f"can't find icon directory ({ICONDIR!r})")
def listicons(icondir=ICONDIR):
"""Utility to display the available icons."""
diff --git a/Lib/idlelib/undo.py b/Lib/idlelib/undo.py
index 85ecffecb4..5f10c0f05c 100644
--- a/Lib/idlelib/undo.py
+++ b/Lib/idlelib/undo.py
@@ -309,7 +309,7 @@ def __repr__(self):
s = self.__class__.__name__
strs = []
for cmd in self.cmds:
- strs.append(" %r" % (cmd,))
+ strs.append(f" {cmd!r}")
return s + "(\n" + ",\n".join(strs) + "\n)"
def __len__(self): |
This comment was marked as resolved.
This comment was marked as resolved.
PR for 3. For 2.x, tkinter comprised several modules that became tkinter submodules. For 3.0, 'import tkOld' was replaced by 'import tkinter.new as tkOld', where 'new' is lowercase version of 'Old'. Fix remaining instances of tkColorChooser, tkFileDialog, tkSimpleDialog, and tkMessageBox by replacing 'tkOld' with 'new' and import with 'from tkinter import new'. Replace 'tkFont' with 'tkfont' instead of 'font' since 'font' is already used and leave import in 'as' form. There are no remaining instances of SimpleDialog or tkCommonDialog. |
There are about 40 open PRs with 'idle' or 'idlelib' in title. I only found 2 or 3 with merge conflicts related to this issue -- and they are easy to fix. There are more conflicts from other patches (some fixed). These are usually more difficult to fix as when a PR adds code where another patch later adds code and both additions need to be kept, in the proper order. TODO: 4 built-in name parameters, 6 .keys(), 7 pyupgrade. The latter found fixups in about 15 idlelib files and a few test files. I may do these for individual files that are well tested or are being worked on. Anthony: removing 'set' from 'list(set(interable))' is wrong if 'set' were added to remove duplicates. |
This comment was marked as outdated.
This comment was marked as outdated.
(I took the liberty to collapse Anthony's multi-screenful diff in #87179 (comment) with a |
ISTM that most cleanups mentioned in the OP have been done (2to3 modernisation, tkinter modernisation). Suggesting to close this and open targeted, narrow issues for each further refactor/modernisation. |
@erlend-aasland Thank you for the example of a collapsed section. This was new to me, and I expect to use it. I found the page for it. Is this standard html? I will open separate issues for further changes but made this a task issue to keep track of them. |
Yes, so it seems: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details It is a very convenient HTML feature. |
Remove unneeded '(object)' and '()'.
Remove unneeded '(object)' and '()'. (cherry picked from commit aa671b4) Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
Remove unneeded '(object)' and '()'. (cherry picked from commit aa671b4) Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
Remove unneeded '(object)' and '()'.
@terryjreedy Could you address the remaining three TODO items so we can close this issue for good? |
I open 3 issues for the 3 items, did one, and am working on the other two. |
I did 2/3rds of item 4, replacing redefinitions of 'dict' and 'object' and deferred the same for 'type'. Hence closing this. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: