File tree Expand file tree Collapse file tree 4 files changed +42
-15
lines changed
Expand file tree Collapse file tree 4 files changed +42
-15
lines changed Original file line number Diff line number Diff line change @@ -644,6 +644,30 @@ class Test8(Union):
644644 self .assertEqual (ctx .exception .args [0 ], 'item 1 in _argtypes_ passes '
645645 'a union by value, which is unsupported.' )
646646
647+ def test_do_not_share_pointer_type_cache_via_stginfo_clone (self ):
648+ # This test case calls PyCStgInfo_clone()
649+ # for the Mid and Vector class definitions
650+ # and checks that pointer_type cache not shared
651+ # between subclasses.
652+ class Base (Structure ):
653+ _fields_ = [('y' , c_double ),
654+ ('x' , c_double )]
655+ base_ptr = POINTER (Base )
656+
657+ class Mid (Base ):
658+ pass
659+ Mid ._fields_ = []
660+ mid_ptr = POINTER (Mid )
661+
662+ class Vector (Mid ):
663+ pass
664+
665+ vector_ptr = POINTER (Vector )
666+
667+ self .assertIsNot (base_ptr , mid_ptr )
668+ self .assertIsNot (base_ptr , vector_ptr )
669+ self .assertIsNot (mid_ptr , vector_ptr )
670+
647671
648672if __name__ == '__main__' :
649673 unittest .main ()
Original file line number Diff line number Diff line change @@ -494,6 +494,20 @@ ctype_clear_stginfo(StgInfo *info)
494494 Py_CLEAR (info -> module ); // decref the module last
495495}
496496
497+ void
498+ ctype_free_stginfo_members (StgInfo * info )
499+ {
500+ assert (info );
501+
502+ PyMem_Free (info -> ffi_type_pointer .elements );
503+ info -> ffi_type_pointer .elements = NULL ;
504+ PyMem_Free (info -> format );
505+ info -> format = NULL ;
506+ PyMem_Free (info -> shape );
507+ info -> shape = NULL ;
508+ ctype_clear_stginfo (info );
509+ }
510+
497511static int
498512CType_Type_clear (PyObject * self )
499513{
@@ -517,13 +531,7 @@ CType_Type_dealloc(PyObject *self)
517531 "deallocating ctypes %R" , self );
518532 }
519533 if (info ) {
520- PyMem_Free (info -> ffi_type_pointer .elements );
521- info -> ffi_type_pointer .elements = NULL ;
522- PyMem_Free (info -> format );
523- info -> format = NULL ;
524- PyMem_Free (info -> shape );
525- info -> shape = NULL ;
526- ctype_clear_stginfo (info );
534+ ctype_free_stginfo_members (info );
527535 }
528536
529537 PyTypeObject * tp = Py_TYPE (self );
Original file line number Diff line number Diff line change @@ -378,6 +378,7 @@ typedef struct {
378378
379379extern int PyCStgInfo_clone (StgInfo * dst_info , StgInfo * src_info );
380380extern void ctype_clear_stginfo (StgInfo * info );
381+ extern void ctype_free_stginfo_members (StgInfo * info );
381382
382383typedef int (* PPROC )(void );
383384
Original file line number Diff line number Diff line change @@ -25,13 +25,7 @@ PyCStgInfo_clone(StgInfo *dst_info, StgInfo *src_info)
2525{
2626 Py_ssize_t size ;
2727
28- ctype_clear_stginfo (dst_info );
29- PyMem_Free (dst_info -> ffi_type_pointer .elements );
30- PyMem_Free (dst_info -> format );
31- dst_info -> format = NULL ;
32- PyMem_Free (dst_info -> shape );
33- dst_info -> shape = NULL ;
34- dst_info -> ffi_type_pointer .elements = NULL ;
28+ ctype_free_stginfo_members (dst_info );
3529
3630 memcpy (dst_info , src_info , sizeof (StgInfo ));
3731
@@ -40,8 +34,8 @@ PyCStgInfo_clone(StgInfo *dst_info, StgInfo *src_info)
4034 Py_XINCREF (dst_info -> converters );
4135 Py_XINCREF (dst_info -> restype );
4236 Py_XINCREF (dst_info -> checker );
43- dst_info -> pointer_type = NULL ; // the cache cannot be shared
4437 Py_XINCREF (dst_info -> module );
38+ dst_info -> pointer_type = NULL ; // the cache cannot be shared
4539
4640 if (src_info -> format ) {
4741 dst_info -> format = PyMem_Malloc (strlen (src_info -> format ) + 1 );
You can’t perform that action at this time.
0 commit comments