Py_INCREF() incomprehension

Thomas Rachel nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915 at spamschutz.glglgl.de
Tue Apr 26 13:45:07 EDT 2011


Am 26.04.2011 19:28, schrieb Hegedüs Ervin:

> Another question: here is an another part ot my code:
>
> static PyObject*
> mycrypt_decrypt(PyObject *self, PyObject *args)
> {
>      if (!PyArg_ParseTuple(args, "ss",&data,&path)) {
>          return NULL;
>      }
>
> ...
>
> }
>
> When I call this function from Python without argument or more
> than it expects, I get an exception, eg.:
> TypeError: function takes exactly 2 arguments (0 given)
>
> But, when I don't read input arguments (there isn't
> PyArg_ParseTuple), there isn't exception.
>
> How Python handle the number of arguments?

 From what you tell it: with PyArg_ParseTuple(). (see 
http://docs.python.org/c-api/arg.html for this).

You give a format string (in your case: "ss", again: better use "s#s#" 
if possible) which is parsed in order to get the (needed number of) 
parameters.

If you call with () or only one arg, args points to an empty tuple, but 
the parser wants two arguments -> bang.

If you call with more than two args, the function notices it too: the 
arguments would just be dropped, which is probably not what is wanted.

If you call with two args, but of wrong type, they don't match to "s" 
(=string) -> bang again.

Only with calling with the correct number AND type of args, the function 
says "ok".

Why is "s#" better than "s"? Simple: the former gives the string length 
as well. "s" means a 0-terminated string, which might not be what you 
want, especially with binary data (what you have, I suppose).

If you give e.g. "ab\0cd" where "s" is used, you get an exception as 
well, as this string cannot be parsed cmpletely. So better use "s#" and 
get the length as well.


> I just ask this,
> because I don't set errstring with PyErr_SetString, but I get
> TypeError - how does Python knows, this error raised?

There is magic inside... :-)


Thomas



More information about the Python-list mailing list