[Python-checkins] bpo-38530: Require 50% similarity in NameError and AttributeError suggestions (GH-25584)
pablogsal
webhook-mailer at python.org
Mon Apr 26 20:22:54 EDT 2021
https://github.com/python/cpython/commit/284c52da092438522949d6f96d8c1f9ff37f9f00
commit: 284c52da092438522949d6f96d8c1f9ff37f9f00
branch: master
author: Dennis Sweeney <36520290+sweeneyde at users.noreply.github.com>
committer: pablogsal <Pablogsal at gmail.com>
date: 2021-04-27T01:22:27+01:00
summary:
bpo-38530: Require 50% similarity in NameError and AttributeError suggestions (GH-25584)
files:
M Lib/test/test_exceptions.py
M Python/suggestions.c
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index b3c00b04a37621..590935cb6cd624 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -1507,6 +1507,61 @@ def f():
self.assertNotIn("somethingverywronghehe", err.getvalue())
+ def test_name_error_bad_suggestions_do_not_trigger_for_small_names(self):
+ vvv = mom = w = id = pytho = None
+
+ with self.subTest(name="b"):
+ try:
+ b
+ except NameError as exc:
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
+ self.assertNotIn("you mean", err.getvalue())
+ self.assertNotIn("vvv", err.getvalue())
+ self.assertNotIn("mom", err.getvalue())
+ self.assertNotIn("'id'", err.getvalue())
+ self.assertNotIn("'w'", err.getvalue())
+ self.assertNotIn("'pytho'", err.getvalue())
+
+ with self.subTest(name="v"):
+ try:
+ v
+ except NameError as exc:
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
+ self.assertNotIn("you mean", err.getvalue())
+ self.assertNotIn("vvv", err.getvalue())
+ self.assertNotIn("mom", err.getvalue())
+ self.assertNotIn("'id'", err.getvalue())
+ self.assertNotIn("'w'", err.getvalue())
+ self.assertNotIn("'pytho'", err.getvalue())
+
+ with self.subTest(name="m"):
+ try:
+ m
+ except NameError as exc:
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
+ self.assertNotIn("you mean", err.getvalue())
+ self.assertNotIn("vvv", err.getvalue())
+ self.assertNotIn("mom", err.getvalue())
+ self.assertNotIn("'id'", err.getvalue())
+ self.assertNotIn("'w'", err.getvalue())
+ self.assertNotIn("'pytho'", err.getvalue())
+
+ with self.subTest(name="py"):
+ try:
+ py
+ except NameError as exc:
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
+ self.assertNotIn("you mean", err.getvalue())
+ self.assertNotIn("vvv", err.getvalue())
+ self.assertNotIn("mom", err.getvalue())
+ self.assertNotIn("'id'", err.getvalue())
+ self.assertNotIn("'w'", err.getvalue())
+ self.assertNotIn("'pytho'", err.getvalue())
+
def test_name_error_suggestions_do_not_trigger_for_too_many_locals(self):
def f():
# Mutating locals() is unreliable, so we need to do it by hand
@@ -1661,6 +1716,63 @@ class A:
self.assertNotIn("blech", err.getvalue())
+ def test_getattr_error_bad_suggestions_do_not_trigger_for_small_names(self):
+ class MyClass:
+ vvv = mom = w = id = pytho = None
+
+ with self.subTest(name="b"):
+ try:
+ MyClass.b
+ except AttributeError as exc:
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
+ self.assertNotIn("you mean", err.getvalue())
+ self.assertNotIn("vvv", err.getvalue())
+ self.assertNotIn("mom", err.getvalue())
+ self.assertNotIn("'id'", err.getvalue())
+ self.assertNotIn("'w'", err.getvalue())
+ self.assertNotIn("'pytho'", err.getvalue())
+
+ with self.subTest(name="v"):
+ try:
+ MyClass.v
+ except AttributeError as exc:
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
+ self.assertNotIn("you mean", err.getvalue())
+ self.assertNotIn("vvv", err.getvalue())
+ self.assertNotIn("mom", err.getvalue())
+ self.assertNotIn("'id'", err.getvalue())
+ self.assertNotIn("'w'", err.getvalue())
+ self.assertNotIn("'pytho'", err.getvalue())
+
+ with self.subTest(name="m"):
+ try:
+ MyClass.m
+ except AttributeError as exc:
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
+ self.assertNotIn("you mean", err.getvalue())
+ self.assertNotIn("vvv", err.getvalue())
+ self.assertNotIn("mom", err.getvalue())
+ self.assertNotIn("'id'", err.getvalue())
+ self.assertNotIn("'w'", err.getvalue())
+ self.assertNotIn("'pytho'", err.getvalue())
+
+ with self.subTest(name="py"):
+ try:
+ MyClass.py
+ except AttributeError as exc:
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
+ self.assertNotIn("you mean", err.getvalue())
+ self.assertNotIn("vvv", err.getvalue())
+ self.assertNotIn("mom", err.getvalue())
+ self.assertNotIn("'id'", err.getvalue())
+ self.assertNotIn("'w'", err.getvalue())
+ self.assertNotIn("'pytho'", err.getvalue())
+
+
def test_getattr_suggestions_do_not_trigger_for_big_dicts(self):
class A:
blech = None
diff --git a/Python/suggestions.c b/Python/suggestions.c
index d4e9dc22bbc7b9..2fd6714e847874 100644
--- a/Python/suggestions.c
+++ b/Python/suggestions.c
@@ -102,7 +102,10 @@ calculate_suggestions(PyObject *dir,
if (current_distance == -1) {
return NULL;
}
- if (current_distance == 0 || current_distance > MAX_DISTANCE) {
+ if (current_distance == 0 ||
+ current_distance > MAX_DISTANCE ||
+ current_distance * 2 > name_size)
+ {
continue;
}
if (!suggestion || current_distance < suggestion_distance) {
More information about the Python-checkins
mailing list