PyArg_ParseTupleAndKeywords

2010-01-22 Thread Mr.M

Hi,

i can't understand what i'm doing wrong. I have a c/api that implements 
a new class.

In (initproc) function i have somethink like this:

[code]

(some declarations omitted here)
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, "|ssii", 
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;

[/code]

Ok, what i want is something like this:

[code]
import mymodule
a = mymodule.myclass() # ok, this works
a = mymodule.myclass(flags = 1) # bad, this won't work
> TypeError: expected string or Unicode object, tuple found
[/code]

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.


Could you please help me?

Thank you,

Luca.
--
http://mail.python.org/mailman/listinfo/python-list


Re: PyArg_ParseTupleAndKeywords

2010-01-23 Thread Mr.M

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, "|ssii",
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_t

Re: PyArg_ParseTupleAndKeywords

2010-01-23 Thread Mr.M

MRAB ha scritto:


Did you specify that the method accepts keywords arguments with
METH_KEYWORDS? The function would take parameters for the instance
(self), the positional arguments (args) and the keyword arguments
(kwargs).

http://docs.python.org/c-api/structures.html

If you don't use METH_KEYWORDS then it'll think that all the arguments
are positional, which is what seems to be happening:



Thank you MRAB for your reply.
No, i didn't specify METH_KEYWORDS flag, but i think init method (the 
one that you put in tp_init slot, it is "initproc" type) doesn't have to 
appear in the PyMethodDef structure.


Maybe i'm wrong?

Luca.
--
http://mail.python.org/mailman/listinfo/python-list


Re: PyArg_ParseTupleAndKeywords

2010-01-23 Thread Mr.M

MRAB ha scritto:

I think you're right.



I have rewritten my code, a piece at a time, and (and this is very 
annoying) now it works fine.


I really can't understand what went wrong with my old code.

Luca.
--
http://mail.python.org/mailman/listinfo/python-list


get PyObject* knowing its string name

2010-01-29 Thread Mr.M
I think this sounds like a stupid question, but I searched the C/Api doc 
and google but I wasn't able to find any hint:


how can I retrive PyObject pointer if I only know it's name?

What I'd like to do is something like this:

[code]
PyObject* obj = PyFindWhatImLookingFor("w.z.y.x");
[/code]

Of course if I know that w is a module, z is a class and so on I can 
search w dictionary than z members than...


But I wonder if there is a way to retrive without knowing what w.z.y.x 
means.


Thank you,

Luca.
--
http://mail.python.org/mailman/listinfo/python-list


C API: module cleanup function

2010-01-29 Thread Mr.M

Hi,

I can't figure out if there is a way to run a specialized cleanup 
function when a module needs to be "unloaded" (i.e. just before a 
reload() or when i quit the interpreter).


I'm thinking of something like tp_dealloc.

If I call Py_InitModule3 and look at module->ob_type->tp_dealloc, I find 
that Python provides a default tp_dealloc for me.


Now, suppose my module needs to allocate some resources at startup, I'm 
not sure, but I think I'd have to do it in my PyMODINIT_FUNC, right?


But, if I reload() my module or if I quit the Python interpreter, I'd 
like to free those resources (before allocate them again, in case of a 
reload).


Is there a way to make this work?

Thank you, Luca.
--
http://mail.python.org/mailman/listinfo/python-list


Re: C API: module cleanup function

2010-01-29 Thread Mr.M

Gabriel Genellina ha scritto:
I think what you want to do isn't possible with Python 2, and it's one 
of the reasons the module handling was redesigned in Python 3.x; see PEP 
3121.


Thank you Gabriel for your help. Unlucky I can't use Python 3.x in my 
project, sob!


Luca.
--
http://mail.python.org/mailman/listinfo/python-list


Re: C API: module cleanup function

2010-01-30 Thread Mr.M

Stefan Behnel ha scritto:

Gabriel already pointed you to the module cleanup support in Py3, which can
be used to provide reload capabilities to your module.

In Py2, there are at least some ways to free resources when terminating the
interpreter. See the "atexit" module and the Py_AtExit() function:

http://docs.python.org/library/atexit.html
http://docs.python.org/c-api/sys.html

Note that both have their specific limitations, though, as you can see from
the docs.

Also note that it might help you to take a look at Cython, a Python-to-C
compiler for writing fast C extensions. It has an option for generating
module-level cleanup code automatically, and generally simplifies writing
binary extension modules quite a bit.

Stefan


Thank you very much Stefan for your reply, I'll study the sources you 
have pointed me to.


Could I allocate my resources in a "static" object (without publishing 
the type of that object so that I can't instantiate another one) linked 
to my module?
This way, when I stop the interpreter, the object will be destroyed 
calling its destructor.


There's something I'm missing?

Thank you, Luca.
--
http://mail.python.org/mailman/listinfo/python-list


Re: C API: module cleanup function

2010-01-30 Thread Mr.M

Stefan Behnel ha scritto:

Note that there is the type() builtin function which returns the type given
an instance. So you can't hide the type.


Argh! Yes, you are right.

So I'd better have a look to Cython, right?

L-
--
http://mail.python.org/mailman/listinfo/python-list