@@ -4385,7 +4385,6 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
43854385 _Py_IDENTIFIER (__reduce__ );
43864386 _Py_IDENTIFIER (__reduce_ex__ );
43874387
4388-
43894388 /* XXX: If the __reduce__ method is defined, __reduce_ex__ is
43904389 automatically defined as __reduce__. While this is convenient, this
43914390 make it impossible to know which method was actually called. Of
@@ -4406,14 +4405,15 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
44064405 }
44074406 }
44084407 else {
4409- PickleState * st = _Pickle_GetGlobalState ();
4410-
44114408 /* Check for a __reduce__ method. */
4412- reduce_func = _PyObject_GetAttrId (obj , & PyId___reduce__ );
4409+ if (_PyObject_LookupAttrId (obj , & PyId___reduce__ , & reduce_func ) < 0 ) {
4410+ goto error ;
4411+ }
44134412 if (reduce_func != NULL ) {
44144413 reduce_value = _PyObject_CallNoArg (reduce_func );
44154414 }
44164415 else {
4416+ PickleState * st = _Pickle_GetGlobalState ();
44174417 PyErr_Format (st -> PicklingError ,
44184418 "can't pickle '%.200s' object: %R" ,
44194419 type -> tp_name , obj );
@@ -6448,7 +6448,9 @@ do_append(UnpicklerObject *self, Py_ssize_t x)
64486448 PyObject * extend_func ;
64496449 _Py_IDENTIFIER (extend );
64506450
6451- extend_func = _PyObject_GetAttrId (list , & PyId_extend );
6451+ if (_PyObject_LookupAttrId (list , & PyId_extend , & extend_func ) < 0 ) {
6452+ return -1 ;
6453+ }
64526454 if (extend_func != NULL ) {
64536455 slice = Pdata_poplist (self -> stack , x );
64546456 if (!slice ) {
@@ -6468,7 +6470,6 @@ do_append(UnpicklerObject *self, Py_ssize_t x)
64686470 /* Even if the PEP 307 requires extend() and append() methods,
64696471 fall back on append() if the object has no extend() method
64706472 for backward compatibility. */
6471- PyErr_Clear ();
64726473 append_func = _PyObject_GetAttrId (list , & PyId_append );
64736474 if (append_func == NULL )
64746475 return -1 ;
0 commit comments