PyArg_ParseTuple() when the type could be anything?

  • Thread starter David M. Cotter
  • Start date
D

David M. Cotter

I'd like to be able to use PyArg_ParseTuple() in a generic way.

for example, i'd like to have all commands start with 1 integer parameter, and this "commandID" will inform me of what parameters come next (via LUT).

knowing that i can then call ParseTuple again with the proper parameters.

like this:

if (PyArg_ParseTuple(args, "i|", &commandID)) {

switch (commandID) {

case cmd_with_str: {
const char *strZ = NULL;

if (PyArg_ParseTuple(args, "is", &commandID, &strZ)) {
// do something with string
}
break;
}

case cmd_with_float: {
float valF = -1;

if (PyArg_ParseTuple(args, "if", &commandID, &valF)) {
// do something with float
}
break;
}
}
}

is there a way to achieve this? the "i|" at the start is not working
 
S

Stefan Behnel

David M. Cotter, 03.08.2013 02:55:
I'd like to be able to use PyArg_ParseTuple() in a generic way.

for example, i'd like to have all commands start with 1 integer parameter, and this "commandID" will inform me of what parameters come next (via LUT).

knowing that i can then call ParseTuple again with the proper parameters.

like this:

if (PyArg_ParseTuple(args, "i|", &commandID)) {

switch (commandID) {

case cmd_with_str: {
const char *strZ = NULL;

if (PyArg_ParseTuple(args, "is", &commandID, &strZ)) {
// do something with string
}
break;
}

case cmd_with_float: {
float valF = -1;

if (PyArg_ParseTuple(args, "if", &commandID, &valF)) {
// do something with float
}
break;
}
}
}

is there a way to achieve this? the "i|" at the start is not working

If you're willing to switch to Cython, here's an (untested) example:

cdef enum:
cmd_with_str = 1
cmd_with_float = 2

cdef int command_id = args[0]
if command_id == cmd_with_str:
str_z = args[1] # it's an object, so use it as such
print(str_z)
elif command_id == cmd_with_float:
val_f = <float>args[1] # converting to C float here
...
else:
raise ValueError("unknown command")

Two comments:

1) you can obviously do the same in C, by writing a bit more code. It would
likely be a lot slower, though, and you'd have to take care of error
handling etc.

2) you might want to rethink your design as this is a rather unpythonic
API. Although it depends on who (or what) you are expecting to use it.

Stefan
 
D

David M. Cotter

i was able to get what i wanted by simply iterating over the tupile insteadof using ParseTupile, then just query the type, then convert the type to Cand move on to the next. totally great, now i can pass N different argument types to a single function, and have the C side deal gracefully with whatever types are sent.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top