posit-dev / positron

Positron, a next-generation data science IDE
Other
2.44k stars 73 forks source link

Console: Shell commands cannot accept user input in Python consoles #696

Open seeM opened 1 year ago

seeM commented 1 year ago

I encountered this when trying to do pip uninstall ipdb which requires me to enter Y, but I'm unable to:

>>> pip uninstall ipdb
Found existing installation: ipdb 0.13.13
Uninstalling ipdb-0.13.13:
  Would remove:
    /Users/seem/.pyenv/versions/3.10.11/envs/codal/bin/ipdb3
    /Users/seem/.pyenv/versions/3.10.11/envs/codal/lib/python3.10/site-packages/ipdb-0.13.13.dist-info/*
    /Users/seem/.pyenv/versions/3.10.11/envs/codal/lib/python3.10/site-packages/ipdb/*
Proceed (Y/n)?

A simpler example is:

>>> !read

which has the same issue.

Both of these work in IPython.

Might be related to https://github.com/rstudio/positron/issues/284?

nstrayer commented 6 months ago

Can recreate with the pip uninstall workflow. print(input("Type something: ")) works just fine so it's purely shell commands.

nstrayer commented 6 months ago
image

When the shell command is looking for an input, React is rendering the line as the <ConsoleInput/> component instead of <RuntimePendingInput/> like it does with native python input.

jmcphers commented 6 months ago

The thing that makes this hard is that the "awaiting user input" state is difficult to detect in child processes. From the perspective of the Python kernel, the pip command emitted some output, and then stopped emitting output for a while. How can we know that it's blocked waiting for stdin input and we need Positron to supply it?

This only works in IPython by accident; IPython doesn't do anything special other than (correctly) forward stuff you type while a child process is active to the child process's stdin. There's no mechanism for doing that in Positron.

One way to fix this would be to make the IPython kernel try to detect that there's a prompt active and ask Positron to supply input for the prompt (using the normal prompt input flow over the stdin socket).

Another approach, which would be more expensive but probably more correct, would be to alert Positron to the fact that a subprocess is active; in this mode, the Console would just toss all user input over to the kernel to be fed as stdin to the child process. Then we wouldn't have to detect a prompt.

seeM commented 6 months ago

This is also present in Jupyter Lab and VSCode notebooks. Adding some more context to Jonathan's diagnosis:

Here's the issue currently tracking this for Jupyter Lab: https://github.com/jupyterlab/jupyterlab/issues/14041.

Here's a really old issue that tracked this in IPython but was accidentally closed in a repo reorg: https://github.com/ipython/ipython/issues/514.

Here's an issue in the third party bash_kernel project that has a useful discussion: https://github.com/takluyver/bash_kernel/issues/113.

juliasilge commented 6 months ago

If this is something that Jupyter Lab and VS Code also have not fixed as of today, I would like to vote for moving this to the Future milestone and we wait to see the best way to address it further down the line.