summaryrefslogtreecommitdiffstats
path: root/Lib/ctypes
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/ctypes')
-rw-r--r--Lib/ctypes/__init__.py172
-rw-r--r--Lib/ctypes/_aix.py331
-rw-r--r--Lib/ctypes/_endian.py10
-rw-r--r--Lib/ctypes/macholib/dyld.py21
-rw-r--r--Lib/ctypes/test/__init__.py216
-rw-r--r--Lib/ctypes/test/__main__.py4
-rw-r--r--Lib/ctypes/test/runtests.py19
-rw-r--r--Lib/ctypes/test/test_anon.py4
-rw-r--r--Lib/ctypes/test/test_array_in_pointer.py2
-rw-r--r--Lib/ctypes/test/test_arrays.py120
-rw-r--r--Lib/ctypes/test/test_as_parameter.py10
-rw-r--r--Lib/ctypes/test/test_bitfields.py15
-rw-r--r--Lib/ctypes/test/test_buffers.py55
-rw-r--r--Lib/ctypes/test/test_bytes.py66
-rw-r--r--Lib/ctypes/test/test_byteswap.py30
-rw-r--r--Lib/ctypes/test/test_callbacks.py20
-rw-r--r--Lib/ctypes/test/test_cast.py31
-rw-r--r--Lib/ctypes/test/test_cfuncs.py2
-rw-r--r--Lib/ctypes/test/test_checkretval.py2
-rw-r--r--Lib/ctypes/test/test_errno.py40
-rw-r--r--Lib/ctypes/test/test_find.py125
-rw-r--r--Lib/ctypes/test/test_frombuffer.py89
-rw-r--r--Lib/ctypes/test/test_funcptr.py18
-rw-r--r--Lib/ctypes/test/test_functions.py10
-rw-r--r--Lib/ctypes/test/test_incomplete.py6
-rw-r--r--Lib/ctypes/test/test_init.py2
-rw-r--r--Lib/ctypes/test/test_internals.py25
-rw-r--r--Lib/ctypes/test/test_keeprefs.py28
-rw-r--r--Lib/ctypes/test/test_libc.py10
-rw-r--r--Lib/ctypes/test/test_loading.py139
-rw-r--r--Lib/ctypes/test/test_macholib.py58
-rw-r--r--Lib/ctypes/test/test_memfunctions.py30
-rw-r--r--Lib/ctypes/test/test_numbers.py33
-rw-r--r--Lib/ctypes/test/test_objects.py20
-rw-r--r--Lib/ctypes/test/test_parameters.py33
-rw-r--r--Lib/ctypes/test/test_pep3118.py87
-rw-r--r--Lib/ctypes/test/test_pickling.py2
-rw-r--r--Lib/ctypes/test/test_pointers.py27
-rw-r--r--Lib/ctypes/test/test_prototypes.py61
-rw-r--r--Lib/ctypes/test/test_python_api.py47
-rw-r--r--Lib/ctypes/test/test_random_things.py14
-rw-r--r--Lib/ctypes/test/test_refcounts.py3
-rw-r--r--Lib/ctypes/test/test_repr.py4
-rw-r--r--Lib/ctypes/test/test_returnfuncptrs.py19
-rw-r--r--Lib/ctypes/test/test_simplesubclasses.py8
-rw-r--r--Lib/ctypes/test/test_sizes.py1
-rw-r--r--Lib/ctypes/test/test_slicing.py54
-rw-r--r--Lib/ctypes/test/test_stringptr.py32
-rw-r--r--Lib/ctypes/test/test_strings.py112
-rw-r--r--Lib/ctypes/test/test_structures.py401
-rw-r--r--Lib/ctypes/test/test_unicode.py126
-rw-r--r--Lib/ctypes/test/test_values.py52
-rw-r--r--Lib/ctypes/test/test_win32.py78
-rw-r--r--Lib/ctypes/util.py250
-rw-r--r--Lib/ctypes/wintypes.py169
55 files changed, 1297 insertions, 2046 deletions
diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py
index 8f09911..88c85ff 100644
--- a/Lib/ctypes/__init__.py
+++ b/Lib/ctypes/__init__.py
@@ -16,7 +16,7 @@ from struct import calcsize as _calcsize
if __version__ != _ctypes_version:
raise Exception("Version number mismatch", __version__, _ctypes_version)
-if _os.name == "nt":
+if _os.name in ("nt", "ce"):
from _ctypes import FormatError
DEFAULT_MODE = RTLD_LOCAL
@@ -26,7 +26,7 @@ if _os.name == "posix" and _sys.platform == "darwin":
# libraries. OS X 10.3 is Darwin 7, so we check for
# that.
- if int(_os.uname().release.split('.')[0]) < 8:
+ if int(_os.uname()[2].split('.')[0]) < 8:
DEFAULT_MODE = RTLD_GLOBAL
from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
@@ -34,31 +34,31 @@ from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO, \
FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR
-# WINOLEAPI -> HRESULT
-# WINOLEAPI_(type)
-#
-# STDMETHODCALLTYPE
-#
-# STDMETHOD(name)
-# STDMETHOD_(type, name)
-#
-# STDAPICALLTYPE
+"""
+WINOLEAPI -> HRESULT
+WINOLEAPI_(type)
+
+STDMETHODCALLTYPE
+
+STDMETHOD(name)
+STDMETHOD_(type, name)
+
+STDAPICALLTYPE
+"""
def create_string_buffer(init, size=None):
- """create_string_buffer(aBytes) -> character array
+ """create_string_buffer(aString) -> character array
create_string_buffer(anInteger) -> character array
- create_string_buffer(aBytes, anInteger) -> character array
+ create_string_buffer(aString, anInteger) -> character array
"""
- if isinstance(init, bytes):
+ if isinstance(init, (str, unicode)):
if size is None:
size = len(init)+1
- _sys.audit("ctypes.create_string_buffer", init, size)
buftype = c_char * size
buf = buftype()
buf.value = init
return buf
- elif isinstance(init, int):
- _sys.audit("ctypes.create_string_buffer", None, init)
+ elif isinstance(init, (int, long)):
buftype = c_char * init
buf = buftype()
return buf
@@ -105,9 +105,12 @@ def CFUNCTYPE(restype, *argtypes, **kw):
_c_functype_cache[(restype, argtypes, flags)] = CFunctionType
return CFunctionType
-if _os.name == "nt":
+if _os.name in ("nt", "ce"):
from _ctypes import LoadLibrary as _dlopen
from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
+ if _os.name == "ce":
+ # 'ce' doesn't have the stdcall calling convention
+ _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL
_win_functype_cache = {}
def WINFUNCTYPE(restype, *argtypes, **kw):
@@ -154,7 +157,7 @@ class py_object(_SimpleCData):
_type_ = "O"
def __repr__(self):
try:
- return super().__repr__()
+ return super(py_object, self).__repr__()
except ValueError:
return "%s(<NULL>)" % type(self).__name__
_check_size(py_object, "P")
@@ -236,8 +239,14 @@ _check_size(c_char)
class c_char_p(_SimpleCData):
_type_ = "z"
- def __repr__(self):
- return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value)
+ if _os.name == "nt":
+ def __repr__(self):
+ if not windll.kernel32.IsBadStringPtrA(self, -1):
+ return "%s(%r)" % (self.__class__.__name__, self.value)
+ return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
+ else:
+ def __repr__(self):
+ return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
_check_size(c_char_p, "P")
class c_void_p(_SimpleCData):
@@ -250,53 +259,55 @@ class c_bool(_SimpleCData):
from _ctypes import POINTER, pointer, _pointer_type_cache
-class c_wchar_p(_SimpleCData):
- _type_ = "Z"
- def __repr__(self):
- return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value)
-
-class c_wchar(_SimpleCData):
- _type_ = "u"
-
def _reset_cache():
_pointer_type_cache.clear()
_c_functype_cache.clear()
- if _os.name == "nt":
+ if _os.name in ("nt", "ce"):
_win_functype_cache.clear()
# _SimpleCData.c_wchar_p_from_param
POINTER(c_wchar).from_param = c_wchar_p.from_param
# _SimpleCData.c_char_p_from_param
POINTER(c_char).from_param = c_char_p.from_param
_pointer_type_cache[None] = c_void_p
+ # XXX for whatever reasons, creating the first instance of a callback
+ # function is needed for the unittests on Win64 to succeed. This MAY
+ # be a compiler bug, since the problem occurs only when _ctypes is
+ # compiled with the MS SDK compiler. Or an uninitialized variable?
+ CFUNCTYPE(c_int)(lambda: None)
-def create_unicode_buffer(init, size=None):
- """create_unicode_buffer(aString) -> character array
- create_unicode_buffer(anInteger) -> character array
- create_unicode_buffer(aString, anInteger) -> character array
- """
- if isinstance(init, str):
- if size is None:
- if sizeof(c_wchar) == 2:
- # UTF-16 requires a surrogate pair (2 wchar_t) for non-BMP
- # characters (outside [U+0000; U+FFFF] range). +1 for trailing
- # NUL character.
- size = sum(2 if ord(c) > 0xFFFF else 1 for c in init) + 1
- else:
- # 32-bit wchar_t (1 wchar_t per Unicode character). +1 for
- # trailing NUL character.
- size = len(init) + 1
- _sys.audit("ctypes.create_unicode_buffer", init, size)
- buftype = c_wchar * size
- buf = buftype()
- buf.value = init
- return buf
- elif isinstance(init, int):
- _sys.audit("ctypes.create_unicode_buffer", None, init)
- buftype = c_wchar * init
- buf = buftype()
- return buf
- raise TypeError(init)
+try:
+ from _ctypes import set_conversion_mode
+except ImportError:
+ pass
+else:
+ if _os.name in ("nt", "ce"):
+ set_conversion_mode("mbcs", "ignore")
+ else:
+ set_conversion_mode("ascii", "strict")
+
+ class c_wchar_p(_SimpleCData):
+ _type_ = "Z"
+ class c_wchar(_SimpleCData):
+ _type_ = "u"
+
+ def create_unicode_buffer(init, size=None):
+ """create_unicode_buffer(aString) -> character array
+ create_unicode_buffer(anInteger) -> character array
+ create_unicode_buffer(aString, anInteger) -> character array
+ """
+ if isinstance(init, (str, unicode)):
+ if size is None:
+ size = len(init)+1
+ buftype = c_wchar * size
+ buf = buftype()
+ buf.value = init
+ return buf
+ elif isinstance(init, (int, long)):
+ buftype = c_wchar * init
+ buf = buftype()
+ return buf
+ raise TypeError(init)
# XXX Deprecated
def SetPointerType(pointer, cls):
@@ -338,31 +349,13 @@ class CDLL(object):
def __init__(self, name, mode=DEFAULT_MODE, handle=None,
use_errno=False,
- use_last_error=False,
- winmode=None):
+ use_last_error=False):
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
@@ -375,10 +368,10 @@ class CDLL(object):
self._handle = handle
def __repr__(self):
- return "<%s '%s', handle %x at %#x>" % \
+ return "<%s '%s', handle %x at %x>" % \
(self.__class__.__name__, self._name,
- (self._handle & (_sys.maxsize*2 + 1)),
- id(self) & (_sys.maxsize*2 + 1))
+ (self._handle & (_sys.maxint*2 + 1)),
+ id(self) & (_sys.maxint*2 + 1))
def __getattr__(self, name):
if name.startswith('__') and name.endswith('__'):
@@ -389,7 +382,7 @@ class CDLL(object):
def __getitem__(self, name_or_ordinal):
func = self._FuncPtr((name_or_ordinal, self))
- if not isinstance(name_or_ordinal, int):
+ if not isinstance(name_or_ordinal, (int, long)):
func.__name__ = name_or_ordinal
return func
@@ -400,7 +393,7 @@ class PyDLL(CDLL):
"""
_func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
-if _os.name == "nt":
+if _os.name in ("nt", "ce"):
class WinDLL(CDLL):
"""This class represents a dll exporting functions using the
@@ -415,7 +408,7 @@ if _os.name == "nt":
_type_ = "l"
# _check_retval_ is called with the function's result when it
# is used as restype. It checks for the FAILED bit, and
- # raises an OSError if it is set.
+ # raises a WindowsError if it is set.
#
# The _check_retval_ method is implemented in C, so that the
# method definition itself is not included in the traceback
@@ -427,7 +420,7 @@ if _os.name == "nt":
class OleDLL(CDLL):
"""This class represents a dll exporting functions using the
Windows stdcall calling convention, and returning HRESULT.
- HRESULT error values are automatically raised as OSError
+ HRESULT error values are automatically raised as WindowsError
exceptions.
"""
_func_flags_ = _FUNCFLAG_STDCALL
@@ -453,7 +446,7 @@ class LibraryLoader(object):
cdll = LibraryLoader(CDLL)
pydll = LibraryLoader(PyDLL)
-if _os.name == "nt":
+if _os.name in ("nt", "ce"):
pythonapi = PyDLL("python dll", None, _sys.dllhandle)
elif _sys.platform == "cygwin":
pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
@@ -461,11 +454,14 @@ else:
pythonapi = PyDLL(None)
-if _os.name == "nt":
+if _os.name in ("nt", "ce"):
windll = LibraryLoader(WinDLL)
oledll = LibraryLoader(OleDLL)
- GetLastError = windll.kernel32.GetLastError
+ if _os.name == "nt":
+ GetLastError = windll.kernel32.GetLastError
+ else:
+ GetLastError = windll.coredll.GetLastError
from _ctypes import get_last_error, set_last_error
def WinError(code=None, descr=None):
@@ -473,7 +469,7 @@ if _os.name == "nt":
code = GetLastError()
if descr is None:
descr = FormatError(code).strip()
- return OSError(None, descr, None, code)
+ return WindowsError(code, descr)
if sizeof(c_uint) == sizeof(c_void_p):
c_size_t = c_uint
@@ -526,7 +522,7 @@ else:
return _wstring_at(ptr, size)
-if _os.name == "nt": # COM stuff
+if _os.name in ("nt", "ce"): # COM stuff
def DllGetClassObject(rclsid, riid, ppv):
try:
ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
diff --git a/Lib/ctypes/_aix.py b/Lib/ctypes/_aix.py
deleted file mode 100644
index 190cac6..0000000
--- a/Lib/ctypes/_aix.py
+++ /dev/null
@@ -1,331 +0,0 @@
-"""
-Lib/ctypes.util.find_library() support for AIX
-Similar approach as done for Darwin support by using separate files
-but unlike Darwin - no extension such as ctypes.macholib.*
-
-dlopen() is an interface to AIX initAndLoad() - primary documentation at:
-https://www.ibm.com/support/knowledgecenter/en/ssw_aix_61/com.ibm.aix.basetrf1/dlopen.htm
-https://www.ibm.com/support/knowledgecenter/en/ssw_aix_61/com.ibm.aix.basetrf1/load.htm
-
-AIX supports two styles for dlopen(): svr4 (System V Release 4) which is common on posix
-platforms, but also a BSD style - aka SVR3.
-
-From AIX 5.3 Difference Addendum (December 2004)
-2.9 SVR4 linking affinity
-Nowadays, there are two major object file formats used by the operating systems:
-XCOFF: The COFF enhanced by IBM and others. The original COFF (Common
-Object File Format) was the base of SVR3 and BSD 4.2 systems.
-ELF: Executable and Linking Format that was developed by AT&T and is a
-base for SVR4 UNIX.
-
-While the shared library content is identical on AIX - one is located as a filepath name
-(svr4 style) and the other is located as a member of an archive (and the archive
-is located as a filepath name).
-
-The key difference arises when supporting multiple abi formats (i.e., 32 and 64 bit).
-For svr4 either only one ABI is supported, or there are two directories, or there
-are different file names. The most common solution for multiple ABI is multiple
-directories.
-
-For the XCOFF (aka AIX) style - one directory (one archive file) is sufficient
-as multiple shared libraries can be in the archive - even sharing the same name.
-In documentation the archive is also referred to as the "base" and the shared
-library object is referred to as the "member".
-
-For dlopen() on AIX (read initAndLoad()) the calls are similar.
-Default activity occurs when no path information is provided. When path
-information is provided dlopen() does not search any other directories.
-
-For SVR4 - the shared library name is the name of the file expected: libFOO.so
-For AIX - the shared library is expressed as base(member). The search is for the
-base (e.g., libFOO.a) and once the base is found the shared library - identified by
-member (e.g., libFOO.so, or shr.o) is located and loaded.
-
-The mode bit RTLD_MEMBER tells initAndLoad() that it needs to use the AIX (SVR3)
-naming style.
-"""
-__author__ = "Michael Felt <aixtools@felt.demon.nl>"
-
-import re
-from os import environ, path
-from sys import executable
-from ctypes import c_void_p, sizeof
-from subprocess import Popen, PIPE, DEVNULL
-
-# Executable bit size - 32 or 64
-# Used to filter the search in an archive by size, e.g., -X64
-AIX_ABI = sizeof(c_void_p) * 8
-
-
-from sys import maxsize
-def _last_version(libnames, sep):
- def _num_version(libname):
- # "libxyz.so.MAJOR.MINOR" => [MAJOR, MINOR]
- parts = libname.split(sep)
- nums = []
- try:
- while parts:
- nums.insert(0, int(parts.pop()))
- except ValueError:
- pass
- return nums or [maxsize]
- return max(reversed(libnames), key=_num_version)
-
-def get_ld_header(p):
- # "nested-function, but placed at module level
- ld_header = None
- for line in p.stdout:
- if line.startswith(('/', './', '../')):
- ld_header = line
- elif "INDEX" in line:
- return ld_header.rstrip('\n')
- return None
-
-def get_ld_header_info(p):
- # "nested-function, but placed at module level
- # as an ld_header was found, return known paths, archives and members
- # these lines start with a digit
- info = []
- for line in p.stdout:
- if re.match("[0-9]", line):
- info.append(line)
- else:
- # blank line (separator), consume line and end for loop
- break
- return info
-
-def get_ld_headers(file):
- """
- Parse the header of the loader section of executable and archives
- This function calls /usr/bin/dump -H as a subprocess
- and returns a list of (ld_header, ld_header_info) tuples.
- """
- # get_ld_headers parsing:
- # 1. Find a line that starts with /, ./, or ../ - set as ld_header
- # 2. If "INDEX" in occurs in a following line - return ld_header
- # 3. get info (lines starting with [0-9])
- ldr_headers = []
- p = Popen(["/usr/bin/dump", f"-X{AIX_ABI}", "-H", file],
- universal_newlines=True, stdout=PIPE, stderr=DEVNULL)
- # be sure to read to the end-of-file - getting all entries
- while True:
- ld_header = get_ld_header(p)
- if ld_header:
- ldr_headers.append((ld_header, get_ld_header_info(p)))
- else:
- break
- p.stdout.close()
- p.wait()
- return ldr_headers
-
-def get_shared(ld_headers):
- """
- extract the shareable objects from ld_headers
- character "[" is used to strip off the path information.
- Note: the "[" and "]" characters that are part of dump -H output
- are not removed here.
- """
- shared = []
- for (line, _) in ld_headers:
- # potential member lines contain "["
- # otherwise, no processing needed
- if "[" in line:
- # Strip off trailing colon (:)
- shared.append(line[line.index("["):-1])
- return shared
-
-def get_one_match(expr, lines):
- """
- Must be only one match, otherwise result is None.
- When there is a match, strip leading "[" and trailing "]"
- """
- # member names in the ld_headers output are between square brackets
- expr = rf'\[({expr})\]'
- matches = list(filter(None, (re.search(expr, line) for line in lines)))
- if len(matches) == 1:
- return matches[0].group(1)
- else:
- return None
-
-# additional processing to deal with AIX legacy names for 64-bit members
-def get_legacy(members):
- """
- This routine provides historical aka legacy naming schemes started
- in AIX4 shared library support for library members names.
- e.g., in /usr/lib/libc.a the member name shr.o for 32-bit binary and
- shr_64.o for 64-bit binary.
- """
- if AIX_ABI == 64:
- # AIX 64-bit member is one of shr64.o, shr_64.o, or shr4_64.o
- expr = r'shr4?_?64\.o'
- member = get_one_match(expr, members)
- if member:
- return member
- else:
- # 32-bit legacy names - both shr.o and shr4.o exist.
- # shr.o is the preffered name so we look for shr.o first
- # i.e., shr4.o is returned only when shr.o does not exist
- for name in ['shr.o', 'shr4.o']:
- member = get_one_match(re.escape(name), members)
- if member:
- return member
- return None
-
-def get_version(name, members):
- """
- Sort list of members and return highest numbered version - if it exists.
- This function is called when an unversioned libFOO.a(libFOO.so) has
- not been found.
-
- Versioning for the member name is expected to follow
- GNU LIBTOOL conventions: the highest version (x, then X.y, then X.Y.z)
- * find [libFoo.so.X]
- * find [libFoo.so.X.Y]
- * find [libFoo.so.X.Y.Z]
-
- Before the GNU convention became the standard scheme regardless of
- binary size AIX packagers used GNU convention "as-is" for 32-bit
- archive members but used an "distinguishing" name for 64-bit members.
- This scheme inserted either 64 or _64 between libFOO and .so
- - generally libFOO_64.so, but occasionally libFOO64.so
- """
- # the expression ending for versions must start as
- # '.so.[0-9]', i.e., *.so.[at least one digit]
- # while multiple, more specific expressions could be specified
- # to search for .so.X, .so.X.Y and .so.X.Y.Z
- # after the first required 'dot' digit
- # any combination of additional 'dot' digits pairs are accepted
- # anything more than libFOO.so.digits.digits.digits
- # should be seen as a member name outside normal expectations
- exprs = [rf'lib{name}\.so\.[0-9]+[0-9.]*',
- rf'lib{name}_?64\.so\.[0-9]+[0-9.]*']
- for expr in exprs:
- versions = []
- for line in members:
- m = re.search(expr, line)
- if m:
- versions.append(m.group(0))
- if versions:
- return _last_version(versions, '.')
- return None
-
-def get_member(name, members):
- """
- Return an archive member matching the request in name.
- Name is the library name without any prefix like lib, suffix like .so,
- or version number.
- Given a list of members find and return the most appropriate result
- Priority is given to generic libXXX.so, then a versioned libXXX.so.a.b.c
- and finally, legacy AIX naming scheme.
- """
- # look first for a generic match - prepend lib and append .so
- expr = rf'lib{name}\.so'
- member = get_one_match(expr, members)
- if member:
- return member
- elif AIX_ABI == 64:
- expr = rf'lib{name}64\.so'
- member = get_one_match(expr, members)
- if member:
- return member
- # since an exact match with .so as suffix was not found
- # look for a versioned name
- # If a versioned name is not found, look for AIX legacy member name
- member = get_version(name, members)
- if member:
- return member
- else:
- return get_legacy(members)
-
-def get_libpaths():
- """
- On AIX, the buildtime searchpath is stored in the executable.
- as "loader header information".
- The command /usr/bin/dump -H extracts this info.
- Prefix searched libraries with LD_LIBRARY_PATH (preferred),
- or LIBPATH if defined. These paths are appended to the paths
- to libraries the python executable is linked with.
- This mimics AIX dlopen() behavior.
- """
- libpaths = environ.get("LD_LIBRARY_PATH")
- if libpaths is None:
- libpaths = environ.get("LIBPATH")
- if libpaths is None:
- libpaths = []
- else:
- libpaths = libpaths.split(":")
- objects = get_ld_headers(executable)
- for (_, lines) in objects:
- for line in lines:
- # the second (optional) argument is PATH if it includes a /
- path = line.split()[1]
- if "/" in path:
- libpaths.extend(path.split(":"))
- return libpaths
-
-def find_shared(paths, name):
- """
- paths is a list of directories to search for an archive.
- name is the abbreviated name given to find_library().
- Process: search "paths" for archive, and if an archive is found
- return the result of get_member().
- If an archive is not found then return None
- """
- for dir in paths:
- # /lib is a symbolic link to /usr/lib, skip it
- if dir == "/lib":
- continue
- # "lib" is prefixed to emulate compiler name resolution,
- # e.g., -lc to libc
- base = f'lib{name}.a'
- archive = path.join(dir, base)
- if path.exists(archive):
- members = get_shared(get_ld_headers(archive))
- member = get_member(re.escape(name), members)
- if member != None:
- return (base, member)
- else:
- return (None, None)
- return (None, None)
-
-def find_library(name):
- """AIX implementation of ctypes.util.find_library()
- Find an archive member that will dlopen(). If not available,
- also search for a file (or link) with a .so suffix.
-
- AIX supports two types of schemes that can be used with dlopen().
- The so-called SystemV Release4 (svr4) format is commonly suffixed
- with .so while the (default) AIX scheme has the library (archive)
- ending with the suffix .a
- As an archive has multiple members (e.g., 32-bit and 64-bit) in one file
- the argument passed to dlopen must include both the library and
- the member names in a single string.
-
- find_library() looks first for an archive (.a) with a suitable member.
- If no archive+member pair is found, look for a .so file.
- """
-
- libpaths = get_libpaths()
- (base, member) = find_shared(libpaths, name)
- if base != None:
- return f"{base}({member})"
-
- # To get here, a member in an archive has not been found
- # In other words, either:
- # a) a .a file was not found
- # b) a .a file did not have a suitable member
- # So, look for a .so file
- # Check libpaths for .so file
- # Note, the installation must prepare a link from a .so
- # to a versioned file
- # This is common practice by GNU libtool on other platforms
- soname = f"lib{name}.so"
- for dir in libpaths:
- # /lib is a symbolic link to /usr/lib, skip it
- if dir == "/lib":
- continue
- shlib = path.join(dir, soname)
- if path.exists(shlib):
- return soname
- # if we are here, we have not found anything plausible
- return None
diff --git a/Lib/ctypes/_endian.py b/Lib/ctypes/_endian.py
index 37444bd..c0ba646 100644
--- a/Lib/ctypes/_endian.py
+++ b/Lib/ctypes/_endian.py
@@ -30,7 +30,7 @@ class _swapped_meta(type(Structure)):
rest = desc[2:]
fields.append((name, _other_endian(typ)) + rest)
value = fields
- super().__setattr__(attrname, value)
+ super(_swapped_meta, self).__setattr__(attrname, value)
################################################################
@@ -43,18 +43,18 @@ if sys.byteorder == "little":
LittleEndianStructure = Structure
- class BigEndianStructure(Structure, metaclass=_swapped_meta):
+ class BigEndianStructure(Structure):
"""Structure with big endian byte order"""
- __slots__ = ()
+ __metaclass__ = _swapped_meta
_swappedbytes_ = None
elif sys.byteorder == "big":
_OTHER_ENDIAN = "__ctype_le__"
BigEndianStructure = Structure
- class LittleEndianStructure(Structure, metaclass=_swapped_meta):
+ class LittleEndianStructure(Structure):
"""Structure with little endian byte order"""
- __slots__ = ()
+ __metaclass__ = _swapped_meta
_swappedbytes_ = None
else:
diff --git a/Lib/ctypes/macholib/dyld.py b/Lib/ctypes/macholib/dyld.py
index 9d86b05..1fdf8d6 100644
--- a/Lib/ctypes/macholib/dyld.py
+++ b/Lib/ctypes/macholib/dyld.py
@@ -3,8 +3,8 @@ dyld emulation
"""
import os
-from ctypes.macholib.framework import framework_info
-from ctypes.macholib.dylib import dylib_info
+from framework import framework_info
+from dylib import dylib_info
from itertools import *
__all__ = [
@@ -28,6 +28,12 @@ DEFAULT_LIBRARY_FALLBACK = [
"/usr/lib",
]
+def ensure_utf8(s):
+ """Not all of PyObjC and Python understand unicode paths very well yet"""
+ if isinstance(s, unicode):
+ return s.encode('utf8')
+ return s
+
def dyld_env(env, var):
if env is None:
env = os.environ
@@ -117,6 +123,8 @@ def dyld_find(name, executable_path=None, env=None):
"""
Find a library or framework using dyld semantics
"""
+ name = ensure_utf8(name)
+ executable_path = ensure_utf8(executable_path)
for path in dyld_image_suffix_search(chain(
dyld_override_search(name, env),
dyld_executable_path_search(name, executable_path),
@@ -135,11 +143,10 @@ def framework_find(fn, executable_path=None, env=None):
Python.framework
Python.framework/Versions/Current
"""
- error = None
try:
return dyld_find(fn, executable_path=executable_path, env=env)
- except ValueError as e:
- error = e
+ except ValueError, e:
+ pass
fmwk_index = fn.rfind('.framework')
if fmwk_index == -1:
fmwk_index = len(fn)
@@ -148,9 +155,7 @@ def framework_find(fn, executable_path=None, env=None):
try:
return dyld_find(fn, executable_path=executable_path, env=env)
except ValueError:
- raise error
- finally:
- error = None
+ raise e
def test_dyld_find():
env = {}
diff --git a/Lib/ctypes/test/__init__.py b/Lib/ctypes/test/__init__.py
index 26a70b7..f2cc143 100644
--- a/Lib/ctypes/test/__init__.py
+++ b/Lib/ctypes/test/__init__.py
@@ -1,14 +1,216 @@
-import os
-import unittest
-from test import support
+import os, sys, unittest, getopt, time
-# skip tests if _ctypes was not built
-ctypes = support.import_module('ctypes')
+use_resources = []
+
+import ctypes
ctypes_symbols = dir(ctypes)
def need_symbol(name):
return unittest.skipUnless(name in ctypes_symbols,
'{!r} is required'.format(name))
-def load_tests(*args):
- return support.load_package_tests(os.path.dirname(__file__), *args)
+
+class ResourceDenied(unittest.SkipTest):
+ """Test skipped because it requested a disallowed resource.
+
+ This is raised when a test calls requires() for a resource that
+ has not be enabled. Resources are defined by test modules.
+ """
+
+def is_resource_enabled(resource):
+ """Test whether a resource is enabled.
+
+ If the caller's module is __main__ then automatically return True."""
+ if sys._getframe().f_back.f_globals.get("__name__") == "__main__":
+ return True
+ result = use_resources is not None and \
+ (resource in use_resources or "*" in use_resources)
+ if not result:
+ _unavail[resource] = None
+ return result
+
+_unavail = {}
+def requires(resource, msg=None):
+ """Raise ResourceDenied if the specified resource is not available.
+
+ If the caller's module is __main__ then automatically return True."""
+ # see if the caller's module is __main__ - if so, treat as if
+ # the resource was set
+ if sys._getframe().f_back.f_globals.get("__name__") == "__main__":
+ return
+ if not is_resource_enabled(resource):
+ if msg is None:
+ msg = "Use of the `%s' resource not enabled" % resource
+ raise ResourceDenied(msg)
+
+def find_package_modules(package, mask):
+ import fnmatch
+ if (hasattr(package, "__loader__") and
+ hasattr(package.__loader__, '_files')):
+ path = package.__name__.replace(".", os.path.sep)
+ mask = os.path.join(path, mask)
+ for fnm in package.__loader__._files.iterkeys():
+ if fnmatch.fnmatchcase(fnm, mask):
+ yield os.path.splitext(fnm)[0].replace(os.path.sep, ".")
+ else:
+ path = package.__path__[0]
+ for fnm in os.listdir(path):
+ if fnmatch.fnmatchcase(fnm, mask):
+ yield "%s.%s" % (package.__name__, os.path.splitext(fnm)[0])
+
+def get_tests(package, mask, verbosity, exclude=()):
+ """Return a list of skipped test modules, and a list of test cases."""
+ tests = []
+ skipped = []
+ for modname in find_package_modules(package, mask):
+ if modname.split(".")[-1] in exclude:
+ skipped.append(modname)
+ if verbosity > 1:
+ print >> sys.stderr, "Skipped %s: excluded" % modname
+ continue
+ try:
+ mod = __import__(modname, globals(), locals(), ['*'])
+ except (ResourceDenied, unittest.SkipTest) as detail:
+ skipped.append(modname)
+ if verbosity > 1:
+ print >> sys.stderr, "Skipped %s: %s" % (modname, detail)
+ continue
+ for name in dir(mod):
+ if name.startswith("_"):
+ continue
+ o = getattr(mod, name)
+ if type(o) is type(unittest.TestCase) and issubclass(o, unittest.TestCase):
+ tests.append(o)
+ return skipped, tests
+
+def usage():
+ print __doc__
+ return 1
+
+def test_with_refcounts(runner, verbosity, testcase):
+ """Run testcase several times, tracking reference counts."""
+ import gc
+ import ctypes
+ ptc = ctypes._pointer_type_cache.copy()
+ cfc = ctypes._c_functype_cache.copy()
+ wfc = ctypes._win_functype_cache.copy()
+
+ # when searching for refcount leaks, we have to manually reset any
+ # caches that ctypes has.
+ def cleanup():
+ ctypes._pointer_type_cache = ptc.copy()
+ ctypes._c_functype_cache = cfc.copy()
+ ctypes._win_functype_cache = wfc.copy()
+ gc.collect()
+
+ test = unittest.makeSuite(testcase)
+ for i in range(5):
+ rc = sys.gettotalrefcount()
+ runner.run(test)
+ cleanup()
+ COUNT = 5
+ refcounts = [None] * COUNT
+ for i in range(COUNT):
+ rc = sys.gettotalrefcount()
+ runner.run(test)
+ cleanup()
+ refcounts[i] = sys.gettotalrefcount() - rc
+ if filter(None, refcounts):
+ print "%s leaks:\n\t" % testcase, refcounts
+ elif verbosity:
+ print "%s: ok." % testcase
+
+class TestRunner(unittest.TextTestRunner):
+ def run(self, test, skipped):
+ "Run the given test case or test suite."
+ # Same as unittest.TextTestRunner.run, except that it reports
+ # skipped tests.
+ result = self._makeResult()
+ startTime = time.time()
+ test(result)
+ stopTime = time.time()
+ timeTaken = stopTime - startTime
+ result.printErrors()
+ self.stream.writeln(result.separator2)
+ run = result.testsRun
+ if _unavail: #skipped:
+ requested = _unavail.keys()
+ requested.sort()
+ self.stream.writeln("Ran %d test%s in %.3fs (%s module%s skipped)" %
+ (run, run != 1 and "s" or "", timeTaken,
+ len(skipped),
+ len(skipped) != 1 and "s" or ""))
+ self.stream.writeln("Unavailable resources: %s" % ", ".join(requested))
+ else:
+ self.stream.writeln("Ran %d test%s in %.3fs" %
+ (run, run != 1 and "s" or "", timeTaken))
+ self.stream.writeln()
+ if not result.wasSuccessful():
+ self.stream.write("FAILED (")
+ failed, errored = map(len, (result.failures, result.errors))
+ if failed:
+ self.stream.write("failures=%d" % failed)
+ if errored:
+ if failed: self.stream.write(", ")
+ self.stream.write("errors=%d" % errored)
+ self.stream.writeln(")")
+ else:
+ self.stream.writeln("OK")
+ return result
+
+
+def main(*packages):
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "rqvu:x:")
+ except getopt.error:
+ return usage()
+
+ verbosity = 1
+ search_leaks = False
+ exclude = []
+ for flag, value in opts:
+ if flag == "-q":
+ verbosity -= 1
+ elif flag == "-v":
+ verbosity += 1
+ elif flag == "-r":
+ try:
+ sys.gettotalrefcount
+ except AttributeError:
+ print >> sys.stderr, "-r flag requires Python debug build"
+ return -1
+ search_leaks = True
+ elif flag == "-u":
+ use_resources.extend(value.split(","))
+ elif flag == "-x":
+ exclude.extend(value.split(","))
+
+ mask = "test_*.py"
+ if args:
+ mask = args[0]
+
+ for package in packages:
+ run_tests(package, mask, verbosity, search_leaks, exclude)
+
+
+def run_tests(package, mask, verbosity, search_leaks, exclude):
+ skipped, testcases = get_tests(package, mask, verbosity, exclude)
+ runner = TestRunner(verbosity=verbosity)
+
+ suites = [unittest.makeSuite(o) for o in testcases]
+ suite = unittest.TestSuite(suites)
+ result = runner.run(suite, skipped)
+
+ if search_leaks:
+ # hunt for refcount leaks
+ runner = BasicTestRunner()
+ for t in testcases:
+ test_with_refcounts(runner, verbosity, t)
+
+ return bool(result.errors)
+
+class BasicTestRunner:
+ def run(self, test):
+ result = unittest.TestResult()
+ test(result)
+ return result
diff --git a/Lib/ctypes/test/__main__.py b/Lib/ctypes/test/__main__.py
deleted file mode 100644
index 362a9ec..0000000
--- a/Lib/ctypes/test/__main__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from ctypes.test import load_tests
-import unittest
-
-unittest.main()
diff --git a/Lib/ctypes/test/runtests.py b/Lib/ctypes/test/runtests.py
new file mode 100644
index 0000000..b7a2b26
--- /dev/null
+++ b/Lib/ctypes/test/runtests.py
@@ -0,0 +1,19 @@
+"""Usage: runtests.py [-q] [-r] [-v] [-u resources] [mask]
+
+Run all tests found in this directory, and print a summary of the results.
+Command line flags:
+ -q quiet mode: don't print anything while the tests are running
+ -r run tests repeatedly, look for refcount leaks
+ -u<resources>
+ Add resources to the lits of allowed resources. '*' allows all
+ resources.
+ -v verbose mode: print the test currently executed
+ -x<test1[,test2...]>
+ Exclude specified tests.
+ mask mask to select filenames containing testcases, wildcards allowed
+"""
+import sys
+import ctypes.test
+
+if __name__ == "__main__":
+ sys.exit(ctypes.test.main(ctypes.test))
diff --git a/Lib/ctypes/test/test_anon.py b/Lib/ctypes/test/test_anon.py
index d378392..2c28b7f 100644
--- a/Lib/ctypes/test/test_anon.py
+++ b/Lib/ctypes/test/test_anon.py
@@ -1,5 +1,5 @@
import unittest
-import test.support
+from test.support import cpython_only
from ctypes import *
class AnonTest(unittest.TestCase):
@@ -36,7 +36,7 @@ class AnonTest(unittest.TestCase):
{"_fields_": [],
"_anonymous_": ["x"]}))
- @test.support.cpython_only
+ @cpython_only
def test_issue31490(self):
# There shouldn't be an assertion failure in case the class has an
# attribute whose name is specified in _anonymous_ but not in _fields_.
diff --git a/Lib/ctypes/test/test_array_in_pointer.py b/Lib/ctypes/test/test_array_in_pointer.py
index ca1edcf..ee7863c 100644
--- a/Lib/ctypes/test/test_array_in_pointer.py
+++ b/Lib/ctypes/test/test_array_in_pointer.py
@@ -6,7 +6,7 @@ import re
def dump(obj):
# helper function to dump memory contents in hex, with a hyphen
# between the bytes.
- h = hexlify(memoryview(obj)).decode()
+ h = hexlify(memoryview(obj))
return re.sub(r"(..)", r"\1-", h)[:-1]
diff --git a/Lib/ctypes/test/test_arrays.py b/Lib/ctypes/test/test_arrays.py
index 14603b7..ec00d9f 100644
--- a/Lib/ctypes/test/test_arrays.py
+++ b/Lib/ctypes/test/test_arrays.py
@@ -1,5 +1,5 @@
import unittest
-from test.support import bigmemtest, _2G
+from test.support import precisionbigmemtest, _2G
import sys
from ctypes import *
@@ -15,7 +15,7 @@ class ArrayTestCase(unittest.TestCase):
# create classes holding simple numeric types, and check
# various properties.
- init = list(range(15, 25))
+ init = range(15, 25)
for fmt in formats:
alen = len(init)
@@ -35,7 +35,7 @@ class ArrayTestCase(unittest.TestCase):
# change the items
from operator import setitem
- new_values = list(range(42, 42+alen))
+ new_values = range(42, 42+alen)
[setitem(ia, n, new_values[n]) for n in range(alen)]
values = [ia[i] for i in range(alen)]
self.assertEqual(values, new_values)
@@ -50,36 +50,28 @@ class ArrayTestCase(unittest.TestCase):
CharArray = ARRAY(c_char, 3)
- ca = CharArray(b"a", b"b", b"c")
+ ca = CharArray("a", "b", "c")
# Should this work? It doesn't:
# CharArray("abc")
self.assertRaises(TypeError, CharArray, "abc")
- self.assertEqual(ca[0], b"a")
- self.assertEqual(ca[1], b"b")
- self.assertEqual(ca[2], b"c")
- self.assertEqual(ca[-3], b"a")
- self.assertEqual(ca[-2], b"b")
- self.assertEqual(ca[-1], b"c")
+ self.assertEqual(ca[0], "a")
+ self.assertEqual(ca[1], "b")
+ self.assertEqual(ca[2], "c")
+ self.assertEqual(ca[-3], "a")
+ self.assertEqual(ca[-2], "b")
+ self.assertEqual(ca[-1], "c")
self.assertEqual(len(ca), 3)
+ # slicing is now supported, but not extended slicing (3-argument)!
+ from operator import getslice, delitem
+ self.assertRaises(TypeError, getslice, ca, 0, 1, -1)
+
# cannot delete items
- from operator import delitem
self.assertRaises(TypeError, delitem, ca, 0)
- def test_step_overflow(self):
- a = (c_int * 5)()
- a[3::sys.maxsize] = (1,)
- self.assertListEqual(a[3::sys.maxsize], [1])
- a = (c_char * 5)()
- a[3::sys.maxsize] = b"A"
- self.assertEqual(a[3::sys.maxsize], b"A")
- a = (c_wchar * 5)()
- a[3::sys.maxsize] = u"X"
- self.assertEqual(a[3::sys.maxsize], u"X")
-
def test_numeric_arrays(self):
alen = 5
@@ -108,14 +100,14 @@ class ArrayTestCase(unittest.TestCase):
def test_from_address(self):
# Failed with 0.9.8, reported by JUrner
- p = create_string_buffer(b"foo")
+ p = create_string_buffer("foo")
sz = (c_char * 3).from_address(addressof(p))
- self.assertEqual(sz[:], b"foo")
- self.assertEqual(sz[::], b"foo")
- self.assertEqual(sz[::-1], b"oof")
- self.assertEqual(sz[::3], b"f")
- self.assertEqual(sz[1:4:2], b"o")
- self.assertEqual(sz.value, b"foo")
+ self.assertEqual(sz[:], "foo")
+ self.assertEqual(sz[::], "foo")
+ self.assertEqual(sz[::-1], "oof")
+ self.assertEqual(sz[::3], "f")
+ self.assertEqual(sz[1:4:2], "o")
+ self.assertEqual(sz.value, "foo")
@need_symbol('create_unicode_buffer')
def test_from_addressW(self):
@@ -142,72 +134,6 @@ class ArrayTestCase(unittest.TestCase):
t2 = my_int * 1
self.assertIs(t1, t2)
- def test_subclass(self):
- class T(Array):
- _type_ = c_int
- _length_ = 13
- class U(T):
- pass
- class V(U):
- pass
- class W(V):
- pass
- class X(T):
- _type_ = c_short
- class Y(T):
- _length_ = 187
-
- for c in [T, U, V, W]:
- self.assertEqual(c._type_, c_int)
- self.assertEqual(c._length_, 13)
- self.assertEqual(c()._type_, c_int)
- self.assertEqual(c()._length_, 13)
-
- self.assertEqual(X._type_, c_short)
- self.assertEqual(X._length_, 13)
- self.assertEqual(X()._type_, c_short)
- self.assertEqual(X()._length_, 13)
-
- self.assertEqual(Y._type_, c_int)
- self.assertEqual(Y._length_, 187)
- self.assertEqual(Y()._type_, c_int)
- self.assertEqual(Y()._length_, 187)
-
- def test_bad_subclass(self):
- with self.assertRaises(AttributeError):
- class T(Array):
- pass
- with self.assertRaises(AttributeError):
- class T(Array):
- _type_ = c_int
- with self.assertRaises(AttributeError):
- class T(Array):
- _length_ = 13
-
- def test_bad_length(self):
- with self.assertRaises(ValueError):
- class T(Array):
- _type_ = c_int
- _length_ = - sys.maxsize * 2
- with self.assertRaises(ValueError):
- class T(Array):
- _type_ = c_int
- _length_ = -1
- with self.assertRaises(TypeError):
- class T(Array):
- _type_ = c_int
- _length_ = 1.87
- with self.assertRaises(OverflowError):
- class T(Array):
- _type_ = c_int
- _length_ = sys.maxsize * 2
-
- def test_zero_length(self):
- # _length_ can be zero.
- class T(Array):
- _type_ = c_int
- _length_ = 0
-
def test_empty_element_struct(self):
class EmptyStruct(Structure):
_fields_ = []
@@ -230,9 +156,9 @@ class ArrayTestCase(unittest.TestCase):
c_char * sys.maxsize * 2
@unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
- @bigmemtest(size=_2G, memuse=1, dry_run=False)
+ @precisionbigmemtest(size=_2G, memuse=1, dry_run=False)
def test_large_array(self, size):
- c_char * size
+ a = c_char * size
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/ctypes/test/test_as_parameter.py b/Lib/ctypes/test/test_as_parameter.py
index f9d27cb..de730e9 100644
--- a/Lib/ctypes/test/test_as_parameter.py
+++ b/Lib/ctypes/test/test_as_parameter.py
@@ -22,7 +22,7 @@ class BasicWrapTestCase(unittest.TestCase):
def test_wchar_parm(self):
f = dll._testfunc_i_bhilfd
f.argtypes = [c_byte, c_wchar, c_int, c_long, c_float, c_double]
- result = f(self.wrap(1), self.wrap("x"), self.wrap(3), self.wrap(4), self.wrap(5.0), self.wrap(6.0))
+ result = f(self.wrap(1), self.wrap(u"x"), self.wrap(3), self.wrap(4), self.wrap(5.0), self.wrap(6.0))
self.assertEqual(result, 139)
self.assertIs(type(result), int)
@@ -132,7 +132,7 @@ class BasicWrapTestCase(unittest.TestCase):
f.argtypes = [c_longlong, MyCallback]
def callback(value):
- self.assertIsInstance(value, int)
+ self.assertIsInstance(value, (int, long))
return value & 0x7FFFFFFF
cb = MyCallback(callback)
@@ -169,10 +169,6 @@ class BasicWrapTestCase(unittest.TestCase):
s2h = dll.ret_2h_func(self.wrap(inp))
self.assertEqual((s2h.x, s2h.y), (99*2, 88*3))
- # Test also that the original struct was unmodified (i.e. was passed by
- # value)
- self.assertEqual((inp.x, inp.y), (99, 88))
-
def test_struct_return_8H(self):
class S8I(Structure):
_fields_ = [("a", c_int),
@@ -198,7 +194,7 @@ class BasicWrapTestCase(unittest.TestCase):
a = A()
a._as_parameter_ = a
- with self.assertRaises(RecursionError):
+ with self.assertRaises(RuntimeError):
c_int.from_param(a)
diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/ctypes/test/test_bitfields.py
index 992b8c4..a854d2b 100644
--- a/Lib/ctypes/test/test_bitfields.py
+++ b/Lib/ctypes/test/test_bitfields.py
@@ -3,6 +3,7 @@ from ctypes.test import need_symbol
import unittest
import os
+import ctypes
import _ctypes_test
class BITS(Structure):
@@ -37,18 +38,14 @@ class C_Test(unittest.TestCase):
for name in "ABCDEFGHI":
b = BITS()
setattr(b, name, i)
- self.assertEqual(getattr(b, name), func(byref(b), name.encode('ascii')))
+ self.assertEqual((name, i, getattr(b, name)), (name, i, func(byref(b), name)))
def test_shorts(self):
- b = BITS()
- name = "M"
- if func(byref(b), name.encode('ascii')) == 999:
- self.skipTest("Compiler does not support signed short bitfields")
for i in range(256):
for name in "MNOPQRS":
b = BITS()
setattr(b, name, i)
- self.assertEqual(getattr(b, name), func(byref(b), name.encode('ascii')))
+ self.assertEqual((name, i, getattr(b, name)), (name, i, func(byref(b), name)))
signed_int_types = (c_byte, c_short, c_int, c_long, c_longlong)
unsigned_int_types = (c_ubyte, c_ushort, c_uint, c_ulong, c_ulonglong)
@@ -193,14 +190,14 @@ class BitFieldTest(unittest.TestCase):
def get_except(self, func, *args, **kw):
try:
func(*args, **kw)
- except Exception as detail:
+ except Exception, detail:
return detail.__class__, str(detail)
def test_mixed_1(self):
class X(Structure):
_fields_ = [("a", c_byte, 4),
("b", c_int, 4)]
- if os.name == "nt":
+ if os.name in ("nt", "ce"):
self.assertEqual(sizeof(X), sizeof(c_int)*2)
else:
self.assertEqual(sizeof(X), sizeof(c_int))
@@ -228,7 +225,7 @@ class BitFieldTest(unittest.TestCase):
# MSVC does NOT combine c_short and c_int into one field, GCC
# does (unless GCC is run with '-mms-bitfields' which
# produces code compatible with MSVC).
- if os.name == "nt":
+ if os.name in ("nt", "ce"):
self.assertEqual(sizeof(X), sizeof(c_int) * 4)
else:
self.assertEqual(sizeof(X), sizeof(c_int) * 2)
diff --git a/Lib/ctypes/test/test_buffers.py b/Lib/ctypes/test/test_buffers.py
index 15782be..88d87e9 100644
--- a/Lib/ctypes/test/test_buffers.py
+++ b/Lib/ctypes/test/test_buffers.py
@@ -8,66 +8,65 @@ class StringBufferTestCase(unittest.TestCase):
b = create_string_buffer(32)
self.assertEqual(len(b), 32)
self.assertEqual(sizeof(b), 32 * sizeof(c_char))
- self.assertIs(type(b[0]), bytes)
+ self.assertIs(type(b[0]), str)
- b = create_string_buffer(b"abc")
+ b = create_string_buffer("abc")
self.assertEqual(len(b), 4) # trailing nul char
self.assertEqual(sizeof(b), 4 * sizeof(c_char))
- self.assertIs(type(b[0]), bytes)
- self.assertEqual(b[0], b"a")
- self.assertEqual(b[:], b"abc\0")
- self.assertEqual(b[::], b"abc\0")
- self.assertEqual(b[::-1], b"\0cba")
- self.assertEqual(b[::2], b"ac")
- self.assertEqual(b[::5], b"a")
-
- self.assertRaises(TypeError, create_string_buffer, "abc")
+ self.assertIs(type(b[0]), str)
+ self.assertEqual(b[0], "a")
+ self.assertEqual(b[:], "abc\0")
+ self.assertEqual(b[::], "abc\0")
+ self.assertEqual(b[::-1], "\0cba")
+ self.assertEqual(b[::2], "ac")
+ self.assertEqual(b[::5], "a")
def test_buffer_interface(self):
self.assertEqual(len(bytearray(create_string_buffer(0))), 0)
self.assertEqual(len(bytearray(create_string_buffer(1))), 1)
+ def test_string_conversion(self):
+ b = create_string_buffer(u"abc")
+ self.assertEqual(len(b), 4) # trailing nul char
+ self.assertEqual(sizeof(b), 4 * sizeof(c_char))
+ self.assertTrue(type(b[0]) is str)
+ self.assertEqual(b[0], "a")
+ self.assertEqual(b[:], "abc\0")
+ self.assertEqual(b[::], "abc\0")
+ self.assertEqual(b[::-1], "\0cba")
+ self.assertEqual(b[::2], "ac")
+ self.assertEqual(b[::5], "a")
+
@need_symbol('c_wchar')
def test_unicode_buffer(self):
b = create_unicode_buffer(32)
self.assertEqual(len(b), 32)
self.assertEqual(sizeof(b), 32 * sizeof(c_wchar))
- self.assertIs(type(b[0]), str)
+ self.assertIs(type(b[0]), unicode)
- b = create_unicode_buffer("abc")
+ b = create_unicode_buffer(u"abc")
self.assertEqual(len(b), 4) # trailing nul char
self.assertEqual(sizeof(b), 4 * sizeof(c_wchar))
- self.assertIs(type(b[0]), str)
- self.assertEqual(b[0], "a")
+ self.assertIs(type(b[0]), unicode)
+ self.assertEqual(b[0], u"a")
self.assertEqual(b[:], "abc\0")
self.assertEqual(b[::], "abc\0")
self.assertEqual(b[::-1], "\0cba")
self.assertEqual(b[::2], "ac")
self.assertEqual(b[::5], "a")
- self.assertRaises(TypeError, create_unicode_buffer, b"abc")
-
@need_symbol('c_wchar')
def test_unicode_conversion(self):
b = create_unicode_buffer("abc")
self.assertEqual(len(b), 4) # trailing nul char
self.assertEqual(sizeof(b), 4 * sizeof(c_wchar))
- self.assertIs(type(b[0]), str)
- self.assertEqual(b[0], "a")
+ self.assertIs(type(b[0]), unicode)
+ self.assertEqual(b[0], u"a")
self.assertEqual(b[:], "abc\0")
self.assertEqual(b[::], "abc\0")
self.assertEqual(b[::-1], "\0cba")
self.assertEqual(b[::2], "ac")
self.assertEqual(b[::5], "a")
- @need_symbol('c_wchar')
- def test_create_unicode_buffer_non_bmp(self):
- expected = 5 if sizeof(c_wchar) == 2 else 3
- for s in '\U00010000\U00100000', '\U00010000\U0010ffff':
- b = create_unicode_buffer(s)
- self.assertEqual(len(b), expected)
- self.assertEqual(b[-1], '\0')
-
-
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_bytes.py b/Lib/ctypes/test/test_bytes.py
deleted file mode 100644
index 092ec5a..0000000
--- a/Lib/ctypes/test/test_bytes.py
+++ /dev/null
@@ -1,66 +0,0 @@
-"""Test where byte objects are accepted"""
-import unittest
-import sys
-from ctypes import *
-
-class BytesTest(unittest.TestCase):
- def test_c_char(self):
- x = c_char(b"x")
- self.assertRaises(TypeError, c_char, "x")
- x.value = b"y"
- with self.assertRaises(TypeError):
- x.value = "y"
- c_char.from_param(b"x")
- self.assertRaises(TypeError, c_char.from_param, "x")
- self.assertIn('xbd', repr(c_char.from_param(b"\xbd")))
- (c_char * 3)(b"a", b"b", b"c")
- self.assertRaises(TypeError, c_char * 3, "a", "b", "c")
-
- def test_c_wchar(self):
- x = c_wchar("x")
- self.assertRaises(TypeError, c_wchar, b"x")
- x.value = "y"
- with self.assertRaises(TypeError):
- x.value = b"y"
- c_wchar.from_param("x")
- self.assertRaises(TypeError, c_wchar.from_param, b"x")
- (c_wchar * 3)("a", "b", "c")
- self.assertRaises(TypeError, c_wchar * 3, b"a", b"b", b"c")
-
- def test_c_char_p(self):
- c_char_p(b"foo bar")
- self.assertRaises(TypeError, c_char_p, "foo bar")
-
- def test_c_wchar_p(self):
- c_wchar_p("foo bar")
- self.assertRaises(TypeError, c_wchar_p, b"foo bar")
-
- def test_struct(self):
- class X(Structure):
- _fields_ = [("a", c_char * 3)]
-
- x = X(b"abc")
- self.assertRaises(TypeError, X, "abc")
- self.assertEqual(x.a, b"abc")
- self.assertEqual(type(x.a), bytes)
-
- def test_struct_W(self):
- class X(Structure):
- _fields_ = [("a", c_wchar * 3)]
-
- x = X("abc")
- self.assertRaises(TypeError, X, b"abc")
- self.assertEqual(x.a, "abc")
- self.assertEqual(type(x.a), str)
-
- @unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
- def test_BSTR(self):
- from _ctypes import _SimpleCData
- class BSTR(_SimpleCData):
- _type_ = "X"
-
- BSTR("abc")
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/Lib/ctypes/test/test_byteswap.py b/Lib/ctypes/test/test_byteswap.py
index 01c97e8..d36402b 100644
--- a/Lib/ctypes/test/test_byteswap.py
+++ b/Lib/ctypes/test/test_byteswap.py
@@ -4,7 +4,7 @@ from binascii import hexlify
from ctypes import *
def bin(s):
- return hexlify(memoryview(s)).decode().upper()
+ return hexlify(memoryview(s)).upper()
# Each *simple* type that supports different byte orders has an
# __ctype_be__ attribute that specifies the same type in BIG ENDIAN
@@ -16,32 +16,12 @@ def bin(s):
class Test(unittest.TestCase):
@unittest.skip('test disabled')
def test_X(self):
- print(sys.byteorder, file=sys.stderr)
+ print >> sys.stderr, sys.byteorder
for i in range(32):
bits = BITS()
setattr(bits, "i%s" % i, 1)
dump(bits)
- def test_slots(self):
- class BigPoint(BigEndianStructure):
- __slots__ = ()
- _fields_ = [("x", c_int), ("y", c_int)]
-
- class LowPoint(LittleEndianStructure):
- __slots__ = ()
- _fields_ = [("x", c_int), ("y", c_int)]
-
- big = BigPoint()
- little = LowPoint()
- big.x = 4
- big.y = 2
- little.x = 2
- little.y = 4
- with self.assertRaises(AttributeError):
- big.z = 42
- with self.assertRaises(AttributeError):
- little.z = 24
-
def test_endian_short(self):
if sys.byteorder == "little":
self.assertIs(c_short.__ctype_le__, c_short)
@@ -135,12 +115,12 @@ class Test(unittest.TestCase):
s = c_float(math.pi)
self.assertEqual(bin(struct.pack("f", math.pi)), bin(s))
# Hm, what's the precision of a float compared to a double?
- self.assertAlmostEqual(s.value, math.pi, places=6)
+ self.assertAlmostEqual(s.value, math.pi, 6)
s = c_float.__ctype_le__(math.pi)
- self.assertAlmostEqual(s.value, math.pi, places=6)
+ self.assertAlmostEqual(s.value, math.pi, 6)
self.assertEqual(bin(struct.pack("<f", math.pi)), bin(s))
s = c_float.__ctype_be__(math.pi)
- self.assertAlmostEqual(s.value, math.pi, places=6)
+ self.assertAlmostEqual(s.value, math.pi, 6)
self.assertEqual(bin(struct.pack(">f", math.pi)), bin(s))
def test_endian_double(self):
diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py
index f622093..db3d9e7 100644
--- a/Lib/ctypes/test/test_callbacks.py
+++ b/Lib/ctypes/test/test_callbacks.py
@@ -16,7 +16,7 @@ class Callbacks(unittest.TestCase):
return args[-1]
def check_type(self, typ, arg):
- PROTO = self.functype.__func__(typ, typ)
+ PROTO = self.functype.im_func(typ, typ)
result = PROTO(self.callback)(arg)
if typ == c_float:
self.assertAlmostEqual(result, arg, places=5)
@@ -24,7 +24,7 @@ class Callbacks(unittest.TestCase):
self.assertEqual(self.got_args, (arg,))
self.assertEqual(result, arg)
- PROTO = self.functype.__func__(typ, c_byte, typ)
+ PROTO = self.functype.im_func(typ, c_byte, typ)
result = PROTO(self.callback)(-3, arg)
if typ == c_float:
self.assertAlmostEqual(result, arg, places=5)
@@ -63,10 +63,16 @@ class Callbacks(unittest.TestCase):
self.check_type(c_ulong, 42)
def test_longlong(self):
+ # test some 64-bit values, positive and negative
+ self.check_type(c_longlong, 5948291757245277467)
+ self.check_type(c_longlong, -5229388909784190580)
self.check_type(c_longlong, 42)
self.check_type(c_longlong, -42)
def test_ulonglong(self):
+ # test some 64-bit values, with and without msb set.
+ self.check_type(c_ulonglong, 10955412242170339782)
+ self.check_type(c_ulonglong, 3665885499841167458)
self.check_type(c_ulonglong, 42)
def test_float(self):
@@ -84,8 +90,8 @@ class Callbacks(unittest.TestCase):
self.check_type(c_longdouble, -3.14)
def test_char(self):
- self.check_type(c_char, b"x")
- self.check_type(c_char, b"a")
+ self.check_type(c_char, "x")
+ self.check_type(c_char, "a")
# disabled: would now (correctly) raise a RuntimeWarning about
# a memory leak. A callback function cannot return a non-integral
@@ -113,16 +119,16 @@ class Callbacks(unittest.TestCase):
# functions, the type must have a non-NULL stgdict->setfunc.
# POINTER(c_double), for example, is not supported.
- prototype = self.functype.__func__(POINTER(c_double))
+ prototype = self.functype.im_func(POINTER(c_double))
# The type is checked when the prototype is called
self.assertRaises(TypeError, prototype, lambda: None)
def test_unsupported_restype_2(self):
- prototype = self.functype.__func__(object)
+ prototype = self.functype.im_func(object)
self.assertRaises(TypeError, prototype, lambda: None)
def test_issue_7959(self):
- proto = self.functype.__func__(None)
+ proto = self.functype.im_func(None)
class X(object):
def func(self): pass
diff --git a/Lib/ctypes/test/test_cast.py b/Lib/ctypes/test/test_cast.py
index 6878f97..d24e0b5 100644
--- a/Lib/ctypes/test/test_cast.py
+++ b/Lib/ctypes/test/test_cast.py
@@ -34,18 +34,18 @@ class Test(unittest.TestCase):
def test_p2a_objects(self):
array = (c_char_p * 5)()
self.assertEqual(array._objects, None)
- array[0] = b"foo bar"
- self.assertEqual(array._objects, {'0': b"foo bar"})
+ array[0] = "foo bar"
+ self.assertEqual(array._objects, {'0': "foo bar"})
p = cast(array, POINTER(c_char_p))
# array and p share a common _objects attribute
self.assertIs(p._objects, array._objects)
- self.assertEqual(array._objects, {'0': b"foo bar", id(array): array})
- p[0] = b"spam spam"
- self.assertEqual(p._objects, {'0': b"spam spam", id(array): array})
+ self.assertEqual(array._objects, {'0': "foo bar", id(array): array})
+ p[0] = "spam spam"
+ self.assertEqual(p._objects, {'0': "spam spam", id(array): array})
self.assertIs(array._objects, p._objects)
- p[1] = b"foo bar"
- self.assertEqual(p._objects, {'1': b'foo bar', '0': b"spam spam", id(array): array})
+ p[1] = "foo bar"
+ self.assertEqual(p._objects, {'1': 'foo bar', '0': "spam spam", id(array): array})
self.assertIs(array._objects, p._objects)
def test_other(self):
@@ -72,9 +72,9 @@ class Test(unittest.TestCase):
def test_char_p(self):
# This didn't work: bad argument to internal function
- s = c_char_p(b"hiho")
+ s = c_char_p("hiho")
self.assertEqual(cast(cast(s, c_void_p), c_char_p).value,
- b"hiho")
+ "hiho")
@need_symbol('c_wchar_p')
def test_wchar_p(self):
@@ -82,18 +82,5 @@ class Test(unittest.TestCase):
self.assertEqual(cast(cast(s, c_void_p), c_wchar_p).value,
"hiho")
- def test_bad_type_arg(self):
- # The type argument must be a ctypes pointer type.
- array_type = c_byte * sizeof(c_int)
- array = array_type()
- self.assertRaises(TypeError, cast, array, None)
- self.assertRaises(TypeError, cast, array, array_type)
- class Struct(Structure):
- _fields_ = [("a", c_int)]
- self.assertRaises(TypeError, cast, array, Struct)
- class MyUnion(Union):
- _fields_ = [("a", c_int)]
- self.assertRaises(TypeError, cast, array, MyUnion)
-
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_cfuncs.py b/Lib/ctypes/test/test_cfuncs.py
index ac2240f..765408c 100644
--- a/Lib/ctypes/test/test_cfuncs.py
+++ b/Lib/ctypes/test/test_cfuncs.py
@@ -108,7 +108,7 @@ class CFunctions(unittest.TestCase):
def test_ulong_plus(self):
self._dll.tf_bL.restype = c_ulong
self._dll.tf_bL.argtypes = (c_char, c_ulong)
- self.assertEqual(self._dll.tf_bL(b' ', 4294967295), 1431655765)
+ self.assertEqual(self._dll.tf_bL(' ', 4294967295), 1431655765)
self.assertEqual(self.U(), 4294967295)
def test_longlong(self):
diff --git a/Lib/ctypes/test/test_checkretval.py b/Lib/ctypes/test/test_checkretval.py
index e9567dc..a0dc534 100644
--- a/Lib/ctypes/test/test_checkretval.py
+++ b/Lib/ctypes/test/test_checkretval.py
@@ -28,7 +28,7 @@ class Test(unittest.TestCase):
@need_symbol('oledll')
def test_oledll(self):
- self.assertRaises(OSError,
+ self.assertRaises(WindowsError,
oledll.oleaut32.CreateTypeLib2,
0, None, None)
diff --git a/Lib/ctypes/test/test_errno.py b/Lib/ctypes/test/test_errno.py
index 3685164..c7a5bf0 100644
--- a/Lib/ctypes/test/test_errno.py
+++ b/Lib/ctypes/test/test_errno.py
@@ -1,8 +1,11 @@
import unittest, os, errno
-import threading
-
from ctypes import *
from ctypes.util import find_library
+from test import test_support
+try:
+ import threading
+except ImportError:
+ threading = None
class Test(unittest.TestCase):
def test_open(self):
@@ -17,30 +20,31 @@ class Test(unittest.TestCase):
libc_open.argtypes = c_char_p, c_int
- self.assertEqual(libc_open(b"", 0), -1)
+ self.assertEqual(libc_open("", 0), -1)
self.assertEqual(get_errno(), errno.ENOENT)
self.assertEqual(set_errno(32), errno.ENOENT)
self.assertEqual(get_errno(), 32)
- def _worker():
- set_errno(0)
+ if threading:
+ def _worker():
+ set_errno(0)
- libc = CDLL(libc_name, use_errno=False)
- if os.name == "nt":
- libc_open = libc._open
- else:
- libc_open = libc.open
- libc_open.argtypes = c_char_p, c_int
- self.assertEqual(libc_open(b"", 0), -1)
- self.assertEqual(get_errno(), 0)
+ libc = CDLL(libc_name, use_errno=False)
+ if os.name == "nt":
+ libc_open = libc._open
+ else:
+ libc_open = libc.open
+ libc_open.argtypes = c_char_p, c_int
+ self.assertEqual(libc_open("", 0), -1)
+ self.assertEqual(get_errno(), 0)
- t = threading.Thread(target=_worker)
- t.start()
- t.join()
+ t = threading.Thread(target=_worker)
+ t.start()
+ t.join()
- self.assertEqual(get_errno(), 32)
- set_errno(0)
+ self.assertEqual(get_errno(), 32)
+ set_errno(0)
@unittest.skipUnless(os.name == "nt", 'Test specific to Windows')
def test_GetLastError(self):
diff --git a/Lib/ctypes/test/test_find.py b/Lib/ctypes/test/test_find.py
index b99fdcb..c10d441 100644
--- a/Lib/ctypes/test/test_find.py
+++ b/Lib/ctypes/test/test_find.py
@@ -1,116 +1,75 @@
import unittest
import os.path
import sys
-import test.support
+from test import test_support
from ctypes import *
from ctypes.util import find_library
+from ctypes.test import is_resource_enabled
-# On some systems, loading the OpenGL libraries needs the RTLD_GLOBAL mode.
-class Test_OpenGL_libs(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- lib_gl = lib_glu = lib_gle = None
- if sys.platform == "win32":
- lib_gl = find_library("OpenGL32")
- lib_glu = find_library("Glu32")
- elif sys.platform == "darwin":
- lib_gl = lib_glu = find_library("OpenGL")
- else:
- lib_gl = find_library("GL")
- lib_glu = find_library("GLU")
- lib_gle = find_library("gle")
+if sys.platform == "win32":
+ lib_gl = find_library("OpenGL32")
+ lib_glu = find_library("Glu32")
+ lib_gle = None
+elif sys.platform == "darwin":
+ lib_gl = lib_glu = find_library("OpenGL")
+ lib_gle = None
+else:
+ lib_gl = find_library("GL")
+ lib_glu = find_library("GLU")
+ lib_gle = find_library("gle")
+
+## print, for debugging
+if is_resource_enabled("printing"):
+ if lib_gl or lib_glu or lib_gle:
+ print "OpenGL libraries:"
+ for item in (("GL", lib_gl),
+ ("GLU", lib_glu),
+ ("gle", lib_gle)):
+ print "\t", item
- ## print, for debugging
- if test.support.verbose:
- print("OpenGL libraries:")
- for item in (("GL", lib_gl),
- ("GLU", lib_glu),
- ("gle", lib_gle)):
- print("\t", item)
- cls.gl = cls.glu = cls.gle = None
+# On some systems, loading the OpenGL libraries needs the RTLD_GLOBAL mode.
+class Test_OpenGL_libs(unittest.TestCase):
+ def setUp(self):
+ self.gl = self.glu = self.gle = None
if lib_gl:
try:
- cls.gl = CDLL(lib_gl, mode=RTLD_GLOBAL)
+ self.gl = CDLL(lib_gl, mode=RTLD_GLOBAL)
except OSError:
pass
if lib_glu:
try:
- cls.glu = CDLL(lib_glu, RTLD_GLOBAL)
+ self.glu = CDLL(lib_glu, RTLD_GLOBAL)
except OSError:
pass
if lib_gle:
try:
- cls.gle = CDLL(lib_gle)
+ self.gle = CDLL(lib_gle)
except OSError:
pass
- @classmethod
- def tearDownClass(cls):
- cls.gl = cls.glu = cls.gle = None
+ def tearDown(self):
+ self.gl = self.glu = self.gle = None
+ @unittest.skipUnless(lib_gl, 'lib_gl not available')
def test_gl(self):
- if self.gl is None:
- self.skipTest('lib_gl not available')
- self.gl.glClearIndex
+ if self.gl:
+ self.gl.glClearIndex
+ @unittest.skipUnless(lib_glu, 'lib_glu not available')
def test_glu(self):
- if self.glu is None:
- self.skipTest('lib_glu not available')
- self.glu.gluBeginCurve
+ if self.glu:
+ self.glu.gluBeginCurve
+ @unittest.skipUnless(lib_gle, 'lib_gle not available')
def test_gle(self):
- if self.gle is None:
- self.skipTest('lib_gle not available')
- self.gle.gleGetJoinStyle
+ if self.gle:
+ self.gle.gleGetJoinStyle
def test_shell_injection(self):
- result = find_library('; echo Hello shell > ' + test.support.TESTFN)
- self.assertFalse(os.path.lexists(test.support.TESTFN))
+ result = find_library('; echo Hello shell > ' + test_support.TESTFN)
+ self.assertFalse(os.path.lexists(test_support.TESTFN))
self.assertIsNone(result)
-
-@unittest.skipUnless(sys.platform.startswith('linux'),
- 'Test only valid for Linux')
-class LibPathFindTest(unittest.TestCase):
- def test_find_on_libpath(self):
- import subprocess
- import tempfile
-
- try:
- p = subprocess.Popen(['gcc', '--version'], stdout=subprocess.PIPE,
- stderr=subprocess.DEVNULL)
- out, _ = p.communicate()
- except OSError:
- raise unittest.SkipTest('gcc, needed for test, not available')
- with tempfile.TemporaryDirectory() as d:
- # create an empty temporary file
- srcname = os.path.join(d, 'dummy.c')
- libname = 'py_ctypes_test_dummy'
- dstname = os.path.join(d, 'lib%s.so' % libname)
- with open(srcname, 'w') as f:
- pass
- self.assertTrue(os.path.exists(srcname))
- # compile the file to a shared library
- cmd = ['gcc', '-o', dstname, '--shared',
- '-Wl,-soname,lib%s.so' % libname, srcname]
- out = subprocess.check_output(cmd)
- self.assertTrue(os.path.exists(dstname))
- # now check that the .so can't be found (since not in
- # LD_LIBRARY_PATH)
- self.assertIsNone(find_library(libname))
- # now add the location to LD_LIBRARY_PATH
- with test.support.EnvironmentVarGuard() as env:
- KEY = 'LD_LIBRARY_PATH'
- if KEY not in env:
- v = d
- else:
- v = '%s:%s' % (env[KEY], d)
- env.set(KEY, v)
- # now check that the .so can be found (since in
- # LD_LIBRARY_PATH)
- self.assertEqual(find_library(libname), 'lib%s.so' % libname)
-
-
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_frombuffer.py b/Lib/ctypes/test/test_frombuffer.py
index 55c2443..99c32e0 100644
--- a/Lib/ctypes/test/test_frombuffer.py
+++ b/Lib/ctypes/test/test_frombuffer.py
@@ -10,7 +10,7 @@ class X(Structure):
self._init_called = True
class Test(unittest.TestCase):
- def test_from_buffer(self):
+ def test_fom_buffer(self):
a = array.array("i", range(16))
x = (c_int * 16).from_buffer(a)
@@ -23,64 +23,25 @@ class Test(unittest.TestCase):
a[0], a[-1] = 200, -200
self.assertEqual(x[:], a.tolist())
- self.assertRaises(BufferError, a.append, 100)
- self.assertRaises(BufferError, a.pop)
+ self.assertIn(a, x._objects.values())
- del x; del y; gc.collect(); gc.collect(); gc.collect()
- a.append(100)
- a.pop()
- x = (c_int * 16).from_buffer(a)
-
- self.assertIn(a, [obj.obj if isinstance(obj, memoryview) else obj
- for obj in x._objects.values()])
+ self.assertRaises(ValueError,
+ c_int.from_buffer, a, -1)
expected = x[:]
del a; gc.collect(); gc.collect(); gc.collect()
self.assertEqual(x[:], expected)
- with self.assertRaisesRegex(TypeError, "not writable"):
- (c_char * 16).from_buffer(b"a" * 16)
- with self.assertRaisesRegex(TypeError, "not writable"):
- (c_char * 16).from_buffer(memoryview(b"a" * 16))
- with self.assertRaisesRegex(TypeError, "not C contiguous"):
- (c_char * 16).from_buffer(memoryview(bytearray(b"a" * 16))[::-1])
- msg = "bytes-like object is required"
- with self.assertRaisesRegex(TypeError, msg):
- (c_char * 16).from_buffer("a" * 16)
-
- def test_fortran_contiguous(self):
- try:
- import _testbuffer
- except ImportError as err:
- self.skipTest(str(err))
- flags = _testbuffer.ND_WRITABLE | _testbuffer.ND_FORTRAN
- array = _testbuffer.ndarray(
- [97] * 16, format="B", shape=[4, 4], flags=flags)
- with self.assertRaisesRegex(TypeError, "not C contiguous"):
- (c_char * 16).from_buffer(array)
- array = memoryview(array)
- self.assertTrue(array.f_contiguous)
- self.assertFalse(array.c_contiguous)
- with self.assertRaisesRegex(TypeError, "not C contiguous"):
- (c_char * 16).from_buffer(array)
-
- def test_from_buffer_with_offset(self):
+ self.assertRaises(TypeError,
+ (c_char * 16).from_buffer, "a" * 16)
+
+ def test_fom_buffer_with_offset(self):
a = array.array("i", range(16))
x = (c_int * 15).from_buffer(a, sizeof(c_int))
self.assertEqual(x[:], a.tolist()[1:])
- with self.assertRaises(ValueError):
- c_int.from_buffer(a, -1)
- with self.assertRaises(ValueError):
- (c_int * 16).from_buffer(a, sizeof(c_int))
- with self.assertRaises(ValueError):
- (c_int * 1).from_buffer(a, 16 * sizeof(c_int))
-
- def test_from_buffer_memoryview(self):
- a = [c_char.from_buffer(memoryview(bytearray(b'a')))]
- a.append(a)
- del a
- gc.collect() # Should not crash
+ self.assertRaises(ValueError, lambda: (c_int * 16).from_buffer(a, sizeof(c_int)))
+ self.assertRaises(ValueError, lambda: (c_int * 1).from_buffer(a, 16 * sizeof(c_int)))
def test_from_buffer_copy(self):
a = array.array("i", range(16))
@@ -90,35 +51,31 @@ class Test(unittest.TestCase):
self.assertEqual(y.c_int, a[0])
self.assertFalse(y.init_called)
- self.assertEqual(x[:], list(range(16)))
+ self.assertEqual(x[:], range(16))
a[0], a[-1] = 200, -200
- self.assertEqual(x[:], list(range(16)))
-
- a.append(100)
- self.assertEqual(x[:], list(range(16)))
+ self.assertEqual(x[:], range(16))
self.assertEqual(x._objects, None)
+ self.assertRaises(ValueError,
+ c_int.from_buffer, a, -1)
+
del a; gc.collect(); gc.collect(); gc.collect()
- self.assertEqual(x[:], list(range(16)))
+ self.assertEqual(x[:], range(16))
- x = (c_char * 16).from_buffer_copy(b"a" * 16)
- self.assertEqual(x[:], b"a" * 16)
- with self.assertRaises(TypeError):
- (c_char * 16).from_buffer_copy("a" * 16)
+ x = (c_char * 16).from_buffer_copy("a" * 16)
+ self.assertEqual(x[:], "a" * 16)
- def test_from_buffer_copy_with_offset(self):
+ def test_fom_buffer_copy_with_offset(self):
a = array.array("i", range(16))
x = (c_int * 15).from_buffer_copy(a, sizeof(c_int))
self.assertEqual(x[:], a.tolist()[1:])
- with self.assertRaises(ValueError):
- c_int.from_buffer_copy(a, -1)
- with self.assertRaises(ValueError):
- (c_int * 16).from_buffer_copy(a, sizeof(c_int))
- with self.assertRaises(ValueError):
- (c_int * 1).from_buffer_copy(a, 16 * sizeof(c_int))
+ self.assertRaises(ValueError,
+ (c_int * 16).from_buffer_copy, a, sizeof(c_int))
+ self.assertRaises(ValueError,
+ (c_int * 1).from_buffer_copy, a, 16 * sizeof(c_int))
def test_abstract(self):
from ctypes import _Pointer, _SimpleCData, _CFuncPtr
diff --git a/Lib/ctypes/test/test_funcptr.py b/Lib/ctypes/test/test_funcptr.py
index e0b9b54..5750303 100644
--- a/Lib/ctypes/test/test_funcptr.py
+++ b/Lib/ctypes/test/test_funcptr.py
@@ -1,4 +1,4 @@
-import unittest
+import os, unittest
from ctypes import *
try:
@@ -39,7 +39,7 @@ class CFuncPtrTestCase(unittest.TestCase):
# possible, as in C, to call cdecl functions with more parameters.
#self.assertRaises(TypeError, c, 1, 2, 3)
self.assertEqual(c(1, 2, 3, 4, 5, 6), 3)
- if not WINFUNCTYPE is CFUNCTYPE:
+ if not WINFUNCTYPE is CFUNCTYPE and os.name != "ce":
self.assertRaises(TypeError, s, 1, 2, 3)
def test_structures(self):
@@ -97,8 +97,8 @@ class CFuncPtrTestCase(unittest.TestCase):
strchr = lib.my_strchr
strchr.restype = c_char_p
strchr.argtypes = (c_char_p, c_char)
- self.assertEqual(strchr(b"abcdefghi", b"b"), b"bcdefghi")
- self.assertEqual(strchr(b"abcdefghi", b"x"), None)
+ self.assertEqual(strchr("abcdefghi", "b"), "bcdefghi")
+ self.assertEqual(strchr("abcdefghi", "x"), None)
strtok = lib.my_strtok
@@ -111,17 +111,17 @@ class CFuncPtrTestCase(unittest.TestCase):
size = len(init) + 1
return (c_char*size)(*init)
- s = b"a\nb\nc"
+ s = "a\nb\nc"
b = c_string(s)
## b = (c_char * (len(s)+1))()
## b.value = s
## b = c_string(s)
- self.assertEqual(strtok(b, b"\n"), b"a")
- self.assertEqual(strtok(None, b"\n"), b"b")
- self.assertEqual(strtok(None, b"\n"), b"c")
- self.assertEqual(strtok(None, b"\n"), None)
+ self.assertEqual(strtok(b, "\n"), "a")
+ self.assertEqual(strtok(None, "\n"), "b")
+ self.assertEqual(strtok(None, "\n"), "c")
+ self.assertEqual(strtok(None, "\n"), None)
def test_abstract(self):
from ctypes import _CFuncPtr
diff --git a/Lib/ctypes/test/test_functions.py b/Lib/ctypes/test/test_functions.py
index 7562892..a374415 100644
--- a/Lib/ctypes/test/test_functions.py
+++ b/Lib/ctypes/test/test_functions.py
@@ -68,7 +68,7 @@ class FunctionTestCase(unittest.TestCase):
def test_wchar_parm(self):
f = dll._testfunc_i_bhilfd
f.argtypes = [c_byte, c_wchar, c_int, c_long, c_float, c_double]
- result = f(1, "x", 3, 4, 5.0, 6.0)
+ result = f(1, u"x", 3, 4, 5.0, 6.0)
self.assertEqual(result, 139)
self.assertEqual(type(result), int)
@@ -78,7 +78,7 @@ class FunctionTestCase(unittest.TestCase):
f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
f.restype = c_wchar
result = f(0, 0, 0, 0, 0, 0)
- self.assertEqual(result, '\x00')
+ self.assertEqual(result, u'\x00')
def test_voidresult(self):
f = dll._testfunc_v
@@ -168,8 +168,8 @@ class FunctionTestCase(unittest.TestCase):
f = dll._testfunc_p_p
f.argtypes = None
f.restype = c_char_p
- result = f(b"123")
- self.assertEqual(result, b"123")
+ result = f("123")
+ self.assertEqual(result, "123")
result = f(None)
self.assertEqual(result, None)
@@ -299,7 +299,7 @@ class FunctionTestCase(unittest.TestCase):
f.argtypes = [c_longlong, MyCallback]
def callback(value):
- self.assertIsInstance(value, int)
+ self.assertIsInstance(value, (int, long))
return value & 0x7FFFFFFF
cb = MyCallback(callback)
diff --git a/Lib/ctypes/test/test_incomplete.py b/Lib/ctypes/test/test_incomplete.py
index 00c430e..1e03e9f 100644
--- a/Lib/ctypes/test/test_incomplete.py
+++ b/Lib/ctypes/test/test_incomplete.py
@@ -17,9 +17,9 @@ class MyTestCase(unittest.TestCase):
SetPointerType(lpcell, cell)
c1 = cell()
- c1.name = b"foo"
+ c1.name = "foo"
c2 = cell()
- c2.name = b"bar"
+ c2.name = "bar"
c1.next = pointer(c2)
c2.next = pointer(c1)
@@ -30,7 +30,7 @@ class MyTestCase(unittest.TestCase):
for i in range(8):
result.append(p.name)
p = p.next[0]
- self.assertEqual(result, [b"foo", b"bar"] * 4)
+ self.assertEqual(result, ["foo", "bar"] * 4)
# to not leak references, we must clean _pointer_type_cache
from ctypes import _pointer_type_cache
diff --git a/Lib/ctypes/test/test_init.py b/Lib/ctypes/test/test_init.py
index 75fad11..82bd1f9 100644
--- a/Lib/ctypes/test/test_init.py
+++ b/Lib/ctypes/test/test_init.py
@@ -7,7 +7,7 @@ class X(Structure):
new_was_called = False
def __new__(cls):
- result = super().__new__(cls)
+ result = super(X, cls).__new__(cls)
result.new_was_called = True
return result
diff --git a/Lib/ctypes/test/test_internals.py b/Lib/ctypes/test/test_internals.py
index 271e3f5..2e5b1fe 100644
--- a/Lib/ctypes/test/test_internals.py
+++ b/Lib/ctypes/test/test_internals.py
@@ -5,14 +5,17 @@ from sys import getrefcount as grc
# XXX This test must be reviewed for correctness!!!
-# ctypes' types are container types.
-#
-# They have an internal memory block, which only consists of some bytes,
-# but it has to keep references to other objects as well. This is not
-# really needed for trivial C types like int or char, but it is important
-# for aggregate types like strings or pointers in particular.
-#
-# What about pointers?
+"""
+ctypes' types are container types.
+
+They have an internal memory block, which only consists of some bytes,
+but it has to keep references to other objects as well. This is not
+really needed for trivial C types like int or char, but it is important
+for aggregate types like strings or pointers in particular.
+
+What about pointers?
+
+"""
class ObjectsTestCase(unittest.TestCase):
def assertSame(self, a, b):
@@ -26,7 +29,7 @@ class ObjectsTestCase(unittest.TestCase):
self.assertEqual(ci._objects, None)
def test_c_char_p(self):
- s = b"Hello, World"
+ s = "Hello, World"
refcnt = grc(s)
cs = c_char_p(s)
self.assertEqual(refcnt + 1, grc(s))
@@ -67,8 +70,8 @@ class ObjectsTestCase(unittest.TestCase):
class Y(Structure):
_fields_ = [("x", X), ("y", X)]
- s1 = b"Hello, World"
- s2 = b"Hallo, Welt"
+ s1 = "Hello, World"
+ s2 = "Hallo, Welt"
x = X()
x.a = s1
diff --git a/Lib/ctypes/test/test_keeprefs.py b/Lib/ctypes/test/test_keeprefs.py
index 94c0257..b2a50ab 100644
--- a/Lib/ctypes/test/test_keeprefs.py
+++ b/Lib/ctypes/test/test_keeprefs.py
@@ -13,10 +13,10 @@ class SimpleTestCase(unittest.TestCase):
def test_ccharp(self):
x = c_char_p()
self.assertEqual(x._objects, None)
- x.value = b"abc"
- self.assertEqual(x._objects, b"abc")
- x = c_char_p(b"spam")
- self.assertEqual(x._objects, b"spam")
+ x.value = "abc"
+ self.assertEqual(x._objects, "abc")
+ x = c_char_p("spam")
+ self.assertEqual(x._objects, "spam")
class StructureTestCase(unittest.TestCase):
def test_cint_struct(self):
@@ -37,9 +37,9 @@ class StructureTestCase(unittest.TestCase):
x = X()
self.assertEqual(x._objects, None)
- x.a = b"spam"
- x.b = b"foo"
- self.assertEqual(x._objects, {"0": b"spam", "1": b"foo"})
+ x.a = "spam"
+ x.b = "foo"
+ self.assertEqual(x._objects, {"0": "spam", "1": "foo"})
def test_struct_struct(self):
class POINT(Structure):
@@ -101,13 +101,13 @@ class DeletePointerTestCase(unittest.TestCase):
x = X()
i = c_char_p("abc def")
from sys import getrefcount as grc
- print("2?", grc(i))
+ print "2?", grc(i)
x.p = pointer(i)
- print("3?", grc(i))
+ print "3?", grc(i)
for i in range(320):
c_int(99)
x.p[0]
- print(x.p[0])
+ print x.p[0]
## del x
## print "2?", grc(i)
## del i
@@ -116,14 +116,14 @@ class DeletePointerTestCase(unittest.TestCase):
for i in range(320):
c_int(99)
x.p[0]
- print(x.p[0])
- print(x.p.contents)
+ print x.p[0]
+ print x.p.contents
## print x._objects
x.p[0] = "spam spam"
## print x.p[0]
- print("+" * 42)
- print(x._objects)
+ print "+" * 42
+ print x._objects
class PointerToStructure(unittest.TestCase):
def test(self):
diff --git a/Lib/ctypes/test/test_libc.py b/Lib/ctypes/test/test_libc.py
index 56285b5..3dc463f 100644
--- a/Lib/ctypes/test/test_libc.py
+++ b/Lib/ctypes/test/test_libc.py
@@ -5,10 +5,6 @@ import _ctypes_test
lib = CDLL(_ctypes_test.__file__)
-def three_way_cmp(x, y):
- """Return -1 if x < y, 0 if x == y and 1 if x > y"""
- return (x > y) - (x < y)
-
class LibTest(unittest.TestCase):
def test_sqrt(self):
lib.my_sqrt.argtypes = c_double,
@@ -23,11 +19,11 @@ class LibTest(unittest.TestCase):
lib.my_qsort.restype = None
def sort(a, b):
- return three_way_cmp(a[0], b[0])
+ return cmp(a[0], b[0])
- chars = create_string_buffer(b"spam, spam, and spam")
+ chars = create_string_buffer("spam, spam, and spam")
lib.my_qsort(chars, len(chars)-1, sizeof(c_char), comparefunc(sort))
- self.assertEqual(chars.raw, b" ,,aaaadmmmnpppsss\x00")
+ self.assertEqual(chars.raw, " ,,aaaadmmmnpppsss\x00")
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py
index 9b97d80..e64fff7 100644
--- a/Lib/ctypes/test/test_loading.py
+++ b/Lib/ctypes/test/test_loading.py
@@ -1,43 +1,44 @@
from ctypes import *
+import sys, unittest
import os
-import shutil
-import subprocess
-import sys
-import sysconfig
-import unittest
-import test.support
from ctypes.util import find_library
+from ctypes.test import is_resource_enabled
+import test.test_support as support
libc_name = None
-
-def setUpModule():
- global libc_name
- if os.name == "nt":
- libc_name = find_library("c")
- elif sys.platform == "cygwin":
- libc_name = "cygwin1.dll"
- else:
- libc_name = find_library("c")
-
- if test.support.verbose:
- print("libc_name is", libc_name)
+if os.name == "nt":
+ libc_name = find_library("c")
+elif os.name == "ce":
+ libc_name = "coredll"
+elif sys.platform == "cygwin":
+ libc_name = "cygwin1.dll"
+else:
+ libc_name = find_library("c")
+
+if is_resource_enabled("printing"):
+ print "libc_name is", libc_name
class LoaderTest(unittest.TestCase):
unknowndll = "xxrandomnamexx"
+ @unittest.skipUnless(libc_name is not None, 'could not find libc')
def test_load(self):
- if libc_name is None:
- self.skipTest('could not find libc')
CDLL(libc_name)
CDLL(os.path.basename(libc_name))
self.assertRaises(OSError, CDLL, self.unknowndll)
+ @support.requires_unicode
+ @unittest.skipUnless(libc_name is not None, 'could not find libc')
+ def test_load_unicode(self):
+ CDLL(unicode(libc_name))
+ self.assertRaises(OSError, CDLL, unicode(self.unknowndll))
+
+ @unittest.skipUnless(libc_name is not None, 'could not find libc')
+ @unittest.skipUnless(libc_name is not None and
+ os.path.basename(libc_name) == "libc.so.6",
+ 'wrong libc path for test')
def test_load_version(self):
- if libc_name is None:
- self.skipTest('could not find libc')
- if os.path.basename(libc_name) != 'libc.so.6':
- self.skipTest('wrong libc path for test')
cdll.LoadLibrary("libc.so.6")
# linux uses version, libc 9 should not exist
self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9")
@@ -50,26 +51,27 @@ class LoaderTest(unittest.TestCase):
cdll.LoadLibrary(lib)
CDLL(lib)
- @unittest.skipUnless(os.name == "nt",
- 'test specific to Windows')
+ @unittest.skipUnless(os.name in ("nt", "ce"),
+ 'test specific to Windows (NT/CE)')
def test_load_library(self):
- # CRT is no longer directly loadable. See issue23606 for the
- # discussion about alternative approaches.
- #self.assertIsNotNone(libc_name)
- if test.support.verbose:
- print(find_library("kernel32"))
- print(find_library("user32"))
+ self.assertIsNotNone(libc_name)
+ if is_resource_enabled("printing"):
+ print find_library("kernel32")
+ print find_library("user32")
if os.name == "nt":
windll.kernel32.GetModuleHandleW
windll["kernel32"].GetModuleHandleW
windll.LoadLibrary("kernel32").GetModuleHandleW
WinDLL("kernel32").GetModuleHandleW
- # embedded null character
- self.assertRaises(ValueError, windll.LoadLibrary, "kernel32\0")
-
- @unittest.skipUnless(os.name == "nt",
- 'test specific to Windows')
+ elif os.name == "ce":
+ windll.coredll.GetModuleHandleW
+ windll["coredll"].GetModuleHandleW
+ windll.LoadLibrary("coredll").GetModuleHandleW
+ WinDLL("coredll").GetModuleHandleW
+
+ @unittest.skipUnless(os.name in ("nt", "ce"),
+ 'test specific to Windows (NT/CE)')
def test_load_ordinal_functions(self):
import _ctypes_test
dll = WinDLL(_ctypes_test.__file__)
@@ -110,71 +112,10 @@ class LoaderTest(unittest.TestCase):
windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p
windll.kernel32.GetProcAddress.restype = c_void_p
proc = windll.kernel32.GetProcAddress(advapi32._handle,
- b"CloseEventLog")
+ "CloseEventLog")
self.assertTrue(proc)
# This is the real test: call the function via 'call_function'
self.assertEqual(0, call_function(proc, (None,)))
- @unittest.skipUnless(os.name == "nt",
- 'test specific to Windows')
- def test_load_dll_with_flags(self):
- _sqlite3 = test.support.import_module("_sqlite3")
- src = _sqlite3.__file__
- if src.lower().endswith("_d.pyd"):
- ext = "_d.dll"
- else:
- ext = ".dll"
-
- with test.support.temp_dir() as tmp:
- # We copy two files and load _sqlite3.dll (formerly .pyd),
- # which has a dependency on sqlite3.dll. Then we test
- # loading it in subprocesses to avoid it starting in memory
- # for each test.
- target = os.path.join(tmp, "_sqlite3.dll")
- shutil.copy(src, target)
- shutil.copy(os.path.join(os.path.dirname(src), "sqlite3" + ext),
- os.path.join(tmp, "sqlite3" + ext))
-
- def should_pass(command):
- with self.subTest(command):
- subprocess.check_output(
- [sys.executable, "-c",
- "from ctypes import *; import nt;" + command],
- cwd=tmp
- )
-
- def should_fail(command):
- with self.subTest(command):
- with self.assertRaises(subprocess.CalledProcessError):
- subprocess.check_output(
- [sys.executable, "-c",
- "from ctypes import *; import nt;" + command],
- cwd=tmp, stderr=subprocess.STDOUT,
- )
-
- # Default load should not find this in CWD
- should_fail("WinDLL('_sqlite3.dll')")
-
- # Relative path (but not just filename) should succeed
- should_pass("WinDLL('./_sqlite3.dll')")
-
- # Insecure load flags should succeed
- should_pass("WinDLL('_sqlite3.dll', winmode=0)")
-
- # Full path load without DLL_LOAD_DIR shouldn't find dependency
- should_fail("WinDLL(nt._getfullpathname('_sqlite3.dll'), " +
- "winmode=nt._LOAD_LIBRARY_SEARCH_SYSTEM32)")
-
- # Full path load with DLL_LOAD_DIR should succeed
- should_pass("WinDLL(nt._getfullpathname('_sqlite3.dll'), " +
- "winmode=nt._LOAD_LIBRARY_SEARCH_SYSTEM32|" +
- "nt._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)")
-
- # User-specified directory should succeed
- should_pass("import os; p = os.add_dll_directory(os.getcwd());" +
- "WinDLL('_sqlite3.dll'); p.close()")
-
-
-
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_macholib.py b/Lib/ctypes/test/test_macholib.py
index 6b35269..9779b2f 100644
--- a/Lib/ctypes/test/test_macholib.py
+++ b/Lib/ctypes/test/test_macholib.py
@@ -3,33 +3,35 @@ import sys
import unittest
# Bob Ippolito:
-#
-# Ok.. the code to find the filename for __getattr__ should look
-# something like:
-#
-# import os
-# from macholib.dyld import dyld_find
-#
-# def find_lib(name):
-# possible = ['lib'+name+'.dylib', name+'.dylib',
-# name+'.framework/'+name]
-# for dylib in possible:
-# try:
-# return os.path.realpath(dyld_find(dylib))
-# except ValueError:
-# pass
-# raise ValueError, "%s not found" % (name,)
-#
-# It'll have output like this:
-#
-# >>> find_lib('pthread')
-# '/usr/lib/libSystem.B.dylib'
-# >>> find_lib('z')
-# '/usr/lib/libz.1.dylib'
-# >>> find_lib('IOKit')
-# '/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit'
-#
-# -bob
+"""
+Ok.. the code to find the filename for __getattr__ should look
+something like:
+
+import os
+from macholib.dyld import dyld_find
+
+def find_lib(name):
+ possible = ['lib'+name+'.dylib', name+'.dylib',
+ name+'.framework/'+name]
+ for dylib in possible:
+ try:
+ return os.path.realpath(dyld_find(dylib))
+ except ValueError:
+ pass
+ raise ValueError, "%s not found" % (name,)
+
+It'll have output like this:
+
+ >>> find_lib('pthread')
+'/usr/lib/libSystem.B.dylib'
+ >>> find_lib('z')
+'/usr/lib/libz.1.dylib'
+ >>> find_lib('IOKit')
+'/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit'
+
+-bob
+
+"""
from ctypes.macholib.dyld import dyld_find
@@ -54,7 +56,7 @@ class MachOTest(unittest.TestCase):
# /usr/local/lib before /usr/lib, which caused test failures if
# a local copy of libz exists in one of them. Now ignore the head
# of the path.
- self.assertRegex(result, r".*/lib/libz\..*.*\.dylib")
+ self.assertRegexpMatches(result, r".*/lib/libz\..*.*\.dylib")
self.assertEqual(find_lib('IOKit'),
'/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit')
diff --git a/Lib/ctypes/test/test_memfunctions.py b/Lib/ctypes/test/test_memfunctions.py
index e784b9a..ba9eea6 100644
--- a/Lib/ctypes/test/test_memfunctions.py
+++ b/Lib/ctypes/test/test_memfunctions.py
@@ -1,5 +1,4 @@
import sys
-from test import support
import unittest
from ctypes import *
from ctypes.test import need_symbol
@@ -20,27 +19,27 @@ class MemFunctionsTest(unittest.TestCase):
# large buffers apparently increase the chance that the memory
# is allocated in high address space.
a = create_string_buffer(1000000)
- p = b"Hello, World"
+ p = "Hello, World"
result = memmove(a, p, len(p))
- self.assertEqual(a.value, b"Hello, World")
+ self.assertEqual(a.value, "Hello, World")
- self.assertEqual(string_at(result), b"Hello, World")
- self.assertEqual(string_at(result, 5), b"Hello")
- self.assertEqual(string_at(result, 16), b"Hello, World\0\0\0\0")
- self.assertEqual(string_at(result, 0), b"")
+ self.assertEqual(string_at(result), "Hello, World")
+ self.assertEqual(string_at(result, 5), "Hello")
+ self.assertEqual(string_at(result, 16), "Hello, World\0\0\0\0")
+ self.assertEqual(string_at(result, 0), "")
def test_memset(self):
a = create_string_buffer(1000000)
result = memset(a, ord('x'), 16)
- self.assertEqual(a.value, b"xxxxxxxxxxxxxxxx")
+ self.assertEqual(a.value, "xxxxxxxxxxxxxxxx")
- self.assertEqual(string_at(result), b"xxxxxxxxxxxxxxxx")
- self.assertEqual(string_at(a), b"xxxxxxxxxxxxxxxx")
- self.assertEqual(string_at(a, 20), b"xxxxxxxxxxxxxxxx\0\0\0\0")
+ self.assertEqual(string_at(result), "xxxxxxxxxxxxxxxx")
+ self.assertEqual(string_at(a), "xxxxxxxxxxxxxxxx")
+ self.assertEqual(string_at(a, 20), "xxxxxxxxxxxxxxxx\0\0\0\0")
def test_cast(self):
a = (c_ubyte * 32)(*map(ord, "abcdef"))
- self.assertEqual(cast(a, c_char_p).value, b"abcdef")
+ self.assertEqual(cast(a, c_char_p).value, "abcdef")
self.assertEqual(cast(a, POINTER(c_byte))[:7],
[97, 98, 99, 100, 101, 102, 0])
self.assertEqual(cast(a, POINTER(c_byte))[:7:],
@@ -52,16 +51,15 @@ class MemFunctionsTest(unittest.TestCase):
self.assertEqual(cast(a, POINTER(c_byte))[:7:7],
[97])
- @support.refcount_test
def test_string_at(self):
- s = string_at(b"foo bar")
+ s = string_at("foo bar")
# XXX The following may be wrong, depending on how Python
# manages string instances
self.assertEqual(2, sys.getrefcount(s))
self.assertTrue(s, "foo bar")
- self.assertEqual(string_at(b"foo bar", 7), b"foo bar")
- self.assertEqual(string_at(b"foo bar", 3), b"foo")
+ self.assertEqual(string_at("foo bar", 8), "foo bar\0")
+ self.assertEqual(string_at("foo bar", 3), "foo")
@need_symbol('create_unicode_buffer')
def test_wstring_at(self):
diff --git a/Lib/ctypes/test/test_numbers.py b/Lib/ctypes/test/test_numbers.py
index c6d843b..ec42e96 100644
--- a/Lib/ctypes/test/test_numbers.py
+++ b/Lib/ctypes/test/test_numbers.py
@@ -12,10 +12,10 @@ def valid_ranges(*types):
for t in types:
fmt = t._type_
size = struct.calcsize(fmt)
- a = struct.unpack(fmt, (b"\x00"*32)[:size])[0]
- b = struct.unpack(fmt, (b"\xFF"*32)[:size])[0]
- c = struct.unpack(fmt, (b"\x7F"+b"\x00"*32)[:size])[0]
- d = struct.unpack(fmt, (b"\x80"+b"\xFF"*32)[:size])[0]
+ a = struct.unpack(fmt, ("\x00"*32)[:size])[0]
+ b = struct.unpack(fmt, ("\xFF"*32)[:size])[0]
+ c = struct.unpack(fmt, ("\x7F"+"\x00"*32)[:size])[0]
+ d = struct.unpack(fmt, ("\x80"+"\xFF"*32)[:size])[0]
result.append((min(a, b, c, d), max(a, b, c, d)))
return result
@@ -105,7 +105,7 @@ class NumberTestCase(unittest.TestCase):
def test_floats(self):
# c_float and c_double can be created from
- # Python int and float
+ # Python int, long and float
class FloatLike(object):
def __float__(self):
return 2.0
@@ -113,7 +113,7 @@ class NumberTestCase(unittest.TestCase):
for t in float_types:
self.assertEqual(t(2.0).value, 2.0)
self.assertEqual(t(2).value, 2.0)
- self.assertEqual(t(2).value, 2.0)
+ self.assertEqual(t(2L).value, 2.0)
self.assertEqual(t(f).value, 2.0)
def test_integers(self):
@@ -124,18 +124,12 @@ class NumberTestCase(unittest.TestCase):
class IntLike(object):
def __int__(self):
return 2
- d = IntLike()
- class IndexLike(object):
- def __index__(self):
- return 2
- i = IndexLike()
+ i = IntLike()
# integers cannot be constructed from floats,
# but from integer-like objects
for t in signed_types + unsigned_types:
self.assertRaises(TypeError, t, 3.14)
self.assertRaises(TypeError, t, f)
- with self.assertWarns(DeprecationWarning):
- self.assertEqual(t(d).value, 2)
self.assertEqual(t(i).value, 2)
def test_sizes(self):
@@ -197,14 +191,13 @@ class NumberTestCase(unittest.TestCase):
from ctypes import c_char
from array import array
- a = array('b', [0])
- a[0] = ord('x')
+ a = array('c', 'x')
v = c_char.from_address(a.buffer_info()[0])
- self.assertEqual(v.value, b'x')
+ self.assertEqual(v.value, a[0])
self.assertIs(type(v), c_char)
- a[0] = ord('?')
- self.assertEqual(v.value, b'?')
+ a[0] = '?'
+ self.assertEqual(v.value, a[0])
# array does not support c_bool / 't'
@unittest.skip('test disabled')
@@ -247,7 +240,7 @@ class c_int_S(_SimpleCData):
def run_test(rep, msg, func, arg=None):
## items = [None] * rep
items = range(rep)
- from time import perf_counter as clock
+ from time import clock
if arg is not None:
start = clock()
for i in items:
@@ -258,7 +251,7 @@ def run_test(rep, msg, func, arg=None):
for i in items:
func(); func(); func(); func(); func()
stop = clock()
- print("%15s: %.2f us" % (msg, ((stop-start)*1e6/5/rep)))
+ print "%15s: %.2f us" % (msg, ((stop-start)*1e6/5/rep))
def check_perf():
# Construct 5 objects
diff --git a/Lib/ctypes/test/test_objects.py b/Lib/ctypes/test/test_objects.py
index 19e3dc1..a7c5247 100644
--- a/Lib/ctypes/test/test_objects.py
+++ b/Lib/ctypes/test/test_objects.py
@@ -13,18 +13,18 @@ Here is an array of string pointers:
>>> from ctypes import *
>>> array = (c_char_p * 5)()
->>> print(array._objects)
+>>> print array._objects
None
>>>
The memory block stores pointers to strings, and the strings itself
assigned from Python must be kept.
->>> array[4] = b'foo bar'
+>>> array[4] = 'foo bar'
>>> array._objects
-{'4': b'foo bar'}
+{'4': 'foo bar'}
>>> array[4]
-b'foo bar'
+'foo bar'
>>>
It gets more complicated when the ctypes instance itself is contained
@@ -34,27 +34,27 @@ in a 'base' object.
... _fields_ = [("x", c_int), ("y", c_int), ("array", c_char_p * 5)]
...
>>> x = X()
->>> print(x._objects)
+>>> print x._objects
None
>>>
The'array' attribute of the 'x' object shares part of the memory buffer
of 'x' ('_b_base_' is either None, or the root object owning the memory block):
->>> print(x.array._b_base_) # doctest: +ELLIPSIS
+>>> print x.array._b_base_ # doctest: +ELLIPSIS
<ctypes.test.test_objects.X object at 0x...>
>>>
->>> x.array[0] = b'spam spam spam'
+>>> x.array[0] = 'spam spam spam'
>>> x._objects
-{'0:2': b'spam spam spam'}
+{'0:2': 'spam spam spam'}
>>> x.array._b_base_._objects
-{'0:2': b'spam spam spam'}
+{'0:2': 'spam spam spam'}
>>>
'''
-import unittest, doctest
+import unittest, doctest, sys
import ctypes.test.test_objects
diff --git a/Lib/ctypes/test/test_parameters.py b/Lib/ctypes/test/test_parameters.py
index e4c25fd..23c1b6e 100644
--- a/Lib/ctypes/test/test_parameters.py
+++ b/Lib/ctypes/test/test_parameters.py
@@ -1,4 +1,4 @@
-import unittest
+import unittest, sys
from ctypes.test import need_symbol
import test.support
@@ -21,6 +21,7 @@ class SimpleTypesTestCase(unittest.TestCase):
else:
set_conversion_mode(*self.prev_conv_mode)
+
def test_subclasses(self):
from ctypes import c_void_p, c_char_p
# ctypes 0.9.5 and before did overwrite from_param in SimpleType_new
@@ -50,33 +51,37 @@ class SimpleTypesTestCase(unittest.TestCase):
# XXX Replace by c_char_p tests
def test_cstrings(self):
- from ctypes import c_char_p
+ from ctypes import c_char_p, byref
# c_char_p.from_param on a Python String packs the string
# into a cparam object
- s = b"123"
+ s = "123"
self.assertIs(c_char_p.from_param(s)._obj, s)
# new in 0.9.1: convert (encode) unicode to ascii
- self.assertEqual(c_char_p.from_param(b"123")._obj, b"123")
- self.assertRaises(TypeError, c_char_p.from_param, "123\377")
+ self.assertEqual(c_char_p.from_param(u"123")._obj, "123")
+ self.assertRaises(UnicodeEncodeError, c_char_p.from_param, u"123\377")
+
self.assertRaises(TypeError, c_char_p.from_param, 42)
# calling c_char_p.from_param with a c_char_p instance
# returns the argument itself:
- a = c_char_p(b"123")
+ a = c_char_p("123")
self.assertIs(c_char_p.from_param(a), a)
@need_symbol('c_wchar_p')
def test_cw_strings(self):
- from ctypes import c_wchar_p
+ from ctypes import byref, c_wchar_p
+ s = u"123"
+ if sys.platform == "win32":
+ self.assertTrue(c_wchar_p.from_param(s)._obj is s)
+ self.assertRaises(TypeError, c_wchar_p.from_param, 42)
- c_wchar_p.from_param("123")
+ # new in 0.9.1: convert (decode) ascii to unicode
+ self.assertEqual(c_wchar_p.from_param("123")._obj, u"123")
+ self.assertRaises(UnicodeDecodeError, c_wchar_p.from_param, "123\377")
- self.assertRaises(TypeError, c_wchar_p.from_param, 42)
- self.assertRaises(TypeError, c_wchar_p.from_param, b"123\377")
-
- pa = c_wchar_p.from_param(c_wchar_p("123"))
+ pa = c_wchar_p.from_param(c_wchar_p(u"123"))
self.assertEqual(type(pa), c_wchar_p)
def test_int_pointers(self):
@@ -99,7 +104,7 @@ class SimpleTypesTestCase(unittest.TestCase):
def test_byref_pointer(self):
# The from_param class method of POINTER(typ) classes accepts what is
# returned by byref(obj), it type(obj) == typ
- from ctypes import c_short, c_uint, c_int, c_long, POINTER, byref
+ from ctypes import c_short, c_uint, c_int, c_long, pointer, POINTER, byref
LPINT = POINTER(c_int)
LPINT.from_param(byref(c_int(42)))
@@ -197,7 +202,7 @@ class SimpleTypesTestCase(unittest.TestCase):
class WorseStruct(Structure):
@property
def __dict__(self):
- 1/0
+ 1/0.0
with self.assertRaises(ZeroDivisionError):
WorseStruct().__setstate__({}, b'foo')
diff --git a/Lib/ctypes/test/test_pep3118.py b/Lib/ctypes/test/test_pep3118.py
index 81e8ca7..49a1356 100644
--- a/Lib/ctypes/test/test_pep3118.py
+++ b/Lib/ctypes/test/test_pep3118.py
@@ -25,17 +25,14 @@ class Test(unittest.TestCase):
v = memoryview(ob)
try:
self.assertEqual(normalize(v.format), normalize(fmt))
- if shape:
+ if shape is not None:
self.assertEqual(len(v), shape[0])
else:
self.assertEqual(len(v) * sizeof(itemtp), sizeof(ob))
self.assertEqual(v.itemsize, sizeof(itemtp))
self.assertEqual(v.shape, shape)
- # XXX Issue #12851: PyCData_NewGetBuffer() must provide strides
- # if requested. memoryview currently reconstructs missing
- # stride information, so this assert will fail.
- # self.assertEqual(v.strides, ())
-
+ # ctypes object always have a non-strided memory block
+ self.assertEqual(v.strides, None)
# they are always read/write
self.assertFalse(v.readonly)
@@ -55,15 +52,14 @@ class Test(unittest.TestCase):
v = memoryview(ob)
try:
self.assertEqual(v.format, fmt)
- if shape:
+ if shape is not None:
self.assertEqual(len(v), shape[0])
else:
self.assertEqual(len(v) * sizeof(itemtp), sizeof(ob))
self.assertEqual(v.itemsize, sizeof(itemtp))
self.assertEqual(v.shape, shape)
- # XXX Issue #12851
- # self.assertEqual(v.strides, ())
-
+ # ctypes object always have a non-strided memory block
+ self.assertEqual(v.strides, None)
# they are always read/write
self.assertFalse(v.readonly)
@@ -99,6 +95,7 @@ class aUnion(Union):
class StructWithArrays(Structure):
_fields_ = [("x", c_long * 3 * 2), ("y", Point * 4)]
+
class Incomplete(Structure):
pass
@@ -145,33 +142,33 @@ native_types = [
## simple types
- (c_char, "<c", (), c_char),
- (c_byte, "<b", (), c_byte),
- (c_ubyte, "<B", (), c_ubyte),
- (c_short, "<" + s_short, (), c_short),
- (c_ushort, "<" + s_ushort, (), c_ushort),
+ (c_char, "<c", None, c_char),
+ (c_byte, "<b", None, c_byte),
+ (c_ubyte, "<B", None, c_ubyte),
+ (c_short, "<" + s_short, None, c_short),
+ (c_ushort, "<" + s_ushort, None, c_ushort),
- (c_int, "<" + s_int, (), c_int),
- (c_uint, "<" + s_uint, (), c_uint),
+ (c_int, "<" + s_int, None, c_int),
+ (c_uint, "<" + s_uint, None, c_uint),
- (c_long, "<" + s_long, (), c_long),
- (c_ulong, "<" + s_ulong, (), c_ulong),
+ (c_long, "<" + s_long, None, c_long),
+ (c_ulong, "<" + s_ulong, None, c_ulong),
- (c_longlong, "<" + s_longlong, (), c_longlong),
- (c_ulonglong, "<" + s_ulonglong, (), c_ulonglong),
+ (c_longlong, "<" + s_longlong, None, c_longlong),
+ (c_ulonglong, "<" + s_ulonglong, None, c_ulonglong),
- (c_float, "<f", (), c_float),
- (c_double, "<d", (), c_double),
+ (c_float, "<f", None, c_float),
+ (c_double, "<d", None, c_double),
- (c_longdouble, "<" + s_longdouble, (), c_longdouble),
+ (c_longdouble, "<" + s_longdouble, None, c_longdouble),
- (c_bool, "<" + s_bool, (), c_bool),
- (py_object, "<O", (), py_object),
+ (c_bool, "<" + s_bool, None, c_bool),
+ (py_object, "<O", None, py_object),
## pointers
- (POINTER(c_byte), "&<b", (), POINTER(c_byte)),
- (POINTER(POINTER(c_long)), "&&<" + s_long, (), POINTER(POINTER(c_long))),
+ (POINTER(c_byte), "&<b", None, POINTER(c_byte)),
+ (POINTER(POINTER(c_long)), "&&<" + s_long, None, POINTER(POINTER(c_long))),
## arrays and pointers
@@ -179,35 +176,35 @@ native_types = [
(c_float * 4 * 3 * 2, "<f", (2,3,4), c_float),
(POINTER(c_short) * 2, "&<" + s_short, (2,), POINTER(c_short)),
(POINTER(c_short) * 2 * 3, "&<" + s_short, (3,2,), POINTER(c_short)),
- (POINTER(c_short * 2), "&(2)<" + s_short, (), POINTER(c_short)),
+ (POINTER(c_short * 2), "&(2)<" + s_short, None, POINTER(c_short)),
## structures and unions
- (Point, "T{<l:x:<l:y:}".replace('l', s_long), (), Point),
+ (Point, "T{<l:x:<l:y:}".replace('l', s_long), None, Point),
# packed structures do not implement the pep
- (PackedPoint, "B", (), PackedPoint),
- (Point2, "T{<l:x:<l:y:}".replace('l', s_long), (), Point2),
- (EmptyStruct, "T{}", (), EmptyStruct),
- # the pep doesn't support unions
- (aUnion, "B", (), aUnion),
+ (PackedPoint, "B", None, PackedPoint),
+ (Point2, "T{<l:x:<l:y:}".replace('l', s_long), None, Point2),
+ (EmptyStruct, "T{}", None, EmptyStruct),
+ # the pep does't support unions
+ (aUnion, "B", None, aUnion),
# structure with sub-arrays
- (StructWithArrays, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}".replace('l', s_long), (), StructWithArrays),
+ (StructWithArrays, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}".replace('l', s_long), None, StructWithArrays),
(StructWithArrays * 3, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}".replace('l', s_long), (3,), StructWithArrays),
## pointer to incomplete structure
- (Incomplete, "B", (), Incomplete),
- (POINTER(Incomplete), "&B", (), POINTER(Incomplete)),
+ (Incomplete, "B", None, Incomplete),
+ (POINTER(Incomplete), "&B", None, POINTER(Incomplete)),
# 'Complete' is a structure that starts incomplete, but is completed after the
# pointer type to it has been created.
- (Complete, "T{<l:a:}".replace('l', s_long), (), Complete),
+ (Complete, "T{<l:a:}".replace('l', s_long), None, Complete),
# Unfortunately the pointer format string is not fixed...
- (POINTER(Complete), "&B", (), POINTER(Complete)),
+ (POINTER(Complete), "&B", None, POINTER(Complete)),
## other
# function signatures are not implemented
- (CFUNCTYPE(None), "X{}", (), CFUNCTYPE(None)),
+ (CFUNCTYPE(None), "X{}", None, CFUNCTYPE(None)),
]
@@ -223,10 +220,10 @@ class LEPoint(LittleEndianStructure):
# and little endian machines.
#
endian_types = [
- (BEPoint, "T{>l:x:>l:y:}".replace('l', s_long), (), BEPoint),
- (LEPoint, "T{<l:x:<l:y:}".replace('l', s_long), (), LEPoint),
- (POINTER(BEPoint), "&T{>l:x:>l:y:}".replace('l', s_long), (), POINTER(BEPoint)),
- (POINTER(LEPoint), "&T{<l:x:<l:y:}".replace('l', s_long), (), POINTER(LEPoint)),
+ (BEPoint, "T{>l:x:>l:y:}".replace('l', s_long), None, BEPoint),
+ (LEPoint, "T{<l:x:<l:y:}".replace('l', s_long), None, LEPoint),
+ (POINTER(BEPoint), "&T{>l:x:>l:y:}".replace('l', s_long), None, POINTER(BEPoint)),
+ (POINTER(LEPoint), "&T{<l:x:<l:y:}".replace('l', s_long), None, POINTER(LEPoint)),
]
if __name__ == "__main__":
diff --git a/Lib/ctypes/test/test_pickling.py b/Lib/ctypes/test/test_pickling.py
index c4a79b9..73528d4 100644
--- a/Lib/ctypes/test/test_pickling.py
+++ b/Lib/ctypes/test/test_pickling.py
@@ -69,7 +69,7 @@ class PickleTest:
def test_wchar(self):
self.dumps(c_char(b"x"))
# Issue 5049
- self.dumps(c_wchar("x"))
+ self.dumps(c_wchar(u"x"))
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
name = 'PickleTest_%s' % proto
diff --git a/Lib/ctypes/test/test_pointers.py b/Lib/ctypes/test/test_pointers.py
index e975158..4a8887c 100644
--- a/Lib/ctypes/test/test_pointers.py
+++ b/Lib/ctypes/test/test_pointers.py
@@ -5,8 +5,8 @@ import _ctypes_test
ctype_types = [c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint,
c_long, c_ulong, c_longlong, c_ulonglong, c_double, c_float]
-python_types = [int, int, int, int, int, int,
- int, int, int, int, float, float]
+python_types = [int, int, int, int, int, long,
+ int, long, long, long, float, float]
class PointersTestCase(unittest.TestCase):
@@ -22,10 +22,7 @@ class PointersTestCase(unittest.TestCase):
def test_pass_pointers(self):
dll = CDLL(_ctypes_test.__file__)
func = dll._testfunc_p_p
- if sizeof(c_longlong) == sizeof(c_void_p):
- func.restype = c_longlong
- else:
- func.restype = c_long
+ func.restype = c_long
i = c_int(12345678)
## func.argtypes = (POINTER(c_int),)
@@ -148,10 +145,10 @@ class PointersTestCase(unittest.TestCase):
func.restype = c_char_p
argv = (c_char_p * 2)()
argc = c_int( 2 )
- argv[0] = b'hello'
- argv[1] = b'world'
+ argv[0] = 'hello'
+ argv[1] = 'world'
result = func( byref(argc), argv )
- self.assertEqual(result, b'world')
+ assert result == 'world', result
def test_bug_1467852(self):
# http://sourceforge.net/tracker/?func=detail&atid=532154&aid=1467852&group_id=71702
@@ -168,16 +165,16 @@ class PointersTestCase(unittest.TestCase):
def test_c_void_p(self):
# http://sourceforge.net/tracker/?func=detail&aid=1518190&group_id=5470&atid=105470
if sizeof(c_void_p) == 4:
- self.assertEqual(c_void_p(0xFFFFFFFF).value,
+ self.assertEqual(c_void_p(0xFFFFFFFFL).value,
c_void_p(-1).value)
- self.assertEqual(c_void_p(0xFFFFFFFFFFFFFFFF).value,
+ self.assertEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value,
c_void_p(-1).value)
elif sizeof(c_void_p) == 8:
- self.assertEqual(c_void_p(0xFFFFFFFF).value,
- 0xFFFFFFFF)
- self.assertEqual(c_void_p(0xFFFFFFFFFFFFFFFF).value,
+ self.assertEqual(c_void_p(0xFFFFFFFFL).value,
+ 0xFFFFFFFFL)
+ self.assertEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value,
c_void_p(-1).value)
- self.assertEqual(c_void_p(0xFFFFFFFFFFFFFFFFFFFFFFFF).value,
+ self.assertEqual(c_void_p(0xFFFFFFFFFFFFFFFFFFFFFFFFL).value,
c_void_p(-1).value)
self.assertRaises(TypeError, c_void_p, 3.14) # make sure floats are NOT accepted
diff --git a/Lib/ctypes/test/test_prototypes.py b/Lib/ctypes/test/test_prototypes.py
index cd0c649..a10317b 100644
--- a/Lib/ctypes/test/test_prototypes.py
+++ b/Lib/ctypes/test/test_prototypes.py
@@ -34,7 +34,7 @@ def positive_address(a):
# View the bits in `a` as unsigned instead.
import struct
num_bits = struct.calcsize("P") * 8 # num bits in native machine address
- a += 1 << num_bits
+ a += 1L << num_bits
assert a >= 0
return a
@@ -58,7 +58,7 @@ class CharPointersTestCase(unittest.TestCase):
try:
func()
- except TypeError as details:
+ except TypeError, details:
self.assertEqual(str(details), "required argument 'input' missing")
else:
self.fail("TypeError not raised")
@@ -69,10 +69,7 @@ class CharPointersTestCase(unittest.TestCase):
def test_int_pointer_arg(self):
func = testdll._testfunc_p_p
- if sizeof(c_longlong) == sizeof(c_void_p):
- func.restype = c_longlong
- else:
- func.restype = c_long
+ func.restype = c_long
self.assertEqual(0, func(0))
ci = c_int(0)
@@ -96,14 +93,14 @@ class CharPointersTestCase(unittest.TestCase):
func.argtypes = POINTER(c_char),
self.assertEqual(None, func(None))
- self.assertEqual(b"123", func(b"123"))
+ self.assertEqual("123", func("123"))
self.assertEqual(None, func(c_char_p(None)))
- self.assertEqual(b"123", func(c_char_p(b"123")))
+ self.assertEqual("123", func(c_char_p("123")))
- self.assertEqual(b"123", func(c_buffer(b"123")))
- ca = c_char(b"a")
- self.assertEqual(ord(b"a"), func(pointer(ca))[0])
- self.assertEqual(ord(b"a"), func(byref(ca))[0])
+ self.assertEqual("123", func(c_buffer("123")))
+ ca = c_char("a")
+ self.assertEqual("a", func(pointer(ca))[0])
+ self.assertEqual("a", func(byref(ca))[0])
def test_c_char_p_arg(self):
func = testdll._testfunc_p_p
@@ -111,14 +108,14 @@ class CharPointersTestCase(unittest.TestCase):
func.argtypes = c_char_p,
self.assertEqual(None, func(None))
- self.assertEqual(b"123", func(b"123"))
+ self.assertEqual("123", func("123"))
self.assertEqual(None, func(c_char_p(None)))
- self.assertEqual(b"123", func(c_char_p(b"123")))
+ self.assertEqual("123", func(c_char_p("123")))
- self.assertEqual(b"123", func(c_buffer(b"123")))
- ca = c_char(b"a")
- self.assertEqual(ord(b"a"), func(pointer(ca))[0])
- self.assertEqual(ord(b"a"), func(byref(ca))[0])
+ self.assertEqual("123", func(c_buffer("123")))
+ ca = c_char("a")
+ self.assertEqual("a", func(pointer(ca))[0])
+ self.assertEqual("a", func(byref(ca))[0])
def test_c_void_p_arg(self):
func = testdll._testfunc_p_p
@@ -126,14 +123,14 @@ class CharPointersTestCase(unittest.TestCase):
func.argtypes = c_void_p,
self.assertEqual(None, func(None))
- self.assertEqual(b"123", func(b"123"))
- self.assertEqual(b"123", func(c_char_p(b"123")))
+ self.assertEqual("123", func("123"))
+ self.assertEqual("123", func(c_char_p("123")))
self.assertEqual(None, func(c_char_p(None)))
- self.assertEqual(b"123", func(c_buffer(b"123")))
- ca = c_char(b"a")
- self.assertEqual(ord(b"a"), func(pointer(ca))[0])
- self.assertEqual(ord(b"a"), func(byref(ca))[0])
+ self.assertEqual("123", func(c_buffer("123")))
+ ca = c_char("a")
+ self.assertEqual("a", func(pointer(ca))[0])
+ self.assertEqual("a", func(byref(ca))[0])
func(byref(c_int()))
func(pointer(c_int()))
@@ -146,7 +143,7 @@ class CharPointersTestCase(unittest.TestCase):
func.argtypes = c_void_p,
self.assertEqual(None, func(c_wchar_p(None)))
- self.assertEqual("123", func(c_wchar_p("123")))
+ self.assertEqual(u"123", func(c_wchar_p(u"123")))
def test_instance(self):
func = testdll._testfunc_p_p
@@ -176,24 +173,24 @@ class WCharPointersTestCase(unittest.TestCase):
func.argtypes = POINTER(c_wchar),
self.assertEqual(None, func(None))
- self.assertEqual("123", func("123"))
+ self.assertEqual(u"123", func(u"123"))
self.assertEqual(None, func(c_wchar_p(None)))
- self.assertEqual("123", func(c_wchar_p("123")))
+ self.assertEqual(u"123", func(c_wchar_p(u"123")))
- self.assertEqual("123", func(c_wbuffer("123")))
+ self.assertEqual(u"123", func(c_wbuffer(u"123")))
ca = c_wchar("a")
- self.assertEqual("a", func(pointer(ca))[0])
- self.assertEqual("a", func(byref(ca))[0])
+ self.assertEqual(u"a", func(pointer(ca))[0])
+ self.assertEqual(u"a", func(byref(ca))[0])
def test_c_wchar_p_arg(self):
func = testdll._testfunc_p_p
func.restype = c_wchar_p
func.argtypes = c_wchar_p,
- c_wchar_p.from_param("123")
+ c_wchar_p.from_param(u"123")
self.assertEqual(None, func(None))
- self.assertEqual("123", func("123"))
+ self.assertEqual("123", func(u"123"))
self.assertEqual(None, func(c_wchar_p(None)))
self.assertEqual("123", func(c_wchar_p("123")))
diff --git a/Lib/ctypes/test/test_python_api.py b/Lib/ctypes/test/test_python_api.py
index 9c13746..bc2ffd0 100644
--- a/Lib/ctypes/test/test_python_api.py
+++ b/Lib/ctypes/test/test_python_api.py
@@ -1,6 +1,6 @@
from ctypes import *
import unittest, sys
-from test import support
+from ctypes.test import requires
################################################################
# This section should be moved into ctypes\__init__.py, when it's ready.
@@ -17,44 +17,45 @@ else:
class PythonAPITestCase(unittest.TestCase):
- def test_PyBytes_FromStringAndSize(self):
- PyBytes_FromStringAndSize = pythonapi.PyBytes_FromStringAndSize
+ def test_PyString_FromStringAndSize(self):
+ PyString_FromStringAndSize = pythonapi.PyString_FromStringAndSize
- PyBytes_FromStringAndSize.restype = py_object
- PyBytes_FromStringAndSize.argtypes = c_char_p, c_py_ssize_t
+ PyString_FromStringAndSize.restype = py_object
+ PyString_FromStringAndSize.argtypes = c_char_p, c_py_ssize_t
- self.assertEqual(PyBytes_FromStringAndSize(b"abcdefghi", 3), b"abc")
+ self.assertEqual(PyString_FromStringAndSize("abcdefghi", 3), "abc")
- @support.refcount_test
def test_PyString_FromString(self):
- pythonapi.PyBytes_FromString.restype = py_object
- pythonapi.PyBytes_FromString.argtypes = (c_char_p,)
+ pythonapi.PyString_FromString.restype = py_object
+ pythonapi.PyString_FromString.argtypes = (c_char_p,)
- s = b"abc"
+ s = "abc"
refcnt = grc(s)
- pyob = pythonapi.PyBytes_FromString(s)
+ pyob = pythonapi.PyString_FromString(s)
self.assertEqual(grc(s), refcnt)
self.assertEqual(s, pyob)
del pyob
self.assertEqual(grc(s), refcnt)
- @support.refcount_test
- def test_PyLong_Long(self):
+ # This test is unreliable, because it is possible that code in
+ # unittest changes the refcount of the '42' integer. So, it
+ # is disabled by default.
+ def test_PyInt_Long(self):
+ requires("refcount")
ref42 = grc(42)
- pythonapi.PyLong_FromLong.restype = py_object
- self.assertEqual(pythonapi.PyLong_FromLong(42), 42)
+ pythonapi.PyInt_FromLong.restype = py_object
+ self.assertEqual(pythonapi.PyInt_FromLong(42), 42)
self.assertEqual(grc(42), ref42)
- pythonapi.PyLong_AsLong.argtypes = (py_object,)
- pythonapi.PyLong_AsLong.restype = c_long
+ pythonapi.PyInt_AsLong.argtypes = (py_object,)
+ pythonapi.PyInt_AsLong.restype = c_long
- res = pythonapi.PyLong_AsLong(42)
+ res = pythonapi.PyInt_AsLong(42)
self.assertEqual(grc(res), ref42 + 1)
del res
self.assertEqual(grc(42), ref42)
- @support.refcount_test
def test_PyObj_FromPtr(self):
s = "abc def ghi jkl"
ref = grc(s)
@@ -71,11 +72,11 @@ class PythonAPITestCase(unittest.TestCase):
PyOS_snprintf.argtypes = POINTER(c_char), c_size_t, c_char_p
buf = c_buffer(256)
- PyOS_snprintf(buf, sizeof(buf), b"Hello from %s", b"ctypes")
- self.assertEqual(buf.value, b"Hello from ctypes")
+ PyOS_snprintf(buf, sizeof(buf), "Hello from %s", "ctypes")
+ self.assertEqual(buf.value, "Hello from ctypes")
- PyOS_snprintf(buf, sizeof(buf), b"Hello from %s (%d, %d, %d)", b"ctypes", 1, 2, 3)
- self.assertEqual(buf.value, b"Hello from ctypes (1, 2, 3)")
+ PyOS_snprintf(buf, sizeof(buf), "Hello from %s", "ctypes", 1, 2, 3)
+ self.assertEqual(buf.value, "Hello from ctypes")
# not enough arguments
self.assertRaises(TypeError, PyOS_snprintf, buf)
diff --git a/Lib/ctypes/test/test_random_things.py b/Lib/ctypes/test/test_random_things.py
index ee5b212..d72b7c8 100644
--- a/Lib/ctypes/test/test_random_things.py
+++ b/Lib/ctypes/test/test_random_things.py
@@ -2,7 +2,7 @@ from ctypes import *
import unittest, sys
def callback_func(arg):
- 42 / arg
+ 42 // arg
raise ValueError(arg)
@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
@@ -16,8 +16,8 @@ class call_function_TestCase(unittest.TestCase):
windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p
windll.kernel32.GetProcAddress.restype = c_void_p
- hdll = windll.kernel32.LoadLibraryA(b"kernel32")
- funcaddr = windll.kernel32.GetProcAddress(hdll, b"GetModuleHandleA")
+ hdll = windll.kernel32.LoadLibraryA("kernel32")
+ funcaddr = windll.kernel32.GetProcAddress(hdll, "GetModuleHandleA")
self.assertEqual(call_function(funcaddr, (None,)),
windll.kernel32.GetModuleHandleA(None))
@@ -36,9 +36,9 @@ class CallbackTracbackTestCase(unittest.TestCase):
def capture_stderr(self, func, *args, **kw):
# helper - call function 'func', and return the captured stderr
- import io
+ import StringIO
old_stderr = sys.stderr
- logger = sys.stderr = io.StringIO()
+ logger = sys.stderr = StringIO.StringIO()
try:
func(*args, **kw)
finally:
@@ -65,10 +65,10 @@ class CallbackTracbackTestCase(unittest.TestCase):
def test_TypeErrorDivisionError(self):
cb = CFUNCTYPE(c_int, c_char_p)(callback_func)
- out = self.capture_stderr(cb, b"spam")
+ out = self.capture_stderr(cb, "spam")
self.assertEqual(out.splitlines()[-1],
"TypeError: "
- "unsupported operand type(s) for /: 'int' and 'bytes'")
+ "unsupported operand type(s) for //: 'int' and 'str'")
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/ctypes/test/test_refcounts.py b/Lib/ctypes/test/test_refcounts.py
index f2edfa6..2031346 100644
--- a/Lib/ctypes/test/test_refcounts.py
+++ b/Lib/ctypes/test/test_refcounts.py
@@ -1,5 +1,4 @@
import unittest
-from test import support
import ctypes
import gc
@@ -11,7 +10,6 @@ dll = ctypes.CDLL(_ctypes_test.__file__)
class RefcountTestCase(unittest.TestCase):
- @support.refcount_test
def test_1(self):
from sys import getrefcount as grc
@@ -36,7 +34,6 @@ class RefcountTestCase(unittest.TestCase):
self.assertEqual(grc(callback), 2)
- @support.refcount_test
def test_refcount(self):
from sys import getrefcount as grc
def func(*args):
diff --git a/Lib/ctypes/test/test_repr.py b/Lib/ctypes/test/test_repr.py
index 60a2c80..99cc556 100644
--- a/Lib/ctypes/test/test_repr.py
+++ b/Lib/ctypes/test/test_repr.py
@@ -22,8 +22,8 @@ class ReprTest(unittest.TestCase):
self.assertEqual("<X object at", repr(typ(42))[:12])
def test_char(self):
- self.assertEqual("c_char(b'x')", repr(c_char(b'x')))
- self.assertEqual("<X object at", repr(X(b'x'))[:12])
+ self.assertEqual("c_char('x')", repr(c_char('x')))
+ self.assertEqual("<X object at", repr(X('x'))[:12])
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_returnfuncptrs.py b/Lib/ctypes/test/test_returnfuncptrs.py
index 1974f40..0827f0a 100644
--- a/Lib/ctypes/test/test_returnfuncptrs.py
+++ b/Lib/ctypes/test/test_returnfuncptrs.py
@@ -1,5 +1,6 @@
import unittest
from ctypes import *
+import os
import _ctypes_test
@@ -12,12 +13,10 @@ class ReturnFuncPtrTestCase(unittest.TestCase):
get_strchr = dll.get_strchr
get_strchr.restype = CFUNCTYPE(c_char_p, c_char_p, c_char)
strchr = get_strchr()
- self.assertEqual(strchr(b"abcdef", b"b"), b"bcdef")
- self.assertEqual(strchr(b"abcdef", b"x"), None)
- self.assertEqual(strchr(b"abcdef", 98), b"bcdef")
- self.assertEqual(strchr(b"abcdef", 107), None)
- self.assertRaises(ArgumentError, strchr, b"abcdef", 3.0)
- self.assertRaises(TypeError, strchr, b"abcdef")
+ self.assertEqual(strchr("abcdef", "b"), "bcdef")
+ self.assertEqual(strchr("abcdef", "x"), None)
+ self.assertRaises(ArgumentError, strchr, "abcdef", 3)
+ self.assertRaises(TypeError, strchr, "abcdef")
def test_without_prototype(self):
dll = CDLL(_ctypes_test.__file__)
@@ -28,10 +27,10 @@ class ReturnFuncPtrTestCase(unittest.TestCase):
# _CFuncPtr instances are now callable with an integer argument
# which denotes a function address:
strchr = CFUNCTYPE(c_char_p, c_char_p, c_char)(addr)
- self.assertTrue(strchr(b"abcdef", b"b"), "bcdef")
- self.assertEqual(strchr(b"abcdef", b"x"), None)
- self.assertRaises(ArgumentError, strchr, b"abcdef", 3.0)
- self.assertRaises(TypeError, strchr, b"abcdef")
+ self.assertTrue(strchr("abcdef", "b"), "bcdef")
+ self.assertEqual(strchr("abcdef", "x"), None)
+ self.assertRaises(ArgumentError, strchr, "abcdef", 3)
+ self.assertRaises(TypeError, strchr, "abcdef")
def test_from_dll(self):
dll = CDLL(_ctypes_test.__file__)
diff --git a/Lib/ctypes/test/test_simplesubclasses.py b/Lib/ctypes/test/test_simplesubclasses.py
index 3da2794..1b73fb3 100644
--- a/Lib/ctypes/test/test_simplesubclasses.py
+++ b/Lib/ctypes/test/test_simplesubclasses.py
@@ -2,10 +2,12 @@ import unittest
from ctypes import *
class MyInt(c_int):
- def __eq__(self, other):
+ def __cmp__(self, other):
if type(other) != MyInt:
- return NotImplementedError
- return self.value == other.value
+ return -1
+ return cmp(self.value, other.value)
+ def __hash__(self): # Silence Py3k warning
+ return hash(self.value)
class Test(unittest.TestCase):
diff --git a/Lib/ctypes/test/test_sizes.py b/Lib/ctypes/test/test_sizes.py
index 4ceacbc..f9b5e97 100644
--- a/Lib/ctypes/test/test_sizes.py
+++ b/Lib/ctypes/test/test_sizes.py
@@ -2,6 +2,7 @@
from ctypes import *
+import sys
import unittest
diff --git a/Lib/ctypes/test/test_slicing.py b/Lib/ctypes/test/test_slicing.py
index a3932f1..a9ee3a8 100644
--- a/Lib/ctypes/test/test_slicing.py
+++ b/Lib/ctypes/test/test_slicing.py
@@ -6,8 +6,8 @@ import _ctypes_test
class SlicesTestCase(unittest.TestCase):
def test_getslice_cint(self):
- a = (c_int * 100)(*range(1100, 1200))
- b = list(range(1100, 1200))
+ a = (c_int * 100)(*xrange(1100, 1200))
+ b = range(1100, 1200)
self.assertEqual(a[0:2], b[0:2])
self.assertEqual(a[0:2:], b[0:2:])
self.assertEqual(len(a), len(b))
@@ -22,20 +22,20 @@ class SlicesTestCase(unittest.TestCase):
self.assertEqual(a[2:6:4], b[2:6:4])
a[0:5] = range(5, 10)
- self.assertEqual(a[0:5], list(range(5, 10)))
- self.assertEqual(a[0:5:], list(range(5, 10)))
- self.assertEqual(a[4::-1], list(range(9, 4, -1)))
+ self.assertEqual(a[0:5], range(5, 10))
+ self.assertEqual(a[0:5:], range(5, 10))
+ self.assertEqual(a[4::-1], range(9, 4, -1))
def test_setslice_cint(self):
- a = (c_int * 100)(*range(1100, 1200))
- b = list(range(1100, 1200))
+ a = (c_int * 100)(*xrange(1100, 1200))
+ b = range(1100, 1200)
- a[32:47] = list(range(32, 47))
- self.assertEqual(a[32:47], list(range(32, 47)))
+ a[32:47] = range(32, 47)
+ self.assertEqual(a[32:47], range(32, 47))
a[32:47] = range(132, 147)
- self.assertEqual(a[32:47:], list(range(132, 147)))
+ self.assertEqual(a[32:47:], range(132, 147))
a[46:31:-1] = range(232, 247)
- self.assertEqual(a[32:47:1], list(range(246, 231, -1)))
+ self.assertEqual(a[32:47:1], range(246, 231, -1))
a[32:47] = range(1132, 1147)
self.assertEqual(a[:], b)
@@ -46,21 +46,25 @@ class SlicesTestCase(unittest.TestCase):
b[33::-3] = range(12)
self.assertEqual(a[:], b)
- from operator import setitem
+ from operator import setslice, setitem
# TypeError: int expected instead of str instance
+ self.assertRaises(TypeError, setslice, a, 0, 5, "abcde")
self.assertRaises(TypeError, setitem, a, slice(0, 5), "abcde")
# TypeError: int expected instead of str instance
+ self.assertRaises(TypeError, setslice, a, 0, 5, ["a", "b", "c", "d", "e"])
self.assertRaises(TypeError, setitem, a, slice(0, 5),
["a", "b", "c", "d", "e"])
# TypeError: int expected instead of float instance
+ self.assertRaises(TypeError, setslice, a, 0, 5, [1, 2, 3, 4, 3.14])
self.assertRaises(TypeError, setitem, a, slice(0, 5),
[1, 2, 3, 4, 3.14])
# ValueError: Can only assign sequence of same size
+ self.assertRaises(ValueError, setslice, a, 0, 5, range(32))
self.assertRaises(ValueError, setitem, a, slice(0, 5), range(32))
def test_char_ptr(self):
- s = b"abcdefghijklmnopqrstuvwxyz"
+ s = "abcdefghijklmnopqrstuvwxyz"
dll = CDLL(_ctypes_test.__file__)
dll.my_strdup.restype = POINTER(c_char)
@@ -83,19 +87,21 @@ class SlicesTestCase(unittest.TestCase):
self.assertRaises(ValueError, operator.getitem,
res, slice(-5, None, None))
+ self.assertRaises(TypeError, operator.setslice,
+ res, 0, 5, u"abcde")
self.assertRaises(TypeError, operator.setitem,
- res, slice(0, 5), "abcde")
+ res, slice(0, 5), u"abcde")
dll.my_free(res)
dll.my_strdup.restype = POINTER(c_byte)
res = dll.my_strdup(s)
- self.assertEqual(res[:len(s)], list(range(ord("a"), ord("z")+1)))
- self.assertEqual(res[:len(s):], list(range(ord("a"), ord("z")+1)))
+ self.assertEqual(res[:len(s)], range(ord("a"), ord("z")+1))
+ self.assertEqual(res[:len(s):], range(ord("a"), ord("z")+1))
dll.my_free(res)
def test_char_ptr_with_free(self):
dll = CDLL(_ctypes_test.__file__)
- s = b"abcdefghijklmnopqrstuvwxyz"
+ s = "abcdefghijklmnopqrstuvwxyz"
class allocated_c_char_p(c_char_p):
pass
@@ -116,7 +122,7 @@ class SlicesTestCase(unittest.TestCase):
def test_char_array(self):
- s = b"abcdefghijklmnopqrstuvwxyz\0"
+ s = "abcdefghijklmnopqrstuvwxyz\0"
p = (c_char * 27)(*s)
self.assertEqual(p[:], s)
@@ -128,21 +134,23 @@ class SlicesTestCase(unittest.TestCase):
@need_symbol('c_wchar')
def test_wchar_ptr(self):
- s = "abcdefghijklmnopqrstuvwxyz\0"
+ s = u"abcdefghijklmnopqrstuvwxyz\0"
dll = CDLL(_ctypes_test.__file__)
dll.my_wcsdup.restype = POINTER(c_wchar)
dll.my_wcsdup.argtypes = POINTER(c_wchar),
dll.my_free.restype = None
- res = dll.my_wcsdup(s[:-1])
+ res = dll.my_wcsdup(s)
self.assertEqual(res[:len(s)], s)
self.assertEqual(res[:len(s):], s)
self.assertEqual(res[len(s)-1:-1:-1], s[::-1])
self.assertEqual(res[len(s)-1:5:-7], s[:5:-7])
import operator
+ self.assertRaises(TypeError, operator.setslice,
+ res, 0, 5, u"abcde")
self.assertRaises(TypeError, operator.setitem,
- res, slice(0, 5), "abcde")
+ res, slice(0, 5), u"abcde")
dll.my_free(res)
if sizeof(c_wchar) == sizeof(c_short):
@@ -153,8 +161,8 @@ class SlicesTestCase(unittest.TestCase):
dll.my_wcsdup.restype = POINTER(c_long)
else:
self.skipTest('Pointers to c_wchar are not supported')
- res = dll.my_wcsdup(s[:-1])
- tmpl = list(range(ord("a"), ord("z")+1))
+ res = dll.my_wcsdup(s)
+ tmpl = range(ord("a"), ord("z")+1)
self.assertEqual(res[:len(s)-1], tmpl)
self.assertEqual(res[:len(s)-1:], tmpl)
self.assertEqual(res[len(s)-2:-1:-1], tmpl[::-1])
diff --git a/Lib/ctypes/test/test_stringptr.py b/Lib/ctypes/test/test_stringptr.py
index c20951f..abed58b 100644
--- a/Lib/ctypes/test/test_stringptr.py
+++ b/Lib/ctypes/test/test_stringptr.py
@@ -1,5 +1,4 @@
import unittest
-from test import support
from ctypes import *
import _ctypes_test
@@ -8,7 +7,6 @@ lib = CDLL(_ctypes_test.__file__)
class StringPtrTestCase(unittest.TestCase):
- @support.refcount_test
def test__POINTER_c_char(self):
class X(Structure):
_fields_ = [("str", POINTER(c_char))]
@@ -16,7 +14,7 @@ class StringPtrTestCase(unittest.TestCase):
# NULL pointer access
self.assertRaises(ValueError, getattr, x.str, "contents")
- b = c_buffer(b"Hello, World")
+ b = c_buffer("Hello, World")
from sys import getrefcount as grc
self.assertEqual(grc(b), 2)
x.str = b
@@ -37,10 +35,10 @@ class StringPtrTestCase(unittest.TestCase):
# c_char_p and Python string is compatible
# c_char_p and c_buffer is NOT compatible
self.assertEqual(x.str, None)
- x.str = b"Hello, World"
- self.assertEqual(x.str, b"Hello, World")
- b = c_buffer(b"Hello, World")
- self.assertRaises(TypeError, setattr, x, b"str", b)
+ x.str = "Hello, World"
+ self.assertEqual(x.str, "Hello, World")
+ b = c_buffer("Hello, World")
+ self.assertRaises(TypeError, setattr, x, "str", b)
def test_functions(self):
@@ -50,28 +48,28 @@ class StringPtrTestCase(unittest.TestCase):
# c_char_p and Python string is compatible
# c_char_p and c_buffer are now compatible
strchr.argtypes = c_char_p, c_char
- self.assertEqual(strchr(b"abcdef", b"c"), b"cdef")
- self.assertEqual(strchr(c_buffer(b"abcdef"), b"c"), b"cdef")
+ self.assertEqual(strchr("abcdef", "c"), "cdef")
+ self.assertEqual(strchr(c_buffer("abcdef"), "c"), "cdef")
# POINTER(c_char) and Python string is NOT compatible
# POINTER(c_char) and c_buffer() is compatible
strchr.argtypes = POINTER(c_char), c_char
- buf = c_buffer(b"abcdef")
- self.assertEqual(strchr(buf, b"c"), b"cdef")
- self.assertEqual(strchr(b"abcdef", b"c"), b"cdef")
+ buf = c_buffer("abcdef")
+ self.assertEqual(strchr(buf, "c"), "cdef")
+ self.assertEqual(strchr("abcdef", "c"), "cdef")
# XXX These calls are dangerous, because the first argument
# to strchr is no longer valid after the function returns!
# So we must keep a reference to buf separately
strchr.restype = POINTER(c_char)
- buf = c_buffer(b"abcdef")
- r = strchr(buf, b"c")
+ buf = c_buffer("abcdef")
+ r = strchr(buf, "c")
x = r[0], r[1], r[2], r[3], r[4]
- self.assertEqual(x, (b"c", b"d", b"e", b"f", b"\000"))
+ self.assertEqual(x, ("c", "d", "e", "f", "\000"))
del buf
- # Because r is a pointer to memory that is freed after deleting buf,
- # the pointer is hanging and using it would reference freed memory.
+ # x1 will NOT be the same as x, usually:
+ x1 = r[0], r[1], r[2], r[3], r[4]
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/ctypes/test/test_strings.py b/Lib/ctypes/test/test_strings.py
index 5434efd..879c58a 100644
--- a/Lib/ctypes/test/test_strings.py
+++ b/Lib/ctypes/test/test_strings.py
@@ -1,47 +1,54 @@
import unittest
from ctypes import *
from ctypes.test import need_symbol
+from test import test_support
class StringArrayTestCase(unittest.TestCase):
def test(self):
BUF = c_char * 4
- buf = BUF(b"a", b"b", b"c")
- self.assertEqual(buf.value, b"abc")
- self.assertEqual(buf.raw, b"abc\000")
+ buf = BUF("a", "b", "c")
+ self.assertEqual(buf.value, "abc")
+ self.assertEqual(buf.raw, "abc\000")
- buf.value = b"ABCD"
- self.assertEqual(buf.value, b"ABCD")
- self.assertEqual(buf.raw, b"ABCD")
+ buf.value = "ABCD"
+ self.assertEqual(buf.value, "ABCD")
+ self.assertEqual(buf.raw, "ABCD")
- buf.value = b"x"
- self.assertEqual(buf.value, b"x")
- self.assertEqual(buf.raw, b"x\000CD")
+ buf.value = "x"
+ self.assertEqual(buf.value, "x")
+ self.assertEqual(buf.raw, "x\000CD")
- buf[1] = b"Z"
- self.assertEqual(buf.value, b"xZCD")
- self.assertEqual(buf.raw, b"xZCD")
+ buf[1] = "Z"
+ self.assertEqual(buf.value, "xZCD")
+ self.assertEqual(buf.raw, "xZCD")
- self.assertRaises(ValueError, setattr, buf, "value", b"aaaaaaaa")
+ self.assertRaises(ValueError, setattr, buf, "value", "aaaaaaaa")
self.assertRaises(TypeError, setattr, buf, "value", 42)
- def test_c_buffer_value(self):
+ def test_c_buffer_value(self, memoryview=memoryview):
buf = c_buffer(32)
- buf.value = b"Hello, World"
- self.assertEqual(buf.value, b"Hello, World")
+ buf.value = "Hello, World"
+ self.assertEqual(buf.value, "Hello, World")
- self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"Hello, World"))
- self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"abc"))
- self.assertRaises(ValueError, setattr, buf, "raw", memoryview(b"x" * 100))
+ self.assertRaises(TypeError, setattr, buf, "value", memoryview("Hello, World"))
+ self.assertRaises(TypeError, setattr, buf, "value", memoryview("abc"))
+ self.assertRaises(ValueError, setattr, buf, "raw", memoryview("x" * 100))
- def test_c_buffer_raw(self):
+ def test_c_buffer_raw(self, memoryview=memoryview):
buf = c_buffer(32)
- buf.raw = memoryview(b"Hello, World")
- self.assertEqual(buf.value, b"Hello, World")
- self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"abc"))
- self.assertRaises(ValueError, setattr, buf, "raw", memoryview(b"x" * 100))
+ buf.raw = memoryview("Hello, World")
+ self.assertEqual(buf.value, "Hello, World")
+ self.assertRaises(TypeError, setattr, buf, "value", memoryview("abc"))
+ self.assertRaises(ValueError, setattr, buf, "raw", memoryview("x" * 100))
+
+ def test_c_buffer_deprecated(self):
+ # Compatibility with 2.x
+ with test_support.check_py3k_warnings():
+ self.test_c_buffer_value(buffer)
+ self.test_c_buffer_raw(buffer)
def test_param_1(self):
BUF = c_char * 4
@@ -66,24 +73,17 @@ class WStringArrayTestCase(unittest.TestCase):
def test(self):
BUF = c_wchar * 4
- buf = BUF("a", "b", "c")
- self.assertEqual(buf.value, "abc")
-
- buf.value = "ABCD"
- self.assertEqual(buf.value, "ABCD")
+ buf = BUF(u"a", u"b", u"c")
+ self.assertEqual(buf.value, u"abc")
- buf.value = "x"
- self.assertEqual(buf.value, "x")
+ buf.value = u"ABCD"
+ self.assertEqual(buf.value, u"ABCD")
- buf[1] = "Z"
- self.assertEqual(buf.value, "xZCD")
+ buf.value = u"x"
+ self.assertEqual(buf.value, u"x")
- @unittest.skipIf(sizeof(c_wchar) < 4,
- "sizeof(wchar_t) is smaller than 4 bytes")
- def test_nonbmp(self):
- u = chr(0x10ffff)
- w = c_wchar(u)
- self.assertEqual(w.value, u)
+ buf[1] = u"Z"
+ self.assertEqual(buf.value, u"xZCD")
class StringTestCase(unittest.TestCase):
@unittest.skip('test disabled')
@@ -111,7 +111,7 @@ class StringTestCase(unittest.TestCase):
self.assertEqual(cs.value, "XY")
self.assertEqual(cs.raw, "XY\000\000\000\000\000")
- self.assertRaises(TypeError, c_string, "123")
+ self.assertRaises(TypeError, c_string, u"123")
@unittest.skip('test disabled')
def test_sized_strings(self):
@@ -157,14 +157,14 @@ class StringTestCase(unittest.TestCase):
@need_symbol('c_wchar')
class WStringTestCase(unittest.TestCase):
def test_wchar(self):
- c_wchar("x")
- repr(byref(c_wchar("x")))
+ c_wchar(u"x")
+ repr(byref(c_wchar(u"x")))
c_wchar("x")
@unittest.skip('test disabled')
def test_basic_wstrings(self):
- cs = c_wstring("abcdef")
+ cs = c_wstring(u"abcdef")
# XXX This behaviour is about to change:
# len returns the size of the internal buffer in bytes.
@@ -172,41 +172,41 @@ class WStringTestCase(unittest.TestCase):
self.assertEqual(sizeof(cs), 14)
# The value property is the string up to the first terminating NUL.
- self.assertEqual(cs.value, "abcdef")
- self.assertEqual(c_wstring("abc\000def").value, "abc")
+ self.assertEqual(cs.value, u"abcdef")
+ self.assertEqual(c_wstring(u"abc\000def").value, u"abc")
- self.assertEqual(c_wstring("abc\000def").value, "abc")
+ self.assertEqual(c_wstring(u"abc\000def").value, u"abc")
# The raw property is the total buffer contents:
- self.assertEqual(cs.raw, "abcdef\000")
- self.assertEqual(c_wstring("abc\000def").raw, "abc\000def\000")
+ self.assertEqual(cs.raw, u"abcdef\000")
+ self.assertEqual(c_wstring(u"abc\000def").raw, u"abc\000def\000")
# We can change the value:
- cs.value = "ab"
- self.assertEqual(cs.value, "ab")
- self.assertEqual(cs.raw, "ab\000\000\000\000\000")
+ cs.value = u"ab"
+ self.assertEqual(cs.value, u"ab")
+ self.assertEqual(cs.raw, u"ab\000\000\000\000\000")
self.assertRaises(TypeError, c_wstring, "123")
self.assertRaises(ValueError, c_wstring, 0)
@unittest.skip('test disabled')
def test_toolong(self):
- cs = c_wstring("abcdef")
+ cs = c_wstring(u"abcdef")
# Much too long string:
- self.assertRaises(ValueError, setattr, cs, "value", "123456789012345")
+ self.assertRaises(ValueError, setattr, cs, "value", u"123456789012345")
# One char too long values:
- self.assertRaises(ValueError, setattr, cs, "value", "1234567")
+ self.assertRaises(ValueError, setattr, cs, "value", u"1234567")
def run_test(rep, msg, func, arg):
items = range(rep)
- from time import perf_counter as clock
+ from time import clock
start = clock()
for i in items:
func(arg); func(arg); func(arg); func(arg); func(arg)
stop = clock()
- print("%20s: %.2f us" % (msg, ((stop-start)*1e6/5/rep)))
+ print "%20s: %.2f us" % (msg, ((stop-start)*1e6/5/rep))
def check_perf():
# Construct 5 objects
diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py
index 283ccbf..9a863c9 100644
--- a/Lib/ctypes/test/test_structures.py
+++ b/Lib/ctypes/test/test_structures.py
@@ -1,16 +1,9 @@
-import platform
-import sys
import unittest
from ctypes import *
from ctypes.test import need_symbol
from struct import calcsize
+import _testcapi
import _ctypes_test
-from test import support
-
-# The following definition is meant to be used from time to time to assist
-# temporarily disabling tests on specific architectures while investigations
-# are in progress, to keep buildbots happy.
-MACHINE = platform.machine()
class SubclassesTest(unittest.TestCase):
def test_subclass(self):
@@ -136,7 +129,7 @@ class StructureTestCase(unittest.TestCase):
self.assertEqual(sizeof(XX), 0)
def test_fields(self):
- # test the offset and size attributes of Structure/Union fields.
+ # test the offset and size attributes of Structure/Unoin fields.
class X(Structure):
_fields_ = [("x", c_int),
("y", c_char)]
@@ -209,10 +202,7 @@ class StructureTestCase(unittest.TestCase):
"_pack_": -1}
self.assertRaises(ValueError, type(Structure), "X", (Structure,), d)
- @support.cpython_only
- def test_packed_c_limits(self):
# Issue 15989
- import _testcapi
d = {"_fields_": [("a", c_byte)],
"_pack_": _testcapi.INT_MAX + 1}
self.assertRaises(ValueError, type(Structure), "X", (Structure,), d)
@@ -226,22 +216,22 @@ class StructureTestCase(unittest.TestCase):
("age", c_int)]
self.assertRaises(TypeError, Person, 42)
- self.assertRaises(ValueError, Person, b"asldkjaslkdjaslkdj")
+ self.assertRaises(ValueError, Person, "asldkjaslkdjaslkdj")
self.assertRaises(TypeError, Person, "Name", "HI")
# short enough
- self.assertEqual(Person(b"12345", 5).name, b"12345")
+ self.assertEqual(Person("12345", 5).name, "12345")
# exact fit
- self.assertEqual(Person(b"123456", 5).name, b"123456")
+ self.assertEqual(Person("123456", 5).name, "123456")
# too long
- self.assertRaises(ValueError, Person, b"1234567", 5)
+ self.assertRaises(ValueError, Person, "1234567", 5)
def test_conflicting_initializers(self):
class POINT(Structure):
- _fields_ = [("phi", c_float), ("rho", c_float)]
+ _fields_ = [("x", c_int), ("y", c_int)]
# conflicting positional and keyword args
- self.assertRaisesRegex(TypeError, "phi", POINT, 2, 3, phi=4)
- self.assertRaisesRegex(TypeError, "rho", POINT, 2, 3, rho=4)
+ self.assertRaises(TypeError, POINT, 2, 3, x=4)
+ self.assertRaises(TypeError, POINT, 2, 3, y=4)
# too many initializers
self.assertRaises(TypeError, POINT, 2, 3, 4)
@@ -266,7 +256,7 @@ class StructureTestCase(unittest.TestCase):
class S(Structure):
_fields_ = [(name, c_int)]
- self.assertRaises(TypeError, declare_with_name, b"x")
+ self.assertRaises(TypeError, declare_with_name, u"x\xe9")
def test_intarray_fields(self):
class SomeInts(Structure):
@@ -296,11 +286,11 @@ class StructureTestCase(unittest.TestCase):
("phone", Phone),
("age", c_int)]
- p = Person(b"Someone", (b"1234", b"5678"), 5)
+ p = Person("Someone", ("1234", "5678"), 5)
- self.assertEqual(p.name, b"Someone")
- self.assertEqual(p.phone.areacode, b"1234")
- self.assertEqual(p.phone.number, b"5678")
+ self.assertEqual(p.name, "Someone")
+ self.assertEqual(p.phone.areacode, "1234")
+ self.assertEqual(p.phone.number, "5678")
self.assertEqual(p.age, 5)
@need_symbol('c_wchar')
@@ -309,15 +299,15 @@ class StructureTestCase(unittest.TestCase):
_fields_ = [("name", c_wchar * 12),
("age", c_int)]
- p = PersonW("Someone \xe9")
- self.assertEqual(p.name, "Someone \xe9")
+ p = PersonW(u"Someone")
+ self.assertEqual(p.name, "Someone")
- self.assertEqual(PersonW("1234567890").name, "1234567890")
- self.assertEqual(PersonW("12345678901").name, "12345678901")
+ self.assertEqual(PersonW(u"1234567890").name, u"1234567890")
+ self.assertEqual(PersonW(u"12345678901").name, u"12345678901")
# exact fit
- self.assertEqual(PersonW("123456789012").name, "123456789012")
+ self.assertEqual(PersonW(u"123456789012").name, u"123456789012")
#too long
- self.assertRaises(ValueError, PersonW, "1234567890123")
+ self.assertRaises(ValueError, PersonW, u"1234567890123")
def test_init_errors(self):
class Phone(Structure):
@@ -329,16 +319,26 @@ class StructureTestCase(unittest.TestCase):
("phone", Phone),
("age", c_int)]
- cls, msg = self.get_except(Person, b"Someone", (1, 2))
+ cls, msg = self.get_except(Person, "Someone", (1, 2))
self.assertEqual(cls, RuntimeError)
- self.assertEqual(msg,
- "(Phone) <class 'TypeError'>: "
- "expected bytes, int found")
+ # In Python 2.5, Exception is a new-style class, and the repr changed
+ if issubclass(Exception, object):
+ self.assertEqual(msg,
+ "(Phone) <type 'exceptions.TypeError'>: "
+ "expected string or Unicode object, int found")
+ else:
+ # Compatibility no longer strictly required
+ self.assertEqual(msg,
+ "(Phone) exceptions.TypeError: "
+ "expected string or Unicode object, int found")
- cls, msg = self.get_except(Person, b"Someone", (b"a", b"b", b"c"))
+ cls, msg = self.get_except(Person, "Someone", ("a", "b", "c"))
self.assertEqual(cls, RuntimeError)
- self.assertEqual(msg,
- "(Phone) <class 'TypeError'>: too many initializers")
+ if issubclass(Exception, object):
+ self.assertEqual(msg,
+ "(Phone) <type 'exceptions.TypeError'>: too many initializers")
+ else:
+ self.assertEqual(msg, "(Phone) exceptions.TypeError: too many initializers")
def test_huge_field_name(self):
# issue12881: segfault with large structure field names
@@ -356,7 +356,7 @@ class StructureTestCase(unittest.TestCase):
def get_except(self, func, *args):
try:
func(*args)
- except Exception as detail:
+ except Exception, detail:
return detail.__class__, str(detail)
@unittest.skip('test disabled')
@@ -403,339 +403,26 @@ class StructureTestCase(unittest.TestCase):
self.assertRaises(TypeError, lambda: Z(1, 2, 3, 4, 5, 6, 7))
def test_pass_by_value(self):
- # This should mirror the Test structure
- # in Modules/_ctypes/_ctypes_test.c
- class Test(Structure):
+ # This should mirror the structure in Modules/_ctypes/_ctypes_test.c
+ class X(Structure):
_fields_ = [
('first', c_ulong),
('second', c_ulong),
('third', c_ulong),
]
- s = Test()
+ s = X()
s.first = 0xdeadbeef
s.second = 0xcafebabe
s.third = 0x0bad1dea
dll = CDLL(_ctypes_test.__file__)
func = dll._testfunc_large_struct_update_value
- func.argtypes = (Test,)
- func.restype = None
- func(s)
- self.assertEqual(s.first, 0xdeadbeef)
- self.assertEqual(s.second, 0xcafebabe)
- self.assertEqual(s.third, 0x0bad1dea)
-
- def test_pass_by_value_finalizer(self):
- # bpo-37140: Similar to test_pass_by_value(), but the Python structure
- # has a finalizer (__del__() method): the finalizer must only be called
- # once.
-
- finalizer_calls = []
-
- class Test(Structure):
- _fields_ = [
- ('first', c_ulong),
- ('second', c_ulong),
- ('third', c_ulong),
- ]
- def __del__(self):
- finalizer_calls.append("called")
-
- s = Test(1, 2, 3)
- # Test the StructUnionType_paramfunc() code path which copies the
- # structure: if the stucture is larger than sizeof(void*).
- self.assertGreater(sizeof(s), sizeof(c_void_p))
-
- dll = CDLL(_ctypes_test.__file__)
- func = dll._testfunc_large_struct_update_value
- func.argtypes = (Test,)
- func.restype = None
- func(s)
- # bpo-37140: Passing the structure by refrence must not call
- # its finalizer!
- self.assertEqual(finalizer_calls, [])
- self.assertEqual(s.first, 1)
- self.assertEqual(s.second, 2)
- self.assertEqual(s.third, 3)
-
- # The finalizer must be called exactly once
- s = None
- support.gc_collect()
- self.assertEqual(finalizer_calls, ["called"])
-
- def test_pass_by_value_in_register(self):
- class X(Structure):
- _fields_ = [
- ('first', c_uint),
- ('second', c_uint)
- ]
-
- s = X()
- s.first = 0xdeadbeef
- s.second = 0xcafebabe
- dll = CDLL(_ctypes_test.__file__)
- func = dll._testfunc_reg_struct_update_value
func.argtypes = (X,)
func.restype = None
func(s)
self.assertEqual(s.first, 0xdeadbeef)
self.assertEqual(s.second, 0xcafebabe)
- got = X.in_dll(dll, "last_tfrsuv_arg")
- self.assertEqual(s.first, got.first)
- self.assertEqual(s.second, got.second)
-
- def test_array_in_struct(self):
- # See bpo-22273
-
- # These should mirror the structures in Modules/_ctypes/_ctypes_test.c
- class Test2(Structure):
- _fields_ = [
- ('data', c_ubyte * 16),
- ]
-
- class Test3(Structure):
- _fields_ = [
- ('data', c_double * 2),
- ]
-
- class Test3A(Structure):
- _fields_ = [
- ('data', c_float * 2),
- ]
-
- class Test3B(Test3A):
- _fields_ = [
- ('more_data', c_float * 2),
- ]
-
- s = Test2()
- expected = 0
- for i in range(16):
- s.data[i] = i
- expected += i
- dll = CDLL(_ctypes_test.__file__)
- func = dll._testfunc_array_in_struct1
- func.restype = c_int
- func.argtypes = (Test2,)
- result = func(s)
- self.assertEqual(result, expected)
- # check the passed-in struct hasn't changed
- for i in range(16):
- self.assertEqual(s.data[i], i)
-
- s = Test3()
- s.data[0] = 3.14159
- s.data[1] = 2.71828
- expected = 3.14159 + 2.71828
- func = dll._testfunc_array_in_struct2
- func.restype = c_double
- func.argtypes = (Test3,)
- result = func(s)
- self.assertEqual(result, expected)
- # check the passed-in struct hasn't changed
- self.assertEqual(s.data[0], 3.14159)
- self.assertEqual(s.data[1], 2.71828)
-
- s = Test3B()
- s.data[0] = 3.14159
- s.data[1] = 2.71828
- s.more_data[0] = -3.0
- s.more_data[1] = -2.0
-
- expected = 3.14159 + 2.71828 - 5.0
- func = dll._testfunc_array_in_struct2a
- func.restype = c_double
- func.argtypes = (Test3B,)
- result = func(s)
- self.assertAlmostEqual(result, expected, places=6)
- # check the passed-in struct hasn't changed
- self.assertAlmostEqual(s.data[0], 3.14159, places=6)
- self.assertAlmostEqual(s.data[1], 2.71828, places=6)
- self.assertAlmostEqual(s.more_data[0], -3.0, places=6)
- self.assertAlmostEqual(s.more_data[1], -2.0, places=6)
-
- def test_38368(self):
- class U(Union):
- _fields_ = [
- ('f1', c_uint8 * 16),
- ('f2', c_uint16 * 8),
- ('f3', c_uint32 * 4),
- ]
- u = U()
- u.f3[0] = 0x01234567
- u.f3[1] = 0x89ABCDEF
- u.f3[2] = 0x76543210
- u.f3[3] = 0xFEDCBA98
- f1 = [u.f1[i] for i in range(16)]
- f2 = [u.f2[i] for i in range(8)]
- if sys.byteorder == 'little':
- self.assertEqual(f1, [0x67, 0x45, 0x23, 0x01,
- 0xef, 0xcd, 0xab, 0x89,
- 0x10, 0x32, 0x54, 0x76,
- 0x98, 0xba, 0xdc, 0xfe])
- self.assertEqual(f2, [0x4567, 0x0123, 0xcdef, 0x89ab,
- 0x3210, 0x7654, 0xba98, 0xfedc])
-
- def test_union_by_value(self):
- # See bpo-16575
-
- # These should mirror the structures in Modules/_ctypes/_ctypes_test.c
-
- class Nested1(Structure):
- _fields_ = [
- ('an_int', c_int),
- ('another_int', c_int),
- ]
-
- class Test4(Union):
- _fields_ = [
- ('a_long', c_long),
- ('a_struct', Nested1),
- ]
-
- class Nested2(Structure):
- _fields_ = [
- ('an_int', c_int),
- ('a_union', Test4),
- ]
-
- class Test5(Structure):
- _fields_ = [
- ('an_int', c_int),
- ('nested', Nested2),
- ('another_int', c_int),
- ]
-
- test4 = Test4()
- dll = CDLL(_ctypes_test.__file__)
- with self.assertRaises(TypeError) as ctx:
- func = dll._testfunc_union_by_value1
- func.restype = c_long
- func.argtypes = (Test4,)
- result = func(test4)
- self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes '
- 'a union by value, which is unsupported.')
- test5 = Test5()
- with self.assertRaises(TypeError) as ctx:
- func = dll._testfunc_union_by_value2
- func.restype = c_long
- func.argtypes = (Test5,)
- result = func(test5)
- self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes '
- 'a union by value, which is unsupported.')
-
- # passing by reference should be OK
- test4.a_long = 12345;
- func = dll._testfunc_union_by_reference1
- func.restype = c_long
- func.argtypes = (POINTER(Test4),)
- result = func(byref(test4))
- self.assertEqual(result, 12345)
- self.assertEqual(test4.a_long, 0)
- self.assertEqual(test4.a_struct.an_int, 0)
- self.assertEqual(test4.a_struct.another_int, 0)
- test4.a_struct.an_int = 0x12340000
- test4.a_struct.another_int = 0x5678
- func = dll._testfunc_union_by_reference2
- func.restype = c_long
- func.argtypes = (POINTER(Test4),)
- result = func(byref(test4))
- self.assertEqual(result, 0x12345678)
- self.assertEqual(test4.a_long, 0)
- self.assertEqual(test4.a_struct.an_int, 0)
- self.assertEqual(test4.a_struct.another_int, 0)
- test5.an_int = 0x12000000
- test5.nested.an_int = 0x345600
- test5.another_int = 0x78
- func = dll._testfunc_union_by_reference3
- func.restype = c_long
- func.argtypes = (POINTER(Test5),)
- result = func(byref(test5))
- self.assertEqual(result, 0x12345678)
- self.assertEqual(test5.an_int, 0)
- self.assertEqual(test5.nested.an_int, 0)
- self.assertEqual(test5.another_int, 0)
-
- #@unittest.skipIf('s390' in MACHINE, 'Test causes segfault on S390')
- def test_bitfield_by_value(self):
- # See bpo-16576
-
- # These should mirror the structures in Modules/_ctypes/_ctypes_test.c
-
- class Test6(Structure):
- _fields_ = [
- ('A', c_int, 1),
- ('B', c_int, 2),
- ('C', c_int, 3),
- ('D', c_int, 2),
- ]
-
- test6 = Test6()
- # As these are signed int fields, all are logically -1 due to sign
- # extension.
- test6.A = 1
- test6.B = 3
- test6.C = 7
- test6.D = 3
- dll = CDLL(_ctypes_test.__file__)
- with self.assertRaises(TypeError) as ctx:
- func = dll._testfunc_bitfield_by_value1
- func.restype = c_long
- func.argtypes = (Test6,)
- result = func(test6)
- self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes '
- 'a struct/union with a bitfield by value, which is '
- 'unsupported.')
- # passing by reference should be OK
- func = dll._testfunc_bitfield_by_reference1
- func.restype = c_long
- func.argtypes = (POINTER(Test6),)
- result = func(byref(test6))
- self.assertEqual(result, -4)
- self.assertEqual(test6.A, 0)
- self.assertEqual(test6.B, 0)
- self.assertEqual(test6.C, 0)
- self.assertEqual(test6.D, 0)
-
- class Test7(Structure):
- _fields_ = [
- ('A', c_uint, 1),
- ('B', c_uint, 2),
- ('C', c_uint, 3),
- ('D', c_uint, 2),
- ]
- test7 = Test7()
- test7.A = 1
- test7.B = 3
- test7.C = 7
- test7.D = 3
- func = dll._testfunc_bitfield_by_reference2
- func.restype = c_long
- func.argtypes = (POINTER(Test7),)
- result = func(byref(test7))
- self.assertEqual(result, 14)
- self.assertEqual(test7.A, 0)
- self.assertEqual(test7.B, 0)
- self.assertEqual(test7.C, 0)
- self.assertEqual(test7.D, 0)
-
- # for a union with bitfields, the union check happens first
- class Test8(Union):
- _fields_ = [
- ('A', c_int, 1),
- ('B', c_int, 2),
- ('C', c_int, 3),
- ('D', c_int, 2),
- ]
-
- test8 = Test8()
- with self.assertRaises(TypeError) as ctx:
- func = dll._testfunc_bitfield_by_value2
- func.restype = c_long
- func.argtypes = (Test8,)
- result = func(test8)
- self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes '
- 'a union by value, which is unsupported.')
+ self.assertEqual(s.third, 0x0bad1dea)
class PointerMemberTestCase(unittest.TestCase):
@@ -785,7 +472,7 @@ class TestRecursiveStructure(unittest.TestCase):
try:
Recursive._fields_ = [("next", Recursive)]
- except AttributeError as details:
+ except AttributeError, details:
self.assertIn("Structure or union cannot contain itself",
str(details))
else:
@@ -802,7 +489,7 @@ class TestRecursiveStructure(unittest.TestCase):
try:
Second._fields_ = [("first", First)]
- except AttributeError as details:
+ except AttributeError, details:
self.assertIn("_fields_ is final", str(details))
else:
self.fail("AttributeError not raised")
diff --git a/Lib/ctypes/test/test_unicode.py b/Lib/ctypes/test/test_unicode.py
index c200af7..ec5663a 100644
--- a/Lib/ctypes/test/test_unicode.py
+++ b/Lib/ctypes/test/test_unicode.py
@@ -1,56 +1,138 @@
+# coding: latin-1
import unittest
import ctypes
from ctypes.test import need_symbol
-
import _ctypes_test
@need_symbol('c_wchar')
class UnicodeTestCase(unittest.TestCase):
- def test_wcslen(self):
+ @classmethod
+ def setUpClass(cls):
dll = ctypes.CDLL(_ctypes_test.__file__)
- wcslen = dll.my_wcslen
- wcslen.argtypes = [ctypes.c_wchar_p]
+ cls.wcslen = dll.my_wcslen
+ cls.wcslen.argtypes = [ctypes.c_wchar_p]
+ def setUp(self):
+ self.prev_conv_mode = ctypes.set_conversion_mode("ascii", "strict")
+
+ def tearDown(self):
+ ctypes.set_conversion_mode(*self.prev_conv_mode)
+
+ def test_ascii_strict(self):
+ wcslen = self.wcslen
+ ctypes.set_conversion_mode("ascii", "strict")
+ # no conversions take place with unicode arguments
+ self.assertEqual(wcslen(u"abc"), 3)
+ self.assertEqual(wcslen(u"ab\u2070"), 3)
+ # string args are converted
+ self.assertEqual(wcslen("abc"), 3)
+ self.assertRaises(ctypes.ArgumentError, wcslen, "abä")
+
+ def test_ascii_replace(self):
+ wcslen = self.wcslen
+ ctypes.set_conversion_mode("ascii", "replace")
+ self.assertEqual(wcslen(u"abc"), 3)
+ self.assertEqual(wcslen(u"ab\u2070"), 3)
+ self.assertEqual(wcslen("abc"), 3)
+ self.assertEqual(wcslen("abä"), 3)
+ def test_ascii_ignore(self):
+ wcslen = self.wcslen
+ ctypes.set_conversion_mode("ascii", "ignore")
+ self.assertEqual(wcslen(u"abc"), 3)
+ self.assertEqual(wcslen(u"ab\u2070"), 3)
+ # ignore error mode skips non-ascii characters
self.assertEqual(wcslen("abc"), 3)
- self.assertEqual(wcslen("ab\u2070"), 3)
- self.assertRaises(ctypes.ArgumentError, wcslen, b"ab\xe4")
+ self.assertEqual(wcslen("äöüß"), 0)
+
+ def test_latin1_strict(self):
+ wcslen = self.wcslen
+ ctypes.set_conversion_mode("latin-1", "strict")
+ self.assertEqual(wcslen(u"abc"), 3)
+ self.assertEqual(wcslen(u"ab\u2070"), 3)
+ self.assertEqual(wcslen("abc"), 3)
+ self.assertEqual(wcslen("äöüß"), 4)
def test_buffers(self):
+ ctypes.set_conversion_mode("ascii", "strict")
buf = ctypes.create_unicode_buffer("abc")
self.assertEqual(len(buf), 3+1)
- buf = ctypes.create_unicode_buffer("ab\xe4\xf6\xfc")
- self.assertEqual(buf[:], "ab\xe4\xf6\xfc\0")
- self.assertEqual(buf[::], "ab\xe4\xf6\xfc\0")
- self.assertEqual(buf[::-1], '\x00\xfc\xf6\xe4ba')
- self.assertEqual(buf[::2], 'a\xe4\xfc')
- self.assertEqual(buf[6:5:-1], "")
+ ctypes.set_conversion_mode("ascii", "replace")
+ buf = ctypes.create_unicode_buffer("abäöü")
+ self.assertEqual(buf[:], u"ab\uFFFD\uFFFD\uFFFD\0")
+ self.assertEqual(buf[::], u"ab\uFFFD\uFFFD\uFFFD\0")
+ self.assertEqual(buf[::-1], u"\0\uFFFD\uFFFD\uFFFDba")
+ self.assertEqual(buf[::2], u"a\uFFFD\uFFFD")
+ self.assertEqual(buf[6:5:-1], u"")
-func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p
+ ctypes.set_conversion_mode("ascii", "ignore")
+ buf = ctypes.create_unicode_buffer("abäöü")
+ # is that correct? not sure. But with 'ignore', you get what you pay for..
+ self.assertEqual(buf[:], u"ab\0\0\0\0")
+ self.assertEqual(buf[::], u"ab\0\0\0\0")
+ self.assertEqual(buf[::-1], u"\0\0\0\0ba")
+ self.assertEqual(buf[::2], u"a\0\0")
+ self.assertEqual(buf[6:5:-1], u"")
+@need_symbol('c_wchar')
class StringTestCase(UnicodeTestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(StringTestCase, cls).setUpClass()
+ cls.func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p
+
def setUp(self):
+ func = self.func
+ self.prev_conv_mode = ctypes.set_conversion_mode("ascii", "strict")
func.argtypes = [ctypes.c_char_p]
func.restype = ctypes.c_char_p
def tearDown(self):
+ func = self.func
+ ctypes.set_conversion_mode(*self.prev_conv_mode)
func.argtypes = None
func.restype = ctypes.c_int
- def test_func(self):
- self.assertEqual(func(b"abc\xe4"), b"abc\xe4")
+ def test_ascii_strict(self):
+ func = self.func
+ ctypes.set_conversion_mode("ascii", "strict")
+ self.assertEqual(func("abc"), "abc")
+ self.assertEqual(func(u"abc"), "abc")
+ self.assertRaises(ctypes.ArgumentError, func, u"abä")
+
+ def test_ascii_ignore(self):
+ func = self.func
+ ctypes.set_conversion_mode("ascii", "ignore")
+ self.assertEqual(func("abc"), "abc")
+ self.assertEqual(func(u"abc"), "abc")
+ self.assertEqual(func(u"äöüß"), "")
+
+ def test_ascii_replace(self):
+ func = self.func
+ ctypes.set_conversion_mode("ascii", "replace")
+ self.assertEqual(func("abc"), "abc")
+ self.assertEqual(func(u"abc"), "abc")
+ self.assertEqual(func(u"äöüß"), "????")
def test_buffers(self):
- buf = ctypes.create_string_buffer(b"abc")
+ ctypes.set_conversion_mode("ascii", "strict")
+ buf = ctypes.create_string_buffer(u"abc")
self.assertEqual(len(buf), 3+1)
- buf = ctypes.create_string_buffer(b"ab\xe4\xf6\xfc")
- self.assertEqual(buf[:], b"ab\xe4\xf6\xfc\0")
- self.assertEqual(buf[::], b"ab\xe4\xf6\xfc\0")
- self.assertEqual(buf[::-1], b'\x00\xfc\xf6\xe4ba')
- self.assertEqual(buf[::2], b'a\xe4\xfc')
- self.assertEqual(buf[6:5:-1], b"")
+ ctypes.set_conversion_mode("ascii", "replace")
+ buf = ctypes.create_string_buffer(u"abäöü")
+ self.assertEqual(buf[:], "ab???\0")
+ self.assertEqual(buf[::], "ab???\0")
+ self.assertEqual(buf[::-1], "\0???ba")
+ self.assertEqual(buf[::2], "a??")
+ self.assertEqual(buf[6:5:-1], "")
+ ctypes.set_conversion_mode("ascii", "ignore")
+ buf = ctypes.create_string_buffer(u"abäöü")
+ # is that correct? not sure. But with 'ignore', you get what you pay for..
+ self.assertEqual(buf[:], "ab\0\0\0\0")
+ self.assertEqual(buf[::], "ab\0\0\0\0")
+ self.assertEqual(buf[::-1], "\0\0\0\0ba")
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/ctypes/test/test_values.py b/Lib/ctypes/test/test_values.py
index 87eb919..fe7dcf0 100644
--- a/Lib/ctypes/test/test_values.py
+++ b/Lib/ctypes/test/test_values.py
@@ -11,18 +11,12 @@ import _ctypes_test
class ValuesTestCase(unittest.TestCase):
def test_an_integer(self):
- # This test checks and changes an integer stored inside the
- # _ctypes_test dll/shared lib.
ctdll = CDLL(_ctypes_test.__file__)
an_integer = c_int.in_dll(ctdll, "an_integer")
x = an_integer.value
self.assertEqual(x, ctdll.get_an_integer())
an_integer.value *= 2
self.assertEqual(x*2, ctdll.get_an_integer())
- # To avoid test failures when this test is repeated several
- # times the original value must be restored
- an_integer.value = x
- self.assertEqual(x, ctdll.get_an_integer())
def test_undefined(self):
ctdll = CDLL(_ctypes_test.__file__)
@@ -32,11 +26,20 @@ class PythonValuesTestCase(unittest.TestCase):
"""This test only works when python itself is a dll/shared library"""
def test_optimizeflag(self):
- # This test accesses the Py_OptimizeFlag integer, which is
- # exported by the Python dll and should match the sys.flags value
+ # This test accesses the Py_OptimizeFlag intger, which is
+ # exported by the Python dll.
+ # It's value is set depending on the -O and -OO flags:
+ # if not given, it is 0 and __debug__ is 1.
+ # If -O is given, the flag is 1, for -OO it is 2.
+ # docstrings are also removed in the latter case.
opt = c_int.in_dll(pythonapi, "Py_OptimizeFlag").value
- self.assertEqual(opt, sys.flags.optimize)
+ if __debug__:
+ self.assertEqual(opt, 0)
+ elif ValuesTestCase.__doc__ is not None:
+ self.assertEqual(opt, 1)
+ else:
+ self.assertEqual(opt, 2)
def test_frozentable(self):
# Python exports a PyImport_FrozenModules symbol. This is a
@@ -56,39 +59,18 @@ class PythonValuesTestCase(unittest.TestCase):
ft = FrozenTable.in_dll(pythonapi, "PyImport_FrozenModules")
# ft is a pointer to the struct_frozen entries:
items = []
- # _frozen_importlib changes size whenever importlib._bootstrap
- # changes, so it gets a special case. We should make sure it's
- # found, but don't worry about its size too much. The same
- # applies to _frozen_importlib_external.
- bootstrap_seen = []
- bootstrap_expected = [
- b'_frozen_importlib',
- b'_frozen_importlib_external',
- b'zipimport',
- ]
for entry in ft:
# This is dangerous. We *can* iterate over a pointer, but
# the loop will not terminate (maybe with an access
# violation;-) because the pointer instance has no size.
if entry.name is None:
break
+ items.append((entry.name, entry.size))
- if entry.name in bootstrap_expected:
- bootstrap_seen.append(entry.name)
- self.assertTrue(entry.size,
- "{!r} was reported as having no size".format(entry.name))
- continue
- items.append((entry.name.decode("ascii"), entry.size))
-
- expected = [("__hello__", 141),
- ("__phello__", -141),
- ("__phello__.spam", 141),
- ]
- self.assertEqual(items, expected, "PyImport_FrozenModules example "
- "in Doc/library/ctypes.rst may be out of date")
-
- self.assertEqual(sorted(bootstrap_seen), bootstrap_expected,
- "frozen bootstrap modules did not match PyImport_FrozenModules")
+ expected = [("__hello__", 104),
+ ("__phello__", -104),
+ ("__phello__.spam", 104)]
+ self.assertEqual(items, expected)
from ctypes import _pointer_type_cache
del _pointer_type_cache[struct_frozen]
diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py
index e51bdc8..13a9863 100644
--- a/Lib/ctypes/test/test_win32.py
+++ b/Lib/ctypes/test/test_win32.py
@@ -1,45 +1,72 @@
# Windows specific tests
from ctypes import *
+from ctypes.test import requires
import unittest, sys
-from test import support
+from test import test_support as support
import _ctypes_test
+# Only windows 32-bit has different calling conventions.
+@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
+@unittest.skipUnless(sizeof(c_void_p) == sizeof(c_int),
+ "sizeof c_void_p and c_int differ")
+class WindowsTestCase(unittest.TestCase):
+ def test_callconv_1(self):
+ # Testing stdcall function
+
+ IsWindow = windll.user32.IsWindow
+ # ValueError: Procedure probably called with not enough arguments
+ # (4 bytes missing)
+ self.assertRaises(ValueError, IsWindow)
+
+ # This one should succeed...
+ self.assertEqual(0, IsWindow(0))
+
+ # ValueError: Procedure probably called with too many arguments
+ # (8 bytes in excess)
+ self.assertRaises(ValueError, IsWindow, 0, 0, 0)
+
+ def test_callconv_2(self):
+ # Calling stdcall function as cdecl
+
+ IsWindow = cdll.user32.IsWindow
+
+ # ValueError: Procedure called with not enough arguments
+ # (4 bytes missing) or wrong calling convention
+ self.assertRaises(ValueError, IsWindow, None)
+
@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
class FunctionCallTestCase(unittest.TestCase):
@unittest.skipUnless('MSC' in sys.version, "SEH only supported by MSC")
- @unittest.skipIf(sys.executable.lower().endswith('_d.exe'),
+ @unittest.skipIf(sys.executable.endswith('_d.exe'),
"SEH not enabled in debug builds")
def test_SEH(self):
- # Disable faulthandler to prevent logging the warning:
- # "Windows fatal exception: access violation"
- with support.disable_faulthandler():
- # Call functions with invalid arguments, and make sure
- # that access violations are trapped and raise an
- # exception.
- self.assertRaises(OSError, windll.kernel32.GetModuleHandleA, 32)
+ requires("SEH")
+ # Call functions with invalid arguments, and make sure
+ # that access violations are trapped and raise an
+ # exception.
+ self.assertRaises(WindowsError, windll.kernel32.GetModuleHandleA, 32)
def test_noargs(self):
# This is a special case on win32 x64
windll.user32.GetDesktopWindow()
-
@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
class ReturnStructSizesTestCase(unittest.TestCase):
def test_sizes(self):
dll = CDLL(_ctypes_test.__file__)
for i in range(1, 11):
- fields = [ (f"f{f}", c_char) for f in range(1, i + 1)]
+ fields = [ ("f%d" % f, c_char) for f in range(1, i + 1)]
class S(Structure):
_fields_ = fields
- f = getattr(dll, f"TestSize{i}")
+ f = getattr(dll, "TestSize%d" % i)
f.restype = S
res = f()
for i, f in enumerate(fields):
value = getattr(res, f[0])
- expected = bytes([ord('a') + i])
- self.assertEqual(value, expected)
+ expected = chr(ord('a') + i)
+ self.assertEquals(value, expected)
@@ -67,29 +94,6 @@ class TestWintypes(unittest.TestCase):
self.assertEqual(ex.text, "text")
self.assertEqual(ex.details, ("details",))
-@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
-class TestWinError(unittest.TestCase):
- def test_winerror(self):
- # see Issue 16169
- import errno
- ERROR_INVALID_PARAMETER = 87
- msg = FormatError(ERROR_INVALID_PARAMETER).strip()
- args = (errno.EINVAL, msg, None, ERROR_INVALID_PARAMETER)
-
- e = WinError(ERROR_INVALID_PARAMETER)
- self.assertEqual(e.args, args)
- self.assertEqual(e.errno, errno.EINVAL)
- self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER)
-
- windll.kernel32.SetLastError(ERROR_INVALID_PARAMETER)
- try:
- raise WinError()
- except OSError as exc:
- e = exc
- self.assertEqual(e.args, args)
- self.assertEqual(e.errno, errno.EINVAL)
- self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER)
-
class Structures(unittest.TestCase):
def test_struct_by_value(self):
class POINT(Structure):
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
index 01176bf..ab10ec5 100644
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
@@ -1,5 +1,4 @@
import os
-import shutil
import subprocess
import sys
@@ -20,8 +19,6 @@ if os.name == "nt":
i = i + len(prefix)
s, rest = sys.version[i:].split(" ", 1)
majorVersion = int(s[:-2]) - 6
- if majorVersion >= 13:
- majorVersion += 1
minorVersion = int(s[2:3]) / 10.0
# I don't think paths are affected by minor version in version 6
if majorVersion == 6:
@@ -39,16 +36,12 @@ if os.name == "nt":
return None
if version <= 6:
clibname = 'msvcrt'
- elif version <= 13:
- clibname = 'msvcr%d' % (version * 10)
else:
- # CRT is no longer directly loadable. See issue23606 for the
- # discussion about alternative approaches.
- return None
+ clibname = 'msvcr%d' % (version * 10)
# If python was built with in debug mode
- import importlib.machinery
- if '_d.pyd' in importlib.machinery.EXTENSION_SUFFIXES:
+ import imp
+ if imp.get_suffixes()[0][0] == '_d.pyd':
clibname += 'd'
return clibname+'.dll'
@@ -67,7 +60,17 @@ if os.name == "nt":
return fname
return None
-elif os.name == "posix" and sys.platform == "darwin":
+if os.name == "ce":
+ # search path according to MSDN:
+ # - absolute path specified by filename
+ # - The .exe launch directory
+ # - the Windows directory
+ # - ROM dll files (where are they?)
+ # - OEM specified search path: HKLM\Loader\SystemPath
+ def find_library(name):
+ return name
+
+if os.name == "posix" and sys.platform == "darwin":
from ctypes.macholib.dyld import dyld_find as _dyld_find
def find_library(name):
possible = ['lib%s.dylib' % name,
@@ -80,60 +83,37 @@ elif os.name == "posix" and sys.platform == "darwin":
continue
return None
-elif sys.platform.startswith("aix"):
- # AIX has two styles of storing shared libraries
- # GNU auto_tools refer to these as svr4 and aix
- # svr4 (System V Release 4) is a regular file, often with .so as suffix
- # AIX style uses an archive (suffix .a) with members (e.g., shr.o, libssl.so)
- # see issue#26439 and _aix.py for more details
-
- from ctypes._aix import find_library
-
elif os.name == "posix":
# Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
- import re, tempfile
+ import re, tempfile, errno
def _findLib_gcc(name):
# Run GCC's linker with the -t (aka --trace) option and examine the
# library name it prints out. The GCC command will fail because we
# haven't supplied a proper program with main(), but that does not
# matter.
- expr = os.fsencode(r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name))
-
- c_compiler = shutil.which('gcc')
- if not c_compiler:
- c_compiler = shutil.which('cc')
- if not c_compiler:
- # No C compiler available, give up
- return None
+ expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)
+ cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; elif type cc >/dev/null 2>&1; then CC=cc;else exit; fi;' \
+ 'LANG=C LC_ALL=C $CC -Wl,-t -o "$2" 2>&1 -l"$1"'
temp = tempfile.NamedTemporaryFile()
try:
- args = [c_compiler, '-Wl,-t', '-o', temp.name, '-l' + name]
-
- env = dict(os.environ)
- env['LC_ALL'] = 'C'
- env['LANG'] = 'C'
- try:
- proc = subprocess.Popen(args,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- env=env)
- except OSError: # E.g. bad executable
- return None
- with proc:
- trace = proc.stdout.read()
+ proc = subprocess.Popen((cmd, '_findLib_gcc', name, temp.name),
+ shell=True,
+ stdout=subprocess.PIPE)
+ [trace, _] = proc.communicate()
finally:
try:
temp.close()
- except FileNotFoundError:
- # Raised if the file was already removed, which is the normal
- # behaviour of GCC if linking fails
- pass
+ except OSError, e:
+ # ENOENT is raised if the file was already removed, which is
+ # the normal behaviour of GCC if linking fails
+ if e.errno != errno.ENOENT:
+ raise
res = re.search(expr, trace)
if not res:
return None
- return os.fsdecode(res.group(0))
+ return res.group(0)
if sys.platform == "sunos5":
@@ -142,42 +122,37 @@ elif os.name == "posix":
if not f:
return None
+ null = open(os.devnull, "wb")
try:
- proc = subprocess.Popen(("/usr/ccs/bin/dump", "-Lpv", f),
- stdout=subprocess.PIPE,
- stderr=subprocess.DEVNULL)
+ with null:
+ proc = subprocess.Popen(("/usr/ccs/bin/dump", "-Lpv", f),
+ stdout=subprocess.PIPE,
+ stderr=null)
except OSError: # E.g. command not found
return None
- with proc:
- data = proc.stdout.read()
+ [data, _] = proc.communicate()
res = re.search(br'\[.*\]\sSONAME\s+([^\s]+)', data)
if not res:
return None
- return os.fsdecode(res.group(1))
+ return res.group(1)
else:
def _get_soname(f):
# assuming GNU binutils / ELF
if not f:
return None
- objdump = shutil.which('objdump')
- if not objdump:
- # objdump is not available, give up
- return None
-
- try:
- proc = subprocess.Popen((objdump, '-p', '-j', '.dynamic', f),
- stdout=subprocess.PIPE,
- stderr=subprocess.DEVNULL)
- except OSError: # E.g. bad executable
- return None
- with proc:
- dump = proc.stdout.read()
+ cmd = 'if ! type objdump >/dev/null 2>&1; then exit; fi;' \
+ 'objdump -p -j .dynamic 2>/dev/null "$1"'
+ proc = subprocess.Popen((cmd, '_get_soname', f), shell=True,
+ stdout=subprocess.PIPE)
+ [dump, _] = proc.communicate()
res = re.search(br'\sSONAME\s+([^\s]+)', dump)
if not res:
return None
- return os.fsdecode(res.group(1))
+ return res.group(1)
- if sys.platform.startswith(("freebsd", "openbsd", "dragonfly")):
+ if (sys.platform.startswith("freebsd")
+ or sys.platform.startswith("openbsd")
+ or sys.platform.startswith("dragonfly")):
def _num_version(libname):
# "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ]
@@ -188,28 +163,28 @@ elif os.name == "posix":
nums.insert(0, int(parts.pop()))
except ValueError:
pass
- return nums or [sys.maxsize]
+ return nums or [sys.maxint]
def find_library(name):
ename = re.escape(name)
expr = r':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename, ename)
- expr = os.fsencode(expr)
+ null = open(os.devnull, 'wb')
try:
- proc = subprocess.Popen(('/sbin/ldconfig', '-r'),
- stdout=subprocess.PIPE,
- stderr=subprocess.DEVNULL)
+ with null:
+ proc = subprocess.Popen(('/sbin/ldconfig', '-r'),
+ stdout=subprocess.PIPE,
+ stderr=null)
except OSError: # E.g. command not found
data = b''
else:
- with proc:
- data = proc.stdout.read()
+ [data, _] = proc.communicate()
res = re.findall(expr, data)
if not res:
return _get_soname(_findLib_gcc(name))
res.sort(key=_num_version)
- return os.fsdecode(res[-1])
+ return res[-1]
elif sys.platform == "sunos5":
@@ -226,18 +201,23 @@ elif os.name == "posix":
args = ('/usr/bin/crle',)
paths = None
+ null = open(os.devnull, 'wb')
try:
- proc = subprocess.Popen(args,
- stdout=subprocess.PIPE,
- stderr=subprocess.DEVNULL,
- env=env)
+ with null:
+ proc = subprocess.Popen(args,
+ stdout=subprocess.PIPE,
+ stderr=null,
+ env=env)
except OSError: # E.g. bad executable
return None
- with proc:
+ try:
for line in proc.stdout:
line = line.strip()
if line.startswith(b'Default Library Path (ELF):'):
- paths = os.fsdecode(line).split()[4]
+ paths = line.split()[4]
+ finally:
+ proc.stdout.close()
+ proc.wait()
if not paths:
return None
@@ -257,9 +237,9 @@ elif os.name == "posix":
def _findSoname_ldconfig(name):
import struct
if struct.calcsize('l') == 4:
- machine = os.uname().machine + '-32'
+ machine = os.uname()[4] + '-32'
else:
- machine = os.uname().machine + '-64'
+ machine = os.uname()[4] + '-64'
mach_map = {
'x86_64-64': 'libc6,x86-64',
'ppc64-64': 'libc6,64bit',
@@ -270,46 +250,28 @@ elif os.name == "posix":
abi_type = mach_map.get(machine, 'libc6')
# XXX assuming GLIBC's ldconfig (with option -p)
- regex = r'\s+(lib%s\.[^\s]+)\s+\(%s'
- regex = os.fsencode(regex % (re.escape(name), abi_type))
- try:
- with subprocess.Popen(['/sbin/ldconfig', '-p'],
- stdin=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL,
- stdout=subprocess.PIPE,
- env={'LC_ALL': 'C', 'LANG': 'C'}) as p:
- res = re.search(regex, p.stdout.read())
- if res:
- return os.fsdecode(res.group(1))
- except OSError:
- pass
+ expr = r'\s+(lib%s\.[^\s]+)\s+\(%s' % (re.escape(name), abi_type)
- def _findLib_ld(name):
- # See issue #9998 for why this is needed
- expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)
- cmd = ['ld', '-t']
- libpath = os.environ.get('LD_LIBRARY_PATH')
- if libpath:
- for d in libpath.split(':'):
- cmd.extend(['-L', d])
- cmd.extend(['-o', os.devnull, '-l%s' % name])
- result = None
+ env = dict(os.environ)
+ env['LC_ALL'] = 'C'
+ env['LANG'] = 'C'
+ null = open(os.devnull, 'wb')
try:
- p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- universal_newlines=True)
- out, _ = p.communicate()
- res = re.search(expr, os.fsdecode(out))
- if res:
- result = res.group(0)
- except Exception:
- pass # result will be None
- return result
+ with null:
+ p = subprocess.Popen(['/sbin/ldconfig', '-p'],
+ stderr=null,
+ stdout=subprocess.PIPE,
+ env=env)
+ except OSError: # E.g. command not found
+ return None
+ [data, _] = p.communicate()
+ res = re.search(expr, data)
+ if not res:
+ return None
+ return res.group(1)
def find_library(name):
- # See issue #9998
- return _findSoname_ldconfig(name) or \
- _get_soname(_findLib_gcc(name) or _findLib_ld(name))
+ return _findSoname_ldconfig(name) or _get_soname(_findLib_gcc(name))
################################################################
# test code
@@ -317,42 +279,30 @@ elif os.name == "posix":
def test():
from ctypes import cdll
if os.name == "nt":
- print(cdll.msvcrt)
- print(cdll.load("msvcrt"))
- print(find_library("msvcrt"))
+ print cdll.msvcrt
+ print cdll.load("msvcrt")
+ print find_library("msvcrt")
if os.name == "posix":
# find and load_version
- print(find_library("m"))
- print(find_library("c"))
- print(find_library("bz2"))
+ print find_library("m")
+ print find_library("c")
+ print find_library("bz2")
+
+ # getattr
+## print cdll.m
+## print cdll.bz2
# load
if sys.platform == "darwin":
- print(cdll.LoadLibrary("libm.dylib"))
- print(cdll.LoadLibrary("libcrypto.dylib"))
- print(cdll.LoadLibrary("libSystem.dylib"))
- print(cdll.LoadLibrary("System.framework/System"))
- # issue-26439 - fix broken test call for AIX
- elif sys.platform.startswith("aix"):
- from ctypes import CDLL
- if sys.maxsize < 2**32:
- print(f"Using CDLL(name, os.RTLD_MEMBER): {CDLL('libc.a(shr.o)', os.RTLD_MEMBER)}")
- print(f"Using cdll.LoadLibrary(): {cdll.LoadLibrary('libc.a(shr.o)')}")
- # librpm.so is only available as 32-bit shared library
- print(find_library("rpm"))
- print(cdll.LoadLibrary("librpm.so"))
- else:
- print(f"Using CDLL(name, os.RTLD_MEMBER): {CDLL('libc.a(shr_64.o)', os.RTLD_MEMBER)}")
- print(f"Using cdll.LoadLibrary(): {cdll.LoadLibrary('libc.a(shr_64.o)')}")
- print(f"crypt\t:: {find_library('crypt')}")
- print(f"crypt\t:: {cdll.LoadLibrary(find_library('crypt'))}")
- print(f"crypto\t:: {find_library('crypto')}")
- print(f"crypto\t:: {cdll.LoadLibrary(find_library('crypto'))}")
+ print cdll.LoadLibrary("libm.dylib")
+ print cdll.LoadLibrary("libcrypto.dylib")
+ print cdll.LoadLibrary("libSystem.dylib")
+ print cdll.LoadLibrary("System.framework/System")
else:
- print(cdll.LoadLibrary("libm.so"))
- print(cdll.LoadLibrary("libcrypt.so"))
- print(find_library("crypt"))
+ print cdll.LoadLibrary("libm.so")
+ print cdll.LoadLibrary("libcrypt.so")
+ print find_library("crypt")
if __name__ == "__main__":
test()
diff --git a/Lib/ctypes/wintypes.py b/Lib/ctypes/wintypes.py
index c619d27..e7f569c 100644
--- a/Lib/ctypes/wintypes.py
+++ b/Lib/ctypes/wintypes.py
@@ -1,50 +1,49 @@
# The most useful windows datatypes
-import ctypes
+from ctypes import *
-BYTE = ctypes.c_byte
-WORD = ctypes.c_ushort
-DWORD = ctypes.c_ulong
+BYTE = c_byte
+WORD = c_ushort
+DWORD = c_ulong
-#UCHAR = ctypes.c_uchar
-CHAR = ctypes.c_char
-WCHAR = ctypes.c_wchar
-UINT = ctypes.c_uint
-INT = ctypes.c_int
+WCHAR = c_wchar
+UINT = c_uint
+INT = c_int
-DOUBLE = ctypes.c_double
-FLOAT = ctypes.c_float
+DOUBLE = c_double
+FLOAT = c_float
BOOLEAN = BYTE
-BOOL = ctypes.c_long
+BOOL = c_long
-class VARIANT_BOOL(ctypes._SimpleCData):
+from ctypes import _SimpleCData
+class VARIANT_BOOL(_SimpleCData):
_type_ = "v"
def __repr__(self):
return "%s(%r)" % (self.__class__.__name__, self.value)
-ULONG = ctypes.c_ulong
-LONG = ctypes.c_long
+ULONG = c_ulong
+LONG = c_long
-USHORT = ctypes.c_ushort
-SHORT = ctypes.c_short
+USHORT = c_ushort
+SHORT = c_short
# in the windows header files, these are structures.
-_LARGE_INTEGER = LARGE_INTEGER = ctypes.c_longlong
-_ULARGE_INTEGER = ULARGE_INTEGER = ctypes.c_ulonglong
+_LARGE_INTEGER = LARGE_INTEGER = c_longlong
+_ULARGE_INTEGER = ULARGE_INTEGER = c_ulonglong
-LPCOLESTR = LPOLESTR = OLESTR = ctypes.c_wchar_p
-LPCWSTR = LPWSTR = ctypes.c_wchar_p
-LPCSTR = LPSTR = ctypes.c_char_p
-LPCVOID = LPVOID = ctypes.c_void_p
+LPCOLESTR = LPOLESTR = OLESTR = c_wchar_p
+LPCWSTR = LPWSTR = c_wchar_p
+LPCSTR = LPSTR = c_char_p
+LPCVOID = LPVOID = c_void_p
# WPARAM is defined as UINT_PTR (unsigned type)
# LPARAM is defined as LONG_PTR (signed type)
-if ctypes.sizeof(ctypes.c_long) == ctypes.sizeof(ctypes.c_void_p):
- WPARAM = ctypes.c_ulong
- LPARAM = ctypes.c_long
-elif ctypes.sizeof(ctypes.c_longlong) == ctypes.sizeof(ctypes.c_void_p):
- WPARAM = ctypes.c_ulonglong
- LPARAM = ctypes.c_longlong
+if sizeof(c_long) == sizeof(c_void_p):
+ WPARAM = c_ulong
+ LPARAM = c_long
+elif sizeof(c_longlong) == sizeof(c_void_p):
+ WPARAM = c_ulonglong
+ LPARAM = c_longlong
ATOM = WORD
LANGID = WORD
@@ -57,7 +56,7 @@ LCID = DWORD
################################################################
# HANDLE types
-HANDLE = ctypes.c_void_p # in the header files: void *
+HANDLE = c_void_p # in the header files: void *
HACCEL = HANDLE
HBITMAP = HANDLE
@@ -94,45 +93,45 @@ SERVICE_STATUS_HANDLE = HANDLE
################################################################
# Some important structure definitions
-class RECT(ctypes.Structure):
- _fields_ = [("left", LONG),
- ("top", LONG),
- ("right", LONG),
- ("bottom", LONG)]
+class RECT(Structure):
+ _fields_ = [("left", c_long),
+ ("top", c_long),
+ ("right", c_long),
+ ("bottom", c_long)]
tagRECT = _RECTL = RECTL = RECT
-class _SMALL_RECT(ctypes.Structure):
- _fields_ = [('Left', SHORT),
- ('Top', SHORT),
- ('Right', SHORT),
- ('Bottom', SHORT)]
+class _SMALL_RECT(Structure):
+ _fields_ = [('Left', c_short),
+ ('Top', c_short),
+ ('Right', c_short),
+ ('Bottom', c_short)]
SMALL_RECT = _SMALL_RECT
-class _COORD(ctypes.Structure):
- _fields_ = [('X', SHORT),
- ('Y', SHORT)]
+class _COORD(Structure):
+ _fields_ = [('X', c_short),
+ ('Y', c_short)]
-class POINT(ctypes.Structure):
- _fields_ = [("x", LONG),
- ("y", LONG)]
+class POINT(Structure):
+ _fields_ = [("x", c_long),
+ ("y", c_long)]
tagPOINT = _POINTL = POINTL = POINT
-class SIZE(ctypes.Structure):
- _fields_ = [("cx", LONG),
- ("cy", LONG)]
+class SIZE(Structure):
+ _fields_ = [("cx", c_long),
+ ("cy", c_long)]
tagSIZE = SIZEL = SIZE
def RGB(red, green, blue):
return red + (green << 8) + (blue << 16)
-class FILETIME(ctypes.Structure):
+class FILETIME(Structure):
_fields_ = [("dwLowDateTime", DWORD),
("dwHighDateTime", DWORD)]
_FILETIME = FILETIME
-class MSG(ctypes.Structure):
+class MSG(Structure):
_fields_ = [("hWnd", HWND),
- ("message", UINT),
+ ("message", c_uint),
("wParam", WPARAM),
("lParam", LPARAM),
("time", DWORD),
@@ -140,7 +139,7 @@ class MSG(ctypes.Structure):
tagMSG = MSG
MAX_PATH = 260
-class WIN32_FIND_DATAA(ctypes.Structure):
+class WIN32_FIND_DATAA(Structure):
_fields_ = [("dwFileAttributes", DWORD),
("ftCreationTime", FILETIME),
("ftLastAccessTime", FILETIME),
@@ -149,10 +148,10 @@ class WIN32_FIND_DATAA(ctypes.Structure):
("nFileSizeLow", DWORD),
("dwReserved0", DWORD),
("dwReserved1", DWORD),
- ("cFileName", CHAR * MAX_PATH),
- ("cAlternateFileName", CHAR * 14)]
+ ("cFileName", c_char * MAX_PATH),
+ ("cAlternateFileName", c_char * 14)]
-class WIN32_FIND_DATAW(ctypes.Structure):
+class WIN32_FIND_DATAW(Structure):
_fields_ = [("dwFileAttributes", DWORD),
("ftCreationTime", FILETIME),
("ftLastAccessTime", FILETIME),
@@ -161,42 +160,22 @@ class WIN32_FIND_DATAW(ctypes.Structure):
("nFileSizeLow", DWORD),
("dwReserved0", DWORD),
("dwReserved1", DWORD),
- ("cFileName", WCHAR * MAX_PATH),
- ("cAlternateFileName", WCHAR * 14)]
-
-################################################################
-# Pointer types
-
-LPBOOL = PBOOL = ctypes.POINTER(BOOL)
-PBOOLEAN = ctypes.POINTER(BOOLEAN)
-LPBYTE = PBYTE = ctypes.POINTER(BYTE)
-PCHAR = ctypes.POINTER(CHAR)
-LPCOLORREF = ctypes.POINTER(COLORREF)
-LPDWORD = PDWORD = ctypes.POINTER(DWORD)
-LPFILETIME = PFILETIME = ctypes.POINTER(FILETIME)
-PFLOAT = ctypes.POINTER(FLOAT)
-LPHANDLE = PHANDLE = ctypes.POINTER(HANDLE)
-PHKEY = ctypes.POINTER(HKEY)
-LPHKL = ctypes.POINTER(HKL)
-LPINT = PINT = ctypes.POINTER(INT)
-PLARGE_INTEGER = ctypes.POINTER(LARGE_INTEGER)
-PLCID = ctypes.POINTER(LCID)
-LPLONG = PLONG = ctypes.POINTER(LONG)
-LPMSG = PMSG = ctypes.POINTER(MSG)
-LPPOINT = PPOINT = ctypes.POINTER(POINT)
-PPOINTL = ctypes.POINTER(POINTL)
-LPRECT = PRECT = ctypes.POINTER(RECT)
-LPRECTL = PRECTL = ctypes.POINTER(RECTL)
-LPSC_HANDLE = ctypes.POINTER(SC_HANDLE)
-PSHORT = ctypes.POINTER(SHORT)
-LPSIZE = PSIZE = ctypes.POINTER(SIZE)
-LPSIZEL = PSIZEL = ctypes.POINTER(SIZEL)
-PSMALL_RECT = ctypes.POINTER(SMALL_RECT)
-LPUINT = PUINT = ctypes.POINTER(UINT)
-PULARGE_INTEGER = ctypes.POINTER(ULARGE_INTEGER)
-PULONG = ctypes.POINTER(ULONG)
-PUSHORT = ctypes.POINTER(USHORT)
-PWCHAR = ctypes.POINTER(WCHAR)
-LPWIN32_FIND_DATAA = PWIN32_FIND_DATAA = ctypes.POINTER(WIN32_FIND_DATAA)
-LPWIN32_FIND_DATAW = PWIN32_FIND_DATAW = ctypes.POINTER(WIN32_FIND_DATAW)
-LPWORD = PWORD = ctypes.POINTER(WORD)
+ ("cFileName", c_wchar * MAX_PATH),
+ ("cAlternateFileName", c_wchar * 14)]
+
+__all__ = ['ATOM', 'BOOL', 'BOOLEAN', 'BYTE', 'COLORREF', 'DOUBLE', 'DWORD',
+ 'FILETIME', 'FLOAT', 'HACCEL', 'HANDLE', 'HBITMAP', 'HBRUSH',
+ 'HCOLORSPACE', 'HDC', 'HDESK', 'HDWP', 'HENHMETAFILE', 'HFONT',
+ 'HGDIOBJ', 'HGLOBAL', 'HHOOK', 'HICON', 'HINSTANCE', 'HKEY',
+ 'HKL', 'HLOCAL', 'HMENU', 'HMETAFILE', 'HMODULE', 'HMONITOR',
+ 'HPALETTE', 'HPEN', 'HRGN', 'HRSRC', 'HSTR', 'HTASK', 'HWINSTA',
+ 'HWND', 'INT', 'LANGID', 'LARGE_INTEGER', 'LCID', 'LCTYPE',
+ 'LGRPID', 'LONG', 'LPARAM', 'LPCOLESTR', 'LPCSTR', 'LPCVOID',
+ 'LPCWSTR', 'LPOLESTR', 'LPSTR', 'LPVOID', 'LPWSTR', 'MAX_PATH',
+ 'MSG', 'OLESTR', 'POINT', 'POINTL', 'RECT', 'RECTL', 'RGB',
+ 'SC_HANDLE', 'SERVICE_STATUS_HANDLE', 'SHORT', 'SIZE', 'SIZEL',
+ 'SMALL_RECT', 'UINT', 'ULARGE_INTEGER', 'ULONG', 'USHORT',
+ 'VARIANT_BOOL', 'WCHAR', 'WIN32_FIND_DATAA', 'WIN32_FIND_DATAW',
+ 'WORD', 'WPARAM', '_COORD', '_FILETIME', '_LARGE_INTEGER',
+ '_POINTL', '_RECTL', '_SMALL_RECT', '_ULARGE_INTEGER', 'tagMSG',
+ 'tagPOINT', 'tagRECT', 'tagSIZE']