<div dir="ltr"><div><div><div><div><div><div>Our input handling actually does two intertwined things: telling when a block of input is complete and ready to execute, and transforming IPython's special syntax into regular Python calls. They're intertwined because we need to handle the special syntax to tell when it's complete.<br>
</div><div><br></div><div>The different frontends use these in different ways:<br></div><div><br></div>- The plain terminal sends lines to InputSplitter as they're entered, and when InputSplitter says the block is complete, it's sent to run_cell to execute.<br>
</div>- The Qt console currently does the same thing in the frontend, and sends the cell to the kernel when it's ready to execute. Users can override the automatic 'is it complete' using ctrl/shift+return.<br>
</div>- The notebook has no 'is it complete' detection, and simply sends the raw cell to the notebook when the user executes it.<br><br></div>There are a couple of problems I'd like to address:<br><br></div>- In the line-oriented frontends, transformations are actually done twice: once for the 'is it complete' detection, and again when run_cell is called. This is inefficient and confusing.<br>
</div><div>- The Qt console currently relies on having a frontend copy of part of the kernel's code. If you add a new input transformer in the kernel, the frontend won't know about it. This also means you can't write a line-oriented frontend with 'is it complete' detection in anything but Python - which I think is a problem, although Brian disagrees.<br>
<br></div><div>I'm proposing these changes, which I'll implement in a new pull request once we've finally dealt with #2447:<br><br></div><div>1. Add an optional transformed_cell parameter to run_cell(). In the terminal, the transformed code from InputSplitter will be passed in, avoiding the need to run those transformations again.<br>
<br></div><div>2. Add a new message type to the protocol, is_complete_request & is_complete_reply. When the Qt console (or another line-oriented frontend) gets a line of input, it will make an is_complete_request to decide whether it should accept another line of input, or send the code for execution. The InputSplitter logic in the Qt console would be removed. There are two possible APIs:<br>
</div><div> a. Send the entire block entered so far on each request to ask if it's complete (stateless).<br></div><div> b. Send each line at a time, and have a reset signal to indicate a new cell. This is more efficient, because the kernel doesn't repeatedly process the same lines. But it's stateful, so it's more complex to manage.<br>
<br></div><div>My preference is for a. In a line-oriented frontend, you're often running single-line commands anyway, in which case it's no less efficient. Keeping the API simple seems more important.<br><br></div>
<div>Thanks,<br></div><div>Thomas<br></div></div>