Repository navigation
traceback._compute_suggestion_error crashes on __getattr__ raising #129605
Copy link
Copy link
Closed
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
Bug description:
This is a regression introduced in 3.13 because the new pyrepl. 3.14 is also affected.
Type this in an interactive 3.13/3.14 session:
>>> class a:
... def __getattr__(self, x):
... print(x)
... print(qq)
...
>>> b=a()
>>> b.pepe
pepe
qq
qq
Traceback (most recent call last):
File "<python-input-5>", line 1, in <module>
File "<python-input-3>", line 4, in __getattr__
NameError: name 'qq' is not defined
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/usr/local/lib/python3.13/_pyrepl/__main__.py", line 6, in <module>
__pyrepl_interactive_console()
File "/usr/local/lib/python3.13/_pyrepl/main.py", line 59, in interactive_console
run_multiline_interactive_console(console)
File "/usr/local/lib/python3.13/_pyrepl/simple_interact.py", line 160, in run_multiline_interactive_console
more = console.push(_strip_final_indent(statement), filename=input_name, _symbol="single") # type: ignore[call-arg]
File "/usr/local/lib/python3.13/code.py", line 314, in push
more = self.runsource(source, filename, symbol=_symbol)
File "/usr/local/lib/python3.13/_pyrepl/console.py", line 211, in runsource
self.runcode(code)
File "/usr/local/lib/python3.13/code.py", line 96, in runcode
self.showtraceback()
File "/usr/local/lib/python3.13/code.py", line 129, in showtraceback
self._showtraceback(typ, value, tb.tb_next, '')
File "/usr/local/lib/python3.13/code.py", line 145, in _showtraceback
self._excepthook(typ, value, tb)
File "/usr/local/lib/python3.13/_pyrepl/console.py", line 169, in _excepthook
lines = traceback.format_exception(
File "/usr/local/lib/python3.13/traceback.py", line 154, in format_exception
te = TracebackException(type(value), value, tb, limit=limit, compact=True)
File "/usr/local/lib/python3.13/traceback.py", line 1090, in __init__
suggestion = _compute_suggestion_error(exc_value, exc_traceback, wrong_name)
File "/usr/local/lib/python3.13/traceback.py", line 1516, in _compute_suggestion_error
if hasattr(self, wrong_name):
File "<python-input-3>", line 4, in __getattr__
NameError: name 'qq' is not definedAnd the interactive python session is terminated.
Under previous Python releases, with no pyrepl, the right exception is raised and the repl keeps going:
Python 3.9.21 (main, Dec 9 2024, 19:43:35)
[GCC 10.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> class a:
... def __getattr__(self, x):
... print(x)
... print(qq)
...
>>> b=a()
>>> b.pepe
pepe
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __getattr__
NameError: name 'qq' is not defined
>>> Notice that this problem raises SPECIFICALLY if __getattr__ raises a NameError exception. Other exceptions, like division by zero, don't break pyrepl.
CPython versions tested on:
3.13, 3.12, 3.11, 3.10, 3.9, 3.14
Operating systems tested on:
Linux
Linked PRs
- gh-129605: Fix crashing pyrepl when NameError occurres in __getattr__ method #129615
- gh-129605: Add more exception handling when computing suggestions in traceback.py #129632
- [3.15] gh-129605: Add more exception handling when computing suggestions in traceback.py (GH-129632) #159983
- [3.14] gh-129605: Add more exception handling when computing suggestions in traceback.py (GH-129632) #159994
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Activity
skirpichev commentedon Feb 3, 2025
A quick fix (I'm not sure it's a right way):
>>> b.pepe pepe qq Traceback (most recent call last): File "<python-input-2>", line 1, in <module> b.pepe File "<python-input-0>", line 4, in __getattr__ print(qq) ^^ NameError: name 'qq' is not definedjcea commentedon Feb 3, 2025
Cool, but "qq" should not be searched in the class. Notice that
__getattr__is called twice, first for "pepe" and another one, incorrectly, for "qq".skirpichev commentedon Feb 3, 2025
That might be helpful for suggestions, see 99e2e60.
Merge branch 'main' into pythongh-129605
Merge branch 'main' into pythongh-129605
Merge branch 'main' into pythongh-129605
Merge branch 'main' into pythongh-129605
lopuhin commentedon Feb 25, 2025
Another instance of the same error:
gives (at least on Python 3.12):
so the property gets re-executed. In other cases this can also lead to an infinite chain of exceptions.
[-]Crashing "pyrepl" with "__getattr__"[/-][+]traceback._compute_suggestion_error crashes on `__getattr__` raising[/+]kak-0 commentedon Apr 14, 2025
I encountered this bug when trying to log such an exception using
logging.The following code demonstrates the issue (using
ValueErrorfor demonstration purposes, even though the real issue I had was aNameErrordue to forgetting to writeself.).logger.exceptionprints"--- Logging error ---"and then callstraceback.print_exceptionwhich fails to print the traceback. The exception raised byhasattris propagated bylogger.exception, preventing the program from continuing!I think this should be considered a bug in
logging:logger.exceptionshould probably silently drop any exceptions raised while trying to handle logging errors instead of propagating the exceptions.duaneg commentedon Jun 13, 2025
This cannot be reproduced in v3.14: bisection confirms it was fixed in 641253c, for #132385. We can probably close this.
skirpichev commentedon Jun 13, 2025
Looks valid in the master:
jcea commentedon Nov 11, 2025
Current Python 3.13.8 and 3.14.0 are not crashing anymore. I close this issue.
shenker commentedon May 30, 2026
I found another way to reproduce this bug that still works in 3.14.4. PR #129632's approach of wrapping the NameError branch in try/except Exception: return None would fix this.
Here's the real-world reproducer (and how I came across this bug). Create a marimo (0.23.8) notebook with the following cell (that imports statsmodel 0.14.6, which in turn imports patsy 1.0.2).
The CPython process running the marimo kernel will crash when the cell is run. A misspelled column name in a formula string triggers a
NameErrorinside patsy'seval()call (wheref_localsis a liveVarLookupDict). Marimo callstraceback.print_exceptiondirectly from Python to format cell errors — unlike the REPL, which uses C-levelPyErr_Displayand is robust to this — so theKeyError(0)propagates uncaught and kills the notebook kernel.This minimal reproducer mocks patsy's VarLookupDict, which implements
__getitem__but not__iter__, causing Python to fall back to the legacy sequence protocol(__getitem__(0), __getitem__(1), ...)and immediately raiseKeyError(0):gh-129605: Add more exception handling when computing suggestions in …
[3.15] gh-129605: Add more exception handling when computing suggesti…
[3.14] gh-129605: Add more exception handling when computing suggesti…