PyArg_ParseTupleAndKeywords

Mr.M mrm at unknown.nospam
Sat Jan 23 10:34:15 CET 2010


Carl Banks ha scritto:
>> (some declarations omitted here)
> 
> You probably shouldn't have, that could be where the error is....  I'd
> include the whole function up to the call that raises the exception.

Thank you so much Carl for your help, i'll provide more info so that you
can try to fix my errors!
Thank you again!

First of all i'll try to explain what i've discovered over a night i
spent awake trying to find where the bug is.

My init behaves differently in this situations:

[code]
# this works
dummy = mymodule.myclass()

# this works
dummy = mymodule.myclass("string for service")

# this also works
dummy = mymodule.myclass("string for service", "string for event_type")
# and it works if i provide arguments in the right sequence, of course

# this won't work
dummy = mymodule.myclass("string for service", "string for event_type",
free_text = "string for free_text")

# but this works
dummy = mymodule.myclass(service = "string for service")

# the worst thing: this doesn't work but it did and i can't
# understand what is changed

dummy = mymodule.myclass(free_text = "text for free_text")

ok, every time the code fails i get this exception:

TypeError: expected string or Unicode object, tuple found

so, i think for some reason PyArg_ParseTupleAndKeywords receives "args"
as a touple instead of something else.

This is everything i managed to discover.

This is the code:

[code]
         /* DEBUG INFO */
         printf("event INIT\n");
         if (args)
         {
                 int i;
                 printf("args        = \"%s\"\n", PyString_AsString(args));
                 printf("type        = %s\n",
PyString_AsString(PyObject_Repr(PyObject_Type(args))));
                 printf("tuple size  = %d\n", PyTuple_Size(args));
                 for (i = 0; i < PyTuple_Size(args); i++)
                 {
                         printf("%d) %s\n", i,
PyString_AsString(PyTuple_GetItem(args, i)));
                 }
         }
         else
         {
                 printf("args = NULL\n");
         }
         printf("dict:\n");
         if (keywords)
         {
                 printf("     = %s\n",
PyString_AsString(PyObject_Repr(keywords)));
                 printf("type = %s\n",
PyString_AsString(PyObject_Repr(PyObject_Type(keywords))));
         }
         else
         {
                 printf("keywords = NULL\n");
         }

     char* service          = NULL;
     char* event_type       = NULL;
     char* free_text        = NULL;
     char* group_uid        = NULL;
     char* remote_name      = NULL;
     char* remote_abook_uid = NULL;

     time_t start_time   = -1L;
     time_t end_time     = -1L;
     time_t storage_time = -1L;

     int flags = 0;

     int bytes_sent     = -1;
     int bytes_received = -1;

     PyObject* temp;

     static char* keywordlist[] = {"service",
                                   "event_type",
                                   "free_text",
                                   "group_uid",
                                   "remote_name",
                                   "remote_abook_uid",
                                   "start_time",
                                   "end_time",
                                   "storage_time",
                                   "flags",
                                   "bytes_sent",
                                   "bytes_received",
                                   NULL};

     if (!PyArg_ParseTupleAndKeywords(args, keywords, "|ssssssiiiiii",
keywordlist,
                                      &service,
                                      &event_type,
                                      &free_text,
                                      &group_uid,
                                      &remote_name,
                                      &remote_abook_uid,
                                      &start_time,
                                      &end_time,
                                      &storage_time,
                                      &flags,
                                      &bytes_sent,
                                      &bytes_received))
     {
         return -1;
     }

     printf("PyArg_ParseTupleAndKeywords worked fine\n");

[/code]

(sorry if my code is a little messy and my english rather bad!)

> Are you sure that PyArg_ParseTupleAndKeywords is what's raising the
> error?

Yes, i think so. I have a lot of printf in my code!

> Are you subclassing this type in Python, and passing one of the string
> parameters a tuple by mistake?  For instance, did you do something
> like this:
> 
> class myclass(_mycmodule._myctype):
>     def __init__(self,*args,**kwargs):
>         log_something_here()
>         super(myclass,self).__init__(args,**kwargs)
> 
> Note the missing * on args.

no, i'm not subclassing.
I have to admit that i had some testcase and a few weeks ago they worked
like a charm... i can't understand what i changed, of course.

> 
> 
>> I found that if i write this everything works fine:
>>
>> [code]
>> import mymodule
>> a = mymodule.myclass(service = "blabla", event_type = "event", free_text
>>   = "free", group_uid = "group", remote_name = "remote name",
>> remote_abook_uid = "abook", start_time = 1, end_time = 61, storage_time
>> = 61, flags = 2)
>> [/code]
>>
>> in other words, the code only works if *EVERY* argument is specified in
>> exactly the same position it appears in keyword-null-terminated array.
> 
> That it would have to be in a certain order is strange.  Are you sure
> it's just not merely that they all have to be present?
> 

No, i tryied to remove the "|" and Python complains that 12 argument 
must be present. So they are, in a sense, optional, but (and this is 
strange), they must be present in the right order even i provide them 
with keyword arguments.

> Tricky, but I think it'd help if you provided more information.  My
> gut feeling is that there exception is being raised somewhere other
> than you think it is (i.e., not by PyArg_ParseTuple), so I'd recommend
> adding some debugging statements to track down the exact point wher
> the error occurs.

Ok, thank you!
The code i posted is exactly the same i run (and it fails).
I've no problem sending you the whole module or adding any other debug 
info you think could be helpfull to find the source of the bug.

Ciao,

Luca.



More information about the Python-list mailing list