I found the place in the code to try to understand what is happening, but am a
little out of my depth
In libffi_support.m
case _C_ID:
if (argtype[1] == '?') {
/* Argument is a block */
if (argument == Py_None) {
argbuf_cur = align(argbuf_cur,
PyObjCRT_AlignOfType(argtype));
arg = argbuf + argbuf_cur;
argbuf_cur += PyObjCRT_SizeOfType(argtype);
PyObjC_Assert(argbuf_cur <= argbuf_len, -1);
*(void**)arg = NULL;
} else {
if (methinfo->argtype[i]->callable == NULL) {
PyErr_Format(PyExc_TypeError,
"Argument %" PY_FORMAT_SIZE_T
"d is a block, but no signature
available",
i);
return -1;
}
argbuf_cur = align(argbuf_cur,
PyObjCRT_AlignOfType(argtype));
arg = argbuf + argbuf_cur;
argbuf_cur += PyObjCRT_SizeOfType(argtype);
PyObjC_Assert(argbuf_cur <= argbuf_len, -1);
*(void**)arg =
PyObjCBlock_Create(methinfo->argtype[i]->callable,
argument);
if (*(void**)arg == NULL) {
return -1;
}
byref_attr[i].buffer = PyCapsule_New(
*(void**)arg, "objc.__block__",
block_capsule_cleanup);
}
arglist[i] = signature_to_ffi_type(argtype);
values[i] = arg;
break;
}
Is this telling me that I am not passing a python callable?
> On Jan 6, 2020, at 09:27, Ronald Oussoren <[email protected]> wrote:
>
>
>
>> On 6 Jan 2020, at 00:51, Rand Dvorak <[email protected]> wrote:
>>
>>
>> I am trying to implement a simple server in PyObjC for the Criollo HTTP
>> server. The server has a method to set route handlers by passing a block to
>> setup the route and then when it receives and HTTP request for the route it
>> calls the block. The block has the signature:
>>
>> typedef void(^CRRouteBlock)(CRRequest* _Nonnull request, CRResponse*
>> _Nonnull response, CRRouteCompletionBlock _Nonnull completionHandler);
>>
>>
>> So, here is my simple proof of concept:
>>
>> import objc
>> CRApplication = objc.lookUpClass("CRApplication")
>> global server
>>
>> def helloHandler(self, request, response, handler):
>> response.send_("Hello World!")
>> handler()
>>
>> if __name__ == "__main__":
>> server = CRApplication.sharedApplication().delegate().server()
>> server.get_block_("/", objc.selector(helloHandler,
>> signature=b'v@:@@@‘)) *** error occurs here
>> server.startListening()
>>
>>
>> But, when I try to setup the route I get the following error:
>>
>> Traceback (most recent call last):
>> File "main.py", line 21, in <module>
>> server.get_block_("/", objc.selector(helloHandler, signature=b'v@:@@'))
>> TypeError: Argument 3 is a block, but no signature available
>>
>>
>> Any ideas how to workaround this issue and implement the route handlers in
>> PyObjC?
>
> The code below should do the trick, but eas typed directly into this mail and
> might therefore contain syntax errors.
>
> import objc
> objc.registerMetaDataForSelector(
> b”CRApplication”, # name of the class implementing “get_block:”, or
> “NSObject”
> b”get_block:”,
> {
> “arguments”: {
> 2: {
> “callable”: {
> “arguments”: {
> 0: { “type”: b”^v” },
> 1: { “type”: b”@” },
> 2: { “type”: b”@” },
> 3: { “type”: b”@” }
> },
> “retail”: { “type”: b”v” }
> }
> }
> }
> )
>
> This tells the bridge the signature for the block argument of the
> “get_block:” selector, which is information that cannot be retrieved from the
> Objective-C runtime. Argument 2 is the first real argument of ObjC
> selectors, after the implicit arguments “self” and “_imp” (which is not
> available in python code).
>
> Ronald
> —
>
> Twitter: @ronaldoussoren
> Blog: https://blog.ronaldoussoren.net/
>> _______________________________________________
>> Pythonmac-SIG maillist - [email protected]
>> https://mail.python.org/mailman/listinfo/pythonmac-sig
>> unsubscribe: https://mail.python.org/mailman/options/Pythonmac-SIG
>
_______________________________________________
Pythonmac-SIG maillist - [email protected]
https://mail.python.org/mailman/listinfo/pythonmac-sig
unsubscribe: https://mail.python.org/mailman/options/Pythonmac-SIG