-
-
Notifications
You must be signed in to change notification settings - Fork 29.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve the TypeError message for non-string second arguments passed to the built-in functions getattr and hasattr #88190
Comments
Problem Actual behaviour: >>> getattr('foobar', 123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: getattr(): attribute name must be string
>>> hasattr('foobar', 123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: hasattr(): attribute name must be string Expected behaviour: >>> getattr('foobar', 123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: attribute name must be string, not 'int'
>>> hasattr('foobar', 123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: attribute name must be string, not 'int' Motivation: >>> setattr('foobar', 123, 'baz')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: attribute name must be string, not 'int'
>>> delattr('foobar', 123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: attribute name must be string, not 'int' Solution In the function if (!PyUnicode_Check(name)) {
PyErr_SetString(PyExc_TypeError,
"getattr(): attribute name must be string");
return NULL;
} because the expected PyObject *
PyObject_GetAttr(PyObject *v, PyObject *name)
{
PyTypeObject *tp = Py_TYPE(v);
if (!PyUnicode_Check(name)) {
PyErr_Format(PyExc_TypeError,
"attribute name must be string, not '%.200s'",
Py_TYPE(name)->tp_name);
return NULL;
}
[…]
int
_PyObject_LookupAttr(PyObject *v, PyObject *name, PyObject **result)
{
PyTypeObject *tp = Py_TYPE(v);
if (!PyUnicode_Check(name)) {
PyErr_Format(PyExc_TypeError,
"attribute name must be string, not '%.200s'",
Py_TYPE(name)->tp_name);
*result = NULL;
return -1;
}
[…] Likewise, in the function if (!PyUnicode_Check(name)) {
PyErr_SetString(PyExc_TypeError,
"hasattr(): attribute name must be string");
return NULL;
} because the expected |
Good point. That code was originally added in bpo-420304 because every exception raised in PyObject_GetAttr() (including a TypeError for non-string name) was silenced in hasattr() and 3-argument getattr(). It was changed in Python 3, so this code duplication is no longer needed. The name of the function was added in error messages in a9b9c9f. Now it will gone. It is a minor regression, but I think that it is fine. Not all error messages contain a function name. In this case the context is clear from the traceback, and the error is not specific to these two functions, setattr() and delattr() raise the same error. |
Thank you for your contribution Géry. |
Thanks for the review Serhiy. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: