From f1fc9f37f4dcafd37c9b6dbf08105a07adffef69 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 11 Apr 2025 12:42:29 +0300 Subject: [PATCH 1/2] gh-132385: Fix instance error suggestions side effects in `traceback` --- Lib/test/test_traceback.py | 22 +++++++++++++++++++ Lib/traceback.py | 6 ++++- ...-04-11-12-41-47.gh-issue-132385.86HoA7.rst | 2 ++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2025-04-11-12-41-47.gh-issue-132385.86HoA7.rst diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 5c390fd056b3e3..dc87982963e7f3 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -4504,6 +4504,28 @@ def foo(self): actual = self.get_suggestion(instance.foo) self.assertNotIn("self.blech", actual) + def test_unbound_local_error_with_side_effect(self): + # gh-132385 + class A: + def __getattr__(self, key): + if key == 'foo': + raise SystemExit('foo') + if key == 'spam': + raise ValueError('spam') + + def bar(self): + foo + def baz(self): + spam + + suggestion = self.get_suggestion(A().bar) + self.assertNotIn('self.', suggestion) + self.assertIn("'foo'", suggestion) + + suggestion = self.get_suggestion(A().baz) + self.assertNotIn('self.', suggestion) + self.assertIn("'spam'", suggestion) + def test_unbound_local_error_does_not_match(self): def func(): something = 3 diff --git a/Lib/traceback.py b/Lib/traceback.py index 647c23ed782c41..277ca016f64336 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -1532,7 +1532,11 @@ def _compute_suggestion_error(exc_value, tb, wrong_name): # has the wrong name as attribute if 'self' in frame.f_locals: self = frame.f_locals['self'] - if hasattr(self, wrong_name): + try: + has_wrong_name = hasattr(self, wrong_name) + except BaseException: + has_wrong_name = False + if has_wrong_name: return f"self.{wrong_name}" try: diff --git a/Misc/NEWS.d/next/Library/2025-04-11-12-41-47.gh-issue-132385.86HoA7.rst b/Misc/NEWS.d/next/Library/2025-04-11-12-41-47.gh-issue-132385.86HoA7.rst new file mode 100644 index 00000000000000..9aa2da452d29f6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-04-11-12-41-47.gh-issue-132385.86HoA7.rst @@ -0,0 +1,2 @@ +Fix instance error suggestions trigger potential exceptions +in :meth:`object.__getattr__` in :mod:`traceback`. From 06a97b70fdf70596958ba33dba085a9a349de913 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 11 Apr 2025 13:45:24 +0300 Subject: [PATCH 2/2] Address review --- Lib/test/test_traceback.py | 2 +- Lib/traceback.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index dc87982963e7f3..3cb0e1e0fd547c 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -4509,7 +4509,7 @@ def test_unbound_local_error_with_side_effect(self): class A: def __getattr__(self, key): if key == 'foo': - raise SystemExit('foo') + raise AttributeError('foo') if key == 'spam': raise ValueError('spam') diff --git a/Lib/traceback.py b/Lib/traceback.py index 277ca016f64336..ae2d07ce7fcfb5 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -1534,7 +1534,7 @@ def _compute_suggestion_error(exc_value, tb, wrong_name): self = frame.f_locals['self'] try: has_wrong_name = hasattr(self, wrong_name) - except BaseException: + except Exception: has_wrong_name = False if has_wrong_name: return f"self.{wrong_name}"