Skip to content

Add the attribute that describe which operation cause NameError in NameError object #140779

@Locked-chess-official

Description

@Locked-chess-official

Feature or enhancement

Proposal:

>>> del next
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    del next
        ^^^^
NameError: name 'next' is not defined. Did you mean: 'anext'?
>>> del anext
Traceback (most recent call last):
  File "<python-input-1>", line 1, in <module>
    del anext
        ^^^^^
NameError: name 'anext' is not defined. Did you mean: 'next'?

As you see, the two suggestions played football with you about which name was right (508 loop detected).

The reason is that now the code in _compute_suggestion_error anyway add f_builtins when suggest for NameError :

https://github.com/python/cpython/blob/main/Lib/traceback.py#L1670-L1682

        assert isinstance(exc_value, NameError)
        # find most recent frame
        if tb is None:
            return None
        while tb.tb_next is not None:
            tb = tb.tb_next
        frame = tb.tb_frame
        d = (
            list(frame.f_locals)
            + list(frame.f_globals)
            + list(frame.f_builtins)
        )
        d = [x for x in d if isinstance(x, str)]

If we can add the attribute in NameError (e.g. "op") to describe which operation cause the NameError, the suggestion will be more exactly:

        assert isinstance(exc_value, NameError)
        # find most recent frame
        if tb is None:
            return None
        while tb.tb_next is not None:
            tb = tb.tb_next
        frame = tb.tb_frame
        if getattr(exc_value, "op", "getting") == "deleting":
            d = (list(frame.f_locals)
                + list(frame.f_globals))
        else:
            d = (
                list(frame.f_locals)
                + list(frame.f_globals)
                + list(frame.f_builtins)
            )
        d = [x for x in d if isinstance(x, str)]

By this way, the suggestion on NameError caused by deleting a variable won't possibly be a builtins name that user hasn't redefined it.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)type-featureA feature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions