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?
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:
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.
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.
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.