summaryrefslogtreecommitdiffstats
path: root/Lib/idlelib/run.py
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2021-05-08 00:35:25 (GMT)
committerGitHub <noreply@github.com>2021-05-08 00:35:25 (GMT)
commit5a5237c6d08ed97458b0903d6836624168df0b51 (patch)
treef3af69678ae8173f7e4596d40f7350f75044e2a8 /Lib/idlelib/run.py
parent13de28f17af02563cb8c6d0f6da3c178a4241ff3 (diff)
downloadcpython-5a5237c6d08ed97458b0903d6836624168df0b51.zip
cpython-5a5237c6d08ed97458b0903d6836624168df0b51.tar.gz
cpython-5a5237c6d08ed97458b0903d6836624168df0b51.tar.bz2
bpo-44026: Idle - display interpreter's 'did you mean' hints (GH-25912)
A C function accessible by the default exception handler, but not by python code, finds the existing name closest to the name causing a name or attribute error. For such errors, call the default handler after capturing stderr and retrieve its message line. Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu> (cherry picked from commit 092f9ddb5e85665552c8207972cd393d492f764e) Co-authored-by: E-Paine <63801254+E-Paine@users.noreply.github.com>
Diffstat (limited to 'Lib/idlelib/run.py')
-rw-r--r--Lib/idlelib/run.py16
1 files changed, 15 insertions, 1 deletions
diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py
index 07e9a2b..3836727 100644
--- a/Lib/idlelib/run.py
+++ b/Lib/idlelib/run.py
@@ -4,6 +4,7 @@ Simplified, pyshell.ModifiedInterpreter spawns a subprocess with
f'''{sys.executable} -c "__import__('idlelib.run').run.main()"'''
'.run' is needed because __import__ returns idlelib, not idlelib.run.
"""
+import contextlib
import functools
import io
import linecache
@@ -211,6 +212,19 @@ def show_socket_error(err, address):
parent=root)
root.destroy()
+
+def get_message_lines(typ, exc, tb):
+ "Return line composing the exception message."
+ if typ in (AttributeError, NameError):
+ # 3.10+ hints are not directly accessible from python (#44026).
+ err = io.StringIO()
+ with contextlib.redirect_stderr(err):
+ sys.__excepthook__(typ, exc, tb)
+ return [err.getvalue().split("\n")[-2] + "\n"]
+ else:
+ return traceback.format_exception_only(typ, exc)
+
+
def print_exception():
import linecache
linecache.checkcache()
@@ -241,7 +255,7 @@ def print_exception():
"debugger_r.py", "bdb.py")
cleanup_traceback(tbe, exclude)
traceback.print_list(tbe, file=efile)
- lines = traceback.format_exception_only(typ, exc)
+ lines = get_message_lines(typ, exc, tb)
for line in lines:
print(line, end='', file=efile)