Debugging Usability Question: Which Console?

155 views
Skip to first unread message

Jed Ludlow

unread,
Feb 9, 2013, 6:31:20 PM2/9/13
to spyderlib
I just committed a change that now makes the debugging toolbar commands work for all Spyder console types (excluding Spyder's own internal console, of course) [1]. That includes standard external Python consoles, IPython consoles attached to Spyder-controlled kernels, and IPython consoles attached to external kernels. Note that there are still some limitations with debugging in an external kernel. For example, breakpoints set in Spyder will not be active [2].In the process of implementing the feature, an important usability question came up.

Spyder allows you have multiple consoles open, and more than one of those could be running the current file in the editor. Furthermore, because the dock widgets can be moved from the main window, a window layout like the attached is possible. In fact, I know there are some of you who routinely pull the Console plugin outside like I've shown in the attached screenshot.

In that light, an ambiguity arises. If the current editor file is set to run in an existing Python interpreter, which of the two interpreters should it choose?  Here are a couple of options:
  1. If only one console is visible, run in that one. If more than one type is visible, run in the IPython console. This is the current behavior. The IPython choice is kind of arbitrary and could be changed to default to the Python console.
  2. Require the user to set focus on one of the desired console before running or before sending a debug command.
The first option seems more convenient because you don't have to worry about widget focus, and it is actually a somewhat rare condition to have both consoles visible. And, under the layout in the screenshot, if you want to make sure everything goes to the Python console you simply hide the IPython console by hitting the History log tab. The second option seems the most general and has some intuitive appeal, but it might make things less convenient for the user because you have to keep setting focus.

I'm very much interested in your feedback about which of the two options you'd prefer. Please reply with thoughts.

external_console_usability.PNG

Pierre Raybaut

unread,
Feb 10, 2013, 7:43:54 AM2/10/13
to spyd...@googlegroups.com
There is a similar problem with the editor plugin: multiple editor
widgets may be visible at the same time, and it should happen more
often than for consoles. The solution with the editor plugin was to
keep track of the last editor widget which had focus. This widget is
considered as the current active widget (e.g. new files will be opened
in that widget).

So I guess that the same behavior should be expected for consoles:
this is your second solution. However, I'm not sure to understand why
you wrote that it would imply for the user to systematically click on
the console before executing the command: for me, as I understand it,
the user would simply click on the console once, to make it active.

-Pierre

2013/2/10 Jed Ludlow <jed.l...@gmail.com>:
> --
> You received this message because you are subscribed to the Google Groups
> "spyder" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to spyderlib+...@googlegroups.com.
> To post to this group, send email to spyd...@googlegroups.com.
> Visit this group at http://groups.google.com/group/spyderlib?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Jed Ludlow

unread,
Feb 10, 2013, 10:22:51 AM2/10/13
to spyderlib
On Sun, Feb 10, 2013 at 5:43 AM, Pierre Raybaut <pierre....@gmail.com> wrote:

So I guess that the same behavior should be expected for consoles:
this is your second solution. However, I'm not sure to understand why
you wrote that it would imply for the user to systematically click on
the console before executing the command: for me, as I understand it,
the user would simply click on the console once, to make it active.


Yes, once a console received focus for receiving debugging commands it would keep that focus until it was changed by the user. This would probably happen most often when you decided to browse the code in the editor after pdb had stopped. In order to begin sending debugging commands you would have to set focus back to the console of interest. I guess if you were entering commands manually at the pdb prompt you'd have to do the same thing anyway. Maybe it's not that big of a usability hit to set focus manually.

Carlos Córdoba

unread,
Feb 12, 2013, 2:03:15 PM2/12/13
to spyd...@googlegroups.com
Hi,

I think there are two issues here:

1. Select the console to send commands to.

Right now the logic is very simple: if the ipython console is visible, send commands there. If not, send commands to the python one. If both are visible (as in Jed's screenshot), commands are always going to be sent to the ipython console.

I agree with Pierre that the best thing to do is properly implement option 2. This would require to maintain a variable (probably in spyder.py) that keeps track of the currently focused console (python or ipython).

2. Decide what happens when the user is debugging and changes focus to another console.

@Jed: If the user only changes focus to the editor but don't move to another console, then (as things are right now) debug commands continue to be sent to the selected console (could you confirm it?). if that's not the case, then we must fix it because otherwise it'd be counterintuitive.

For the case I mentioned, I think we need to have a variable for each console to know if it is debugging state or not. This would let us avoid to send debug commands to non-debugging consoles.

Cheers,
Carlos

El 09/02/13 18:31, Jed Ludlow escribió:

Jed Ludlow

unread,
Feb 12, 2013, 3:09:21 PM2/12/13
to spyderlib
On Tue, Feb 12, 2013 at 12:03 PM, Carlos Córdoba <ccord...@gmail.com> wrote:
Hi,

I think there are two issues here:

1. Select the console to send commands to.

Right now the logic is very simple: if the ipython console is visible, send commands there. If not, send commands to the python one. If both are visible (as in Jed's screenshot), commands are always going to be sent to the ipython console.

I agree with Pierre that the best thing to do is properly implement option 2. This would require to maintain a variable (probably in spyder.py) that keeps track of the currently focused console (python or ipython).

Or, rather, it would keep track of the last console that had focus since very often the editor will have current focus when a "run" command is issued. 
 

2. Decide what happens when the user is debugging and changes focus to another console.

@Jed: If the user only changes focus to the editor but don't move to another console, then (as things are right now) debug commands continue to be sent to the selected console (could you confirm it?). if that's not the case, then we must fix it because otherwise it'd be counterintuitive.

Today, all decisions about run commands and debugging control commands are based upon console visibility. So, if two consoles are visible and you change focus to the editor, commands will always go to the IPython console regardless of widget focus today. To get them to enter the other console you have to hide the IPython console.

Incidentally, one longer-term solution would be to make it impossible for more than one console to be showing by housing all consoles, both standard Python interpreters and IPython clients, as tabs of the same plugin. Old Spyder was this way. That would eliminate all ambiguity about command direction and require no manual focus setting. I know issue 1053 argues for putting IPython kernels and clients in the same plugin [1], but the more I think about it the kernels are the things that really belong in their own plugin by themselves. Standard Python interpreters and IPython clients seem to be more natural cousins to be housed in the same tab widget given the type of input they receive from the user. 
 

For the case I mentioned, I think we need to have a variable for each console to know if it is debugging state or not. This would let us avoid to send debug commands to non-debugging consoles.


This will likely require a monkey patch to pdb since it's possible to put a console into debug mode from the command line, and the only way for Spyder to find out about that would be if pdb itself did the notifying. That's not really a good option for external kernels since we can't monkey patch pdb in those. I think we can come to a rational console selection method without having to go there.


 

Carlos Córdoba

unread,
Feb 12, 2013, 4:50:44 PM2/12/13
to spyd...@googlegroups.com
Hi Jed,

My answers are below.

El 12/02/13 15:09, Jed Ludlow escribió:
On Tue, Feb 12, 2013 at 12:03 PM, Carlos Córdoba <ccord...@gmail.com> wrote:
Hi,

I think there are two issues here:

1. Select the console to send commands to.

Right now the logic is very simple: if the ipython console is visible, send commands there. If not, send commands to the python one. If both are visible (as in Jed's screenshot), commands are always going to be sent to the ipython console.

I agree with Pierre that the best thing to do is properly implement option 2. This would require to maintain a variable (probably in spyder.py) that keeps track of the currently focused console (python or ipython).

Or, rather, it would keep track of the last console that had focus since very often the editor will have current focus when a "run" command is issued.

Yep, that's what I meant: not focused console but selected one.



2. Decide what happens when the user is debugging and changes focus to another console.

@Jed: If the user only changes focus to the editor but don't move to another console, then (as things are right now) debug commands continue to be sent to the selected console (could you confirm it?). if that's not the case, then we must fix it because otherwise it'd be counterintuitive.

Today, all decisions about run commands and debugging control commands are based upon console visibility. So, if two consoles are visible and you change focus to the editor, commands will always go to the IPython console regardless of widget focus today. To get them to enter the other console you have to hide the IPython console.

My bad, it was the easiest thing for me to do at first. Perhaps after solving the previous point, it should fix this one too.


Incidentally, one longer-term solution would be to make it impossible for more than one console to be showing by housing all consoles, both standard Python interpreters and IPython clients, as tabs of the same plugin. Old Spyder was this way. That would eliminate all ambiguity about command direction and require no manual focus setting. I know issue 1053 argues for putting IPython kernels and clients in the same plugin [1], but the more I think about it the kernels are the things that really belong in their own plugin by themselves. Standard Python interpreters and IPython clients seem to be more natural cousins to be housed in the same tab widget given the type of input they receive from the user.

Work for 2.3, right? :-) The two consoles are wildly different right now and joining them won't be easy (if feasible at all).



For the case I mentioned, I think we need to have a variable for each console to know if it is debugging state or not. This would let us avoid to send debug commands to non-debugging consoles.


This will likely require a monkey patch to pdb since it's possible to put a console into debug mode from the command line, and the only way for Spyder to find out about that would be if pdb itself did the notifying. That's not really a good option for external kernels since we can't monkey patch pdb in those. I think we can come to a rational console selection method without having to go there.

I think it could be far more easier: add a signal to the Debug action and button that changes the state of a new console attribute called "debugging".

Cheers,
Carlos

Jed Ludlow

unread,
Feb 12, 2013, 6:20:15 PM2/12/13
to spyderlib
On Tue, Feb 12, 2013 at 2:50 PM, Carlos Córdoba <ccord...@gmail.com> wrote:
Today, all decisions about run commands and debugging control commands are based upon console visibility. So, if two consoles are visible and you change focus to the editor, commands will always go to the IPython console regardless of widget focus today. To get them to enter the other console you have to hide the IPython console.

My bad, it was the easiest thing for me to do at first. Perhaps after solving the previous point, it should fix this one too.


I don't think it's bad at all. It's actually quite convenient for the large majority of use cases. It only becomes a bit tricky when two consoles are visible. That's a fairly rare situation.
 
Incidentally, one longer-term solution would be to make it impossible for more than one console to be showing by housing all consoles, both standard Python interpreters and IPython clients, as tabs of the same plugin. Old Spyder was this way. That would eliminate all ambiguity about command direction and require no manual focus setting. I know issue 1053 argues for putting IPython kernels and clients in the same plugin [1], but the more I think about it the kernels are the things that really belong in their own plugin by themselves. Standard Python interpreters and IPython clients seem to be more natural cousins to be housed in the same tab widget given the type of input they receive from the user.

Work for 2.3, right? :-) The two consoles are wildly different right now and joining them won't be easy (if feasible at all).

Yes, I mean for 2.3 or beyond. I'm not recommending it lightly since I recognize it would be a fair amount of work. Rather, I'm suggesting that it's worth considering since it seems more intuitive than forcing kernels and clients into the same plugin (which sounds like a lot of work, too). If we are to adopt a problem that involves a lot of work, we should make sure we adopt the right one.
 
This will likely require a monkey patch to pdb since it's possible to put a console into debug mode from the command line, and the only way for Spyder to find out about that would be if pdb itself did the notifying. That's not really a good option for external kernels since we can't monkey patch pdb in those. I think we can come to a rational console selection method without having to go there.

I think it could be far more easier: add a signal to the Debug action and button that changes the state of a new console attribute called "debugging".


It is possible to catch it there for many use cases, but what happens when, say, you use IPython magic from the command line and manually issue "%run -d script.py". Now Spyder has no idea that debugging is going on in that console. 

Steve

unread,
Feb 14, 2013, 4:24:31 PM2/14/13
to spyd...@googlegroups.com
Hmm.. This conversation may be relevant to my situation.  Debugging integration is broken for me.  I use a console window on my second monitor (regular python, not ipython).  Clicking the icons on the toolbar does nothing as well as my hotkey bindings.  I'm going to try and go back and time and see when it broke.

Steve

unread,
Feb 14, 2013, 4:32:02 PM2/14/13
to spyd...@googlegroups.com
Was running 0de971c2b32dcffbcef1465d612c365b3027838b.  Going back to the tagged v2.2.0beta2 works fine. The merge of the ipython improvements (e6ff60e4db575a0625388d6cb0b8daa7e70ef632) causes the breakage .

Jed Ludlow

unread,
Feb 14, 2013, 5:00:22 PM2/14/13
to spyderlib
On Thu, Feb 14, 2013 at 2:32 PM, Steve <steve.f....@gmail.com> wrote:
Was running 0de971c2b32dcffbcef1465d612c365b3027838b.  Going back to the tagged v2.2.0beta2 works fine. The merge of the ipython improvements (e6ff60e4db575a0625388d6cb0b8daa7e70ef632) causes the breakage .


Hi, Steve. I can't seem to locate the commits you referenced above in the default repository. Which repository are you referencing?

Steve

unread,
Feb 14, 2013, 5:04:17 PM2/14/13
to spyd...@googlegroups.com
Oh. Oops.  Disregard those original commits.  They are from our git mirror of the hg repo.  Updated to reference hg commits below.


On Thursday, February 14, 2013 4:00:22 PM UTC-6, Jed Ludlow wrote:
On Thu, Feb 14, 2013 at 2:32 PM, Steve <steve.f....@gmail.com> wrote:
Was running f28202581fe8.  Going back to the tagged v2.2.0beta2 works fine. The merge of the ipython improvements (c3fc28ffbe77) causes the breakage .

Jed Ludlow

unread,
Feb 14, 2013, 5:27:46 PM2/14/13
to spyderlib
On Thu, Feb 14, 2013 at 3:04 PM, Steve <steve.f....@gmail.com> wrote:
Oh. Oops.  Disregard those original commits.  They are from our git mirror of the hg repo.  Updated to reference hg commits below.

On Thursday, February 14, 2013 4:00:22 PM UTC-6, Jed Ludlow wrote:

On Thu, Feb 14, 2013 at 2:32 PM, Steve <steve.f....@gmail.com> wrote:
Was running f28202581fe8.  Going back to the tagged v2.2.0beta2 works fine. The merge of the ipython improvements (c3fc28ffbe77) causes the breakage .

Ok, Steve, I can reproduce this if an older version of IPython is installed. My bisecting showed the problem showed up at revision 4adf2d0b5594. Can you confirm that this is the commit that breaks things for you? What version of IPython (if any) do you have installed?

Steve

unread,
Feb 14, 2013, 6:20:56 PM2/14/13
to spyd...@googlegroups.com
I don't currently have it installed.

Jed Ludlow

unread,
Feb 14, 2013, 7:38:41 PM2/14/13
to spyderlib
On Thu, Feb 14, 2013 at 4:20 PM, Steve <steve.f....@gmail.com> wrote:

On Thu, Feb 14, 2013 at 2:32 PM, Steve <steve.f....@gmail.com> wrote:
Was running f28202581fe8.  Going back to the tagged v2.2.0beta2 works fine. The merge of the ipython improvements (c3fc28ffbe77) causes the breakage .

Ok, Steve, I can reproduce this if an older version of IPython is installed. My bisecting showed the problem showed up at revision 4adf2d0b5594. Can you confirm that this is the commit that breaks things for you? What version of IPython (if any) do you have installed?

Ok, this should now be fixed by this commit:


Feedback is appreciated!

Steve

unread,
Feb 14, 2013, 8:12:39 PM2/14/13
to spyd...@googlegroups.com
It appears to be working.  I'll hammer on it some more tomorrow.

Steve

unread,
Feb 15, 2013, 4:11:43 PM2/15/13
to spyd...@googlegroups.com
Yeah, things are working great again.  I wanted to try out ipython but I can't find the setting in spyder to use it over the regular console for debugging.  How do I fix it?

Jed Ludlow

unread,
Feb 15, 2013, 5:56:22 PM2/15/13
to spyderlib
On Fri, Feb 15, 2013 at 2:11 PM, Steve <steve.f....@gmail.com> wrote:
Yeah, things are working great again.  I wanted to try out ipython but I can't find the setting in spyder to use it over the regular console for debugging.  How do I fix it?


If you have IPython >13 installed, first open an IPython console in Spyder. For the file you wish to debug, set "Execute in current Python or IPython interpreter" from the run configuration dialog. Make sure the IPython console is visible. Launch the debugger.

Jed Ludlow

unread,
Feb 16, 2013, 2:30:46 PM2/16/13
to spyderlib
On Sun, Feb 10, 2013 at 5:43 AM, Pierre Raybaut <pierre....@gmail.com> wrote:
There is a similar problem with the editor plugin: multiple editor
widgets may be visible at the same time, and it should happen more
often than for consoles. The solution with the editor plugin was to
keep track of the last editor widget which had focus. This widget is
considered as the current active widget (e.g. new files will be opened
in that widget).

So I guess that the same behavior should be expected for consoles:
this is your second solution. However, I'm not sure to understand why
you wrote that it would imply for the user to systematically click on
the console before executing the command: for me, as I understand it,
the user would simply click on the console once, to make it active.

-Pierre

Ok, I have implemented the above described behavior. Instead of using current visibility, Spyder will now send requests to execute code to the last console that had focus. It will also use the same logic to determine where to send debugging control commands. It took a little bit of extra work to get this to behave in a sane way when the Console or the IPython console dockwidgets are floating outside the main window. But I think it is now well behaved. The relevant commit is here:


Code review and testing, as always, is much appreciated.

Jed

Sylvain Corlay

unread,
Feb 16, 2013, 2:47:27 PM2/16/13
to spyd...@googlegroups.com
Hi Jed, It seems that it has broken the "open an ipython console", which does open a new kernel but not the corresponding console. 
Sylvain

Jed Ludlow

unread,
Feb 16, 2013, 2:53:41 PM2/16/13
to spyderlib

That's odd. Which platform? Any trackback?

Sylvain Corlay

unread,
Feb 16, 2013, 4:25:35 PM2/16/13
to spyd...@googlegroups.com

Ubuntu 12.04 64bits.  I will try to get a traceback tonight.

On Feb 16, 2013 2:53 PM, "Jed Ludlow" <jed.l...@gmail.com> wrote:

That's odd. Which platform? Any trackback?

--

Sylvain Corlay

unread,
Feb 16, 2013, 9:33:45 PM2/16/13
to spyd...@googlegroups.com
Apparently, the problem has been present for a week. I can observe this behavior from revision bd449cff6a93. The traceback follows. 
Thanks,

Sylvain

Exception in thread Thread-4:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 504, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/home/sylvain/spyderlib/spyderlib/spyder.py", line 1845, in start_open_files_server
    req, addr = self.open_files_server.accept()
  File "/usr/lib/python2.7/socket.py", line 202, in accept
    sock, addr = self._sock.accept()
error: [Errno 4] Interrupted system call

Exception in thread Thread-3:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
    self.run()
  File "/home/sylvain/spyderlib/spyderlib/widgets/externalshell/introspection.py", line 62, in run
    conn, _addr = sock.accept()
  File "/usr/lib/python2.7/socket.py", line 202, in accept
    sock, addr = self._sock.accept()
error: [Errno 4] Interrupted system call

Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
    self.run()
  File "/home/sylvain/spyderlib/spyderlib/widgets/externalshell/introspection.py", line 62, in run
    conn, _addr = sock.accept()
  File "/usr/lib/python2.7/socket.py", line 202, in accept
    sock, addr = self._sock.accept()
error: [Errno 4] Interrupted system call

On Saturday, February 16, 2013 4:25:35 PM UTC-5, Sylvain Corlay wrote:

Ubuntu 12.04 64bits.  I will try to get a traceback tonight.

Message has been deleted

Sylvain Corlay

unread,
Feb 18, 2013, 4:54:21 PM2/18/13
to spyd...@googlegroups.com
Hi Jed, 

I attached two diff files that solve my issue in the following thread. 


Sylvain
Reply all
Reply to author
Forward
0 new messages