diff -r ad855c779bf3 Lib/test/test_class.py --- a/Lib/test/test_class.py Thu Dec 03 17:32:05 2015 -0800 +++ b/Lib/test/test_class.py Fri Dec 04 06:11:21 2015 -0600 @@ -568,5 +568,17 @@ a = A(hash(A.f)^(-1)) hash(a.f) + def testSetattrWrapperNameIntern(self): + ''' issue 25794: __setattr__ should intern the attribute name''' + class Test(object): + pass + + def add(self, other): + return 1 + + name = '__{}__'.format('add') # not interned + type.__setattr__(Test, name, add) + Test() + 1 + if __name__ == '__main__': unittest.main() diff -r ad855c779bf3 Objects/typeobject.c --- a/Objects/typeobject.c Thu Dec 03 17:32:05 2015 -0800 +++ b/Objects/typeobject.c Fri Dec 04 06:11:21 2015 -0600 @@ -5379,7 +5379,16 @@ return NULL; if (!hackcheck(self, func, "__setattr__")) return NULL; + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); + return NULL; + } + Py_INCREF(name); + PyUnicode_InternInPlace(&name); res = (*func)(self, name, value); + Py_DECREF(name); if (res < 0) return NULL; Py_INCREF(Py_None); @@ -5398,7 +5407,16 @@ name = PyTuple_GET_ITEM(args, 0); if (!hackcheck(self, func, "__delattr__")) return NULL; + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); + return NULL; + } + Py_INCREF(name); + PyUnicode_InternInPlace(&name); res = (*func)(self, name, NULL); + Py_DECREF(name); if (res < 0) return NULL; Py_INCREF(Py_None);