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 <ronaldousso...@mac.com> wrote:
> 
> 
> 
>> On 6 Jan 2020, at 00:51, Rand Dvorak <randdvo...@gmail.com> 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  -  Pythonmac-SIG@python.org
>> https://mail.python.org/mailman/listinfo/pythonmac-sig
>> unsubscribe: https://mail.python.org/mailman/options/Pythonmac-SIG
> 

_______________________________________________
Pythonmac-SIG maillist  -  Pythonmac-SIG@python.org
https://mail.python.org/mailman/listinfo/pythonmac-sig
unsubscribe: https://mail.python.org/mailman/options/Pythonmac-SIG

Reply via email to