RobThorpe · 2022-04-01 04:02
I am using the python shell (provided by M-x run-python) on Emacs 27.2 on MS Windows.
I have a program that someone else has written. If I run in from the python shell then it works fine. But afterwards that python shell is useless, it won't respond to inputs. (Simple scripts don't suffer from this problem.)
Why am I asking about this here? It doesn't do this outside of Emacs. If start a python shell from a Windows cmd window then the python shell continues working after the program has ended.
Has anyone seen anything like this before?
mattplm · 2022-04-01 06:00
Can you maybe send a minimal code sample to reproducs this and send it here so we can help you?
RobThorpe · 2022-04-01 16:18
It seems to be related to Tk. This is the smallest code sample I can get:
import tkinter as tk
from tkinter import ttk
window = tk.Tk()
If you run that it will bring up an empty Tk window. Then click on the "X" to close it. If you're using python from a normal cmd shell then you will get back to the python prompt. But if you're using it from within M-x run-python then you get the prompt displayed ">>>" but nothing more after that.
RobThorpe · 2022-04-01 16:27
I am not the first to discover this.
It looks like it was first discovered [20 years ago](https://python-list.python.narkive.com/miSHgA8U/problems-with-tkinter-based-scripts-under-emacs#post2)! Then [again](https://bytes.com/topic/python/answers/19483-emacs-py-mode-tkinter-problem) in 2005.
I can't find any sign of an answer though.
mattplm · 2022-04-02 12:40
Do you have the same issue with windows created with the sdl for example? Unfortunatly seeing your other comment, doesn't seem like something we can figure out easilly :(
NoisyFrequency · 2022-04-04 12:01
`M-x run-python` starts a python process but doesn't run the code afaik. When I run the code with `python-shell-send-buffer` or `python-shell-send-region`, I don't have the issue you're mentioning.
Also, I use `ipython` instead of `python` most of the time.
Another solution I just tried and which seems to work is to use python with `vterm` in Emacs, so maybe using [isend-mode](https://github.com/ffevotte/isend-mode.el) to send your Python process to an `ansi-term` or to `vterm` will fix the issue?
RobThorpe · 2022-04-04 12:44
> M-x run-python starts a python process but doesn't run the code afaik. When I run the code with python-shell-send-buffer or python-shell-send-region, I don't have the issue you're mentioning.
That's interesting. I tried using those two commands just now and they didn't work for me. Both of them showed the problem.
I know that I can use it through a different shell interface such as one of the term interfaces or just M-x shell. That may be the best work-around.
I don't understand ipython, but I might have to try it.
NoisyFrequency · 2022-04-04 12:54
I hope you'll find a solution, especially if it's a long standing issue!
Bombastry · 2022-04-28 20:57
I just stumbled upon this issue myself (via trying to find a minimal example of why Matplotlib was causing Emacs to hang). It looks like [this issue made the "help-gnu-emacs" mailing list in 2006](https://lists.gnu.org/archive/html/help-gnu-emacs/2006-11/msg00067.html) and [again in 2009](https://lists.gnu.org/archive/html/help-gnu-emacs/2009-02/msg00587.html), but unfortunately I couldn't much of a resolution either.
I did see [this StackOverflow answer that suggests a change for calling IPython in a way that may get this to work](https://stackoverflow.com/a/18745188/8116829). I don't use IPython much, so I haven't tried it yet. However, [it seems that running IPython in this manner changes how it receives inputs and returns output information](https://ipython.readthedocs.io/en/stable/development/how_ipython_works.html#the-ipython-kernel).
------
**Some things that didn't work for me:**
I'm not sure if all of this is relevant or useful experimentation, but here are a few things I tried to do to see if I could get any insight into what is causing this issue.
*Pipe vs. pty:* I wondered if this issue is caused because Emacs cannot use a pty on Windows and is stuck using a pipe instead. I tried setting up the Python shell as a pipe on my Mac, but did not experience this same issue.
*TKinter vs QT:* I installed PyQt6 and experienced the same issue using some pretty basic code.
from PyQt6.QtWidgets import QApplication
app = QApplication([])
*Exploring what happens if run through asyncio:* I tried running asynchronous code to see if Tkinter would block code in another coroutine from running (that was intentionally paused until after the window was created). Both coroutines ended up terminating, but Python still hanged at the end.
*Attempting to run code to write to disk to see if Python is accepting input but failing to return output:" After getting Python to hang, I attempted to send a couple of lines to write a short file. Unsurprisingly this failed. However, if I sent all of the code, with the file writing coming after the call to TKinter, it succeeded in writing the file. I even put an extremely long string (> 10k characters) in the middle to make sure the input stream was sent in multiple batches, but it still succeeded. This seems to suggest that Python will properly read all of its input stream, even after Tkinter/QT causes it to hang.
*Monitoring the output from Python:* I used a custom function in `comint-preoutput-filter-functions` to monitor the output from Python. Unsurprisingly, when Python has hanged, nothing passes through this function.
*Sending a large amount of input to Python after it has hanged:* I used `make-string` to send a string of 10,000 characters after Python hanged. This causes Emacs to hang in addition to Python (until `C-g` is pressed). I believe that the issue here is that Emacs is waiting to send the rest of the input until the input buffer has been emptied. But since for whatever reason Python is not reading the input buffer, Emacs will have to wait indefinitely to send more input.
-----
I don't know a lot about Windows processes or how Emacs handles them, but the problem seems to be somewhere in Emacs sending new strings to the process, Windows handling this connection, or Python continuing to read its input buffer, but I have not been able to narrow down which one the culprit is. It appears that Emacs is at least attempting to send the string; it also appears that Python will read anything that is in the input stream that contains the tkinter call, even if that input is received after the tkinter window has been created.
**tl;dr** I don't have a solution either but am putting this up to help compile information about this issue in one place.
RobThorpe · 2022-04-29 02:37
Thank you very much for your input. I will look into it more myself. I filed this as a bug against emacs [here](https://debbugs.gnu.org/db/55/55119.html). I got a reply from Eli Zaretski. He suggested that it finding a solution is unlikely.
I'm going to try the ipython way. I'll reply here if it works.
RobThorpe · 2022-07-25 04:17
Using Ipython removes the problem I have with Tk.