I'm trying to find a way to use remote_pdb and entr together as an environment for rapid testing and development of Python 3 multiprocessing applications, but they're not playing nicely together.
Consider the trivial test case below:
import time
from multiprocessing import Process
from remote_pdb import RemotePdb
def child():
RemotePdb('localhost', 4444).set_trace()
while True:
print("I am the child")
time.sleep(1)
proc = Process(target=child)
proc.start()
proc.join()
If I save it in a file, say, 'mp.py' and the run it with:
python mp.py
it works very nicely. It breaks, as expected, in the child process displaying
CRITICAL:root:RemotePdb session open at 127.0.0.1:4444, waiting for connection ...
RemotePdb session open at 127.0.0.1:4444, waiting for connection ...
and I can connect from another terminal session with, netcat or socat and use the python debugger. Exiting the debugger leaves the child and parent running until I explicitly kill them.
If I now comment out the RemotePdb() call and run the script under control of entr
with
ls mp.py | entr -r python mp.py
it allows me to edit mp.py and get an automatic clean restart each time I save.
The problem arises when I uncomment the RemotePdb() call.
The script is restarted by entr and it breaks in the child displaying the same 'waiting for connection' message as before but if I try to connect with netcat
in another terminal window the pdb session is unresponsive with no output and no echo -- just empty lines in response to CR's. I get the same result with socat
.
I'm developing on OS X 10.11.6 with python 3.5.3, entr 3.7, remote_pdb 1.2.
What I'm asking for:
I'll accept an answer that provides a command line solution which combines the benefits of entr
and remote_pdb
or a clear explanation why it can't be done.
Thanks!
Update
Further testing shows that the -r
(restart) option to entr is necessary to produce the problem, i.e.
ls mp.py | entr python mp.py
permits the debugger connection to work. Unfortunately, the restart option is essential to the workflow.
Update 2: The problem seems to be related to setting the process group. This is done by entr -r
to make sure all the child processes can be killed. While trying to come up with a Python script to replace entr
I found that calling os.setpgrp()
in the parent process will produce the same failure (no I/O to debugger) if the script is launched from an IPython shell (!python mp.py
) but not if it launched from bash
.
Update 3: The author of remote_pdb and I have independently verified that the problem is not occurring in Linux. This is an OS X issue apparently having something to do with Python sockets and process groups. I've added to the tags accordingly.