Format attribute name with repr() when formatting AttributeError error message #154610
Copy link
Copy link
Open
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancementA feature request or enhancement
Description
Feature or enhancement
Some code paths format the attribute name with str() to format the AttributeError error message. Example:
>>> getattr(object(), "a'b")
AttributeError: 'object' object has no attribute 'a'b'
The quote character ' should be escaped in the error message ('a\'b'), or the attribute name should be quoted with " character ("a'b").
The expected error is:
AttributeError: 'object' object has no attribute "a'b"
I propose replacing str() with repr() to format the attribute name.
This issue is a follow-up of #153786 (comment) discussion (another AttributeError change).
Linked PRs
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancementA feature request or enhancement
Activity
pythongh-154610: Use repr() to format the attribute name in Attribute…
serhiy-storchaka commentedon Jul 24, 2026
How does it work with StrEnum?
vstinner commentedon Jul 24, 2026
My PR changes how
StrEnuminstances andstrsubclasses are formatted.Currently,
PyErr_Format(PyExc_AttributeError, "...%U", ..., name)callsPyUnicode_FromFormatV()which calls_PyUnicodeWriter_WriteStr()to render%U. The_PyUnicodeWriter_WriteStr(writer, obj)call expects astrinstance and writesstr.__str__(obj)even if the__str__()method is overridden in astrsubclass.StrEnumexample:Before (Python 3.15):
After:
Example of a
strsubclass:Before (Python 3.15):
After:
serhiy-storchaka commentedon Jul 24, 2026
__str__()should not be called for%U. We have%Sfor this.serhiy-storchaka commentedon Jul 24, 2026
My concerns:
%Urarely fails (especially if we forbid execution of__str__()).%Ris more complex, it usually involves several memory allocations.vstinner commentedon Jul 24, 2026
Sometimes, I wish that we could more easily extend PyUnicode_FromFormat() formats. For example, it would be nice to have a format similar to
%Ubut which would quote the string: similar torepr(str)but don't call__repr__()method on str subclasses. Adding a suffix such as%Uqformat is not possible, since currently, it's parsed as%Uformat +qliteral string. There is%#Uwhere#usually means "alternative format". But I'm not sure if#relationship to "repr/quote" is obvious enough.Note: PEP 737 added
%T,%#T,%Nand%#Nwhere#only changes the separator: use colon (:) instead of dot (.).serhiy-storchaka commentedon Jul 25, 2026
I thought about adding variants of %c and %s which escape non-printable characters.
serhiy-storchaka commentedon Jul 25, 2026
Implemented in #154669.
vstinner commentedon Sep 17, 2026
I created PR gh-157685 to add
!Rto f-string and add%#RtoPyUnicode_FromFormat().I also created https://discuss.python.org/t/add-r-conversion-to-f-string-and-str-format-to-format-error-messages/109098 discussion. Changing string formatting concerns a lot of people, so I prefer to involve a larger audience.