##// END OF EJS Templates
Handle kernel messages synchronously...
Handle kernel messages synchronously A problem can happen when two messages come in for different comms, where the second depends on the first (for example, the first might be a message setting the state of a widget, and the second triggering a view creation for the widget). Since comm message queues are independent of each other, the second message could be executed before the first message. This exposes a more fundamental assumption users are likely to have that messages from python are processed synchronously. Thanks to @dmadeka for reporting an error that led to discovering this issue.

File last commit:

r16815:a2ad9393
r20621:f936f880
Show More
execution.rst
64 lines | 2.3 KiB | text/x-rst | RstLexer

Execution semantics in the IPython kernel

The execution of use code consists of the following phases:

  1. Fire the pre_execute event.
  2. Fire the pre_run_cell event unless silent is True.
  3. Execute the code field, 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.

To understand how the code field is executed, one must know that Python code can be compiled in one of three modes (controlled by the mode argument to the :func:`compile` builtin):

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 one 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 one 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 one is also multiline), run all in 'exec' mode as a single unit.