@@ -1094,8 +1094,8 @@ PyObject_GetAttr(PyObject *v, PyObject *name)
10941094 if (name == NULL )
10951095 return NULL ;
10961096 }
1097+ else
10971098#endif
1098-
10991099 if (!PyString_Check (name )) {
11001100 PyErr_SetString (PyExc_TypeError ,
11011101 "attribute name must be string" );
@@ -1207,46 +1207,73 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
12071207{
12081208 PyTypeObject * tp = obj -> ob_type ;
12091209 PyObject * descr ;
1210+ PyObject * res = NULL ;
12101211 descrgetfunc f ;
12111212 PyObject * * dictptr ;
12121213
1214+ #ifdef Py_USING_UNICODE
1215+ /* The Unicode to string conversion is done here because the
1216+ existing tp_setattro slots expect a string object as name
1217+ and we wouldn't want to break those. */
1218+ if (PyUnicode_Check (name )) {
1219+ name = PyUnicode_AsEncodedString (name , NULL , NULL );
1220+ if (name == NULL )
1221+ return NULL ;
1222+ }
1223+ else
1224+ #endif
1225+ if (!PyString_Check (name )){
1226+ PyErr_SetString (PyExc_TypeError ,
1227+ "attribute name must be string" );
1228+ return NULL ;
1229+ }
1230+ else
1231+ Py_INCREF (name );
1232+
12131233 if (tp -> tp_dict == NULL ) {
12141234 if (PyType_Ready (tp ) < 0 )
1215- return NULL ;
1235+ goto done ;
12161236 }
12171237
12181238 descr = _PyType_Lookup (tp , name );
12191239 f = NULL ;
12201240 if (descr != NULL ) {
12211241 f = descr -> ob_type -> tp_descr_get ;
1222- if (f != NULL && PyDescr_IsData (descr ))
1223- return f (descr , obj , (PyObject * )obj -> ob_type );
1242+ if (f != NULL && PyDescr_IsData (descr )) {
1243+ res = f (descr , obj , (PyObject * )obj -> ob_type );
1244+ goto done ;
1245+ }
12241246 }
12251247
12261248 dictptr = _PyObject_GetDictPtr (obj );
12271249 if (dictptr != NULL ) {
12281250 PyObject * dict = * dictptr ;
12291251 if (dict != NULL ) {
1230- PyObject * res = PyDict_GetItem (dict , name );
1252+ res = PyDict_GetItem (dict , name );
12311253 if (res != NULL ) {
12321254 Py_INCREF (res );
1233- return res ;
1255+ goto done ;
12341256 }
12351257 }
12361258 }
12371259
1238- if (f != NULL )
1239- return f (descr , obj , (PyObject * )obj -> ob_type );
1260+ if (f != NULL ) {
1261+ res = f (descr , obj , (PyObject * )obj -> ob_type );
1262+ goto done ;
1263+ }
12401264
12411265 if (descr != NULL ) {
12421266 Py_INCREF (descr );
1243- return descr ;
1267+ res = descr ;
1268+ goto done ;
12441269 }
12451270
12461271 PyErr_Format (PyExc_AttributeError ,
12471272 "'%.50s' object has no attribute '%.400s'" ,
12481273 tp -> tp_name , PyString_AS_STRING (name ));
1249- return NULL ;
1274+ done :
1275+ Py_DECREF (name );
1276+ return res ;
12501277}
12511278
12521279int
@@ -1256,18 +1283,40 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
12561283 PyObject * descr ;
12571284 descrsetfunc f ;
12581285 PyObject * * dictptr ;
1286+ int res = -1 ;
1287+
1288+ #ifdef Py_USING_UNICODE
1289+ /* The Unicode to string conversion is done here because the
1290+ existing tp_setattro slots expect a string object as name
1291+ and we wouldn't want to break those. */
1292+ if (PyUnicode_Check (name )) {
1293+ name = PyUnicode_AsEncodedString (name , NULL , NULL );
1294+ if (name == NULL )
1295+ return -1 ;
1296+ }
1297+ else
1298+ #endif
1299+ if (!PyString_Check (name )){
1300+ PyErr_SetString (PyExc_TypeError ,
1301+ "attribute name must be string" );
1302+ return -1 ;
1303+ }
1304+ else
1305+ Py_INCREF (name );
12591306
12601307 if (tp -> tp_dict == NULL ) {
12611308 if (PyType_Ready (tp ) < 0 )
1262- return -1 ;
1309+ goto done ;
12631310 }
12641311
12651312 descr = _PyType_Lookup (tp , name );
12661313 f = NULL ;
12671314 if (descr != NULL ) {
12681315 f = descr -> ob_type -> tp_descr_set ;
1269- if (f != NULL && PyDescr_IsData (descr ))
1270- return f (descr , obj , value );
1316+ if (f != NULL && PyDescr_IsData (descr )) {
1317+ res = f (descr , obj , value );
1318+ goto done ;
1319+ }
12711320 }
12721321
12731322 dictptr = _PyObject_GetDictPtr (obj );
@@ -1276,35 +1325,38 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
12761325 if (dict == NULL && value != NULL ) {
12771326 dict = PyDict_New ();
12781327 if (dict == NULL )
1279- return -1 ;
1328+ goto done ;
12801329 * dictptr = dict ;
12811330 }
12821331 if (dict != NULL ) {
1283- int res ;
12841332 if (value == NULL )
12851333 res = PyDict_DelItem (dict , name );
12861334 else
12871335 res = PyDict_SetItem (dict , name , value );
12881336 if (res < 0 && PyErr_ExceptionMatches (PyExc_KeyError ))
12891337 PyErr_SetObject (PyExc_AttributeError , name );
1290- return res ;
1338+ goto done ;
12911339 }
12921340 }
12931341
1294- if (f != NULL )
1295- return f (descr , obj , value );
1342+ if (f != NULL ) {
1343+ res = f (descr , obj , value );
1344+ goto done ;
1345+ }
12961346
12971347 if (descr == NULL ) {
12981348 PyErr_Format (PyExc_AttributeError ,
12991349 "'%.50s' object has no attribute '%.400s'" ,
13001350 tp -> tp_name , PyString_AS_STRING (name ));
1301- return -1 ;
1351+ goto done ;
13021352 }
13031353
13041354 PyErr_Format (PyExc_AttributeError ,
13051355 "'%.50s' object attribute '%.400s' is read-only" ,
13061356 tp -> tp_name , PyString_AS_STRING (name ));
1307- return -1 ;
1357+ done :
1358+ Py_DECREF (name );
1359+ return res ;
13081360}
13091361
13101362/* Test a value used as condition, e.g., in a for or if statement.
0 commit comments