@@ -4846,6 +4846,25 @@ persistent_id(PyObject *self, PyObject *obj)
48464846 Py_RETURN_NONE ;
48474847}
48484848
4849+ static PyObject * Pickler_getattr (PyObject * self , PyObject * name );
4850+
4851+ /* Like PyObject_GetOptionalAttr(), but avoids creating an AttributeError
4852+ for a missing attribute. Must not be used for "persistent_id". */
4853+ static int
4854+ pickler_get_optional_attr (PicklerObject * self , PyObject * name ,
4855+ PyObject * * result )
4856+ {
4857+ if (Py_TYPE (self )-> tp_getattro == Pickler_getattr ) {
4858+ * result = _PyObject_GenericGetAttrWithDict ((PyObject * )self , name ,
4859+ NULL , 1 );
4860+ if (* result != NULL ) {
4861+ return 1 ;
4862+ }
4863+ return PyErr_Occurred () ? -1 : 0 ;
4864+ }
4865+ return PyObject_GetOptionalAttr ((PyObject * )self , name , result );
4866+ }
4867+
48494868static int
48504869dump (PickleState * state , PicklerObject * self , PyObject * obj )
48514870{
@@ -4867,8 +4886,8 @@ dump(PickleState *state, PicklerObject *self, PyObject *obj)
48674886 Py_XSETREF (self -> persistent_id , tmp );
48684887
48694888 /* Cache the reducer_override method, if it exists. */
4870- if (PyObject_GetOptionalAttr (( PyObject * ) self , & _Py_ID (reducer_override ),
4871- & tmp ) < 0 ) {
4889+ if (pickler_get_optional_attr ( self , & _Py_ID (reducer_override ),
4890+ & tmp ) < 0 ) {
48724891 goto error ;
48734892 }
48744893 Py_XSETREF (self -> reducer_override , tmp );
@@ -5148,8 +5167,8 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file,
51485167 self -> fast_memo = NULL ;
51495168
51505169 if (self -> dispatch_table == NULL ) {
5151- if (PyObject_GetOptionalAttr (( PyObject * ) self , & _Py_ID (dispatch_table ),
5152- & self -> dispatch_table ) < 0 ) {
5170+ if (pickler_get_optional_attr ( self , & _Py_ID (dispatch_table ),
5171+ & self -> dispatch_table ) < 0 ) {
51535172 goto error ;
51545173 }
51555174 }
0 commit comments