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 092f9ddb5e)
Co-authored-by: E-Paine <63801254+E-Paine@users.noreply.github.com>
This commit is contained in:
Miss Islington (bot) 2021-05-07 17:35:25 -07:00 committed by GitHub
parent 13de28f17a
commit 5a5237c6d0
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)