Skip to content

TypeError: invalid type in setfunc of make_callback_returnable on Python 3.13 #750

@Rjvs

Description

@Rjvs

Describe the bug

I'm hitting this in toga-cocoa’s TogaTable when using rubicon-objc 0.5.3 with Python 3.13 on macOS 26.3.1 (a). It looks like the setfunc installed by make_callback_returnable in ctypes_patch.py raises TypeError: invalid type at line 286:

ctypes.memmove(ptr, ctypes.addressof(value), actual_size)

The exceptions are “ignored” (non-crashing) but indicate struct parameters aren’t being marshalled correctly into the callback.

How to reproduce the bug

It looks like any @objc_method that takes a struct parameter triggers this.

Minimum example code

from rubicon.objc import NSPoint, objc_method, objc_property
from rubicon.objc.runtime import load_library, objc_id

NSTableView = ObjCClass("NSTableView")

class MyTableView(NSTableView):
    @objc_method
    def canDragRowsWithIndexes_atPoint_(
        self,
        rowIndexes,
        mouseDownPoint: NSPoint,
    ) -> bool:
        return False

Screenshots

No response

Environment details

  • macOS 26.3.1 (a) (25D771280a), Apple Silicon
  • Python 3.13 (Briefcase-packaged)
  • Briefcase 0.4.1
  • toga-cocoa 0.5.3
  • rubicon-objc 0.5.3

Logs

2026-04-21 11:26:28.956 Connie[93191:127588242] TypeError: invalid type
2026-04-21 11:26:28.959 Connie[93191:127588242] Exception ignored on calling ctypes callback function <function make_callback_returnable.<locals>.setfunc at 0x10b5fd9e0>:
2026-04-21 11:26:28.959 Connie[93191:127588242] Traceback (most recent call last):
2026-04-21 11:26:28.959 Connie[93191:127588242]   File "{redacted}/connie/build/connie/macos/app/Connie.app/Contents/Resources/app_packages/rubicon/objc/ctypes_patch.py", line 286, in setfunc
2026-04-21 11:26:28.959 Connie[93191:127588242]     ctypes.memmove(ptr, ctypes.addressof(value), actual_size)

Additional context

Would this fix?

@SETFUNC
def setfunc(ptr, value, size):
    actual_size = ctypes.sizeof(ctype)
    if size != 0 and size != actual_size:
        raise ValueError(
            f"setfunc for ctype {ctype}: Requested size {size} "
            f"does not match actual size {actual_size}"
        )

    # value is already the expected type or another ctypes instance
    if isinstance(value, ctypes.Structure):
        ctypes.memmove(ptr, ctypes.addressof(value), actual_size)
        return

    # value is a tuple/list of field values (e.g. NSPoint as (x, y))
    if isinstance(value, (tuple, list)):
        value = ctype(*value)
        ctypes.memmove(ptr, ctypes.addressof(value), actual_size)
        return

    # value is raw bytes
    if isinstance(value, (bytes, bytearray)):
        value = ctype.from_buffer_copy(value)
        ctypes.memmove(ptr, ctypes.addressof(value), actual_size)
        return

    # last resort — single-value construction
    value = ctype(value)
    ctypes.memmove(ptr, ctypes.addressof(value), actual_size)

Metadata

Metadata

Assignees

No one assigned

    Labels

    awaiting detailsMore details are needed before the issue can be triaged.bugA crash or error in behavior.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions