microsoft / vscode-jupyter

VS Code Jupyter extension
https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter
MIT License
1.25k stars 274 forks source link

Enable Python Interactive for use as a debugging console #1278

Open geophpherie opened 4 years ago

geophpherie commented 4 years ago

I think this is related to / mentioned deep in the comments here, but I'm not convinced they're quite duplicates.

I think it'd be tremendously useful to be able to also select Python Interactive as your debug terminal, essentially launching a Python Interactive window at a breakpoint with the state of your program loaded into it, giving you access to your variables. That way plotting functions and visualizations could be made use of pretty easily as a way of debugging. This varies slightly from the current "Debug Current File in Python Interactive window", which would run your entire script in Python Interactive, in that you are still able to configure the debugger launch.json. For my specific use case it would allow passing in command line args to the script, while still being able to debug in Python Interactive.

At a high level, I can see two ways of it happening: 1) Use only Python Interactive and allow it to continue execution of the code as the full debug tool. 2) Use the main debug terminal for the debugging flow, but at a breakpoint launch the Python Interactive window that opens preloaded with the current program state. At that point, the Python Interactive window is essentially detached from debugger, but at least has the data from the program at that time, allowing for more native exploring of the variables. Once the user continues debugging, the current Python Interactive window is either updated or a new one is launched at the next breakpoint.

My current work around is just to write a data frame to a .csv in the current debugger, then load it into Python Interactive - which works well enough, but I think it'd be really helpful if they were somehow integrated!

Thank you for making this product so awesome to use!

IanMatthewHuff commented 4 years ago

@jbeyer16. I like this suggestion, right now there is a bit of an odd bifurcation between the debugging and interactive debugging workflows. We'll consider it in the next triage meeting.

geophpherie commented 4 years ago

awesome! looking forward to seeing how it develops. thanks!

alexhamiltonRN commented 4 years ago

Great suggestion @jbeyer16. Thanks for considering @IanMatthewHuff - the described functionality would be a huge improvement for my workflow.

adamryczkowski commented 4 years ago

@gramster I understand debugging Python inside Jupyter is not easy. Did you check out how the problem was solved in 2018 by PixieDebugger? (https://medium.com/codait/the-visual-python-debugger-for-jupyter-notebooks-youve-always-wanted-761713babc62)

gramster commented 4 years ago

We’re not trying to implement a debugger that runs entirely in Jupyter cells; for us we have to integrate the debugger into the overall Visual Studio Code debug experience. It’s a different problem.

On Sun, Nov 3, 2019 at 4:57 AM Adam Ryczkowski notifications@github.com wrote:

@gramster https://github.com/gramster I understand debugging Python inside Jupyter is not easy. Did you check out how the problem was solved in 2018 by PixieDebugger? ( https://medium.com/codait/the-visual-python-debugger-for-jupyter-notebooks-youve-always-wanted-761713babc62 )

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/microsoft/vscode-python/issues/6972?email_source=notifications&email_token=AAVCPCBGAOJT4LOQQ5PZ6XLQR3DCHA5CNFSM4ILYADY2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEC5R6QQ#issuecomment-549134146, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAVCPCFNKSK6XSNSHGB7HULQR3DCHANCNFSM4ILYADYQ .

mwindowshz commented 4 years ago

Yes this would be a great feature, just like in Spyder the debug console is limited and not easy to use. Interactive python is much better

syagev commented 4 years ago

This is actually extremely useful for data-science oriented work. PyCharm somehow does this seamlessly, when debugging a regular Python project, the "Debug console" is actually an IPython one. That means, for instance, that it can be used for interactive matplotlib plotting even when the project is not executed in jupyter.

I'm interested to understand how something like this would be implemented to see if I can find some "ugly" temporary workaround. So maybe I can start some sort of listener server in my own code , then when stopped on a breakpoint I coudl launch IPython from the terminal and somehow "attach" it to my current session

netanelrabinowitz commented 4 years ago

@syagev don't know if this is what you want but it's kind of workaround and it's definitely ugly :) you can launch an embedded IPython REPL right from the DEBUG CONSOLE tab

    import IPython
    IPython.embed()

and interact with it at the TERMINAL tab.

derekeden commented 4 years ago

Has there been any update on this ? I love VScode but this is the sole reason I don't use it over my current IDE

sushant-tj commented 4 years ago

I need this feature man.

derekeden commented 4 years ago

I need this feature man.

same - honestly would love to use VSCode as my main IDE but there's no way I can effectively debug without an interactive debugger

robfromdublin commented 4 years ago

I didn't know this wasn't possible and just lost my morning trying different configuration options to make it so. This feature is a must have for me. I find the inconsistency between debug and interactive consoles annoying

fengyanghe commented 4 years ago

Awesome! I am looking forward to a new interactive debug like WingIDE's. Thanks

bashtage commented 4 years ago

@NetanelRabinowitz This is such a useful hint. It would be great if this could be made into an automatic process somehow so that everything a particular debug config was run the terminal would have an interactive IPython session.

rchiodo commented 4 years ago

I think the original problem could possibly have been solved by allowing the user to specify the interactive debug settings in the launch.json.

sedghi commented 4 years ago

This is absolutely an necessary feature for data science and machine learning projects. can we have it?

rchiodo commented 4 years ago

Which 'this' are you referring to? Launch with interactive as an option in the launch.json is likely possible, but connect to a python process with the interactive console is not.

sedghi commented 4 years ago

@rchiodo Sorry if i was not clear, I was referring to a PyCharm-like debug console which is IPython. I tried all the above answers to have a simple matplotlib plot to show up while debugging, and it didn't work.

bashtage commented 4 years ago

The ability to drop into an IPython debug console anywhere is a very powerful tool, and is a real USP of PyCharm.

hoechenberger commented 4 years ago

I would also like to chime in here and say that this is really a big blocker for my department's adoption of VS Code.

whong-art commented 4 years ago

Looking for this feature as well

m-guggenmos commented 4 years ago

@syagev don't know if this is what you want but it's kind of workaround and it's definitely ugly :) you can launch an embedded IPython REPL right from the DEBUG CONSOLE tab

    import IPython
    IPython.embed()

and interact with it at the TERMINAL tab.

Meanwhile - is there any way to automate this nice workaround?

Edit: I missed @bashtage's similar comment.

sedghi commented 3 years ago

is there any update here?

rchiodo commented 3 years ago

This item is kinda ambiguous.

The original request was to support launch.json settings for the interactive window. That might happen. We don't have a definite plan for it though.

The other request was to allow the user to switch to an IPython terminal in the middle of debugging. That will likely never happen. Transferring kernel state (especially from a non kernel runtime) is non trivial and not something we're likely to pursue.

We might allow the user to start the debugger with IPython as a terminal though. Basically automate the workaround as described by @NetanelRabinowitz up above.

The status of this issue is waiting for @jmew or @claudiaregio to split it into those 3 parts.

sedghi commented 3 years ago

@rchiodo As I described in the previous comments, a very handy tool that PyCharm has is that it allows to plot in the middle of debugging which is super useful for different areas of image analysis especially in medical imaging. The IPython as a terminal with a workaround above does not allow for plotting of any kind.

rchiodo commented 3 years ago

@sedghi you should be able to use the first option:

You'd start the debugger using the interactive window. This should be possible now minus the settings (arguments to pass to the script etc).

bashtage commented 3 years ago

We might allow the user to start the debugger with IPython as a terminal though. Basically automate the workaround as described by @NetanelRabinowitz up above.

I think this is the closest to what PyCharm does. If you have IPython installed, when you drop into the console, you get an IPython session. There is no available to open as a standard Python session and then transform this to an IPython session.

geophpherie commented 3 years ago

This item is kinda ambiguous.

I am entirely on board with moving forward with suggestion 1 and scratching suggestion 2. They were just ideas I had about how it could be implemented. The main end goal was just being able to use some sort of iPython-like console to debug - (and as others have suggested) mostly to allow for plotting capability within a debug breakpoint.

pepicello commented 3 years ago

I'd like to share my debugging workflow, as it is slightly different from OP's request.

It sometimes occurs to me that some functions misbehave and raise exceptions with a specific set of inputs which are generated in Python Interactive windows. It usually takes time to generate the inputs and I would love to have debugging tools at hand keeping the current kernel state. This would involve running a debugger from within Python Interactive, instead of exiting the Python Interactive window and running the debugger.

I realize this issue is about the opposite of what is discussed here: i.e. having a debugger within the Python Interactive window rather than a Python Interactive window within the debugger. Is this something which could be integrated with the solutions proposed here, or is it better to discuss in a new issue? I think this feature would really help me in switching to vscode. Thanks!

rchiodo commented 3 years ago

@pepicello can you use the existing debug cell? We already have a way to start the debugger while using the interactive window.

pepicello commented 3 years ago

@rchiodo , yes, I missed that feature and that is exactly what I needed, thanks!

JanHomann commented 3 years ago

Plotting does actually currently work on my end. You just have to add plt.show() after the plot command.

plt.matshow(df)
plt.show()

This pops up an external plot window. The debug console is then blocked and will complain that plt.show() did not finish after 3 seconds, but the plot is there and fully functional.

Then when i am done analyzing the figure, I click on close, or press q (the shortcut for closing a matplotlib window) and that unblocks the debugger. The plot window though doesn't disappear, but freezes. But it's still possible to do additional plots like that, which will then use the same window. It's also possible to prepare several figure objects in one or several debugging commands, and plt.show() will show all of them. In addition if you show the plot with plt.pause(0.001) instead of plt.show(), then you return immediately back to the debug terminal (but the plot freezes).

If you want interactivity again of your opened plots at any point in time, you have to first call plt.ion() at least once, then plt.show() again, and then input(). That will allow you to fiddle with you plot, until you hit enter in the integrated terminal.

If you use "Debug Current File in Python Interactive Window", it uses that window as the output of the debug console. That means plots don't block the console and dataframes can be displayed with

from IPython.display import display            # can be done in the header of the original file
display(df)

Update: When you use plotly express, plots will be directed to an external browser window and stay fully interactive even when python keeps on computing. So I guess it makes sense to use this instead of matplotlib.

Steph71 commented 3 years ago

Hi,

I am using VScode Python for remote debugging, because Pycharm blocks this feature in its community edition.

I would love to make VScode my main IDE for Python, because I like the idea to have one Editor for all languages.

But the missing interactive debug console is a showstopper for me.

Hitting a breakpoint and dropping into an IPython Console is an essential feature for a Python IDE:

https://www.jetbrains.com/help/pycharm/using-debug-console.html

Actually also the good old pydev can do it:

https://www.pydev.org/manual_adv_debug_console.html

Best Regards

rchiodo commented 3 years ago

@Steph71 not sure what you're missing. The IPython console is available when using the interactive window for debugging. Click the 'Debug Cell' code lens over top of your code. All output will be sent to the interactive window.

image

Perhaps you're talking about being able to eval in the ipython console. That's not currently supported (as the kernel is busy with the cell that's running). You can eval in the debug console at the same time though. Output is then duplicated in the interactive window and the debug console:

image

rchiodo commented 3 years ago

Or perhaps you're asking for a switch to 'interactive' after you've already started debugging. This won't likely be supported any time soon (I mentioned this in one of the comments above). We'd have to transfer the state of the python app you launched into a jupyter kernel.

geophpherie commented 3 years ago

Maybe it's worth restating what I thought when I created this issue and what I've learned thanks to some comments from others.

The initial hope was to have an additional option in the launch.json file under console that allowed you to pick "Python Interactive". The idea was then, when a debug breakpoint was hit, instead of working in the debug console, a Python Interactive window would open with your variables in the workspace, and you could play around in Python Interactive as you desired. I have no idea if this is feasible or not, but sounds not particularly likely.

In lieu of this feature, there was a great suggestion above to run:

from IPython import embed; embed()

in the Debug Console as soon as a breakpoint hit. You could then click "Terminal" and have an embedded IPython console running with all your workspace variables available. There are some differences between the IPython console and Interactive Python, but functionally they work pretty similarly. This method accomplishes pretty much everything I was hoping for, just with a bit of manual interaction and without the friendliness of the Python Interactive interface.

You can then, for example, run (in your embedded IPython console):

import matplotlib.pyplot as plt plt.ion()

Then you can then create and explore plots with your data from the state of your script at the debug breakpoint. The downside here is that the embedded IPython console essentially blocks the debugger, so you can't interact with any of the Variables on the VSCode side until you terminate the IPython session. Even still, I think this is a very helpful alternative.

So one suggestion may be just to automate that from IPython import embed; embed() call. So maybe in the launch.json file, you can select "IPython Terminal" as your console, and basically behind the scenes that line of code runs for you and pops up the IPython console. Not sure. But like I said, running from IPython import embed; embed() accomplishes most all of what I'm looking for, and I encourage others to try that out and see what they think!

rchiodo commented 3 years ago

The idea was then, when a debug breakpoint was hit, instead of working in the debug console, a Python Interactive window would open with your variables in the workspace, and you could play around in Python Interactive as you desired. I have no idea if this is feasible or not, but sounds not particularly likely.

Actually this idea is pretty feasible. Switching to this console after starting isn't, but starting the debuggee with the interactive window should be doable. It would essentially run your entire process as a cell.

In lieu of that, your other workaround sounds good too.

Steph71 commented 3 years ago

Hi,

thanks for all the answers.

I tried to run my code in the interactive window ... but I do not see, how I would set a breakpint there and step in and through functions.

the suggested way

from IPython import embed; embed()

does basically what I am looking for, but it has some downsides:

1.) I have to type or paste the command whenever I need the interactive console, then I have to switch windows 2.) The main debug process is stalled, so I if I want to step one line in my original code, I need to exit the Ipython console, do the step, then start the console again ... 3.) The pycharm debug console is giving me nice features like

to me this sounds more like a workaround than a feature ... but this is probably just the difference bewteen a generic editor, enabled with some plugin to support a language and an IDE, specifically build to develop in a language ...

Best Regards Stephan

hoechenberger commented 3 years ago

@rchiodo

but starting the debuggee with the interactive window should be doable. It would essentially run your entire process as a cell.

This would be exactly what I'm looking for :)

rchiodo commented 3 years ago

@Steph71

I tried to run my code in the interactive window ... but I do not see, how I would set a breakpint there and step in and through functions.

Setting a breakpoint is the same as setting breakpoints without the interactive window. You click in the gutter or hit F9.

image

As you step of if you hit F5, the breakpoints should hit. This should also work with breakpoints in other files. It's running the same debugger as non interactive.

but this is probably just the difference bewteen a generic editor, enabled with some plugin to support a language and an IDE, specifically build to develop in a language ...

I agree it's not ideal. We should implement what @jbeyer16 asked for, set the console for any debug session to 'interactive' and then it just runs the entire file you have open in the interactive window. This would also require changes to the interactive window so you could input during debugging (the mismatch you may be referring to between a full IDE and an editor).

I'd argue that VS code is an IDE, it's just the scenario you're asking for wasn't implemented yet.

Steph71 commented 3 years ago

@rchiodo

ah, now I got it debug ... but actually its the same issue here ... while debugging the interactive window is not interactive but frozen.

If the option @jbeyer16 is proposing is feasable, that would be a big step forward ... actually the Interavtive window is even somehwhat better than the ipython console as plots can be directly plotted to the window instead having them floating around ...

So I will watch this issue and hope for that getting resolved the one or the other way ... probably its worth looking how the pydev people are doing that, as jetbrains are just using their code ...

OSHI7 commented 3 years ago

I'd second @jbeyer16 's suggestion.

oponcea-dn commented 3 years ago

This would be a great feature! I just started using vscode debugging and got used to PyCharm way of doing things. So, any news on it?

rchiodo commented 3 years ago

It's on our backlog but no news on when we'll get to it.

sunshe35 commented 3 years ago

i love it. i love debug python file using ipython console like pycharm. so i do not like the debuging way for python now when i use vs-code.

ChelsyMena commented 3 years ago

Hey, correct me if I'm wrong but is this not the "right click + open a console for notebook" function in JupyterLab? That's what I miss the most when I'm in VSC (and Shift + Tab docstrings, but that's another beast)

aksg87 commented 2 years ago

@JanHomann @jbeyer16

When following the steps of launching: from IPython import embed; embed()

I am not getting a second external window pop up after trying to display my plot. Anything I am missing here?

My steps:

  1. from IPython import embed; embed()
  2. import matplotlib.pyplot as plt
  3. plt.imshow(...) + plt.show()

image

aksg87 commented 2 years ago

@Steph71 not sure what you're missing. The IPython console is available when using the interactive window for debugging. Click the 'Debug Cell' code lens over top of your code. All output will be sent to the interactive window.

image

Perhaps you're talking about being able to eval in the ipython console. That's not currently supported (as the kernel is busy with the cell that's running). You can eval in the debug console at the same time though. Output is then duplicated in the interactive window and the debug console:

image

When trying to debug an individual cell, I still can't interrogate data and plot new aspects while debugging the cell. The debug cell does allow me to step through the existing code and see variables states, but I still don't see how I can plot new things dynamically?

geophpherie commented 2 years ago

@aksg87 I think you might have to create the figure explicitly before plotting.

from IPython import embed; embed()
import matplotlib.pyplot as plt
plt.ion()
plt.figure()
plt.plot([1,2], [3,3])

seems to work for me.

vintprox commented 2 years ago

In my use case, it's one keybinding away on Jupyter: Debug Current File in Interactive Window command, but I wouldn't like to waste students' time to set these up. Alas, no default is provided. launch.json only allows old-school terminal with big payload (that one is distracting, for when you press F5).