From 1f7be2520b58dca05b1ae54f5ef09dc460d27116 Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Sun, 15 Jun 2025 09:17:09 +0800 Subject: [PATCH 01/12] Update run.py --- Lib/idlelib/run.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index a30db99a619a93..8f8d98670b37df 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -271,7 +271,13 @@ def print_exc(typ, exc, tb): "debugger_r.py", "bdb.py") cleanup_traceback(tbe, exclude) traceback.print_list(tbe, file=efile) - lines = get_message_lines(typ, exc, tb) + if not isinstance(exc, NameError) and not isinstance(exc, AttributeError): + lines = get_message_lines(typ, exc, tb) + else: + if "\n" in str(val): #The message must be defined by user if "\n" in the message + lines = [f"{typ.__name__}: {str(val)}"] + else: + lines = get_message_lines(typ, exc, tb) for line in lines: print(line, end='', file=efile) From 76156d0f82048bf1454250d1cfda6938da7182b6 Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Sun, 15 Jun 2025 09:52:13 +0800 Subject: [PATCH 02/12] Add files via upload --- .../next/IDLE/2025-06-15-09-50-19.gh-issue-135511.2C5EX-.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/IDLE/2025-06-15-09-50-19.gh-issue-135511.2C5EX-.rst diff --git a/Misc/NEWS.d/next/IDLE/2025-06-15-09-50-19.gh-issue-135511.2C5EX-.rst b/Misc/NEWS.d/next/IDLE/2025-06-15-09-50-19.gh-issue-135511.2C5EX-.rst new file mode 100644 index 00000000000000..a0e9e627fdf06a --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2025-06-15-09-50-19.gh-issue-135511.2C5EX-.rst @@ -0,0 +1 @@ +Fixed `NameError` and `AttributeError` lack of the message in IDLE From 590ad56e00b6e81548398d52b07fc4e10d8e9694 Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Sun, 15 Jun 2025 10:35:33 +0800 Subject: [PATCH 03/12] Update run.py --- Lib/idlelib/run.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 8f8d98670b37df..fd7f3d2715b3d9 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -271,13 +271,10 @@ def print_exc(typ, exc, tb): "debugger_r.py", "bdb.py") cleanup_traceback(tbe, exclude) traceback.print_list(tbe, file=efile) - if not isinstance(exc, NameError) and not isinstance(exc, AttributeError): + if not isinstance(exc, (NameError, AttributeError)) or "\n" in str(exc): lines = get_message_lines(typ, exc, tb) else: - if "\n" in str(val): #The message must be defined by user if "\n" in the message - lines = [f"{typ.__name__}: {str(val)}"] - else: - lines = get_message_lines(typ, exc, tb) + lines = [f"{typ.__name__}: {str(exc)}"] for line in lines: print(line, end='', file=efile) From a03137b9ce139b938b38c66c93adc203ed5576d3 Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Sun, 15 Jun 2025 13:57:33 +0800 Subject: [PATCH 04/12] Update run.py --- Lib/idlelib/run.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index fd7f3d2715b3d9..3182ca89f4fe68 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -271,10 +271,13 @@ def print_exc(typ, exc, tb): "debugger_r.py", "bdb.py") cleanup_traceback(tbe, exclude) traceback.print_list(tbe, file=efile) - if not isinstance(exc, (NameError, AttributeError)) or "\n" in str(exc): + if not isinstance(exc, NameError) and not isinstance(exc, AttributeError): lines = get_message_lines(typ, exc, tb) else: - lines = [f"{typ.__name__}: {str(exc)}"] + if "\n" in str(exc): + lines = [f"{typ.__name__}: {str(exc)}"] + else: + lines = get_message_lines(typ, exc, tb) for line in lines: print(line, end='', file=efile) From 9ad6d9255eed17beeb65308368243529b5cabe14 Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Sun, 15 Jun 2025 20:04:48 +0800 Subject: [PATCH 05/12] Apply suggestions from code review Co-authored-by: Terry Jan Reedy --- .../next/IDLE/2025-06-15-09-50-19.gh-issue-135511.2C5EX-.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/IDLE/2025-06-15-09-50-19.gh-issue-135511.2C5EX-.rst b/Misc/NEWS.d/next/IDLE/2025-06-15-09-50-19.gh-issue-135511.2C5EX-.rst index a0e9e627fdf06a..7a704b5581292a 100644 --- a/Misc/NEWS.d/next/IDLE/2025-06-15-09-50-19.gh-issue-135511.2C5EX-.rst +++ b/Misc/NEWS.d/next/IDLE/2025-06-15-09-50-19.gh-issue-135511.2C5EX-.rst @@ -1 +1 @@ -Fixed `NameError` and `AttributeError` lack of the message in IDLE +Fix display of :exc:`NameError` and :exc:`AttributeError` with multi-line message. From 695a90e0ab5786325963383ff44590d251cf395f Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Sun, 15 Jun 2025 20:06:25 +0800 Subject: [PATCH 06/12] Apply suggestions from code review Co-authored-by: Terry Jan Reedy --- Lib/idlelib/run.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 3182ca89f4fe68..b02e3f3ed84432 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -271,13 +271,11 @@ def print_exc(typ, exc, tb): "debugger_r.py", "bdb.py") cleanup_traceback(tbe, exclude) traceback.print_list(tbe, file=efile) - if not isinstance(exc, NameError) and not isinstance(exc, AttributeError): + if ((not isinstance(exc, NameError) and not isinstance(exc, AttributeError)) + or "\n" in str(exc)): lines = get_message_lines(typ, exc, tb) - else: - if "\n" in str(exc): - lines = [f"{typ.__name__}: {str(exc)}"] - else: - lines = get_message_lines(typ, exc, tb) + else: # User-created Name/AttributeError with multiline message, GH-135511. + lines = [f"{typ.__name__}: {str(exc)}"] for line in lines: print(line, end='', file=efile) From 465097b0c3087e24a7c890cfc76b1eb0043711d8 Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Sun, 15 Jun 2025 20:09:56 +0800 Subject: [PATCH 07/12] Update run.py --- Lib/idlelib/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index b02e3f3ed84432..53c5a2d1c164f7 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -272,7 +272,7 @@ def print_exc(typ, exc, tb): cleanup_traceback(tbe, exclude) traceback.print_list(tbe, file=efile) if ((not isinstance(exc, NameError) and not isinstance(exc, AttributeError)) - or "\n" in str(exc)): + or "\n" not in str(exc)): lines = get_message_lines(typ, exc, tb) else: # User-created Name/AttributeError with multiline message, GH-135511. lines = [f"{typ.__name__}: {str(exc)}"] From b4cd5c9047be32f1880c612c3644bcf29ae7dc53 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 15 Jun 2025 14:28:01 -0400 Subject: [PATCH 08/12] Update Lib/idlelib/run.py --- Lib/idlelib/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 53c5a2d1c164f7..41d172cdf2bfdf 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -274,7 +274,7 @@ def print_exc(typ, exc, tb): if ((not isinstance(exc, NameError) and not isinstance(exc, AttributeError)) or "\n" not in str(exc)): lines = get_message_lines(typ, exc, tb) - else: # User-created Name/AttributeError with multiline message, GH-135511. + else: # User-created Name/AttributeError with multiline message, GH-135511. lines = [f"{typ.__name__}: {str(exc)}"] for line in lines: print(line, end='', file=efile) From ab7bf20760b6368fb83238cd4a2fea8d6f5b8b88 Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Wed, 18 Jun 2025 15:54:18 +0800 Subject: [PATCH 09/12] Update run.py --- Lib/idlelib/run.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 41d172cdf2bfdf..e7e78b741a1318 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -240,15 +240,19 @@ def get_message_lines(typ, exc, tb): return traceback.format_exception_only(typ, exc) -def print_exception(): +def print_exception(in_test=False): import linecache linecache.checkcache() flush_stdout() - efile = sys.stderr + if not in_test: + efile = sys.stderr + else: + efile = io.StringIO() typ, val, tb = excinfo = sys.exc_info() sys.last_type, sys.last_value, sys.last_traceback = excinfo sys.last_exc = val seen = set() + err = io.StringIO() def print_exc(typ, exc, tb): seen.add(id(exc)) @@ -274,12 +278,14 @@ def print_exc(typ, exc, tb): if ((not isinstance(exc, NameError) and not isinstance(exc, AttributeError)) or "\n" not in str(exc)): lines = get_message_lines(typ, exc, tb) - else: # User-created Name/AttributeError with multiline message, GH-135511. - lines = [f"{typ.__name__}: {str(exc)}"] + else: + lines = [f"{typ.__name__}: {str(exc)}"] for line in lines: print(line, end='', file=efile) + print(line, end='', file=err) print_exc(typ, val, tb) + return err.getvalue() def cleanup_traceback(tb, exclude): "Remove excluded traces from beginning/end of tb; get cached lines" From 2b182013df7bed9154d3ab238750cceac26805b9 Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Wed, 18 Jun 2025 15:56:30 +0800 Subject: [PATCH 10/12] Update test_run.py --- Lib/idlelib/idle_test/test_run.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index 83ecbffa2a197e..4e495bbe397a5c 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -45,6 +45,7 @@ def __eq__(self, other): ('int.reel', AttributeError, "type object 'int' has no attribute 'reel'. " "Did you mean: 'real'?\n"), + ('raise NameError("123\\n456")', NameError, "123\n456"), ) @force_not_colorized @@ -52,10 +53,16 @@ def test_get_message(self): for code, exc, msg in self.data: with self.subTest(code=code): try: - eval(compile(code, '', 'eval')) + if "raise " not in code: + eval(compile(code, '', 'eval')) + else: + exec(compile(code, '', 'exec')) except exc: - typ, val, tb = sys.exc_info() - actual = run.get_message_lines(typ, val, tb)[0] + if "raise " in code: + actual = run.print_exception(in_test=True) + else: + typ, val, tb = sys.exc_info() + actual = run.get_message_lines(typ, val, tb)[0] expect = f'{exc.__name__}: {msg}' self.assertEqual(actual, expect) From 282a8aa9060a9e1ef324ce150d30b2f6ec3d72ae Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Wed, 18 Jun 2025 15:58:39 +0800 Subject: [PATCH 11/12] Update run.py --- Lib/idlelib/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index e7e78b741a1318..fc41a473fd804b 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -247,7 +247,7 @@ def print_exception(in_test=False): if not in_test: efile = sys.stderr else: - efile = io.StringIO() + efile = io.StringIO() #If in test, anything mustn't be printed to sys.stderr typ, val, tb = excinfo = sys.exc_info() sys.last_type, sys.last_value, sys.last_traceback = excinfo sys.last_exc = val From 24bb5d17e2e633ff7b703062b4c1a77e30bf29c4 Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Wed, 18 Jun 2025 16:25:09 +0800 Subject: [PATCH 12/12] Update run.py --- Lib/idlelib/run.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index fc41a473fd804b..d146d0c989323f 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -240,7 +240,7 @@ def get_message_lines(typ, exc, tb): return traceback.format_exception_only(typ, exc) -def print_exception(in_test=False): +def print_exception(in_test=False): #Only when in test it is True, other it is False import linecache linecache.checkcache() flush_stdout() @@ -273,7 +273,8 @@ def print_exc(typ, exc, tb): print('Traceback (most recent call last):', file=efile) exclude = ("run.py", "rpc.py", "threading.py", "queue.py", "debugger_r.py", "bdb.py") - cleanup_traceback(tbe, exclude) + if not in_test: #When in test, the rpc.objecttable has no key 'exec' + cleanup_traceback(tbe, exclude) traceback.print_list(tbe, file=efile) if ((not isinstance(exc, NameError) and not isinstance(exc, AttributeError)) or "\n" not in str(exc)):