Opened 6 years ago
Last modified 4 years ago
#30416 assigned Bug
Runserver's reloading mechanism should restore terminal state completely
Reported by: | Daniel Hahler | Owned by: | Daniel Hahler |
---|---|---|---|
Component: | Core (Management commands) | Version: | 2.2 |
Severity: | Normal | Keywords: | |
Cc: | Tom Forbes | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | yes | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Currently it only ensures that echo is on, but not that e.g. Ctrl-C works etc.
This can be triggered when using pdb++, which uses pyrepl itself: it puts the terminal into raw state.
If the reloader then kicks in while at the prompt this will not be restored (except for echo).
Related issue, which mentions that a better mechanism would be good: https://code.djangoproject.com/ticket/15880
btw: pyrepl has no chance to restore itself: listening to SIGTERM is not possible in threads apparently, and e.g. atexit
is also not triggered there.
Change History (9)
comment:1 by , 6 years ago
Description: | modified (diff) |
---|
comment:2 by , 6 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:3 by , 5 years ago
Resolution: | → needsinfo |
---|---|
Status: | new → closed |
Without more details (after 7 months) this isn't really actionable. Happy to see it taken on, with a concrete action plan in place.
comment:4 by , 5 years ago
@Carlton
I would be grateful if you could add a detailed set of reproduce steps and/or an example project so that someone picking it up can get going on it easily.
I think everybody being able to fix this has enough info in the original issue already.
I've mentioned one way to trigger this: use pdb++ (with pyrepl), then have the reloader kick in while in the debugger.
A simpler method would be using termios.tcsetattr
directly to put it into e.g. raw state, then have the reloader kick in.
Therefore I suggest re-opening it already - it's an existing issue after all, and was mentioned in another issue (linked above) already.
comment:5 by , 5 years ago
Also note that the reloader should not really kick in in the first place when the debugger is used / only when the request finished.
(The use case is having a pdb.set_trace()
, the debugger being used, and then saving some file - it should not "kill" the debugger then (resulting in this issue))
Therefore waiting for the request / debugger to be finished before reloading would work around this issues (allowing the debugger (pyrepl in this case) to restore the terminal state itself).
Related: https://github.com/pallets/werkzeug/pull/1525 (for Werkzeug's reloader, which is similar IIRC).
comment:6 by , 5 years ago
Resolution: | needsinfo |
---|---|
Status: | closed → new |
I've rebased and added a test to https://github.com/django/django/pull/11291.
To reproduce this:
- install pdbpp (with pyrepl)
- put
pdb.set_trace()
in a view manage.py runserver
- trigger the reloader or use ctrl-c directly
- see that ctrl-c does not work on your shell anymore until you use
reset
Alternatively:
- add the following code to a view or similar:
import sys import termios fd = sys.stdin.fileno() attr = termios.tcgetattr(fd).copy() attr[3] &= ~( termios.ICANON | termios.ECHO | termios.IEXTEN | (termios.ISIG * 1) ) termios.tcsetattr(fd, termios.TCSANOW, attr)
- trigger the code
- observer that ctrl-c does not work anymore
With the patch/fix it will work again after the reloader gets triggered, and/or when killing the runserver manually.
comment:7 by , 4 years ago
Has patch: | set |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:8 by , 4 years ago
Cc: | added |
---|
comment:9 by , 4 years ago
Needs tests: | set |
---|
I've left comments on PR — ultimately I'm not sure we need to resolve this ourselves…
Maybe offering a way to pause the auto-reloader if you're in a debugger (as per comment:5 — but not necessarily with the lock approach in linked PR), but even then, I'm not sure we're committed to the auto-reloader working flawlessly if you save file changes whilst working in the debugger.
Possibly the suggested patch is a marginal improvement, but there are no tests at all. (Indeed some coverage is removed.) I'm not sure if we can come up with decent tests to make sure we don't introduce regressions. (It's on that untestable edge.) If we do merge this I think we need to ask regular contributors to try and break it with their debugging setup just to be sure we didn't break something else unexpectedly.
Current status ≈-0
Hi Daniel. I'm going to Accept this, because I see where you're coming from, but I would be grateful if you could add a detailed set of reproduce steps and/or an example project so that someone picking it up can get going on it easily.
Thanks.