classification
Title: IDLE / PyOS_InputHook
Type: behavior Stage: test needed
Components: IDLE Versions: Python 2.6
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: kbk Nosy List: amaury.forgeotdarc, gpolo, kbk, mdehoon
Priority: normal Keywords:

Created on 2003-08-31 08:45 by mdehoon, last changed 2009-06-08 15:19 by gpolo. This issue is now closed.

Messages (7)
msg18025 - (view) Author: Michiel de Hoon (mdehoon) * Date: 2003-08-31 08:45
[This bug report is a follow-up of a discussion with
Matthew Cowler of help@python]

I noticed an inconsistency with the usage of the
PyOS_InputHook variable between Python 2.3's IDLE and
Python run from the (DOS or linux) command prompt. This
problem does not occur with earlier versions of Python.
First I will describe the problem, then why it is
important to me.

The PyOS_InputHook variable can be used to install a
callback function that gets called periodically (via
readline's rl_event_hook) when Python is waiting for
terminal input. When Python is run as a terminal
application (from the DOS or linux command prompt),
PyOS_InputHook is NULL initially. Python C extension
modules can set PyOS_InputHook to a function which is
to be called periodically. This works with Python 2.3
and older versions.

In Python 2.2, IDLE makes use of the PyOS_InputHook
variable, presumably to get messages delivered to the
Tkinter window. Python C extension modules that are
loaded from IDLE find that PyOS_InputHook is not NULL,
and therefore cannot specify a different callback
function via PyOS_InputHook, as that would freeze the
Tkinter window.

Now on Python 2.2, in practice that is not a problem.
IDLE in Python 2.2 runs in a single thread. This thread
contains a message loop (probably hidden in the Tk
library) that takes care of the messages destined for
the Tk window. If we open an additional (non-Tk) window
from our C extension module, then its messages also get
processed by Tk's message loop as it is running in the
same thread. So we don't need an additional message
loop for our non-Tk window, and we don't need to change
PyOS_InputHook.

In Python 2.3, IDLE works differently, as it talks to
its interactive interpreter on the TCP/IP loopback
interface and does not make use of PyOS_InputHook. If I
import my C extension module from IDLE, it shows that
PyOS_InputHook is NULL. In addition, multithreading is
now used, with three threads on Windows and two on
Linux and Mac OS X. (I am not sure where the additional
thread on Windows is coming from). In particular, the C
extension module and Tk's message loop are running in
separate threads. So if I open a non-Tk window from my
C extension module, its messages are not handled by
Tk's message loop.

The solution would be to have a message loop in my C
extension module also, which is how the C extension
module works when Python is run as a terminal
application. As PyOS_InputHook is NULL (both with and
without IDLE) when I import my extension module, I can
point it to a message loop in the extension module
without causing havoc. However, whereas Python without
IDLE calls the function specified by PyOS_InputHook
correctly, Python with IDLE fails to call
PyOS_InputHook. Hence, with IDLE I am stuck in a thread
without a message loop, and no way to provide a message
loop of my own.

If I run IDLE with the "-n" command-line argument to
disable running Python code in a sub-process, there is
only one thread, and I can use that thread's message
loop without problems.

Would it be possible in Python 2.3 to have
PyOS_InputHook called also if IDLE / Tkinter is
running? I would think that that no longer interferes
with the correct operation of Tkinter / IDLE, as after
importing IDLE, PyOS_InputHook is NULL anyway.


This problem is important to me because of the
Windows-port of Pygist (gist scientific plotting
package for Python), which I codeveloped several months
ago. The core graphics routines of Pygist are written
in C for performance reasons. Pygist does not work with
Python 2.3 with IDLE, while it does work with Python
2.2 with IDLE. There are no problems with Python 2.3
run from the DOS command prompt, nor with PythonWin or
PyShell.

The problem with Python 2.3 with IDLE is that the
graphics window no longer receives its messages. In
usual Windows programs, there is one message loop,
which looks like

while (GetMessage(&msg, NULL, 0, 0))
{ TranslateMessage(&msg);
  DispatchMessage(&msg);
}

In Python 2.2 with IDLE, we use Tk's message loop to
get messages delivered to the Pygist graphics window.
When running Python 2.2 and Python 2.3 as a terminal
application, we start our own message loop in the C
extension module and point to it using PyOS_InputHook.
With Python 2.3 with IDLE, Tk's message loop is in a
separate thread, so we can't use it, while at the same
time PyOS_InputHook is being ignored. Hence Pygist's
graphics window freezes.

Note that Pygist is different from many other plotting
packages for Python, as it returns to the Python prompt
after opening a graphics Window (allowing you to modify
the window interactively). So the trick is to let both
the Python interpreter and the graphics window receive
their messages.


With regards,

Michiel de Hoon, University of Tokyo.
msg18026 - (view) Author: Michiel de Hoon (mdehoon) * Date: 2004-02-16 01:36
Logged In: YES 
user_id=488897

I had another look at this and it seems that the problem is
in the Modules/_tkinter.c. If I understand correctly,
tkinter does not use the code in Modules/readline.c, which
contains the call to PyOS_InputHook, and hence
PyOS_InputHook is not being called. Surprisingly, the
tkinter code does set the PyOS_InputHook variable to the
EventHook routine, but this seems to be in vain as
PyOS_InputHook is not being called anyway. I suggest to
resubmit this bug report to the Tkinter category.
msg18027 - (view) Author: Kurt B. Kaiser (kbk) * (Python committer) Date: 2005-02-04 04:16
Logged In: YES 
user_id=149084

Michiel de Hoon's comments re this Bug on python-dev:
http://mail.python.org/pipermail/python-dev/2005-January/050895.html

In IDLE there are two processes.  One runs the GUI and
communicates with the second via the socket interface.  The
subprocess has two threads: MainThread, which runs the user
code, and SocketThread, which monitors the socket interface.
SocketThread communicates with MainThread via two Queue
objects and several global flags which are involved in shutting
down the subprocess.

So it's the subprocess (run.py) MainThread that should call
PyOS_InputHook.

See Patch  989712.  Noam Raphael is trying to hook in
tkinter's mainloop.  This should all be solved together.

Putting it back in IDLE for now so I can keep an eye on it.
msg86321 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2009-04-22 19:50
This issue has remained as is for too long, I assume the OP has found
another solution or: dropped tkinter from his usage, fixed his problem
according to issue989712, something else.

Some time ago I read about your proposal to change PyOS_InputHook by
PyOS_AddInputHook and PyOS_RemoveInputHook, and it was strongly
discouraged. I'm not seeing this moving forward, so I will be closing
this very soon if no one else around does it before me.
msg89021 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2009-06-06 22:35
Closing as promised.
msg89080 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2009-06-08 15:17
Guilherme, you did not actually close the issue
msg89081 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2009-06-08 15:18
Uh oh, awesome. Thanks ;)
History
Date User Action Args
2009-06-08 15:19:08gpolosetresolution: rejected
2009-06-08 15:18:31gpolosetstatus: open -> closed

messages: + msg89081
2009-06-08 15:17:23amaury.forgeotdarcsetnosy: + amaury.forgeotdarc
messages: + msg89080
2009-06-06 22:35:19gpolosetmessages: + msg89021
2009-04-22 19:50:06gpolosetmessages: + msg86321
2009-04-22 17:17:44ajaksu2setnosy: + gpolo
2009-02-14 12:47:29ajaksu2linkissue989712 dependencies
2009-02-14 12:47:22ajaksu2setdependencies: - IDLE / PyOS_InputHook
2009-02-14 12:47:22ajaksu2unlinkissue798058 dependencies
2009-02-13 03:48:05ajaksu2setdependencies: + IDLE / PyOS_InputHook
type: behavior
stage: test needed
versions: + Python 2.6, - Python 2.5
2009-02-13 03:48:05ajaksu2linkissue798058 dependencies
2003-08-31 08:45:24mdehooncreate