classification
Title: Improve the TypeError message for non-string second arguments passed to the built-in functions getattr and hasattr
Type: behavior Stage: patch review
Components: Interpreter Core Versions: Python 3.11, Python 3.10, Python 3.9, Python 3.8, Python 3.7, Python 3.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: maggyero
Priority: normal Keywords: patch

Created on 2021-05-03 22:50 by maggyero, last changed 2021-05-05 12:20 by maggyero.

Pull Requests
URL Status Linked Edit
PR 25863 open maggyero, 2021-05-03 22:51
Messages (1)
msg392843 - (view) Author: Géry (maggyero) * Date: 2021-05-03 22:50
Problem
-------

Actual behaviour:

```python
>>> 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:

```python
>>> 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:

```python
>>> 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:

```c
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:

```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:

```c
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.
History
Date User Action Args
2021-05-05 12:20:20maggyerosettitle: Improve the error message for non-string second arguments passed to the built-in functions getattr and hasattr -> Improve the TypeError message for non-string second arguments passed to the built-in functions getattr and hasattr
2021-05-04 20:45:29maggyerosettitle: Use common TypeError message for built-in functions getattr and hasattr -> Improve the error message for non-string second arguments passed to the built-in functions getattr and hasattr
2021-05-03 22:51:06maggyerosetkeywords: + patch
stage: patch review
pull_requests: + pull_request24544
2021-05-03 22:50:44maggyerocreate