<div>Hello Python Experts,<br></div><div><div class="gmail_quote"><div lang="EN-US" link="#0563C1" vlink="#954F72" style="word-wrap:break-word"><div class="m_6681928744166535170WordSection1"><p class="MsoNormal"><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I had a question on embedding Python interpreter in my application.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I have an application where:<u></u><u></u></p>
<ul style="margin-top:0in" type="disc">
<li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">I need to embed a Python Interpreter<u></u><u></u></li><li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">Run different blocks of Python code on this embedded interpreter<u></u><u></u></li><li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">However, each block should not see any of the changes made by the previous block of Python code (except for instances of a particular class which, if created in the first block of
Python code, should be visible from the 2<sup>nd</sup> and subsequent block of Python code)<u></u><u></u></li><ul style="margin-top:0in" type="circle">
<li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">In other words, for the most part, I would need kind of a fresh Python interpreter for running each block of Python code, with the exception that certain class instances will be shared
across all blocks<u></u><u></u></li></ul>
</ul>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I am using BOOST PYTHON at the moment, since we didn’t want to deal with the lower level details like reference count in Python C API.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Wanted some advice on what is the best (production suitable quality-wise) way to get multiple Python interpreters selectively preserve some state and forget all other states?<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I did some research and came up with the following 4 approaches, wanted to hear some opinion in this forum for/against these approaches:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<ol style="margin-top:0in" start="1" type="1">
<li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">Invoke Py_Initialize() / Py_Finalize() multiple times<u></u><u></u></li><ol style="margin-top:0in" start="1" type="a">
<li class="MsoNormal" style="margin-bottom:8.0pt;line-height:106%">
BOOST Python documentation kind of documents that Py_Finalize() should not be called:
<a href="https://www.boost.org/doc/libs/1_62_0/libs/python/doc/html/tutorial/tutorial/embedding.html" target="_blank">
<span style="color:black">https://www.boost.org/doc/libs/1_62_0/libs/python/doc/html/tutorial/tutorial/embedding.html</span></a><u></u><u></u></li><li class="MsoNormal" style="margin-bottom:8.0pt;line-height:106%">
So, that flow isn’t quite officially supported it looks like. <u></u><u></u></li></ol>
<li class="MsoNormal" style="margin-bottom:8.0pt;line-height:106%">
Invoke multiple Python sub-interpreters<u></u><u></u></li><ol style="margin-top:0in" start="1" type="a">
<li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">BOOST Python documentation didn’t seem to talk about sub-interpreters at all – which could mean that it is not supported.
<u></u><u></u></li><li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">I tried it any way and keep getting this error message, which probably is indicating that BOOST Python is trying to re-register the to-Python convertors the 2<sup>nd</sup> and subsequent
time – once again, it didn’t look like a very/officially supported flow.<u></u><u></u></li></ol>
</ol>
<p class="m_6681928744166535170MsoListParagraph" style="margin-left:1.5in">
<u></u><b><span><span style="font:7.0pt "Times New Roman"">
</span>i.<span style="font:7.0pt "Times New Roman""> </span></span></b><u></u><b>frozen_importlib:219: RuntimeWarning: to-Python converter for MyClass already registered; second conversion method ignored.<u></u><u></u></b></p>
<ol style="margin-top:0in" start="3" type="1">
<li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">Create the initial Python interpreter in the main process and for executing each Python block fork off a new process and execute each Python block in a child process<u></u><u></u></li><ol style="margin-top:0in" start="1" type="a">
<li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">This would work fine as long as the Python blocks are not writing something back to the data base<u></u><u></u></li><li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">When Python blocks write something back to the data base, this has to be propagated to the main / parent process<u></u><u></u></li></ol>
</ol>
<p class="m_6681928744166535170MsoListParagraph" style="margin-left:1.5in">
<u></u><span><span style="font:7.0pt "Times New Roman"">
</span>i.<span style="font:7.0pt "Times New Roman""> </span></span><u></u>In multi-threaded environment, this has to be propagated to all active child processes, since eventual consistency isn’t quite allowable in my application domain.<u></u><u></u></p>
<ol style="margin-top:0in" start="3" type="1">
<ol style="margin-top:0in" start="3" type="a">
<li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">Sharing of instances across process can be done using shared memory kind of IPC and serialization using pickle / dill<u></u><u></u></li></ol>
<li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">Manually Manage Interpreters<u></u><u></u></li><ol style="margin-top:0in" start="1" type="a">
<li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">Create just 1 interpreter
<u></u><u></u></li><li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">Save its state in some global hash like<u></u><u></u></li></ol>
</ol>
<p class="m_6681928744166535170MsoListParagraph" style="margin-left:1.5in">
<u></u><span><span style="font:7.0pt "Times New Roman"">
</span>i.<span style="font:7.0pt "Times New Roman""> </span></span><u></u>Initial_state = dirs()<u></u><u></u></p>
<ol style="margin-top:0in" start="4" type="1">
<ol style="margin-top:0in" start="3" type="a">
<li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">Use some kind of a lock to allow only 1 block to run at a time (this is acceptable for my application domain)<u></u><u></u></li><li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">After a block of Python code runs in the interpreter, and before running the next block of Python code, clean up the interpreter using the following approach:<u></u><u></u></li></ol>
</ol>
<p class="m_6681928744166535170MsoListParagraph" style="margin-left:1.5in">
<u></u><span><span style="font:7.0pt "Times New Roman"">
</span>i.<span style="font:7.0pt "Times New Roman""> </span></span><u></u>Walk over globals() and pop everything off / remove from globals() all symbols that is not present (previously saved) in Initial_state – that way any additions by the previous
block will not be reachable any more and thus, should be garbage collected.<u></u><u></u></p>
<ol style="margin-top:0in" start="4" type="1">
<ol style="margin-top:0in" start="4" type="a">
<ol style="margin-top:0in" start="1" type="i">
<ol style="margin-top:0in" start="1" type="1">
<li class="m_6681928744166535170MsoListParagraph" style="margin-left:0in">For sharing state across blocks, we may choose to not pop off symbols, based on some condition like instances of a pre-defined class.<u></u><u></u></li></ol>
</ol>
</ol>
</ol>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Any comments / pros / cons on these approaches that I missed?<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Is there a 5<sup>th</sup> approach that I missed thinking of? Any pointers is appreciated.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Thanks,<u></u><u></u></p>
<p class="MsoNormal">AD<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
</div></div>