Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #51827 > unrolled thread

PyArg_ParseTuple() when the type could be anything?

Started by"David M. Cotter" <me@davecotter.com>
First post2013-08-02 17:55 -0700
Last post2013-08-05 15:55 -0700
Articles 3 — 2 participants

Back to article view | Back to comp.lang.python


Contents

  PyArg_ParseTuple() when the type could be anything? "David M. Cotter" <me@davecotter.com> - 2013-08-02 17:55 -0700
    Re: PyArg_ParseTuple() when the type could be anything? Stefan Behnel <stefan_ml@behnel.de> - 2013-08-03 16:31 +0200
    Re: PyArg_ParseTuple() when the type could be anything? "David M. Cotter" <me@davecotter.com> - 2013-08-05 15:55 -0700

#51827 — PyArg_ParseTuple() when the type could be anything?

From"David M. Cotter" <me@davecotter.com>
Date2013-08-02 17:55 -0700
SubjectPyArg_ParseTuple() when the type could be anything?
Message-ID<d89fba21-68b0-47b4-818b-2c8e80b35ff8@googlegroups.com>
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

[toc] | [next] | [standalone]


#51860

FromStefan Behnel <stefan_ml@behnel.de>
Date2013-08-03 16:31 +0200
Message-ID<mailman.156.1375540313.1251.python-list@python.org>
In reply to#51827
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

[toc] | [prev] | [next] | [standalone]


#51987

From"David M. Cotter" <me@davecotter.com>
Date2013-08-05 15:55 -0700
Message-ID<7756ab34-3545-4dba-8a7e-c94d469681ce@googlegroups.com>
In reply to#51827
i was able to get what i wanted by simply iterating over the tupile instead of using ParseTupile, then just query the type, then convert the type to C and 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.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web