Open henryiii opened 3 weeks ago
As another instance of this same problem, I created a nox session that runs mkdocs docs-serve for the project, which runs until stopped by Ctrl-C. (Maybe that's not a typical nox task, but it's sort of a task runner task.)
Nox's Ctrl-C handling means that docs-serve doesn't always quit cleanly and sometimes lingers in the background, keeping the port used, which the user notices when they can't run mkdocs docs-serve again.
The brute force workaround is to call os.execvp
in the noxfile, which has its own drawbacks.
Here's my example script:
# ctrlc.py
import time
while True:
try:
time.sleep(1) # Sleep to avoid busy-waiting
except KeyboardInterrupt:
print("KeyboardInterrupt caught!")
And an example session to try it out with:
@nox.session(python=None)
def ctrlc(session):
session.run("python3", "ctrlc.py")
By setting the defaults to None, this provides a much nicer behavior, where the first Control-C is passed through, and the second one performs the kill. I wish there was a way to allow multiple Control-Cs, but this is IMO a nice improvement already.
For now, you can manually set these timeouts to None. I'd like to see if we can improve the passthrough behavior. Jupyter, for example, requires two Ctrl-C presses to quit.
The current Control-C handling doesn't work for thing like pytest very well. For example, I was running this on nox itself:
Part way through, I saw a failure, so I pressed Control-C to get the failure. But instead of seeing it, nox just prints "Inturrupted". Running
uv run nox ...
instead works perfectly, and shows me the missing failure. The problem is that nox is quickly escalating and killing the process before the slow pytest wrap-up procedure can finish. Here, uv (or running it directly, etc) isn't jumping in and "helping" by sending a kill after .2 + .3 seconds.A suggested fix: we could replace the final timeout with another Control-C loop, so a second Control-C would trigger nox's hard kill. (Users can also send
Control-\
, so maybe even this is over, ah, kill?) This would happen if this timeout was set to None (new default), but users could set it and the old behavior would be used. Nox could also explain what it's doing.