Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.1k
Description
Feature or enhancement
Proposal:
Problem description
In more recent versions of Python, for uncaughtNameError
s andAttributeErrors
, the system tries to suggest names that might have been typoed:
>>>inttTraceback (mostrecentcalllast):File"<stdin>",line1,in<module>NameError:name'intt'isnotdefined.Didyoumean:'int'?
However, the suggestion logic apparently does not take underscore conventions into account:
>>> _foo = 1>>> fooTraceback (most recent call last): File "<stdin>", line 1, in <module>NameError: name 'foo' is not defined. Did you mean: '_foo'?
Commonly, leading underscores on names are used by convention to mark names that should not be referenced directly in client code. (Of course, it's occasionally necessary or desirable to call dunder methods directly, particularly when inheritance is involved, but generally not outside of classes.)
This has thenegative effect, that Python itself could recommend that users invoke undocumented, unstable or unintentional APIs without good reason. One current real-world example of this occurs with Pandas, where version 2.0 removed theappend
method fromDataFrame
s, but there happens to be an_append
method left behind as an implementation detail:
>>> import pandas as pd>>> pd.DataFrame().appendTraceback (most recent call last): File "<stdin>", line 1, in <module> File "/path/to/lib/python3.11/site-packages/pandas/core/generic.py", line 6296, in __getattr__ return object.__getattribute__(self, name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^AttributeError: 'DataFrame' object has no attribute 'append'. Did you mean: '_append'?
Proposal
I propose that:when the invalid identifier or attribute name does not already start with an underscore, valid names thatdo start with an underscore should be excluded from suggestions. As mentioned in the linked discussion, there is already precedent for this -
- As implemented by
help
:
>>> import pydoc>>> pydoc.pager = print # to simplify behaviour for the example>>> class Example:... __slots__ = [] # to simplify behaviour for the example... def method(self): pass... def _method(self): pass... >>> help(Example)Help on class Example in module __main__:class Example(builtins.object) | Methods defined here: | | method(self)>>>
- When using star-imports:
>>> _, name, result = 1, 2, {}>>> exec('from __main__ import *', result)>>> '_' in resultFalse>>> 'name' in resultTrue
It still makes sense IMO to suggest underscore names when the invalid name already starts with an underscore - even mixing and matching single- and double-underscore cases. For example,_init_
is a very plausible typo for__init__
, especially for beginners who are learning from a book or an old PDF.
Has this already been discussed elsewhere?
I have already discussed this feature proposal on Discourse