Skip to content

Fix KeyError(b'd') in make_type for unregistered struct types on Python 3#149

Open
ElliotGarbus wants to merge 2 commits into
kivy:masterfrom
ElliotGarbus:fix/bytes-type-key-keyerror
Open

Fix KeyError(b'd') in make_type for unregistered struct types on Python 3#149
ElliotGarbus wants to merge 2 commits into
kivy:masterfrom
ElliotGarbus:fix/bytes-type-key-keyerror

Conversation

@ElliotGarbus

@ElliotGarbus ElliotGarbus commented Jun 12, 2026

Copy link
Copy Markdown

Summary

Fixes #148.

On Python 3, signature_types_to_list returns bytes items (e.g. b'd'), but the types dict in objc_py_types.py has str keys ('d'). Pre-registered structs (CGRect, NSRange, CGPoint, CGSize) are returned from the registry before make_type is ever called, which masked this bug. Any unregistered struct with primitive fields — including UIEdgeInsets — falls through to make_type and raises KeyError: b'd'.

Changes

  • pyobjus/objc_py_types.py — decode _type from bytes before the types dict lookup in make_type. Also collapsed the duplicated field_list.append that existed in both branches of if not field_name into a single statement.
  • tests/test_make_type_bytes.py — new regression test file with 6 tests (+ 14 subtests) covering: 4-double struct (the UIEdgeInsets shape), float, mixed int/float, every primitive type in the dict via subtests, and both code paths (auto-generated field names and explicit member names).

Also fixed a pre-existing failure in test_multiple_delegates: each connection_didFailWithError_ callback calls CFRunLoopStop, so a single CFRunLoopRunInMode call exits after the first delegate fires and the second connection's event is never delivered. The fix restarts the run loop in short bursts until both delegates have been called (or a 10-second timeout is reached).

…on 3

The types dict uses str keys but signature_types_to_list returns bytes on
Python 3 (b'd' != 'd'), causing a KeyError for any unregistered struct
with primitive fields (e.g. UIEdgeInsets). Pre-registered structs such as
CGRect never hit this path, masking the bug.

Decode _type from bytes before the dict lookup and collapse the duplicated
field_list.append call into a single statement.

Closes kivy#148
connection_didFailWithError_ calls CFRunLoopStop after each failure, so a
single CFRunLoopRunInMode call exits after the first delegate fires and
the second connection's event is never delivered.  Run the loop in short
bursts, restarting after each CFRunLoopStop, until both delegates have
been called.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

make_type raises KeyError(b'd') for unregistered struct return types on Python 3

1 participant