GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — traceback._compute_suggestion_error crashes on `__getattr__` raising · Issue #129605 · python/cpython

traceback._compute_suggestion_error crashes on __getattr__ raising #129605

New issue
Copy link
New issue
Copy link
Closed
Closed
traceback._compute_suggestion_error crashes on __getattr__ raising#129605
Copy link
Assignees
pablogsal
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

@jcea
jcea
opened on Feb 3, 2025
Issue body actions

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 defined

And 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
Reacted by Gregory P. Smith and Konstantin Lopuhin

Activity

  1. jcea
    added
    topic-replRelated to the interactive shellRelated to the interactive shell
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Feb 3, 2025
  2. jcea
    assigned
    pablogsal
    on Feb 3, 2025
  3. skirpichev commented on Feb 3, 2025

    @skirpichev
    skirpichev
    on Feb 3, 2025
    Member
    More actions

    A quick fix (I'm not sure it's a right way):

    diff --git a/Lib/traceback.py b/Lib/traceback.py
    index 31c73efcef..abcc099c29 100644
    --- a/Lib/traceback.py
    +++ b/Lib/traceback.py
    @@ -1520,8 +1520,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):
    -                return f"self.{wrong_name}"
    +            try:
    +                if hasattr(self, wrong_name):
    +                    return f"self.{wrong_name}"
    +            except NameError:
    +                pass
     
         try:
             import _suggestions
    >>> 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 defined
  4. jcea commented on Feb 3, 2025

    @jcea
    jcea
    on Feb 3, 2025
    MemberAuthor
    More actions

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

  5. skirpichev commented on Feb 3, 2025

    @skirpichev
    skirpichev
    on Feb 3, 2025
    Member
    More actions

    That might be helpful for suggestions, see 99e2e60.

  6. srinivasreddy
    added 4 commits that reference this issue on Feb 4, 2025

    Merge branch 'main' into pythongh-129605

    720d6e5

    Merge branch 'main' into pythongh-129605

    bab4f8b

    Merge branch 'main' into pythongh-129605

    12fd25e

    Merge branch 'main' into pythongh-129605

    2f25445
  7. lopuhin commented on Feb 25, 2025

    @lopuhin
    lopuhin
    on Feb 25, 2025
    More actions

    Another instance of the same error:

    import traceback
    
    
    class C:
        @property
        def foo(self):
            return foo
    
    try:
        C().foo
    except Exception:
        print(traceback.format_exc())
    

    gives (at least on Python 3.12):

    % python t.py
    Traceback (most recent call last):
      File "/Users/konstantin/t.py", line 10, in <module>
        C().foo
      File "/Users/konstantin/t.py", line 7, in foo
        return foo
               ^^^
    NameError: name 'foo' is not defined
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/Users/konstantin/t.py", line 12, in <module>
        print(traceback.format_exc())
              ^^^^^^^^^^^^^^^^^^^^^^
      File "/opt/homebrew/Cellar/[email protected]/3.12.6/Frameworks/Python.framework/Versions/3.12/lib/python3.12/traceback.py", line 184, in format_exc
        return "".join(format_exception(sys.exception(), limit=limit, chain=chain))
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/opt/homebrew/Cellar/[email protected]/3.12.6/Frameworks/Python.framework/Versions/3.12/lib/python3.12/traceback.py", line 139, in format_exception
        te = TracebackException(type(value), value, tb, limit=limit, compact=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/opt/homebrew/Cellar/[email protected]/3.12.6/Frameworks/Python.framework/Versions/3.12/lib/python3.12/traceback.py", line 767, in __init__
        suggestion = _compute_suggestion_error(exc_value, exc_traceback, wrong_name)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/opt/homebrew/Cellar/[email protected]/3.12.6/Frameworks/Python.framework/Versions/3.12/lib/python3.12/traceback.py", line 1100, in _compute_suggestion_error
        if hasattr(self, wrong_name):
           ^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/konstantin/t.py", line 7, in foo
        return foo
               ^^^
    NameError: name 'foo' is not defined
    

    so the property gets re-executed. In other cases this can also lead to an infinite chain of exceptions.

  8. picnixz
    added
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    on Feb 25, 2025
  9. ambv
    changed the title [-]Crashing "pyrepl" with "__getattr__"[/-] [+]traceback._compute_suggestion_error crashes on `__getattr__` raising[/+] on Mar 20, 2025
  10. ambv
    removed
    topic-replRelated to the interactive shellRelated to the interactive shell
    on Mar 20, 2025
  11. kak-0 commented on Apr 14, 2025

    @kak-0
    kak-0
    on Apr 14, 2025
    More actions

    I encountered this bug when trying to log such an exception using logging.

    The following code demonstrates the issue (using ValueError for demonstration purposes, even though the real issue I had was a NameError due to forgetting to write self.).

    import logging
    
    class Foo:
        @property
        def x(self):
            raise ValueError("x")
    
        def y(self):
            return x
    
    logger = logging.getLogger(__name__)
    
    try:
        Foo().y()
    except Exception as e:
        logger.exception("y failed") # raises!
    
    print("done") # not reached!

    logger.exception prints "--- Logging error ---" and then calls traceback.print_exception which fails to print the traceback. The exception raised by hasattr is propagated by logger.exception, preventing the program from continuing!

    I think this should be considered a bug in logging: logger.exception should probably silently drop any exceptions raised while trying to handle logging errors instead of propagating the exceptions.

    Reacted by Konstantin Lopuhin
  12. duaneg commented on Jun 13, 2025

    @duaneg
    duaneg
    on Jun 13, 2025
    Contributor
    More actions

    This cannot be reproduced in v3.14: bisection confirms it was fixed in 641253c, for #132385. We can probably close this.

  13. skirpichev commented on Jun 13, 2025

    @skirpichev
    skirpichev
    on Jun 13, 2025
    Member
    More actions

    Looks valid in the master:

    Python 3.15.0a0 (heads/main-dirty:2b0c684e07, Jun 13 2025, 06:46:26) [Clang 14.0.6 ] 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
    qq
    Traceback (most recent call last):
      File "<python-input-1>", line 1, in <module>
        b.pepe
      File "<python-input-0>", line 4, in __getattr__
        print(qq)
              ^^
    NameError: name 'qq' is not defined
    >>> 
  14. jcea commented on Nov 11, 2025

    @jcea
    jcea
    on Nov 11, 2025
    MemberAuthor
    More actions

    Current Python 3.13.8 and 3.14.0 are not crashing anymore. I close this issue.

  15. jcea
    closed this as completedon Nov 11, 2025
  16. shenker commented on May 30, 2026

    @shenker
    shenker
    on May 30, 2026
    More actions

    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).

    import polars as pl
    import statsmodels.formula.api as smf
    
    df = pl.DataFrame({"a2": range(10), "b": range(10, 20)})
    model = smf.ols(
        "a ~ b",
        data=df.to_pandas(),
    )

    The CPython process running the marimo kernel will crash when the cell is run. A misspelled column name in a formula string triggers a NameError inside patsy's eval() call (where f_locals is a live VarLookupDict). Marimo calls traceback.print_exception directly from Python to format cell errors — unlike the REPL, which uses C-level PyErr_Display and is robust to this — so the KeyError(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 raise KeyError(0):

    import traceback
    
    class LegacyMapping:
        """Minimal repro of patsy.eval.VarLookupDict — implements __getitem__ but not __iter__."""
        def __getitem__(self, key):
            if key == "x":
                return 1
            raise KeyError(key)  # raises KeyError for integer keys too
    
    try:
        eval("nonexistent_var", {}, LegacyMapping())
    except NameError as e:
        traceback.print_exception(e)
        # Expected: prints NameError cleanly
        # Actual (3.13+): KeyError: 0 propagates out of print_exception
  17. ambv
    added 3 commits that reference this issue on Oct 20, 2026

    gh-129605: Add more exception handling when computing suggestions in …

    97b5f24

    [3.15] gh-129605: Add more exception handling when computing suggesti…

    9ce74c5

    [3.14] gh-129605: Add more exception handling when computing suggesti…

    a14a97f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @pablogsal
    pablogsal

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

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.