windows specific tests disable faulthandler to prevent logging the warning windows fatal exception access violation call functions with invalid arguments and make sure that access violations are trapped and raise an exception this is a special case on win32 x64 see issue 16169 the c function will check and modify ret if something is passed in improperly to not leak references we must clean pointertypecache windows specific tests disable faulthandler to prevent logging the warning windows fatal exception access violation call functions with invalid arguments and make sure that access violations are trapped and raise an exception this is a special case on win32 x64 see issue 16169 the c function will check and modify ret if something is passed in improperly to not leak references we must clean _pointer_type_cache
import _ctypes_test
import ctypes
import errno
import sys
import unittest
from ctypes import (CDLL, Structure, POINTER, pointer, sizeof, byref,
                    _pointer_type_cache,
                    c_void_p, c_char, c_int, c_long)
from test import support


@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'),
                     "SEH not enabled in debug builds")
    def test_SEH(self):
        
        
        kernel32 = ctypes.windll.kernel32
        with support.disable_faulthandler():
            
            
            
            self.assertRaises(OSError, kernel32.GetModuleHandleA, 32)

    def test_noargs(self):
        
        user32 = ctypes.windll.user32
        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)]
            class S(Structure):
                _fields_ = fields
            f = getattr(dll, f"TestSize{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)


@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_PARAM(self):
        from ctypes import wintypes
        self.assertEqual(sizeof(wintypes.WPARAM),
                             sizeof(c_void_p))
        self.assertEqual(sizeof(wintypes.LPARAM),
                             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.")

        ex = COMError(-1, "text", ("details",))
        self.assertEqual(ex.hresult, -1)
        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):
        
        ERROR_INVALID_PARAMETER = 87
        msg = ctypes.FormatError(ERROR_INVALID_PARAMETER).strip()
        args = (errno.EINVAL, msg, None, ERROR_INVALID_PARAMETER)

        e = ctypes.WinError(ERROR_INVALID_PARAMETER)
        self.assertEqual(e.args, args)
        self.assertEqual(e.errno, errno.EINVAL)
        self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER)

        kernel32 = ctypes.windll.kernel32
        kernel32.SetLastError(ERROR_INVALID_PARAMETER)
        try:
            raise ctypes.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),
                        ("y", c_long)]

        class RECT(Structure):
            _fields_ = [("left", c_long),
                        ("top", c_long),
                        ("right", c_long),
                        ("bottom", c_long)]

        dll = CDLL(_ctypes_test.__file__)

        pt = POINT(15, 25)
        left = c_long.in_dll(dll, 'left')
        top = c_long.in_dll(dll, 'top')
        right = c_long.in_dll(dll, 'right')
        bottom = c_long.in_dll(dll, 'bottom')
        rect = RECT(left, top, right, bottom)
        PointInRect = dll.PointInRect
        PointInRect.argtypes = [POINTER(RECT), POINT]
        self.assertEqual(1, PointInRect(byref(rect), pt))

        ReturnRect = dll.ReturnRect
        ReturnRect.argtypes = [c_int, RECT, POINTER(RECT), POINT, RECT,
                               POINTER(RECT), POINT, RECT]
        ReturnRect.restype = RECT
        for i in range(4):
            ret = ReturnRect(i, rect, pointer(rect), pt, rect,
                         byref(rect), pt, rect)
            
            
            self.assertEqual(ret.left, left.value)
            self.assertEqual(ret.right, right.value)
            self.assertEqual(ret.top, top.value)
            self.assertEqual(ret.bottom, bottom.value)

        
        del _pointer_type_cache[RECT]


if __name__ == '__main__':
    unittest.main()