GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Ctypes: Unclear Error Message for WinFunctionType Mismatch in Windows API Calls · Issue #125788 · python/cpython

Ctypes: Unclear Error Message for WinFunctionType Mismatch in Windows API Calls #125788

New issue
Copy link
New issue
Copy link
Open
Open
Ctypes: Unclear Error Message for WinFunctionType Mismatch in Windows API Calls#125788
Copy link
Labels
easytopic-ctypestype-featureA feature request or enhancementA feature request or enhancement

Description

@songyuc
songyuc
opened on Oct 21, 2024
Issue body actions

Description:

When working with Windows API functions (such as SetWindowsHookExW) using ctypes, providing a HOOKPROC callback function of an incorrect type results in an unclear error message. This can be confusing, especially for beginners or when debugging complex scenarios.

Current error message:
TypeError: expected WinFunctionType instance instead of WinFunctionType

Suggested improved error message:
TypeError: expected WinFunctionType with signature (restype=wintypes.LPARAM, argtypes=[ctypes.c_int32, wintypes.WPARAM, wintypes.LPARAM]) but received WinFunctionType with signature (restype=ctypes.c_int, argtypes=[ctypes.c_int, wintypes.WPARAM, wintypes.LPARAM])

Steps to Reproduce:

  1. Create a Python script with the following content:
import ctypes
import ctypes.wintypes

HOOKPROC = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.wintypes.WPARAM, ctypes.wintypes.LPARAM)

user32 = ctypes.windll.user32
user32.SetWindowsHookExW.argtypes = [ctypes.c_int, HOOKPROC, ctypes.wintypes.HINSTANCE, ctypes.wintypes.DWORD]
user32.SetWindowsHookExW.restype = ctypes.wintypes.HHOOK

def callback(nCode, wParam, lParam):
    return user32.CallNextHookEx(None, nCode, wParam, lParam)

pointer = HOOKPROC(callback)
hook_id = user32.SetWindowsHookExW(13, pointer, None, 0)  # 13 corresponds to WH_KEYBOARD_LL

# At this point, import pynput, which modifies the SetWindowsHookExW function
from pynput import keyboard, mouse

# Attempt to set the hook again, which now fails due to type mismatch
hook_id = user32.SetWindowsHookExW(13, pointer, None, 0)
  1. Run the script

Expected Result:
A clear error message indicating the mismatch between the expected and provided WinFunctionType, including details about their signatures.

Actual Result:
An unclear error message: "TypeError: expected WinFunctionType instance instead of WinFunctionType"

Python Version: 3.12.7
Operating System: Windows

Suggested Improvement:
Modify the logic in ctypes that generates these error messages to include more detailed information about the expected and actual WinFunctionType instances, such as their return types and argument types. This would greatly improve the readability and usefulness of the error message, especially for beginners and when debugging complex scenarios.

Additional Notes:
This issue becomes apparent when using libraries like pynput that modify Windows API function signatures. A more descriptive error message would help users identify and resolve such conflicts more easily.

CPython versions tested on:

3.12

Operating systems tested on:

Windows

Linked PRs

  • gh-125788: Include signatures in mismatched ctypes callback TypeError #160995
  • gh-125788: Improve ctypes error message for mismatched callback prototypes #161873

Activity

  1. songyuc
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Oct 21, 2024
  2. picnixz
    added
    OS-windows
    topic-ctypes
    on Oct 21, 2024
  3. zooba
    added
    type-featureA feature request or enhancementA feature request or enhancement
    and removed
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Oct 21, 2024
  4. zooba commented on Oct 21, 2024

    @zooba
    zooba
    on Oct 21, 2024
    Member
    More actions

    Improving an error message is a feature, not a bug, but there shouldn't be any reason why it can't be done here (it just won't be backported to maintenance releases).

    (The bugfix in pynput (or the user's own code) is to use ctypes.WinDLL("user32") rather than ctypes.windll.user32 so that they aren't modifying shared objects. This should already be documented, I'm pretty sure.)

    Reacted by Song Yucheng
    Reacted by Song Yucheng
    Reacted by Song Yucheng
  5. songyuc commented on Oct 29, 2024

    @songyuc
    songyuc
    on Oct 29, 2024
    Author
    More actions

    Improving an error message is a feature, not a bug, but there shouldn't be any reason why it can't be done here (it just won't be backported to maintenance releases).

    (The bugfix in pynput (or the user's own code) is to use ctypes.WinDLL("user32") rather than ctypes.windll.user32 so that they aren't modifying shared objects. This should already be documented, I'm pretty sure.)

    Thanks sincerely for your guide!

  6. moi15moi
    added 2 commits that reference this issue on Oct 15, 2025

    Replace cdll with CDLL and windll with WinDLL

    ecdd82e

    Replace cdll with CDLL and windll with WinDLL

    781147e
  7. diegogimenez04 commented on Jun 9, 2026

    @diegogimenez04
    diegogimenez04
    on Jun 9, 2026
    More actions

    Hello everyone. Is this still an issue? If not, I suggest closing it

  8. ZeroIntensity
    added
    easy
    and removed
    OS-windows
    on Oct 20, 2026
  9. ZeroIntensity commented on Oct 20, 2026

    @ZeroIntensity
    ZeroIntensity
    on Oct 20, 2026
    Member
    More actions

    Yes, this is still valid. This also isn't specific to Windows; here's a Linux repro:

    import ctypes
    
    libc = ctypes.CDLL(None)
    
    CMPFUNC_INT = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p)
    CMPFUNC_LONG = ctypes.CFUNCTYPE(ctypes.c_long, ctypes.c_void_p, ctypes.c_void_p)
    
    libc.qsort.restype = None
    libc.qsort.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_size_t, CMPFUNC_INT]
    
    def cmp(a, b):
        return 0
    
    libc.qsort(None, 0, ctypes.sizeof(ctypes.c_int), CMPFUNC_LONG(cmp))
    Traceback (most recent call last):
      File "/home/peter/develop/cpython/a.py", line 14, in <module>
        libc.qsort(None, 0, ctypes.sizeof(ctypes.c_int), CMPFUNC_LONG(cmp))
        ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ctypes.ArgumentError: argument 4: TypeError: expected CFunctionType instance instead of CFunctionType
    
  10. assilrguez commented on Oct 23, 2026

    @assilrguez
    assilrguez
    on Oct 23, 2026 – with ChatGPT Codex Connector
    More actions

    I worked through a local proposal for this. The mismatch is handled by CDataType_from_param_impl() in Modules/_ctypes/_ctypes.c; callback function types currently reach its generic type error, where both types have the same tp_name.

    For mismatched ctypes callback types, the proposed special case uses each callback type's StgInfo to show the expected and actual return and argument types, while leaving the existing generic error unchanged for other mismatches:

    if (PyCFuncPtrTypeObject_Check(st, type) &&
        PyCFuncPtrObject_Check(st, value)) {
        StgInfo *expected_info, *actual_info;
        if (PyStgInfo_FromType(st, type, &expected_info) < 0 ||
            PyStgInfo_FromType(st, (PyObject *)Py_TYPE(value),
                               &actual_info) < 0) {
            return NULL;
        }
        if (expected_info != NULL && actual_info != NULL) {
            PyErr_Format(PyExc_TypeError,
                         "expected %s with signature (restype=%R, argtypes=%R), "
                         "got %s with signature (restype=%R, argtypes=%R)",
                         ((PyTypeObject *)type)->tp_name,
                         expected_info->restype ? expected_info->restype : Py_None,
                         expected_info->argtypes ? expected_info->argtypes : Py_None,
                         Py_TYPE(value)->tp_name,
                         actual_info->restype ? actual_info->restype : Py_None,
                         actual_info->argtypes ? actual_info->argtypes : Py_None);
            return NULL;
        }
    }

    The resulting message is in the familiar “expected …, got …” form, for example:

    expected CFunctionType with signature (restype=<class 'ctypes.c_float'>, argtypes=(<class 'ctypes.c_void_p'>,)), got CFunctionType with signature (restype=<class 'ctypes.c_double'>, argtypes=(<class 'ctypes.c_short'>,))
    

    I added a regression test in Lib/test/test_ctypes/test_parameters.py that passes a callback with a different restype and argtype and checks that both signatures appear in the TypeError. I also added a Misc/NEWS.d/next/Library entry.

    On my local Windows Release build, the focused test passed and the complete test_ctypes suite passed (701 tests run, 43 skipped). This proposal is for the in-development branch; I have not tested the reporter's exact pynput scenario.

  11. junaidkhan80121
    added a commit that references this issue on Oct 31, 2026

    pythongh-125788: Include signatures in mismatched ctypes callback Typ…

    8849ad6
  12. Anurag-S1ngh commented on Oct 31, 2026

    @Anurag-S1ngh
    Anurag-S1ngh
    on Oct 31, 2026
    More actions

    Hi, I'd like to take this issue. Could you assign it to me?

  13. ZeroIntensity commented on Oct 31, 2026

    @ZeroIntensity
    ZeroIntensity
    on Oct 31, 2026
    Member
    More actions

    We don't assign issues to non-members, but feel free to submit a PR if you have a patch.

  14. cursor
    added a commit that references this issue on Nov 12, 2026

    pythongh-125788: Improve ctypes error message for mismatched callback…

    fd17c9a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    easytopic-ctypestype-featureA feature request or enhancementA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.