Skip to content

Commit 16bf9bd

Browse files
authored
bpo-44024: Improve the TypeError message in getattr and hasattr (GH-25863)
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.
1 parent 60ceedb commit 16bf9bd

File tree

3 files changed

+16
-14
lines changed

3 files changed

+16
-14
lines changed

Lib/test/test_builtin.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,9 @@ def test_delattr(self):
509509
sys.spam = 1
510510
delattr(sys, 'spam')
511511
self.assertRaises(TypeError, delattr)
512+
self.assertRaises(TypeError, delattr, sys)
513+
msg = r"^attribute name must be string, not 'int'$"
514+
self.assertRaisesRegex(TypeError, msg, delattr, sys, 1)
512515

513516
def test_dir(self):
514517
# dir(wrong number of arguments)
@@ -801,17 +804,21 @@ def test_filter_pickle(self):
801804

802805
def test_getattr(self):
803806
self.assertTrue(getattr(sys, 'stdout') is sys.stdout)
804-
self.assertRaises(TypeError, getattr, sys, 1)
805-
self.assertRaises(TypeError, getattr, sys, 1, "foo")
806807
self.assertRaises(TypeError, getattr)
808+
self.assertRaises(TypeError, getattr, sys)
809+
msg = r"^attribute name must be string, not 'int'$"
810+
self.assertRaisesRegex(TypeError, msg, getattr, sys, 1)
811+
self.assertRaisesRegex(TypeError, msg, getattr, sys, 1, 'spam')
807812
self.assertRaises(AttributeError, getattr, sys, chr(sys.maxunicode))
808813
# unicode surrogates are not encodable to the default encoding (utf8)
809814
self.assertRaises(AttributeError, getattr, 1, "\uDAD1\uD51E")
810815

811816
def test_hasattr(self):
812817
self.assertTrue(hasattr(sys, 'stdout'))
813-
self.assertRaises(TypeError, hasattr, sys, 1)
814818
self.assertRaises(TypeError, hasattr)
819+
self.assertRaises(TypeError, hasattr, sys)
820+
msg = r"^attribute name must be string, not 'int'$"
821+
self.assertRaisesRegex(TypeError, msg, hasattr, sys, 1)
815822
self.assertEqual(False, hasattr(sys, chr(sys.maxunicode)))
816823

817824
# Check that hasattr propagates all exceptions outside of
@@ -1457,8 +1464,11 @@ def test_bug_27936(self):
14571464
def test_setattr(self):
14581465
setattr(sys, 'spam', 1)
14591466
self.assertEqual(sys.spam, 1)
1460-
self.assertRaises(TypeError, setattr, sys, 1, 'spam')
14611467
self.assertRaises(TypeError, setattr)
1468+
self.assertRaises(TypeError, setattr, sys)
1469+
self.assertRaises(TypeError, setattr, sys, 'spam')
1470+
msg = r"^attribute name must be string, not 'int'$"
1471+
self.assertRaisesRegex(TypeError, msg, setattr, sys, 1, 'spam')
14621472

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Improve the exc:`TypeError` message for non-string second arguments passed to
2+
the built-in functions :func:`getattr` and :func:`hasattr`. Patch by Géry Ogam.

Python/bltinmodule.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,11 +1091,6 @@ builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
10911091

10921092
v = args[0];
10931093
name = args[1];
1094-
if (!PyUnicode_Check(name)) {
1095-
PyErr_SetString(PyExc_TypeError,
1096-
"getattr(): attribute name must be string");
1097-
return NULL;
1098-
}
10991094
if (nargs > 2) {
11001095
if (_PyObject_LookupAttr(v, name, &result) == 0) {
11011096
PyObject *dflt = args[2];
@@ -1156,11 +1151,6 @@ builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name)
11561151
{
11571152
PyObject *v;
11581153

1159-
if (!PyUnicode_Check(name)) {
1160-
PyErr_SetString(PyExc_TypeError,
1161-
"hasattr(): attribute name must be string");
1162-
return NULL;
1163-
}
11641154
if (_PyObject_LookupAttr(obj, name, &v) < 0) {
11651155
return NULL;
11661156
}

0 commit comments

Comments
 (0)