@@ -11,9 +11,31 @@ import asyncpg
1111from  asyncpg import  exceptions
1212
1313
14- cdef void *  binary_codec_map[(MAXSUPPORTEDOID +  1 ) *  2 ]
15- cdef void *  text_codec_map[(MAXSUPPORTEDOID +  1 ) *  2 ]
16- cdef dict  EXTRA_CODECS =  {}
14+ #  The class indirection is needed because Cython
15+ #  does not (as of 3.1.0) store global cdef variables
16+ #  in module state.
17+ @cython.final 
18+ cdef class  CodecMap:
19+ 
20+     def  __cinit__ (self ):
21+         self .extra_codecs =  {}
22+         self .binary_codec_map =  < void  ** > cpython.PyMem_Calloc((MAXSUPPORTEDOID +  1 ) *  2 , sizeof(void  * ));
23+         self .text_codec_map =  < void  ** > cpython.PyMem_Calloc((MAXSUPPORTEDOID +  1 ) *  2 , sizeof(void  * ));
24+ 
25+     cdef inline void  * get_binary_codec_ptr(self , uint32_t idx):
26+         return  < void * > self .binary_codec_map[idx]
27+ 
28+     cdef inline void  set_binary_codec_ptr(self , uint32_t idx, void  * ptr):
29+         self .binary_codec_map[idx] =  ptr
30+ 
31+     cdef inline void  * get_text_codec_ptr(self , uint32_t idx):
32+         return  < void * > self .text_codec_map[idx]
33+ 
34+     cdef inline void  set_text_codec_ptr(self , uint32_t idx, void  * ptr):
35+         self .text_codec_map[idx] =  ptr
36+ 
37+ 
38+ codec_map =  CodecMap()
1739
1840
1941@cython.final 
@@ -67,7 +89,7 @@ cdef class Codec:
6789                )
6890
6991        if  element_names is  not  None :
70-             self .record_desc =  record.ApgRecordDesc_New (
92+             self .record_desc =  RecordDescriptor (
7193                element_names, tuple (element_names))
7294        else :
7395            self .record_desc =  None 
@@ -271,7 +293,7 @@ cdef class Codec:
271293                schema = self .schema,
272294                data_type = self .name,
273295            )
274-         result =  record.ApgRecord_New (asyncpg.Record,  self .record_desc , elem_count)
296+         result =  self .record_desc.make_record (asyncpg.Record, elem_count)
275297        for  i in  range (elem_count):
276298            elem_typ =  self .element_type_oids[i]
277299            received_elem_typ =  < uint32_t> hton.unpack_int32(frb_read(buf, 4 ))
@@ -301,7 +323,7 @@ cdef class Codec:
301323                    settings, frb_slice_from(& elem_buf, buf, elem_len))
302324
303325            cpython.Py_INCREF(elem)
304-             record .ApgRecord_SET_ITEM(result, i, elem)
326+             recordcapi .ApgRecord_SET_ITEM(result, i, elem)
305327
306328        return  result
307329
@@ -811,9 +833,9 @@ cdef inline Codec get_core_codec(
811833    if  oid >  MAXSUPPORTEDOID:
812834        return  None 
813835    if  format ==  PG_FORMAT_BINARY:
814-         ptr =  binary_codec_map[ oid *  xformat] 
836+         ptr =  ( < CodecMap > codec_map).get_binary_codec_ptr( oid *  xformat) 
815837    elif  format ==  PG_FORMAT_TEXT:
816-         ptr =  text_codec_map[ oid *  xformat] 
838+         ptr =  ( < CodecMap > codec_map).get_text_codec_ptr( oid *  xformat) 
817839
818840    if  ptr is  NULL :
819841        return  None 
@@ -839,7 +861,10 @@ cdef inline Codec get_any_core_codec(
839861
840862
841863cdef inline int  has_core_codec(uint32_t oid):
842-     return  binary_codec_map[oid] !=  NULL  or  text_codec_map[oid] !=  NULL 
864+     return  (
865+         (< CodecMap> codec_map).get_binary_codec_ptr(oid) !=  NULL 
866+         or  (< CodecMap> codec_map).get_text_codec_ptr(oid) !=  NULL 
867+     )
843868
844869
845870cdef register_core_codec(uint32_t oid,
@@ -867,9 +892,9 @@ cdef register_core_codec(uint32_t oid,
867892    cpython.Py_INCREF(codec)  #  immortalize
868893
869894    if  format ==  PG_FORMAT_BINARY:
870-         binary_codec_map[ oid *  xformat]  =   < void * > codec
895+         ( < CodecMap > codec_map).set_binary_codec_ptr( oid *  xformat,  < void * > codec) 
871896    elif  format ==  PG_FORMAT_TEXT:
872-         text_codec_map[ oid *  xformat]  =   < void * > codec
897+         ( < CodecMap > codec_map).set_text_codec_ptr( oid *  xformat,  < void * > codec) 
873898    else :
874899        raise  exceptions.InternalClientError(
875900            ' invalid data format: {}' 
@@ -888,8 +913,8 @@ cdef register_extra_codec(str name,
888913    codec =  Codec(INVALIDOID)
889914    codec.init(name, None , kind, CODEC_C, format, PG_XFORMAT_OBJECT,
890915               encode, decode, None , None , None , None , None , None , None , 0 )
891-     EXTRA_CODECS [name, format] =  codec
916+     ( < CodecMap > codec_map).extra_codecs [name, format] =  codec
892917
893918
894919cdef inline Codec get_extra_codec(str  name, ServerDataFormat format):
895-     return  EXTRA_CODECS .get((name, format))
920+     return  ( < CodecMap > codec_map).extra_codecs .get((name, format))
0 commit comments