From 1178a32ca0ac03b9cf90dad29c7b26334e2a12f6 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Fri, 7 Apr 2023 11:09:50 +0100 Subject: [PATCH 1/7] gh-102832: [idle] reduce use of deprecated sys.last_xyzs --- Lib/idlelib/stackviewer.py | 46 ++++++++++++++------------------------ 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/Lib/idlelib/stackviewer.py b/Lib/idlelib/stackviewer.py index 94ffb4eff4dd26..f272e124d6d61e 100644 --- a/Lib/idlelib/stackviewer.py +++ b/Lib/idlelib/stackviewer.py @@ -1,33 +1,31 @@ import linecache import os -import sys import tkinter as tk from idlelib.debugobj import ObjectTreeItem, make_objecttreeitem from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas -def StackBrowser(root, flist=None, tb=None, top=None): +def StackBrowser(root, flist=None, exc=None, top=None): global sc, item, node # For testing. if top is None: top = tk.Toplevel(root) sc = ScrolledCanvas(top, bg="white", highlightthickness=0) sc.frame.pack(expand=1, fill="both") - item = StackTreeItem(flist, tb) + item = StackTreeItem(flist, exc) node = TreeNode(sc.canvas, None, item) node.expand() class StackTreeItem(TreeItem): - def __init__(self, flist=None, tb=None): + def __init__(self, flist=None, exc=None): + assert isinstance(exc, BaseException) self.flist = flist - self.stack = self.get_stack(tb) - self.text = self.get_exception() + self.stack = self.get_stack(exc.__traceback__) + self.text = self.get_exception(exc) def get_stack(self, tb): - if tb is None: - tb = sys.last_traceback stack = [] if tb and tb.tb_frame is None: tb = tb.tb_next @@ -36,14 +34,12 @@ def get_stack(self, tb): tb = tb.tb_next return stack - def get_exception(self): - type = sys.last_type - value = sys.last_value - if hasattr(type, "__name__"): - type = type.__name__ - s = str(type) - if value is not None: - s = s + ": " + str(value) + def get_exception(self, exc): + assert isinstance(exc, BaseException) + typ = type(exc) + if hasattr(typ, "__name__"): + typ = typ.__name__ + s = str(typ) + ": " + str(exc) return s def GetText(self): @@ -133,19 +129,11 @@ def _stack_viewer(parent): # htest # flist = PyShellFileList(top) try: # to obtain a traceback object intentional_name_error - except NameError: - exc_type, exc_value, exc_tb = sys.exc_info() - # inject stack trace to sys - sys.last_type = exc_type - sys.last_value = exc_value - sys.last_traceback = exc_tb - - StackBrowser(top, flist=flist, top=top, tb=exc_tb) - - # restore sys to original state - del sys.last_type - del sys.last_value - del sys.last_traceback + except NameError as e: + exc = e + + StackBrowser(top, flist=flist, top=top, tb=exc) + if __name__ == '__main__': from unittest import main From a16e192f98785858269e2088faa18011c5e452de Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Fri, 7 Apr 2023 11:17:07 +0100 Subject: [PATCH 2/7] remove last_xyzs from test as well --- Lib/idlelib/idle_test/test_stackviewer.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Lib/idlelib/idle_test/test_stackviewer.py b/Lib/idlelib/idle_test/test_stackviewer.py index 98f53f9537bb25..0df68adf631abd 100644 --- a/Lib/idlelib/idle_test/test_stackviewer.py +++ b/Lib/idlelib/idle_test/test_stackviewer.py @@ -6,19 +6,12 @@ from tkinter import Tk from idlelib.tree import TreeNode, ScrolledCanvas -import sys class StackBrowserTest(unittest.TestCase): @classmethod def setUpClass(cls): - svs = stackviewer.sys - try: - abc - except NameError: - svs.last_type, svs.last_value, svs.last_traceback = ( - sys.exc_info()) requires('gui') cls.root = Tk() @@ -26,8 +19,6 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - svs = stackviewer.sys - del svs.last_traceback, svs.last_type, svs.last_value cls.root.update_idletasks() ## for id in cls.root.tk.call('after', 'info'): From b7ef0e131b7fa390ecc0b48a80bc92b3577e1229 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Fri, 7 Apr 2023 19:52:59 +0100 Subject: [PATCH 3/7] tolerate exc == None --- Lib/idlelib/stackviewer.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Lib/idlelib/stackviewer.py b/Lib/idlelib/stackviewer.py index f272e124d6d61e..7f52376c88bfa2 100644 --- a/Lib/idlelib/stackviewer.py +++ b/Lib/idlelib/stackviewer.py @@ -20,9 +20,8 @@ def StackBrowser(root, flist=None, exc=None, top=None): class StackTreeItem(TreeItem): def __init__(self, flist=None, exc=None): - assert isinstance(exc, BaseException) self.flist = flist - self.stack = self.get_stack(exc.__traceback__) + self.stack = self.get_stack(None if exc is None else exc.__traceback__) self.text = self.get_exception(exc) def get_stack(self, tb): @@ -35,8 +34,7 @@ def get_stack(self, tb): return stack def get_exception(self, exc): - assert isinstance(exc, BaseException) - typ = type(exc) + typ = None if exc is None else type(exc) if hasattr(typ, "__name__"): typ = typ.__name__ s = str(typ) + ": " + str(exc) @@ -132,7 +130,7 @@ def _stack_viewer(parent): # htest # except NameError as e: exc = e - StackBrowser(top, flist=flist, top=top, tb=exc) + StackBrowser(top, flist=flist, top=top, exc=exc) if __name__ == '__main__': From 7a6839b41775a2323b720d19f905514256d7e6b0 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Wed, 7 Jun 2023 22:05:39 -0400 Subject: [PATCH 4/7] Fix StackBrowser def and test calls. --- Lib/idlelib/idle_test/test_stackviewer.py | 5 ++++- Lib/idlelib/stackviewer.py | 6 ++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Lib/idlelib/idle_test/test_stackviewer.py b/Lib/idlelib/idle_test/test_stackviewer.py index 0df68adf631abd..7c6bf4dc33480f 100644 --- a/Lib/idlelib/idle_test/test_stackviewer.py +++ b/Lib/idlelib/idle_test/test_stackviewer.py @@ -27,7 +27,10 @@ def tearDownClass(cls): del cls.root def test_init(self): - sb = stackviewer.StackBrowser(self.root) + try: + abc + except NameError as exc: + sb = stackviewer.StackBrowser(self.root, exc) isi = self.assertIsInstance isi(stackviewer.sc, ScrolledCanvas) isi(stackviewer.item, stackviewer.StackTreeItem) diff --git a/Lib/idlelib/stackviewer.py b/Lib/idlelib/stackviewer.py index 7f52376c88bfa2..9126646ceac0b4 100644 --- a/Lib/idlelib/stackviewer.py +++ b/Lib/idlelib/stackviewer.py @@ -6,7 +6,7 @@ from idlelib.debugobj import ObjectTreeItem, make_objecttreeitem from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas -def StackBrowser(root, flist=None, exc=None, top=None): +def StackBrowser(root, exc, flist=None, top=None): global sc, item, node # For testing. if top is None: top = tk.Toplevel(root) @@ -128,9 +128,7 @@ def _stack_viewer(parent): # htest # try: # to obtain a traceback object intentional_name_error except NameError as e: - exc = e - - StackBrowser(top, flist=flist, top=top, exc=exc) + sb = StackBrowser(top, e, flist=flist, top=top) if __name__ == '__main__': From e84e58f121a5cea4bc94656645a5f5b2da441da0 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Wed, 7 Jun 2023 22:16:46 -0400 Subject: [PATCH 5/7] Fix pyshell -n mode Stackbrowser call. Tested by running in -n mode. --- Lib/idlelib/pyshell.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index bdde156166171b..3141b477eff181 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -1363,19 +1363,19 @@ def runit(self): self.text.tag_remove(self.user_input_insert_tags, index_before) self.shell_sidebar.update_sidebar() - def open_stack_viewer(self, event=None): + def open_stack_viewer(self, event=None): # -n mode only if self.interp.rpcclt: return self.interp.remote_stack_viewer() + + from idlelib.stackviewer import StackBrowser try: - sys.last_traceback + StackBrowser(self.root, sys.last_value, self.flist) except: messagebox.showerror("No stack trace", "There is no stack trace yet.\n" - "(sys.last_traceback is not defined)", + "(sys.last_value is not defined)", parent=self.text) - return - from idlelib.stackviewer import StackBrowser - StackBrowser(self.root, self.flist) + return None def view_restart_mark(self, event=None): self.text.see("iomark") From 144d3fda561d8a6e4b11f00a58f471c96eb08117 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Wed, 7 Jun 2023 23:41:31 -0400 Subject: [PATCH 6/7] Fix StackTreeItem def and calls. --- Lib/idlelib/run.py | 7 +++---- Lib/idlelib/stackviewer.py | 17 +++++------------ 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 84792a82b0022c..4ffc90ab0c852a 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -622,7 +622,7 @@ def get_the_completion_list(self, what, mode): def stackviewer(self, flist_oid=None): if self.user_exc_info: - typ, val, tb = self.user_exc_info + _, exc, tb = self.user_exc_info else: return None flist = None @@ -630,9 +630,8 @@ def stackviewer(self, flist_oid=None): flist = self.rpchandler.get_remote_proxy(flist_oid) while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]: tb = tb.tb_next - sys.last_type = typ - sys.last_value = val - item = stackviewer.StackTreeItem(flist, tb) + exc.__traceback__ = tb + item = stackviewer.StackTreeItem(exc, flist) return debugobj_r.remote_object_tree_item(item) diff --git a/Lib/idlelib/stackviewer.py b/Lib/idlelib/stackviewer.py index 9126646ceac0b4..7b00c4cdb7d033 100644 --- a/Lib/idlelib/stackviewer.py +++ b/Lib/idlelib/stackviewer.py @@ -12,17 +12,17 @@ def StackBrowser(root, exc, flist=None, top=None): top = tk.Toplevel(root) sc = ScrolledCanvas(top, bg="white", highlightthickness=0) sc.frame.pack(expand=1, fill="both") - item = StackTreeItem(flist, exc) + item = StackTreeItem(exc, flist) node = TreeNode(sc.canvas, None, item) node.expand() class StackTreeItem(TreeItem): - def __init__(self, flist=None, exc=None): + def __init__(self, exc, flist=None): self.flist = flist self.stack = self.get_stack(None if exc is None else exc.__traceback__) - self.text = self.get_exception(exc) + self.text = f"{type(exc).__name__}: {str(exc)}" def get_stack(self, tb): stack = [] @@ -33,14 +33,7 @@ def get_stack(self, tb): tb = tb.tb_next return stack - def get_exception(self, exc): - typ = None if exc is None else type(exc) - if hasattr(typ, "__name__"): - typ = typ.__name__ - s = str(typ) + ": " + str(exc) - return s - - def GetText(self): + def GetText(self): # Titlecase names are overrides. return self.text def GetSubList(self): @@ -128,7 +121,7 @@ def _stack_viewer(parent): # htest # try: # to obtain a traceback object intentional_name_error except NameError as e: - sb = StackBrowser(top, e, flist=flist, top=top) + StackBrowser(top, e, flist=flist, top=top) if __name__ == '__main__': From bbd7e0cccf31658ea5e416df9cbde9bd5cfc4693 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Thu, 8 Jun 2023 00:08:50 -0400 Subject: [PATCH 7/7] indent fix --- Lib/idlelib/idle_test/test_stackviewer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/idlelib/idle_test/test_stackviewer.py b/Lib/idlelib/idle_test/test_stackviewer.py index 7c6bf4dc33480f..55f510382bf4c3 100644 --- a/Lib/idlelib/idle_test/test_stackviewer.py +++ b/Lib/idlelib/idle_test/test_stackviewer.py @@ -30,7 +30,7 @@ def test_init(self): try: abc except NameError as exc: - sb = stackviewer.StackBrowser(self.root, exc) + sb = stackviewer.StackBrowser(self.root, exc) isi = self.assertIsInstance isi(stackviewer.sc, ScrolledCanvas) isi(stackviewer.item, stackviewer.StackTreeItem)