[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