[pygccxml-development] Feature proposal: "Argument policies"
Brought to you by:
mbaas,
roman_yakovenko
From: Matthias B. <ba...@ir...> - 2006-04-18 17:06:36
|
Hi, here's a suggestion for a new feature that should deal with the problem that C++ functions that have more than just one output (by taking references) cannot be translated literally to Python. Even worse, they compile without errors but they are plain useless in Python because there's no way to invoke such functions. One example of such a function is the already mentioned getSize(int& width, int& height) method that returns the resolution of an image. It is my understanding that such a function requires a wrapper function that changes the signature so that the function takes no arguments and returns a Python tuple with the result. Having to write those wrappers manually is quite a repetitive and tedious task. So my suggestion is to introduce something similar to call policies, that's why I called it "argument policies". The idea is just that for each "problematic" argument you specify that it needs special treatment. In the above case, pyplusplus needs to know that the arguments are actually used for output values instead of input values. This could be specified like this: Image.Method("getSize").setArgPolicy(Output(1), Output(2)) setArgPolicy() is a new decorator that takes an arbitrary number of "argument policies" as input. The "Output" policy takes one integer as argument which is the index of the argument it applies to. So by writing "Output(1)", the user specifies that the first argument is actually an output value. This is already enough information so that a wrapper function can be created automatically. The wrapper function would take no arguments anymore and return two integers with the result. Another example is a function that takes a pointer to a double as input. For example: void getTranslation(double t[3]) void setTranslation(double t[3]) In the first case, 't' is an ouput argument used to store the result whereas in the second case 't' is an input argument. The above Output policy cannot be used because Python has no double[3] type. Instead, the wrapper needs some additional code to copy a Python sequence into a double array or vice versa: cls.Method("getTranslation").setArgPolicy(OutputArray(1,3)) cls.Method("setTranslation").setArgPolicy(InputArray(1,3)) The first argument to the OutputArray/InputArray class is again the index of the argument this policy applies to. The second argument is the size of the array. These policies will then also take care of converting between Python sequences and C arrays. More policies can be defined as appropriate. For example, variants of the InputArray/OutputArray policies could take the array size from an additional argument. The nice thing about this framework is that another thing I wanted to have fits nicely into it. For the Maya SDK, I wanted to convert Status objects into exceptions. This can also be expressed with those policies by using a custom policy such as "MStatusToException" that adds code that throws an exception when an error has occurred. There can also be policies that do something with the return value, etc. I have already implemented a prototype version of this in the experimental module. So far, it has worked quite fine for my Maya bindings (by the way, I have just released a first "preview" version of those bindings, so if anybody wants to have a look how I create them, have a look at the 'maya' package over here: http://cgkit.sourceforge.net/) Currently, my implementation would not work when a class already receives wrappers generated by pyplusplus. But I think this could be changed so that the wrappers created by pyplusplus use the same framework for specifying wrapper source code (but this needs modification inside pyplusplus). The above argument policies use the same "code creator" concept that pyplusplus already uses, the interface of those code creators is just different because there are actually two places where code can be placed, either before or after the original function invocation. And in addition to creating code, those special code creators can also modify the signature of a function. So pyplusplus would have to use those special code creators instead of just creating one static block of C++ source code for the entire wrapper function. Any comments? Do you already see cases where this could not work or how it could be improved? - Matthias - |