mirror of
https://github.com/python/cpython.git
synced 2025-09-27 18:59:43 +00:00
gh-105751: test_ctypes gets Windows attrs from ctypes (#105758)
test_ctypes now gets attributes specific to Windows from the ctypes module, rather than relying on "from ctypes import *". Attributes: * ctypes.FormatError * ctypes.WINFUNCTYPE * ctypes.WinError * ctypes.WinDLL * ctypes.windll * ctypes.oledll * ctypes.get_last_error() * ctypes.set_last_error()
This commit is contained in:
parent
b87d288275
commit
ac7b551bde
11 changed files with 75 additions and 64 deletions
|
@ -1,4 +1,5 @@
|
||||||
import unittest
|
import unittest
|
||||||
|
import ctypes
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
from test.test_ctypes import need_symbol
|
from test.test_ctypes import need_symbol
|
||||||
import _ctypes_test
|
import _ctypes_test
|
||||||
|
@ -6,8 +7,8 @@ import _ctypes_test
|
||||||
dll = CDLL(_ctypes_test.__file__)
|
dll = CDLL(_ctypes_test.__file__)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
CALLBACK_FUNCTYPE = WINFUNCTYPE
|
CALLBACK_FUNCTYPE = ctypes.WINFUNCTYPE
|
||||||
except NameError:
|
except AttributeError:
|
||||||
# fake to enable this test on Linux
|
# fake to enable this test on Linux
|
||||||
CALLBACK_FUNCTYPE = CFUNCTYPE
|
CALLBACK_FUNCTYPE = CFUNCTYPE
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import functools
|
||||||
import unittest
|
import unittest
|
||||||
from test import support
|
from test import support
|
||||||
|
|
||||||
|
import ctypes
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
from test.test_ctypes import need_symbol
|
from test.test_ctypes import need_symbol
|
||||||
from _ctypes import CTYPES_MAX_ARGCOUNT
|
from _ctypes import CTYPES_MAX_ARGCOUNT
|
||||||
|
@ -152,7 +153,7 @@ class Callbacks(unittest.TestCase):
|
||||||
|
|
||||||
@need_symbol('WINFUNCTYPE')
|
@need_symbol('WINFUNCTYPE')
|
||||||
def test_i38748_stackCorruption(self):
|
def test_i38748_stackCorruption(self):
|
||||||
callback_funcType = WINFUNCTYPE(c_long, c_long, c_longlong)
|
callback_funcType = ctypes.WINFUNCTYPE(c_long, c_long, c_longlong)
|
||||||
@callback_funcType
|
@callback_funcType
|
||||||
def callback(a, b):
|
def callback(a, b):
|
||||||
c = a + b
|
c = a + b
|
||||||
|
@ -163,12 +164,10 @@ class Callbacks(unittest.TestCase):
|
||||||
self.assertEqual(dll._test_i38748_runCallback(callback, 5, 10), 15)
|
self.assertEqual(dll._test_i38748_runCallback(callback, 5, 10), 15)
|
||||||
|
|
||||||
|
|
||||||
@need_symbol('WINFUNCTYPE')
|
if hasattr(ctypes, 'WINFUNCTYPE'):
|
||||||
class StdcallCallbacks(Callbacks):
|
class StdcallCallbacks(Callbacks):
|
||||||
try:
|
functype = ctypes.WINFUNCTYPE
|
||||||
functype = WINFUNCTYPE
|
|
||||||
except NameError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
|
|
||||||
|
@ -216,13 +215,14 @@ class SampleCallbacksTestCase(unittest.TestCase):
|
||||||
global windowCount
|
global windowCount
|
||||||
windowCount = 0
|
windowCount = 0
|
||||||
|
|
||||||
@WINFUNCTYPE(BOOL, HWND, LPARAM)
|
@ctypes.WINFUNCTYPE(BOOL, HWND, LPARAM)
|
||||||
def EnumWindowsCallbackFunc(hwnd, lParam):
|
def EnumWindowsCallbackFunc(hwnd, lParam):
|
||||||
global windowCount
|
global windowCount
|
||||||
windowCount += 1
|
windowCount += 1
|
||||||
return True #Allow windows to keep enumerating
|
return True #Allow windows to keep enumerating
|
||||||
|
|
||||||
windll.user32.EnumWindows(EnumWindowsCallbackFunc, 0)
|
user32 = ctypes.windll.user32
|
||||||
|
user32.EnumWindows(EnumWindowsCallbackFunc, 0)
|
||||||
|
|
||||||
def test_callback_register_int(self):
|
def test_callback_register_int(self):
|
||||||
# Issue #8275: buggy handling of callback args under Win64
|
# Issue #8275: buggy handling of callback args under Win64
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
# Byte order related?
|
# Byte order related?
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
import ctypes
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
from test.test_ctypes import need_symbol
|
from test.test_ctypes import need_symbol
|
||||||
|
|
||||||
|
@ -197,12 +198,8 @@ class CFunctions(unittest.TestCase):
|
||||||
|
|
||||||
# The following repeats the above tests with stdcall functions (where
|
# The following repeats the above tests with stdcall functions (where
|
||||||
# they are available)
|
# they are available)
|
||||||
try:
|
if hasattr(ctypes, 'WinDLL'):
|
||||||
WinDLL
|
class stdcall_dll(ctypes.WinDLL):
|
||||||
except NameError:
|
|
||||||
def stdcall_dll(*_): pass
|
|
||||||
else:
|
|
||||||
class stdcall_dll(WinDLL):
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
if name[:2] == '__' and name[-2:] == '__':
|
if name[:2] == '__' and name[-2:] == '__':
|
||||||
raise AttributeError(name)
|
raise AttributeError(name)
|
||||||
|
@ -210,7 +207,6 @@ else:
|
||||||
setattr(self, name, func)
|
setattr(self, name, func)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
@need_symbol('WinDLL')
|
|
||||||
class stdcallCFunctions(CFunctions):
|
class stdcallCFunctions(CFunctions):
|
||||||
_dll = stdcall_dll(_ctypes_test.__file__)
|
_dll = stdcall_dll(_ctypes_test.__file__)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
import ctypes
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
from test.test_ctypes import need_symbol
|
from test.test_ctypes import need_symbol
|
||||||
|
|
||||||
|
@ -28,9 +29,8 @@ class Test(unittest.TestCase):
|
||||||
|
|
||||||
@need_symbol('oledll')
|
@need_symbol('oledll')
|
||||||
def test_oledll(self):
|
def test_oledll(self):
|
||||||
self.assertRaises(OSError,
|
oleaut32 = ctypes.oledll.oleaut32
|
||||||
oledll.oleaut32.CreateTypeLib2,
|
self.assertRaises(OSError, oleaut32.CreateTypeLib2, 0, None, None)
|
||||||
0, None, None)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import unittest, os, errno
|
import unittest, os, errno
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
|
import ctypes
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
from ctypes.util import find_library
|
from ctypes.util import find_library
|
||||||
|
|
||||||
|
@ -44,33 +45,33 @@ class Test(unittest.TestCase):
|
||||||
|
|
||||||
@unittest.skipUnless(os.name == "nt", 'Test specific to Windows')
|
@unittest.skipUnless(os.name == "nt", 'Test specific to Windows')
|
||||||
def test_GetLastError(self):
|
def test_GetLastError(self):
|
||||||
dll = WinDLL("kernel32", use_last_error=True)
|
dll = ctypes.WinDLL("kernel32", use_last_error=True)
|
||||||
GetModuleHandle = dll.GetModuleHandleA
|
GetModuleHandle = dll.GetModuleHandleA
|
||||||
GetModuleHandle.argtypes = [c_wchar_p]
|
GetModuleHandle.argtypes = [c_wchar_p]
|
||||||
|
|
||||||
self.assertEqual(0, GetModuleHandle("foo"))
|
self.assertEqual(0, GetModuleHandle("foo"))
|
||||||
self.assertEqual(get_last_error(), 126)
|
self.assertEqual(ctypes.get_last_error(), 126)
|
||||||
|
|
||||||
self.assertEqual(set_last_error(32), 126)
|
self.assertEqual(ctypes.set_last_error(32), 126)
|
||||||
self.assertEqual(get_last_error(), 32)
|
self.assertEqual(ctypes.get_last_error(), 32)
|
||||||
|
|
||||||
def _worker():
|
def _worker():
|
||||||
set_last_error(0)
|
ctypes.set_last_error(0)
|
||||||
|
|
||||||
dll = WinDLL("kernel32", use_last_error=False)
|
dll = ctypes.WinDLL("kernel32", use_last_error=False)
|
||||||
GetModuleHandle = dll.GetModuleHandleW
|
GetModuleHandle = dll.GetModuleHandleW
|
||||||
GetModuleHandle.argtypes = [c_wchar_p]
|
GetModuleHandle.argtypes = [c_wchar_p]
|
||||||
GetModuleHandle("bar")
|
GetModuleHandle("bar")
|
||||||
|
|
||||||
self.assertEqual(get_last_error(), 0)
|
self.assertEqual(ctypes.get_last_error(), 0)
|
||||||
|
|
||||||
t = threading.Thread(target=_worker)
|
t = threading.Thread(target=_worker)
|
||||||
t.start()
|
t.start()
|
||||||
t.join()
|
t.join()
|
||||||
|
|
||||||
self.assertEqual(get_last_error(), 32)
|
self.assertEqual(ctypes.get_last_error(), 32)
|
||||||
|
|
||||||
set_last_error(0)
|
ctypes.set_last_error(0)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import unittest
|
import unittest
|
||||||
|
import ctypes
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
|
|
||||||
try:
|
try:
|
||||||
WINFUNCTYPE
|
WINFUNCTYPE = ctypes.WINFUNCTYPE
|
||||||
except NameError:
|
except AttributeError:
|
||||||
# fake to enable this test on Linux
|
# fake to enable this test on Linux
|
||||||
WINFUNCTYPE = CFUNCTYPE
|
WINFUNCTYPE = CFUNCTYPE
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ class CFuncPtrTestCase(unittest.TestCase):
|
||||||
# possible, as in C, to call cdecl functions with more parameters.
|
# possible, as in C, to call cdecl functions with more parameters.
|
||||||
#self.assertRaises(TypeError, c, 1, 2, 3)
|
#self.assertRaises(TypeError, c, 1, 2, 3)
|
||||||
self.assertEqual(c(1, 2, 3, 4, 5, 6), 3)
|
self.assertEqual(c(1, 2, 3, 4, 5, 6), 3)
|
||||||
if not WINFUNCTYPE is CFUNCTYPE:
|
if WINFUNCTYPE is not CFUNCTYPE:
|
||||||
self.assertRaises(TypeError, s, 1, 2, 3)
|
self.assertRaises(TypeError, s, 1, 2, 3)
|
||||||
|
|
||||||
def test_structures(self):
|
def test_structures(self):
|
||||||
|
@ -91,7 +92,7 @@ class CFuncPtrTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def NoNullHandle(value):
|
def NoNullHandle(value):
|
||||||
if not value:
|
if not value:
|
||||||
raise WinError()
|
raise ctypes.WinError()
|
||||||
return value
|
return value
|
||||||
|
|
||||||
strchr = lib.my_strchr
|
strchr = lib.my_strchr
|
||||||
|
|
|
@ -5,20 +5,21 @@ show how the type behave.
|
||||||
Later...
|
Later...
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import ctypes
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
from test.test_ctypes import need_symbol
|
from test.test_ctypes import need_symbol
|
||||||
import sys, unittest
|
import sys, unittest
|
||||||
|
|
||||||
try:
|
try:
|
||||||
WINFUNCTYPE
|
WINFUNCTYPE = ctypes.WINFUNCTYPE
|
||||||
except NameError:
|
except AttributeError:
|
||||||
# fake to enable this test on Linux
|
# fake to enable this test on Linux
|
||||||
WINFUNCTYPE = CFUNCTYPE
|
WINFUNCTYPE = CFUNCTYPE
|
||||||
|
|
||||||
import _ctypes_test
|
import _ctypes_test
|
||||||
dll = CDLL(_ctypes_test.__file__)
|
dll = CDLL(_ctypes_test.__file__)
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
windll = WinDLL(_ctypes_test.__file__)
|
windll = ctypes.WinDLL(_ctypes_test.__file__)
|
||||||
|
|
||||||
class POINT(Structure):
|
class POINT(Structure):
|
||||||
_fields_ = [("x", c_int), ("y", c_int)]
|
_fields_ = [("x", c_int), ("y", c_int)]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
|
import ctypes
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -72,18 +73,18 @@ class LoaderTest(unittest.TestCase):
|
||||||
print(find_library("user32"))
|
print(find_library("user32"))
|
||||||
|
|
||||||
if os.name == "nt":
|
if os.name == "nt":
|
||||||
windll.kernel32.GetModuleHandleW
|
ctypes.windll.kernel32.GetModuleHandleW
|
||||||
windll["kernel32"].GetModuleHandleW
|
ctypes.windll["kernel32"].GetModuleHandleW
|
||||||
windll.LoadLibrary("kernel32").GetModuleHandleW
|
ctypes.windll.LoadLibrary("kernel32").GetModuleHandleW
|
||||||
WinDLL("kernel32").GetModuleHandleW
|
ctypes.WinDLL("kernel32").GetModuleHandleW
|
||||||
# embedded null character
|
# embedded null character
|
||||||
self.assertRaises(ValueError, windll.LoadLibrary, "kernel32\0")
|
self.assertRaises(ValueError, ctypes.windll.LoadLibrary, "kernel32\0")
|
||||||
|
|
||||||
@unittest.skipUnless(os.name == "nt",
|
@unittest.skipUnless(os.name == "nt",
|
||||||
'test specific to Windows')
|
'test specific to Windows')
|
||||||
def test_load_ordinal_functions(self):
|
def test_load_ordinal_functions(self):
|
||||||
import _ctypes_test
|
import _ctypes_test
|
||||||
dll = WinDLL(_ctypes_test.__file__)
|
dll = ctypes.WinDLL(_ctypes_test.__file__)
|
||||||
# We load the same function both via ordinal and name
|
# We load the same function both via ordinal and name
|
||||||
func_ord = dll[2]
|
func_ord = dll[2]
|
||||||
func_name = dll.GetString
|
func_name = dll.GetString
|
||||||
|
@ -114,14 +115,16 @@ class LoaderTest(unittest.TestCase):
|
||||||
# also has a high address. 'call_function' should accept
|
# also has a high address. 'call_function' should accept
|
||||||
# addresses so large.
|
# addresses so large.
|
||||||
from _ctypes import call_function
|
from _ctypes import call_function
|
||||||
advapi32 = windll.advapi32
|
|
||||||
|
advapi32 = ctypes.windll.advapi32
|
||||||
# Calling CloseEventLog with a NULL argument should fail,
|
# Calling CloseEventLog with a NULL argument should fail,
|
||||||
# but the call should not segfault or so.
|
# but the call should not segfault or so.
|
||||||
self.assertEqual(0, advapi32.CloseEventLog(None))
|
self.assertEqual(0, advapi32.CloseEventLog(None))
|
||||||
windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p
|
|
||||||
windll.kernel32.GetProcAddress.restype = c_void_p
|
kernel32 = ctypes.windll.kernel32
|
||||||
proc = windll.kernel32.GetProcAddress(advapi32._handle,
|
kernel32.GetProcAddress.argtypes = c_void_p, c_char_p
|
||||||
b"CloseEventLog")
|
kernel32.GetProcAddress.restype = c_void_p
|
||||||
|
proc = kernel32.GetProcAddress(advapi32._handle, b"CloseEventLog")
|
||||||
self.assertTrue(proc)
|
self.assertTrue(proc)
|
||||||
# This is the real test: call the function via 'call_function'
|
# This is the real test: call the function via 'call_function'
|
||||||
self.assertEqual(0, call_function(proc, (None,)))
|
self.assertEqual(0, call_function(proc, (None,)))
|
||||||
|
@ -130,7 +133,7 @@ class LoaderTest(unittest.TestCase):
|
||||||
'test specific to Windows')
|
'test specific to Windows')
|
||||||
def test_load_hasattr(self):
|
def test_load_hasattr(self):
|
||||||
# bpo-34816: shouldn't raise OSError
|
# bpo-34816: shouldn't raise OSError
|
||||||
self.assertFalse(hasattr(windll, 'test'))
|
self.assertFalse(hasattr(ctypes.windll, 'test'))
|
||||||
|
|
||||||
@unittest.skipUnless(os.name == "nt",
|
@unittest.skipUnless(os.name == "nt",
|
||||||
'test specific to Windows')
|
'test specific to Windows')
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import unittest, sys
|
import unittest, sys
|
||||||
|
|
||||||
|
import ctypes
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
import _ctypes_test
|
import _ctypes_test
|
||||||
|
|
||||||
|
@ -193,7 +194,7 @@ class PointersTestCase(unittest.TestCase):
|
||||||
|
|
||||||
# COM methods are boolean True:
|
# COM methods are boolean True:
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
mth = WINFUNCTYPE(None)(42, "name", (), None)
|
mth = ctypes.WINFUNCTYPE(None)(42, "name", (), None)
|
||||||
self.assertEqual(bool(mth), True)
|
self.assertEqual(bool(mth), True)
|
||||||
|
|
||||||
def test_pointer_type_name(self):
|
def test_pointer_type_name(self):
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
|
import ctypes
|
||||||
import contextlib
|
import contextlib
|
||||||
from test import support
|
from test import support
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -16,15 +17,17 @@ class call_function_TestCase(unittest.TestCase):
|
||||||
|
|
||||||
def test(self):
|
def test(self):
|
||||||
from _ctypes import call_function
|
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")
|
kernel32 = ctypes.windll.kernel32
|
||||||
funcaddr = windll.kernel32.GetProcAddress(hdll, b"GetModuleHandleA")
|
kernel32.LoadLibraryA.restype = c_void_p
|
||||||
|
kernel32.GetProcAddress.argtypes = c_void_p, c_char_p
|
||||||
|
kernel32.GetProcAddress.restype = c_void_p
|
||||||
|
|
||||||
|
hdll = kernel32.LoadLibraryA(b"kernel32")
|
||||||
|
funcaddr = kernel32.GetProcAddress(hdll, b"GetModuleHandleA")
|
||||||
|
|
||||||
self.assertEqual(call_function(funcaddr, (None,)),
|
self.assertEqual(call_function(funcaddr, (None,)),
|
||||||
windll.kernel32.GetModuleHandleA(None))
|
kernel32.GetModuleHandleA(None))
|
||||||
|
|
||||||
class CallbackTracbackTestCase(unittest.TestCase):
|
class CallbackTracbackTestCase(unittest.TestCase):
|
||||||
# When an exception is raised in a ctypes callback function, the C
|
# When an exception is raised in a ctypes callback function, the C
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# Windows specific tests
|
# Windows specific tests
|
||||||
|
|
||||||
|
import ctypes
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
import unittest, sys
|
import unittest, sys
|
||||||
from test import support
|
from test import support
|
||||||
|
@ -14,15 +15,17 @@ class FunctionCallTestCase(unittest.TestCase):
|
||||||
def test_SEH(self):
|
def test_SEH(self):
|
||||||
# Disable faulthandler to prevent logging the warning:
|
# Disable faulthandler to prevent logging the warning:
|
||||||
# "Windows fatal exception: access violation"
|
# "Windows fatal exception: access violation"
|
||||||
|
kernel32 = ctypes.windll.kernel32
|
||||||
with support.disable_faulthandler():
|
with support.disable_faulthandler():
|
||||||
# Call functions with invalid arguments, and make sure
|
# Call functions with invalid arguments, and make sure
|
||||||
# that access violations are trapped and raise an
|
# that access violations are trapped and raise an
|
||||||
# exception.
|
# exception.
|
||||||
self.assertRaises(OSError, windll.kernel32.GetModuleHandleA, 32)
|
self.assertRaises(OSError, kernel32.GetModuleHandleA, 32)
|
||||||
|
|
||||||
def test_noargs(self):
|
def test_noargs(self):
|
||||||
# This is a special case on win32 x64
|
# This is a special case on win32 x64
|
||||||
windll.user32.GetDesktopWindow()
|
user32 = ctypes.windll.user32
|
||||||
|
user32.GetDesktopWindow()
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
|
@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
|
||||||
|
@ -73,17 +76,18 @@ class TestWinError(unittest.TestCase):
|
||||||
# see Issue 16169
|
# see Issue 16169
|
||||||
import errno
|
import errno
|
||||||
ERROR_INVALID_PARAMETER = 87
|
ERROR_INVALID_PARAMETER = 87
|
||||||
msg = FormatError(ERROR_INVALID_PARAMETER).strip()
|
msg = ctypes.FormatError(ERROR_INVALID_PARAMETER).strip()
|
||||||
args = (errno.EINVAL, msg, None, ERROR_INVALID_PARAMETER)
|
args = (errno.EINVAL, msg, None, ERROR_INVALID_PARAMETER)
|
||||||
|
|
||||||
e = WinError(ERROR_INVALID_PARAMETER)
|
e = ctypes.WinError(ERROR_INVALID_PARAMETER)
|
||||||
self.assertEqual(e.args, args)
|
self.assertEqual(e.args, args)
|
||||||
self.assertEqual(e.errno, errno.EINVAL)
|
self.assertEqual(e.errno, errno.EINVAL)
|
||||||
self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER)
|
self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER)
|
||||||
|
|
||||||
windll.kernel32.SetLastError(ERROR_INVALID_PARAMETER)
|
kernel32 = ctypes.windll.kernel32
|
||||||
|
kernel32.SetLastError(ERROR_INVALID_PARAMETER)
|
||||||
try:
|
try:
|
||||||
raise WinError()
|
raise ctypes.WinError()
|
||||||
except OSError as exc:
|
except OSError as exc:
|
||||||
e = exc
|
e = exc
|
||||||
self.assertEqual(e.args, args)
|
self.assertEqual(e.args, args)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue