On 6 August 2011 16:09, Matthew Brush mbrush@codebrainz.ca wrote:
On 08/05/11 23:01, Lex Trotman wrote:
On 6 August 2011 15:05, Matthew Brushmbrush@codebrainz.ca wrote:
On 08/05/11 21:32, Lex Trotman wrote:
BTW what are the restrictions on what Python can be used when Geany calls a Python callback, I guess everything has to be a function that runs to completion. Can it be a closure, can it use yield, can it use threads, can it do async I/O so as not to block Geany?
More or less anything Python itself supports, including Global Interpreter Lock [1]. GeanyPy pretty much only the Python X.X interpreter, and pre-loades the Geany Python package (written in C) which glues Geany's C API to Python's C API.
Ok, so my Python plugin can start an I/O bound thread in its plugin_init routine and have that thread call a Geany function like updating the status bar when the I/O completes?
Be very careful, both answers are wrong ;-)
In as much as Python and PyGTK/PyGObject can do this (ie. using GIO and friends, like Geany itself, or the threading module from Python). Geany's GMainLoop is the main loop for Python as well as well, and there's no extra restrictions, AFAIK, on what can be done, beyond those of Python/PyGTK.
Ok if you do the I/O with GIO not Python. That means structuring everything in callbacks and somehow keeping status between calls.
Can I do (assume appropriate imports and other setup):
class MyPlugin: def __init__(self): geany.object.connect('menu_item_activate', self.menu_item_callback) def menu_item_callback(self): threading.Thread(target=self.do_slow_stuff, args=(self,)) def do_slow_stuff(self): with open("slow_file",r) as f: do_something_with_f
AFAICT basically there is no way of getting back into the Python interpretor to check if any I/O waits in do_something have completed and to continue. As soon as do_something releases the GIL and blocks menu_item_callback will complete and return control to Geany and never return to Python until the next callback.
Same problem even with multiprocessing, no way to find out if the subprocesses have completed (needs a Python thread so, see above).
So long as I don't call back into Geany I can do this using Posix threads in C.
Cheers Lex