Show More
@@ -0,0 +1,140 b'' | |||
|
1 | #!/usr/bin/env python | |
|
2 | # coding: utf-8 | |
|
3 | """ | |
|
4 | Support for creating GUI apps and starting event loops. | |
|
5 | ||
|
6 | IPython's GUI integration allows interative plotting and GUI usage in IPython | |
|
7 | session. IPython has two different types of GUI integration: | |
|
8 | ||
|
9 | 1. The terminal based IPython supports GUI event loops through Python's | |
|
10 | PyOS_InputHook. PyOS_InputHook is a hook that Python calls periodically | |
|
11 | whenever raw_input is waiting for a user to type code. We implement GUI | |
|
12 | support in the terminal by setting PyOS_InputHook to a function that | |
|
13 | iterates the event loop for a short while. It is important to note that | |
|
14 | in this situation, the real GUI event loop is NOT run in the normal | |
|
15 | manner, so you can't use the normal means to detect that it is running. | |
|
16 | 2. In the two process IPython kernel/frontend, the GUI event loop is run in | |
|
17 | the kernel. In this case, the event loop is run in the normal manner by | |
|
18 | calling the function or method of the GUI toolkit that starts the event | |
|
19 | loop. | |
|
20 | ||
|
21 | In addition to starting the GUI event loops in one of these two ways, IPython | |
|
22 | will *always* create an appropriate GUI application object when GUi | |
|
23 | integration is enabled. | |
|
24 | ||
|
25 | If you want your GUI apps to run in IPython you need to do two things: | |
|
26 | ||
|
27 | 1. Test to see if there is already an existing main application object. If | |
|
28 | there is, you should use it. If there is not an existing application object | |
|
29 | you should create one. | |
|
30 | 2. Test to see if the GUI event loop is running. If it is, you should not | |
|
31 | start it. If the event loop is not running you may start it. | |
|
32 | ||
|
33 | This module contains functions for each toolkit that perform these things | |
|
34 | in a consistent manner. Because of how PyOS_InputHook runs the event loop | |
|
35 | you cannot detect if the event loop is running using the traditional calls | |
|
36 | (such as ``wx.GetApp.IsMainLoopRunning()`` in wxPython). If PyOS_InputHook is | |
|
37 | set These methods will return a false negative. That is, they will say the | |
|
38 | event loop is not running, when is actually is. To work around this limitation | |
|
39 | we proposed the following informal protocol: | |
|
40 | ||
|
41 | * Whenever someone starts the event loop, they *must* set the ``_in_event_loop`` | |
|
42 | attribute of the main application object to ``True``. This should be done | |
|
43 | regardless of how the event loop is actually run. | |
|
44 | * Whenever someone stops the event loop, they *must* set the ``_in_event_loop`` | |
|
45 | attribute of the main application object to ``False``. | |
|
46 | * If you want to see if the event loop is running, you *must* use ``hasattr`` | |
|
47 | to see if ``_in_event_loop`` attribute has been set. If it is set, you | |
|
48 | *must* use its value. If it has not been set, you can query the toolkit | |
|
49 | in the normal manner. | |
|
50 | ||
|
51 | The functions below implement this logic for each GUI toolkit. If you need | |
|
52 | to create custom application subclasses, you will likely have to modify this | |
|
53 | code for your own purposes. This code can be copied into your own project | |
|
54 | so you don't have to depend on IPython. | |
|
55 | ||
|
56 | """ | |
|
57 | ||
|
58 | #----------------------------------------------------------------------------- | |
|
59 | # Copyright (C) 2008-2010 The IPython Development Team | |
|
60 | # | |
|
61 | # Distributed under the terms of the BSD License. The full license is in | |
|
62 | # the file COPYING, distributed as part of this software. | |
|
63 | #----------------------------------------------------------------------------- | |
|
64 | ||
|
65 | #----------------------------------------------------------------------------- | |
|
66 | # Imports | |
|
67 | #----------------------------------------------------------------------------- | |
|
68 | ||
|
69 | #----------------------------------------------------------------------------- | |
|
70 | # wx | |
|
71 | #----------------------------------------------------------------------------- | |
|
72 | ||
|
73 | def get_app_wx(*args, **kwargs): | |
|
74 | """Create a new wx app or return an exiting one.""" | |
|
75 | import wx | |
|
76 | app = wx.GetApp() | |
|
77 | if app is None: | |
|
78 | app = wx.PySimpleApp(*args, **kwargs) | |
|
79 | return app | |
|
80 | ||
|
81 | def is_event_loop_running_wx(app=None): | |
|
82 | """Is the wx event loop running.""" | |
|
83 | if app is None: | |
|
84 | app = get_app_wx() | |
|
85 | if hasattr(app, '_in_event_loop'): | |
|
86 | return app._in_event_loop | |
|
87 | else: | |
|
88 | return app.IsMainLoopRunning() | |
|
89 | ||
|
90 | def start_event_loop_wx(app=None): | |
|
91 | """Start the wx event loop in a consistent manner.""" | |
|
92 | if app is None: | |
|
93 | app = get_app_wx() | |
|
94 | if not is_event_loop_running_wx(app): | |
|
95 | app._in_event_loop = True | |
|
96 | app.MainLoop() | |
|
97 | app._in_event_loop = False | |
|
98 | else: | |
|
99 | app._in_event_loop = True | |
|
100 | ||
|
101 | #----------------------------------------------------------------------------- | |
|
102 | # qt4 | |
|
103 | #----------------------------------------------------------------------------- | |
|
104 | ||
|
105 | def get_app_qt4(*args, **kwargs): | |
|
106 | """Create a new qt4 app or return an existing one.""" | |
|
107 | from PyQt4 import QtGui | |
|
108 | app = QtGui.QApplication.instance() | |
|
109 | if app is None: | |
|
110 | app = QtGui.QApplication(*args, **kwargs) | |
|
111 | return app | |
|
112 | ||
|
113 | def is_event_loop_running_qt4(app=None): | |
|
114 | """Is the qt4 event loop running.""" | |
|
115 | if app is None: | |
|
116 | app = get_app_qt4() | |
|
117 | if hasattr(app, '_in_event_loop'): | |
|
118 | return app._in_event_loop | |
|
119 | else: | |
|
120 | # Does qt4 provide a other way to detect this? | |
|
121 | return False | |
|
122 | ||
|
123 | def start_event_loop_qt4(app=None): | |
|
124 | """Start the qt4 event loop in a consistent manner.""" | |
|
125 | if app is None: | |
|
126 | app = get_app_qt4() | |
|
127 | if not is_event_loop_running_qt4(app): | |
|
128 | app._in_event_loop = True | |
|
129 | app.exec_() | |
|
130 | app._in_event_loop = False | |
|
131 | else: | |
|
132 | app._in_event_loop = True | |
|
133 | ||
|
134 | #----------------------------------------------------------------------------- | |
|
135 | # Tk | |
|
136 | #----------------------------------------------------------------------------- | |
|
137 | ||
|
138 | #----------------------------------------------------------------------------- | |
|
139 | # gtk | |
|
140 | #----------------------------------------------------------------------------- |
@@ -1,3 +1,9 b'' | |||
|
1 | """Produce SVG versions of active plots for display by the rich Qt frontend. | |
|
2 | """ | |
|
3 | #----------------------------------------------------------------------------- | |
|
4 | # Imports | |
|
5 | #----------------------------------------------------------------------------- | |
|
6 | ||
|
1 | 7 | # Standard library imports |
|
2 | 8 | from cStringIO import StringIO |
|
3 | 9 | |
@@ -8,12 +14,14 b' from matplotlib._pylab_helpers import Gcf' | |||
|
8 | 14 | # Local imports. |
|
9 | 15 | from backend_payload import add_plot_payload |
|
10 | 16 | |
|
17 | #----------------------------------------------------------------------------- | |
|
18 | # Functions | |
|
19 | #----------------------------------------------------------------------------- | |
|
11 | 20 | |
|
12 | 21 | def show(): |
|
13 | 22 | """ Deliver a SVG payload. |
|
14 | 23 | """ |
|
15 |
figure_manager |
|
|
16 | if figure_manager is not None: | |
|
24 | for figure_manager in Gcf.get_all_fig_managers(): | |
|
17 | 25 | # Make the background transparent. |
|
18 | 26 | # figure_manager.canvas.figure.patch.set_alpha(0.0) |
|
19 | 27 | # Set the background to white instead so it looks good on black. |
@@ -22,6 +30,7 b' def show():' | |||
|
22 | 30 | data = svg_from_canvas(figure_manager.canvas) |
|
23 | 31 | add_plot_payload('svg', data) |
|
24 | 32 | |
|
33 | ||
|
25 | 34 | def svg_from_canvas(canvas): |
|
26 | 35 | """ Return a string containing the SVG representation of a FigureCanvasSvg. |
|
27 | 36 | """ |
@@ -1,8 +1,29 b'' | |||
|
1 | """A ZMQ-based subclass of InteractiveShell. | |
|
2 | ||
|
3 | This code is meant to ease the refactoring of the base InteractiveShell into | |
|
4 | something with a cleaner architecture for 2-process use, without actually | |
|
5 | breaking InteractiveShell itself. So we're doing something a bit ugly, where | |
|
6 | we subclass and override what we want to fix. Once this is working well, we | |
|
7 | can go back to the base class and refactor the code for a cleaner inheritance | |
|
8 | implementation that doesn't rely on so much monkeypatching. | |
|
9 | ||
|
10 | But this lets us maintain a fully working IPython as we develop the new | |
|
11 | machinery. This should thus be thought of as scaffolding. | |
|
12 | """ | |
|
13 | #----------------------------------------------------------------------------- | |
|
14 | # Imports | |
|
15 | #----------------------------------------------------------------------------- | |
|
16 | from __future__ import print_function | |
|
17 | ||
|
18 | # Stdlib | |
|
1 | 19 | import inspect |
|
20 | import os | |
|
2 | 21 | import re |
|
3 | 22 | import sys |
|
23 | ||
|
4 | 24 | from subprocess import Popen, PIPE |
|
5 | 25 | |
|
26 | # Our own | |
|
6 | 27 | from IPython.core.interactiveshell import ( |
|
7 | 28 | InteractiveShell, InteractiveShellABC |
|
8 | 29 | ) |
@@ -16,9 +37,16 b' from IPython.zmq.session import extract_header' | |||
|
16 | 37 | from IPython.core.payloadpage import install_payload_page |
|
17 | 38 | from session import Session |
|
18 | 39 | |
|
40 | #----------------------------------------------------------------------------- | |
|
41 | # Globals and side-effects | |
|
42 | #----------------------------------------------------------------------------- | |
|
43 | ||
|
19 | 44 | # Install the payload version of page. |
|
20 | 45 | install_payload_page() |
|
21 | 46 | |
|
47 | #----------------------------------------------------------------------------- | |
|
48 | # Functions and classes | |
|
49 | #----------------------------------------------------------------------------- | |
|
22 | 50 | |
|
23 | 51 | class ZMQDisplayHook(DisplayHook): |
|
24 | 52 | |
@@ -56,16 +84,23 b' class ZMQInteractiveShell(InteractiveShell):' | |||
|
56 | 84 | displayhook_class = Type(ZMQDisplayHook) |
|
57 | 85 | |
|
58 | 86 | def system(self, cmd): |
|
59 | cmd = self.var_expand(cmd, depth=2) | |
|
87 | cmd = self.var_expand(cmd, depth=2).strip() | |
|
88 | ||
|
89 | # Runnning a bacgkrounded process from within the gui isn't supported | |
|
90 | # because we do p.wait() at the end. So instead of silently blocking | |
|
91 | # we simply refuse to run in this mode, to avoid surprising the user. | |
|
92 | if cmd.endswith('&'): | |
|
93 | raise OSError("Background processes not supported.") | |
|
94 | ||
|
60 | 95 | sys.stdout.flush() |
|
61 | 96 | sys.stderr.flush() |
|
62 | 97 | p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE) |
|
63 | 98 | for line in p.stdout.read().split('\n'): |
|
64 | 99 | if len(line) > 0: |
|
65 |
print |
|
|
100 | print(line) | |
|
66 | 101 | for line in p.stderr.read().split('\n'): |
|
67 | 102 | if len(line) > 0: |
|
68 |
print |
|
|
103 | print(line, file=sys.stderr) | |
|
69 | 104 | p.wait() |
|
70 | 105 | |
|
71 | 106 | def init_io(self): |
@@ -349,7 +384,11 b' class ZMQInteractiveShell(InteractiveShell):' | |||
|
349 | 384 | |
|
350 | 385 | if use_temp: |
|
351 | 386 | filename = self.shell.mktempfile(data) |
|
352 |
print |
|
|
387 | print('IPython will make a temporary file named:', filename) | |
|
388 | ||
|
389 | # Make sure we send to the client an absolute path, in case the working | |
|
390 | # directory of client and kernel don't match | |
|
391 | filename = os.path.abspath(filename) | |
|
353 | 392 | |
|
354 | 393 | payload = { |
|
355 | 394 | 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic', |
@@ -101,4 +101,4 b' gitwash-update:' | |||
|
101 | 101 | cd source/development/gitwash && rename 's/.rst/.txt/' *.rst |
|
102 | 102 | |
|
103 | 103 | nightly: dist |
|
104 | rsync -avH --delete dist/ ipython:www/doc/nightly No newline at end of file | |
|
104 | rsync -avH --delete dist/ ipython:www/doc/nightly |
@@ -130,15 +130,9 b' Messages on the XREP/XREQ socket' | |||
|
130 | 130 | Execute |
|
131 | 131 | ------- |
|
132 | 132 | |
|
133 | The execution request contains a single string, but this may be a multiline | |
|
134 | string. The kernel is responsible for splitting this into possibly more than | |
|
135 | one block and deciding whether to compile these in 'single' or 'exec' mode. | |
|
136 | We're still sorting out this policy. The current inputsplitter is capable of | |
|
137 | splitting the input for blocks that can all be run as 'single', but in the long | |
|
138 | run it may prove cleaner to only use 'single' mode for truly single-line | |
|
139 | inputs, and run all multiline input in 'exec' mode. This would preserve the | |
|
140 | natural behavior of single-line inputs while allowing long cells to behave more | |
|
141 | likea a script. This design will be refined as we complete the implementation. | |
|
133 | This message type is used by frontends to ask the kernel to execute code on | |
|
134 | behalf of the user, in a namespace reserved to the user's variables (and thus | |
|
135 | separate from the kernel's own internal code and variables). | |
|
142 | 136 | |
|
143 | 137 | Message type: ``execute_request``:: |
|
144 | 138 | |
@@ -148,17 +142,94 b' Message type: ``execute_request``::' | |||
|
148 | 142 | |
|
149 | 143 | # A boolean flag which, if True, signals the kernel to execute this |
|
150 | 144 | # code as quietly as possible. This means that the kernel will compile |
|
151 |
# the code with 'exec' instead of 'single' (so |
|
|
152 | # fire), and will *not*: | |
|
145 | # the code witIPython/core/tests/h 'exec' instead of 'single' (so | |
|
146 | # sys.displayhook will not fire), and will *not*: | |
|
153 | 147 | # - broadcast exceptions on the PUB socket |
|
154 | 148 | # - do any logging |
|
155 | 149 | # - populate any history |
|
150 | # | |
|
156 | 151 | # The default is False. |
|
157 | 152 | 'silent' : bool, |
|
153 | ||
|
154 | # A list of variable names from the user's namespace to be retrieved. What | |
|
155 | # returns is a JSON string of the variable's repr(), not a python object. | |
|
156 | 'user_variables' : list, | |
|
157 | ||
|
158 | # Similarly, a dict mapping names to expressions to be evaluated in the | |
|
159 | # user's dict. | |
|
160 | 'user_expressions' : dict, | |
|
158 | 161 | } |
|
159 | 162 | |
|
160 | Upon execution, the kernel *always* sends a reply, with a status code | |
|
161 | indicating what happened and additional data depending on the outcome. | |
|
163 | The ``code`` field contains a single string, but this may be a multiline | |
|
164 | string. The kernel is responsible for splitting this into possibly more than | |
|
165 | one block and deciding whether to compile these in 'single' or 'exec' mode. | |
|
166 | We're still sorting out this policy. The current inputsplitter is capable of | |
|
167 | splitting the input for blocks that can all be run as 'single', but in the long | |
|
168 | run it may prove cleaner to only use 'single' mode for truly single-line | |
|
169 | inputs, and run all multiline input in 'exec' mode. This would preserve the | |
|
170 | natural behavior of single-line inputs while allowing long cells to behave more | |
|
171 | likea a script. This design will be refined as we complete the implementation. | |
|
172 | ||
|
173 | The ``user_`` fields deserve a detailed explanation. In the past, IPython had | |
|
174 | the notion of a prompt string that allowed arbitrary code to be evaluated, and | |
|
175 | this was put to good use by many in creating prompts that displayed system | |
|
176 | status, path information, and even more esoteric uses like remote instrument | |
|
177 | status aqcuired over the network. But now that IPython has a clean separation | |
|
178 | between the kernel and the clients, the notion of embedding 'prompt' | |
|
179 | maninpulations into the kernel itself feels awkward. Prompts should be a | |
|
180 | frontend-side feature, and it should be even possible for different frontends | |
|
181 | to display different prompts while interacting with the same kernel. | |
|
182 | ||
|
183 | We have therefore abandoned the idea of a 'prompt string' to be evaluated by | |
|
184 | the kernel, and instead provide the ability to retrieve from the user's | |
|
185 | namespace information after the execution of the main ``code``, with two fields | |
|
186 | of the execution request: | |
|
187 | ||
|
188 | - ``user_variables``: If only variables from the user's namespace are needed, a | |
|
189 | list of variable names can be passed and a dict with these names as keys and | |
|
190 | their :func:`repr()` as values will be returned. | |
|
191 | ||
|
192 | - ``user_expressions``: For more complex expressions that require function | |
|
193 | evaluations, a dict can be provided with string keys and arbitrary python | |
|
194 | expressions as values. The return message will contain also a dict with the | |
|
195 | same keys and the :func:`repr()` of the evaluated expressions as value. | |
|
196 | ||
|
197 | With this information, frontends can display any status information they wish | |
|
198 | in the form that best suits each frontend (a status line, a popup, inline for a | |
|
199 | terminal, etc). | |
|
200 | ||
|
201 | .. Note:: | |
|
202 | ||
|
203 | In order to obtain the current execution counter for the purposes of | |
|
204 | displaying input prompts, frontends simply make an execution request with an | |
|
205 | empty code string and ``silent=True``. | |
|
206 | ||
|
207 | Execution semantics | |
|
208 | Upon completion of the execution request, the kernel *always* sends a | |
|
209 | reply, with a status code indicating what happened and additional data | |
|
210 | depending on the outcome. | |
|
211 | ||
|
212 | The ``code`` field is executed first, and then the ``user_variables`` and | |
|
213 | ``user_expressions`` are computed. This ensures that any error in the | |
|
214 | latter don't harm the main code execution. | |
|
215 | ||
|
216 | Any error in retrieving the ``user_variables`` or evaluating the | |
|
217 | ``user_expressions`` will result in a simple error message in the return | |
|
218 | fields of the form:: | |
|
219 | ||
|
220 | [ERROR] ExceptionType: Exception message | |
|
221 | ||
|
222 | The user can simply send the same variable name or expression for | |
|
223 | evaluation to see a regular traceback. | |
|
224 | ||
|
225 | Execution counter (old prompt number) | |
|
226 | The kernel has a single, monotonically increasing counter of all execution | |
|
227 | requests that are made with ``silent=False``. This counter is used to | |
|
228 | populate the ``In[n]``, ``Out[n]`` and ``_n`` variables, so clients will | |
|
229 | likely want to display it in some form to the user, which will typically | |
|
230 | (but not necessarily) be done in the prompts. The value of this counter | |
|
231 | will be returned as the ``execution_count`` field of all ``execute_reply``` | |
|
232 | messages. | |
|
162 | 233 | |
|
163 | 234 | Message type: ``execute_reply``:: |
|
164 | 235 | |
@@ -166,30 +237,25 b' Message type: ``execute_reply``::' | |||
|
166 | 237 | # One of: 'ok' OR 'error' OR 'abort' |
|
167 | 238 | 'status' : str, |
|
168 | 239 | |
|
169 | # This has the same structure as the output of a prompt request, but is | |
|
170 | # for the client to set up the *next* prompt (with identical limitations | |
|
171 | # to a prompt request) | |
|
172 | 'next_prompt' : { | |
|
173 | 'prompt_string' : str, | |
|
174 | 'prompt_number' : int, | |
|
175 | 'input_sep' : str | |
|
176 | }, | |
|
177 | ||
|
178 | # The prompt number of the actual execution for this code, which may be | |
|
179 | # different from the one used when the code was typed, which was the | |
|
180 | # 'next_prompt' field of the *previous* request. They will differ in the | |
|
181 | # case where there is more than one client talking simultaneously to a | |
|
182 | # kernel, since the numbers can go out of sync. GUI clients can use this | |
|
183 | # to correct the previously written number in-place, terminal ones may | |
|
184 | # re-print a corrected one if desired. | |
|
185 | 'prompt_number' : int, | |
|
240 | # The global kernel counter that increases by one with each non-silent | |
|
241 | # executed request. This will typically be used by clients to display | |
|
242 | # prompt numbers to the user. If the request was a silent one, this will | |
|
243 | # be the current value of the counter in the kernel. | |
|
244 | 'execution_count' : int, | |
|
245 | ||
|
246 | # If the state_template was provided, this will contain the evaluated | |
|
247 | # form of the template. | |
|
248 | 'state' : str, | |
|
186 | 249 | } |
|
187 | 250 | |
|
188 | 251 | When status is 'ok', the following extra fields are present:: |
|
189 | 252 | |
|
190 | 253 | { |
|
191 |
# The kernel will often transform the input provided to it. |
|
|
192 | # contains the transformed code, which is what was actually executed. | |
|
254 | # The kernel will often transform the input provided to it. If the | |
|
255 | # '---->' transform had been applied, this is filled, otherwise it's the | |
|
256 | # empty string. So transformations like magics don't appear here, only | |
|
257 | # autocall ones. | |
|
258 | ||
|
193 | 259 | 'transformed_code' : str, |
|
194 | 260 | |
|
195 | 261 | # The execution payload is a dict with string keys that may have been |
@@ -235,31 +301,65 b" When status is 'error', the following extra fields are present::" | |||
|
235 | 301 | When status is 'abort', there are for now no additional data fields. This |
|
236 | 302 | happens when the kernel was interrupted by a signal. |
|
237 | 303 | |
|
304 | Kernel attribute access | |
|
305 | ----------------------- | |
|
238 | 306 | |
|
239 | Prompt | |
|
240 | ------ | |
|
307 | While this protocol does not specify full RPC access to arbitrary methods of | |
|
308 | the kernel object, the kernel does allow read (and in some cases write) access | |
|
309 | to certain attributes. | |
|
241 | 310 | |
|
242 | A simple request for a current prompt string. | |
|
311 | The policy for which attributes can be read is: any attribute of the kernel, or | |
|
312 | its sub-objects, that belongs to a :class:`Configurable` object and has been | |
|
313 | declared at the class-level with Traits validation, is in principle accessible | |
|
314 | as long as its name does not begin with a leading underscore. The attribute | |
|
315 | itself will have metadata indicating whether it allows remote read and/or write | |
|
316 | access. The message spec follows for attribute read and write requests. | |
|
243 | 317 | |
|
244 |
Message type: `` |
|
|
318 | Message type: ``getattr_request``:: | |
|
245 | 319 | |
|
246 |
content = { |
|
|
320 | content = { | |
|
321 | # The (possibly dotted) name of the attribute | |
|
322 | 'name' : str, | |
|
323 | } | |
|
324 | ||
|
325 | When a ``getattr_request`` fails, there are two possible error types: | |
|
326 | ||
|
327 | - AttributeError: this type of error was raised when trying to access the | |
|
328 | given name by the kernel itself. This means that the attribute likely | |
|
329 | doesn't exist. | |
|
330 | ||
|
331 | - AccessError: the attribute exists but its value is not readable remotely. | |
|
247 | 332 | |
|
248 | In the reply, the prompt string comes back with the prompt number placeholder | |
|
249 | *unevaluated*. The message format is: | |
|
250 | ||
|
251 | Message type: ``prompt_reply``:: | |
|
333 | ||
|
334 | Message type: ``getattr_reply``:: | |
|
335 | ||
|
336 | content = { | |
|
337 | # One of ['ok', 'AttributeError', 'AccessError']. | |
|
338 | 'status' : str, | |
|
339 | # If status is 'ok', a JSON object. | |
|
340 | 'value' : object, | |
|
341 | } | |
|
342 | ||
|
343 | Message type: ``setattr_request``:: | |
|
252 | 344 | |
|
253 | 345 | content = { |
|
254 | 'prompt_string' : str, | |
|
255 | 'prompt_number' : int, | |
|
256 | 'input_sep' : str | |
|
346 | # The (possibly dotted) name of the attribute | |
|
347 | 'name' : str, | |
|
348 | ||
|
349 | # A JSON-encoded object, that will be validated by the Traits | |
|
350 | # information in the kernel | |
|
351 | 'value' : object, | |
|
257 | 352 | } |
|
258 | 353 | |
|
259 | Clients can produce a prompt with ``prompt_string.format(prompt_number)``, but | |
|
260 | they should be aware that the actual prompt number for that input could change | |
|
261 | later, in the case where multiple clients are interacting with a single | |
|
262 | kernel. | |
|
354 | When a ``setattr_request`` fails, there are also two possible error types with | |
|
355 | similar meanings as those of the ``getattr_request`` case, but for writing. | |
|
356 | ||
|
357 | Message type: ``setattr_reply``:: | |
|
358 | ||
|
359 | content = { | |
|
360 | # One of ['ok', 'AttributeError', 'AccessError']. | |
|
361 | 'status' : str, | |
|
362 | } | |
|
263 | 363 | |
|
264 | 364 | |
|
265 | 365 | Object information |
@@ -276,12 +376,12 b' Message type: ``object_info_request``::' | |||
|
276 | 376 | |
|
277 | 377 | content = { |
|
278 | 378 | # The (possibly dotted) name of the object to be searched in all |
|
279 |
|
|
|
280 | 'name' : str, | |
|
379 | # relevant namespaces | |
|
380 | 'name' : str, | |
|
281 | 381 | |
|
282 | # The level of detail desired. The default (0) is equivalent to typing | |
|
283 |
|
|
|
284 |
|
|
|
382 | # The level of detail desired. The default (0) is equivalent to typing | |
|
383 | # 'x?' at the prompt, 1 is equivalent to 'x??'. | |
|
384 | 'detail_level' : int, | |
|
285 | 385 | } |
|
286 | 386 | |
|
287 | 387 | The returned information will be a dictionary with keys very similar to the |
@@ -315,9 +415,29 b' Message type: ``object_info_reply``::' | |||
|
315 | 415 | 'file' : str, |
|
316 | 416 | |
|
317 | 417 | # For pure Python callable objects, we can reconstruct the object |
|
318 | # definition line which provides its call signature | |
|
418 | # definition line which provides its call signature. For convenience this | |
|
419 | # is returned as a single 'definition' field, but below the raw parts that | |
|
420 | # compose it are also returned as the argspec field. | |
|
319 | 421 | 'definition' : str, |
|
320 | 422 | |
|
423 | # The individual parts that together form the definition string. Clients | |
|
424 | # with rich display capabilities may use this to provide a richer and more | |
|
425 | # precise representation of the definition line (e.g. by highlighting | |
|
426 | # arguments based on the user's cursor position). For non-callable | |
|
427 | # objects, this field is empty. | |
|
428 | 'argspec' : { # The names of all the arguments | |
|
429 | args : list, | |
|
430 | # The name of the varargs (*args), if any | |
|
431 | varargs : str, | |
|
432 | # The name of the varkw (**kw), if any | |
|
433 | varkw : str, | |
|
434 | # The values (as strings) of all default arguments. Note | |
|
435 | # that these must be matched *in reverse* with the 'args' | |
|
436 | # list above, since the first positional args have no default | |
|
437 | # value at all. | |
|
438 | func_defaults : list, | |
|
439 | }, | |
|
440 | ||
|
321 | 441 | # For instances, provide the constructor signature (the definition of |
|
322 | 442 | # the __init__ method): |
|
323 | 443 | 'init_definition' : str, |
@@ -406,6 +526,7 b' Message type: ``history_reply``::' | |||
|
406 | 526 | # respectively. |
|
407 | 527 | 'history' : dict, |
|
408 | 528 | } |
|
529 | ||
|
409 | 530 | Messages on the PUB/SUB socket |
|
410 | 531 | ============================== |
|
411 | 532 | |
@@ -458,10 +579,10 b' Message type: ``pyout``::' | |||
|
458 | 579 | # The data is typically the repr() of the object. |
|
459 | 580 | 'data' : str, |
|
460 | 581 | |
|
461 |
# The |
|
|
462 |
# |
|
|
463 |
# |
|
|
464 | 'prompt_number' : int, | |
|
582 | # The counter for this execution is also provided so that clients can | |
|
583 | # display it, since IPython automatically creates variables called _N (for | |
|
584 | # prompt N). | |
|
585 | 'execution_count' : int, | |
|
465 | 586 | } |
|
466 | 587 | |
|
467 | 588 | Python errors |
General Comments 0
You need to be logged in to leave comments.
Login now