1010                    c_byte , c_ubyte , c_short , c_ushort , c_int , c_uint ,
1111                    c_long , c_ulong , c_longlong , c_ulonglong ,
1212                    c_float , c_double )
13- from  ctypes  import  _pointer_type_cache 
13+ from  ctypes  import  _pointer_type_cache ,  _pointer_type_cache_fallback 
1414from  test .support  import  import_helper 
1515from  weakref  import  WeakSet 
1616_ctypes_test  =  import_helper .import_module ("_ctypes_test" )
2525
2626
2727class  PointersTestCase (unittest .TestCase ):
28+     def  tearDown (self ):
29+         _pointer_type_cache_fallback .clear ()
30+ 
2831    def  test_inheritance_hierarchy (self ):
2932        self .assertEqual (_Pointer .mro (), [_Pointer , _CData , object ])
3033
@@ -246,7 +249,8 @@ def test_pointer_type_name(self):
246249
247250    def  test_pointer_type_str_name (self ):
248251        large_string  =  'T'  *  2  **  25 
249-         P  =  POINTER (large_string )
252+         with  self .assertWarns (DeprecationWarning ):
253+             P  =  POINTER (large_string )
250254        self .assertTrue (P )
251255
252256    def  test_abstract (self ):
@@ -267,14 +271,17 @@ def test_pointer_types_equal(self):
267271        self .assertIs (type (p1 ), t1 )
268272        self .assertIs (type (p2 ), t1 )
269273
270-     def  test_incomplete_pointer_types_not_equal (self ):
271-         t1  =  POINTER ("LP_C" )
272-         t2  =  POINTER ("LP_C" )
274+     def  test_incomplete_pointer_types_still_equal (self ):
275+         with  self .assertWarns (DeprecationWarning ):
276+             t1  =  POINTER ("LP_C" )
277+         with  self .assertWarns (DeprecationWarning ):
278+             t2  =  POINTER ("LP_C" )
273279
274-         self .assertIsNot (t1 , t2 )
280+         self .assertIs (t1 , t2 )
275281
276282    def  test_incomplete_pointer_types_cannot_instantiate (self ):
277-         t1  =  POINTER ("LP_C" )
283+         with  self .assertWarns (DeprecationWarning ):
284+             t1  =  POINTER ("LP_C" )
278285        with  self .assertRaisesRegex (TypeError , "has no _type_" ):
279286            t1 ()
280287
@@ -288,15 +295,29 @@ def test_pointer_set_type_twice(self):
288295        self .assertIs (t1 ._type_ , c_int )
289296
290297    def  test_pointer_set_wrong_type (self ):
291-         class  C (c_int ):
292-             pass 
293- 
294-         t1  =  POINTER (c_int )
295-         with  self .assertRaisesRegex (TypeError , "pointer type already set" ):
298+         int_ptr  =  POINTER (c_int )
299+         float_ptr  =  POINTER (float_ptr )
300+         try :
301+             class  C (c_int ):
302+                 pass 
303+ 
304+             t1  =  POINTER (c_int )
305+             t2  =  POINTER (c_float )
296306            t1 .set_type (c_float )
307+             self .assertEqual (t1 (c_float (1.5 ))[0 ], 1.5 )
308+             self .assertIs (c_int ._type_ , c_float )
309+             self .assertIs (c_int .__pointer_type__ , t1 )
310+             self .assertIs (c_float .__pointer_type__ , float_ptr )
297311
298-         with  self .assertRaisesRegex (TypeError , "cls type already set" ):
299312            t1 .set_type (C )
313+             self .assertEqual (t1 (C (123 ))[0 ].value , 123 )
314+             self .assertIs (c_int .__pointer_type__ , t1 )
315+             self .assertIs (c_float .__pointer_type__ , float_ptr )
316+         finally :
317+             POINTER (c_int ).set_type (c_int )
318+         self .assertIs (POINTER (c_int ), int_ptr )
319+         self .assertIs (POINTER (c_int )._type_ , c_int )
320+         self .assertIs (c_int .__pointer_type__ , int_ptr )
300321
301322    def  test_pointer_not_ctypes_type (self ):
302323        with  self .assertRaisesRegex (TypeError , "must have storage info" ):
@@ -326,6 +347,34 @@ class Cls(Structure):
326347        p  =  POINTER (Cls )
327348        self .assertIs (Cls .__pointer_type__ , p )
328349
350+     def  test_arbitrary_pointer_type_attribute (self ):
351+         class  Cls (Structure ):
352+             _fields_  =  (
353+                 ('a' , c_int ),
354+                 ('b' , c_float ),
355+             )
356+ 
357+         garbage  =  'garbage' 
358+ 
359+         P  =  POINTER (Cls )
360+         self .assertIs (Cls .__pointer_type__ , P )
361+         Cls .__pointer_type__  =  garbage 
362+         self .assertIs (Cls .__pointer_type__ , garbage )
363+         self .assertIs (POINTER (Cls ), garbage )
364+         self .assertIs (P ._type_ , Cls )
365+ 
366+         instance  =  Cls (1 , 2.0 )
367+         pointer  =  P (instance )
368+         self .assertEqual (pointer [0 ].a , 1 )
369+         self .assertEqual (pointer [0 ].b , 2 )
370+ 
371+         del  Cls .__pointer_type__ 
372+ 
373+         NewP  =  POINTER (Cls )
374+         self .assertIsNot (NewP , P )
375+         self .assertIs (Cls .__pointer_type__ , NewP )
376+         self .assertIs (P ._type_ , Cls )
377+ 
329378    def  test_pointer_types_factory (self ):
330379        """Shouldn't leak""" 
331380        def  factory ():
@@ -357,21 +406,31 @@ class Cls(Structure):
357406
358407class  PointerTypeCacheTestCase (unittest .TestCase ):
359408    # dummy tests to check warnings and base behavior 
409+     def  tearDown (self ):
410+         _pointer_type_cache_fallback .clear ()
360411
361412    def  test_deprecated_cache_with_not_ctypes_type (self ):
362413        class  C :
363414            pass 
364415
365-         P  =  POINTER ("C" )
366416        with  self .assertWarns (DeprecationWarning ):
367-             _pointer_type_cache [ C ]  =  P 
417+             P  =  POINTER ( "C" ) 
368418
419+         with  self .assertWarns (DeprecationWarning ):
420+             self .assertIs (_pointer_type_cache ["C" ], P )
421+ 
422+         with  self .assertWarns (DeprecationWarning ):
423+             _pointer_type_cache [C ] =  P 
369424        self .assertIs (C .__pointer_type__ , P )
370425        with  self .assertWarns (DeprecationWarning ):
371426            self .assertIs (_pointer_type_cache [C ], P )
372427
428+     def  test_deprecated_cache_with_ints (self ):
429+         with  self .assertWarns (DeprecationWarning ):
430+             _pointer_type_cache [123 ] =  456 
431+ 
373432        with  self .assertWarns (DeprecationWarning ):
374-             self .assertIs (_pointer_type_cache . get ( C ),  P )
433+             self .assertEqual (_pointer_type_cache [ 123 ],  456 )
375434
376435    def  test_deprecated_cache_with_ctypes_type (self ):
377436        class  C (Structure ):
@@ -380,21 +439,20 @@ class C(Structure):
380439                        ("c" , c_int )]
381440
382441        P1  =  POINTER (C )
383-         P2  =  POINTER ("C" )
384442        with  self .assertWarns (DeprecationWarning ):
385-             _pointer_type_cache [ C ]  =  P1 
443+             P2  =  POINTER ( "C" ) 
386444
387445        with  self .assertWarns (DeprecationWarning ):
388-             _pointer_type_cache [C ] =  P2   # silently do nothing 
446+             _pointer_type_cache [C ] =  P2 
389447
390-         self .assertIs (C .__pointer_type__ , P1 )
391-         self .assertIsNot (C .__pointer_type__ , P2 )
448+         self .assertIs (C .__pointer_type__ , P2 )
449+         self .assertIsNot (C .__pointer_type__ , P1 )
392450
393451        with  self .assertWarns (DeprecationWarning ):
394-             self .assertIs (_pointer_type_cache [C ], P1 )
452+             self .assertIs (_pointer_type_cache [C ], P2 )
395453
396454        with  self .assertWarns (DeprecationWarning ):
397-             self .assertIs (_pointer_type_cache .get (C ), P1 )
455+             self .assertIs (_pointer_type_cache .get (C ), P2 )
398456
399457    def  test_get_not_registered (self ):
400458        with  self .assertWarns (DeprecationWarning ):
0 commit comments