@@ -266,7 +266,72 @@ class c_void_p(_SimpleCData):
266
266
class c_bool (_SimpleCData ):
267
267
_type_ = "?"
268
268
269
- from _ctypes import POINTER , pointer , _pointer_type_cache
269
+ def POINTER (cls ):
270
+ """Create and return a new ctypes pointer type.
271
+
272
+ Pointer types are cached and reused internally,
273
+ so calling this function repeatedly is cheap.
274
+ """
275
+ if cls is None :
276
+ return c_void_p
277
+ try :
278
+ return cls .__pointer_type__
279
+ except AttributeError :
280
+ pass
281
+ if isinstance (cls , str ):
282
+ # handle old-style incomplete types (see test_ctypes.test_incomplete)
283
+ import warnings
284
+ warnings ._deprecated ("ctypes.POINTER with string" , remove = (3 , 19 ))
285
+ try :
286
+ return _pointer_type_cache_fallback [cls ]
287
+ except KeyError :
288
+ result = type (f'LP_{ cls } ' , (_Pointer ,), {})
289
+ _pointer_type_cache_fallback [cls ] = result
290
+ return result
291
+
292
+ # create pointer type and set __pointer_type__ for cls
293
+ return type (f'LP_{ cls .__name__ } ' , (_Pointer ,), {'_type_' : cls })
294
+
295
+ def pointer (obj ):
296
+ """Create a new pointer instance, pointing to 'obj'.
297
+
298
+ The returned object is of the type POINTER(type(obj)). Note that if you
299
+ just want to pass a pointer to an object to a foreign function call, you
300
+ should use byref(obj) which is much faster.
301
+ """
302
+ typ = POINTER (type (obj ))
303
+ return typ (obj )
304
+
305
+ class _PointerTypeCache :
306
+ def __setitem__ (self , cls , pointer_type ):
307
+ import warnings
308
+ warnings ._deprecated ("ctypes._pointer_type_cache" , remove = (3 , 19 ))
309
+ try :
310
+ cls .__pointer_type__ = pointer_type
311
+ except AttributeError :
312
+ _pointer_type_cache_fallback [cls ] = pointer_type
313
+
314
+ def __getitem__ (self , cls ):
315
+ import warnings
316
+ warnings ._deprecated ("ctypes._pointer_type_cache" , remove = (3 , 19 ))
317
+ try :
318
+ return cls .__pointer_type__
319
+ except AttributeError :
320
+ return _pointer_type_cache_fallback [cls ]
321
+
322
+ def get (self , cls , default = None ):
323
+ import warnings
324
+ warnings ._deprecated ("ctypes._pointer_type_cache" , remove = (3 , 19 ))
325
+ try :
326
+ return cls .__pointer_type__
327
+ except AttributeError :
328
+ return _pointer_type_cache_fallback .get (cls , default )
329
+
330
+ def __contains__ (self , cls ):
331
+ return hasattr (cls , '__pointer_type__' )
332
+
333
+ _pointer_type_cache_fallback = {}
334
+ _pointer_type_cache = _PointerTypeCache ()
270
335
271
336
class c_wchar_p (_SimpleCData ):
272
337
_type_ = "Z"
@@ -277,15 +342,14 @@ class c_wchar(_SimpleCData):
277
342
_type_ = "u"
278
343
279
344
def _reset_cache ():
280
- _pointer_type_cache .clear ()
345
+ _pointer_type_cache_fallback .clear ()
281
346
_c_functype_cache .clear ()
282
347
if _os .name == "nt" :
283
348
_win_functype_cache .clear ()
284
349
# _SimpleCData.c_wchar_p_from_param
285
350
POINTER (c_wchar ).from_param = c_wchar_p .from_param
286
351
# _SimpleCData.c_char_p_from_param
287
352
POINTER (c_char ).from_param = c_char_p .from_param
288
- _pointer_type_cache [None ] = c_void_p
289
353
290
354
def create_unicode_buffer (init , size = None ):
291
355
"""create_unicode_buffer(aString) -> character array
@@ -319,13 +383,7 @@ def create_unicode_buffer(init, size=None):
319
383
def SetPointerType (pointer , cls ):
320
384
import warnings
321
385
warnings ._deprecated ("ctypes.SetPointerType" , remove = (3 , 15 ))
322
- if _pointer_type_cache .get (cls , None ) is not None :
323
- raise RuntimeError ("This type already exists in the cache" )
324
- if id (pointer ) not in _pointer_type_cache :
325
- raise RuntimeError ("What's this???" )
326
386
pointer .set_type (cls )
327
- _pointer_type_cache [cls ] = pointer
328
- del _pointer_type_cache [id (pointer )]
329
387
330
388
def ARRAY (typ , len ):
331
389
return typ * len
0 commit comments