@@ -5023,6 +5023,25 @@ persistent_id(PyObject *self, PyObject *obj)
50235023 Py_RETURN_NONE ;
50245024}
50255025
5026+ static PyObject * Pickler_getattr (PyObject * self , PyObject * name );
5027+
5028+ /* Like PyObject_GetOptionalAttr(), but avoids creating an AttributeError
5029+ for a missing attribute. Must not be used for "persistent_id". */
5030+ static int
5031+ pickler_get_optional_attr (PicklerObject * self , PyObject * name ,
5032+ PyObject * * result )
5033+ {
5034+ if (Py_TYPE (self )-> tp_getattro == Pickler_getattr ) {
5035+ * result = _PyObject_GenericGetAttrWithDict ((PyObject * )self , name ,
5036+ NULL , 1 );
5037+ if (* result != NULL ) {
5038+ return 1 ;
5039+ }
5040+ return PyErr_Occurred () ? -1 : 0 ;
5041+ }
5042+ return PyObject_GetOptionalAttr ((PyObject * )self , name , result );
5043+ }
5044+
50265045static int
50275046dump (PickleState * state , PicklerObject * self , PyObject * obj )
50285047{
@@ -5044,8 +5063,8 @@ dump(PickleState *state, PicklerObject *self, PyObject *obj)
50445063 Py_XSETREF (self -> persistent_id , tmp );
50455064
50465065 /* Cache the reducer_override method, if it exists. */
5047- if (PyObject_GetOptionalAttr (( PyObject * ) self , & _Py_ID (reducer_override ),
5048- & tmp ) < 0 ) {
5066+ if (pickler_get_optional_attr ( self , & _Py_ID (reducer_override ),
5067+ & tmp ) < 0 ) {
50495068 goto error ;
50505069 }
50515070 Py_XSETREF (self -> reducer_override , tmp );
@@ -5342,8 +5361,8 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file,
53425361 self -> fast_memo = NULL ;
53435362
53445363 if (self -> dispatch_table == NULL ) {
5345- if (PyObject_GetOptionalAttr (( PyObject * ) self , & _Py_ID (dispatch_table ),
5346- & self -> dispatch_table ) < 0 ) {
5364+ if (pickler_get_optional_attr ( self , & _Py_ID (dispatch_table ),
5365+ & self -> dispatch_table ) < 0 ) {
53475366 goto error ;
53485367 }
53495368 }
0 commit comments