Skip to content

Commit

Permalink
bpo-44024: Improve the TypeError message in getattr and hasattr (GH-2…
Browse files Browse the repository at this point in the history
…5863)

Use common error message for non-string attribute name in the builtin
functions getattr and hasattr.
The special check no longer needed since Python 3.0.
  • Loading branch information
geryogam committed Jan 18, 2022
1 parent 60ceedb commit 16bf9bd
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 14 deletions.
18 changes: 14 additions & 4 deletions Lib/test/test_builtin.py
Expand Up @@ -509,6 +509,9 @@ def test_delattr(self):
sys.spam = 1
delattr(sys, 'spam')
self.assertRaises(TypeError, delattr)
self.assertRaises(TypeError, delattr, sys)
msg = r"^attribute name must be string, not 'int'$"
self.assertRaisesRegex(TypeError, msg, delattr, sys, 1)

def test_dir(self):
# dir(wrong number of arguments)
Expand Down Expand Up @@ -801,17 +804,21 @@ def test_filter_pickle(self):

def test_getattr(self):
self.assertTrue(getattr(sys, 'stdout') is sys.stdout)
self.assertRaises(TypeError, getattr, sys, 1)
self.assertRaises(TypeError, getattr, sys, 1, "foo")
self.assertRaises(TypeError, getattr)
self.assertRaises(TypeError, getattr, sys)
msg = r"^attribute name must be string, not 'int'$"
self.assertRaisesRegex(TypeError, msg, getattr, sys, 1)
self.assertRaisesRegex(TypeError, msg, getattr, sys, 1, 'spam')
self.assertRaises(AttributeError, getattr, sys, chr(sys.maxunicode))
# unicode surrogates are not encodable to the default encoding (utf8)
self.assertRaises(AttributeError, getattr, 1, "\uDAD1\uD51E")

def test_hasattr(self):
self.assertTrue(hasattr(sys, 'stdout'))
self.assertRaises(TypeError, hasattr, sys, 1)
self.assertRaises(TypeError, hasattr)
self.assertRaises(TypeError, hasattr, sys)
msg = r"^attribute name must be string, not 'int'$"
self.assertRaisesRegex(TypeError, msg, hasattr, sys, 1)
self.assertEqual(False, hasattr(sys, chr(sys.maxunicode)))

# Check that hasattr propagates all exceptions outside of
Expand Down Expand Up @@ -1457,8 +1464,11 @@ def test_bug_27936(self):
def test_setattr(self):
setattr(sys, 'spam', 1)
self.assertEqual(sys.spam, 1)
self.assertRaises(TypeError, setattr, sys, 1, 'spam')
self.assertRaises(TypeError, setattr)
self.assertRaises(TypeError, setattr, sys)
self.assertRaises(TypeError, setattr, sys, 'spam')
msg = r"^attribute name must be string, not 'int'$"
self.assertRaisesRegex(TypeError, msg, setattr, sys, 1, 'spam')

# test_str(): see test_unicode.py and test_bytes.py for str() tests.

Expand Down
@@ -0,0 +1,2 @@
Improve the exc:`TypeError` message for non-string second arguments passed to
the built-in functions :func:`getattr` and :func:`hasattr`. Patch by Géry Ogam.
10 changes: 0 additions & 10 deletions Python/bltinmodule.c
Expand Up @@ -1091,11 +1091,6 @@ builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs)

v = args[0];
name = args[1];
if (!PyUnicode_Check(name)) {
PyErr_SetString(PyExc_TypeError,
"getattr(): attribute name must be string");
return NULL;
}
if (nargs > 2) {
if (_PyObject_LookupAttr(v, name, &result) == 0) {
PyObject *dflt = args[2];
Expand Down Expand Up @@ -1156,11 +1151,6 @@ builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name)
{
PyObject *v;

if (!PyUnicode_Check(name)) {
PyErr_SetString(PyExc_TypeError,
"hasattr(): attribute name must be string");
return NULL;
}
if (_PyObject_LookupAttr(obj, name, &v) < 0) {
return NULL;
}
Expand Down

0 comments on commit 16bf9bd

Please sign in to comment.