When to use cleanup() in Jython

376 Views Asked by At

Is it necessary to call cleanup() before close() in a PythonInterpreter in Jython every time?

I've been reading the docs, but I don't find much information about this function. The javadocs don't say anything at all. The closest information I've found is here, in readthedocs, where they explain that a cleanup is necessary in some cases programming with threads, and I'm not even sure they refer to this particular function.

I wonder when I need to call cleanup()... and if the answer is always, then why would they make cleanup() and close() separate functions?

1

There are 1 best solutions below

4
Miguel On BEST ANSWER

Okay, I've been reading the Jython source code and doing some tests. Here is what I found:

What cleanup() does: It takes charge of the unhandeled resources, like running threads and files.

What cleanup() doesn't: Reset the state of the interpreter in any form; imported modules and defined variables are kept.

The following examples show this behavior:

Example 1

Let's import a module, define a variable and open a file.

PythonInterpreter py = new PythonInterpreter();

String code1 = "import sys;"
        + "a=45;"
        + "f = open('test.txt')";
String code2 = "print(sys.version_info);"
        + "print(a);"
        + "print(f.closed)";

// first execution
py.exec(code1);
py.exec(code2);

// second execution
py.cleanup();
py.exec(code2);

py.close()

It outputs

sys.version_info(major=2, minor=7, micro=2, releaselevel='final', serial=0)
45
False
------
sys.version_info(major=2, minor=7, micro=2, releaselevel='final', serial=0)
45
True

The module sys and the variables a and f still exist with the same values after the cleanup, but the open file is closed.

Example 2

For this, func is a slow function that takes aprox 2 seconds to complete (more than a normal cleanup()).

PythonInterpreter py = new PythonInterpreter();

String code3 = "from threading import Thread\n"
        + "def func():\n"
        + "  print 'th start'\n"
        + "  for i in range(0,20000000):\n"
        + "    x=i\n"
        + "  print 'th done'\n"
        + "th = Thread(target=func)\n"
        + "th.start()";
String code4 = "print th.isAlive()\n"
        + "th.join()";

// first execution
py.exec(code3);
py.exec(code4);
System.out.println("------");   

// second execution
py.exec(code3);
py.cleanup();
py.exec(code4);

py.close();

That outputs:

th start
True
th done
------
th start
th done
False

In the first execution, the main thread has plenty of time to check if th is alive and print it. In the second one, it always waits for th to finish, meaning that the cleanup() joins the thread somewhere.

Conclusion

As @mzjn pointed out, the close() function calls cleanup() and that makes sense, so you never need to call cleanup() before close(). The only case where you could need to call it manually would be if you wanted to continue using the PythonInterpreter but needed to close all open files and join all threads.