0
0
mirror of https://github.com/python/cpython.git synced 2024-11-24 00:38:00 +01:00

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.
This commit is contained in:
Serhiy Storchaka 2024-05-06 15:53:15 +03:00 committed by GitHub
parent d6fa1d4bee
commit 0085c3ae8f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 45 additions and 0 deletions

View File

@ -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"

View File

@ -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:

View File

@ -0,0 +1,2 @@
Name suggestions for :exc:`AttributeError` and :exc:`ImportError` now only
include underscored names if the original name was underscored.