[Pythonmac-SIG] PyObjC calling syntax again, an idea.

Just van Rossum just@letterror.com
Thu, 24 Oct 2002 11:35:01 +0200


A while back, Jack replied to me:

[JvR]
> > I still know very little about ObjC, let alone pyobjc, but in my ideal 
> > would be
> > something like:
> >
> >   obj.message(arg1name=arg1value, arg2name=arg2value)

[Jack]
> There's a fundamental problem with this: the "argnames" are really part 
> of the Objective C method name. I.e. if you see  a call [object message: 
> arg1 withFoo: arg2] you should think of "message:withFoo:" as the method 
> name, *not* of "message:" as the message name and "withFoo:" as the name 
> of an optional argument.

It just occured to me that this is solvable with an appropriate metaclass. This
method:

  class Foo(SomeCocoaClassWithAppropriateMetaClass):
  
      def foo(self, arg1, arg2, arg3):
          ...

would be converted to this at class definition time:

      def foo_arg1_arg2_arg3_(self, arg1, arg2, arg3):
          ...

This snippet already works:

  import pprint
  import types
      
  class PseudoPyObjCMetaType(type):
  
      def __init__(self, name, bases, dict):
          for name, method in dict.items():
              if isinstance(method, types.FunctionType):
                  code = method.func_code
                  assert code.co_varnames[0] == "self", "complain"
                  argnames = code.co_varnames[1:code.co_argcount]
                  selector = name + "_" + "_".join(argnames) + "_"
                  self.__dict__[selector] = method
  
  
  class Test(object):
      
      __metaclass__ = PseudoPyObjCMetaType
      
      def foo(self, arg1, arg2):
          print arg1, arg2
  
  
  t = Test()
  t.foo(1, 2)
  t.foo_arg1_arg2_(3, 4)


Now, for the other way around (to call an ObjC from Python), maybe a similar
trick can be used? If it is possible to query a class at runtime which selectors
it supports, maybe Python wrappers can be generated on the fly so you can still
do

  obj.foo(arg1="x", arg2="y")

? Maybe this will cost too much. Would like to learn more about the (Py)ObjC
internals...

Just