I got it working.  Basically I have a main.py file in Resources that get loaded 
and run by PyRun_SimpleFile in applicationDidFinishLaunching.  Control is then 
passed to the python interpreter.  Notice the infinite loop at the bottom which 
is needed because the interpreter finishes executing the file and exits.  It is 
needed to keep the python interpreter alive.  I need a better solution to keep 
the interpreter alive because this eats up too much cpu. It was just a hack to 
prove that is what was happening.
import objc 
from Foundation import NSLog
CRApplication = objc.lookUpClass("CRApplication")
objc.registerMetaDataForSelector(
        b'CRRouter',
        b'get:block:',
        {
        'arguments': {
                3: { 'callable': {
                        'arguments': {
                        0:{'type': b'^v'},
                        1:{'type': b'@'},
                        2:{'type': b'@'},
                        3:{'type': b'@'}
                        },
                '       retval': { 'type': b'v' }
                        }
                   }
                }
        }
)

global server

        
def helloHandler(request, response, handler):
        NSLog("%@ %@ %@", request, response, handler)
        response.send_("Hello World!")
        handler()
        
if __name__ == "__main__":
        server = CRApplication.sharedApplication().delegate().server()
        NSLog("Server: %@", server)
        server.get_block_("/", objc.selector(helloHandler, signature=b'^v:@@@'))
        NSLog("Started...")
        socket = server.startListening()
        while(socket):
                pass


> On Jan 8, 2020, at 15:41, Ronald Oussoren <ronaldousso...@mac.com> wrote:
> 
> What is the type of ‘server’?
> 
> And I just noticed the metadata block is a bit of, the callable is argument 3 
> instead of 2. 
> 
> Ronald
> 
> --
> On the road, hence brief. 
> 
>> On 8 Jan 2020, at 17:18, Rand Dvorak <randdvo...@gmail.com> wrote:
>> 
>> Same result:
>> 
>>   File "main.py", line 40, in <module>
>>     server.get_block_("/", helloHandler)
>> TypeError: Argument 3 is a block, but no signature available
>> 
>> 
>>> On Jan 8, 2020, at 03:20, Ronald Oussoren <ronaldousso...@mac.com 
>>> <mailto:ronaldousso...@mac.com>> wrote:
>>> 
>>> Please change “get_block_” to “get:block:” in the call to 
>>> objc.registerMetadataForSelector.
>>> 
>>> Ronald
>>> —
>>> 
>>> Twitter: @ronaldoussoren
>>> Blog: https://blog.ronaldoussoren.net/ <https://blog.ronaldoussoren.net/>
>>> 
>>>> On 8 Jan 2020, at 02:04, Rand Dvorak <randdvo...@gmail.com 
>>>> <mailto:randdvo...@gmail.com>> wrote:
>>>> 
>>>> Same results with this code:
>>>> 
>>>> import objc 
>>>> CRApplication = objc.lookUpClass("CRApplication")
>>>> objc.registerMetaDataForSelector(
>>>>    b'CRServer',
>>>>    b'get_block_',
>>>>    {
>>>>    'arguments': {
>>>>            2: {
>>>>                    'callable': {
>>>>                    'arguments': {
>>>>                    0:{'type': b'^v'},
>>>>                    1:{'type': b'@'},
>>>>                    2:{'type': b'@'},
>>>>                    3:{'type': b'?'}
>>>>                    },
>>>>            '       retval': { 'type': b'v' }
>>>>                    } 
>>>>            }
>>>>    }
>>>>    }
>>>> )
>>>> 
>>>> global server
>>>> 
>>>>    
>>>> def helloHandler(request, response, handler):
>>>>    response.send_("Hello World!")
>>>>    handler()
>>>>    
>>>> if __name__ == "__main__":
>>>>    server = CRApplication.sharedApplication().delegate().server()
>>>>    server.get_block_("/", helloHandler)
>>>>    server.startListening()
>>>> 
>>>> 
>>>>> On Jan 7, 2020, at 04:47, Ronald Oussoren <ronaldousso...@mac.com 
>>>>> <mailto:ronaldousso...@mac.com>> wrote:
>>>>> 
>>>>> And given de example on https://criollo.io: <https://criollo.io/>
>>>>> 
>>>>> - The class name is CRServer, not CRApplication
>>>>> - The selector is “get:block:” instead of “get_block:”, which also means 
>>>>> the block is argument 3 instead of 2.
>>>>> 
>>>>>>> objc.registerMetaDataForSelector(
>>>>>>>         b'CRServer',
>>>>>>>         b’get:block:',
>>>>>>>         {
>>>>>>>         'arguments': {
>>>>>>>                 3: {
>>>>>>>                         'callable': {
>>>>>>>                         'arguments': {
>>>>>>>                         0:{'type': b'^v'},
>>>>>>>                         1:{'type': b'@'},
>>>>>>>                         2:{'type': b'@'},
>>>>>>>                         3:{'type': b'@'}
>>>>>>>                         },
>>>>>>>                         'retval': { 'type': b'v' }
>>>>>>>                         } 
>>>>>>>                 }
>>>>>>>         }
>>>>>>>         }
>>>>>>> )
>>>>> 
>>>>> and later:
>>>>> 
>>>>>>>         server.get_block_("/", helloHandler)
>>>>> 
>>>>>> 
>>>>> 
>>>>> 
>>>>> —
>>>>> 
>>>>> Twitter: @ronaldoussoren
>>>>> Blog: https://blog.ronaldoussoren.net/ <https://blog.ronaldoussoren.net/>
>>>>> 
>>>>>> On 7 Jan 2020, at 10:00, Ronald Oussoren via Pythonmac-SIG 
>>>>>> <pythonmac-sig@python.org <mailto:pythonmac-sig@python.org>> wrote:
>>>>>> 
>>>>>> Hi,
>>>>>> 
>>>>>> You also need to remove the call to objc.selector. With correct metadata 
>>>>>> “blocks” are callables in Python code.
>>>>>> 
>>>>>> Ronald
>>>>>> —
>>>>>> 
>>>>>> Twitter: @ronaldoussoren
>>>>>> Blog: https://blog.ronaldoussoren.net/ <https://blog.ronaldoussoren.net/>
>>>>>> 
>>>>>>> On 6 Jan 2020, at 23:59, Rand Dvorak <randdvo...@gmail.com 
>>>>>>> <mailto:randdvo...@gmail.com>> wrote:
>>>>>>> 
>>>>>>> Same result:
>>>>>>> 
>>>>>>> Updated code:
>>>>>>> 
>>>>>>> import objc 
>>>>>>> CRApplication = objc.lookUpClass("CRApplication")
>>>>>>> objc.registerMetaDataForSelector(
>>>>>>>         b'CRApplication',
>>>>>>>         b'get_block_',
>>>>>>>         {
>>>>>>>         'arguments': {
>>>>>>>                 2: {
>>>>>>>                         'callable': {
>>>>>>>                         'arguments': {
>>>>>>>                         0:{'type': b'^v'},
>>>>>>>                         1:{'type': b'@'},
>>>>>>>                         2:{'type': b'@'},
>>>>>>>                         3:{'type': b'@'}
>>>>>>>                         },
>>>>>>>                 '       retval': { 'type': b'v' }
>>>>>>>                         } 
>>>>>>>                 }
>>>>>>>         }
>>>>>>>         }
>>>>>>> )
>>>>>>> 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@:@@@'))
>>>>>>>         server.startListening()
>>>>>>> 
>>>>>>> 
>>>>>>> results:
>>>>>>> 
>>>>>>> Traceback (most recent call last):
>>>>>>>   File "main.py", line 37, in <module>
>>>>>>>     server.get_block_("/", objc.selector(helloHandler, 
>>>>>>> signature=b'v@:@@@'))
>>>>>>> TypeError: Argument 3 is a block, but no signature available
>>>>>>> 
>>>>>>> 
>>>>>>>> On Jan 6, 2020, at 09:27, Ronald Oussoren <ronaldousso...@mac.com 
>>>>>>>> <mailto:ronaldousso...@mac.com>> wrote:
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>>> On 6 Jan 2020, at 00:51, Rand Dvorak <randdvo...@gmail.com 
>>>>>>>>> <mailto: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/ 
>>>>>>>> <https://blog.ronaldoussoren.net/>
>>>>>>>>> _______________________________________________
>>>>>>>>> Pythonmac-SIG maillist  -  Pythonmac-SIG@python.org 
>>>>>>>>> <mailto:Pythonmac-SIG@python.org>
>>>>>>>>> https://mail.python.org/mailman/listinfo/pythonmac-sig 
>>>>>>>>> <https://mail.python.org/mailman/listinfo/pythonmac-sig>
>>>>>>>>> unsubscribe: https://mail.python.org/mailman/options/Pythonmac-SIG 
>>>>>>>>> <https://mail.python.org/mailman/options/Pythonmac-SIG>
>>>>>>>> 
>>>>>>> 
>>>>>> 
>>>>>> _______________________________________________
>>>>>> Pythonmac-SIG maillist  -  Pythonmac-SIG@python.org 
>>>>>> <mailto:Pythonmac-SIG@python.org>
>>>>>> https://mail.python.org/mailman/listinfo/pythonmac-sig 
>>>>>> <https://mail.python.org/mailman/listinfo/pythonmac-sig>
>>>>>> unsubscribe: https://mail.python.org/mailman/options/Pythonmac-SIG 
>>>>>> <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