I have an application that implements a python interpreter, with custom python modules exporting classes. An example C ++ class might look like this:
class MyClass {
MyClass() { cout << "created" << endl; }
~MyClass() { cout << "destroyed" << endl; }
};
The code for executing python scripts looks like this:
namespace bp = boost::python;
bp::dict dict;
try {
dict = bp::dict(bp::import("__main__").attr("__dict__"));
bp::exec_file(filename, dict, dict);
} catch (bp::error_already_set &) {
PyErr_Print();
PyErr_Clear();
}
The problem is that C ++ objects created from python code are not destroyed immediately after the script completes with an exception. For example, a simple script is executed twice:
import MyModule
myobj = MyModule.MyClass()
assert False
I get ( A ):
created
created
destroyed
destroyed
I want ( B ):
created
destroyed
created
destroyed
Now, the fun part. If we uncomment // dict.clear()
, the behavior starts to change depending on the structure of the script. For the above python snippet, I get output B (as expected), but I still get A for the script as:
import MyModule
def main():
myobj = MyModule.MyClass()
assert False
if __name__ == "__main__":
main()
++, python?