Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Upgrade ctypes to Python v3.13.11
  • Loading branch information
youknowone committed Dec 23, 2025
commit 03d6f4634f86a1b9d12e85159bdd14361921c7ed
94 changes: 51 additions & 43 deletions Lib/ctypes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""create and manipulate C data types in Python"""

import os as _os, sys as _sys
import os as _os
import sys as _sys
import sysconfig as _sysconfig
import types as _types

__version__ = "1.1.0"
Expand Down Expand Up @@ -107,7 +109,7 @@ class CFunctionType(_CFuncPtr):
return CFunctionType

if _os.name == "nt":
from _ctypes import LoadLibrary as _dlopen
from _ctypes import LoadLibrary as _LoadLibrary
from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL

_win_functype_cache = {}
Expand Down Expand Up @@ -302,8 +304,9 @@ def create_unicode_buffer(init, size=None):
raise TypeError(init)


# XXX Deprecated
def SetPointerType(pointer, cls):
import warnings
warnings._deprecated("ctypes.SetPointerType", remove=(3, 15))
if _pointer_type_cache.get(cls, None) is not None:
raise RuntimeError("This type already exists in the cache")
if id(pointer) not in _pointer_type_cache:
Expand All @@ -312,7 +315,6 @@ def SetPointerType(pointer, cls):
_pointer_type_cache[cls] = pointer
del _pointer_type_cache[id(pointer)]

# XXX Deprecated
def ARRAY(typ, len):
return typ * len

Expand Down Expand Up @@ -344,52 +346,59 @@ def __init__(self, name, mode=DEFAULT_MODE, handle=None,
use_errno=False,
use_last_error=False,
winmode=None):
class _FuncPtr(_CFuncPtr):
_flags_ = self._func_flags_
_restype_ = self._func_restype_
if use_errno:
_flags_ |= _FUNCFLAG_USE_ERRNO
if use_last_error:
_flags_ |= _FUNCFLAG_USE_LASTERROR

self._FuncPtr = _FuncPtr
if name:
name = _os.fspath(name)

self._handle = self._load_library(name, mode, handle, winmode)

if _os.name == "nt":
def _load_library(self, name, mode, handle, winmode):
if winmode is None:
import nt as _nt
winmode = _nt._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
# WINAPI LoadLibrary searches for a DLL if the given name
# is not fully qualified with an explicit drive. For POSIX
# compatibility, and because the DLL search path no longer
# contains the working directory, begin by fully resolving
# any name that contains a path separator.
if name is not None and ('/' in name or '\\' in name):
name = _nt._getfullpathname(name)
winmode |= _nt._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
self._name = name
if handle is not None:
return handle
return _LoadLibrary(self._name, winmode)

else:
def _load_library(self, name, mode, handle, winmode):
# If the filename that has been provided is an iOS/tvOS/watchOS
# .fwork file, dereference the location to the true origin of the
# binary.
if name.endswith(".fwork"):
if name and name.endswith(".fwork"):
with open(name) as f:
name = _os.path.join(
_os.path.dirname(_sys.executable),
f.read().strip()
)

self._name = name
flags = self._func_flags_
if use_errno:
flags |= _FUNCFLAG_USE_ERRNO
if use_last_error:
flags |= _FUNCFLAG_USE_LASTERROR
if _sys.platform.startswith("aix"):
"""When the name contains ".a(" and ends with ")",
e.g., "libFOO.a(libFOO.so)" - this is taken to be an
archive(member) syntax for dlopen(), and the mode is adjusted.
Otherwise, name is presented to dlopen() as a file argument.
"""
if name and name.endswith(")") and ".a(" in name:
mode |= ( _os.RTLD_MEMBER | _os.RTLD_NOW )
if _os.name == "nt":
if winmode is not None:
mode = winmode
else:
import nt
mode = nt._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
if '/' in name or '\\' in name:
self._name = nt._getfullpathname(self._name)
mode |= nt._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR

class _FuncPtr(_CFuncPtr):
_flags_ = flags
_restype_ = self._func_restype_
self._FuncPtr = _FuncPtr

if handle is None:
self._handle = _dlopen(self._name, mode)
else:
self._handle = handle
if _sys.platform.startswith("aix"):
"""When the name contains ".a(" and ends with ")",
e.g., "libFOO.a(libFOO.so)" - this is taken to be an
archive(member) syntax for dlopen(), and the mode is adjusted.
Otherwise, name is presented to dlopen() as a file argument.
"""
if name and name.endswith(")") and ".a(" in name:
mode |= _os.RTLD_MEMBER | _os.RTLD_NOW
self._name = name
return _dlopen(name, mode)

def __repr__(self):
return "<%s '%s', handle %x at %#x>" % \
Expand Down Expand Up @@ -477,10 +486,9 @@ def LoadLibrary(self, name):

if _os.name == "nt":
pythonapi = PyDLL("python dll", None, _sys.dllhandle)
elif _sys.platform == "android":
pythonapi = PyDLL("libpython%d.%d.so" % _sys.version_info[:2])
elif _sys.platform == "cygwin":
pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
elif _sys.platform in ["android", "cygwin"]:
# These are Unix-like platforms which use a dynamically-linked libpython.
pythonapi = PyDLL(_sysconfig.get_config_var("LDLIBRARY"))
else:
pythonapi = PyDLL(None)

Expand Down
8 changes: 4 additions & 4 deletions Lib/ctypes/_endian.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
from ctypes import *
from ctypes import Array, Structure, Union

_array_type = type(Array)

Expand All @@ -15,8 +15,8 @@ def _other_endian(typ):
# if typ is array
if isinstance(typ, _array_type):
return _other_endian(typ._type_) * typ._length_
# if typ is structure
if issubclass(typ, Structure):
# if typ is structure or union
if issubclass(typ, (Structure, Union)):
return typ
raise TypeError("This type does not support other endian: %s" % typ)

Expand All @@ -37,7 +37,7 @@ class _swapped_union_meta(_swapped_meta, type(Union)): pass
################################################################

# Note: The Structure metaclass checks for the *presence* (not the
# value!) of a _swapped_bytes_ attribute to determine the bit order in
# value!) of a _swappedbytes_ attribute to determine the bit order in
# structures containing bit fields.

if sys.byteorder == "little":
Expand Down
16 changes: 0 additions & 16 deletions Lib/ctypes/test/__init__.py

This file was deleted.

4 changes: 0 additions & 4 deletions Lib/ctypes/test/__main__.py

This file was deleted.

73 changes: 0 additions & 73 deletions Lib/ctypes/test/test_anon.py

This file was deleted.

64 changes: 0 additions & 64 deletions Lib/ctypes/test/test_array_in_pointer.py

This file was deleted.

Loading