pyobjus
pyobjus copied to clipboard
Use `method_getNumberOfArguments`, `method_copyArgumentType` and `method_copyReturnType` to define argument and return types
I'm upgrading the iOS and macOS camera support on Kivy, and after a few tests I decided to use pyobjus
sometimes, so the user can easily interact with AVCaptureDevice
and AVCaptureSession
, without writing a specific API.
Unfortunately, during development, something took my attention:
File "/Users/mirko/Documents/projects/kivy/kivy/uix/camera.py", line 116, in on_play
self._camera.start()
File "kivy/core/camera/camera_avfoundation.pyx", line 135, in kivy.core.camera.camera_avfoundation.CameraAVFoundation.start
self.set_preset("AVCaptureSessionPresetHigh")
File "kivy/core/camera/camera_avfoundation.pyx", line 158, in kivy.core.camera.camera_avfoundation.CameraAVFoundation.set_preset
if self._kivyavfcamera.mCaptureSession.canSetSessionPreset_(preset):
File "pyobjus/pyobjus_types.pxi", line 647, in pyobjus.ObjcClassInstance.__getattribute__
File "pyobjus/pyobjus.pyx", line 500, in pyobjus.ObjcMethod.__call__
File "pyobjus/pyobjus.pyx", line 240, in pyobjus.ObjcMethod.__init__
File "pyobjus/pyobjus_conversions.pxi", line 181, in pyobjus.convert_to_cy_cls_instance
File "pyobjus/pyobjus.pyx", line 736, in pyobjus.autoclass
File "pyobjus/pyobjus.pyx", line 539, in pyobjus.class_get_methods
File "pyobjus/pyobjus.pyx", line 531, in pyobjus.objc_method_to_py
File "pyobjus/pyobjus.pyx", line 240, in pyobjus.ObjcMethod.__init__
File "pyobjus/type_enc.pxi", line 13, in pyobjus.parse_signature
File "pyobjus/type_enc.pxi", line 2, in pyobjus.seperate_encoding
IndexError: list index out of range
So, I added some debug in pyobjus
, and I found out that sometimes (E.g. (b'b@:@', b'conformsToProtocol:')
), the signature does not contain any stack layout info. (See: https://stackoverflow.com/questions/11527385/how-are-the-digits-in-objc-method-type-encoding-calculated)
Our previous logic took the return value from method_getTypeEncoding
and then parsed the signature, by using a regex to split it. Unfortunately, the regex works thanks to the stack layout info digits.
Thankfully 🎉, Apple provides method_getNumberOfArguments
, method_copyArgumentType
and method_copyReturnType
(https://developer.apple.com/documentation/objectivec/objective-c_functions?language=objc), so we can avoid implementing any extra logic or specific patches on our side, while also cleaning-up some complexity.
⚠️ But, there's an issue ⚠️
While doing these changes, I needed to change the positional arguments of the ObjcMethod
init method.
Even if the risk of someone who used it directly is quite low, I'm still breaking the API, so we likely need a new major release bump and a warning should be added in the release notes.
💡Also likely fixes issue: https://github.com/kivy/pyobjus/issues/21