<type>documentation</type>
<domain>intro</domain>
<id>tutorial-debugging-shell</id>
<title>Tutorial: Debugging from the Python Shell</title>
<date>$Date$</date>
<product>all</product>

In addition to launching code to debug from Wing's menu bar and ``Debug`` menu, it is also
possible to debug code that is entered into the
~~~if not WINGPRO:
``Python Shell``.
~~~
~~~if WINGPRO:
``Python Shell`` and ``Debug Console``.
~~~

Enable this now by clicking on the bug icon in the top right of the `Python Shell
<script:show-panel-python-shell>`__. Once this is done, the status message at the top of
the ``Python Shell`` should change to include ``Commands will be debugged`` and an extra
margin is shown in which you can set breakpoints. Wing will reach those breakpoints, as
well as any breakpoints in editors for code that is invoked. Any exceptions will be
reported in the debugger.

Let's try this out.  First stop any running debug process with the |stop| ``Stop``
icon in the toolbar.  Then paste the following into the ``Python Shell`` and press ``Enter``
so that you are returned to the ``>>>`` prompt:

.. python::

  def test_function():
    x = 10
    print(x)
    x += 5
    y = 20
    print(x+y)

.. |stop| image:: icon:wingide-debug-kill
  :class: inline-image
  
Next place a breakpoint on the line that reads ``print(x)`` by clicking in the breakpoint
margin to the left of the prompt on that line.

Then type this into the ``Python Shell`` and press ``Enter``:

.. python::

  test_function()

Wing should reach the breakpoint on ``print(x)``.

You can now work with the debugger in the same way that you would if you had launched
code from the toolbar or ``Debug`` menu.  Try stepping and viewing the values of ``x``
and ``y`` as they change, either in the ``Stack Data`` tool or by hovering the mouse over 
the variable names.  

Take a look at the stack in the ``Call Stack`` or ``Stack Data`` tool to see how stack
frames that occur within the ``Python Shell`` are listed. You can move up and down the
stack just as you would if your stack frames were in an editor.

Notice that if you step off the end of the call, you will return to the shell prompt. If
you press the |stop| ``Stop`` item in the toolbar or select ``Stop Debugging`` from the
``Debug`` menu, Wing will complete execution of the code without debug and return you to
the ``>>>`` prompt. Note that the code is still executed to completion in this case
becaused there is no way to simply abandon a number of stack frames in the Python
interpreter.

~~~if WINGPRO:
**Recursive Debugging**

By default Wing will not return you to the ``>>>`` prompt until your code has finished
executing. In Wing Pro, it is possible to enable recursive debugging. This is disabled by
default because it can be confusing for users that don't understand it.

To try this out, check the ``Enable Recursive Debug`` item in the ``Options`` menu in the
`Python Shell <script:show-panel-python-shell>`__. Then type ``test_function()`` again in
the ``Python Shell``, or use the up arrow to retrieve it from command history.

You will see that the shell returns immediately to the ``>>>`` prompt even though you are
now at the breakpoint you set earlier on ``print(x)``. The message area in the ``Python
Shell`` indicates that you are debugging recursively and gives you the level to which you
have recursed. For example ``Debugging recursively (R=2)`` indicates two levels of
recursive debugging.

Now enter ``test_function()`` again and then press ``Enter``. This is essentially the same
thing as invoking ``test_function()`` from the line at which the debugger is currently
paused, in this case within ``test_function`` itself.

Try doing this several times. Each time, another level of recursive debugging will be
entered. Look at the ``Call Stack`` tool and go up and down the stack to better understand
what is happening.

Now if you press |continue| ``Continue`` in the toolbar or use ``Start / Continue`` in the
``Debug`` menu you will exit one level of recursion. Similarly, ``Stop`` exits one level
of recursion without debugging the remainder of that recursive invocation.

.. |continue| image:: icon:wingide-debug-continue
  :class: inline-image
~~~

See `Debugging Code in the Python Shell <ref:debug/shell-debugging>`__ for details.
