Skip to content

Conversation

@geryogam
Copy link
Contributor

@geryogam geryogam commented May 3, 2021

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 builtin_getattr defined in Python/bltinmodule.c, we remove the following lines:

    if (!PyUnicode_Check(name)) {
        PyErr_SetString(PyExc_TypeError,
                        "getattr(): attribute name must be string");
        return NULL;
    }

because the expected TypeError message is already implemented in the subsequent call to the functions _PyObject_LookupAttr and PyObject_GetAttr defined in Objects/object.c:

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 builtin_hasattr_impl defined in Python/bltinmodule.c, we remove the following lines:

    if (!PyUnicode_Check(name)) {
        PyErr_SetString(PyExc_TypeError,
                        "hasattr(): attribute name must be string");
        return NULL;
    }

because the expected TypeError message is already implemented in the subsequent call to the function _PyObject_LookupAttr defined in Objects/object.c.

https://bugs.python.org/issue44024

Copy link
Member

@JelleZijlstra JelleZijlstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a test for the error message and a news entry for the change?

@geryogam geryogam changed the title bpo-44024: Use common TypeError message for built-in functions getattr and hasattr bpo-44024: Use the common TypeError message for non-string second arguments passed to the built-in functions getattr and hasattr May 4, 2021
…24.M9m8Qd.rst

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
@geryogam geryogam changed the title bpo-44024: Use the common TypeError message for non-string second arguments passed to the built-in functions getattr and hasattr bpo-44024: Improve the error message for non-string second arguments passed to the built-in functions getattr and hasattr May 4, 2021
@geryogam
Copy link
Contributor Author

geryogam commented May 4, 2021

Thanks for the review @JelleZijlstra!

@geryogam geryogam changed the title bpo-44024: Improve the error message for non-string second arguments passed to the built-in functions getattr and hasattr bpo-44024: Improve the TypeError message for non-string second arguments passed to the built-in functions getattr and hasattr May 4, 2021
@github-actions
Copy link

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale Stale PR or inactive for long period of time. label Jun 25, 2021
@merwok
Copy link
Member

merwok commented Jan 5, 2022

Looks good, thanks! Could you pull and merge upstream in your branch?

Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change LGTM, but tests are added in wrong place.

@hugovk hugovk removed the stale Stale PR or inactive for long period of time. label Jan 5, 2022
Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants