@@ -1212,8 +1212,18 @@ PyObject_SetAttrString(PyObject *v, const char *name, PyObject *w)
12121212 PyObject * s ;
12131213 int res ;
12141214
1215- if (Py_TYPE (v )-> tp_setattr != NULL )
1215+ if (Py_TYPE (v )-> tp_setattr != NULL ) {
1216+ if (w == NULL && PyErr_Occurred ()) {
1217+ if (PyErr_WarnFormat (PyExc_DeprecationWarning , 0 ,
1218+ "calling PyObject_SetAttrString() with NULL value "
1219+ "and an exception set is deprecated; "
1220+ "use PyObject_DelAttrString() instead" )) {
1221+ return -1 ;
1222+ }
1223+ }
1224+
12161225 return (* Py_TYPE (v )-> tp_setattr )(v , (char * )name , w );
1226+ }
12171227 s = PyUnicode_InternFromString (name );
12181228 if (s == NULL )
12191229 return -1 ;
@@ -1437,7 +1447,7 @@ int
14371447PyObject_SetAttr (PyObject * v , PyObject * name , PyObject * value )
14381448{
14391449 PyTypeObject * tp = Py_TYPE (v );
1440- int err ;
1450+ int res ;
14411451
14421452 if (!PyUnicode_Check (name )) {
14431453 PyErr_Format (PyExc_TypeError ,
@@ -1447,25 +1457,37 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
14471457 }
14481458 Py_INCREF (name );
14491459
1450- PyInterpreterState * interp = _PyInterpreterState_GET ();
1451- _PyUnicode_InternMortal (interp , & name );
1460+ PyThreadState * tstate = _PyThreadState_GET ();
1461+ PyObject * exc = NULL ;
1462+ if (value == NULL && _PyErr_Occurred (tstate )) {
1463+ exc = _PyErr_GetRaisedException (tstate );
1464+ res = PyErr_WarnFormat (PyExc_DeprecationWarning , 0 ,
1465+ "calling PyObject_SetAttr() with NULL value "
1466+ "and an exception set is deprecated; "
1467+ "use PyObject_DelAttr() instead" );
1468+ if (res ) {
1469+ res = -1 ;
1470+ goto done ;
1471+ }
1472+ }
1473+
1474+ _PyUnicode_InternMortal (tstate -> interp , & name );
1475+
14521476 if (tp -> tp_setattro != NULL ) {
1453- err = (* tp -> tp_setattro )(v , name , value );
1454- Py_DECREF (name );
1455- return err ;
1477+ res = (* tp -> tp_setattro )(v , name , value );
1478+ goto done ;
14561479 }
1480+
14571481 if (tp -> tp_setattr != NULL ) {
14581482 const char * name_str = PyUnicode_AsUTF8 (name );
14591483 if (name_str == NULL ) {
1460- Py_DECREF ( name ) ;
1461- return -1 ;
1484+ res = -1 ;
1485+ goto done ;
14621486 }
1463- err = (* tp -> tp_setattr )(v , (char * )name_str , value );
1464- Py_DECREF (name );
1465- return err ;
1487+ res = (* tp -> tp_setattr )(v , (char * )name_str , value );
1488+ goto done ;
14661489 }
1467- Py_DECREF (name );
1468- _PyObject_ASSERT (name , Py_REFCNT (name ) >= 1 );
1490+
14691491 if (tp -> tp_getattr == NULL && tp -> tp_getattro == NULL )
14701492 PyErr_Format (PyExc_TypeError ,
14711493 "'%.100s' object has no attributes "
@@ -1480,7 +1502,15 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
14801502 tp -> tp_name ,
14811503 value == NULL ? "del" : "assign to" ,
14821504 name );
1483- return -1 ;
1505+ res = -1 ;
1506+ goto done ;
1507+
1508+ done :
1509+ if (exc ) {
1510+ _PyErr_ChainExceptions1Tstate (tstate , exc );
1511+ }
1512+ Py_DECREF (name );
1513+ return res ;
14841514}
14851515
14861516int
0 commit comments