.. _execution_semantics:

Execution of cells in the IPython kernel
========================================

When IPython kernel receives `execute_request <https://jupyter-client.readthedocs.io/en/latest/messaging.html#execute>`_
with user code, it processes the message in the following phases:

1. Fire the ``pre_execute`` event.
2. Fire the ``pre_run_cell`` event unless silent is ``True``.
3. Execute ``run_cell`` method to preprocess ``code``, compile and run it, see below for details.
4. If execution succeeds, expressions in ``user_expressions`` are computed.
   This ensures that any error in the expressions don't affect the main code execution.
5. Fire the ``post_execute`` event.
6. Fire the ``post_run_cell`` event unless silent is ``True``.

.. seealso::

    :doc:`/config/callbacks`


Running user ``code``
=====================

First, the ``code`` cell is transformed to expand ``%magic`` and ``!system``
commands by ``IPython.core.inputtransformer2``. Then expanded cell is compiled
using standard Python :func:`compile` function and executed.

Python :func:`compile` function provides ``mode`` argument to select one
of three ways of compiling code:

*single*
  Valid for a single interactive statement (though the source can contain
  multiple lines, such as a for loop).  When compiled in this mode, the
  generated bytecode contains special instructions that trigger the calling of
  :func:`sys.displayhook` for any expression in the block that returns a value.
  This means that a single statement can actually produce multiple calls to
  :func:`sys.displayhook`, if for example it contains a loop where each
  iteration computes an unassigned expression would generate 10 calls::

      for i in range(10):
          i**2

*exec*
  An arbitrary amount of source code, this is how modules are compiled.
  :func:`sys.displayhook` is *never* implicitly called.

*eval*
  A single expression that returns a value.  :func:`sys.displayhook` is *never*
  implicitly called.


The ``code`` field is split into individual blocks each of which is valid for
execution in 'single' mode, and then:

- If there is only a single block: it is executed in 'single' mode.

- If there is more than one block:

  * if the last block is a single line long, run all but the last in 'exec' mode
    and the very last one in 'single' mode.  This makes it easy to type simple
    expressions at the end to see computed values.

  * if the last block is no more than two lines long, run all but the last in
    'exec' mode and the very last one in 'single' mode.  This makes it easy to
    type simple expressions at the end to see computed values.  - otherwise
    (last one is also multiline), run all in 'exec' mode

  * otherwise (last block is also multiline), run all in 'exec' mode as a single
    unit.


