Given this example where the bar
attribute has been deprecated in favor of new_bar
:
class Foo:
def __init__(self):
self._bar = "other_bar"
self.new_bar = "new_bar"
def __getattr__(self, name):
if name == "bar":
raise AttributeError("Use 'new_bar' instead.")
return super().__getattribute__(name)
Foo().bar
Since Python 3.10, there are name suggestions, and the resulting error message will be:
AttributeError: Use 'new_bar' instead.. Did you mean: '_bar'?
This is very similar to this suggestion. However, in this case, the AttributeError
is raised manually in the code and the feature that followed this suggestion no longer applies.
Moreover, the error message provided manually may conflict with the name suggestion. For example, with NumPy 2.0:
>>> import numpy
>>> numpy.float_
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/arnaud-ma/.pyenv/versions/3.12.6/lib/python3.12/site-packages/numpy/__init__.py", line 397, in __getattr__
raise AttributeError(
AttributeError: `np.float_` was removed in the NumPy 2.0 release. Use `np.float64` instead.. Did you mean: 'float16'?
The undocumented workaround is to replace raise AttributeError(msg)
with raise AttributeError(msg, name=None)
. However, this is not documented at all, and it could break at any moment. The only thing that is said in the doc is:
The
name
andobj
attributes can be set using keyword-only arguments to the constructor. When set they represent the name of the attribute that was attempted to be accessed and the object that was accessed for said attribute, respectively.
Possible solutions include:
- Providing a way to disable name suggestions, or at least documenting the fact that setting the
name
attribute toNone
disables name suggestions. - Do we really need name suggestions when raising an
AttributeError
/NameError
manually with a specific message? The message should already contain all the necessary information about the error. Moreover, the author of the message is likely unaware that something will be appended afterward. In my opinion, this behavior should be disabled by default.