summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2024-05-06 12:53:15 (GMT)
committerGitHub <noreply@github.com>2024-05-06 12:53:15 (GMT)
commit0085c3ae8f067abd4f6540d0f6dd2fb13107618e (patch)
tree02a0986dbc669ca6e6c53bf9fb567cfb25e95130
parentd6fa1d4beef2bf9d83048469667e0ba5f2b41068 (diff)
downloadcpython-0085c3ae8f067abd4f6540d0f6dd2fb13107618e.zip
cpython-0085c3ae8f067abd4f6540d0f6dd2fb13107618e.tar.gz
cpython-0085c3ae8f067abd4f6540d0f6dd2fb13107618e.tar.bz2
gh-116871: Improve name suggestions in tracebacks (GH-116930)
Only include underscored names in name suggestions for AttributeError and ImportError if the original name was underscored.
-rw-r--r--Lib/test/test_traceback.py32
-rw-r--r--Lib/traceback.py11
-rw-r--r--Misc/NEWS.d/next/Library/2024-03-17-18-24-23.gh-issue-116871.9uSl8M.rst2
3 files changed, 45 insertions, 0 deletions
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index 7e48510..5987ec3 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -3882,6 +3882,27 @@ class SuggestionFormattingTestBase:
actual = self.get_suggestion(cls(), 'bluch')
self.assertIn(suggestion, actual)
+ def test_getattr_suggestions_underscored(self):
+ class A:
+ bluch = None
+
+ self.assertIn("'bluch'", self.get_suggestion(A(), 'blach'))
+ self.assertIn("'bluch'", self.get_suggestion(A(), '_luch'))
+ self.assertIn("'bluch'", self.get_suggestion(A(), '_bluch'))
+
+ class B:
+ _bluch = None
+ def method(self, name):
+ getattr(self, name)
+
+ self.assertIn("'_bluch'", self.get_suggestion(B(), '_blach'))
+ self.assertIn("'_bluch'", self.get_suggestion(B(), '_luch'))
+ self.assertNotIn("'_bluch'", self.get_suggestion(B(), 'bluch'))
+
+ self.assertIn("'_bluch'", self.get_suggestion(partial(B().method, '_blach')))
+ self.assertIn("'_bluch'", self.get_suggestion(partial(B().method, '_luch')))
+ self.assertIn("'_bluch'", self.get_suggestion(partial(B().method, 'bluch')))
+
def test_getattr_suggestions_do_not_trigger_for_long_attributes(self):
class A:
blech = None
@@ -4074,6 +4095,17 @@ class SuggestionFormattingTestBase:
actual = self.get_import_from_suggestion(code, 'bluch')
self.assertIn(suggestion, actual)
+ def test_import_from_suggestions_underscored(self):
+ code = "bluch = None"
+ self.assertIn("'bluch'", self.get_import_from_suggestion(code, 'blach'))
+ self.assertIn("'bluch'", self.get_import_from_suggestion(code, '_luch'))
+ self.assertIn("'bluch'", self.get_import_from_suggestion(code, '_bluch'))
+
+ code = "_bluch = None"
+ self.assertIn("'_bluch'", self.get_import_from_suggestion(code, '_blach'))
+ self.assertIn("'_bluch'", self.get_import_from_suggestion(code, '_luch'))
+ self.assertNotIn("'_bluch'", self.get_import_from_suggestion(code, 'bluch'))
+
def test_import_from_suggestions_do_not_trigger_for_long_attributes(self):
code = "blech = None"
diff --git a/Lib/traceback.py b/Lib/traceback.py
index 1878779..9401b46 100644
--- a/Lib/traceback.py
+++ b/Lib/traceback.py
@@ -1469,12 +1469,23 @@ def _compute_suggestion_error(exc_value, tb, wrong_name):
obj = exc_value.obj
try:
d = dir(obj)
+ hide_underscored = (wrong_name[:1] != '_')
+ if hide_underscored and tb is not None:
+ while tb.tb_next is not None:
+ tb = tb.tb_next
+ frame = tb.tb_frame
+ if 'self' in frame.f_locals and frame.f_locals['self'] is obj:
+ hide_underscored = False
+ if hide_underscored:
+ d = [x for x in d if x[:1] != '_']
except Exception:
return None
elif isinstance(exc_value, ImportError):
try:
mod = __import__(exc_value.name)
d = dir(mod)
+ if wrong_name[:1] != '_':
+ d = [x for x in d if x[:1] != '_']
except Exception:
return None
else:
diff --git a/Misc/NEWS.d/next/Library/2024-03-17-18-24-23.gh-issue-116871.9uSl8M.rst b/Misc/NEWS.d/next/Library/2024-03-17-18-24-23.gh-issue-116871.9uSl8M.rst
new file mode 100644
index 0000000..f3caa63
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-03-17-18-24-23.gh-issue-116871.9uSl8M.rst
@@ -0,0 +1,2 @@
+Name suggestions for :exc:`AttributeError` and :exc:`ImportError` now only
+include underscored names if the original name was underscored.