Skip to content

Commit 487c159

Browse files
authored
Merge pull request RustPython#7165 from youknowone/ctypes
Update ctypes from v3.14.3 and make _ctypes compatible
2 parents d7ed210 + 007f216 commit 487c159

59 files changed

Lines changed: 5364 additions & 741 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Lib/ctypes/__init__.py

Lines changed: 90 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
1515
from _ctypes import ArgumentError
1616
from _ctypes import SIZEOF_TIME_T
17+
from _ctypes import CField
1718

1819
from struct import calcsize as _calcsize
1920

2021
if __version__ != _ctypes_version:
2122
raise Exception("Version number mismatch", __version__, _ctypes_version)
2223

2324
if _os.name == "nt":
24-
from _ctypes import FormatError
25+
from _ctypes import COMError, CopyComPointer, FormatError
2526

2627
DEFAULT_MODE = RTLD_LOCAL
2728
if _os.name == "posix" and _sys.platform == "darwin":
@@ -208,6 +209,18 @@ class c_longdouble(_SimpleCData):
208209
if sizeof(c_longdouble) == sizeof(c_double):
209210
c_longdouble = c_double
210211

212+
try:
213+
class c_double_complex(_SimpleCData):
214+
_type_ = "D"
215+
_check_size(c_double_complex)
216+
class c_float_complex(_SimpleCData):
217+
_type_ = "F"
218+
_check_size(c_float_complex)
219+
class c_longdouble_complex(_SimpleCData):
220+
_type_ = "G"
221+
except AttributeError:
222+
pass
223+
211224
if _calcsize("l") == _calcsize("q"):
212225
# if long and long long have the same size, make c_longlong an alias for c_long
213226
c_longlong = c_long
@@ -255,7 +268,72 @@ class c_void_p(_SimpleCData):
255268
class c_bool(_SimpleCData):
256269
_type_ = "?"
257270

258-
from _ctypes import POINTER, pointer, _pointer_type_cache
271+
def POINTER(cls):
272+
"""Create and return a new ctypes pointer type.
273+
274+
Pointer types are cached and reused internally,
275+
so calling this function repeatedly is cheap.
276+
"""
277+
if cls is None:
278+
return c_void_p
279+
try:
280+
return cls.__pointer_type__
281+
except AttributeError:
282+
pass
283+
if isinstance(cls, str):
284+
# handle old-style incomplete types (see test_ctypes.test_incomplete)
285+
import warnings
286+
warnings._deprecated("ctypes.POINTER with string", remove=(3, 19))
287+
try:
288+
return _pointer_type_cache_fallback[cls]
289+
except KeyError:
290+
result = type(f'LP_{cls}', (_Pointer,), {})
291+
_pointer_type_cache_fallback[cls] = result
292+
return result
293+
294+
# create pointer type and set __pointer_type__ for cls
295+
return type(f'LP_{cls.__name__}', (_Pointer,), {'_type_': cls})
296+
297+
def pointer(obj):
298+
"""Create a new pointer instance, pointing to 'obj'.
299+
300+
The returned object is of the type POINTER(type(obj)). Note that if you
301+
just want to pass a pointer to an object to a foreign function call, you
302+
should use byref(obj) which is much faster.
303+
"""
304+
typ = POINTER(type(obj))
305+
return typ(obj)
306+
307+
class _PointerTypeCache:
308+
def __setitem__(self, cls, pointer_type):
309+
import warnings
310+
warnings._deprecated("ctypes._pointer_type_cache", remove=(3, 19))
311+
try:
312+
cls.__pointer_type__ = pointer_type
313+
except AttributeError:
314+
_pointer_type_cache_fallback[cls] = pointer_type
315+
316+
def __getitem__(self, cls):
317+
import warnings
318+
warnings._deprecated("ctypes._pointer_type_cache", remove=(3, 19))
319+
try:
320+
return cls.__pointer_type__
321+
except AttributeError:
322+
return _pointer_type_cache_fallback[cls]
323+
324+
def get(self, cls, default=None):
325+
import warnings
326+
warnings._deprecated("ctypes._pointer_type_cache", remove=(3, 19))
327+
try:
328+
return cls.__pointer_type__
329+
except AttributeError:
330+
return _pointer_type_cache_fallback.get(cls, default)
331+
332+
def __contains__(self, cls):
333+
return hasattr(cls, '__pointer_type__')
334+
335+
_pointer_type_cache_fallback = {}
336+
_pointer_type_cache = _PointerTypeCache()
259337

260338
class c_wchar_p(_SimpleCData):
261339
_type_ = "Z"
@@ -266,15 +344,14 @@ class c_wchar(_SimpleCData):
266344
_type_ = "u"
267345

268346
def _reset_cache():
269-
_pointer_type_cache.clear()
347+
_pointer_type_cache_fallback.clear()
270348
_c_functype_cache.clear()
271349
if _os.name == "nt":
272350
_win_functype_cache.clear()
273351
# _SimpleCData.c_wchar_p_from_param
274352
POINTER(c_wchar).from_param = c_wchar_p.from_param
275353
# _SimpleCData.c_char_p_from_param
276354
POINTER(c_char).from_param = c_char_p.from_param
277-
_pointer_type_cache[None] = c_void_p
278355

279356
def create_unicode_buffer(init, size=None):
280357
"""create_unicode_buffer(aString) -> character array
@@ -308,13 +385,7 @@ def create_unicode_buffer(init, size=None):
308385
def SetPointerType(pointer, cls):
309386
import warnings
310387
warnings._deprecated("ctypes.SetPointerType", remove=(3, 15))
311-
if _pointer_type_cache.get(cls, None) is not None:
312-
raise RuntimeError("This type already exists in the cache")
313-
if id(pointer) not in _pointer_type_cache:
314-
raise RuntimeError("What's this???")
315388
pointer.set_type(cls)
316-
_pointer_type_cache[cls] = pointer
317-
del _pointer_type_cache[id(pointer)]
318389

319390
def ARRAY(typ, len):
320391
return typ * len
@@ -521,6 +592,7 @@ def WinError(code=None, descr=None):
521592
# functions
522593

523594
from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
595+
from _ctypes import _memoryview_at_addr
524596

525597
## void *memmove(void *, const void *, size_t);
526598
memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
@@ -546,6 +618,14 @@ def string_at(ptr, size=-1):
546618
Return the byte string at void *ptr."""
547619
return _string_at(ptr, size)
548620

621+
_memoryview_at = PYFUNCTYPE(
622+
py_object, c_void_p, c_ssize_t, c_int)(_memoryview_at_addr)
623+
def memoryview_at(ptr, size, readonly=False):
624+
"""memoryview_at(ptr, size[, readonly]) -> memoryview
625+
626+
Return a memoryview representing the memory at void *ptr."""
627+
return _memoryview_at(ptr, size, bool(readonly))
628+
549629
try:
550630
from _ctypes import _wstring_at_addr
551631
except ImportError:

0 commit comments

Comments
 (0)