Skip to content

gh-146406: Add cross-language method suggestions for builtin AttributeError#146407

Open
mvanhorn wants to merge 2 commits intopython:mainfrom
mvanhorn:osc/cross-language-attr-hints
Open

gh-146406: Add cross-language method suggestions for builtin AttributeError#146407
mvanhorn wants to merge 2 commits intopython:mainfrom
mvanhorn:osc/cross-language-attr-hints

Conversation

@mvanhorn
Copy link
Contributor

@mvanhorn mvanhorn commented Mar 25, 2026

Summary

When an AttributeError on a builtin type (list, str, dict) has no
Levenshtein-based suggestion, check a static table of common method names
from other 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

Discussed at https://discuss.python.org/t/106632 (420 views, 25 likes, 15 posts, 3 core devs).

Design decisions from the thread:

  • Flat table per @pf_moore (post 14, 4 likes):

    "the table can simply map the method name and object type onto a suggestion. So add on a list is mapped straight to 'did you mean to use a set?' No need to check whether add is a set method - you know it is already."

  • list.add() suggests set, not append per @Storchaka (post 8):

    "It can also mean that you passed a list instead of set. Changing 'add' to 'append' will not fix the error, it will introduce yet one error."

    Reinforced by @tjreedy (post 12):

    "When a method exists for another, related, Python class, I think it better to suggest the other class rather than assume a foreign language match."

  • Scope guardrails per @dr_carlos (post 3): only add entries backed by real confusion evidence, not just because methods are similar.

  • Static table for builtins only (Option 1) - community consensus. 11 entries covering JavaScript, Java, C#, and Ruby.

Verification

Before (system Python 3.13, no cross-language hints):

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

>>> 'hello'.toUpperCase()
AttributeError: 'str' object has no attribute 'toUpperCase'

>>> {}.keySet()
AttributeError: 'dict' object has no attribute 'keySet'

>>> [].add(1)
AttributeError: 'list' object has no attribute 'add'

After (this PR):

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

>>> 'hello'.toUpperCase()
AttributeError: 'str' object has no attribute 'toUpperCase'. Did you mean '.upper' instead of '.toUpperCase'?

>>> {}.keySet()
AttributeError: 'dict' object has no attribute 'keySet'. Did you mean '.keys' instead of '.keySet'?

>>> [].add(1)
AttributeError: 'list' object has no attribute 'add'. Did you mean to use a set? Sets have an .add() method

Levenshtein still takes priority (trim->strip, indexOf->index already work and are not in the table). Only exact builtin types are matched - subclasses are not affected.

Changes

  • Lib/traceback.py: Added _CROSS_LANGUAGE_HINTS dict (11 entries), _get_cross_language_hint() function, and a 4-line fallback hook in TracebackException.__init__ that runs only when Levenshtein found nothing.
  • Lib/test/test_traceback.py: 15 test cases covering all entries, priority ordering, unknown attrs, and subclass exclusion.
  • Misc/NEWS.d/: NEWS entry.

Evidence

Source Evidence
SO: push vs append 320K views
SO: trim whitespace 1.5M views
JetBrains/PSF Survey 2024 40% of Python devs also use JS
CPython precedent elseif->elif (gh-132449), import x from y->from x import y (gh-98931)
Discourse thread 420 views, 25 likes, 3 core devs supportive

Fixes #146406

When Levenshtein-based suggestions find no match for an AttributeError
on list, str, or dict, check a static table of common method names from
JavaScript, Java, C#, and Ruby.

For example, [].push() now suggests .append(), "".toUpperCase() suggests
.upper(), and {}.keySet() suggests .keys().

The list.add() case suggests using a set instead of suggesting .append(),
since .add() is a set method and the user may have passed a list where
a set was expected (per discussion with Serhiy Storchaka, Terry Reedy,
and Paul Moore).

Design: flat (type, attr) -> suggestion text table, no runtime
introspection. Only exact builtin types are matched to avoid false
positives on subclasses.

Discussion: https://discuss.python.org/t/106632
@mvanhorn
Copy link
Contributor Author

Verification screenshots

Built CPython from source and ran the REPL to verify before/after behavior.

Before (Python 3.13, no cross-language hints)

before

After (this PR)

after

All 447 tests in test_traceback pass (including 28 new cross-language tests).

@picnixz picnixz self-requested a review March 25, 2026 09:05
@picnixz
Copy link
Member

picnixz commented Mar 25, 2026

I will make a review of this PR when I have time (by the end of the week), so fellow core devs, please hold off any merge, TiA!

@nedbat
Copy link
Member

nedbat commented Mar 25, 2026

Thanks for taking this on! From a language perspective, I think these can be shorter. Instead of:

AttributeError: 'list' object has no attribute 'push'. Did you mean '.append' instead of '.push'?

I think it is enough to say:

AttributeError: 'list' object has no attribute 'push'. Did you mean '.append' instead?

or even:

AttributeError: 'list' object has no attribute 'push'. Did you mean '.append'?

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add cross-language method suggestions for builtin AttributeError

3 participants