@@ -612,6 +612,7 @@ typedef struct PicklerObject {
612612 objects to support self-referential objects
613613 pickling. */
614614 PyObject * persistent_id ; /* persistent_id() method, can be NULL */
615+ PyObject * persistent_id_attr ; /* instance attribute, can be NULL */
615616 PyObject * dispatch_table ; /* private dispatch_table, can be NULL */
616617 PyObject * reducer_override ; /* hook for invoking user-defined callbacks
617618 instead of save_global when pickling
@@ -654,6 +655,7 @@ typedef struct UnpicklerObject {
654655 size_t memo_len ; /* Number of objects in the memo */
655656
656657 PyObject * persistent_load ; /* persistent_load() method, can be NULL. */
658+ PyObject * persistent_load_attr ; /* instance attribute, can be NULL. */
657659
658660 Py_buffer buffer ;
659661 char * input_buffer ;
@@ -1107,6 +1109,7 @@ _Pickler_New(PickleState *st)
11071109
11081110 self -> memo = memo ;
11091111 self -> persistent_id = NULL ;
1112+ self -> persistent_id_attr = NULL ;
11101113 self -> dispatch_table = NULL ;
11111114 self -> reducer_override = NULL ;
11121115 self -> write = NULL ;
@@ -1605,6 +1608,7 @@ _Unpickler_New(PyObject *module)
16051608 self -> memo_size = MEMO_SIZE ;
16061609 self -> memo_len = 0 ;
16071610 self -> persistent_load = NULL ;
1611+ self -> persistent_load_attr = NULL ;
16081612 memset (& self -> buffer , 0 , sizeof (Py_buffer ));
16091613 self -> input_buffer = NULL ;
16101614 self -> input_line = NULL ;
@@ -5021,6 +5025,33 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored))
50215025 return -1 ;
50225026}
50235027
5028+ static PyObject *
5029+ Pickler_getattr (PyObject * self , PyObject * name )
5030+ {
5031+ if (PyUnicode_Check (name )
5032+ && PyUnicode_EqualToUTF8 (name , "persistent_id" )
5033+ && ((PicklerObject * )self )-> persistent_id_attr )
5034+ {
5035+ return Py_NewRef (((PicklerObject * )self )-> persistent_id_attr );
5036+ }
5037+
5038+ return PyObject_GenericGetAttr (self , name );
5039+ }
5040+
5041+ static int
5042+ Pickler_setattr (PyObject * self , PyObject * name , PyObject * value )
5043+ {
5044+ if (PyUnicode_Check (name )
5045+ && PyUnicode_EqualToUTF8 (name , "persistent_id" ))
5046+ {
5047+ Py_XINCREF (value );
5048+ Py_XSETREF (((PicklerObject * )self )-> persistent_id_attr , value );
5049+ return 0 ;
5050+ }
5051+
5052+ return PyObject_GenericSetAttr (self , name , value );
5053+ }
5054+
50245055static PyMemberDef Pickler_members [] = {
50255056 {"bin" , Py_T_INT , offsetof(PicklerObject , bin )},
50265057 {"fast" , Py_T_INT , offsetof(PicklerObject , fast )},
@@ -5036,6 +5067,8 @@ static PyGetSetDef Pickler_getsets[] = {
50365067
50375068static PyType_Slot pickler_type_slots [] = {
50385069 {Py_tp_dealloc , Pickler_dealloc },
5070+ {Py_tp_getattro , Pickler_getattr },
5071+ {Py_tp_setattro , Pickler_setattr },
50395072 {Py_tp_methods , Pickler_methods },
50405073 {Py_tp_members , Pickler_members },
50415074 {Py_tp_getset , Pickler_getsets },
@@ -7476,6 +7509,33 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored
74767509 return -1 ;
74777510}
74787511
7512+ static PyObject *
7513+ Unpickler_getattr (PyObject * self , PyObject * name )
7514+ {
7515+ if (PyUnicode_Check (name )
7516+ && PyUnicode_EqualToUTF8 (name , "persistent_load" )
7517+ && ((UnpicklerObject * )self )-> persistent_load_attr )
7518+ {
7519+ return Py_NewRef (((UnpicklerObject * )self )-> persistent_load_attr );
7520+ }
7521+
7522+ return PyObject_GenericGetAttr (self , name );
7523+ }
7524+
7525+ static int
7526+ Unpickler_setattr (PyObject * self , PyObject * name , PyObject * value )
7527+ {
7528+ if (PyUnicode_Check (name )
7529+ && PyUnicode_EqualToUTF8 (name , "persistent_load" ))
7530+ {
7531+ Py_XINCREF (value );
7532+ Py_XSETREF (((UnpicklerObject * )self )-> persistent_load_attr , value );
7533+ return 0 ;
7534+ }
7535+
7536+ return PyObject_GenericSetAttr (self , name , value );
7537+ }
7538+
74797539static PyGetSetDef Unpickler_getsets [] = {
74807540 {"memo" , (getter )Unpickler_get_memo , (setter )Unpickler_set_memo },
74817541 {NULL }
@@ -7484,6 +7544,8 @@ static PyGetSetDef Unpickler_getsets[] = {
74847544static PyType_Slot unpickler_type_slots [] = {
74857545 {Py_tp_dealloc , Unpickler_dealloc },
74867546 {Py_tp_doc , (char * )_pickle_Unpickler___init____doc__ },
7547+ {Py_tp_getattro , Unpickler_getattr },
7548+ {Py_tp_setattro , Unpickler_setattr },
74877549 {Py_tp_traverse , Unpickler_traverse },
74887550 {Py_tp_clear , Unpickler_clear },
74897551 {Py_tp_methods , Unpickler_methods },
0 commit comments