Embedding Python: How to help the scripter? - c++

I'm using Boost to embed Python in my application. For example, I want to check that the following function receives an integer and a string as the first and second parameters (the function is defined in C++).
someFunction(123, 'words')
If I find that the parameters are incorrect, how can I notify the scripter about which line they need to correct, for example?

If you wrap the function using usual def("someFunction",someFunction,...), caller will get automatically notified about c++ signature which could not be matched with objects passed from python, like this (the method takes one dictionary argument, is called with 3 numbers instead):
>>> scene.updateAttrs(1,2,3)
ArgumentError: Python argument types in
Serializable.updateAttrs(Scene, int, int, int)
did not match C++ signature:
updateAttrs(Serializable {lvalue}, boost::python::dict)
Can you post some code to see what is your problem?

Raise an exception with all the information you want them to know, just like you would in Python. In fact, that answer seems so obvious, it makes me think I'm missing something in your question.

Related

Passing function, why is lambda required

I'm trying to use timeit to time an algorthm (reversing the string)
My question is about the signature of timeit.repeat
here is what i'm using, it is working fine
timeit.repeat(lambda: reverseString_perf(s), setup='pass', timer=timeit.default_timer,number=3)
my questions is - why can i not pass the function directly (as shown below)
timeit.repeat(reverseString_perf(s), setup='pass', timer=timeit.default_timer,number=3) #does not work
instead i'm having to pass lambda:reverseString_perf(s)
to get it to work.
there is no anonymous function here, so this is confusing usage.
reverseString_perf(s) evaluates to the return value. If you passed in just reverseString_perf, it would work; however, you wouldn't be able to include the parameter in this case.
lambda: reverseString_perf(s) works because it is still a function, unlike reverseString_perf(s), which is the return value.

Proper way of handling char * returning data in swig/python

I have a C++ routine MyClass::myFunction(char * message). which returns a message by writing in the message buffer. This routine is exported to python via SWIG. When the routine is called, I assume that the char * points to a python allocated memory area associated to the string.
Now, the SWIG documentation says that modifying the contents of this buffer is a baaad idea, which makes sense because strings are supposed to be immutable. So the question now is: what is the proper way of dealing with this case?
Sounds like you need the cstring.i library:
The cstring.i library file provides a collection of macros for dealing
with functions that either mutate string arguments or which try to
output string data through their arguments.
Particularly the %cstring_mutable macro:
%include <cstring.i>
%cstring_mutable(char *ustr);
...
void make_upper(char *ustr);
In Python:
>>> make_upper("hello world")
'HELLO WORLD'
The parameter name matters. In this case any function with a char *ustr parameter will be affected. So either make your parameter name unique or make all your mutable string parameters have the same name.
Note that there's also an expansion option that might be useful in your case.

Parsing python arguments in c++ extension

Is there a function similar to PyArg_ParseTuple and PyArg_ParseTupleAndKeywords, without using a variable argument list?
I have a c++ extension that takes a long list of input arguments. Parsing them in the format of PyArg_ParseTuple and PyArg_ParseTupleAndKeywords is just ugly to look at. I'm hoping to be able to pass my argument list in the form of ([keyword1, format1, ptr1], [keyword2, format2, ptr2], ...). Are there existing functions or packages to do so?

c++ how to process the argu which uncertain type?

There's a web api which output json format:
{"ret":0}
c++ program could get the value of "ret", and it's a INT type.
but if modify the api, output to this:
{"ret":"0"}
c++ program runs error.
what if the value of "ret" is uncertain type, maybe INT or maybe STRING?
is there a way to process the uncertain type value in c++?
No, C++ is a statically-typed language. It's my opinion that you should code against the datatypes of the API which should not change. It is commonly accepted that if the API chagnges, then the code calling that API has to change as well.
You could just use Regex for different cases.
Like checking if there are two " around your input

Name variable Lua

I have the following code in Lua:
ABC:
test (X)
The test function is implemented in C + +. My problem is this: I need to know what the variable name passed as parameter (in this case X). In C + + only have access to the value of this variable, but I must know her name.
Help please
Functions are not passed variables; they are passed values. Variables are just locations that store values.
When you say X somewhere in your Lua code, that means to get the value from the variable X (note: it's actually more complicated than that, but I won't get into that here).
So when you say test(X), you're saying, "Get the value from the variable X and pass that value as the first parameter to the function test."
What it seems like you want to do is change the contents of X, right? You want to have the test function modify X in some way. Well, you can't really do that directly in Lua. Nor should you.
See, in Lua, you can return values from functions. And you can return multiple values. Even from C++ code, you can return multiple values. So whatever it is you wanted to store in X can just be returned:
X = test(X)
This way, the caller of the function decides what to do with the value, not the function itself. If the caller wants to modify the variable, that's fine. If the caller wants to stick it somewhere else, that's also fine. Your function should not care one way or the other.
Also, this allows the user to do things like test(5). Here, there is no variable; you just pass a value directly. That's one reason why functions cannot modify the "variable" that is passed; because it doesn't have to be a variable. Only values are passed, so the user could simply pass a literal value rather than one stored in a variable.
In short: you can't do it, and you shouldn't want to.
The correct answer is that Lua doesn't really support this, but there is the debug interface. See this question for the solution you're looking for. If you can't get a call to debug to work directly from C++, then wrap your function call with a Lua function that first extracts the debug results and then calls your C++ function.
If what you're after is a string representation of the argument, then you're kind of stuck in lua.
I'm thinking something like in C:
assert( x==y );
Which generates a nice message on failure. In C this is done through macros.
Something like this (untested and probably broken).
#define assert(X) if(!(X)) { printf("ASSERION FAILED: %s\n", #X ); abort(); }
Here #X means the string form of the arguments. In the example above that is "x==y". Note that this is subtly different from a variable name - its just the string used in the parser when expanding the macro.
Unfortunately there's no such corresponding functionality in lua. For my lua testing libraries I end up passing the stringified version as part of the expression, so in lua my code looks something like this:
assert( x==y, "x==y")
There may be ways to make this work as assert("x==y") using some kind of string evaluation and closure mechanism, but it seemed to tricky to be worth doing to me.
EDIT:
While this doesn't appear to be possible in pure lua, there's a patched version that does seem to support macros: http://lua-users.org/wiki/LuaMacros . They even have an example of a nicer assert.