@@ -20,6 +20,11 @@ static PyObject * record_new_items_iter(PyObject *);
2020static  ApgRecordObject  * free_list [ApgRecord_MAXSAVESIZE ];
2121static  int  numfree [ApgRecord_MAXSAVESIZE ];
2222
23+ static  PyObject  * record_reconstruct_obj ;
24+ static  PyObject  * record_desc_reconstruct_obj ;
25+ 
26+ static  PyMethodDef  record_desc_methods [];
27+ 
2328static  size_t  MAX_RECORD_SIZE  =  (
2429    ((size_t )PY_SSIZE_T_MAX  -  sizeof (ApgRecordObject ) -  sizeof (PyObject  * ))
2530    / sizeof (PyObject  * )
@@ -575,14 +580,14 @@ record_repr(ApgRecordObject *v)
575580
576581
577582static  PyObject  * 
578- record_values (PyObject  * o , PyObject  * args )
583+ record_values (PyObject  * o , PyObject  * Py_UNUSED ( unused ) )
579584{
580585    return  record_iter (o );
581586}
582587
583588
584589static  PyObject  * 
585- record_keys (PyObject  * o , PyObject  * args )
590+ record_keys (PyObject  * o , PyObject  * Py_UNUSED ( unused ) )
586591{
587592    if  (!ApgRecord_Check (o )) {
588593        PyErr_BadInternalCall ();
@@ -594,7 +599,7 @@ record_keys(PyObject *o, PyObject *args)
594599
595600
596601static  PyObject  * 
597- record_items (PyObject  * o , PyObject  * args )
602+ record_items (PyObject  * o , PyObject  * Py_UNUSED ( unused ) )
598603{
599604    if  (!ApgRecord_Check (o )) {
600605        PyErr_BadInternalCall ();
@@ -657,12 +662,71 @@ static PyMappingMethods record_as_mapping = {
657662    0                                                 /* mp_ass_subscript */ 
658663};
659664
665+ static  PyMethodDef  record_methods [];
666+ 
667+ static  PyObject  * 
668+ record_reduce (ApgRecordObject  * o , PyObject  * Py_UNUSED (unused ))
669+ {
670+     PyObject  * value  =  PyTuple_New (2 );
671+      if  (value  ==  NULL ) {
672+         return  NULL ;
673+     }
674+ 	Py_ssize_t  len  =  Py_SIZE (o );
675+     PyObject  * state  =  PyTuple_New (1  +  len );
676+     if  (state  ==  NULL ) {
677+     	Py_DECREF (value );
678+         return  NULL ;
679+     }
680+     PyTuple_SET_ITEM (value , 0 , record_reconstruct_obj );
681+     Py_INCREF (record_reconstruct_obj );
682+     PyTuple_SET_ITEM (value , 1 , state );
683+     PyTuple_SET_ITEM (state , 0 , (PyObject  * )o -> desc );
684+     Py_INCREF (o -> desc );
685+     for  (Py_ssize_t  i  =  0 ; i  <  len ; i ++ ) {
686+         PyObject  * item  =  ApgRecord_GET_ITEM (o , i );
687+         PyTuple_SET_ITEM (state , i  +  1 , item );
688+ 		Py_INCREF (item );
689+     }
690+     return  value ;
691+ }
692+ 
693+ static  PyObject  * 
694+ record_reconstruct (PyObject  * Py_UNUSED (unused ), PyObject  * args )
695+ {
696+     if  (!PyTuple_CheckExact (args )) {
697+         return  NULL ;
698+     }
699+     Py_ssize_t  len  =  PyTuple_GET_SIZE (args );
700+     if  (len  <  2 ) {
701+         return  NULL ;
702+     }
703+     len -- ;
704+     ApgRecordDescObject  * desc  =  (ApgRecordDescObject  * )PyTuple_GET_ITEM (args , 0 );
705+     if  (!ApgRecordDesc_CheckExact (desc )) {
706+         return  NULL ;
707+     }
708+     if  (PyObject_Length (desc -> mapping ) !=  len ) {
709+         return  NULL ;
710+     }
711+     PyObject  * record  =  ApgRecord_New (& ApgRecord_Type , (PyObject  * )desc , len );
712+     if  (record  ==  NULL ) {
713+         return  NULL ;
714+     }
715+     for  (Py_ssize_t  i  =  0 ; i  <  len ; i ++ ) {
716+         PyObject  * item  =  PyTuple_GET_ITEM (args , i  +  1 );
717+         ApgRecord_SET_ITEM (record , i , item );
718+         Py_INCREF (item );
719+     }
720+ 	return  record ;
721+ }
660722
661723static  PyMethodDef  record_methods [] =  {
662724    {"values" ,          (PyCFunction )record_values , METH_NOARGS },
663725    {"keys" ,            (PyCFunction )record_keys , METH_NOARGS },
664726    {"items" ,           (PyCFunction )record_items , METH_NOARGS },
665727    {"get" ,             (PyCFunction )record_get , METH_VARARGS },
728+     {"__reduce__" ,      (PyCFunction )record_reduce , METH_NOARGS },
729+     {"__reconstruct__" , (PyCFunction )record_reconstruct , METH_VARARGS  | METH_STATIC },
666730    {NULL ,              NULL }           /* sentinel */ 
667731};
668732
@@ -942,7 +1006,7 @@ record_new_items_iter(PyObject *seq)
9421006}
9431007
9441008
945- PyTypeObject  * 
1009+ PyObject  * 
9461010ApgRecord_InitTypes (void )
9471011{
9481012    if  (PyType_Ready (& ApgRecord_Type ) <  0 ) {
@@ -961,7 +1025,22 @@ ApgRecord_InitTypes(void)
9611025        return  NULL ;
9621026    }
9631027
964-     return  & ApgRecord_Type ;
1028+     record_reconstruct_obj  =  PyCFunction_New (
1029+         & record_methods [5 ], (PyObject  * )& ApgRecord_Type 
1030+     );
1031+     record_desc_reconstruct_obj  =  PyCFunction_New (
1032+         & record_desc_methods [1 ], (PyObject  * )& ApgRecordDesc_Type 
1033+     );
1034+ 
1035+ 	PyObject  * types  =  PyTuple_New (2 );
1036+ 	if  (types  ==  NULL ) {
1037+ 	    return  NULL ;
1038+ 	}
1039+ 	PyTuple_SET_ITEM (types , 0 , (PyObject  * )& ApgRecord_Type );
1040+ 	Py_INCREF (& ApgRecord_Type );
1041+ 	PyTuple_SET_ITEM (types , 1 , (PyObject  * )& ApgRecordDesc_Type );
1042+ 	Py_INCREF (& ApgRecordDesc_Type );
1043+     return  types ;
9651044}
9661045
9671046
@@ -987,15 +1066,54 @@ record_desc_traverse(ApgRecordDescObject *o, visitproc visit, void *arg)
9871066}
9881067
9891068
1069+ static  PyObject  * record_desc_reduce (ApgRecordDescObject  * o , PyObject  * Py_UNUSED (unused ))
1070+ {
1071+     PyObject  * value  =  PyTuple_New (2 );
1072+      if  (value  ==  NULL ) {
1073+         return  NULL ;
1074+     }
1075+     PyObject  * state  =  PyTuple_New (2 );
1076+     if  (state  ==  NULL ) {
1077+     	Py_DECREF (value );
1078+         return  NULL ;
1079+     }
1080+     PyTuple_SET_ITEM (value , 0 , record_desc_reconstruct_obj );
1081+     Py_INCREF (record_desc_reconstruct_obj );
1082+     PyTuple_SET_ITEM (value , 1 , state );
1083+     PyTuple_SET_ITEM (state , 0 , o -> mapping );
1084+     Py_INCREF (o -> mapping );
1085+     PyTuple_SET_ITEM (state , 1 , o -> keys );
1086+     Py_INCREF (o -> keys );
1087+     return  value ;
1088+ }
1089+ 
1090+ 
1091+ static  PyObject  * record_desc_reconstruct (PyObject  * Py_UNUSED (unused ), PyObject  * args )
1092+ {
1093+ 	if  (PyTuple_GET_SIZE (args ) !=  2 ) {
1094+ 	    return  NULL ;
1095+ 	}
1096+ 	return  ApgRecordDesc_New (PyTuple_GET_ITEM (args , 0 ), PyTuple_GET_ITEM (args , 1 ));
1097+ }
1098+ 
1099+ 
1100+ static  PyMethodDef  record_desc_methods [] =  {
1101+     {"__reduce__" , (PyCFunction )record_desc_reduce , METH_NOARGS },
1102+     {"__reconstruct__" , (PyCFunction )record_desc_reconstruct , METH_VARARGS  | METH_STATIC },
1103+     {NULL ,              NULL }           /* sentinel */ 
1104+ };
1105+ 
1106+ 
9901107PyTypeObject  ApgRecordDesc_Type  =  {
9911108    PyVarObject_HEAD_INIT (NULL , 0 )
992-     .tp_name  =  "RecordDescriptor" ,
1109+     .tp_name  =  "asyncpg.protocol.protocol. RecordDescriptor" ,
9931110    .tp_basicsize  =  sizeof (ApgRecordDescObject ),
9941111    .tp_dealloc  =  (destructor )record_desc_dealloc ,
9951112    .tp_getattro  =  PyObject_GenericGetAttr ,
9961113    .tp_flags  =  Py_TPFLAGS_DEFAULT  | Py_TPFLAGS_HAVE_GC ,
9971114    .tp_traverse  =  (traverseproc )record_desc_traverse ,
9981115    .tp_iter  =  PyObject_SelfIter ,
1116+     .tp_methods  =  record_desc_methods ,
9991117};
10001118
10011119
0 commit comments