Skip to content

Commit 97b5f24

Browse files
gh-129605: Add more exception handling when computing suggestions in traceback.py (#129632)
1 parent c360884 commit 97b5f24

3 files changed

Lines changed: 54 additions & 24 deletions

File tree

‎Lib/test/test_traceback.py‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5109,6 +5109,32 @@ def func():
51095109
actual = self.get_suggestion(func)
51105110
self.assertIn("forget to import '_io'", actual)
51115111

5112+
def test_name_error_with_bad_getattr(self):
5113+
class A:
5114+
def __getattr__(self, x):
5115+
spam
5116+
5117+
actual = self.get_suggestion(A(), "eggs")
5118+
self.assertIn("name 'spam' is not defined", actual)
5119+
5120+
def test_name_error_with_bad_getattribute(self):
5121+
5122+
class A:
5123+
def __getattribute__(self, x):
5124+
spam
5125+
5126+
actual = self.get_suggestion(A(), "eggs")
5127+
self.assertIn("name 'spam' is not defined", actual)
5128+
5129+
def test_name_error_with_bad_property(self):
5130+
class A:
5131+
@property
5132+
def eggs(self):
5133+
eggs
5134+
5135+
actual = self.get_suggestion(A(), "eggs")
5136+
self.assertIn("name 'eggs' is not defined", actual)
5137+
51125138

51135139

51145140
class PurePythonSuggestionFormattingTests(

‎Lib/traceback.py‎

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1954,31 +1954,34 @@ def _compute_suggestion_error(exc_value, tb, wrong_name):
19541954
return None
19551955
else:
19561956
assert isinstance(exc_value, NameError)
1957-
# find most recent frame
1958-
if tb is None:
1957+
try:
1958+
# find most recent frame
1959+
if tb is None:
1960+
return None
1961+
while tb.tb_next is not None:
1962+
tb = tb.tb_next
1963+
frame = tb.tb_frame
1964+
d = (
1965+
list(frame.f_locals)
1966+
+ list(frame.f_globals)
1967+
+ list(frame.f_builtins)
1968+
)
1969+
d = [x for x in d if isinstance(x, str)]
1970+
if not_normalized and wrong_name in d:
1971+
return wrong_name
1972+
1973+
# Check first if we are in a method and the instance
1974+
# has the wrong name as attribute
1975+
if 'self' in frame.f_locals:
1976+
self = frame.f_locals['self']
1977+
try:
1978+
has_wrong_name = hasattr(self, wrong_name)
1979+
except Exception:
1980+
has_wrong_name = False
1981+
if has_wrong_name:
1982+
return f"self.{wrong_name}"
1983+
except Exception:
19591984
return None
1960-
while tb.tb_next is not None:
1961-
tb = tb.tb_next
1962-
frame = tb.tb_frame
1963-
d = (
1964-
list(frame.f_locals)
1965-
+ list(frame.f_globals)
1966-
+ list(frame.f_builtins)
1967-
)
1968-
d = [x for x in d if isinstance(x, str)]
1969-
if not_normalized and wrong_name in d:
1970-
return wrong_name
1971-
1972-
# Check first if we are in a method and the instance
1973-
# has the wrong name as attribute
1974-
if 'self' in frame.f_locals:
1975-
self = frame.f_locals['self']
1976-
try:
1977-
has_wrong_name = hasattr(self, wrong_name)
1978-
except Exception:
1979-
has_wrong_name = False
1980-
if has_wrong_name:
1981-
return f"self.{wrong_name}"
19821985

19831986
if not_normalized and wrong_name in d:
19841987
return wrong_name
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve exception handling when computing suggestions in traceback.py. This fixes a bug that could cause PyREPL to exit unexpectedly.

0 commit comments

Comments
 (0)