-
Notifications
You must be signed in to change notification settings - Fork 297
add pypy-3.7 to test matrix #663
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
the test as-written is sensitive to garbage collection, which is different on pypy instead, test only that we create a valid tracker
783882d
to
6b04978
Compare
wait for the expected output to appear, instead of assuming 1 second is enough this should be both faster (where sleep(1) was enough) and more reliable
There does appear to be a real failure and real difference in behavior with respect to signalling child processes of the kernel. We use killpg to terminate the process group of the kernel. This is what's being tested in the failing I managed to reproduce it with this test: test_signal_subprocesses.pyimport os
import signal
import sys
import time
from subprocess import Popen
def child():
print(f"child waiting: {os.getpid()}")
try:
time.sleep(10)
except KeyboardInterrupt:
print(f"child interrupted: {os.getpid()}")
sys.exit(-2)
def parent():
children = []
for i in range(2):
p = Popen(['bash', '-i', '-c', 'sleep 10'])
children.append(p)
print(f"parent waiting: {os.getpid()}")
try:
time.sleep(10)
except KeyboardInterrupt:
print(f"parent interrupted: {os.getpid()}")
for child in children:
child.wait()
print(f"child {child.pid} status: {child.poll()}")
def test():
p = Popen([sys.executable, __file__, 'parent'], start_new_session=True)
pgid = os.getpgid(p.pid)
print(f"parent pid: {p.pid}, pgid: {pgid}")
time.sleep(2)
print("signalling parent")
os.killpg(pgid, signal.SIGINT)
p.wait()
def main(which):
if which == 'test':
test()
elif which == 'parent':
parent()
elif which == 'child':
child()
if __name__ == "__main__":
if len(sys.argv) > 1:
main(sys.argv[1])
else:
main("test") where CPython interrupts the bash children, but PyPy does not. I suspect this has to do with signal handler inheritance, and CPython is clearing signal handlers while PyPy doesn't? That's a guess. Switching the subprocess to use Python instead of bash results in interrupted children, though, so I assume the Python interpreter reinitializes SIGINT handler where bash does not. @mattip I think this should be considered a bug in PyPy's subprocess module. Switching the subprocesses to use Python instead of bash causes the test to pass. |
PyPy doesn't create subprocesses in the same way as CPython, resulting in ignored signals when we try to interrupt with `killpg`
Thanks for tracking this down. I will try to figure out what is going on. |
wait for processes to exit, not for expected result otherwise, a timeout is forced for any incorrect result
The remaining failures (for me) are FD exhaustion, which makes me suspect that we are somewhere relying on garbage collection to clean up some zmq sockets or other. This is usually reliable on CPython, which is how we may have gotten into the situation without noticing, whereas PyPy often needs explicit |
I am not sure I understand the difference in behaviour. On Ubuntu 20.04, both cpython and pypy3.7-v7.3.5 print (at the end) for
As for closing resources: if you could add a fixture to always call |
Ah, maybe it's a macOS thing, then. For me, the children run to completion with pypy and exit with status 0 (identical behavior to not signalling them at all). CPython behaves as expected, though. Good call on the gc. I'm poking around to see where I can find leftover references. I think a fixture to assert that there are no open zmq resources across tests is the right thing to do, which ought to catch this kind of issue. There could also be other issues, like subprocess pipes which might not be closed. |
You good folk are wizards, thank you for pushing this forward! |
db4ee2d
to
4d433eb
Compare
so hangs don't run for hours pypy needs more than 10 minutes, cpython doesn't
(I'm coming in late here and possibly haven't read the thread carefully enough) -- but what difference should I be observing here? On Big Sur 11.4 (MBA M1 2021) I see no difference between running this on |
@Julian we initially discovered some of these challenges when running the full test suite of the downstream conda-forge/ipykernel-feedstock#84 (comment) Unfortunately, I know little about the inner guts of |
I added |
Cool. It is passing (without coverage) in a similar time to the CPython runs. It seems this issue can be closed? Please do ping me if tests break. |
Sounds good, thanks @mattip |
Investigating downstream errors: