-
-
Notifications
You must be signed in to change notification settings - Fork 34.3k
Description
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