[C++-sig] Object destructor not always called in embedded interpreter

Tanguy Fautré tfautre at telenet.be
Tue Oct 14 15:48:55 CEST 2008


> Hi Tanguy,
> 
> I'm no python expert, but I think it works as follows:
> When you import __main__, it is added to the internal list of modules
> in python. It's __dict__ is therefore also referenced. So even though
> you no longer reference it, the __dict__ will still be referenced by
> the interpreter itself, and it's refcount doesn't reach 0 until you
> finalize the interpreter...
> 
> So, what can you do? I also wanted to be able to clear the interpreter
> and re-run scripts in clean namespaces, without re-initializing the
> interpreter.
> 
> This can be achieved by calling clear() on the namespace (it's a dictionary).
> 
> However, that also clears the members "__builtins__", "__doc__" and
> "__name__", which are needed (at least __builtins__) if you want to
> execute code again. I solved this too, simply by re-initializing those
> variables again after clearing the dictionary.
> 
> I also discovered that a similar initialization enables you to create
> other modules than the "__main__" module (using PyImport_AddModule
> instead of import) and execute scripts in those too, which can be
> useful. I don't know whether this is the "correct" way of doing things
> though...
> 
> See below for an example.
> 
> Regards,
> Thomas
> 
> [...]


Hi Thomas,

Thanks for the advise, it seems to work. It's also good to know how to create other modules.

Although, I'm still surprised by this. Because I'm copying the __dict__ of __main__ instead of referencing it (I've even tried directly calling dict.copy()). So I'm surprised by the fact that the interpreter would hold a reference to my copy.

I've also tested the following code, and it seems to do the same as yours (as far as I can tell) and can be called several time. Notice how the clear() at the end seems to only affect the copy and not the __main__.__dict__.


object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
dict new_namespace(main_namespace);

object ignored = exec_file("main.py", new_namespace, new_namespace);

new_namespace.clear();


Thanks for your help!
Cheers,

Tanguy


PS: I apologize if there is any problem with my posts (e.g. formatting), I'm forced to use my ISP webmail for the moment.




More information about the Cplusplus-sig mailing list