@@ -11,9 +11,33 @@ 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(
23+             (MAXSUPPORTEDOID +  1 ) *  2 , sizeof(void  * ))
24+         self .text_codec_map =  < void  ** > cpython.PyMem_Calloc(
25+             (MAXSUPPORTEDOID +  1 ) *  2 , sizeof(void  * ))
26+ 
27+     cdef inline void  * get_binary_codec_ptr(self , uint32_t idx):
28+         return  < void * > self .binary_codec_map[idx]
29+ 
30+     cdef inline void  set_binary_codec_ptr(self , uint32_t idx, void  * ptr):
31+         self .binary_codec_map[idx] =  ptr
32+ 
33+     cdef inline void  * get_text_codec_ptr(self , uint32_t idx):
34+         return  < void * > self .text_codec_map[idx]
35+ 
36+     cdef inline void  set_text_codec_ptr(self , uint32_t idx, void  * ptr):
37+         self .text_codec_map[idx] =  ptr
38+ 
39+ 
40+ codec_map =  CodecMap()
1741
1842
1943@cython.final 
@@ -67,7 +91,7 @@ cdef class Codec:
6791                )
6892
6993        if  element_names is  not  None :
70-             self .record_desc =  record.ApgRecordDesc_New (
94+             self .record_desc =  RecordDescriptor (
7195                element_names, tuple (element_names))
7296        else :
7397            self .record_desc =  None 
@@ -271,7 +295,7 @@ cdef class Codec:
271295                schema = self .schema,
272296                data_type = self .name,
273297            )
274-         result =  record.ApgRecord_New (asyncpg.Record,  self .record_desc , elem_count)
298+         result =  self .record_desc.make_record (asyncpg.Record, elem_count)
275299        for  i in  range (elem_count):
276300            elem_typ =  self .element_type_oids[i]
277301            received_elem_typ =  < uint32_t> hton.unpack_int32(frb_read(buf, 4 ))
@@ -301,7 +325,7 @@ cdef class Codec:
301325                    settings, frb_slice_from(& elem_buf, buf, elem_len))
302326
303327            cpython.Py_INCREF(elem)
304-             record .ApgRecord_SET_ITEM(result, i, elem)
328+             recordcapi .ApgRecord_SET_ITEM(result, i, elem)
305329
306330        return  result
307331
@@ -811,9 +835,9 @@ cdef inline Codec get_core_codec(
811835    if  oid >  MAXSUPPORTEDOID:
812836        return  None 
813837    if  format ==  PG_FORMAT_BINARY:
814-         ptr =  binary_codec_map[ oid *  xformat] 
838+         ptr =  ( < CodecMap > codec_map).get_binary_codec_ptr( oid *  xformat) 
815839    elif  format ==  PG_FORMAT_TEXT:
816-         ptr =  text_codec_map[ oid *  xformat] 
840+         ptr =  ( < CodecMap > codec_map).get_text_codec_ptr( oid *  xformat) 
817841
818842    if  ptr is  NULL :
819843        return  None 
@@ -839,7 +863,10 @@ cdef inline Codec get_any_core_codec(
839863
840864
841865cdef inline int  has_core_codec(uint32_t oid):
842-     return  binary_codec_map[oid] !=  NULL  or  text_codec_map[oid] !=  NULL 
866+     return  (
867+         (< CodecMap> codec_map).get_binary_codec_ptr(oid) !=  NULL 
868+         or  (< CodecMap> codec_map).get_text_codec_ptr(oid) !=  NULL 
869+     )
843870
844871
845872cdef register_core_codec(uint32_t oid,
@@ -867,9 +894,9 @@ cdef register_core_codec(uint32_t oid,
867894    cpython.Py_INCREF(codec)  #  immortalize
868895
869896    if  format ==  PG_FORMAT_BINARY:
870-         binary_codec_map[ oid *  xformat]  =   < void * > codec
897+         ( < CodecMap > codec_map).set_binary_codec_ptr( oid *  xformat,  < void * > codec) 
871898    elif  format ==  PG_FORMAT_TEXT:
872-         text_codec_map[ oid *  xformat]  =   < void * > codec
899+         ( < CodecMap > codec_map).set_text_codec_ptr( oid *  xformat,  < void * > codec) 
873900    else :
874901        raise  exceptions.InternalClientError(
875902            ' invalid data format: {}' 
@@ -888,8 +915,8 @@ cdef register_extra_codec(str name,
888915    codec =  Codec(INVALIDOID)
889916    codec.init(name, None , kind, CODEC_C, format, PG_XFORMAT_OBJECT,
890917               encode, decode, None , None , None , None , None , None , None , 0 )
891-     EXTRA_CODECS [name, format] =  codec
918+     ( < CodecMap > codec_map).extra_codecs [name, format] =  codec
892919
893920
894921cdef inline Codec get_extra_codec(str  name, ServerDataFormat format):
895-     return  EXTRA_CODECS .get((name, format))
922+     return  ( < CodecMap > codec_map).extra_codecs .get((name, format))
0 commit comments