Feature or enhancement
Proposal:
People very often raise AttributeError(name) (~40 occurrences in CPython repo) or raise AttributeError (bare, this is rarer), but when displaying the traceback this misses either the object targeted or both the object and the attribute name.
That information is already there. AttributeError.obj and AttributeError.name is automatically set via _PyObject_SetAttributeErrorContext and now is only used to calculate attribute suggestions. Let's improve error messages with it too.
Consider a few examples where the user could raise a bare AttributeError or AttributeError("attr"), how we handle it (-), and how we could handle it (+):
importtracebackclassFoo1:
def__getattr__(self, name):
raiseAttributeError(name)
try:
Foo1().missing1exceptAttributeErrorasa:
print(f"-{traceback.format_exc().splitlines()[-1]}")
print(f"+AttributeError: {a.obj} has no attribute {a.name!r}\n")
classFoo2:
def__getattr__(self, name):
raiseAttributeErrortry:
Foo2().missing2exceptAttributeErrorasa:
print(f"-{traceback.format_exc().splitlines()[-1]}")
print(f"+AttributeError: {a.obj} has no attribute {a.name!r}\n")
importmod1# def __getattr__(name): raise AttributeError(name)try:
mod1.missing3exceptAttributeErrorasa:
print(f"-{traceback.format_exc().splitlines()[-1]}")
print(f"+AttributeError: {a.obj} has no attribute {a.name!r}\n")
importmod2# def __getattr__(name): raise AttributeErrortry:
mod2.missing4exceptAttributeErrorasa:
print(f"-{traceback.format_exc().splitlines()[-1]}")
print(f"+AttributeError: {a.obj} has no attribute {a.name!r}\n")-AttributeError: missing1+AttributeError: <__main__.Foo1 object at 0x109f2c8a0> has no attribute 'missing1'-AttributeError+AttributeError: <__main__.Foo2 object at 0x109f2c8a0> has no attribute 'missing2'-AttributeError: missing3+AttributeError: <module 'mod1' from './Python/cpython/mod1.py'> has no attribute 'missing3'-AttributeError+AttributeError: <module 'mod2' from './Python/cpython/mod2.py'> has no attribute 'missing4'
If we generate messages from collected context, we'll also fix some edge cases in the stdlib and snake knows where else. Consider this functools.singledispatchmethod edge case:
fromfunctoolsimportsingledispatchmethodclassC:
@singledispatchmethoddefsdm(self, a):
passC().sdm.__code__
which currently fails with - but could be +:
-AttributeError: . Did you mean: '__call__'?+AttributeError: '_singledispatchmethod_get' object has no attribute '__code__'. Did you mean: '__call__'?
Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
No response
Linked PRs
Feature or enhancement
Proposal:
People very often
raise AttributeError(name)(~40 occurrences in CPython repo) orraise AttributeError(bare, this is rarer), but when displaying the traceback this misses either the object targeted or both the object and the attribute name.That information is already there.
AttributeError.objandAttributeError.nameis automatically set via_PyObject_SetAttributeErrorContextand now is only used to calculate attribute suggestions. Let's improve error messages with it too.Consider a few examples where the user could raise a bare
AttributeErrororAttributeError("attr"), how we handle it (-), and how we could handle it (+):If we generate messages from collected context, we'll also fix some edge cases in the stdlib and snake knows where else. Consider this
functools.singledispatchmethodedge case:which currently fails with
-but could be+:Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
No response
Linked PRs
AttributeErrormessages from context #153786