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>
This commit is contained in:
E-Paine 2021-05-08 00:52:01 +01:00 committed by GitHub
parent b2ec37a722
commit 092f9ddb5e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 5 deletions

View file

@ -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)