@@ -612,6 +612,7 @@ typedef struct PicklerObject {
612
612
objects to support self-referential objects
613
613
pickling. */
614
614
PyObject * persistent_id ; /* persistent_id() method, can be NULL */
615
+ PyObject * persistent_id_attr ; /* instance attribute, can be NULL */
615
616
PyObject * dispatch_table ; /* private dispatch_table, can be NULL */
616
617
PyObject * reducer_override ; /* hook for invoking user-defined callbacks
617
618
instead of save_global when pickling
@@ -654,6 +655,7 @@ typedef struct UnpicklerObject {
654
655
size_t memo_len ; /* Number of objects in the memo */
655
656
656
657
PyObject * persistent_load ; /* persistent_load() method, can be NULL. */
658
+ PyObject * persistent_load_attr ; /* instance attribute, can be NULL. */
657
659
658
660
Py_buffer buffer ;
659
661
char * input_buffer ;
@@ -1107,6 +1109,7 @@ _Pickler_New(PickleState *st)
1107
1109
1108
1110
self -> memo = memo ;
1109
1111
self -> persistent_id = NULL ;
1112
+ self -> persistent_id_attr = NULL ;
1110
1113
self -> dispatch_table = NULL ;
1111
1114
self -> reducer_override = NULL ;
1112
1115
self -> write = NULL ;
@@ -1605,6 +1608,7 @@ _Unpickler_New(PyObject *module)
1605
1608
self -> memo_size = MEMO_SIZE ;
1606
1609
self -> memo_len = 0 ;
1607
1610
self -> persistent_load = NULL ;
1611
+ self -> persistent_load_attr = NULL ;
1608
1612
memset (& self -> buffer , 0 , sizeof (Py_buffer ));
1609
1613
self -> input_buffer = NULL ;
1610
1614
self -> input_line = NULL ;
@@ -5021,6 +5025,33 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored))
5021
5025
return -1 ;
5022
5026
}
5023
5027
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
+
5024
5055
static PyMemberDef Pickler_members [] = {
5025
5056
{"bin" , Py_T_INT , offsetof(PicklerObject , bin )},
5026
5057
{"fast" , Py_T_INT , offsetof(PicklerObject , fast )},
@@ -5036,6 +5067,8 @@ static PyGetSetDef Pickler_getsets[] = {
5036
5067
5037
5068
static PyType_Slot pickler_type_slots [] = {
5038
5069
{Py_tp_dealloc , Pickler_dealloc },
5070
+ {Py_tp_getattro , Pickler_getattr },
5071
+ {Py_tp_setattro , Pickler_setattr },
5039
5072
{Py_tp_methods , Pickler_methods },
5040
5073
{Py_tp_members , Pickler_members },
5041
5074
{Py_tp_getset , Pickler_getsets },
@@ -7476,6 +7509,33 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored
7476
7509
return -1 ;
7477
7510
}
7478
7511
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
+
7479
7539
static PyGetSetDef Unpickler_getsets [] = {
7480
7540
{"memo" , (getter )Unpickler_get_memo , (setter )Unpickler_set_memo },
7481
7541
{NULL }
@@ -7484,6 +7544,8 @@ static PyGetSetDef Unpickler_getsets[] = {
7484
7544
static PyType_Slot unpickler_type_slots [] = {
7485
7545
{Py_tp_dealloc , Unpickler_dealloc },
7486
7546
{Py_tp_doc , (char * )_pickle_Unpickler___init____doc__ },
7547
+ {Py_tp_getattro , Unpickler_getattr },
7548
+ {Py_tp_setattro , Unpickler_setattr },
7487
7549
{Py_tp_traverse , Unpickler_traverse },
7488
7550
{Py_tp_clear , Unpickler_clear },
7489
7551
{Py_tp_methods , Unpickler_methods },
0 commit comments