@@ -4839,6 +4839,25 @@ persistent_id(PyObject *self, PyObject *obj)
48394839 Py_RETURN_NONE ;
48404840}
48414841
4842+ static PyObject * Pickler_getattr (PyObject * self , PyObject * name );
4843+
4844+ /* Like PyObject_GetOptionalAttr(), but avoids creating an AttributeError
4845+ for a missing attribute. Must not be used for "persistent_id". */
4846+ static int
4847+ pickler_get_optional_attr (PicklerObject * self , PyObject * name ,
4848+ PyObject * * result )
4849+ {
4850+ if (Py_TYPE (self )-> tp_getattro == Pickler_getattr ) {
4851+ * result = _PyObject_GenericGetAttrWithDict ((PyObject * )self , name ,
4852+ NULL , 1 );
4853+ if (* result != NULL ) {
4854+ return 1 ;
4855+ }
4856+ return PyErr_Occurred () ? -1 : 0 ;
4857+ }
4858+ return PyObject_GetOptionalAttr ((PyObject * )self , name , result );
4859+ }
4860+
48424861static int
48434862dump (PickleState * state , PicklerObject * self , PyObject * obj )
48444863{
@@ -4860,8 +4879,8 @@ dump(PickleState *state, PicklerObject *self, PyObject *obj)
48604879 Py_XSETREF (self -> persistent_id , tmp );
48614880
48624881 /* Cache the reducer_override method, if it exists. */
4863- if (PyObject_GetOptionalAttr (( PyObject * ) self , & _Py_ID (reducer_override ),
4864- & tmp ) < 0 ) {
4882+ if (pickler_get_optional_attr ( self , & _Py_ID (reducer_override ),
4883+ & tmp ) < 0 ) {
48654884 goto error ;
48664885 }
48674886 Py_XSETREF (self -> reducer_override , tmp );
@@ -5141,8 +5160,8 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file,
51415160 self -> fast_memo = NULL ;
51425161
51435162 if (self -> dispatch_table == NULL ) {
5144- if (PyObject_GetOptionalAttr (( PyObject * ) self , & _Py_ID (dispatch_table ),
5145- & self -> dispatch_table ) < 0 ) {
5163+ if (pickler_get_optional_attr ( self , & _Py_ID (dispatch_table ),
5164+ & self -> dispatch_table ) < 0 ) {
51465165 goto error ;
51475166 }
51485167 }
0 commit comments