[Python-checkins] cpython (3.4): Issue #19493: Refactor ctypes test package.

zach.ware python-checkins at python.org
Fri Jun 13 20:48:37 CEST 2014


http://hg.python.org/cpython/rev/6f63fff5c120
changeset:   91160:6f63fff5c120
branch:      3.4
parent:      91158:ef491d76ac70
user:        Zachary Ware <zachary.ware at gmail.com>
date:        Fri Jun 13 13:44:39 2014 -0500
summary:
  Issue #19493: Refactor ctypes test package.

Skipped tests are now marked as skipped, formerly commented-out or
renamed-so-it-doesn't-look-like-a-test tests are uncommented, properly named,
and unconditionally skipped, some tests that simply didn't run before
are now able to run, and a few are split into multiple methods instead of
skipping via 'return' in the middle of a method.  Also, a couple of unused
files are removed completely.

files:
  Lib/ctypes/test/__init__.py           |   10 +-
  Lib/ctypes/test/test_arrays.py        |   26 +-
  Lib/ctypes/test/test_as_parameter.py  |    6 +-
  Lib/ctypes/test/test_bitfields.py     |   19 +-
  Lib/ctypes/test/test_buffers.py       |   60 ++--
  Lib/ctypes/test/test_bytes.py         |   12 +-
  Lib/ctypes/test/test_byteswap.py      |    3 +-
  Lib/ctypes/test/test_callbacks.py     |   47 ++--
  Lib/ctypes/test/test_cast.py          |   15 +-
  Lib/ctypes/test/test_cfuncs.py        |    9 +-
  Lib/ctypes/test/test_checkretval.py   |   15 +-
  Lib/ctypes/test/test_errcheck.py      |   19 -
  Lib/ctypes/test/test_find.py          |   69 +++---
  Lib/ctypes/test/test_functions.py     |   70 +++---
  Lib/ctypes/test/test_integers.py      |    5 -
  Lib/ctypes/test/test_keeprefs.py      |    3 +-
  Lib/ctypes/test/test_loading.py       |  138 +++++++------
  Lib/ctypes/test/test_macholib.py      |   24 +-
  Lib/ctypes/test/test_memfunctions.py  |   44 ++--
  Lib/ctypes/test/test_numbers.py       |   39 ++-
  Lib/ctypes/test/test_objects.py       |   11 +-
  Lib/ctypes/test/test_parameters.py    |   19 +-
  Lib/ctypes/test/test_prototypes.py    |   84 +++----
  Lib/ctypes/test/test_python_api.py    |   33 +-
  Lib/ctypes/test/test_random_things.py |   27 +-
  Lib/ctypes/test/test_slicing.py       |   67 +++---
  Lib/ctypes/test/test_strings.py       |  126 ++++++------
  Lib/ctypes/test/test_structures.py    |   23 +-
  Lib/ctypes/test/test_unicode.py       |   81 +++----
  Lib/ctypes/test/test_values.py        |  114 ++++++----
  Lib/ctypes/test/test_win32.py         |  145 +++++++------
  Lib/ctypes/test/test_wintypes.py      |    8 +-
  Misc/NEWS                             |    3 +
  33 files changed, 674 insertions(+), 700 deletions(-)


diff --git a/Lib/ctypes/test/__init__.py b/Lib/ctypes/test/__init__.py
--- a/Lib/ctypes/test/__init__.py
+++ b/Lib/ctypes/test/__init__.py
@@ -2,7 +2,15 @@
 
 use_resources = []
 
-class ResourceDenied(Exception):
+import ctypes
+ctypes_symbols = dir(ctypes)
+
+def need_symbol(name):
+    return unittest.skipUnless(name in ctypes_symbols,
+                               '{!r} is required'.format(name))
+
+
+class ResourceDenied(unittest.SkipTest):
     """Test skipped because it requested a disallowed resource.
 
     This is raised when a test calls requires() for a resource that
diff --git a/Lib/ctypes/test/test_arrays.py b/Lib/ctypes/test/test_arrays.py
--- a/Lib/ctypes/test/test_arrays.py
+++ b/Lib/ctypes/test/test_arrays.py
@@ -1,6 +1,8 @@
 import unittest
 from ctypes import *
 
+from ctypes.test import need_symbol
+
 formats = "bBhHiIlLqQfd"
 
 formats = c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, \
@@ -98,20 +100,16 @@
         self.assertEqual(sz[1:4:2], b"o")
         self.assertEqual(sz.value, b"foo")
 
-    try:
-        create_unicode_buffer
-    except NameError:
-        pass
-    else:
-        def test_from_addressW(self):
-            p = create_unicode_buffer("foo")
-            sz = (c_wchar * 3).from_address(addressof(p))
-            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):
+        p = create_unicode_buffer("foo")
+        sz = (c_wchar * 3).from_address(addressof(p))
+        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")
 
     def test_cache(self):
         # Array types are cached internally in the _ctypes extension,
diff --git a/Lib/ctypes/test/test_as_parameter.py b/Lib/ctypes/test/test_as_parameter.py
--- a/Lib/ctypes/test/test_as_parameter.py
+++ b/Lib/ctypes/test/test_as_parameter.py
@@ -1,5 +1,6 @@
 import unittest
 from ctypes import *
+from ctypes.test import need_symbol
 import _ctypes_test
 
 dll = CDLL(_ctypes_test.__file__)
@@ -17,11 +18,8 @@
     def wrap(self, param):
         return param
 
+    @need_symbol('c_wchar')
     def test_wchar_parm(self):
-        try:
-            c_wchar
-        except NameError:
-            return
         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))
diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/ctypes/test/test_bitfields.py
--- a/Lib/ctypes/test/test_bitfields.py
+++ b/Lib/ctypes/test/test_bitfields.py
@@ -1,4 +1,5 @@
 from ctypes import *
+from ctypes.test import need_symbol
 import unittest
 import os
 
@@ -127,20 +128,18 @@
         result = self.fail_fields(("a", c_char, 1))
         self.assertEqual(result, (TypeError, 'bit fields not allowed for type c_char'))
 
-        try:
-            c_wchar
-        except NameError:
-            pass
-        else:
-            result = self.fail_fields(("a", c_wchar, 1))
-            self.assertEqual(result, (TypeError, 'bit fields not allowed for type c_wchar'))
-
         class Dummy(Structure):
             _fields_ = []
 
         result = self.fail_fields(("a", Dummy, 1))
         self.assertEqual(result, (TypeError, 'bit fields not allowed for type Dummy'))
 
+    @need_symbol('c_wchar')
+    def test_c_wchar(self):
+        result = self.fail_fields(("a", c_wchar, 1))
+        self.assertEqual(result,
+                (TypeError, 'bit fields not allowed for type c_wchar'))
+
     def test_single_bitfield_size(self):
         for c_typ in int_types:
             result = self.fail_fields(("a", c_typ, -1))
@@ -240,7 +239,7 @@
             _anonymous_ = ["_"]
             _fields_ = [("_", X)]
 
-    @unittest.skipUnless(hasattr(ctypes, "c_uint32"), "c_int32 is required")
+    @need_symbol('c_uint32')
     def test_uint32(self):
         class X(Structure):
             _fields_ = [("a", c_uint32, 32)]
@@ -250,7 +249,7 @@
         x.a = 0xFDCBA987
         self.assertEqual(x.a, 0xFDCBA987)
 
-    @unittest.skipUnless(hasattr(ctypes, "c_uint64"), "c_int64 is required")
+    @need_symbol('c_uint64')
     def test_uint64(self):
         class X(Structure):
             _fields_ = [("a", c_uint64, 64)]
diff --git a/Lib/ctypes/test/test_buffers.py b/Lib/ctypes/test/test_buffers.py
--- a/Lib/ctypes/test/test_buffers.py
+++ b/Lib/ctypes/test/test_buffers.py
@@ -1,4 +1,5 @@
 from ctypes import *
+from ctypes.test import need_symbol
 import unittest
 
 class StringBufferTestCase(unittest.TestCase):
@@ -24,39 +25,36 @@
         self.assertEqual(len(bytearray(create_string_buffer(0))), 0)
         self.assertEqual(len(bytearray(create_string_buffer(1))), 1)
 
-    try:
-        c_wchar
-    except NameError:
-        pass
-    else:
-        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)
+    @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)
 
-            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.assertEqual(b[:], "abc\0")
-            self.assertEqual(b[::], "abc\0")
-            self.assertEqual(b[::-1], "\0cba")
-            self.assertEqual(b[::2], "ac")
-            self.assertEqual(b[::5], "a")
+        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.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_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.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_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.assertEqual(b[:], "abc\0")
+        self.assertEqual(b[::], "abc\0")
+        self.assertEqual(b[::-1], "\0cba")
+        self.assertEqual(b[::2], "ac")
+        self.assertEqual(b[::5], "a")
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Lib/ctypes/test/test_bytes.py b/Lib/ctypes/test/test_bytes.py
--- a/Lib/ctypes/test/test_bytes.py
+++ b/Lib/ctypes/test/test_bytes.py
@@ -38,13 +38,13 @@
         self.assertEqual(x.a, "abc")
         self.assertEqual(type(x.a), str)
 
-    if sys.platform == "win32":
-        def test_BSTR(self):
-            from _ctypes import _SimpleCData
-            class BSTR(_SimpleCData):
-                _type_ = "X"
+    @unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
+    def test_BSTR(self):
+        from _ctypes import _SimpleCData
+        class BSTR(_SimpleCData):
+            _type_ = "X"
 
-            BSTR("abc")
+        BSTR("abc")
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/Lib/ctypes/test/test_byteswap.py b/Lib/ctypes/test/test_byteswap.py
--- a/Lib/ctypes/test/test_byteswap.py
+++ b/Lib/ctypes/test/test_byteswap.py
@@ -14,7 +14,8 @@
 # For Structures and Unions, these types are created on demand.
 
 class Test(unittest.TestCase):
-    def X_test(self):
+    @unittest.skip('test disabled')
+    def test_X(self):
         print(sys.byteorder, file=sys.stderr)
         for i in range(32):
             bits = BITS()
diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py
--- a/Lib/ctypes/test/test_callbacks.py
+++ b/Lib/ctypes/test/test_callbacks.py
@@ -1,5 +1,6 @@
 import unittest
 from ctypes import *
+from ctypes.test import need_symbol
 import _ctypes_test
 
 class Callbacks(unittest.TestCase):
@@ -88,9 +89,10 @@
     # disabled: would now (correctly) raise a RuntimeWarning about
     # a memory leak.  A callback function cannot return a non-integral
     # C type without causing a memory leak.
-##    def test_char_p(self):
-##        self.check_type(c_char_p, "abc")
-##        self.check_type(c_char_p, "def")
+    @unittest.skip('test disabled')
+    def test_char_p(self):
+        self.check_type(c_char_p, "abc")
+        self.check_type(c_char_p, "def")
 
     def test_pyobject(self):
         o = ()
@@ -142,13 +144,12 @@
         CFUNCTYPE(None)(lambda x=Nasty(): None)
 
 
-try:
-    WINFUNCTYPE
-except NameError:
-    pass
-else:
-    class StdcallCallbacks(Callbacks):
+ at need_symbol('WINFUNCTYPE')
+class StdcallCallbacks(Callbacks):
+    try:
         functype = WINFUNCTYPE
+    except NameError:
+        pass
 
 ################################################################
 
@@ -178,7 +179,7 @@
         from ctypes.util import find_library
         libc_path = find_library("c")
         if not libc_path:
-            return # cannot test
+            self.skipTest('could not find libc')
         libc = CDLL(libc_path)
 
         @CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
@@ -190,23 +191,19 @@
         libc.qsort(array, len(array), sizeof(c_int), cmp_func)
         self.assertEqual(array[:], [1, 5, 7, 33, 99])
 
-    try:
-        WINFUNCTYPE
-    except NameError:
-        pass
-    else:
-        def test_issue_8959_b(self):
-            from ctypes.wintypes import BOOL, HWND, LPARAM
+    @need_symbol('WINFUNCTYPE')
+    def test_issue_8959_b(self):
+        from ctypes.wintypes import BOOL, HWND, LPARAM
+        global windowCount
+        windowCount = 0
+
+        @WINFUNCTYPE(BOOL, HWND, LPARAM)
+        def EnumWindowsCallbackFunc(hwnd, lParam):
             global windowCount
-            windowCount = 0
+            windowCount += 1
+            return True #Allow windows to keep enumerating
 
-            @WINFUNCTYPE(BOOL, HWND, LPARAM)
-            def EnumWindowsCallbackFunc(hwnd, lParam):
-                global windowCount
-                windowCount += 1
-                return True #Allow windows to keep enumerating
-
-            windll.user32.EnumWindows(EnumWindowsCallbackFunc, 0)
+        windll.user32.EnumWindows(EnumWindowsCallbackFunc, 0)
 
     def test_callback_register_int(self):
         # Issue #8275: buggy handling of callback args under Win64
diff --git a/Lib/ctypes/test/test_cast.py b/Lib/ctypes/test/test_cast.py
--- a/Lib/ctypes/test/test_cast.py
+++ b/Lib/ctypes/test/test_cast.py
@@ -1,4 +1,5 @@
 from ctypes import *
+from ctypes.test import need_symbol
 import unittest
 import sys
 
@@ -75,15 +76,11 @@
         self.assertEqual(cast(cast(s, c_void_p), c_char_p).value,
                              b"hiho")
 
-    try:
-        c_wchar_p
-    except NameError:
-        pass
-    else:
-        def test_wchar_p(self):
-            s = c_wchar_p("hiho")
-            self.assertEqual(cast(cast(s, c_void_p), c_wchar_p).value,
-                                 "hiho")
+    @need_symbol('c_wchar_p')
+    def test_wchar_p(self):
+        s = c_wchar_p("hiho")
+        self.assertEqual(cast(cast(s, c_void_p), c_wchar_p).value,
+                             "hiho")
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Lib/ctypes/test/test_cfuncs.py b/Lib/ctypes/test/test_cfuncs.py
--- a/Lib/ctypes/test/test_cfuncs.py
+++ b/Lib/ctypes/test/test_cfuncs.py
@@ -3,6 +3,7 @@
 
 import unittest
 from ctypes import *
+from ctypes.test import need_symbol
 
 import _ctypes_test
 
@@ -193,7 +194,7 @@
 try:
     WinDLL
 except NameError:
-    pass
+    def stdcall_dll(*_): pass
 else:
     class stdcall_dll(WinDLL):
         def __getattr__(self, name):
@@ -203,9 +204,9 @@
             setattr(self, name, func)
             return func
 
-    class stdcallCFunctions(CFunctions):
-        _dll = stdcall_dll(_ctypes_test.__file__)
-        pass
+ at need_symbol('WinDLL')
+class stdcallCFunctions(CFunctions):
+    _dll = stdcall_dll(_ctypes_test.__file__)
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/Lib/ctypes/test/test_checkretval.py b/Lib/ctypes/test/test_checkretval.py
--- a/Lib/ctypes/test/test_checkretval.py
+++ b/Lib/ctypes/test/test_checkretval.py
@@ -1,6 +1,7 @@
 import unittest
 
 from ctypes import *
+from ctypes.test import need_symbol
 
 class CHECKED(c_int):
     def _check_retval_(value):
@@ -25,15 +26,11 @@
         del dll._testfunc_p_p.restype
         self.assertEqual(42, dll._testfunc_p_p(42))
 
-    try:
-        oledll
-    except NameError:
-        pass
-    else:
-        def test_oledll(self):
-            self.assertRaises(OSError,
-                                  oledll.oleaut32.CreateTypeLib2,
-                                  0, None, None)
+    @need_symbol('oledll')
+    def test_oledll(self):
+        self.assertRaises(OSError,
+                              oledll.oleaut32.CreateTypeLib2,
+                              0, None, None)
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Lib/ctypes/test/test_errcheck.py b/Lib/ctypes/test/test_errcheck.py
deleted file mode 100644
--- a/Lib/ctypes/test/test_errcheck.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import sys
-from ctypes import *
-
-##class HMODULE(Structure):
-##    _fields_ = [("value", c_void_p)]
-
-##    def __repr__(self):
-##        return "<HMODULE %s>" % self.value
-
-##windll.kernel32.GetModuleHandleA.restype = HMODULE
-
-##print windll.kernel32.GetModuleHandleA("python23.dll")
-##print hex(sys.dllhandle)
-
-##def nonzero(handle):
-##    return (GetLastError(), handle)
-
-##windll.kernel32.GetModuleHandleA.errcheck = nonzero
-##print windll.kernel32.GetModuleHandleA("spam")
diff --git a/Lib/ctypes/test/test_find.py b/Lib/ctypes/test/test_find.py
--- a/Lib/ctypes/test/test_find.py
+++ b/Lib/ctypes/test/test_find.py
@@ -1,4 +1,5 @@
 import unittest
+import os
 import sys
 from ctypes import *
 from ctypes.util import find_library
@@ -40,43 +41,43 @@
             except OSError:
                 pass
 
-    if lib_gl:
-        def test_gl(self):
-            if self.gl:
-                self.gl.glClearIndex
+    @unittest.skipUnless(lib_gl, 'lib_gl not available')
+    def test_gl(self):
+        if self.gl:
+            self.gl.glClearIndex
 
-    if lib_glu:
-        def test_glu(self):
-            if self.glu:
-                self.glu.gluBeginCurve
+    @unittest.skipUnless(lib_glu, 'lib_glu not available')
+    def test_glu(self):
+        if self.glu:
+            self.glu.gluBeginCurve
 
-    if lib_gle:
-        def test_gle(self):
-            if self.gle:
-                self.gle.gleGetJoinStyle
+    @unittest.skipUnless(lib_gle, 'lib_gle not available')
+    def test_gle(self):
+        if self.gle:
+            self.gle.gleGetJoinStyle
 
-##if os.name == "posix" and sys.platform != "darwin":
-
-##    # On platforms where the default shared library suffix is '.so',
-##    # at least some libraries can be loaded as attributes of the cdll
-##    # object, since ctypes now tries loading the lib again
-##    # with '.so' appended of the first try fails.
-##    #
-##    # Won't work for libc, unfortunately.  OTOH, it isn't
-##    # needed for libc since this is already mapped into the current
-##    # process (?)
-##    #
-##    # On MAC OSX, it won't work either, because dlopen() needs a full path,
-##    # and the default suffix is either none or '.dylib'.
-
-##    class LoadLibs(unittest.TestCase):
-##        def test_libm(self):
-##            import math
-##            libm = cdll.libm
-##            sqrt = libm.sqrt
-##            sqrt.argtypes = (c_double,)
-##            sqrt.restype = c_double
-##            self.assertEqual(sqrt(2), math.sqrt(2))
+# On platforms where the default shared library suffix is '.so',
+# at least some libraries can be loaded as attributes of the cdll
+# object, since ctypes now tries loading the lib again
+# with '.so' appended of the first try fails.
+#
+# Won't work for libc, unfortunately.  OTOH, it isn't
+# needed for libc since this is already mapped into the current
+# process (?)
+#
+# On MAC OSX, it won't work either, because dlopen() needs a full path,
+# and the default suffix is either none or '.dylib'.
+ at unittest.skip('test disabled')
+ at unittest.skipUnless(os.name=="posix" and sys.platform != "darwin",
+                     'test not suitable for this platform')
+class LoadLibs(unittest.TestCase):
+    def test_libm(self):
+        import math
+        libm = cdll.libm
+        sqrt = libm.sqrt
+        sqrt.argtypes = (c_double,)
+        sqrt.restype = c_double
+        self.assertEqual(sqrt(2), math.sqrt(2))
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Lib/ctypes/test/test_functions.py b/Lib/ctypes/test/test_functions.py
--- a/Lib/ctypes/test/test_functions.py
+++ b/Lib/ctypes/test/test_functions.py
@@ -6,6 +6,7 @@
 """
 
 from ctypes import *
+from ctypes.test import need_symbol
 import sys, unittest
 
 try:
@@ -63,22 +64,16 @@
             pass
 
 
+    @need_symbol('c_wchar')
     def test_wchar_parm(self):
-        try:
-            c_wchar
-        except NameError:
-            return
         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)
         self.assertEqual(result, 139)
         self.assertEqual(type(result), int)
 
+    @need_symbol('c_wchar')
     def test_wchar_result(self):
-        try:
-            c_wchar
-        except NameError:
-            return
         f = dll._testfunc_i_bhilfd
         f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
         f.restype = c_wchar
@@ -155,11 +150,8 @@
         self.assertEqual(result, -21)
         self.assertEqual(type(result), float)
 
+    @need_symbol('c_longlong')
     def test_longlongresult(self):
-        try:
-            c_longlong
-        except NameError:
-            return
         f = dll._testfunc_q_bhilfd
         f.restype = c_longlong
         f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
@@ -296,6 +288,7 @@
         result = f(-10, cb)
         self.assertEqual(result, -18)
 
+    @need_symbol('c_longlong')
     def test_longlong_callbacks(self):
 
         f = dll._testfunc_callback_q_qf
@@ -348,16 +341,16 @@
         s2h = dll.ret_2h_func(inp)
         self.assertEqual((s2h.x, s2h.y), (99*2, 88*3))
 
-    if sys.platform == "win32":
-        def test_struct_return_2H_stdcall(self):
-            class S2H(Structure):
-                _fields_ = [("x", c_short),
-                            ("y", c_short)]
+    @unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
+    def test_struct_return_2H_stdcall(self):
+        class S2H(Structure):
+            _fields_ = [("x", c_short),
+                        ("y", c_short)]
 
-            windll.s_ret_2h_func.restype = S2H
-            windll.s_ret_2h_func.argtypes = [S2H]
-            s2h = windll.s_ret_2h_func(S2H(99, 88))
-            self.assertEqual((s2h.x, s2h.y), (99*2, 88*3))
+        windll.s_ret_2h_func.restype = S2H
+        windll.s_ret_2h_func.argtypes = [S2H]
+        s2h = windll.s_ret_2h_func(S2H(99, 88))
+        self.assertEqual((s2h.x, s2h.y), (99*2, 88*3))
 
     def test_struct_return_8H(self):
         class S8I(Structure):
@@ -376,23 +369,24 @@
         self.assertEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
                              (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
 
-    if sys.platform == "win32":
-        def test_struct_return_8H_stdcall(self):
-            class S8I(Structure):
-                _fields_ = [("a", c_int),
-                            ("b", c_int),
-                            ("c", c_int),
-                            ("d", c_int),
-                            ("e", c_int),
-                            ("f", c_int),
-                            ("g", c_int),
-                            ("h", c_int)]
-            windll.s_ret_8i_func.restype = S8I
-            windll.s_ret_8i_func.argtypes = [S8I]
-            inp = S8I(9, 8, 7, 6, 5, 4, 3, 2)
-            s8i = windll.s_ret_8i_func(inp)
-            self.assertEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
-                                 (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
+    @unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
+    def test_struct_return_8H_stdcall(self):
+        class S8I(Structure):
+            _fields_ = [("a", c_int),
+                        ("b", c_int),
+                        ("c", c_int),
+                        ("d", c_int),
+                        ("e", c_int),
+                        ("f", c_int),
+                        ("g", c_int),
+                        ("h", c_int)]
+        windll.s_ret_8i_func.restype = S8I
+        windll.s_ret_8i_func.argtypes = [S8I]
+        inp = S8I(9, 8, 7, 6, 5, 4, 3, 2)
+        s8i = windll.s_ret_8i_func(inp)
+        self.assertEqual(
+                (s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
+                (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
 
     def test_sf1651235(self):
         # see http://www.python.org/sf/1651235
diff --git a/Lib/ctypes/test/test_integers.py b/Lib/ctypes/test/test_integers.py
deleted file mode 100644
--- a/Lib/ctypes/test/test_integers.py
+++ /dev/null
@@ -1,5 +0,0 @@
-# superseded by test_numbers.py
-import unittest
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/Lib/ctypes/test/test_keeprefs.py b/Lib/ctypes/test/test_keeprefs.py
--- a/Lib/ctypes/test/test_keeprefs.py
+++ b/Lib/ctypes/test/test_keeprefs.py
@@ -94,7 +94,8 @@
         self.assertEqual(x._objects, {'1': i})
 
 class DeletePointerTestCase(unittest.TestCase):
-    def X_test(self):
+    @unittest.skip('test disabled')
+    def test_X(self):
         class X(Structure):
             _fields_ = [("p", POINTER(c_char_p))]
         x = X()
diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py
--- a/Lib/ctypes/test/test_loading.py
+++ b/Lib/ctypes/test/test_loading.py
@@ -21,18 +21,21 @@
 
     unknowndll = "xxrandomnamexx"
 
-    if libc_name is not None:
-        def test_load(self):
-            CDLL(libc_name)
-            CDLL(os.path.basename(libc_name))
-            self.assertRaises(OSError, CDLL, self.unknowndll)
+    @unittest.skipUnless(libc_name is not None, 'could not find libc')
+    def test_load(self):
+        CDLL(libc_name)
+        CDLL(os.path.basename(libc_name))
+        self.assertRaises(OSError, CDLL, self.unknowndll)
 
-    if libc_name is not None and os.path.basename(libc_name) == "libc.so.6":
-        def test_load_version(self):
-            cdll.LoadLibrary("libc.so.6")
-            # linux uses version, libc 9 should not exist
-            self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9")
-            self.assertRaises(OSError, cdll.LoadLibrary, 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):
+        cdll.LoadLibrary("libc.so.6")
+        # linux uses version, libc 9 should not exist
+        self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9")
+        self.assertRaises(OSError, cdll.LoadLibrary, self.unknowndll)
 
     def test_find(self):
         for name in ("c", "m"):
@@ -41,66 +44,71 @@
                 cdll.LoadLibrary(lib)
                 CDLL(lib)
 
-    if os.name in ("nt", "ce"):
-        def test_load_library(self):
-            self.assertIsNotNone(libc_name)
-            if is_resource_enabled("printing"):
-                print(find_library("kernel32"))
-                print(find_library("user32"))
+    @unittest.skipUnless(os.name in ("nt", "ce"),
+                         'test specific to Windows (NT/CE)')
+    def test_load_library(self):
+        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
-            elif os.name == "ce":
-                windll.coredll.GetModuleHandleW
-                windll["coredll"].GetModuleHandleW
-                windll.LoadLibrary("coredll").GetModuleHandleW
-                WinDLL("coredll").GetModuleHandleW
+        if os.name == "nt":
+            windll.kernel32.GetModuleHandleW
+            windll["kernel32"].GetModuleHandleW
+            windll.LoadLibrary("kernel32").GetModuleHandleW
+            WinDLL("kernel32").GetModuleHandleW
+        elif os.name == "ce":
+            windll.coredll.GetModuleHandleW
+            windll["coredll"].GetModuleHandleW
+            windll.LoadLibrary("coredll").GetModuleHandleW
+            WinDLL("coredll").GetModuleHandleW
 
-        def test_load_ordinal_functions(self):
-            import _ctypes_test
-            dll = WinDLL(_ctypes_test.__file__)
-            # We load the same function both via ordinal and name
-            func_ord = dll[2]
-            func_name = dll.GetString
-            # addressof gets the address where the function pointer is stored
-            a_ord = addressof(func_ord)
-            a_name = addressof(func_name)
-            f_ord_addr = c_void_p.from_address(a_ord).value
-            f_name_addr = c_void_p.from_address(a_name).value
-            self.assertEqual(hex(f_ord_addr), hex(f_name_addr))
+    @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__)
+        # We load the same function both via ordinal and name
+        func_ord = dll[2]
+        func_name = dll.GetString
+        # addressof gets the address where the function pointer is stored
+        a_ord = addressof(func_ord)
+        a_name = addressof(func_name)
+        f_ord_addr = c_void_p.from_address(a_ord).value
+        f_name_addr = c_void_p.from_address(a_name).value
+        self.assertEqual(hex(f_ord_addr), hex(f_name_addr))
 
-            self.assertRaises(AttributeError, dll.__getitem__, 1234)
+        self.assertRaises(AttributeError, dll.__getitem__, 1234)
 
-    if os.name == "nt":
-        def test_1703286_A(self):
-            from _ctypes import LoadLibrary, FreeLibrary
-            # On winXP 64-bit, advapi32 loads at an address that does
-            # NOT fit into a 32-bit integer.  FreeLibrary must be able
-            # to accept this address.
+    @unittest.skipUnless(os.name == "nt", 'Windows-specific test')
+    def test_1703286_A(self):
+        from _ctypes import LoadLibrary, FreeLibrary
+        # On winXP 64-bit, advapi32 loads at an address that does
+        # NOT fit into a 32-bit integer.  FreeLibrary must be able
+        # to accept this address.
 
-            # These are tests for http://www.python.org/sf/1703286
-            handle = LoadLibrary("advapi32")
-            FreeLibrary(handle)
+        # These are tests for http://www.python.org/sf/1703286
+        handle = LoadLibrary("advapi32")
+        FreeLibrary(handle)
 
-        def test_1703286_B(self):
-            # Since on winXP 64-bit advapi32 loads like described
-            # above, the (arbitrarily selected) CloseEventLog function
-            # also has a high address.  'call_function' should accept
-            # addresses so large.
-            from _ctypes import call_function
-            advapi32 = windll.advapi32
-            # Calling CloseEventLog with a NULL argument should fail,
-            # but the call should not segfault or so.
-            self.assertEqual(0, advapi32.CloseEventLog(None))
-            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")
-            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", 'Windows-specific test')
+    def test_1703286_B(self):
+        # Since on winXP 64-bit advapi32 loads like described
+        # above, the (arbitrarily selected) CloseEventLog function
+        # also has a high address.  'call_function' should accept
+        # addresses so large.
+        from _ctypes import call_function
+        advapi32 = windll.advapi32
+        # Calling CloseEventLog with a NULL argument should fail,
+        # but the call should not segfault or so.
+        self.assertEqual(0, advapi32.CloseEventLog(None))
+        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")
+        self.assertTrue(proc)
+        # This is the real test: call the function via 'call_function'
+        self.assertEqual(0, call_function(proc, (None,)))
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Lib/ctypes/test/test_macholib.py b/Lib/ctypes/test/test_macholib.py
--- a/Lib/ctypes/test/test_macholib.py
+++ b/Lib/ctypes/test/test_macholib.py
@@ -43,21 +43,21 @@
     raise ValueError("%s not found" % (name,))
 
 class MachOTest(unittest.TestCase):
-    if sys.platform == "darwin":
-        def test_find(self):
+    @unittest.skipUnless(sys.platform == "darwin", 'OSX-specific test')
+    def test_find(self):
 
-            self.assertEqual(find_lib('pthread'),
-                                 '/usr/lib/libSystem.B.dylib')
+        self.assertEqual(find_lib('pthread'),
+                             '/usr/lib/libSystem.B.dylib')
 
-            result = find_lib('z')
-            # Issue #21093: dyld default search path includes $HOME/lib and
-            # /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")
+        result = find_lib('z')
+        # Issue #21093: dyld default search path includes $HOME/lib and
+        # /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.assertEqual(find_lib('IOKit'),
-                                 '/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit')
+        self.assertEqual(find_lib('IOKit'),
+                             '/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit')
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Lib/ctypes/test/test_memfunctions.py b/Lib/ctypes/test/test_memfunctions.py
--- a/Lib/ctypes/test/test_memfunctions.py
+++ b/Lib/ctypes/test/test_memfunctions.py
@@ -2,17 +2,19 @@
 from test import support
 import unittest
 from ctypes import *
+from ctypes.test import need_symbol
 
 class MemFunctionsTest(unittest.TestCase):
-##    def test_overflow(self):
-##        # string_at and wstring_at must use the Python calling
-##        # convention (which acquires the GIL and checks the Python
-##        # error flag).  Provoke an error and catch it; see also issue
-##        # #3554: <http://bugs.python.org/issue3554>
-##        self.assertRaises((OverflowError, MemoryError, SystemError),
-##                          lambda: wstring_at(u"foo", sys.maxint - 1))
-##        self.assertRaises((OverflowError, MemoryError, SystemError),
-##                          lambda: string_at("foo", sys.maxint - 1))
+    @unittest.skip('test disabled')
+    def test_overflow(self):
+        # string_at and wstring_at must use the Python calling
+        # convention (which acquires the GIL and checks the Python
+        # error flag).  Provoke an error and catch it; see also issue
+        # #3554: <http://bugs.python.org/issue3554>
+        self.assertRaises((OverflowError, MemoryError, SystemError),
+                          lambda: wstring_at(u"foo", sys.maxint - 1))
+        self.assertRaises((OverflowError, MemoryError, SystemError),
+                          lambda: string_at("foo", sys.maxint - 1))
 
     def test_memmove(self):
         # large buffers apparently increase the chance that the memory
@@ -61,21 +63,17 @@
         self.assertEqual(string_at(b"foo bar", 7), b"foo bar")
         self.assertEqual(string_at(b"foo bar", 3), b"foo")
 
-    try:
-        create_unicode_buffer
-    except NameError:
-        pass
-    else:
-        def test_wstring_at(self):
-            p = create_unicode_buffer("Hello, World")
-            a = create_unicode_buffer(1000000)
-            result = memmove(a, p, len(p) * sizeof(c_wchar))
-            self.assertEqual(a.value, "Hello, World")
+    @need_symbol('create_unicode_buffer')
+    def test_wstring_at(self):
+        p = create_unicode_buffer("Hello, World")
+        a = create_unicode_buffer(1000000)
+        result = memmove(a, p, len(p) * sizeof(c_wchar))
+        self.assertEqual(a.value, "Hello, World")
 
-            self.assertEqual(wstring_at(a), "Hello, World")
-            self.assertEqual(wstring_at(a, 5), "Hello")
-            self.assertEqual(wstring_at(a, 16), "Hello, World\0\0\0\0")
-            self.assertEqual(wstring_at(a, 0), "")
+        self.assertEqual(wstring_at(a), "Hello, World")
+        self.assertEqual(wstring_at(a, 5), "Hello")
+        self.assertEqual(wstring_at(a, 16), "Hello, World\0\0\0\0")
+        self.assertEqual(wstring_at(a, 0), "")
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Lib/ctypes/test/test_numbers.py b/Lib/ctypes/test/test_numbers.py
--- a/Lib/ctypes/test/test_numbers.py
+++ b/Lib/ctypes/test/test_numbers.py
@@ -82,12 +82,13 @@
             self.assertRaises(TypeError, t, "")
             self.assertRaises(TypeError, t, None)
 
-##    def test_valid_ranges(self):
-##        # invalid values of the correct type
-##        # raise ValueError (not OverflowError)
-##        for t, (l, h) in zip(unsigned_types, unsigned_ranges):
-##            self.assertRaises(ValueError, t, l-1)
-##            self.assertRaises(ValueError, t, h+1)
+    @unittest.skip('test disabled')
+    def test_valid_ranges(self):
+        # invalid values of the correct type
+        # raise ValueError (not OverflowError)
+        for t, (l, h) in zip(unsigned_types, unsigned_ranges):
+            self.assertRaises(ValueError, t, l-1)
+            self.assertRaises(ValueError, t, h+1)
 
     def test_from_param(self):
         # the from_param class method attribute always
@@ -200,16 +201,17 @@
         self.assertEqual(v.value, b'?')
 
     # array does not support c_bool / 't'
-    # def test_bool_from_address(self):
-    #     from ctypes import c_bool
-    #     from array import array
-    #     a = array(c_bool._type_, [True])
-    #     v = t.from_address(a.buffer_info()[0])
-    #     self.assertEqual(v.value, a[0])
-    #     self.assertEqual(type(v) is t)
-    #     a[0] = False
-    #     self.assertEqual(v.value, a[0])
-    #     self.assertEqual(type(v) is t)
+    @unittest.skip('test disabled')
+    def test_bool_from_address(self):
+        from ctypes import c_bool
+        from array import array
+        a = array(c_bool._type_, [True])
+        v = t.from_address(a.buffer_info()[0])
+        self.assertEqual(v.value, a[0])
+        self.assertEqual(type(v) is t)
+        a[0] = False
+        self.assertEqual(v.value, a[0])
+        self.assertEqual(type(v) is t)
 
     def test_init(self):
         # c_int() can be initialized from Python's int, and c_int.
@@ -227,8 +229,9 @@
             if (hasattr(t, "__ctype_le__")):
                 self.assertRaises(OverflowError, t.__ctype_le__, big_int)
 
-##    def test_perf(self):
-##        check_perf()
+    @unittest.skip('test disabled')
+    def test_perf(self):
+        check_perf()
 
 from ctypes import _SimpleCData
 class c_int_S(_SimpleCData):
diff --git a/Lib/ctypes/test/test_objects.py b/Lib/ctypes/test/test_objects.py
--- a/Lib/ctypes/test/test_objects.py
+++ b/Lib/ctypes/test/test_objects.py
@@ -59,12 +59,9 @@
 import ctypes.test.test_objects
 
 class TestCase(unittest.TestCase):
-    if sys.hexversion > 0x02040000:
-        # Python 2.3 has no ELLIPSIS flag, so we don't test with this
-        # version:
-        def test(self):
-            doctest.testmod(ctypes.test.test_objects)
+    def test(self):
+        failures, tests = doctest.testmod(ctypes.test.test_objects)
+        self.assertFalse(failures, 'doctests failed, see output above')
 
 if __name__ == '__main__':
-    if sys.hexversion > 0x02040000:
-        doctest.testmod(ctypes.test.test_objects)
+    doctest.testmod(ctypes.test.test_objects)
diff --git a/Lib/ctypes/test/test_parameters.py b/Lib/ctypes/test/test_parameters.py
--- a/Lib/ctypes/test/test_parameters.py
+++ b/Lib/ctypes/test/test_parameters.py
@@ -1,4 +1,5 @@
 import unittest, sys
+from ctypes.test import need_symbol
 
 class SimpleTypesTestCase(unittest.TestCase):
 
@@ -35,10 +36,9 @@
         self.assertEqual(CVOIDP.from_param("abc"), "abcabc")
         self.assertEqual(CCHARP.from_param("abc"), "abcabcabcabc")
 
-        try:
-            from ctypes import c_wchar_p
-        except ImportError:
-            return
+    @need_symbol('c_wchar_p')
+    def test_subclasses_c_wchar_p(self):
+        from ctypes import c_wchar_p
 
         class CWCHARP(c_wchar_p):
             def from_param(cls, value):
@@ -66,13 +66,9 @@
         a = c_char_p(b"123")
         self.assertIs(c_char_p.from_param(a), a)
 
+    @need_symbol('c_wchar_p')
     def test_cw_strings(self):
-        from ctypes import byref
-        try:
-            from ctypes import c_wchar_p
-        except ImportError:
-##            print "(No c_wchar_p)"
-            return
+        from ctypes import byref, c_wchar_p
 
         c_wchar_p.from_param("123")
 
@@ -139,9 +135,6 @@
         self.assertRaises(TypeError, LPINT.from_param, c_long*3)
         self.assertRaises(TypeError, LPINT.from_param, c_uint*3)
 
-##    def test_performance(self):
-##        check_perf()
-
     def test_noctypes_argtype(self):
         import _ctypes_test
         from ctypes import CDLL, c_void_p, ArgumentError
diff --git a/Lib/ctypes/test/test_prototypes.py b/Lib/ctypes/test/test_prototypes.py
--- a/Lib/ctypes/test/test_prototypes.py
+++ b/Lib/ctypes/test/test_prototypes.py
@@ -1,4 +1,5 @@
 from ctypes import *
+from ctypes.test import need_symbol
 import unittest
 
 # IMPORTANT INFO:
@@ -135,13 +136,14 @@
         func(pointer(c_int()))
         func((c_int * 3)())
 
-        try:
-            func.restype = c_wchar_p
-        except NameError:
-            pass
-        else:
-            self.assertEqual(None, func(c_wchar_p(None)))
-            self.assertEqual("123", func(c_wchar_p("123")))
+    @need_symbol('c_wchar_p')
+    def test_c_void_p_arg_with_c_wchar_p(self):
+        func = testdll._testfunc_p_p
+        func.restype = c_wchar_p
+        func.argtypes = c_void_p,
+
+        self.assertEqual(None, func(c_wchar_p(None)))
+        self.assertEqual("123", func(c_wchar_p("123")))
 
     def test_instance(self):
         func = testdll._testfunc_p_p
@@ -156,51 +158,47 @@
         func.argtypes = None
         self.assertEqual(None, func(X()))
 
-try:
-    c_wchar
-except NameError:
-    pass
-else:
-    class WCharPointersTestCase(unittest.TestCase):
+ at need_symbol('c_wchar')
+class WCharPointersTestCase(unittest.TestCase):
 
-        def setUp(self):
-            func = testdll._testfunc_p_p
-            func.restype = c_int
-            func.argtypes = None
+    def setUp(self):
+        func = testdll._testfunc_p_p
+        func.restype = c_int
+        func.argtypes = None
 
 
-        def test_POINTER_c_wchar_arg(self):
-            func = testdll._testfunc_p_p
-            func.restype = c_wchar_p
-            func.argtypes = POINTER(c_wchar),
+    def test_POINTER_c_wchar_arg(self):
+        func = testdll._testfunc_p_p
+        func.restype = c_wchar_p
+        func.argtypes = POINTER(c_wchar),
 
-            self.assertEqual(None, func(None))
-            self.assertEqual("123", func("123"))
-            self.assertEqual(None, func(c_wchar_p(None)))
-            self.assertEqual("123", func(c_wchar_p("123")))
+        self.assertEqual(None, func(None))
+        self.assertEqual("123", func("123"))
+        self.assertEqual(None, func(c_wchar_p(None)))
+        self.assertEqual("123", func(c_wchar_p("123")))
 
-            self.assertEqual("123", func(c_wbuffer("123")))
-            ca = c_wchar("a")
-            self.assertEqual("a", func(pointer(ca))[0])
-            self.assertEqual("a", func(byref(ca))[0])
+        self.assertEqual("123", func(c_wbuffer("123")))
+        ca = c_wchar("a")
+        self.assertEqual("a", func(pointer(ca))[0])
+        self.assertEqual("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,
+    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("123")
 
-            self.assertEqual(None, func(None))
-            self.assertEqual("123", func("123"))
-            self.assertEqual(None, func(c_wchar_p(None)))
-            self.assertEqual("123", func(c_wchar_p("123")))
+        self.assertEqual(None, func(None))
+        self.assertEqual("123", func("123"))
+        self.assertEqual(None, func(c_wchar_p(None)))
+        self.assertEqual("123", func(c_wchar_p("123")))
 
-            # XXX Currently, these raise TypeErrors, although they shouldn't:
-            self.assertEqual("123", func(c_wbuffer("123")))
-            ca = c_wchar("a")
-            self.assertEqual("a", func(pointer(ca))[0])
-            self.assertEqual("a", func(byref(ca))[0])
+        # XXX Currently, these raise TypeErrors, although they shouldn't:
+        self.assertEqual("123", func(c_wbuffer("123")))
+        ca = c_wchar("a")
+        self.assertEqual("a", func(pointer(ca))[0])
+        self.assertEqual("a", func(byref(ca))[0])
 
 class ArrayTest(unittest.TestCase):
     def test(self):
diff --git a/Lib/ctypes/test/test_python_api.py b/Lib/ctypes/test/test_python_api.py
--- a/Lib/ctypes/test/test_python_api.py
+++ b/Lib/ctypes/test/test_python_api.py
@@ -1,7 +1,7 @@
 from ctypes import *
 import unittest, sys
 from test import support
-from ctypes.test import is_resource_enabled
+from ctypes.test import requires
 
 ################################################################
 # This section should be moved into ctypes\__init__.py, when it's ready.
@@ -39,24 +39,25 @@
         del pyob
         self.assertEqual(grc(s), refcnt)
 
-    if is_resource_enabled("refcount"):
-        # 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_PyLong_Long(self):
-            ref42 = grc(42)
-            pythonapi.PyLong_FromLong.restype = py_object
-            self.assertEqual(pythonapi.PyLong_FromLong(42), 42)
+    # 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.
+    @requires("refcount")
+    @support.refcount_test
+    def test_PyLong_Long(self):
+        ref42 = grc(42)
+        pythonapi.PyLong_FromLong.restype = py_object
+        self.assertEqual(pythonapi.PyLong_FromLong(42), 42)
 
-            self.assertEqual(grc(42), ref42)
+        self.assertEqual(grc(42), ref42)
 
-            pythonapi.PyLong_AsLong.argtypes = (py_object,)
-            pythonapi.PyLong_AsLong.restype = c_long
+        pythonapi.PyLong_AsLong.argtypes = (py_object,)
+        pythonapi.PyLong_AsLong.restype = c_long
 
-            res = pythonapi.PyLong_AsLong(42)
-            self.assertEqual(grc(res), ref42 + 1)
-            del res
-            self.assertEqual(grc(42), ref42)
+        res = pythonapi.PyLong_AsLong(42)
+        self.assertEqual(grc(res), ref42 + 1)
+        del res
+        self.assertEqual(grc(42), ref42)
 
     @support.refcount_test
     def test_PyObj_FromPtr(self):
diff --git a/Lib/ctypes/test/test_random_things.py b/Lib/ctypes/test/test_random_things.py
--- a/Lib/ctypes/test/test_random_things.py
+++ b/Lib/ctypes/test/test_random_things.py
@@ -5,23 +5,22 @@
     42 / arg
     raise ValueError(arg)
 
-if sys.platform == "win32":
+ at unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
+class call_function_TestCase(unittest.TestCase):
+    # _ctypes.call_function is deprecated and private, but used by
+    # Gary Bishp's readline module.  If we have it, we must test it as well.
 
-    class call_function_TestCase(unittest.TestCase):
-        # _ctypes.call_function is deprecated and private, but used by
-        # Gary Bishp's readline module.  If we have it, we must test it as well.
+    def test(self):
+        from _ctypes import call_function
+        windll.kernel32.LoadLibraryA.restype = c_void_p
+        windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p
+        windll.kernel32.GetProcAddress.restype = c_void_p
 
-        def test(self):
-            from _ctypes import call_function
-            windll.kernel32.LoadLibraryA.restype = c_void_p
-            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(b"kernel32")
-            funcaddr = windll.kernel32.GetProcAddress(hdll, b"GetModuleHandleA")
-
-            self.assertEqual(call_function(funcaddr, (None,)),
-                                 windll.kernel32.GetModuleHandleA(None))
+        self.assertEqual(call_function(funcaddr, (None,)),
+                             windll.kernel32.GetModuleHandleA(None))
 
 class CallbackTracbackTestCase(unittest.TestCase):
     # When an exception is raised in a ctypes callback function, the C
diff --git a/Lib/ctypes/test/test_slicing.py b/Lib/ctypes/test/test_slicing.py
--- a/Lib/ctypes/test/test_slicing.py
+++ b/Lib/ctypes/test/test_slicing.py
@@ -1,5 +1,6 @@
 import unittest
 from ctypes import *
+from ctypes.test import need_symbol
 
 import _ctypes_test
 
@@ -125,44 +126,40 @@
         self.assertEqual(p[2:5:-3], s[2:5:-3])
 
 
-    try:
-        c_wchar
-    except NameError:
-        pass
-    else:
-        def test_wchar_ptr(self):
-            s = "abcdefghijklmnopqrstuvwxyz\0"
+    @need_symbol('c_wchar')
+    def test_wchar_ptr(self):
+        s = "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)
-            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])
+        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)
+        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.setitem,
-                              res, slice(0, 5), "abcde")
-            dll.my_free(res)
+        import operator
+        self.assertRaises(TypeError, operator.setitem,
+                          res, slice(0, 5), "abcde")
+        dll.my_free(res)
 
-            if sizeof(c_wchar) == sizeof(c_short):
-                dll.my_wcsdup.restype = POINTER(c_short)
-            elif sizeof(c_wchar) == sizeof(c_int):
-                dll.my_wcsdup.restype = POINTER(c_int)
-            elif sizeof(c_wchar) == sizeof(c_long):
-                dll.my_wcsdup.restype = POINTER(c_long)
-            else:
-                return
-            res = dll.my_wcsdup(s)
-            tmpl = list(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])
-            self.assertEqual(res[len(s)-2:5:-7], tmpl[:5:-7])
-            dll.my_free(res)
+        if sizeof(c_wchar) == sizeof(c_short):
+            dll.my_wcsdup.restype = POINTER(c_short)
+        elif sizeof(c_wchar) == sizeof(c_int):
+            dll.my_wcsdup.restype = POINTER(c_int)
+        elif sizeof(c_wchar) == sizeof(c_long):
+            dll.my_wcsdup.restype = POINTER(c_long)
+        else:
+            self.skipTest('Pointers to c_wchar are not supported')
+        res = dll.my_wcsdup(s)
+        tmpl = list(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])
+        self.assertEqual(res[len(s)-2:5:-7], tmpl[:5:-7])
+        dll.my_free(res)
 
 ################################################################
 
diff --git a/Lib/ctypes/test/test_strings.py b/Lib/ctypes/test/test_strings.py
--- a/Lib/ctypes/test/test_strings.py
+++ b/Lib/ctypes/test/test_strings.py
@@ -1,5 +1,6 @@
 import unittest
 from ctypes import *
+from ctypes.test import need_symbol
 
 class StringArrayTestCase(unittest.TestCase):
     def test(self):
@@ -53,36 +54,33 @@
 ##        print BUF.from_param(c_char_p("python"))
 ##        print BUF.from_param(BUF(*"pyth"))
 
-try:
-    c_wchar
-except NameError:
-    pass
-else:
-    class WStringArrayTestCase(unittest.TestCase):
-        def test(self):
-            BUF = c_wchar * 4
+ at need_symbol('c_wchar')
+class WStringArrayTestCase(unittest.TestCase):
+    def test(self):
+        BUF = c_wchar * 4
 
-            buf = BUF("a", "b", "c")
-            self.assertEqual(buf.value, "abc")
+        buf = BUF("a", "b", "c")
+        self.assertEqual(buf.value, "abc")
 
-            buf.value = "ABCD"
-            self.assertEqual(buf.value, "ABCD")
+        buf.value = "ABCD"
+        self.assertEqual(buf.value, "ABCD")
 
-            buf.value = "x"
-            self.assertEqual(buf.value, "x")
+        buf.value = "x"
+        self.assertEqual(buf.value, "x")
 
-            buf[1] = "Z"
-            self.assertEqual(buf.value, "xZCD")
+        buf[1] = "Z"
+        self.assertEqual(buf.value, "xZCD")
 
-        @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)
+    @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)
 
 class StringTestCase(unittest.TestCase):
-    def XX_test_basic_strings(self):
+    @unittest.skip('test disabled')
+    def test_basic_strings(self):
         cs = c_string("abcdef")
 
         # Cannot call len on a c_string any longer
@@ -108,7 +106,8 @@
 
         self.assertRaises(TypeError, c_string, "123")
 
-    def XX_test_sized_strings(self):
+    @unittest.skip('test disabled')
+    def test_sized_strings(self):
 
         # New in releases later than 0.4.0:
         self.assertRaises(TypeError, c_string, None)
@@ -125,7 +124,8 @@
         self.assertEqual(c_string(2).raw[-1], "\000")
         self.assertEqual(len(c_string(2).raw), 2)
 
-    def XX_test_initialized_strings(self):
+    @unittest.skip('test disabled')
+    def test_initialized_strings(self):
 
         self.assertEqual(c_string("ab", 4).raw[:2], "ab")
         self.assertEqual(c_string("ab", 4).raw[:2:], "ab")
@@ -134,7 +134,8 @@
         self.assertEqual(c_string("ab", 4).raw[-1], "\000")
         self.assertEqual(c_string("ab", 2).raw, "a\000")
 
-    def XX_test_toolong(self):
+    @unittest.skip('test disabled')
+    def test_toolong(self):
         cs = c_string("abcdef")
         # Much too long string:
         self.assertRaises(ValueError, setattr, cs, "value", "123456789012345")
@@ -142,54 +143,53 @@
         # One char too long values:
         self.assertRaises(ValueError, setattr, cs, "value", "1234567")
 
-##    def test_perf(self):
-##        check_perf()
+    @unittest.skip('test disabled')
+    def test_perf(self):
+        check_perf()
 
-try:
-    c_wchar
-except NameError:
-    pass
-else:
-    class WStringTestCase(unittest.TestCase):
-        def test_wchar(self):
-            c_wchar("x")
-            repr(byref(c_wchar("x")))
-            c_wchar("x")
+ at need_symbol('c_wchar')
+class WStringTestCase(unittest.TestCase):
+    def test_wchar(self):
+        c_wchar("x")
+        repr(byref(c_wchar("x")))
+        c_wchar("x")
 
 
-        def X_test_basic_wstrings(self):
-            cs = c_wstring("abcdef")
+    @unittest.skip('test disabled')
+    def test_basic_wstrings(self):
+        cs = c_wstring("abcdef")
 
-            # XXX This behaviour is about to change:
-            # len returns the size of the internal buffer in bytes.
-            # This includes the terminating NUL character.
-            self.assertEqual(sizeof(cs), 14)
+        # XXX This behaviour is about to change:
+        # len returns the size of the internal buffer in bytes.
+        # This includes the terminating NUL character.
+        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")
+        # 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(c_wstring("abc\000def").value, "abc")
+        self.assertEqual(c_wstring("abc\000def").value, "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")
+        # The raw property is the total buffer contents:
+        self.assertEqual(cs.raw, "abcdef\000")
+        self.assertEqual(c_wstring("abc\000def").raw, "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")
+        # We can change the value:
+        cs.value = "ab"
+        self.assertEqual(cs.value, "ab")
+        self.assertEqual(cs.raw, "ab\000\000\000\000\000")
 
-            self.assertRaises(TypeError, c_wstring, "123")
-            self.assertRaises(ValueError, c_wstring, 0)
+        self.assertRaises(TypeError, c_wstring, "123")
+        self.assertRaises(ValueError, c_wstring, 0)
 
-        def X_test_toolong(self):
-            cs = c_wstring("abcdef")
-            # Much too long string:
-            self.assertRaises(ValueError, setattr, cs, "value", "123456789012345")
+    @unittest.skip('test disabled')
+    def test_toolong(self):
+        cs = c_wstring("abcdef")
+        # Much too long string:
+        self.assertRaises(ValueError, setattr, cs, "value", "123456789012345")
 
-            # One char too long values:
-            self.assertRaises(ValueError, setattr, cs, "value", "1234567")
+        # One char too long values:
+        self.assertRaises(ValueError, setattr, cs, "value", "1234567")
 
 
 def run_test(rep, msg, func, arg):
diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py
--- a/Lib/ctypes/test/test_structures.py
+++ b/Lib/ctypes/test/test_structures.py
@@ -1,5 +1,6 @@
 import unittest
 from ctypes import *
+from ctypes.test import need_symbol
 from struct import calcsize
 import _testcapi
 
@@ -291,12 +292,8 @@
         self.assertEqual(p.phone.number, b"5678")
         self.assertEqual(p.age, 5)
 
+    @need_symbol('c_wchar')
     def test_structures_with_wchar(self):
-        try:
-            c_wchar
-        except NameError:
-            return # no unicode
-
         class PersonW(Structure):
             _fields_ = [("name", c_wchar * 12),
                         ("age", c_int)]
@@ -354,14 +351,14 @@
         except Exception as detail:
             return detail.__class__, str(detail)
 
-
-##    def test_subclass_creation(self):
-##        meta = type(Structure)
-##        # same as 'class X(Structure): pass'
-##        # fails, since we need either a _fields_ or a _abstract_ attribute
-##        cls, msg = self.get_except(meta, "X", (Structure,), {})
-##        self.assertEqual((cls, msg),
-##                             (AttributeError, "class must define a '_fields_' attribute"))
+    @unittest.skip('test disabled')
+    def test_subclass_creation(self):
+        meta = type(Structure)
+        # same as 'class X(Structure): pass'
+        # fails, since we need either a _fields_ or a _abstract_ attribute
+        cls, msg = self.get_except(meta, "X", (Structure,), {})
+        self.assertEqual((cls, msg),
+                (AttributeError, "class must define a '_fields_' attribute"))
 
     def test_abstract_class(self):
         class X(Structure):
diff --git a/Lib/ctypes/test/test_unicode.py b/Lib/ctypes/test/test_unicode.py
--- a/Lib/ctypes/test/test_unicode.py
+++ b/Lib/ctypes/test/test_unicode.py
@@ -1,58 +1,55 @@
 import unittest
 import ctypes
+from ctypes.test import need_symbol
 
-try:
-    ctypes.c_wchar
-except AttributeError:
-    pass
-else:
-    import _ctypes_test
+import _ctypes_test
 
-    class UnicodeTestCase(unittest.TestCase):
-        def test_wcslen(self):
-            dll = ctypes.CDLL(_ctypes_test.__file__)
-            wcslen = dll.my_wcslen
-            wcslen.argtypes = [ctypes.c_wchar_p]
+ at need_symbol('c_wchar')
+class UnicodeTestCase(unittest.TestCase):
+    def test_wcslen(self):
+        dll = ctypes.CDLL(_ctypes_test.__file__)
+        wcslen = dll.my_wcslen
+        wcslen.argtypes = [ctypes.c_wchar_p]
 
-            self.assertEqual(wcslen("abc"), 3)
-            self.assertEqual(wcslen("ab\u2070"), 3)
-            self.assertRaises(ctypes.ArgumentError, wcslen, b"ab\xe4")
+        self.assertEqual(wcslen("abc"), 3)
+        self.assertEqual(wcslen("ab\u2070"), 3)
+        self.assertRaises(ctypes.ArgumentError, wcslen, b"ab\xe4")
 
-        def test_buffers(self):
-            buf = ctypes.create_unicode_buffer("abc")
-            self.assertEqual(len(buf), 3+1)
+    def test_buffers(self):
+        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], "")
+        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], "")
 
-    func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p
+func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p
 
-    class StringTestCase(UnicodeTestCase):
-        def setUp(self):
-            func.argtypes = [ctypes.c_char_p]
-            func.restype = ctypes.c_char_p
+class StringTestCase(UnicodeTestCase):
+    def setUp(self):
+        func.argtypes = [ctypes.c_char_p]
+        func.restype = ctypes.c_char_p
 
-        def tearDown(self):
-            func.argtypes = None
-            func.restype = ctypes.c_int
+    def tearDown(self):
+        func.argtypes = None
+        func.restype = ctypes.c_int
 
-        def test_func(self):
-            self.assertEqual(func(b"abc\xe4"), b"abc\xe4")
+    def test_func(self):
+        self.assertEqual(func(b"abc\xe4"), b"abc\xe4")
 
-        def test_buffers(self):
-            buf = ctypes.create_string_buffer(b"abc")
-            self.assertEqual(len(buf), 3+1)
+    def test_buffers(self):
+        buf = ctypes.create_string_buffer(b"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"")
+        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"")
 
 
 if __name__ == '__main__':
diff --git a/Lib/ctypes/test/test_values.py b/Lib/ctypes/test/test_values.py
--- a/Lib/ctypes/test/test_values.py
+++ b/Lib/ctypes/test/test_values.py
@@ -3,6 +3,7 @@
 """
 
 import unittest
+import sys
 from ctypes import *
 
 import _ctypes_test
@@ -27,62 +28,77 @@
         ctdll = CDLL(_ctypes_test.__file__)
         self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol")
 
-    class Win_ValuesTestCase(unittest.TestCase):
-        """This test only works when python itself is a dll/shared library"""
+ at unittest.skipUnless(sys.platform == 'win32', 'Windows-specific test')
+class Win_ValuesTestCase(unittest.TestCase):
+    """This test only works when python itself is a dll/shared library"""
 
-        def test_optimizeflag(self):
-            # This test accesses the Py_OptimizeFlag intger, which is
-            # exported by the Python dll.
+    def test_optimizeflag(self):
+        # 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(pydll, "Py_OptimizeFlag").value
-            if __debug__:
-                self.assertEqual(opt, 0)
-            elif ValuesTestCase.__doc__ is not None:
-                self.assertEqual(opt, 1)
-            else:
-                self.assertEqual(opt, 2)
+        # 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
+        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
-            # pointer to an array of struct _frozen entries.  The end of the
-            # array is marked by an entry containing a NULL name and zero
-            # size.
+    def test_frozentable(self):
+        # Python exports a PyImport_FrozenModules symbol. This is a
+        # pointer to an array of struct _frozen entries.  The end of the
+        # array is marked by an entry containing a NULL name and zero
+        # size.
 
-            # In standard Python, this table contains a __hello__
-            # module, and a __phello__ package containing a spam
-            # module.
-            class struct_frozen(Structure):
-                _fields_ = [("name", c_char_p),
-                            ("code", POINTER(c_ubyte)),
-                            ("size", c_int)]
-            FrozenTable = POINTER(struct_frozen)
+        # In standard Python, this table contains a __hello__
+        # module, and a __phello__ package containing a spam
+        # module.
+        class struct_frozen(Structure):
+            _fields_ = [("name", c_char_p),
+                        ("code", POINTER(c_ubyte)),
+                        ("size", c_int)]
+        FrozenTable = POINTER(struct_frozen)
 
-            ft = FrozenTable.in_dll(pydll, "PyImport_FrozenModules")
-            # ft is a pointer to the struct_frozen entries:
-            items = []
-            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))
-            import sys
-            if sys.version_info[:2] >= (2, 3):
-                expected = [("__hello__", 104), ("__phello__", -104), ("__phello__.spam", 104)]
-            else:
-                expected = [("__hello__", 100), ("__phello__", -100), ("__phello__.spam", 100)]
-            self.assertEqual(items, expected)
+        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.
+        _fzn_implib_seen = False
+        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
 
-            from ctypes import _pointer_type_cache
-            del _pointer_type_cache[struct_frozen]
+            if entry.name == b'_frozen_importlib':
+                _fzn_implib_seen = True
+                self.assertTrue(entry.size,
+                    "_frozen_importlib was reported as having no size")
+                continue
+            items.append((entry.name, entry.size))
 
-        def test_undefined(self):
-            self.assertRaises(ValueError, c_int.in_dll, pydll, "Undefined_Symbol")
+        expected = [(b"__hello__", 161),
+                    (b"__phello__", -161),
+                    (b"__phello__.spam", 161),
+                    ]
+        self.assertEqual(items, expected)
+
+        self.assertTrue(_fzn_implib_seen,
+            "_frozen_importlib wasn't found in PyImport_FrozenModules")
+
+        from ctypes import _pointer_type_cache
+        del _pointer_type_cache[struct_frozen]
+
+    def test_undefined(self):
+        self.assertRaises(ValueError, c_int.in_dll, pythonapi,
+                          "Undefined_Symbol")
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py
--- a/Lib/ctypes/test/test_win32.py
+++ b/Lib/ctypes/test/test_win32.py
@@ -1,99 +1,102 @@
 # Windows specific tests
 
 from ctypes import *
-from ctypes.test import is_resource_enabled
+from ctypes.test import requires
 import unittest, sys
 from test import support
 
 import _ctypes_test
 
-if sys.platform == "win32" and sizeof(c_void_p) == sizeof(c_int):
-    # Only windows 32-bit has different calling conventions.
+# Only windows 32-bit has different calling conventions.
+ at unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
+ at 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
 
-    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)
 
-            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))
 
-            # 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)
 
-            # 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
 
-        def test_callconv_2(self):
-            # Calling stdcall function as cdecl
+        IsWindow = cdll.user32.IsWindow
 
-            IsWindow = cdll.user32.IsWindow
+        # ValueError: Procedure called with not enough arguments
+        # (4 bytes missing) or wrong calling convention
+        self.assertRaises(ValueError, IsWindow, None)
 
-            # ValueError: Procedure called with not enough arguments (4 bytes missing)
-            # or wrong calling convention
-            self.assertRaises(ValueError, IsWindow, None)
+ at unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
+class FunctionCallTestCase(unittest.TestCase):
+    @requires("SEH")
+    def test_SEH(self):
+        # Call functions with invalid arguments, and make sure
+        # that access violations are trapped and raise an
+        # exception.
+        self.assertRaises(OSError, windll.kernel32.GetModuleHandleA, 32)
 
-if sys.platform == "win32":
-    class FunctionCallTestCase(unittest.TestCase):
+    def test_noargs(self):
+        # This is a special case on win32 x64
+        windll.user32.GetDesktopWindow()
 
-        if is_resource_enabled("SEH"):
-            def test_SEH(self):
-                # Call functions with invalid arguments, and make sure
-                # that access violations are trapped and raise an
-                # exception.
-                self.assertRaises(OSError, windll.kernel32.GetModuleHandleA, 32)
+ at unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
+class TestWintypes(unittest.TestCase):
+    def test_HWND(self):
+        from ctypes import wintypes
+        self.assertEqual(sizeof(wintypes.HWND), sizeof(c_void_p))
 
-        def test_noargs(self):
-            # This is a special case on win32 x64
-            windll.user32.GetDesktopWindow()
+    def test_PARAM(self):
+        from ctypes import wintypes
+        self.assertEqual(sizeof(wintypes.WPARAM),
+                             sizeof(c_void_p))
+        self.assertEqual(sizeof(wintypes.LPARAM),
+                             sizeof(c_void_p))
 
-    class TestWintypes(unittest.TestCase):
-        def test_HWND(self):
-            from ctypes import wintypes
-            self.assertEqual(sizeof(wintypes.HWND), sizeof(c_void_p))
+    def test_COMError(self):
+        from _ctypes import COMError
+        if support.HAVE_DOCSTRINGS:
+            self.assertEqual(COMError.__doc__,
+                             "Raised when a COM method call failed.")
 
-        def test_PARAM(self):
-            from ctypes import wintypes
-            self.assertEqual(sizeof(wintypes.WPARAM),
-                                 sizeof(c_void_p))
-            self.assertEqual(sizeof(wintypes.LPARAM),
-                                 sizeof(c_void_p))
+        ex = COMError(-1, "text", ("details",))
+        self.assertEqual(ex.hresult, -1)
+        self.assertEqual(ex.text, "text")
+        self.assertEqual(ex.details, ("details",))
 
-        def test_COMError(self):
-            from _ctypes import COMError
-            if support.HAVE_DOCSTRINGS:
-                self.assertEqual(COMError.__doc__,
-                                 "Raised when a COM method call failed.")
+ at 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)
 
-            ex = COMError(-1, "text", ("details",))
-            self.assertEqual(ex.hresult, -1)
-            self.assertEqual(ex.text, "text")
-            self.assertEqual(ex.details, ("details",))
+        e = WinError(ERROR_INVALID_PARAMETER)
+        self.assertEqual(e.args, args)
+        self.assertEqual(e.errno, errno.EINVAL)
+        self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER)
 
-    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)
+        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):
             _fields_ = [("x", c_long),
diff --git a/Lib/ctypes/test/test_wintypes.py b/Lib/ctypes/test/test_wintypes.py
--- a/Lib/ctypes/test/test_wintypes.py
+++ b/Lib/ctypes/test/test_wintypes.py
@@ -1,14 +1,12 @@
 import sys
 import unittest
 
-if not sys.platform.startswith('win'):
-    raise unittest.SkipTest('Windows-only test')
+from ctypes import *
 
-from ctypes import *
-from ctypes import wintypes
-
+ at unittest.skipUnless(sys.platform.startswith('win'), 'Windows-only test')
 class WinTypesTest(unittest.TestCase):
     def test_variant_bool(self):
+        from ctypes import wintypes
         # reads 16-bits from memory, anything non-zero is True
         for true_value in (1, 32767, 32768, 65535, 65537):
             true = POINTER(c_int16)(c_int16(true_value))
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -95,6 +95,9 @@
 Tests
 -----
 
+- Issue #19493: Refactored the ctypes test package to skip tests explicitly
+  rather than silently.
+
 - Issue #18492: All resources are now allowed when tests are not run by
   regrtest.py.
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list