fix(ctypes): pin LPMSG across MSG-pump prototypes for Python 3.13
Python 3.13's ctypes tightened argtypes checks and now rejects mismatched POINTER(MSG) cache entries — each call to POINTER(MSG) can return a class identity that doesn't match what byref() of an instance produces, raising "expected LP_MSG instance instead of pointer to _MSG" inside GetMessageW/TranslateMessage/DispatchMessageW. Capture POINTER(MSG) once into LPMSG and reuse the same class object across all three prototypes in both the WindowsShutdownGuard pump and the PlatformDetector display-power monitor. Restores the 4 failing win_shutdown tests.
This commit is contained in:
@@ -84,6 +84,21 @@ class PlatformDetector:
|
||||
]
|
||||
user32.DefWindowProcW.restype = ctypes.c_ssize_t
|
||||
|
||||
# Pin the MSG pointer type so byref(msg) matches the prototype
|
||||
# (Python 3.13 ctypes rejects mismatched POINTER(MSG) caches).
|
||||
LPMSG = ctypes.POINTER(ctypes.wintypes.MSG)
|
||||
user32.GetMessageW.argtypes = [
|
||||
LPMSG,
|
||||
ctypes.wintypes.HWND,
|
||||
ctypes.c_uint,
|
||||
ctypes.c_uint,
|
||||
]
|
||||
user32.GetMessageW.restype = ctypes.c_int
|
||||
user32.TranslateMessage.argtypes = [LPMSG]
|
||||
user32.TranslateMessage.restype = ctypes.wintypes.BOOL
|
||||
user32.DispatchMessageW.argtypes = [LPMSG]
|
||||
user32.DispatchMessageW.restype = ctypes.c_ssize_t
|
||||
|
||||
def wnd_proc(hwnd, msg, wparam, lparam):
|
||||
if msg == WM_POWERBROADCAST and wparam == PBT_POWERSETTINGCHANGE:
|
||||
try:
|
||||
|
||||
@@ -133,18 +133,23 @@ def _bind_winapi() -> None:
|
||||
]
|
||||
user32.DefWindowProcW.restype = LRESULT
|
||||
|
||||
# Pin the MSG pointer type once and reuse the same class object on all
|
||||
# three prototypes — Python 3.13 ctypes rejects mismatched POINTER(_MSG)
|
||||
# caches across argtypes, even though they look identical.
|
||||
LPMSG = ctypes.POINTER(_MSG)
|
||||
|
||||
user32.GetMessageW.argtypes = [
|
||||
ctypes.POINTER(_MSG),
|
||||
LPMSG,
|
||||
wintypes.HWND,
|
||||
wintypes.UINT,
|
||||
wintypes.UINT,
|
||||
]
|
||||
user32.GetMessageW.restype = wintypes.BOOL
|
||||
|
||||
user32.TranslateMessage.argtypes = [ctypes.POINTER(_MSG)]
|
||||
user32.TranslateMessage.argtypes = [LPMSG]
|
||||
user32.TranslateMessage.restype = wintypes.BOOL
|
||||
|
||||
user32.DispatchMessageW.argtypes = [ctypes.POINTER(_MSG)]
|
||||
user32.DispatchMessageW.argtypes = [LPMSG]
|
||||
user32.DispatchMessageW.restype = LRESULT
|
||||
|
||||
user32.PostMessageW.argtypes = [
|
||||
|
||||
Reference in New Issue
Block a user