@@ -4383,7 +4383,6 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
43834383 _Py_IDENTIFIER (__reduce__ );
43844384 _Py_IDENTIFIER (__reduce_ex__ );
43854385
4386-
43874386 /* XXX: If the __reduce__ method is defined, __reduce_ex__ is
43884387 automatically defined as __reduce__. While this is convenient, this
43894388 make it impossible to know which method was actually called. Of
@@ -4404,14 +4403,15 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
44044403 }
44054404 }
44064405 else {
4407- PickleState * st = _Pickle_GetGlobalState ();
4408-
44094406 /* Check for a __reduce__ method. */
4410- reduce_func = _PyObject_GetAttrId (obj , & PyId___reduce__ );
4407+ if (_PyObject_LookupAttrId (obj , & PyId___reduce__ , & reduce_func ) < 0 ) {
4408+ goto error ;
4409+ }
44114410 if (reduce_func != NULL ) {
44124411 reduce_value = PyObject_CallNoArgs (reduce_func );
44134412 }
44144413 else {
4414+ PickleState * st = _Pickle_GetGlobalState ();
44154415 PyErr_Format (st -> PicklingError ,
44164416 "can't pickle '%.200s' object: %R" ,
44174417 type -> tp_name , obj );
@@ -6446,7 +6446,9 @@ do_append(UnpicklerObject *self, Py_ssize_t x)
64466446 PyObject * extend_func ;
64476447 _Py_IDENTIFIER (extend );
64486448
6449- extend_func = _PyObject_GetAttrId (list , & PyId_extend );
6449+ if (_PyObject_LookupAttrId (list , & PyId_extend , & extend_func ) < 0 ) {
6450+ return -1 ;
6451+ }
64506452 if (extend_func != NULL ) {
64516453 slice = Pdata_poplist (self -> stack , x );
64526454 if (!slice ) {
@@ -6466,7 +6468,6 @@ do_append(UnpicklerObject *self, Py_ssize_t x)
64666468 /* Even if the PEP 307 requires extend() and append() methods,
64676469 fall back on append() if the object has no extend() method
64686470 for backward compatibility. */
6469- PyErr_Clear ();
64706471 append_func = _PyObject_GetAttrId (list , & PyId_append );
64716472 if (append_func == NULL )
64726473 return -1 ;
0 commit comments