Open AGSPhoenix opened 3 years ago
And just 10 more minutes of searching brings me to the open Python issue for this... from 10 years ago. No time to investigate the ideas there at the moment, unfortunately.
@AGSPhoenix currently, eventlet backdoor basically patches stdin/stdout to socket and runs stdlib code.InteractiveConsole
. Personally, I approve implementing REPLoop in backdoor - it's mostly copy code from stdlib and removing sys.stdin/out patching is a huge win for everybody. I've modified backdoor test in f6770dcdb to verify multi-line input and one can continue to work on top of that branch if you like.
Further, less tired reading has revealed that my initial assumptions were incorrect. The buffer cleared by code is the internal buffer where it builds a complete statement, not the buffer of input waiting to be processed. (When will I learn not to submit issues when I should have been asleep an hour ago?)
Interestingly, this doesn't occur with code.interact
, which uses the same InteractiveConsole internally. Dug a bit deeper and hacked a logger onto the raw_input method in code
, and the input()
builtin is somehow skipping over lines when eventlet does its stuff with backdoor, but not when used by code
.
Maybe the lost lines are somehow being eaten when eventlet switches stdin around? Maybe this is some weird quirk of how eventlet wraps the socket with file methods?
Maybe the lost lines are somehow being eaten when eventlet switches stdin around?
My guess this is possible.
Maybe this is some weird quirk of how eventlet wraps the socket with file methods?
My guess this is not the case. socket.makefile
is used a lot, we'd see more errors of this kind.
It shouldn't be much work to make backdoor interact via explicit files. Sorry, I don't have time for it.
All right, an hour of wading through CPython internals has destroyed any interest I have in finding the actual bug. An eventlet-specific copy of InteractiveConsole
built for socket operations is likely going to be the least ridiculous solution.
Sketched out a PoC: https://github.com/AGSPhoenix/eventlet/commit/852df0aa1af979733c8f5a708c27928917123215
It works (usually?), but is not ready for merge. I have several questions about eventlet's internal API I didn't have time to look into. Might make a good base for a proper solution?
@AGSPhoenix what questions?
sys.stdout
switch()
SocketStdout
wrapper, access to sturdy readline
implementation, and just a socket.makefile()
call away"""Eventlet's variant of InteractiveConsole
nit picking, but it's not related to Eventlet actually, just what InteractiveConsole should be without hardcoding sys.std*
references.
Directly copied out of a backdoor session:
Versions (probably "any", but for completeness' sake):
Turns out code.py discards any pending input after successfully running a chunk of code, something I will restrain myself to describing as an interesting design decision.
Is there a good way eventlet could work around this behavior?