mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
bpo-38530: Offer suggestions on NameError (GH-25397)
When printing NameError raised by the interpreter, PyErr_Display will offer suggestions of simmilar variable names in the function that the exception was raised from: >>> schwarzschild_black_hole = None >>> schwarschild_black_hole Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'schwarschild_black_hole' is not defined. Did you mean: schwarzschild_black_hole?
This commit is contained in:
parent
c4073a24f9
commit
5bf8bf2267
8 changed files with 287 additions and 10 deletions
|
@ -1413,6 +1413,129 @@ class ExceptionTests(unittest.TestCase):
|
|||
|
||||
gc_collect()
|
||||
|
||||
global_for_suggestions = None
|
||||
|
||||
class NameErrorTests(unittest.TestCase):
|
||||
def test_name_error_has_name(self):
|
||||
try:
|
||||
bluch
|
||||
except NameError as exc:
|
||||
self.assertEqual("bluch", exc.name)
|
||||
|
||||
def test_name_error_suggestions(self):
|
||||
def Substitution():
|
||||
noise = more_noise = a = bc = None
|
||||
blech = None
|
||||
print(bluch)
|
||||
|
||||
def Elimination():
|
||||
noise = more_noise = a = bc = None
|
||||
blch = None
|
||||
print(bluch)
|
||||
|
||||
def Addition():
|
||||
noise = more_noise = a = bc = None
|
||||
bluchin = None
|
||||
print(bluch)
|
||||
|
||||
def SubstitutionOverElimination():
|
||||
blach = None
|
||||
bluc = None
|
||||
print(bluch)
|
||||
|
||||
def SubstitutionOverAddition():
|
||||
blach = None
|
||||
bluchi = None
|
||||
print(bluch)
|
||||
|
||||
def EliminationOverAddition():
|
||||
blucha = None
|
||||
bluc = None
|
||||
print(bluch)
|
||||
|
||||
for func, suggestion in [(Substitution, "blech?"),
|
||||
(Elimination, "blch?"),
|
||||
(Addition, "bluchin?"),
|
||||
(EliminationOverAddition, "blucha?"),
|
||||
(SubstitutionOverElimination, "blach?"),
|
||||
(SubstitutionOverAddition, "blach?")]:
|
||||
err = None
|
||||
try:
|
||||
func()
|
||||
except NameError as exc:
|
||||
with support.captured_stderr() as err:
|
||||
sys.__excepthook__(*sys.exc_info())
|
||||
self.assertIn(suggestion, err.getvalue())
|
||||
|
||||
def test_name_error_suggestions_from_globals(self):
|
||||
def func():
|
||||
print(global_for_suggestio)
|
||||
try:
|
||||
func()
|
||||
except NameError as exc:
|
||||
with support.captured_stderr() as err:
|
||||
sys.__excepthook__(*sys.exc_info())
|
||||
self.assertIn("global_for_suggestions?", err.getvalue())
|
||||
|
||||
def test_name_error_suggestions_do_not_trigger_for_long_names(self):
|
||||
def f():
|
||||
somethingverywronghehehehehehe = None
|
||||
print(somethingverywronghe)
|
||||
|
||||
try:
|
||||
f()
|
||||
except NameError as exc:
|
||||
with support.captured_stderr() as err:
|
||||
sys.__excepthook__(*sys.exc_info())
|
||||
|
||||
self.assertNotIn("somethingverywronghehe", err.getvalue())
|
||||
|
||||
def test_name_error_suggestions_do_not_trigger_for_big_dicts(self):
|
||||
def f():
|
||||
# Mutating locals() is unreliable, so we need to do it by hand
|
||||
a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = a10 = a11 = a12 = a13 = \
|
||||
a14 = a15 = a16 = a17 = a18 = a19 = a20 = a21 = a22 = a23 = a24 = a25 = \
|
||||
a26 = a27 = a28 = a29 = a30 = a31 = a32 = a33 = a34 = a35 = a36 = a37 = \
|
||||
a38 = a39 = a40 = a41 = a42 = a43 = a44 = a45 = a46 = a47 = a48 = a49 = \
|
||||
a50 = a51 = a52 = a53 = a54 = a55 = a56 = a57 = a58 = a59 = a60 = a61 = \
|
||||
a62 = a63 = a64 = a65 = a66 = a67 = a68 = a69 = a70 = a71 = a72 = a73 = \
|
||||
a74 = a75 = a76 = a77 = a78 = a79 = a80 = a81 = a82 = a83 = a84 = a85 = \
|
||||
a86 = a87 = a88 = a89 = a90 = a91 = a92 = a93 = a94 = a95 = a96 = a97 = \
|
||||
a98 = a99 = a100 = a101 = a102 = a103 = None
|
||||
print(a0)
|
||||
|
||||
try:
|
||||
f()
|
||||
except NameError as exc:
|
||||
with support.captured_stderr() as err:
|
||||
sys.__excepthook__(*sys.exc_info())
|
||||
|
||||
self.assertNotIn("a10", err.getvalue())
|
||||
|
||||
def test_name_error_with_custom_exceptions(self):
|
||||
def f():
|
||||
blech = None
|
||||
raise NameError()
|
||||
|
||||
try:
|
||||
f()
|
||||
except NameError as exc:
|
||||
with support.captured_stderr() as err:
|
||||
sys.__excepthook__(*sys.exc_info())
|
||||
|
||||
self.assertNotIn("blech", err.getvalue())
|
||||
|
||||
def f():
|
||||
blech = None
|
||||
raise NameError
|
||||
|
||||
try:
|
||||
f()
|
||||
except NameError as exc:
|
||||
with support.captured_stderr() as err:
|
||||
sys.__excepthook__(*sys.exc_info())
|
||||
|
||||
self.assertNotIn("blech", err.getvalue())
|
||||
|
||||
class AttributeErrorTests(unittest.TestCase):
|
||||
def test_attributes(self):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue