Py_INCREF() incomprehension

Hegedüs Ervin airween at gmail.com
Sun May 1 16:00:36 EDT 2011


hello,

On Wed, Apr 27, 2011 at 11:58:18AM +0200, Thomas Rachel wrote:
> Am 26.04.2011 20:44, schrieb Hegedüs Ervin:
> 
> >and (maybe) final question: :)
> >
> >I defined many exceptions:
> >
> >static PyObject *cibcrypt_error_nokey;
> >static PyObject *cibcrypt_error_nofile;
> >static PyObject *cibcrypt_error_badpad;
> >...
> >
> >void handle_err(int errcode) {
> >     switch(errcode) {
> >         case -1:    PyErr_SetString(cibcrypt_error_nokey, "Can't find key.");
> >                     break;
> >...
> >}
> >...
> >     cibcrypt_error_nokey = PyErr_NewException("cibcrypt.error_nokey", NULL, NULL);
> >...
> >     PyModule_AddObject(o, "error", cibcrypt_error_nokey);
> 
> Then I would not use the name "error" here, but maybe "error_nokey"
> or even better "NoKeyException".
> 
> Oops: there is an inconsistency in the docu: on the one hand, it says
> 
>   There are exactly two important exceptions to this rule:
>   PyTuple_SetItem() and PyList_SetItem().
> 
> stating these are the only ones who take over ownership.
> 
> But PyModule_AddObject() claims to "steal" a reference as well...
> 
> 
> >I am right, here also no need any Py_INCREF()/Py_DECREF() action,
> >based on this doc:
> >http://docs.python.org/c-api/arg.html
> 
> I'm not sure: On one hand, you pass ownership of the error objects
> to the module. There - one could think - they are until the module
> is unloaded.
> 
> But what if someone does "del module.NoKeyException"? In this case,
> the object could have been destroyed, and you are using it -> BANG.
> 
> On the other hand, if you keep one instance internally, it is not
> possible any longer to unload the module without a memory leak...
> 
> 
> As already stated - you might want to have a look at some other C
> modules and mimic their behaviour... (and hope they are doing it
> right...)

so, I've checked it - there wasn't any Py_INCREF(), I just calmed
down.

But. :)

My module contains just 4 functions (in C), which translate 3rd
party lib to Python. The name would be _mycrypt.so example.

I wrapped it a pure Python module, its name is mycrypt.py.

Then, I've import pure Python module in a main program, like
this:

=%=
mycrypt.py:

import _mycrypt
...
=%=

=%=
userapp.py:

import mycrypt
...
=%=

I've missed out something, and then I didn't get exception,
instead there were a segfault. :(


I've put it a Py_INCREF() after every PyModule_AddObject(), eg.:

    PyModule_AddObject(o, "error", cibcrypt_error_nokey);
    Py_INCREF(cibcrypt_error_nokey);

and now if there is some expected exception, I get it.


Any explanation?


Thanks:


a.


ps: this is just for my passion, but I would like to understand
it very-very much :)




More information about the Python-list mailing list