From eb87bcd12d479fac977a098360b3eba2c6757720 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Fri, 16 Aug 2019 00:58:07 -0400 Subject: [PATCH 1/7] bpo-37824: Properly handle user input warnings in IDLE shell. Cease turning SyntaxWarnings into SyntaxErrors. Print warnings in the shell, not a possibly non-existent command line. --- Lib/idlelib/pyshell.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 87401f33f55f16..ec9b80f04a4671 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -60,10 +60,9 @@ HOST = '127.0.0.1' # python execution server on localhost loopback PORT = 0 # someday pass in host, port for remote debug capability -# Override warnings module to write to warning_stream. Initialize to send IDLE -# internal warnings to the console. ScriptBinding.check_syntax() will -# temporarily redirect the stream to the shell window to display warnings when -# checking user's code. +# Override warnings.show_warning to write to IDLE format to warning_stream. +# Initially send IDLE internal warnings to the console, if present. +# Send to Shell.stderr (traceback stream) when available. warning_stream = sys.__stderr__ # None, at least on Windows, if no console. def idle_showwarning( @@ -665,8 +664,6 @@ def runsource(self, source): "Extend base class method: Stuff the source in the line cache first" filename = self.stuffsource(source) self.more = 0 - self.save_warnings_filters = warnings.filters[:] - warnings.filterwarnings(action="error", category=SyntaxWarning) # at the moment, InteractiveInterpreter expects str assert isinstance(source, str) #if isinstance(source, str): @@ -677,14 +674,8 @@ def runsource(self, source): # self.tkconsole.resetoutput() # self.write("Unsupported characters in input\n") # return - try: - # InteractiveInterpreter.runsource() calls its runcode() method, - # which is overridden (see below) - return InteractiveInterpreter.runsource(self, source, filename) - finally: - if self.save_warnings_filters is not None: - warnings.filters[:] = self.save_warnings_filters - self.save_warnings_filters = None + # II.runsource() calls .runcode(), overridden below. + return InteractiveInterpreter.runsource(self, source, filename) def stuffsource(self, source): "Stuff source in the filename cache" @@ -916,6 +907,8 @@ def __init__(self, flist=None): sys.stdout = self.stdout sys.stderr = self.stderr sys.stdin = self.stdin + global warning_stream + warning_stream = self.stderr try: # page help() text to shell. import pydoc # import must be done here to capture i/o rebinding. From be17e414f16804cb65e25bfba671e5e521ac75e9 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Fri, 16 Aug 2019 01:04:08 -0400 Subject: [PATCH 2/7] Revern warning_stream when Shell closes. --- Lib/idlelib/pyshell.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index ec9b80f04a4671..2c7e1f41eeb7e4 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -1016,10 +1016,12 @@ def _close(self): self.close_debugger() if use_subprocess: self.interp.kill_subprocess() - # Restore std streams + # Restore std streams and warning_stream sys.stdout = self.save_stdout sys.stderr = self.save_stderr sys.stdin = self.save_stdin + global warning_stream + warning_stream = sys.__stderr__ # Break cycles self.interp = None self.console = None From 54edc239af51d8bf9791bf894616e393c68eeeb1 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Fri, 16 Aug 2019 01:08:12 -0400 Subject: [PATCH 3/7] Stop printing bogus prompt after warning. --- Lib/idlelib/pyshell.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 2c7e1f41eeb7e4..9d24845654e295 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -67,18 +67,16 @@ def idle_showwarning( message, category, filename, lineno, file=None, line=None): - """Show Idle-format warning (after replacing warnings.showwarning). + """Print Idle-format warning to warning_stream. - The differences are the formatter called, the file=None replacement, - which can be None, the capture of the consequence AttributeError, - and the output of a hard-coded prompt. + Difference from show_warning are the formatter, the file=None + replacement, and the capture of the consequence AttributeError. """ if file is None: file = warning_stream try: file.write(idle_formatwarning( message, category, filename, lineno, line=line)) - file.write(">>> ") except (AttributeError, OSError): pass # if file (probably __stderr__) is invalid, skip warning. From 0fade74f1b1a3030e08bf8ac197182a263caefea Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Mon, 26 Aug 2019 03:49:47 -0400 Subject: [PATCH 4/7] Adjust test to changed warning format. --- Lib/idlelib/idle_test/test_warning.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/idlelib/idle_test/test_warning.py b/Lib/idlelib/idle_test/test_warning.py index 221068c5885fcb..fcd5b56fac673a 100644 --- a/Lib/idlelib/idle_test/test_warning.py +++ b/Lib/idlelib/idle_test/test_warning.py @@ -25,7 +25,7 @@ Line of code UserWarning: Test ''' -shellmsg = idlemsg + ">>> " +shellmsg = idlemsg class RunWarnTest(unittest.TestCase): From 8d4d9bbe7d5ff38340f7ffe092c717d4daf3c150 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 24 May 2020 09:27:48 -0400 Subject: [PATCH 5/7] bpo-37309: Update IDLE NEWS.txt --- Lib/idlelib/NEWS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index b112e8ea293a99..709008f78a571d 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -4,6 +4,7 @@ Released on 2020-10-05? bpo-40723: Make test_idle pass when run after import. +Patch by Florian Dahlitz. bpo-38689: IDLE will no longer freeze when inspect.signature fails when fetching a calltip. From a20cf7c9fdd0543796a6fce617f1d8671bf76edd Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Mon, 25 May 2020 21:03:08 -0400 Subject: [PATCH 6/7] Show warnings once --- Lib/idlelib/pyshell.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index f5c3c707086e84..f1b5458501c91f 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -684,7 +684,9 @@ def runsource(self, source): # self.write("Unsupported characters in input\n") # return # II.runsource() calls .runcode(), overridden below. - return InteractiveInterpreter.runsource(self, source, filename) + with warnings.catch_warnings(): + warnings.filterwarnings('once') + return InteractiveInterpreter.runsource(self, source, filename) def stuffsource(self, source): "Stuff source in the filename cache" From d5849ad7181e934c040cf80694c1c1d7797ed27c Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Wed, 27 May 2020 22:55:27 -0400 Subject: [PATCH 7/7] Clean PyShell.runsource of unneeded assert and comments. --- Lib/idlelib/pyshell.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index f1b5458501c91f..7b087baa8f131e 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -671,18 +671,8 @@ def execfile(self, filename, source=None): self.runcode(code) def runsource(self, source): - "Extend base class method: Stuff the source in the line cache first" + "Return overriden base call after caching source." filename = self.stuffsource(source) - # at the moment, InteractiveInterpreter expects str - assert isinstance(source, str) - #if isinstance(source, str): - # from idlelib import iomenu - # try: - # source = source.encode(iomenu.encoding) - # except UnicodeError: - # self.tkconsole.resetoutput() - # self.write("Unsupported characters in input\n") - # return # II.runsource() calls .runcode(), overridden below. with warnings.catch_warnings(): warnings.filterwarnings('once')