]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-38530: Require 50% similarity in NameError and AttributeError suggestions (GH...
authorDennis Sweeney <36520290+sweeneyde@users.noreply.github.com>
Tue, 27 Apr 2021 00:22:27 +0000 (20:22 -0400)
committerGitHub <noreply@github.com>
Tue, 27 Apr 2021 00:22:27 +0000 (01:22 +0100)
Lib/test/test_exceptions.py
Python/suggestions.c

index b3c00b04a37621ae892b57603fd646062c7e8ed7..590935cb6cd624b54f84a0aad80b7e24703fd576 100644 (file)
@@ -1507,6 +1507,61 @@ class NameErrorTests(unittest.TestCase):
 
         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 AttributeErrorTests(unittest.TestCase):
 
         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
index d4e9dc22bbc7b9ebd1b2b6a2e206ff830a663d09..2fd6714e84787400935789c5419f429c0080b47a 100644 (file)
@@ -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) {