Skip to content

Add cross-language method suggestions for builtin AttributeError #146406

@mvanhorn

Description

@mvanhorn

Proposal

When an AttributeError occurs on a builtin type (list, str, dict) and the existing Levenshtein-based suggestion system finds no match, check a static table of common method names from other programming languages.

Before:

>>> [1, 2, 3].push(4)
AttributeError: 'list' object has no attribute 'push'

After:

>>> [1, 2, 3].push(4)
AttributeError: 'list' object has no attribute 'push'. Did you mean '.append' instead of '.push'?

Discourse discussion

This was discussed at https://discuss.python.org/t/cross-language-method-suggestions-for-attributeerror/106632 (420 views, 25 likes, 3 core devs participated).

Design decisions from the discussion:

  • Flat table approach per @pf_moore (post 14, 4 likes): each (type, attr) entry carries the exact suggestion text. No runtime introspection of related types needed.

  • list.add() suggests using a set per @Storchaka (post 8) and @tjreedy (post 12): "It can also mean that you passed a list instead of set." The table maps this to a wrong-type hint rather than suggesting append.

  • Option 1: static table for builtins only - community consensus. 11 entries covering JS/Java/C#/Ruby. Inclusion criteria: evidence of real confusion, not catchable by Levenshtein, from a top-4 language.

  • Scope guardrails per @dr_carlos (post 3): "only add entries with clear evidence of real confusion, not just because two methods do similar things."

Examples

What user writes Before After
[].push(4) no suggestion Did you mean '.append'?
"".toUpperCase() no suggestion Did you mean '.upper'?
{}.keySet() no suggestion Did you mean '.keys'?
[].add(1) no suggestion Did you mean to use a set?
"".trimStart() no suggestion Did you mean '.lstrip'?

Entries where Levenshtein already provides a match (indexOf->index, trim->strip) are intentionally excluded from the table since they already work.

Implementation

~60 lines in Lib/traceback.py: a dict mapping (builtin_type, wrong_name) to suggestion text, a small lookup function, and a 4-line hook in TracebackException.__init__ that runs only when Levenshtein found nothing. Tests cover all entries plus priority ordering and subclass exclusion.

Has this already been discussed elsewhere?

Yes, on Discourse: https://discuss.python.org/t/106632

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-replRelated to the interactive shelltype-featureA feature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions