@@ -20,6 +20,9 @@ static PyObject * record_new_items_iter(PyObject *);
20
20
static ApgRecordObject * free_list [ApgRecord_MAXSAVESIZE ];
21
21
static int numfree [ApgRecord_MAXSAVESIZE ];
22
22
23
+ static PyObject * record_reconstruct_obj ;
24
+ static PyObject * record_desc_reconstruct_obj ;
25
+
23
26
static size_t MAX_RECORD_SIZE = (
24
27
((size_t )PY_SSIZE_T_MAX - sizeof (ApgRecordObject ) - sizeof (PyObject * ))
25
28
/ sizeof (PyObject * )
@@ -575,14 +578,14 @@ record_repr(ApgRecordObject *v)
575
578
576
579
577
580
static PyObject *
578
- record_values (PyObject * o , PyObject * args )
581
+ record_values (PyObject * o , PyObject * Py_UNUSED ( unused ) )
579
582
{
580
583
return record_iter (o );
581
584
}
582
585
583
586
584
587
static PyObject *
585
- record_keys (PyObject * o , PyObject * args )
588
+ record_keys (PyObject * o , PyObject * Py_UNUSED ( unused ) )
586
589
{
587
590
if (!ApgRecord_Check (o )) {
588
591
PyErr_BadInternalCall ();
@@ -594,7 +597,7 @@ record_keys(PyObject *o, PyObject *args)
594
597
595
598
596
599
static PyObject *
597
- record_items (PyObject * o , PyObject * args )
600
+ record_items (PyObject * o , PyObject * Py_UNUSED ( unused ) )
598
601
{
599
602
if (!ApgRecord_Check (o )) {
600
603
PyErr_BadInternalCall ();
@@ -658,11 +661,69 @@ static PyMappingMethods record_as_mapping = {
658
661
};
659
662
660
663
664
+ static PyObject *
665
+ record_reduce (ApgRecordObject * o , PyObject * Py_UNUSED (unused ))
666
+ {
667
+ PyObject * value = PyTuple_New (2 );
668
+ if (value == NULL ) {
669
+ return NULL ;
670
+ }
671
+ Py_ssize_t len = Py_SIZE (o );
672
+ PyObject * state = PyTuple_New (1 + len );
673
+ if (state == NULL ) {
674
+ Py_DECREF (value );
675
+ return NULL ;
676
+ }
677
+ PyTuple_SET_ITEM (value , 0 , record_reconstruct_obj );
678
+ Py_INCREF (record_reconstruct_obj );
679
+ PyTuple_SET_ITEM (value , 1 , state );
680
+ PyTuple_SET_ITEM (state , 0 , (PyObject * )o -> desc );
681
+ Py_INCREF (o -> desc );
682
+ for (Py_ssize_t i = 0 ; i < len ; i ++ ) {
683
+ PyObject * item = ApgRecord_GET_ITEM (o , i );
684
+ PyTuple_SET_ITEM (state , i + 1 , item );
685
+ Py_INCREF (item );
686
+ }
687
+ return value ;
688
+ }
689
+
690
+ static PyObject *
691
+ record_reconstruct (PyObject * Py_UNUSED (unused ), PyObject * args )
692
+ {
693
+ if (!PyTuple_CheckExact (args )) {
694
+ return NULL ;
695
+ }
696
+ Py_ssize_t len = PyTuple_GET_SIZE (args );
697
+ if (len < 2 ) {
698
+ return NULL ;
699
+ }
700
+ len -- ;
701
+ ApgRecordDescObject * desc = (ApgRecordDescObject * )PyTuple_GET_ITEM (args , 0 );
702
+ if (!ApgRecordDesc_CheckExact (desc )) {
703
+ return NULL ;
704
+ }
705
+ if (PyObject_Length (desc -> mapping ) != len ) {
706
+ return NULL ;
707
+ }
708
+ PyObject * record = ApgRecord_New (& ApgRecord_Type , (PyObject * )desc , len );
709
+ if (record == NULL ) {
710
+ return NULL ;
711
+ }
712
+ for (Py_ssize_t i = 0 ; i < len ; i ++ ) {
713
+ PyObject * item = PyTuple_GET_ITEM (args , i + 1 );
714
+ ApgRecord_SET_ITEM (record , i , item );
715
+ Py_INCREF (item );
716
+ }
717
+ return record ;
718
+ }
719
+
661
720
static PyMethodDef record_methods [] = {
662
721
{"values" , (PyCFunction )record_values , METH_NOARGS },
663
722
{"keys" , (PyCFunction )record_keys , METH_NOARGS },
664
723
{"items" , (PyCFunction )record_items , METH_NOARGS },
665
724
{"get" , (PyCFunction )record_get , METH_VARARGS },
725
+ {"__reduce__" , (PyCFunction )record_reduce , METH_NOARGS },
726
+ {"__reconstruct__" , (PyCFunction )record_reconstruct , METH_VARARGS | METH_STATIC },
666
727
{NULL , NULL } /* sentinel */
667
728
};
668
729
@@ -942,29 +1003,6 @@ record_new_items_iter(PyObject *seq)
942
1003
}
943
1004
944
1005
945
- PyTypeObject *
946
- ApgRecord_InitTypes (void )
947
- {
948
- if (PyType_Ready (& ApgRecord_Type ) < 0 ) {
949
- return NULL ;
950
- }
951
-
952
- if (PyType_Ready (& ApgRecordDesc_Type ) < 0 ) {
953
- return NULL ;
954
- }
955
-
956
- if (PyType_Ready (& ApgRecordIter_Type ) < 0 ) {
957
- return NULL ;
958
- }
959
-
960
- if (PyType_Ready (& ApgRecordItems_Type ) < 0 ) {
961
- return NULL ;
962
- }
963
-
964
- return & ApgRecord_Type ;
965
- }
966
-
967
-
968
1006
/* ----------------- */
969
1007
970
1008
@@ -987,15 +1025,54 @@ record_desc_traverse(ApgRecordDescObject *o, visitproc visit, void *arg)
987
1025
}
988
1026
989
1027
1028
+ static PyObject * record_desc_reduce (ApgRecordDescObject * o , PyObject * Py_UNUSED (unused ))
1029
+ {
1030
+ PyObject * value = PyTuple_New (2 );
1031
+ if (value == NULL ) {
1032
+ return NULL ;
1033
+ }
1034
+ PyObject * state = PyTuple_New (2 );
1035
+ if (state == NULL ) {
1036
+ Py_DECREF (value );
1037
+ return NULL ;
1038
+ }
1039
+ PyTuple_SET_ITEM (value , 0 , record_desc_reconstruct_obj );
1040
+ Py_INCREF (record_desc_reconstruct_obj );
1041
+ PyTuple_SET_ITEM (value , 1 , state );
1042
+ PyTuple_SET_ITEM (state , 0 , o -> mapping );
1043
+ Py_INCREF (o -> mapping );
1044
+ PyTuple_SET_ITEM (state , 1 , o -> keys );
1045
+ Py_INCREF (o -> keys );
1046
+ return value ;
1047
+ }
1048
+
1049
+
1050
+ static PyObject * record_desc_reconstruct (PyObject * Py_UNUSED (unused ), PyObject * args )
1051
+ {
1052
+ if (PyTuple_GET_SIZE (args ) != 2 ) {
1053
+ return NULL ;
1054
+ }
1055
+ return ApgRecordDesc_New (PyTuple_GET_ITEM (args , 0 ), PyTuple_GET_ITEM (args , 1 ));
1056
+ }
1057
+
1058
+
1059
+ static PyMethodDef record_desc_methods [] = {
1060
+ {"__reduce__" , (PyCFunction )record_desc_reduce , METH_NOARGS },
1061
+ {"__reconstruct__" , (PyCFunction )record_desc_reconstruct , METH_VARARGS | METH_STATIC },
1062
+ {NULL , NULL } /* sentinel */
1063
+ };
1064
+
1065
+
990
1066
PyTypeObject ApgRecordDesc_Type = {
991
1067
PyVarObject_HEAD_INIT (NULL , 0 )
992
- .tp_name = "RecordDescriptor" ,
1068
+ .tp_name = "asyncpg.protocol.protocol. RecordDescriptor" ,
993
1069
.tp_basicsize = sizeof (ApgRecordDescObject ),
994
1070
.tp_dealloc = (destructor )record_desc_dealloc ,
995
1071
.tp_getattro = PyObject_GenericGetAttr ,
996
1072
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC ,
997
1073
.tp_traverse = (traverseproc )record_desc_traverse ,
998
1074
.tp_iter = PyObject_SelfIter ,
1075
+ .tp_methods = record_desc_methods ,
999
1076
};
1000
1077
1001
1078
@@ -1023,3 +1100,41 @@ ApgRecordDesc_New(PyObject *mapping, PyObject *keys)
1023
1100
PyObject_GC_Track (o );
1024
1101
return (PyObject * ) o ;
1025
1102
}
1103
+
1104
+
1105
+ PyObject *
1106
+ ApgRecord_InitTypes (void )
1107
+ {
1108
+ if (PyType_Ready (& ApgRecord_Type ) < 0 ) {
1109
+ return NULL ;
1110
+ }
1111
+
1112
+ if (PyType_Ready (& ApgRecordDesc_Type ) < 0 ) {
1113
+ return NULL ;
1114
+ }
1115
+
1116
+ if (PyType_Ready (& ApgRecordIter_Type ) < 0 ) {
1117
+ return NULL ;
1118
+ }
1119
+
1120
+ if (PyType_Ready (& ApgRecordItems_Type ) < 0 ) {
1121
+ return NULL ;
1122
+ }
1123
+
1124
+ record_reconstruct_obj = PyCFunction_New (
1125
+ & record_methods [5 ], (PyObject * )& ApgRecord_Type
1126
+ );
1127
+ record_desc_reconstruct_obj = PyCFunction_New (
1128
+ & record_desc_methods [1 ], (PyObject * )& ApgRecordDesc_Type
1129
+ );
1130
+
1131
+ PyObject * types = PyTuple_New (2 );
1132
+ if (types == NULL ) {
1133
+ return NULL ;
1134
+ }
1135
+ PyTuple_SET_ITEM (types , 0 , (PyObject * )& ApgRecord_Type );
1136
+ Py_INCREF (& ApgRecord_Type );
1137
+ PyTuple_SET_ITEM (types , 1 , (PyObject * )& ApgRecordDesc_Type );
1138
+ Py_INCREF (& ApgRecordDesc_Type );
1139
+ return types ;
1140
+ }
0 commit comments