##// END OF EJS Templates
Merge with upstream/
gvaroquaux -
r1731:adf0e9f0 merge
parent child Browse files
Show More
@@ -0,0 +1,155 b''
1 # encoding: utf-8
2
3 """This file contains unittests for the frontendbase module."""
4
5 __docformat__ = "restructuredtext en"
6
7 #---------------------------------------------------------------------------
8 # Copyright (C) 2008 The IPython Development Team
9 #
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
12 #---------------------------------------------------------------------------
13
14 #---------------------------------------------------------------------------
15 # Imports
16 #---------------------------------------------------------------------------
17
18 import unittest
19
20 try:
21 from IPython.frontend.asyncfrontendbase import AsyncFrontEndBase
22 from IPython.frontend import frontendbase
23 from IPython.kernel.engineservice import EngineService
24 except ImportError:
25 import nose
26 raise nose.SkipTest("This test requires zope.interface, Twisted and Foolscap")
27
28 from IPython.testing.decorators import skip
29
30 class FrontEndCallbackChecker(AsyncFrontEndBase):
31 """FrontEndBase subclass for checking callbacks"""
32 def __init__(self, engine=None, history=None):
33 super(FrontEndCallbackChecker, self).__init__(engine=engine,
34 history=history)
35 self.updateCalled = False
36 self.renderResultCalled = False
37 self.renderErrorCalled = False
38
39 def update_cell_prompt(self, result, blockID=None):
40 self.updateCalled = True
41 return result
42
43 def render_result(self, result):
44 self.renderResultCalled = True
45 return result
46
47
48 def render_error(self, failure):
49 self.renderErrorCalled = True
50 return failure
51
52
53
54
55 class TestAsyncFrontendBase(unittest.TestCase):
56 def setUp(self):
57 """Setup the EngineService and FrontEndBase"""
58
59 self.fb = FrontEndCallbackChecker(engine=EngineService())
60
61 def test_implements_IFrontEnd(self):
62 assert(frontendbase.IFrontEnd.implementedBy(
63 AsyncFrontEndBase))
64
65 def test_is_complete_returns_False_for_incomplete_block(self):
66 """"""
67
68 block = """def test(a):"""
69
70 assert(self.fb.is_complete(block) == False)
71
72 def test_is_complete_returns_True_for_complete_block(self):
73 """"""
74
75 block = """def test(a): pass"""
76
77 assert(self.fb.is_complete(block))
78
79 block = """a=3"""
80
81 assert(self.fb.is_complete(block))
82
83 def test_blockID_added_to_result(self):
84 block = """3+3"""
85
86 d = self.fb.execute(block, blockID='TEST_ID')
87
88 d.addCallback(self.checkBlockID, expected='TEST_ID')
89
90 def test_blockID_added_to_failure(self):
91 block = "raise Exception()"
92
93 d = self.fb.execute(block,blockID='TEST_ID')
94 d.addErrback(self.checkFailureID, expected='TEST_ID')
95
96 def checkBlockID(self, result, expected=""):
97 assert(result['blockID'] == expected)
98
99
100 def checkFailureID(self, failure, expected=""):
101 assert(failure.blockID == expected)
102
103
104 def test_callbacks_added_to_execute(self):
105 """test that
106 update_cell_prompt
107 render_result
108
109 are added to execute request
110 """
111
112 d = self.fb.execute("10+10")
113 d.addCallback(self.checkCallbacks)
114
115 def checkCallbacks(self, result):
116 assert(self.fb.updateCalled)
117 assert(self.fb.renderResultCalled)
118
119 @skip("This test fails and lead to an unhandled error in a Deferred.")
120 def test_error_callback_added_to_execute(self):
121 """test that render_error called on execution error"""
122
123 d = self.fb.execute("raise Exception()")
124 d.addCallback(self.checkRenderError)
125
126 def checkRenderError(self, result):
127 assert(self.fb.renderErrorCalled)
128
129 def test_history_returns_expected_block(self):
130 """Make sure history browsing doesn't fail"""
131
132 blocks = ["a=1","a=2","a=3"]
133 for b in blocks:
134 d = self.fb.execute(b)
135
136 # d is now the deferred for the last executed block
137 d.addCallback(self.historyTests, blocks)
138
139
140 def historyTests(self, result, blocks):
141 """historyTests"""
142
143 assert(len(blocks) >= 3)
144 assert(self.fb.get_history_previous("") == blocks[-2])
145 assert(self.fb.get_history_previous("") == blocks[-3])
146 assert(self.fb.get_history_next() == blocks[-2])
147
148
149 def test_history_returns_none_at_startup(self):
150 """test_history_returns_none_at_startup"""
151
152 assert(self.fb.get_history_previous("")==None)
153 assert(self.fb.get_history_next()==None)
154
155
@@ -0,0 +1,240 b''
1 .. _paralleltask:
2
3 ==========================
4 The IPython task interface
5 ==========================
6
7 .. contents::
8
9 The ``Task`` interface to the controller presents the engines as a fault tolerant, dynamic load-balanced system or workers. Unlike the ``MultiEngine`` interface, in the ``Task`` interface, the user have no direct access to individual engines. In some ways, this interface is simpler, but in other ways it is more powerful. Best of all the user can use both of these interfaces at the same time to take advantage or both of their strengths. When the user can break up the user's work into segments that do not depend on previous execution, the ``Task`` interface is ideal. But it also has more power and flexibility, allowing the user to guide the distribution of jobs, without having to assign Tasks to engines explicitly.
10
11 Starting the IPython controller and engines
12 ===========================================
13
14 To follow along with this tutorial, the user will need to start the IPython
15 controller and four IPython engines. The simplest way of doing this is to
16 use the ``ipcluster`` command::
17
18 $ ipcluster -n 4
19
20 For more detailed information about starting the controller and engines, see our :ref:`introduction <ip1par>` to using IPython for parallel computing.
21
22 The magic here is that this single controller and set of engines is running both the MultiEngine and ``Task`` interfaces simultaneously.
23
24 QuickStart Task Farming
25 =======================
26
27 First, a quick example of how to start running the most basic Tasks.
28 The first step is to import the IPython ``client`` module and then create a ``TaskClient`` instance::
29
30 In [1]: from IPython.kernel import client
31
32 In [2]: tc = client.TaskClient()
33
34 Then the user wrap the commands the user want to run in Tasks::
35
36 In [3]: tasklist = []
37 In [4]: for n in range(1000):
38 ... tasklist.append(client.Task("a = %i"%n, pull="a"))
39
40 The first argument of the ``Task`` constructor is a string, the command to be executed. The most important optional keyword argument is ``pull``, which can be a string or list of strings, and it specifies the variable names to be saved as results of the ``Task``.
41
42 Next, the user need to submit the Tasks to the ``TaskController`` with the ``TaskClient``::
43
44 In [5]: taskids = [ tc.run(t) for t in tasklist ]
45
46 This will give the user a list of the TaskIDs used by the controller to keep track of the Tasks and their results. Now at some point the user are going to want to get those results back. The ``barrier`` method allows the user to wait for the Tasks to finish running::
47
48 In [6]: tc.barrier(taskids)
49
50 This command will block until all the Tasks in ``taskids`` have finished. Now, the user probably want to look at the user's results::
51
52 In [7]: task_results = [ tc.get_task_result(taskid) for taskid in taskids ]
53
54 Now the user have a list of ``TaskResult`` objects, which have the actual result as a dictionary, but also keep track of some useful metadata about the ``Task``::
55
56 In [8]: tr = ``Task``_results[73]
57
58 In [9]: tr
59 Out[9]: ``TaskResult``[ID:73]:{'a':73}
60
61 In [10]: tr.engineid
62 Out[10]: 1
63
64 In [11]: tr.submitted, tr.completed, tr.duration
65 Out[11]: ("2008/03/08 03:41:42", "2008/03/08 03:41:44", 2.12345)
66
67 The actual results are stored in a dictionary, ``tr.results``, and a namespace object ``tr.ns`` which accesses the result keys by attribute::
68
69 In [12]: tr.results['a']
70 Out[12]: 73
71
72 In [13]: tr.ns.a
73 Out[13]: 73
74
75 That should cover the basics of running simple Tasks. There are several more powerful things the user can do with Tasks covered later. The most useful probably being using a ``MutiEngineClient`` interface to initialize all the engines with the import dependencies necessary to run the user's Tasks.
76
77 There are many options for running and managing Tasks. The best way to learn further about the ``Task`` interface is to study the examples in ``docs/examples``. If the user do so and learn a lots about this interface, we encourage the user to expand this documentation about the ``Task`` system.
78
79 Overview of the Task System
80 ===========================
81
82 The user's view of the ``Task`` system has three basic objects: The ``TaskClient``, the ``Task``, and the ``TaskResult``. The names of these three objects well indicate their role.
83
84 The ``TaskClient`` is the user's ``Task`` farming connection to the IPython cluster. Unlike the ``MultiEngineClient``, the ``TaskControler`` handles all the scheduling and distribution of work, so the ``TaskClient`` has no notion of engines, it just submits Tasks and requests their results. The Tasks are described as ``Task`` objects, and their results are wrapped in ``TaskResult`` objects. Thus, there are very few necessary methods for the user to manage.
85
86 Inside the task system is a Scheduler object, which assigns tasks to workers. The default scheduler is a simple FIFO queue. Subclassing the Scheduler should be easy, just implementing your own priority system.
87
88 The TaskClient
89 ==============
90
91 The ``TaskClient`` is the object the user use to connect to the ``Controller`` that is managing the user's Tasks. It is the analog of the ``MultiEngineClient`` for the standard IPython multiplexing interface. As with all client interfaces, the first step is to import the IPython Client Module::
92
93 In [1]: from IPython.kernel import client
94
95 Just as with the ``MultiEngineClient``, the user create the ``TaskClient`` with a tuple, containing the ip-address and port of the ``Controller``. the ``client`` module conveniently has the default address of the ``Task`` interface of the controller. Creating a default ``TaskClient`` object would be done with this::
96
97 In [2]: tc = client.TaskClient(client.default_task_address)
98
99 or, if the user want to specify a non default location of the ``Controller``, the user can specify explicitly::
100
101 In [3]: tc = client.TaskClient(("192.168.1.1", 10113))
102
103 As discussed earlier, the ``TaskClient`` only has a few basic methods.
104
105 * ``tc.run(task)``
106 ``run`` is the method by which the user submits Tasks. It takes exactly one argument, a ``Task`` object. All the advanced control of ``Task`` behavior is handled by properties of the ``Task`` object, rather than the submission command, so they will be discussed later in the `Task`_ section. ``run`` returns an integer, the ``Task``ID by which the ``Task`` and its results can be tracked and retrieved::
107
108 In [4]: ``Task``ID = tc.run(``Task``)
109
110 * ``tc.get_task_result(taskid, block=``False``)``
111 ``get_task_result`` is the method by which results are retrieved. It takes a single integer argument, the ``Task``ID`` of the result the user wish to retrieve. ``get_task_result`` also takes a keyword argument ``block``. ``block`` specifies whether the user actually want to wait for the result. If ``block`` is false, as it is by default, ``get_task_result`` will return immediately. If the ``Task`` has completed, it will return the ``TaskResult`` object for that ``Task``. But if the ``Task`` has not completed, it will return ``None``. If the user specify ``block=``True``, then ``get_task_result`` will wait for the ``Task`` to complete, and always return the ``TaskResult`` for the requested ``Task``.
112 * ``tc.barrier(taskid(s))``
113 ``barrier`` is a synchronization method. It takes exactly one argument, a ``Task``ID or list of taskIDs. ``barrier`` will block until all the specified Tasks have completed. In practice, a barrier is often called between the ``Task`` submission section of the code and the result gathering section::
114
115 In [5]: taskIDs = [ tc.run(``Task``) for ``Task`` in myTasks ]
116
117 In [6]: tc.get_task_result(taskIDs[-1]) is None
118 Out[6]: ``True``
119
120 In [7]: tc.barrier(``Task``ID)
121
122 In [8]: results = [ tc.get_task_result(tid) for tid in taskIDs ]
123
124 * ``tc.queue_status(verbose=``False``)``
125 ``queue_status`` is a method for querying the state of the ``TaskControler``. ``queue_status`` returns a dict of the form::
126
127 {'scheduled': Tasks that have been submitted but yet run
128 'pending' : Tasks that are currently running
129 'succeeded': Tasks that have completed successfully
130 'failed' : Tasks that have finished with a failure
131 }
132
133 if @verbose is not specified (or is ``False``), then the values of the dict are integers - the number of Tasks in each state. if @verbose is ``True``, then each element in the dict is a list of the taskIDs in that state::
134
135 In [8]: tc.queue_status()
136 Out[8]: {'scheduled': 4,
137 'pending' : 2,
138 'succeeded': 5,
139 'failed' : 1
140 }
141
142 In [9]: tc.queue_status(verbose=True)
143 Out[9]: {'scheduled': [8,9,10,11],
144 'pending' : [6,7],
145 'succeeded': [0,1,2,4,5],
146 'failed' : [3]
147 }
148
149 * ``tc.abort(taskid)``
150 ``abort`` allows the user to abort Tasks that have already been submitted. ``abort`` will always return immediately. If the ``Task`` has completed, ``abort`` will raise an ``IndexError ``Task`` Already Completed``. An obvious case for ``abort`` would be where the user submits a long-running ``Task`` with a number of retries (see ``Task``_ section for how to specify retries) in an interactive session, but realizes there has been a typo. The user can then abort the ``Task``, preventing certain failures from cluttering up the queue. It can also be used for parallel search-type problems, where only one ``Task`` will give the solution, so once the user find the solution, the user would want to abort all remaining Tasks to prevent wasted work.
151 * ``tc.spin()``
152 ``spin`` simply triggers the scheduler in the ``TaskControler``. Under most normal circumstances, this will do nothing. The primary known usage case involves the ``Task`` dependency (see `Dependencies`_). The dependency is a function of an Engine's ``properties``, but changing the ``properties`` via the ``MutliEngineClient`` does not trigger a reschedule event. The main example case for this requires the following event sequence:
153 * ``engine`` is available, ``Task`` is submitted, but ``engine`` does not have ``Task``'s dependencies.
154 * ``engine`` gets necessary dependencies while no new Tasks are submitted or completed.
155 * now ``engine`` can run ``Task``, but a ``Task`` event is required for the ``TaskControler`` to try scheduling ``Task`` again.
156
157 ``spin`` is just an empty ping method to ensure that the Controller has scheduled all available Tasks, and should not be needed under most normal circumstances.
158
159 That covers the ``TaskClient``, a simple interface to the cluster. With this, the user can submit jobs (and abort if necessary), request their results, synchronize on arbitrary subsets of jobs.
160
161 .. _task: The Task Object
162
163 The Task Object
164 ===============
165
166 The ``Task`` is the basic object for describing a job. It can be used in a very simple manner, where the user just specifies a command string to be executed as the ``Task``. The usage of this first argument is exactly the same as the ``execute`` method of the ``MultiEngine`` (in fact, ``execute`` is called to run the code)::
167
168 In [1]: t = client.Task("a = str(id)")
169
170 This ``Task`` would run, and store the string representation of the ``id`` element in ``a`` in each worker's namespace, but it is fairly useless because the user does not know anything about the state of the ``worker`` on which it ran at the time of retrieving results. It is important that each ``Task`` not expect the state of the ``worker`` to persist after the ``Task`` is completed.
171 There are many different situations for using ``Task`` Farming, and the ``Task`` object has many attributes for use in customizing the ``Task`` behavior. All of a ``Task``'s attributes may be specified in the constructor, through keyword arguments, or after ``Task`` construction through attribute assignment.
172
173 Data Attributes
174 ***************
175 It is likely that the user may want to move data around before or after executing the ``Task``. We provide methods of sending data to initialize the worker's namespace, and specifying what data to bring back as the ``Task``'s results.
176
177 * pull = []
178 The obvious case is as above, where ``t`` would execute and store the result of ``myfunc`` in ``a``, it is likely that the user would want to bring ``a`` back to their namespace. This is done through the ``pull`` attribute. ``pull`` can be a string or list of strings, and it specifies the names of variables to be retrieved. The ``TaskResult`` object retrieved by ``get_task_result`` will have a dictionary of keys and values, and the ``Task``'s ``pull`` attribute determines what goes into it::
179
180 In [2]: t = client.Task("a = str(id)", pull = "a")
181
182 In [3]: t = client.Task("a = str(id)", pull = ["a", "id"])
183
184 * push = {}
185 A user might also want to initialize some data into the namespace before the code part of the ``Task`` is run. Enter ``push``. ``push`` is a dictionary of key/value pairs to be loaded from the user's namespace into the worker's immediately before execution::
186
187 In [4]: t = client.Task("a = f(submitted)", push=dict(submitted=time.time()), pull="a")
188
189 push and pull result directly in calling an ``engine``'s ``push`` and ``pull`` methods before and after ``Task`` execution respectively, and thus their api is the same.
190
191 Namespace Cleaning
192 ******************
193 When a user is running a large number of Tasks, it is likely that the namespace of the worker's could become cluttered. Some Tasks might be sensitive to clutter, while others might be known to cause namespace pollution. For these reasons, Tasks have two boolean attributes for cleaning up the namespace.
194
195 * ``clear_after``
196 if clear_after is specified ``True``, the worker on which the ``Task`` was run will be reset (via ``engine.reset``) upon completion of the ``Task``. This can be useful for both Tasks that produce clutter or Tasks whose intermediate data one might wish to be kept private::
197
198 In [5]: t = client.Task("a = range(1e10)", pull = "a",clear_after=True)
199
200
201 * ``clear_before``
202 as one might guess, clear_before is identical to ``clear_after``, but it takes place before the ``Task`` is run. This ensures that the ``Task`` runs on a fresh worker::
203
204 In [6]: t = client.Task("a = globals()", pull = "a",clear_before=True)
205
206 Of course, a user can both at the same time, ensuring that all workers are clear except when they are currently running a job. Both of these default to ``False``.
207
208 Fault Tolerance
209 ***************
210 It is possible that Tasks might fail, and there are a variety of reasons this could happen. One might be that the worker it was running on disconnected, and there was nothing wrong with the ``Task`` itself. With the fault tolerance attributes of the ``Task``, the user can specify how many times to resubmit the ``Task``, and what to do if it never succeeds.
211
212 * ``retries``
213 ``retries`` is an integer, specifying the number of times a ``Task`` is to be retried. It defaults to zero. It is often a good idea for this number to be 1 or 2, to protect the ``Task`` from disconnecting engines, but not a large number. If a ``Task`` is failing 100 times, there is probably something wrong with the ``Task``. The canonical bad example:
214
215 In [7]: t = client.Task("os.kill(os.getpid(), 9)", retries=99)
216
217 This would actually take down 100 workers.
218
219 * ``recovery_task``
220 ``recovery_task`` is another ``Task`` object, to be run in the event of the original ``Task`` still failing after running out of retries. Since ``recovery_task`` is another ``Task`` object, it can have its own ``recovery_task``. The chain of Tasks is limitless, except loops are not allowed (that would be bad!).
221
222 Dependencies
223 ************
224 Dependencies are the most powerful part of the ``Task`` farming system, because it allows the user to do some classification of the workers, and guide the ``Task`` distribution without meddling with the controller directly. It makes use of two objects - the ``Task``'s ``depend`` attribute, and the engine's ``properties``. See the `MultiEngine`_ reference for how to use engine properties. The engine properties api exists for extending IPython, allowing conditional execution and new controllers that make decisions based on properties of its engines. Currently the ``Task`` dependency is the only internal use of the properties api.
225
226 .. _MultiEngine: ./parallel_multiengine
227
228 The ``depend`` attribute of a ``Task`` must be a function of exactly one argument, the worker's properties dictionary, and it should return ``True`` if the ``Task`` should be allowed to run on the worker and ``False`` if not. The usage in the controller is fault tolerant, so exceptions raised by ``Task.depend`` will be ignored and functionally equivalent to always returning ``False``. Tasks`` with invalid ``depend`` functions will never be assigned to a worker::
229
230 In [8]: def dep(properties):
231 ... return properties["RAM"] > 2**32 # have at least 4GB
232 In [9]: t = client.Task("a = bigfunc()", depend=dep)
233
234 It is important to note that assignment of values to the properties dict is done entirely by the user, either locally (in the engine) using the EngineAPI, or remotely, through the ``MultiEngineClient``'s get/set_properties methods.
235
236
237
238
239
240
@@ -0,0 +1,191 b''
1 Overview
2 ========
3
4 This document describes the steps required to install IPython. IPython is organized into a number of subpackages, each of which has its own dependencies. All of the subpackages come with IPython, so you don't need to download and install them separately. However, to use a given subpackage, you will need to install all of its dependencies.
5
6
7 Please let us know if you have problems installing IPython or any of its
8 dependencies. IPython requires Python version 2.4 or greater. We have not tested
9 IPython with the upcoming 2.6 or 3.0 versions.
10
11 .. warning::
12
13 IPython will not work with Python 2.3 or below.
14
15 Some of the installation approaches use the :mod:`setuptools` package and its :command:`easy_install` command line program. In many scenarios, this provides the most simple method of installing IPython and its dependencies. It is not required though. More information about :mod:`setuptools` can be found on its website.
16
17 More general information about installing Python packages can be found in Python's documentation at http://www.python.org/doc/.
18
19 Installing IPython itself
20 =========================
21
22 Given a properly built Python, the basic interactive IPython shell will work with no external dependencies. However, some Python distributions (particularly on Windows and OS X), don't come with a working :mod:`readline` module. The IPython shell will work without :mod:`readline`, but will lack many features that users depend on, such as tab completion and command line editing. See below for details of how to make sure you have a working :mod:`readline`.
23
24 Installation using easy_install
25 -------------------------------
26
27 If you have :mod:`setuptools` installed, the easiest way of getting IPython is to simple use :command:`easy_install`::
28
29 $ easy_install IPython
30
31 That's it.
32
33 Installation from source
34 ------------------------
35
36 If you don't want to use :command:`easy_install`, or don't have it installed, just grab the latest stable build of IPython from `here <http://ipython.scipy.org/dist/>`_. Then do the following::
37
38 $ tar -xzf ipython.tar.gz
39 $ cd ipython
40 $ python setup.py install
41
42 If you are installing to a location (like ``/usr/local``) that requires higher permissions, you may need to run the last command with :command:`sudo`.
43
44 Windows
45 -------
46
47 There are a few caveats for Windows users. The main issue is that a basic ``python setup.py install`` approach won't create ``.bat`` file or Start Menu shortcuts, which most users want. To get an installation with these, there are two choices:
48
49 1. Install using :command:`easy_install`.
50
51 2. Install using our binary ``.exe`` Windows installer, which can be found at `here <http://ipython.scipy.org/dist/>`_
52
53 3. Install from source, but using :mod:`setuptools` (``python setupegg.py install``).
54
55 Installing the development version
56 ----------------------------------
57
58 It is also possible to install the development version of IPython from our `Bazaar <http://bazaar-vcs.org/>`_ source code
59 repository. To do this you will need to have Bazaar installed on your system. Then just do::
60
61 $ bzr branch lp:ipython
62 $ cd ipython
63 $ python setup.py install
64
65 Again, this last step on Windows won't create ``.bat`` files or Start Menu shortcuts, so you will have to use one of the other approaches listed above.
66
67 Some users want to be able to follow the development branch as it changes. If you have :mod:`setuptools` installed, this is easy. Simply replace the last step by::
68
69 $ python setupegg.py develop
70
71 This creates links in the right places and installs the command line script to the appropriate places. Then, if you want to update your IPython at any time, just do::
72
73 $ bzr pull
74
75 Basic optional dependencies
76 ===========================
77
78 There are a number of basic optional dependencies that most users will want to get. These are:
79
80 * readline (for command line editing, tab completion, etc.)
81 * nose (to run the IPython test suite)
82 * pexpect (to use things like irunner)
83
84 If you are comfortable installing these things yourself, have at it, otherwise read on for more details.
85
86 readline
87 --------
88
89 In principle, all Python distributions should come with a working :mod:`readline` module. But, reality is not quite that simple. There are two common situations where you won't have a working :mod:`readline` module:
90
91 * If you are using the built-in Python on Mac OS X.
92
93 * If you are running Windows, which doesn't have a :mod:`readline` module.
94
95 On OS X, the built-in Python doesn't not have :mod:`readline` because of license issues. Starting with OS X 10.5 (Leopard), Apple's built-in Python has a BSD-licensed not-quite-compatible readline replacement. As of IPython 0.9, many of the issues related to the differences between readline and libedit have been resolved. For many users, libedit may be sufficient.
96
97 Most users on OS X will want to get the full :mod:`readline` module. To get a working :mod:`readline` module, just do (with :mod:`setuptools` installed)::
98
99 $ easy_install readline
100
101 .. note:
102
103 Other Python distributions on OS X (such as fink, MacPorts and the
104 official python.org binaries) already have readline installed so
105 you don't have to do this step.
106
107 If needed, the readline egg can be build and installed from source (see the wiki page at http://ipython.scipy.org/moin/InstallationOSXLeopard).
108
109 On Windows, you will need the PyReadline module. PyReadline is a separate, Windows only implementation of readline that uses native Windows calls through :mod:`ctypes`. The easiest way of installing PyReadline is you use the binary installer available `here <http://ipython.scipy.org/dist/>`_. The :mod:`ctypes` module, which comes with Python 2.5 and greater, is required by PyReadline. It is available for Python 2.4 at http://python.net/crew/theller/ctypes.
110
111 nose
112 ----
113
114 To run the IPython test suite you will need the :mod:`nose` package. Nose provides a great way of sniffing out and running all of the IPython tests. The simplest way of getting nose, is to use :command:`easy_install`::
115
116 $ easy_install nose
117
118 Another way of getting this is to do::
119
120 $ easy_install IPython[test]
121
122 For more installation options, see the `nose website <http://somethingaboutorange.com/mrl/projects/nose/>`_. Once you have nose installed, you can run IPython's test suite using the iptest command::
123
124 $ iptest
125
126
127 pexpect
128 -------
129
130 The `pexpect <http://www.noah.org/wiki/Pexpect>`_ package is used in IPython's :command:`irunner` script. On Unix platforms (including OS X), just do::
131
132 $ easy_install pexpect
133
134 Windows users are out of luck as pexpect does not run there.
135
136 Dependencies for IPython.kernel (parallel computing)
137 ====================================================
138
139 The IPython kernel provides a nice architecture for parallel computing. The main focus of this architecture is on interactive parallel computing. These features require a number of additional packages:
140
141 * zope.interface (yep, we use interfaces)
142 * Twisted (asynchronous networking framework)
143 * Foolscap (a nice, secure network protocol)
144 * pyOpenSSL (security for network connections)
145
146 On a Unix style platform (including OS X), if you want to use :mod:`setuptools`, you can just do::
147
148 $ easy_install IPython[kernel] # the first three
149 $ easy_install IPython[security] # pyOpenSSL
150
151 zope.interface and Twisted
152 --------------------------
153
154 On Unix style platforms (including OS X), the simplest way of getting the these is to use :command:`easy_install`::
155
156 $ easy_install zope.interface
157 $ easy_install Twisted
158
159 Of course, you can also download the source tarballs from the `Twisted website <twistedmatrix.org>`_ and the `zope.interface page at PyPI <http://pypi.python.org/pypi/zope.interface>`_ and do the usual ``python setup.py install`` if you prefer.
160
161 Windows is a bit different. For zope.interface and Twisted, simply get the latest binary ``.exe`` installer from the Twisted website. This installer includes both zope.interface and Twisted and should just work.
162
163 Foolscap
164 --------
165
166 Foolscap uses Twisted to provide a very nice secure RPC protocol that we use to implement our parallel computing features.
167
168 On all platforms a simple::
169
170 $ easy_install foolscap
171
172 should work. You can also download the source tarballs from the `Foolscap website <http://foolscap.lothar.com/trac>`_ and do ``python setup.py install`` if you prefer.
173
174 pyOpenSSL
175 ---------
176
177 IPython requires an older version of pyOpenSSL (0.6 rather than the current 0.7). There are a couple of options for getting this:
178
179 1. Most Linux distributions have packages for pyOpenSSL.
180 2. The built-in Python 2.5 on OS X 10.5 already has it installed.
181 3. There are source tarballs on the pyOpenSSL website. On Unix-like
182 platforms, these can be built using ``python seutp.py install``.
183 4. There is also a binary ``.exe`` Windows installer on the `pyOpenSSL website <http://pyopenssl.sourceforge.net/>`_.
184
185 Dependencies for IPython.frontend (the IPython GUI)
186 ===================================================
187
188 wxPython
189 --------
190
191 Starting with IPython 0.9, IPython has a new IPython.frontend package that has a nice wxPython based IPython GUI. As you would expect, this GUI requires wxPython. Most Linux distributions have wxPython packages available and the built-in Python on OS X comes with wxPython preinstalled. For Windows, a binary installer is available on the `wxPython website <http://www.wxpython.org/>`_. No newline at end of file
@@ -0,0 +1,423 b''
1 """
2 Defines a docutils directive for inserting inheritance diagrams.
3
4 Provide the directive with one or more classes or modules (separated
5 by whitespace). For modules, all of the classes in that module will
6 be used.
7
8 Example::
9
10 Given the following classes:
11
12 class A: pass
13 class B(A): pass
14 class C(A): pass
15 class D(B, C): pass
16 class E(B): pass
17
18 .. inheritance-diagram: D E
19
20 Produces a graph like the following:
21
22 A
23 / \
24 B C
25 / \ /
26 E D
27
28 The graph is inserted as a PNG+image map into HTML and a PDF in
29 LaTeX.
30 """
31
32 import inspect
33 import os
34 import re
35 import subprocess
36 try:
37 from hashlib import md5
38 except ImportError:
39 from md5 import md5
40
41 from docutils.nodes import Body, Element
42 from docutils.writers.html4css1 import HTMLTranslator
43 from sphinx.latexwriter import LaTeXTranslator
44 from docutils.parsers.rst import directives
45 from sphinx.roles import xfileref_role
46
47 class DotException(Exception):
48 pass
49
50 class InheritanceGraph(object):
51 """
52 Given a list of classes, determines the set of classes that
53 they inherit from all the way to the root "object", and then
54 is able to generate a graphviz dot graph from them.
55 """
56 def __init__(self, class_names, show_builtins=False):
57 """
58 *class_names* is a list of child classes to show bases from.
59
60 If *show_builtins* is True, then Python builtins will be shown
61 in the graph.
62 """
63 self.class_names = class_names
64 self.classes = self._import_classes(class_names)
65 self.all_classes = self._all_classes(self.classes)
66 if len(self.all_classes) == 0:
67 raise ValueError("No classes found for inheritance diagram")
68 self.show_builtins = show_builtins
69
70 py_sig_re = re.compile(r'''^([\w.]*\.)? # class names
71 (\w+) \s* $ # optionally arguments
72 ''', re.VERBOSE)
73
74 def _import_class_or_module(self, name):
75 """
76 Import a class using its fully-qualified *name*.
77 """
78 try:
79 path, base = self.py_sig_re.match(name).groups()
80 except:
81 raise ValueError(
82 "Invalid class or module '%s' specified for inheritance diagram" % name)
83 fullname = (path or '') + base
84 path = (path and path.rstrip('.'))
85 if not path:
86 path = base
87 if not path:
88 raise ValueError(
89 "Invalid class or module '%s' specified for inheritance diagram" % name)
90 try:
91 module = __import__(path, None, None, [])
92 except ImportError:
93 raise ValueError(
94 "Could not import class or module '%s' specified for inheritance diagram" % name)
95
96 try:
97 todoc = module
98 for comp in fullname.split('.')[1:]:
99 todoc = getattr(todoc, comp)
100 except AttributeError:
101 raise ValueError(
102 "Could not find class or module '%s' specified for inheritance diagram" % name)
103
104 # If a class, just return it
105 if inspect.isclass(todoc):
106 return [todoc]
107 elif inspect.ismodule(todoc):
108 classes = []
109 for cls in todoc.__dict__.values():
110 if inspect.isclass(cls) and cls.__module__ == todoc.__name__:
111 classes.append(cls)
112 return classes
113 raise ValueError(
114 "'%s' does not resolve to a class or module" % name)
115
116 def _import_classes(self, class_names):
117 """
118 Import a list of classes.
119 """
120 classes = []
121 for name in class_names:
122 classes.extend(self._import_class_or_module(name))
123 return classes
124
125 def _all_classes(self, classes):
126 """
127 Return a list of all classes that are ancestors of *classes*.
128 """
129 all_classes = {}
130
131 def recurse(cls):
132 all_classes[cls] = None
133 for c in cls.__bases__:
134 if c not in all_classes:
135 recurse(c)
136
137 for cls in classes:
138 recurse(cls)
139
140 return all_classes.keys()
141
142 def class_name(self, cls, parts=0):
143 """
144 Given a class object, return a fully-qualified name. This
145 works for things I've tested in matplotlib so far, but may not
146 be completely general.
147 """
148 module = cls.__module__
149 if module == '__builtin__':
150 fullname = cls.__name__
151 else:
152 fullname = "%s.%s" % (module, cls.__name__)
153 if parts == 0:
154 return fullname
155 name_parts = fullname.split('.')
156 return '.'.join(name_parts[-parts:])
157
158 def get_all_class_names(self):
159 """
160 Get all of the class names involved in the graph.
161 """
162 return [self.class_name(x) for x in self.all_classes]
163
164 # These are the default options for graphviz
165 default_graph_options = {
166 "rankdir": "LR",
167 "size": '"8.0, 12.0"'
168 }
169 default_node_options = {
170 "shape": "box",
171 "fontsize": 10,
172 "height": 0.25,
173 "fontname": "Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",
174 "style": '"setlinewidth(0.5)"'
175 }
176 default_edge_options = {
177 "arrowsize": 0.5,
178 "style": '"setlinewidth(0.5)"'
179 }
180
181 def _format_node_options(self, options):
182 return ','.join(["%s=%s" % x for x in options.items()])
183 def _format_graph_options(self, options):
184 return ''.join(["%s=%s;\n" % x for x in options.items()])
185
186 def generate_dot(self, fd, name, parts=0, urls={},
187 graph_options={}, node_options={},
188 edge_options={}):
189 """
190 Generate a graphviz dot graph from the classes that
191 were passed in to __init__.
192
193 *fd* is a Python file-like object to write to.
194
195 *name* is the name of the graph
196
197 *urls* is a dictionary mapping class names to http urls
198
199 *graph_options*, *node_options*, *edge_options* are
200 dictionaries containing key/value pairs to pass on as graphviz
201 properties.
202 """
203 g_options = self.default_graph_options.copy()
204 g_options.update(graph_options)
205 n_options = self.default_node_options.copy()
206 n_options.update(node_options)
207 e_options = self.default_edge_options.copy()
208 e_options.update(edge_options)
209
210 fd.write('digraph %s {\n' % name)
211 fd.write(self._format_graph_options(g_options))
212
213 for cls in self.all_classes:
214 if not self.show_builtins and cls in __builtins__.values():
215 continue
216
217 name = self.class_name(cls, parts)
218
219 # Write the node
220 this_node_options = n_options.copy()
221 url = urls.get(self.class_name(cls))
222 if url is not None:
223 this_node_options['URL'] = '"%s"' % url
224 fd.write(' "%s" [%s];\n' %
225 (name, self._format_node_options(this_node_options)))
226
227 # Write the edges
228 for base in cls.__bases__:
229 if not self.show_builtins and base in __builtins__.values():
230 continue
231
232 base_name = self.class_name(base, parts)
233 fd.write(' "%s" -> "%s" [%s];\n' %
234 (base_name, name,
235 self._format_node_options(e_options)))
236 fd.write('}\n')
237
238 def run_dot(self, args, name, parts=0, urls={},
239 graph_options={}, node_options={}, edge_options={}):
240 """
241 Run graphviz 'dot' over this graph, returning whatever 'dot'
242 writes to stdout.
243
244 *args* will be passed along as commandline arguments.
245
246 *name* is the name of the graph
247
248 *urls* is a dictionary mapping class names to http urls
249
250 Raises DotException for any of the many os and
251 installation-related errors that may occur.
252 """
253 try:
254 dot = subprocess.Popen(['dot'] + list(args),
255 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
256 close_fds=True)
257 except OSError:
258 raise DotException("Could not execute 'dot'. Are you sure you have 'graphviz' installed?")
259 except ValueError:
260 raise DotException("'dot' called with invalid arguments")
261 except:
262 raise DotException("Unexpected error calling 'dot'")
263
264 self.generate_dot(dot.stdin, name, parts, urls, graph_options,
265 node_options, edge_options)
266 dot.stdin.close()
267 result = dot.stdout.read()
268 returncode = dot.wait()
269 if returncode != 0:
270 raise DotException("'dot' returned the errorcode %d" % returncode)
271 return result
272
273 class inheritance_diagram(Body, Element):
274 """
275 A docutils node to use as a placeholder for the inheritance
276 diagram.
277 """
278 pass
279
280 def inheritance_diagram_directive_run(class_names, options, state):
281 """
282 Run when the inheritance_diagram directive is first encountered.
283 """
284 node = inheritance_diagram()
285
286 # Create a graph starting with the list of classes
287 graph = InheritanceGraph(class_names)
288
289 # Create xref nodes for each target of the graph's image map and
290 # add them to the doc tree so that Sphinx can resolve the
291 # references to real URLs later. These nodes will eventually be
292 # removed from the doctree after we're done with them.
293 for name in graph.get_all_class_names():
294 refnodes, x = xfileref_role(
295 'class', ':class:`%s`' % name, name, 0, state)
296 node.extend(refnodes)
297 # Store the graph object so we can use it to generate the
298 # dot file later
299 node['graph'] = graph
300 # Store the original content for use as a hash
301 node['parts'] = options.get('parts', 0)
302 node['content'] = " ".join(class_names)
303 return [node]
304
305 def get_graph_hash(node):
306 return md5(node['content'] + str(node['parts'])).hexdigest()[-10:]
307
308 def html_output_graph(self, node):
309 """
310 Output the graph for HTML. This will insert a PNG with clickable
311 image map.
312 """
313 graph = node['graph']
314 parts = node['parts']
315
316 graph_hash = get_graph_hash(node)
317 name = "inheritance%s" % graph_hash
318 png_path = os.path.join('_static', name + ".png")
319
320 path = '_static'
321 source = self.document.attributes['source']
322 count = source.split('/doc/')[-1].count('/')
323 for i in range(count):
324 if os.path.exists(path): break
325 path = '../'+path
326 path = '../'+path #specifically added for matplotlib
327
328 # Create a mapping from fully-qualified class names to URLs.
329 urls = {}
330 for child in node:
331 if child.get('refuri') is not None:
332 urls[child['reftitle']] = child.get('refuri')
333 elif child.get('refid') is not None:
334 urls[child['reftitle']] = '#' + child.get('refid')
335
336 # These arguments to dot will save a PNG file to disk and write
337 # an HTML image map to stdout.
338 image_map = graph.run_dot(['-Tpng', '-o%s' % png_path, '-Tcmapx'],
339 name, parts, urls)
340 return ('<img src="%s/%s.png" usemap="#%s" class="inheritance"/>%s' %
341 (path, name, name, image_map))
342
343 def latex_output_graph(self, node):
344 """
345 Output the graph for LaTeX. This will insert a PDF.
346 """
347 graph = node['graph']
348 parts = node['parts']
349
350 graph_hash = get_graph_hash(node)
351 name = "inheritance%s" % graph_hash
352 pdf_path = os.path.join('_static', name + ".pdf")
353
354 graph.run_dot(['-Tpdf', '-o%s' % pdf_path],
355 name, parts, graph_options={'size': '"6.0,6.0"'})
356 return '\\includegraphics{../../%s}' % pdf_path
357
358 def visit_inheritance_diagram(inner_func):
359 """
360 This is just a wrapper around html/latex_output_graph to make it
361 easier to handle errors and insert warnings.
362 """
363 def visitor(self, node):
364 try:
365 content = inner_func(self, node)
366 except DotException, e:
367 # Insert the exception as a warning in the document
368 warning = self.document.reporter.warning(str(e), line=node.line)
369 warning.parent = node
370 node.children = [warning]
371 else:
372 source = self.document.attributes['source']
373 self.body.append(content)
374 node.children = []
375 return visitor
376
377 def do_nothing(self, node):
378 pass
379
380 options_spec = {
381 'parts': directives.nonnegative_int
382 }
383
384 # Deal with the old and new way of registering directives
385 try:
386 from docutils.parsers.rst import Directive
387 except ImportError:
388 from docutils.parsers.rst.directives import _directives
389 def inheritance_diagram_directive(name, arguments, options, content, lineno,
390 content_offset, block_text, state,
391 state_machine):
392 return inheritance_diagram_directive_run(arguments, options, state)
393 inheritance_diagram_directive.__doc__ = __doc__
394 inheritance_diagram_directive.arguments = (1, 100, 0)
395 inheritance_diagram_directive.options = options_spec
396 inheritance_diagram_directive.content = 0
397 _directives['inheritance-diagram'] = inheritance_diagram_directive
398 else:
399 class inheritance_diagram_directive(Directive):
400 has_content = False
401 required_arguments = 1
402 optional_arguments = 100
403 final_argument_whitespace = False
404 option_spec = options_spec
405
406 def run(self):
407 return inheritance_diagram_directive_run(
408 self.arguments, self.options, self.state)
409 inheritance_diagram_directive.__doc__ = __doc__
410
411 directives.register_directive('inheritance-diagram',
412 inheritance_diagram_directive)
413
414 def setup(app):
415 app.add_node(inheritance_diagram)
416
417 HTMLTranslator.visit_inheritance_diagram = \
418 visit_inheritance_diagram(html_output_graph)
419 HTMLTranslator.depart_inheritance_diagram = do_nothing
420
421 LaTeXTranslator.visit_inheritance_diagram = \
422 visit_inheritance_diagram(latex_output_graph)
423 LaTeXTranslator.depart_inheritance_diagram = do_nothing
@@ -0,0 +1,75 b''
1 from pygments.lexer import Lexer, do_insertions
2 from pygments.lexers.agile import PythonConsoleLexer, PythonLexer, \
3 PythonTracebackLexer
4 from pygments.token import Comment, Generic
5 from sphinx import highlighting
6 import re
7
8 line_re = re.compile('.*?\n')
9
10 class IPythonConsoleLexer(Lexer):
11 """
12 For IPython console output or doctests, such as:
13
14 Tracebacks are not currently supported.
15
16 .. sourcecode:: ipython
17
18 In [1]: a = 'foo'
19
20 In [2]: a
21 Out[2]: 'foo'
22
23 In [3]: print a
24 foo
25
26 In [4]: 1 / 0
27 """
28 name = 'IPython console session'
29 aliases = ['ipython']
30 mimetypes = ['text/x-ipython-console']
31 input_prompt = re.compile("(In \[[0-9]+\]: )|( \.\.\.+:)")
32 output_prompt = re.compile("(Out\[[0-9]+\]: )|( \.\.\.+:)")
33 continue_prompt = re.compile(" \.\.\.+:")
34 tb_start = re.compile("\-+")
35
36 def get_tokens_unprocessed(self, text):
37 pylexer = PythonLexer(**self.options)
38 tblexer = PythonTracebackLexer(**self.options)
39
40 curcode = ''
41 insertions = []
42 for match in line_re.finditer(text):
43 line = match.group()
44 input_prompt = self.input_prompt.match(line)
45 continue_prompt = self.continue_prompt.match(line.rstrip())
46 output_prompt = self.output_prompt.match(line)
47 if line.startswith("#"):
48 insertions.append((len(curcode),
49 [(0, Comment, line)]))
50 elif input_prompt is not None:
51 insertions.append((len(curcode),
52 [(0, Generic.Prompt, input_prompt.group())]))
53 curcode += line[input_prompt.end():]
54 elif continue_prompt is not None:
55 insertions.append((len(curcode),
56 [(0, Generic.Prompt, continue_prompt.group())]))
57 curcode += line[continue_prompt.end():]
58 elif output_prompt is not None:
59 insertions.append((len(curcode),
60 [(0, Generic.Output, output_prompt.group())]))
61 curcode += line[output_prompt.end():]
62 else:
63 if curcode:
64 for item in do_insertions(insertions,
65 pylexer.get_tokens_unprocessed(curcode)):
66 yield item
67 curcode = ''
68 insertions = []
69 yield match.start(), Generic.Output, line
70 if curcode:
71 for item in do_insertions(insertions,
72 pylexer.get_tokens_unprocessed(curcode)):
73 yield item
74
75 highlighting.lexers['ipython'] = IPythonConsoleLexer()
@@ -0,0 +1,87 b''
1 #
2 # A pair of directives for inserting content that will only appear in
3 # either html or latex.
4 #
5
6 from docutils.nodes import Body, Element
7 from docutils.writers.html4css1 import HTMLTranslator
8 from sphinx.latexwriter import LaTeXTranslator
9 from docutils.parsers.rst import directives
10
11 class html_only(Body, Element):
12 pass
13
14 class latex_only(Body, Element):
15 pass
16
17 def run(content, node_class, state, content_offset):
18 text = '\n'.join(content)
19 node = node_class(text)
20 state.nested_parse(content, content_offset, node)
21 return [node]
22
23 try:
24 from docutils.parsers.rst import Directive
25 except ImportError:
26 from docutils.parsers.rst.directives import _directives
27
28 def html_only_directive(name, arguments, options, content, lineno,
29 content_offset, block_text, state, state_machine):
30 return run(content, html_only, state, content_offset)
31
32 def latex_only_directive(name, arguments, options, content, lineno,
33 content_offset, block_text, state, state_machine):
34 return run(content, latex_only, state, content_offset)
35
36 for func in (html_only_directive, latex_only_directive):
37 func.content = 1
38 func.options = {}
39 func.arguments = None
40
41 _directives['htmlonly'] = html_only_directive
42 _directives['latexonly'] = latex_only_directive
43 else:
44 class OnlyDirective(Directive):
45 has_content = True
46 required_arguments = 0
47 optional_arguments = 0
48 final_argument_whitespace = True
49 option_spec = {}
50
51 def run(self):
52 self.assert_has_content()
53 return run(self.content, self.node_class,
54 self.state, self.content_offset)
55
56 class HtmlOnlyDirective(OnlyDirective):
57 node_class = html_only
58
59 class LatexOnlyDirective(OnlyDirective):
60 node_class = latex_only
61
62 directives.register_directive('htmlonly', HtmlOnlyDirective)
63 directives.register_directive('latexonly', LatexOnlyDirective)
64
65 def setup(app):
66 app.add_node(html_only)
67 app.add_node(latex_only)
68
69 # Add visit/depart methods to HTML-Translator:
70 def visit_perform(self, node):
71 pass
72 def depart_perform(self, node):
73 pass
74 def visit_ignore(self, node):
75 node.children = []
76 def depart_ignore(self, node):
77 node.children = []
78
79 HTMLTranslator.visit_html_only = visit_perform
80 HTMLTranslator.depart_html_only = depart_perform
81 HTMLTranslator.visit_latex_only = visit_ignore
82 HTMLTranslator.depart_latex_only = depart_ignore
83
84 LaTeXTranslator.visit_html_only = visit_ignore
85 LaTeXTranslator.depart_html_only = depart_ignore
86 LaTeXTranslator.visit_latex_only = visit_perform
87 LaTeXTranslator.depart_latex_only = depart_perform
@@ -0,0 +1,155 b''
1 """A special directive for including a matplotlib plot.
2
3 Given a path to a .py file, it includes the source code inline, then:
4
5 - On HTML, will include a .png with a link to a high-res .png.
6
7 - On LaTeX, will include a .pdf
8
9 This directive supports all of the options of the `image` directive,
10 except for `target` (since plot will add its own target).
11
12 Additionally, if the :include-source: option is provided, the literal
13 source will be included inline, as well as a link to the source.
14 """
15
16 import sys, os, glob, shutil
17 from docutils.parsers.rst import directives
18
19 try:
20 # docutils 0.4
21 from docutils.parsers.rst.directives.images import align
22 except ImportError:
23 # docutils 0.5
24 from docutils.parsers.rst.directives.images import Image
25 align = Image.align
26
27
28 import matplotlib
29 import IPython.Shell
30 matplotlib.use('Agg')
31 import matplotlib.pyplot as plt
32
33 mplshell = IPython.Shell.MatplotlibShell('mpl')
34
35 options = {'alt': directives.unchanged,
36 'height': directives.length_or_unitless,
37 'width': directives.length_or_percentage_or_unitless,
38 'scale': directives.nonnegative_int,
39 'align': align,
40 'class': directives.class_option,
41 'include-source': directives.flag }
42
43 template = """
44 .. htmlonly::
45
46 [`source code <../%(srcdir)s/%(basename)s.py>`__,
47 `png <../%(srcdir)s/%(basename)s.hires.png>`__,
48 `pdf <../%(srcdir)s/%(basename)s.pdf>`__]
49
50 .. image:: ../%(srcdir)s/%(basename)s.png
51 %(options)s
52
53 .. latexonly::
54 .. image:: ../%(srcdir)s/%(basename)s.pdf
55 %(options)s
56
57 """
58
59 def makefig(fullpath, outdir):
60 """
61 run a pyplot script and save the low and high res PNGs and a PDF in _static
62 """
63
64 fullpath = str(fullpath) # todo, why is unicode breaking this
65 formats = [('png', 100),
66 ('hires.png', 200),
67 ('pdf', 72),
68 ]
69
70 basedir, fname = os.path.split(fullpath)
71 basename, ext = os.path.splitext(fname)
72 all_exists = True
73
74 if basedir != outdir:
75 shutil.copyfile(fullpath, os.path.join(outdir, fname))
76
77 for format, dpi in formats:
78 outname = os.path.join(outdir, '%s.%s' % (basename, format))
79 if not os.path.exists(outname):
80 all_exists = False
81 break
82
83 if all_exists:
84 print ' already have %s'%fullpath
85 return
86
87 print ' building %s'%fullpath
88 plt.close('all') # we need to clear between runs
89 matplotlib.rcdefaults()
90
91 mplshell.magic_run(fullpath)
92 for format, dpi in formats:
93 outname = os.path.join(outdir, '%s.%s' % (basename, format))
94 if os.path.exists(outname): continue
95 plt.savefig(outname, dpi=dpi)
96
97 def run(arguments, options, state_machine, lineno):
98 reference = directives.uri(arguments[0])
99 basedir, fname = os.path.split(reference)
100 basename, ext = os.path.splitext(fname)
101
102 # todo - should we be using the _static dir for the outdir, I am
103 # not sure we want to corrupt that dir with autogenerated files
104 # since it also has permanent files in it which makes it difficult
105 # to clean (save an rm -rf followed by and svn up)
106 srcdir = 'pyplots'
107
108 makefig(os.path.join(srcdir, reference), srcdir)
109
110 # todo: it is not great design to assume the makefile is putting
111 # the figs into the right place, so we may want to do that here instead.
112
113 if options.has_key('include-source'):
114 lines = ['.. literalinclude:: ../pyplots/%(reference)s' % locals()]
115 del options['include-source']
116 else:
117 lines = []
118
119 options = [' :%s: %s' % (key, val) for key, val in
120 options.items()]
121 options = "\n".join(options)
122
123 lines.extend((template % locals()).split('\n'))
124
125 state_machine.insert_input(
126 lines, state_machine.input_lines.source(0))
127 return []
128
129
130 try:
131 from docutils.parsers.rst import Directive
132 except ImportError:
133 from docutils.parsers.rst.directives import _directives
134
135 def plot_directive(name, arguments, options, content, lineno,
136 content_offset, block_text, state, state_machine):
137 return run(arguments, options, state_machine, lineno)
138 plot_directive.__doc__ = __doc__
139 plot_directive.arguments = (1, 0, 1)
140 plot_directive.options = options
141
142 _directives['plot'] = plot_directive
143 else:
144 class plot_directive(Directive):
145 required_arguments = 1
146 optional_arguments = 0
147 final_argument_whitespace = True
148 option_spec = options
149 def run(self):
150 return run(self.arguments, self.options,
151 self.state_machine, self.lineno)
152 plot_directive.__doc__ = __doc__
153
154 directives.register_directive('plot', plot_directive)
155
@@ -1,7 +1,5 b''
1 1 # -*- coding: utf-8 -*-
2 """Release data for the IPython project.
3
4 $Id: Release.py 3002 2008-02-01 07:17:00Z fperez $"""
2 """Release data for the IPython project."""
5 3
6 4 #*****************************************************************************
7 5 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
@@ -23,9 +21,9 b" name = 'ipython'"
23 21 # bdist_deb does not accept underscores (a Debian convention).
24 22
25 23 development = False # change this to False to do a release
26 version_base = '0.9.rc1'
24 version_base = '0.9.1'
27 25 branch = 'ipython'
28 revision = '1124'
26 revision = '1143'
29 27
30 28 if development:
31 29 if branch == 'ipython':
@@ -14,7 +14,7 b' __docformat__ = "restructuredtext en"'
14 14 #-------------------------------------------------------------------------------
15 15 # Imports
16 16 #-------------------------------------------------------------------------------
17 import uuid
17 from IPython.external import guid
18 18
19 19
20 20 from zope.interface import Interface, Attribute, implements, classProvides
@@ -59,7 +59,7 b' class AsyncFrontEndBase(FrontEndBase):'
59 59 return Failure(Exception("Block is not compilable"))
60 60
61 61 if(blockID == None):
62 blockID = uuid.uuid4() #random UUID
62 blockID = guid.generate()
63 63
64 64 d = self.engine.execute(block)
65 65 d.addCallback(self._add_history, block=block)
@@ -26,7 +26,7 b' __docformat__ = "restructuredtext en"'
26 26
27 27 import sys
28 28 import objc
29 import uuid
29 from IPython.external import guid
30 30
31 31 from Foundation import NSObject, NSMutableArray, NSMutableDictionary,\
32 32 NSLog, NSNotificationCenter, NSMakeRange,\
@@ -361,7 +361,7 b' class IPythonCocoaController(NSObject, AsyncFrontEndBase):'
361 361
362 362 def next_block_ID(self):
363 363
364 return uuid.uuid4()
364 return guid.generate()
365 365
366 366 def new_cell_block(self):
367 367 """A new CellBlock at the end of self.textView.textStorage()"""
@@ -21,14 +21,13 b' __docformat__ = "restructuredtext en"'
21 21 # Imports
22 22 #-------------------------------------------------------------------------------
23 23 import string
24 import uuid
25 import _ast
24 import codeop
25 from IPython.external import guid
26
26 27
27 28 from IPython.frontend.zopeinterface import (
28 29 Interface,
29 30 Attribute,
30 implements,
31 classProvides
32 31 )
33 32 from IPython.kernel.core.history import FrontEndHistory
34 33 from IPython.kernel.core.util import Bunch
@@ -134,11 +133,7 b' class IFrontEnd(Interface):'
134 133
135 134 pass
136 135
137 def compile_ast(block):
138 """Compiles block to an _ast.AST"""
139
140 pass
141
136
142 137 def get_history_previous(current_block):
143 138 """Returns the block previous in the history. Saves currentBlock if
144 139 the history_cursor is currently at the end of the input history"""
@@ -220,28 +215,14 b' class FrontEndBase(object):'
220 215 """
221 216
222 217 try:
223 ast = self.compile_ast(block)
218 is_complete = codeop.compile_command(block.rstrip() + '\n\n',
219 "<string>", "exec")
224 220 except:
225 221 return False
226 222
227 223 lines = block.split('\n')
228 return (len(lines)==1 or str(lines[-1])=='')
229
230
231 def compile_ast(self, block):
232 """Compile block to an AST
233
234 Parameters:
235 block : str
236
237 Result:
238 AST
239
240 Throws:
241 Exception if block cannot be compiled
242 """
243
244 return compile(block, "<string>", "exec", _ast.PyCF_ONLY_AST)
224 return ((is_complete is not None)
225 and (len(lines)==1 or str(lines[-1])==''))
245 226
246 227
247 228 def execute(self, block, blockID=None):
@@ -261,7 +242,7 b' class FrontEndBase(object):'
261 242 raise Exception("Block is not compilable")
262 243
263 244 if(blockID == None):
264 blockID = uuid.uuid4() #random UUID
245 blockID = guid.generate()
265 246
266 247 try:
267 248 result = self.shell.execute(block)
@@ -18,10 +18,8 b' __docformat__ = "restructuredtext en"'
18 18 #-------------------------------------------------------------------------------
19 19 import re
20 20
21 import IPython
22 21 import sys
23 22 import codeop
24 import traceback
25 23
26 24 from frontendbase import FrontEndBase
27 25 from IPython.kernel.core.interpreter import Interpreter
@@ -182,16 +180,29 b' class LineFrontEndBase(FrontEndBase):'
182 180 raw_string = python_string
183 181 # Create a false result, in case there is an exception
184 182 self.last_result = dict(number=self.prompt_number)
183
184 ## try:
185 ## self.history.input_cache[-1] = raw_string.rstrip()
186 ## result = self.shell.execute(python_string)
187 ## self.last_result = result
188 ## self.render_result(result)
189 ## except:
190 ## self.show_traceback()
191 ## finally:
192 ## self.after_execute()
193
185 194 try:
186 self.history.input_cache[-1] = raw_string.rstrip()
187 result = self.shell.execute(python_string)
188 self.last_result = result
189 self.render_result(result)
190 except:
191 self.show_traceback()
195 try:
196 self.history.input_cache[-1] = raw_string.rstrip()
197 result = self.shell.execute(python_string)
198 self.last_result = result
199 self.render_result(result)
200 except:
201 self.show_traceback()
192 202 finally:
193 203 self.after_execute()
194 204
205
195 206 #--------------------------------------------------------------------------
196 207 # LineFrontEndBase interface
197 208 #--------------------------------------------------------------------------
@@ -284,6 +295,12 b' class LineFrontEndBase(FrontEndBase):'
284 295 self.write(prompt)
285 296
286 297
298 def execute_command(self, command, hidden=False):
299 """ Execute a command, not only in the model, but also in the
300 view, if any.
301 """
302 return self.shell.execute(command)
303
287 304 #--------------------------------------------------------------------------
288 305 # Private API
289 306 #--------------------------------------------------------------------------
@@ -198,17 +198,33 b' This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""'
198 198 # capture it.
199 199 self.capture_output()
200 200 self.last_result = dict(number=self.prompt_number)
201
202 ## try:
203 ## for line in input_string.split('\n'):
204 ## filtered_lines.append(
205 ## self.ipython0.prefilter(line, False).rstrip())
206 ## except:
207 ## # XXX: probably not the right thing to do.
208 ## self.ipython0.showsyntaxerror()
209 ## self.after_execute()
210 ## finally:
211 ## self.release_output()
212
213
201 214 try:
202 for line in input_string.split('\n'):
203 filtered_lines.append(
204 self.ipython0.prefilter(line, False).rstrip())
205 except:
206 # XXX: probably not the right thing to do.
207 self.ipython0.showsyntaxerror()
208 self.after_execute()
215 try:
216 for line in input_string.split('\n'):
217 filtered_lines.append(
218 self.ipython0.prefilter(line, False).rstrip())
219 except:
220 # XXX: probably not the right thing to do.
221 self.ipython0.showsyntaxerror()
222 self.after_execute()
209 223 finally:
210 224 self.release_output()
211 225
226
227
212 228 # Clean up the trailing whitespace, to avoid indentation errors
213 229 filtered_string = '\n'.join(filtered_lines)
214 230 return filtered_string
@@ -1,155 +1,32 b''
1 1 # encoding: utf-8
2
3 """This file contains unittests for the frontendbase module."""
2 """
3 Test the basic functionality of frontendbase.
4 """
4 5
5 6 __docformat__ = "restructuredtext en"
6 7
7 #---------------------------------------------------------------------------
8 # Copyright (C) 2008 The IPython Development Team
9 #
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
12 #---------------------------------------------------------------------------
13
14 #---------------------------------------------------------------------------
15 # Imports
16 #---------------------------------------------------------------------------
17
18 import unittest
19
20 try:
21 from IPython.frontend.asyncfrontendbase import AsyncFrontEndBase
22 from IPython.frontend import frontendbase
23 from IPython.kernel.engineservice import EngineService
24 except ImportError:
25 import nose
26 raise nose.SkipTest("This test requires zope.interface, Twisted and Foolscap")
27
28 from IPython.testing.decorators import skip
29
30 class FrontEndCallbackChecker(AsyncFrontEndBase):
31 """FrontEndBase subclass for checking callbacks"""
32 def __init__(self, engine=None, history=None):
33 super(FrontEndCallbackChecker, self).__init__(engine=engine,
34 history=history)
35 self.updateCalled = False
36 self.renderResultCalled = False
37 self.renderErrorCalled = False
38
39 def update_cell_prompt(self, result, blockID=None):
40 self.updateCalled = True
41 return result
42
43 def render_result(self, result):
44 self.renderResultCalled = True
45 return result
46
47
48 def render_error(self, failure):
49 self.renderErrorCalled = True
50 return failure
51
52
8 #-------------------------------------------------------------------------------
9 # Copyright (C) 2008 The IPython Development Team
10 #
11 # Distributed under the terms of the BSD License. The full license is
12 # in the file COPYING, distributed as part of this software.
13 #-------------------------------------------------------------------------------
14
15 from IPython.frontend.frontendbase import FrontEndBase
16
17 def test_iscomplete():
18 """ Check that is_complete works.
19 """
20 f = FrontEndBase()
21 assert f.is_complete('(a + a)')
22 assert not f.is_complete('(a + a')
23 assert f.is_complete('1')
24 assert not f.is_complete('1 + ')
25 assert not f.is_complete('1 + \n\n')
26 assert f.is_complete('if True:\n print 1\n')
27 assert not f.is_complete('if True:\n print 1')
28 assert f.is_complete('def f():\n print 1\n')
29
30 if __name__ == '__main__':
31 test_iscomplete()
53 32
54
55 class TestAsyncFrontendBase(unittest.TestCase):
56 def setUp(self):
57 """Setup the EngineService and FrontEndBase"""
58
59 self.fb = FrontEndCallbackChecker(engine=EngineService())
60
61 def test_implements_IFrontEnd(self):
62 assert(frontendbase.IFrontEnd.implementedBy(
63 AsyncFrontEndBase))
64
65 def test_is_complete_returns_False_for_incomplete_block(self):
66 """"""
67
68 block = """def test(a):"""
69
70 assert(self.fb.is_complete(block) == False)
71
72 def test_is_complete_returns_True_for_complete_block(self):
73 """"""
74
75 block = """def test(a): pass"""
76
77 assert(self.fb.is_complete(block))
78
79 block = """a=3"""
80
81 assert(self.fb.is_complete(block))
82
83 def test_blockID_added_to_result(self):
84 block = """3+3"""
85
86 d = self.fb.execute(block, blockID='TEST_ID')
87
88 d.addCallback(self.checkBlockID, expected='TEST_ID')
89
90 def test_blockID_added_to_failure(self):
91 block = "raise Exception()"
92
93 d = self.fb.execute(block,blockID='TEST_ID')
94 d.addErrback(self.checkFailureID, expected='TEST_ID')
95
96 def checkBlockID(self, result, expected=""):
97 assert(result['blockID'] == expected)
98
99
100 def checkFailureID(self, failure, expected=""):
101 assert(failure.blockID == expected)
102
103
104 def test_callbacks_added_to_execute(self):
105 """test that
106 update_cell_prompt
107 render_result
108
109 are added to execute request
110 """
111
112 d = self.fb.execute("10+10")
113 d.addCallback(self.checkCallbacks)
114
115 def checkCallbacks(self, result):
116 assert(self.fb.updateCalled)
117 assert(self.fb.renderResultCalled)
118
119 @skip("This test fails and lead to an unhandled error in a Deferred.")
120 def test_error_callback_added_to_execute(self):
121 """test that render_error called on execution error"""
122
123 d = self.fb.execute("raise Exception()")
124 d.addCallback(self.checkRenderError)
125
126 def checkRenderError(self, result):
127 assert(self.fb.renderErrorCalled)
128
129 def test_history_returns_expected_block(self):
130 """Make sure history browsing doesn't fail"""
131
132 blocks = ["a=1","a=2","a=3"]
133 for b in blocks:
134 d = self.fb.execute(b)
135
136 # d is now the deferred for the last executed block
137 d.addCallback(self.historyTests, blocks)
138
139
140 def historyTests(self, result, blocks):
141 """historyTests"""
142
143 assert(len(blocks) >= 3)
144 assert(self.fb.get_history_previous("") == blocks[-2])
145 assert(self.fb.get_history_previous("") == blocks[-3])
146 assert(self.fb.get_history_next() == blocks[-2])
147
148
149 def test_history_returns_none_at_startup(self):
150 """test_history_returns_none_at_startup"""
151
152 assert(self.fb.get_history_previous("")==None)
153 assert(self.fb.get_history_next()==None)
154
155
@@ -36,7 +36,7 b' import re'
36 36
37 37 _DEFAULT_SIZE = 10
38 38 if sys.platform == 'darwin':
39 _DEFAULT_STYLE = 12
39 _DEFAULT_SIZE = 12
40 40
41 41 _DEFAULT_STYLE = {
42 42 'stdout' : 'fore:#0000FF',
@@ -25,7 +25,6 b' __docformat__ = "restructuredtext en"'
25 25 # Major library imports
26 26 import re
27 27 import __builtin__
28 from time import sleep
29 28 import sys
30 29 from threading import Lock
31 30 import string
@@ -276,6 +275,38 b' class WxController(ConsoleWidget, PrefilterFrontEnd):'
276 275 milliseconds=100, oneShot=True)
277 276
278 277
278 def execute_command(self, command, hidden=False):
279 """ Execute a command, not only in the model, but also in the
280 view.
281 """
282 if hidden:
283 return self.shell.execute(command)
284 else:
285 # XXX: we are not storing the input buffer previous to the
286 # execution, as this forces us to run the execution
287 # input_buffer a yield, which is not good.
288 ##current_buffer = self.shell.control.input_buffer
289 command = command.rstrip()
290 if len(command.split('\n')) > 1:
291 # The input command is several lines long, we need to
292 # force the execution to happen
293 command += '\n'
294 cleaned_command = self.prefilter_input(command)
295 self.input_buffer = command
296 # Do not use wx.Yield() (aka GUI.process_events()) to avoid
297 # recursive yields.
298 self.ProcessEvent(wx.PaintEvent())
299 self.write('\n')
300 if not self.is_complete(cleaned_command + '\n'):
301 self._colorize_input_buffer()
302 self.render_error('Incomplete or invalid input')
303 self.new_prompt(self.input_prompt_template.substitute(
304 number=(self.last_result['number'] + 1)))
305 return False
306 self._on_enter()
307 return True
308
309
279 310 #--------------------------------------------------------------------------
280 311 # LineFrontEnd interface
281 312 #--------------------------------------------------------------------------
@@ -16,13 +16,6 b' __docformat__ = "restructuredtext en"'
16 16 # the file COPYING, distributed as part of this software.
17 17 #-------------------------------------------------------------------------------
18 18
19 #-------------------------------------------------------------------------------
20 # Imports
21 #-------------------------------------------------------------------------------
22 import string
23 import uuid
24 import _ast
25
26 19 try:
27 20 from zope.interface import Interface, Attribute, implements, classProvides
28 21 except ImportError:
@@ -8,8 +8,6 b' which can also be useful as templates for writing new, application-specific'
8 8 managers.
9 9 """
10 10
11 from __future__ import with_statement
12
13 11 __docformat__ = "restructuredtext en"
14 12
15 13 #-------------------------------------------------------------------------------
@@ -16,10 +16,12 b' __docformat__ = "restructuredtext en"'
16 16 import os
17 17 from cStringIO import StringIO
18 18
19 from IPython.testing import decorators as testdec
19 # FIXME:
20 import nose
21 import sys
22 if sys.platform == 'win32':
23 raise nose.SkipTest("These tests are not reliable under windows")
20 24
21 # FIXME
22 @testdec.skip("This doesn't work under Windows")
23 25 def test_redirector():
24 26 """ Checks that the redirector can be used to do synchronous capture.
25 27 """
@@ -40,8 +42,6 b' def test_redirector():'
40 42 result2 = "".join("%ic\n%i\n" %(i, i) for i in range(10))
41 43 assert result1 == result2
42 44
43 # FIXME
44 @testdec.skip("This doesn't work under Windows")
45 45 def test_redirector_output_trap():
46 46 """ This test check not only that the redirector_output_trap does
47 47 trap the output, but also that it does it in a gready way, that
@@ -1,4 +1,6 b''
1 from __future__ import with_statement
1 #from __future__ import with_statement
2
3 # XXX This file is currently disabled to preserve 2.4 compatibility.
2 4
3 5 #def test_simple():
4 6 if 0:
@@ -25,17 +27,17 b' if 0:'
25 27
26 28 mec.pushAll()
27 29
28 with parallel as pr:
29 # A comment
30 remote() # this means the code below only runs remotely
31 print 'Hello remote world'
32 x = range(10)
33 # Comments are OK
34 # Even misindented.
35 y = x+1
30 ## with parallel as pr:
31 ## # A comment
32 ## remote() # this means the code below only runs remotely
33 ## print 'Hello remote world'
34 ## x = range(10)
35 ## # Comments are OK
36 ## # Even misindented.
37 ## y = x+1
36 38
37 39
38 with pfor('i',sequence) as pr:
39 print x[i]
40 ## with pfor('i',sequence) as pr:
41 ## print x[i]
40 42
41 43 print pr.x + pr.y
@@ -45,7 +45,10 b' def mergesort(list_of_lists, key=None):'
45 45 for i, itr in enumerate(iter(pl) for pl in list_of_lists):
46 46 try:
47 47 item = itr.next()
48 toadd = (key(item), i, item, itr) if key else (item, i, itr)
48 if key:
49 toadd = (key(item), i, item, itr)
50 else:
51 toadd = (item, i, itr)
49 52 heap.append(toadd)
50 53 except StopIteration:
51 54 pass
@@ -15,8 +15,8 b" What's new"
15 15 1.4.2 Bug fixes
16 16 1.4.3 Backwards incompatible changes
17 17 2 Release 0.8.4
18 3 Release 0.8.2
19 4 Release 0.8.3
18 3 Release 0.8.3
19 4 Release 0.8.2
20 20 5 Older releases
21 21 ..
22 22
@@ -27,6 +27,12 b' Release 0.9'
27 27 New features
28 28 ------------
29 29
30 * All furl files and security certificates are now put in a read-only directory
31 named ~./ipython/security.
32
33 * A single function :func:`get_ipython_dir`, in :mod:`IPython.genutils` that
34 determines the user's IPython directory in a robust manner.
35
30 36 * Laurent's WX application has been given a top-level script called ipython-wx,
31 37 and it has received numerous fixes. We expect this code to be
32 38 architecturally better integrated with Gael's WX 'ipython widget' over the
@@ -58,95 +64,133 b' New features'
58 64 time and report problems), but it now works for the developers. We are
59 65 working hard on continuing to improve it, as this was probably IPython's
60 66 major Achilles heel (the lack of proper test coverage made it effectively
61 impossible to do large-scale refactoring).
62
63 * The notion of a task has been completely reworked. An `ITask` interface has
64 been created. This interface defines the methods that tasks need to implement.
65 These methods are now responsible for things like submitting tasks and processing
66 results. There are two basic task types: :class:`IPython.kernel.task.StringTask`
67 (this is the old `Task` object, but renamed) and the new
68 :class:`IPython.kernel.task.MapTask`, which is based on a function.
69 * A new interface, :class:`IPython.kernel.mapper.IMapper` has been defined to
70 standardize the idea of a `map` method. This interface has a single
71 `map` method that has the same syntax as the built-in `map`. We have also defined
72 a `mapper` factory interface that creates objects that implement
73 :class:`IPython.kernel.mapper.IMapper` for different controllers. Both
74 the multiengine and task controller now have mapping capabilties.
75 * The parallel function capabilities have been reworks. The major changes are that
76 i) there is now an `@parallel` magic that creates parallel functions, ii)
77 the syntax for mulitple variable follows that of `map`, iii) both the
78 multiengine and task controller now have a parallel function implementation.
79 * All of the parallel computing capabilities from `ipython1-dev` have been merged into
80 IPython proper. This resulted in the following new subpackages:
81 :mod:`IPython.kernel`, :mod:`IPython.kernel.core`, :mod:`IPython.config`,
82 :mod:`IPython.tools` and :mod:`IPython.testing`.
83 * As part of merging in the `ipython1-dev` stuff, the `setup.py` script and friends
84 have been completely refactored. Now we are checking for dependencies using
85 the approach that matplotlib uses.
86 * The documentation has been completely reorganized to accept the documentation
87 from `ipython1-dev`.
88 * We have switched to using Foolscap for all of our network protocols in
89 :mod:`IPython.kernel`. This gives us secure connections that are both encrypted
90 and authenticated.
91 * We have a brand new `COPYING.txt` files that describes the IPython license
92 and copyright. The biggest change is that we are putting "The IPython
93 Development Team" as the copyright holder. We give more details about exactly
94 what this means in this file. All developer should read this and use the new
95 banner in all IPython source code files.
96 * sh profile: ./foo runs foo as system command, no need to do !./foo anymore
97 * String lists now support 'sort(field, nums = True)' method (to easily
98 sort system command output). Try it with 'a = !ls -l ; a.sort(1, nums=1)'
99 * '%cpaste foo' now assigns the pasted block as string list, instead of string
100 * The ipcluster script now run by default with no security. This is done because
101 the main usage of the script is for starting things on localhost. Eventually
102 when ipcluster is able to start things on other hosts, we will put security
103 back.
104 * 'cd --foo' searches directory history for string foo, and jumps to that dir.
105 Last part of dir name is checked first. If no matches for that are found,
106 look at the whole path.
67 impossible to do large-scale refactoring). The full test suite can now
68 be run using the :command:`iptest` command line program.
69
70 * The notion of a task has been completely reworked. An `ITask` interface has
71 been created. This interface defines the methods that tasks need to
72 implement. These methods are now responsible for things like submitting
73 tasks and processing results. There are two basic task types:
74 :class:`IPython.kernel.task.StringTask` (this is the old `Task` object, but
75 renamed) and the new :class:`IPython.kernel.task.MapTask`, which is based on
76 a function.
77
78 * A new interface, :class:`IPython.kernel.mapper.IMapper` has been defined to
79 standardize the idea of a `map` method. This interface has a single `map`
80 method that has the same syntax as the built-in `map`. We have also defined
81 a `mapper` factory interface that creates objects that implement
82 :class:`IPython.kernel.mapper.IMapper` for different controllers. Both the
83 multiengine and task controller now have mapping capabilties.
84
85 * The parallel function capabilities have been reworks. The major changes are
86 that i) there is now an `@parallel` magic that creates parallel functions,
87 ii) the syntax for mulitple variable follows that of `map`, iii) both the
88 multiengine and task controller now have a parallel function implementation.
89
90 * All of the parallel computing capabilities from `ipython1-dev` have been
91 merged into IPython proper. This resulted in the following new subpackages:
92 :mod:`IPython.kernel`, :mod:`IPython.kernel.core`, :mod:`IPython.config`,
93 :mod:`IPython.tools` and :mod:`IPython.testing`.
94
95 * As part of merging in the `ipython1-dev` stuff, the `setup.py` script and
96 friends have been completely refactored. Now we are checking for
97 dependencies using the approach that matplotlib uses.
98
99 * The documentation has been completely reorganized to accept the documentation
100 from `ipython1-dev`.
101
102 * We have switched to using Foolscap for all of our network protocols in
103 :mod:`IPython.kernel`. This gives us secure connections that are both
104 encrypted and authenticated.
107 105
106 * We have a brand new `COPYING.txt` files that describes the IPython license
107 and copyright. The biggest change is that we are putting "The IPython
108 Development Team" as the copyright holder. We give more details about
109 exactly what this means in this file. All developer should read this and use
110 the new banner in all IPython source code files.
111
112 * sh profile: ./foo runs foo as system command, no need to do !./foo anymore
113
114 * String lists now support ``sort(field, nums = True)`` method (to easily sort
115 system command output). Try it with ``a = !ls -l ; a.sort(1, nums=1)``.
116
117 * '%cpaste foo' now assigns the pasted block as string list, instead of string
118
119 * The ipcluster script now run by default with no security. This is done
120 because the main usage of the script is for starting things on localhost.
121 Eventually when ipcluster is able to start things on other hosts, we will put
122 security back.
123
124 * 'cd --foo' searches directory history for string foo, and jumps to that dir.
125 Last part of dir name is checked first. If no matches for that are found,
126 look at the whole path.
127
128
108 129 Bug fixes
109 130 ---------
110 131
111 * The colors escapes in the multiengine client are now turned off on win32 as they
112 don't print correctly.
113 * The :mod:`IPython.kernel.scripts.ipengine` script was exec'ing mpi_import_statement
114 incorrectly, which was leading the engine to crash when mpi was enabled.
115 * A few subpackages has missing `__init__.py` files.
116 * The documentation is only created is Sphinx is found. Previously, the `setup.py`
117 script would fail if it was missing.
118 * Greedy 'cd' completion has been disabled again (it was enabled in 0.8.4)
132 * The Windows installer has been fixed. Now all IPython scripts have ``.bat``
133 versions created. Also, the Start Menu shortcuts have been updated.
134
135 * The colors escapes in the multiengine client are now turned off on win32 as
136 they don't print correctly.
137
138 * The :mod:`IPython.kernel.scripts.ipengine` script was exec'ing
139 mpi_import_statement incorrectly, which was leading the engine to crash when
140 mpi was enabled.
141
142 * A few subpackages had missing ``__init__.py`` files.
143
144 * The documentation is only created if Sphinx is found. Previously, the
145 ``setup.py`` script would fail if it was missing.
146
147 * Greedy ``cd`` completion has been disabled again (it was enabled in 0.8.4) as
148 it caused problems on certain platforms.
119 149
120 150
121 151 Backwards incompatible changes
122 152 ------------------------------
123 153
154 * The ``clusterfile`` options of the :command:`ipcluster` command has been
155 removed as it was not working and it will be replaced soon by something much
156 more robust.
157
158 * The :mod:`IPython.kernel` configuration now properly find the user's
159 IPython directory.
160
124 161 * In ipapi, the :func:`make_user_ns` function has been replaced with
125 162 :func:`make_user_namespaces`, to support dict subclasses in namespace
126 163 creation.
127 164
128 * :class:`IPython.kernel.client.Task` has been renamed
129 :class:`IPython.kernel.client.StringTask` to make way for new task types.
130 * The keyword argument `style` has been renamed `dist` in `scatter`, `gather`
131 and `map`.
132 * Renamed the values that the rename `dist` keyword argument can have from
133 `'basic'` to `'b'`.
134 * IPython has a larger set of dependencies if you want all of its capabilities.
135 See the `setup.py` script for details.
136 * The constructors for :class:`IPython.kernel.client.MultiEngineClient` and
137 :class:`IPython.kernel.client.TaskClient` no longer take the (ip,port) tuple.
138 Instead they take the filename of a file that contains the FURL for that
139 client. If the FURL file is in your IPYTHONDIR, it will be found automatically
140 and the constructor can be left empty.
141 * The asynchronous clients in :mod:`IPython.kernel.asyncclient` are now created
142 using the factory functions :func:`get_multiengine_client` and
143 :func:`get_task_client`. These return a `Deferred` to the actual client.
144 * The command line options to `ipcontroller` and `ipengine` have changed to
145 reflect the new Foolscap network protocol and the FURL files. Please see the
146 help for these scripts for details.
147 * The configuration files for the kernel have changed because of the Foolscap stuff.
148 If you were using custom config files before, you should delete them and regenerate
149 new ones.
165 * :class:`IPython.kernel.client.Task` has been renamed
166 :class:`IPython.kernel.client.StringTask` to make way for new task types.
167
168 * The keyword argument `style` has been renamed `dist` in `scatter`, `gather`
169 and `map`.
170
171 * Renamed the values that the rename `dist` keyword argument can have from
172 `'basic'` to `'b'`.
173
174 * IPython has a larger set of dependencies if you want all of its capabilities.
175 See the `setup.py` script for details.
176
177 * The constructors for :class:`IPython.kernel.client.MultiEngineClient` and
178 :class:`IPython.kernel.client.TaskClient` no longer take the (ip,port) tuple.
179 Instead they take the filename of a file that contains the FURL for that
180 client. If the FURL file is in your IPYTHONDIR, it will be found automatically
181 and the constructor can be left empty.
182
183 * The asynchronous clients in :mod:`IPython.kernel.asyncclient` are now created
184 using the factory functions :func:`get_multiengine_client` and
185 :func:`get_task_client`. These return a `Deferred` to the actual client.
186
187 * The command line options to `ipcontroller` and `ipengine` have changed to
188 reflect the new Foolscap network protocol and the FURL files. Please see the
189 help for these scripts for details.
190
191 * The configuration files for the kernel have changed because of the Foolscap
192 stuff. If you were using custom config files before, you should delete them
193 and regenerate new ones.
150 194
151 195 Changes merged in from IPython1
152 196 -------------------------------
@@ -154,89 +198,109 b' Changes merged in from IPython1'
154 198 New features
155 199 ............
156 200
157 * Much improved ``setup.py`` and ``setupegg.py`` scripts. Because Twisted
158 and zope.interface are now easy installable, we can declare them as dependencies
159 in our setupegg.py script.
160 * IPython is now compatible with Twisted 2.5.0 and 8.x.
161 * Added a new example of how to use :mod:`ipython1.kernel.asynclient`.
162 * Initial draft of a process daemon in :mod:`ipython1.daemon`. This has not
163 been merged into IPython and is still in `ipython1-dev`.
164 * The ``TaskController`` now has methods for getting the queue status.
165 * The ``TaskResult`` objects not have information about how long the task
166 took to run.
167 * We are attaching additional attributes to exceptions ``(_ipython_*)`` that
168 we use to carry additional info around.
169 * New top-level module :mod:`asyncclient` that has asynchronous versions (that
170 return deferreds) of the client classes. This is designed to users who want
171 to run their own Twisted reactor
172 * All the clients in :mod:`client` are now based on Twisted. This is done by
173 running the Twisted reactor in a separate thread and using the
174 :func:`blockingCallFromThread` function that is in recent versions of Twisted.
175 * Functions can now be pushed/pulled to/from engines using
176 :meth:`MultiEngineClient.push_function` and :meth:`MultiEngineClient.pull_function`.
177 * Gather/scatter are now implemented in the client to reduce the work load
178 of the controller and improve performance.
179 * Complete rewrite of the IPython docuementation. All of the documentation
180 from the IPython website has been moved into docs/source as restructured
181 text documents. PDF and HTML documentation are being generated using
182 Sphinx.
183 * New developer oriented documentation: development guidelines and roadmap.
184 * Traditional ``ChangeLog`` has been changed to a more useful ``changes.txt`` file
185 that is organized by release and is meant to provide something more relevant
186 for users.
201 * Much improved ``setup.py`` and ``setupegg.py`` scripts. Because Twisted and
202 zope.interface are now easy installable, we can declare them as dependencies
203 in our setupegg.py script.
204
205 * IPython is now compatible with Twisted 2.5.0 and 8.x.
206
207 * Added a new example of how to use :mod:`ipython1.kernel.asynclient`.
208
209 * Initial draft of a process daemon in :mod:`ipython1.daemon`. This has not
210 been merged into IPython and is still in `ipython1-dev`.
211
212 * The ``TaskController`` now has methods for getting the queue status.
213
214 * The ``TaskResult`` objects not have information about how long the task
215 took to run.
216
217 * We are attaching additional attributes to exceptions ``(_ipython_*)`` that
218 we use to carry additional info around.
219
220 * New top-level module :mod:`asyncclient` that has asynchronous versions (that
221 return deferreds) of the client classes. This is designed to users who want
222 to run their own Twisted reactor.
223
224 * All the clients in :mod:`client` are now based on Twisted. This is done by
225 running the Twisted reactor in a separate thread and using the
226 :func:`blockingCallFromThread` function that is in recent versions of Twisted.
227
228 * Functions can now be pushed/pulled to/from engines using
229 :meth:`MultiEngineClient.push_function` and
230 :meth:`MultiEngineClient.pull_function`.
231
232 * Gather/scatter are now implemented in the client to reduce the work load
233 of the controller and improve performance.
234
235 * Complete rewrite of the IPython docuementation. All of the documentation
236 from the IPython website has been moved into docs/source as restructured
237 text documents. PDF and HTML documentation are being generated using
238 Sphinx.
239
240 * New developer oriented documentation: development guidelines and roadmap.
241
242 * Traditional ``ChangeLog`` has been changed to a more useful ``changes.txt``
243 file that is organized by release and is meant to provide something more
244 relevant for users.
187 245
188 246 Bug fixes
189 247 .........
190 248
191 * Created a proper ``MANIFEST.in`` file to create source distributions.
192 * Fixed a bug in the ``MultiEngine`` interface. Previously, multi-engine
193 actions were being collected with a :class:`DeferredList` with
194 ``fireononeerrback=1``. This meant that methods were returning
195 before all engines had given their results. This was causing extremely odd
196 bugs in certain cases. To fix this problem, we have 1) set
197 ``fireononeerrback=0`` to make sure all results (or exceptions) are in
198 before returning and 2) introduced a :exc:`CompositeError` exception
199 that wraps all of the engine exceptions. This is a huge change as it means
200 that users will have to catch :exc:`CompositeError` rather than the actual
201 exception.
249 * Created a proper ``MANIFEST.in`` file to create source distributions.
250
251 * Fixed a bug in the ``MultiEngine`` interface. Previously, multi-engine
252 actions were being collected with a :class:`DeferredList` with
253 ``fireononeerrback=1``. This meant that methods were returning
254 before all engines had given their results. This was causing extremely odd
255 bugs in certain cases. To fix this problem, we have 1) set
256 ``fireononeerrback=0`` to make sure all results (or exceptions) are in
257 before returning and 2) introduced a :exc:`CompositeError` exception
258 that wraps all of the engine exceptions. This is a huge change as it means
259 that users will have to catch :exc:`CompositeError` rather than the actual
260 exception.
202 261
203 262 Backwards incompatible changes
204 263 ..............................
205 264
206 * All names have been renamed to conform to the lowercase_with_underscore
207 convention. This will require users to change references to all names like
208 ``queueStatus`` to ``queue_status``.
209 * Previously, methods like :meth:`MultiEngineClient.push` and
210 :meth:`MultiEngineClient.push` used ``*args`` and ``**kwargs``. This was
211 becoming a problem as we weren't able to introduce new keyword arguments into
212 the API. Now these methods simple take a dict or sequence. This has also allowed
213 us to get rid of the ``*All`` methods like :meth:`pushAll` and :meth:`pullAll`.
214 These things are now handled with the ``targets`` keyword argument that defaults
215 to ``'all'``.
216 * The :attr:`MultiEngineClient.magicTargets` has been renamed to
217 :attr:`MultiEngineClient.targets`.
218 * All methods in the MultiEngine interface now accept the optional keyword argument
219 ``block``.
220 * Renamed :class:`RemoteController` to :class:`MultiEngineClient` and
221 :class:`TaskController` to :class:`TaskClient`.
222 * Renamed the top-level module from :mod:`api` to :mod:`client`.
223 * Most methods in the multiengine interface now raise a :exc:`CompositeError` exception
224 that wraps the user's exceptions, rather than just raising the raw user's exception.
225 * Changed the ``setupNS`` and ``resultNames`` in the ``Task`` class to ``push``
226 and ``pull``.
265 * All names have been renamed to conform to the lowercase_with_underscore
266 convention. This will require users to change references to all names like
267 ``queueStatus`` to ``queue_status``.
268
269 * Previously, methods like :meth:`MultiEngineClient.push` and
270 :meth:`MultiEngineClient.push` used ``*args`` and ``**kwargs``. This was
271 becoming a problem as we weren't able to introduce new keyword arguments into
272 the API. Now these methods simple take a dict or sequence. This has also
273 allowed us to get rid of the ``*All`` methods like :meth:`pushAll` and
274 :meth:`pullAll`. These things are now handled with the ``targets`` keyword
275 argument that defaults to ``'all'``.
276
277 * The :attr:`MultiEngineClient.magicTargets` has been renamed to
278 :attr:`MultiEngineClient.targets`.
279
280 * All methods in the MultiEngine interface now accept the optional keyword
281 argument ``block``.
282
283 * Renamed :class:`RemoteController` to :class:`MultiEngineClient` and
284 :class:`TaskController` to :class:`TaskClient`.
285
286 * Renamed the top-level module from :mod:`api` to :mod:`client`.
287
288 * Most methods in the multiengine interface now raise a :exc:`CompositeError`
289 exception that wraps the user's exceptions, rather than just raising the raw
290 user's exception.
291
292 * Changed the ``setupNS`` and ``resultNames`` in the ``Task`` class to ``push``
293 and ``pull``.
227 294
295
228 296 Release 0.8.4
229 297 =============
230 298
231 Someone needs to describe what went into 0.8.4.
299 This was a quick release to fix an unfortunate bug that slipped into the 0.8.3
300 release. The ``--twisted`` option was disabled, as it turned out to be broken
301 across several platforms.
232 302
233 Release 0.8.2
234 =============
235 303
236 * %pushd/%popd behave differently; now "pushd /foo" pushes CURRENT directory
237 and jumps to /foo. The current behaviour is closer to the documented
238 behaviour, and should not trip anyone.
239
240 304 Release 0.8.3
241 305 =============
242 306
@@ -244,9 +308,18 b' Release 0.8.3'
244 308 it by passing -pydb command line argument to IPython. Note that setting
245 309 it in config file won't work.
246 310
311
312 Release 0.8.2
313 =============
314
315 * %pushd/%popd behave differently; now "pushd /foo" pushes CURRENT directory
316 and jumps to /foo. The current behaviour is closer to the documented
317 behaviour, and should not trip anyone.
318
319
247 320 Older releases
248 321 ==============
249 322
250 Changes in earlier releases of IPython are described in the older file ``ChangeLog``.
251 Please refer to this document for details.
323 Changes in earlier releases of IPython are described in the older file
324 ``ChangeLog``. Please refer to this document for details.
252 325
@@ -1,7 +1,6 b''
1 1 # -*- coding: utf-8 -*-
2 2 #
3 # IPython documentation build configuration file, created by
4 # sphinx-quickstart on Thu May 8 16:45:02 2008.
3 # IPython documentation build configuration file.
5 4
6 5 # NOTE: This file has been edited manually from the auto-generated one from
7 6 # sphinx. Do NOT delete and re-generate. If any changes from sphinx are
@@ -21,7 +20,11 b' import sys, os'
21 20 # If your extensions are in another directory, add it here. If the directory
22 21 # is relative to the documentation root, use os.path.abspath to make it
23 22 # absolute, like shown here.
24 #sys.path.append(os.path.abspath('some/directory'))
23 sys.path.append(os.path.abspath('../sphinxext'))
24
25 # Import support for ipython console session syntax highlighting (lives
26 # in the sphinxext directory defined above)
27 import ipython_console_highlighting
25 28
26 29 # We load the ipython release info into a dict by explicit execution
27 30 iprelease = {}
@@ -32,7 +35,11 b" execfile('../../IPython/Release.py',iprelease)"
32 35
33 36 # Add any Sphinx extension module names here, as strings. They can be extensions
34 37 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
35 #extensions = []
38 extensions = ['sphinx.ext.autodoc',
39 'inheritance_diagram', 'only_directives',
40 'ipython_console_highlighting',
41 # 'plot_directive', # disabled for now, needs matplotlib
42 ]
36 43
37 44 # Add any paths that contain templates here, relative to this directory.
38 45 templates_path = ['_templates']
@@ -67,7 +74,7 b" today_fmt = '%B %d, %Y'"
67 74
68 75 # List of directories, relative to source directories, that shouldn't be searched
69 76 # for source files.
70 #exclude_dirs = []
77 exclude_dirs = ['attic']
71 78
72 79 # If true, '()' will be appended to :func: etc. cross-reference text.
73 80 #add_function_parentheses = True
@@ -135,7 +142,7 b" html_last_updated_fmt = '%b %d, %Y'"
135 142 #html_file_suffix = ''
136 143
137 144 # Output file base name for HTML help builder.
138 htmlhelp_basename = 'IPythondoc'
145 htmlhelp_basename = 'ipythondoc'
139 146
140 147
141 148 # Options for LaTeX output
@@ -151,10 +158,7 b" latex_font_size = '11pt'"
151 158 # (source start file, target name, title, author, document class [howto/manual]).
152 159
153 160 latex_documents = [ ('index', 'ipython.tex', 'IPython Documentation',
154 ur"""Brian Granger, Fernando Pérez and Ville Vainio\\
155 \ \\
156 With contributions from:\\
157 Benjamin Ragan-Kelley and Barry Wark.""",
161 ur"""The IPython Development Team""",
158 162 'manual'),
159 163 ]
160 164
@@ -176,5 +180,8 b" latex_documents = [ ('index', 'ipython.tex', 'IPython Documentation',"
176 180 #latex_use_modindex = True
177 181
178 182
179 # Cleanup: delete release info to avoid pickling errors from sphinx
183 # Cleanup
184 # -------
185 # delete release info to avoid pickling errors from sphinx
186
180 187 del iprelease
@@ -18,6 +18,8 b' time. A hybrid approach of specifying a few options in ipythonrc and'
18 18 doing the more advanced configuration in ipy_user_conf.py is also
19 19 possible.
20 20
21 .. _ipythonrc:
22
21 23 The ipythonrc approach
22 24 ======================
23 25
@@ -36,11 +38,11 b' fairly primitive). Note that these are not python files, and this is'
36 38 deliberate, because it allows us to do some things which would be quite
37 39 tricky to implement if they were normal python files.
38 40
39 First, an rcfile can contain permanent default values for almost all
40 command line options (except things like -help or -Version). Sec
41 `command line options`_ contains a description of all command-line
42 options. However, values you explicitly specify at the command line
43 override the values defined in the rcfile.
41 First, an rcfile can contain permanent default values for almost all command
42 line options (except things like -help or -Version). :ref:`This section
43 <command_line_options>` contains a description of all command-line
44 options. However, values you explicitly specify at the command line override
45 the values defined in the rcfile.
44 46
45 47 Besides command line option values, the rcfile can specify values for
46 48 certain extra special options which are not available at the command
@@ -266,13 +268,13 b' which look like this::'
266 268 IPython profiles
267 269 ================
268 270
269 As we already mentioned, IPython supports the -profile command-line
270 option (see sec. `command line options`_). A profile is nothing more
271 than a particular configuration file like your basic ipythonrc one,
272 but with particular customizations for a specific purpose. When you
273 start IPython with 'ipython -profile <name>', it assumes that in your
274 IPYTHONDIR there is a file called ipythonrc-<name> or
275 ipy_profile_<name>.py, and loads it instead of the normal ipythonrc.
271 As we already mentioned, IPython supports the -profile command-line option (see
272 :ref:`here <command_line_options>`). A profile is nothing more than a
273 particular configuration file like your basic ipythonrc one, but with
274 particular customizations for a specific purpose. When you start IPython with
275 'ipython -profile <name>', it assumes that in your IPYTHONDIR there is a file
276 called ipythonrc-<name> or ipy_profile_<name>.py, and loads it instead of the
277 normal ipythonrc.
276 278
277 279 This system allows you to maintain multiple configurations which load
278 280 modules, set options, define functions, etc. suitable for different
@@ -11,28 +11,27 b' in a directory named by default $HOME/.ipython. You can change this by'
11 11 defining the environment variable IPYTHONDIR, or at runtime with the
12 12 command line option -ipythondir.
13 13
14 If all goes well, the first time you run IPython it should
15 automatically create a user copy of the config directory for you,
16 based on its builtin defaults. You can look at the files it creates to
17 learn more about configuring the system. The main file you will modify
18 to configure IPython's behavior is called ipythonrc (with a .ini
19 extension under Windows), included for reference in `ipythonrc`_
20 section. This file is very commented and has many variables you can
21 change to suit your taste, you can find more details in
22 Sec. customization_. Here we discuss the basic things you will want to
23 make sure things are working properly from the beginning.
14 If all goes well, the first time you run IPython it should automatically create
15 a user copy of the config directory for you, based on its builtin defaults. You
16 can look at the files it creates to learn more about configuring the
17 system. The main file you will modify to configure IPython's behavior is called
18 ipythonrc (with a .ini extension under Windows), included for reference
19 :ref:`here <ipythonrc>`. This file is very commented and has many variables you
20 can change to suit your taste, you can find more details :ref:`here
21 <customization>`. Here we discuss the basic things you will want to make sure
22 things are working properly from the beginning.
24 23
25 24
26 .. _Accessing help:
25 .. _accessing_help:
27 26
28 27 Access to the Python help system
29 28 ================================
30 29
31 This is true for Python in general (not just for IPython): you should
32 have an environment variable called PYTHONDOCS pointing to the directory
33 where your HTML Python documentation lives. In my system it's
34 /usr/share/doc/python-docs-2.3.4/html, check your local details or ask
35 your systems administrator.
30 This is true for Python in general (not just for IPython): you should have an
31 environment variable called PYTHONDOCS pointing to the directory where your
32 HTML Python documentation lives. In my system it's
33 :file:`/usr/share/doc/python-doc/html`, check your local details or ask your
34 systems administrator.
36 35
37 36 This is the directory which holds the HTML version of the Python
38 37 manuals. Unfortunately it seems that different Linux distributions
@@ -40,8 +39,9 b' package these files differently, so you may have to look around a bit.'
40 39 Below I show the contents of this directory on my system for reference::
41 40
42 41 [html]> ls
43 about.dat acks.html dist/ ext/ index.html lib/ modindex.html
44 stdabout.dat tut/ about.html api/ doc/ icons/ inst/ mac/ ref/ style.css
42 about.html dist/ icons/ lib/ python2.5.devhelp.gz whatsnew/
43 acks.html doc/ index.html mac/ ref/
44 api/ ext/ inst/ modindex.html tut/
45 45
46 46 You should really make sure this variable is correctly set so that
47 47 Python's pydoc-based help system works. It is a powerful and convenient
@@ -108,6 +108,8 b' The following terminals seem to handle the color sequences fine:'
108 108 support under cygwin, please post to the IPython mailing list so
109 109 this issue can be resolved for all users.
110 110
111 .. _pyreadline: https://code.launchpad.net/pyreadline
112
111 113 These have shown problems:
112 114
113 115 * Windows command prompt in WinXP/2k logged into a Linux machine via
@@ -157,13 +159,12 b' $HOME/.ipython/ipythonrc and set the colors option to the desired value.'
157 159 Object details (types, docstrings, source code, etc.)
158 160 =====================================================
159 161
160 IPython has a set of special functions for studying the objects you
161 are working with, discussed in detail in Sec. `dynamic object
162 information`_. But this system relies on passing information which is
163 longer than your screen through a data pager, such as the common Unix
164 less and more programs. In order to be able to see this information in
165 color, your pager needs to be properly configured. I strongly
166 recommend using less instead of more, as it seems that more simply can
162 IPython has a set of special functions for studying the objects you are working
163 with, discussed in detail :ref:`here <dynamic_object_info>`. But this system
164 relies on passing information which is longer than your screen through a data
165 pager, such as the common Unix less and more programs. In order to be able to
166 see this information in color, your pager needs to be properly configured. I
167 strongly recommend using less instead of more, as it seems that more simply can
167 168 not understand colored text correctly.
168 169
169 170 In order to configure less as your default pager, do the following:
@@ -4,24 +4,39 b''
4 4 Credits
5 5 =======
6 6
7 IPython is mainly developed by Fernando Pérez
8 <Fernando.Perez@colorado.edu>, but the project was born from mixing in
9 Fernando's code with the IPP project by Janko Hauser
10 <jhauser-AT-zscout.de> and LazyPython by Nathan Gray
11 <n8gray-AT-caltech.edu>. For all IPython-related requests, please
12 contact Fernando.
13
14 As of early 2006, the following developers have joined the core team:
15
16 * [Robert Kern] <rkern-AT-enthought.com>: co-mentored the 2005
17 Google Summer of Code project to develop python interactive
18 notebooks (XML documents) and graphical interface. This project
19 was awarded to the students Tzanko Matev <tsanko-AT-gmail.com> and
20 Toni Alatalo <antont-AT-an.org>
21 * [Brian Granger] <bgranger-AT-scu.edu>: extending IPython to allow
22 support for interactive parallel computing.
23 * [Ville Vainio] <vivainio-AT-gmail.com>: Ville is the new
24 maintainer for the main trunk of IPython after version 0.7.1.
7 IPython is led by Fernando Pérez.
8
9 As of this writing, the following developers have joined the core team:
10
11 * [Robert Kern] <rkern-AT-enthought.com>: co-mentored the 2005
12 Google Summer of Code project to develop python interactive
13 notebooks (XML documents) and graphical interface. This project
14 was awarded to the students Tzanko Matev <tsanko-AT-gmail.com> and
15 Toni Alatalo <antont-AT-an.org>.
16
17 * [Brian Granger] <ellisonbg-AT-gmail.com>: extending IPython to allow
18 support for interactive parallel computing.
19
20 * [Benjamin (Min) Ragan-Kelley]: key work on IPython's parallel
21 computing infrastructure.
22
23 * [Ville Vainio] <vivainio-AT-gmail.com>: Ville has made many improvements
24 to the core of IPython and was the maintainer of the main IPython
25 trunk from version 0.7.1 to 0.8.4.
26
27 * [Gael Varoquaux] <gael.varoquaux-AT-normalesup.org>: work on the merged
28 architecture for the interpreter as of version 0.9, implementing a new WX GUI
29 based on this system.
30
31 * [Barry Wark] <barrywark-AT-gmail.com>: implementing a new Cocoa GUI, as well
32 as work on the new interpreter architecture and Twisted support.
33
34 * [Laurent Dufrechou] <laurent.dufrechou-AT-gmail.com>: development of the WX
35 GUI support.
36
37 * [Jörgen Stenarson] <jorgen.stenarson-AT-bostream.nu>: maintainer of the
38 PyReadline project, necessary for IPython under windows.
39
25 40
26 41 The IPython project is also very grateful to:
27 42
@@ -50,90 +65,143 b" an O'Reilly Python editor. His Oct/11/2001 article about IPP and"
50 65 LazyPython, was what got this project started. You can read it at:
51 66 http://www.onlamp.com/pub/a/python/2001/10/11/pythonnews.html.
52 67
53 And last but not least, all the kind IPython users who have emailed new
54 code, bug reports, fixes, comments and ideas. A brief list follows,
55 please let me know if I have ommitted your name by accident:
56
57 * [Jack Moffit] <jack-AT-xiph.org> Bug fixes, including the infamous
58 color problem. This bug alone caused many lost hours and
59 frustration, many thanks to him for the fix. I've always been a
60 fan of Ogg & friends, now I have one more reason to like these folks.
61 Jack is also contributing with Debian packaging and many other
62 things.
63 * [Alexander Schmolck] <a.schmolck-AT-gmx.net> Emacs work, bug
64 reports, bug fixes, ideas, lots more. The ipython.el mode for
65 (X)Emacs is Alex's code, providing full support for IPython under
66 (X)Emacs.
67 * [Andrea Riciputi] <andrea.riciputi-AT-libero.it> Mac OSX
68 information, Fink package management.
69 * [Gary Bishop] <gb-AT-cs.unc.edu> Bug reports, and patches to work
70 around the exception handling idiosyncracies of WxPython. Readline
71 and color support for Windows.
72 * [Jeffrey Collins] <Jeff.Collins-AT-vexcel.com> Bug reports. Much
73 improved readline support, including fixes for Python 2.3.
74 * [Dryice Liu] <dryice-AT-liu.com.cn> FreeBSD port.
75 * [Mike Heeter] <korora-AT-SDF.LONESTAR.ORG>
76 * [Christopher Hart] <hart-AT-caltech.edu> PDB integration.
77 * [Milan Zamazal] <pdm-AT-zamazal.org> Emacs info.
78 * [Philip Hisley] <compsys-AT-starpower.net>
79 * [Holger Krekel] <pyth-AT-devel.trillke.net> Tab completion, lots
80 more.
81 * [Robin Siebler] <robinsiebler-AT-starband.net>
82 * [Ralf Ahlbrink] <ralf_ahlbrink-AT-web.de>
83 * [Thorsten Kampe] <thorsten-AT-thorstenkampe.de>
84 * [Fredrik Kant] <fredrik.kant-AT-front.com> Windows setup.
85 * [Syver Enstad] <syver-en-AT-online.no> Windows setup.
86 * [Richard] <rxe-AT-renre-europe.com> Global embedding.
87 * [Hayden Callow] <h.callow-AT-elec.canterbury.ac.nz> Gnuplot.py 1.6
88 compatibility.
89 * [Leonardo Santagada] <retype-AT-terra.com.br> Fixes for Windows
90 installation.
91 * [Christopher Armstrong] <radix-AT-twistedmatrix.com> Bugfixes.
92 * [Francois Pinard] <pinard-AT-iro.umontreal.ca> Code and
93 documentation fixes.
94 * [Cory Dodt] <cdodt-AT-fcoe.k12.ca.us> Bug reports and Windows
95 ideas. Patches for Windows installer.
96 * [Olivier Aubert] <oaubert-AT-bat710.univ-lyon1.fr> New magics.
97 * [King C. Shu] <kingshu-AT-myrealbox.com> Autoindent patch.
98 * [Chris Drexler] <chris-AT-ac-drexler.de> Readline packages for
99 Win32/CygWin.
100 * [Gustavo Cordova Avila] <gcordova-AT-sismex.com> EvalDict code for
101 nice, lightweight string interpolation.
102 * [Kasper Souren] <Kasper.Souren-AT-ircam.fr> Bug reports, ideas.
103 * [Gever Tulley] <gever-AT-helium.com> Code contributions.
104 * [Ralf Schmitt] <ralf-AT-brainbot.com> Bug reports & fixes.
105 * [Oliver Sander] <osander-AT-gmx.de> Bug reports.
106 * [Rod Holland] <rhh-AT-structurelabs.com> Bug reports and fixes to
107 logging module.
108 * [Daniel 'Dang' Griffith] <pythondev-dang-AT-lazytwinacres.net>
109 Fixes, enhancement suggestions for system shell use.
110 * [Viktor Ransmayr] <viktor.ransmayr-AT-t-online.de> Tests and
111 reports on Windows installation issues. Contributed a true Windows
112 binary installer.
113 * [Mike Salib] <msalib-AT-mit.edu> Help fixing a subtle bug related
114 to traceback printing.
115 * [W.J. van der Laan] <gnufnork-AT-hetdigitalegat.nl> Bash-like
116 prompt specials.
117 * [Antoon Pardon] <Antoon.Pardon-AT-rece.vub.ac.be> Critical fix for
118 the multithreaded IPython.
119 * [John Hunter] <jdhunter-AT-nitace.bsd.uchicago.edu> Matplotlib
120 author, helped with all the development of support for matplotlib
121 in IPyhton, including making necessary changes to matplotlib itself.
122 * [Matthew Arnison] <maffew-AT-cat.org.au> Bug reports, '%run -d' idea.
123 * [Prabhu Ramachandran] <prabhu_r-AT-users.sourceforge.net> Help
124 with (X)Emacs support, threading patches, ideas...
125 * [Norbert Tretkowski] <tretkowski-AT-inittab.de> help with Debian
126 packaging and distribution.
127 * [George Sakkis] <gsakkis-AT-eden.rutgers.edu> New matcher for
128 tab-completing named arguments of user-defined functions.
129 * [Jörgen Stenarson] <jorgen.stenarson-AT-bostream.nu> Wildcard
130 support implementation for searching namespaces.
131 * [Vivian De Smedt] <vivian-AT-vdesmedt.com> Debugger enhancements,
132 so that when pdb is activated from within IPython, coloring, tab
133 completion and other features continue to work seamlessly.
134 * [Scott Tsai] <scottt958-AT-yahoo.com.tw> Support for automatic
135 editor invocation on syntax errors (see
136 http://www.scipy.net/roundup/ipython/issue36).
137 * [Alexander Belchenko] <bialix-AT-ukr.net> Improvements for win32
138 paging system.
139 * [Will Maier] <willmaier-AT-ml1.net> Official OpenBSD port. No newline at end of file
68 And last but not least, all the kind IPython users who have emailed new code,
69 bug reports, fixes, comments and ideas. A brief list follows, please let us
70 know if we have ommitted your name by accident:
71
72 * Dan Milstein <danmil-AT-comcast.net>. A bold refactoring of the
73 core prefilter stuff in the IPython interpreter.
74
75 * [Jack Moffit] <jack-AT-xiph.org> Bug fixes, including the infamous
76 color problem. This bug alone caused many lost hours and
77 frustration, many thanks to him for the fix. I've always been a
78 fan of Ogg & friends, now I have one more reason to like these folks.
79 Jack is also contributing with Debian packaging and many other
80 things.
81
82 * [Alexander Schmolck] <a.schmolck-AT-gmx.net> Emacs work, bug
83 reports, bug fixes, ideas, lots more. The ipython.el mode for
84 (X)Emacs is Alex's code, providing full support for IPython under
85 (X)Emacs.
86
87 * [Andrea Riciputi] <andrea.riciputi-AT-libero.it> Mac OSX
88 information, Fink package management.
89
90 * [Gary Bishop] <gb-AT-cs.unc.edu> Bug reports, and patches to work
91 around the exception handling idiosyncracies of WxPython. Readline
92 and color support for Windows.
93
94 * [Jeffrey Collins] <Jeff.Collins-AT-vexcel.com> Bug reports. Much
95 improved readline support, including fixes for Python 2.3.
96
97 * [Dryice Liu] <dryice-AT-liu.com.cn> FreeBSD port.
98
99 * [Mike Heeter] <korora-AT-SDF.LONESTAR.ORG>
100
101 * [Christopher Hart] <hart-AT-caltech.edu> PDB integration.
102
103 * [Milan Zamazal] <pdm-AT-zamazal.org> Emacs info.
104
105 * [Philip Hisley] <compsys-AT-starpower.net>
106
107 * [Holger Krekel] <pyth-AT-devel.trillke.net> Tab completion, lots
108 more.
109
110 * [Robin Siebler] <robinsiebler-AT-starband.net>
111
112 * [Ralf Ahlbrink] <ralf_ahlbrink-AT-web.de>
113
114 * [Thorsten Kampe] <thorsten-AT-thorstenkampe.de>
115
116 * [Fredrik Kant] <fredrik.kant-AT-front.com> Windows setup.
117
118 * [Syver Enstad] <syver-en-AT-online.no> Windows setup.
119
120 * [Richard] <rxe-AT-renre-europe.com> Global embedding.
121
122 * [Hayden Callow] <h.callow-AT-elec.canterbury.ac.nz> Gnuplot.py 1.6
123 compatibility.
124
125 * [Leonardo Santagada] <retype-AT-terra.com.br> Fixes for Windows
126 installation.
127
128 * [Christopher Armstrong] <radix-AT-twistedmatrix.com> Bugfixes.
129
130 * [Francois Pinard] <pinard-AT-iro.umontreal.ca> Code and
131 documentation fixes.
132
133 * [Cory Dodt] <cdodt-AT-fcoe.k12.ca.us> Bug reports and Windows
134 ideas. Patches for Windows installer.
135
136 * [Olivier Aubert] <oaubert-AT-bat710.univ-lyon1.fr> New magics.
137
138 * [King C. Shu] <kingshu-AT-myrealbox.com> Autoindent patch.
139
140 * [Chris Drexler] <chris-AT-ac-drexler.de> Readline packages for
141 Win32/CygWin.
142
143 * [Gustavo Cordova Avila] <gcordova-AT-sismex.com> EvalDict code for
144 nice, lightweight string interpolation.
145
146 * [Kasper Souren] <Kasper.Souren-AT-ircam.fr> Bug reports, ideas.
147
148 * [Gever Tulley] <gever-AT-helium.com> Code contributions.
149
150 * [Ralf Schmitt] <ralf-AT-brainbot.com> Bug reports & fixes.
151
152 * [Oliver Sander] <osander-AT-gmx.de> Bug reports.
153
154 * [Rod Holland] <rhh-AT-structurelabs.com> Bug reports and fixes to
155 logging module.
156
157 * [Daniel 'Dang' Griffith] <pythondev-dang-AT-lazytwinacres.net>
158 Fixes, enhancement suggestions for system shell use.
159
160 * [Viktor Ransmayr] <viktor.ransmayr-AT-t-online.de> Tests and
161 reports on Windows installation issues. Contributed a true Windows
162 binary installer.
163
164 * [Mike Salib] <msalib-AT-mit.edu> Help fixing a subtle bug related
165 to traceback printing.
166
167 * [W.J. van der Laan] <gnufnork-AT-hetdigitalegat.nl> Bash-like
168 prompt specials.
169
170 * [Antoon Pardon] <Antoon.Pardon-AT-rece.vub.ac.be> Critical fix for
171 the multithreaded IPython.
172
173 * [John Hunter] <jdhunter-AT-nitace.bsd.uchicago.edu> Matplotlib
174 author, helped with all the development of support for matplotlib
175 in IPyhton, including making necessary changes to matplotlib itself.
176
177 * [Matthew Arnison] <maffew-AT-cat.org.au> Bug reports, '%run -d' idea.
178
179 * [Prabhu Ramachandran] <prabhu_r-AT-users.sourceforge.net> Help
180 with (X)Emacs support, threading patches, ideas...
181
182 * [Norbert Tretkowski] <tretkowski-AT-inittab.de> help with Debian
183 packaging and distribution.
184
185 * [George Sakkis] <gsakkis-AT-eden.rutgers.edu> New matcher for
186 tab-completing named arguments of user-defined functions.
187
188 * [Jörgen Stenarson] <jorgen.stenarson-AT-bostream.nu> Wildcard
189 support implementation for searching namespaces.
190
191 * [Vivian De Smedt] <vivian-AT-vdesmedt.com> Debugger enhancements,
192 so that when pdb is activated from within IPython, coloring, tab
193 completion and other features continue to work seamlessly.
194
195 * [Scott Tsai] <scottt958-AT-yahoo.com.tw> Support for automatic
196 editor invocation on syntax errors (see
197 http://www.scipy.net/roundup/ipython/issue36).
198
199 * [Alexander Belchenko] <bialix-AT-ukr.net> Improvements for win32
200 paging system.
201
202 * [Will Maier] <willmaier-AT-ml1.net> Official OpenBSD port.
203
204 * [Ondrej Certik] <ondrej-AT-certik.cz>: set up the IPython docs to use the new
205 Sphinx system used by Python, Matplotlib and many more projects.
206
207 * [Stefan van der Walt] <stefan-AT-sun.ac.za>: support for the new config system.
@@ -24,11 +24,11 b' There are two, no three, main goals of the IPython effort:'
24 24 to be used from within a variety of GUI applications.
25 25 3. Implement a system for interactive parallel computing.
26 26
27 While the third goal may seem a bit unrelated to the main focus of IPython, it turns
28 out that the technologies required for this goal are nearly identical with those
29 required for goal two. This is the main reason the interactive parallel computing
30 capabilities are being put into IPython proper. Currently the third of these goals is
31 furthest along.
27 While the third goal may seem a bit unrelated to the main focus of IPython, it
28 turns out that the technologies required for this goal are nearly identical
29 with those required for goal two. This is the main reason the interactive
30 parallel computing capabilities are being put into IPython proper. Currently
31 the third of these goals is furthest along.
32 32
33 33 This document describes IPython from the perspective of developers.
34 34
@@ -39,51 +39,59 b' Project organization'
39 39 Subpackages
40 40 -----------
41 41
42 IPython is organized into semi self-contained subpackages. Each of the subpackages will have its own:
42 IPython is organized into semi self-contained subpackages. Each of the
43 subpackages will have its own:
43 44
44 45 - **Dependencies**. One of the most important things to keep in mind in
45 46 partitioning code amongst subpackages, is that they should be used to cleanly
46 encapsulate dependencies.
47 encapsulate dependencies.
48
47 49 - **Tests**. Each subpackage shoud have its own ``tests`` subdirectory that
48 contains all of the tests for that package. For information about writing tests
49 for IPython, see the `Testing System`_ section of this document.
50 - **Configuration**. Each subpackage should have its own ``config`` subdirectory
51 that contains the configuration information for the components of the
52 subpackage. For information about how the IPython configuration system
53 works, see the `Configuration System`_ section of this document.
54 - **Scripts**. Each subpackage should have its own ``scripts`` subdirectory that
55 contains all of the command line scripts associated with the subpackage.
50 contains all of the tests for that package. For information about writing
51 tests for IPython, see the `Testing System`_ section of this document.
52
53 - **Configuration**. Each subpackage should have its own ``config``
54 subdirectory that contains the configuration information for the components
55 of the subpackage. For information about how the IPython configuration
56 system works, see the `Configuration System`_ section of this document.
57
58 - **Scripts**. Each subpackage should have its own ``scripts`` subdirectory
59 that contains all of the command line scripts associated with the subpackage.
56 60
57 61 Installation and dependencies
58 62 -----------------------------
59 63
60 IPython will not use `setuptools`_ for installation. Instead, we will use standard
61 ``setup.py`` scripts that use `distutils`_. While there are a number a extremely nice
62 features that `setuptools`_ has (like namespace packages), the current implementation
63 of `setuptools`_ has performance problems, particularly on shared file systems. In
64 particular, when Python packages are installed on NSF file systems, import times
65 become much too long (up towards 10 seconds).
64 IPython will not use `setuptools`_ for installation. Instead, we will use
65 standard ``setup.py`` scripts that use `distutils`_. While there are a number a
66 extremely nice features that `setuptools`_ has (like namespace packages), the
67 current implementation of `setuptools`_ has performance problems, particularly
68 on shared file systems. In particular, when Python packages are installed on
69 NSF file systems, import times become much too long (up towards 10 seconds).
66 70
67 71 Because IPython is being used extensively in the context of high performance
68 computing, where performance is critical but shared file systems are common, we feel
69 these performance hits are not acceptable. Thus, until the performance problems
70 associated with `setuptools`_ are addressed, we will stick with plain `distutils`_. We
71 are hopeful that these problems will be addressed and that we will eventually begin
72 using `setuptools`_. Because of this, we are trying to organize IPython in a way that
73 will make the eventual transition to `setuptools`_ as painless as possible.
74
75 Because we will be using `distutils`_, there will be no method for automatically installing dependencies. Instead, we are following the approach of `Matplotlib`_ which can be summarized as follows:
72 computing, where performance is critical but shared file systems are common, we
73 feel these performance hits are not acceptable. Thus, until the performance
74 problems associated with `setuptools`_ are addressed, we will stick with plain
75 `distutils`_. We are hopeful that these problems will be addressed and that we
76 will eventually begin using `setuptools`_. Because of this, we are trying to
77 organize IPython in a way that will make the eventual transition to
78 `setuptools`_ as painless as possible.
79
80 Because we will be using `distutils`_, there will be no method for
81 automatically installing dependencies. Instead, we are following the approach
82 of `Matplotlib`_ which can be summarized as follows:
76 83
77 84 - Distinguish between required and optional dependencies. However, the required
78 85 dependencies for IPython should be only the Python standard library.
79 - Upon installation check to see which optional dependencies are present and tell
80 the user which parts of IPython need which optional dependencies.
86
87 - Upon installation check to see which optional dependencies are present and
88 tell the user which parts of IPython need which optional dependencies.
81 89
82 It is absolutely critical that each subpackage of IPython has a clearly specified set
83 of dependencies and that dependencies are not carelessly inherited from other IPython
84 subpackages. Furthermore, tests that have certain dependencies should not fail if
85 those dependencies are not present. Instead they should be skipped and print a
86 message.
90 It is absolutely critical that each subpackage of IPython has a clearly
91 specified set of dependencies and that dependencies are not carelessly
92 inherited from other IPython subpackages. Furthermore, tests that have certain
93 dependencies should not fail if those dependencies are not present. Instead
94 they should be skipped and print a message.
87 95
88 96 .. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools
89 97 .. _distutils: http://docs.python.org/lib/module-distutils.html
@@ -106,9 +114,10 b' Specific subpackages'
106 114
107 115 ``frontends``
108 116 The various frontends for IPython. A frontend is the end-user application
109 that exposes the capabilities of IPython to the user. The most basic frontend
110 will simply be a terminal based application that looks just like today 's
111 IPython. Other frontends will likely be more powerful and based on GUI toolkits.
117 that exposes the capabilities of IPython to the user. The most basic
118 frontend will simply be a terminal based application that looks just like
119 today 's IPython. Other frontends will likely be more powerful and based
120 on GUI toolkits.
112 121
113 122 ``notebook``
114 123 An application that allows users to work with IPython notebooks.
@@ -120,10 +129,12 b' Specific subpackages'
120 129 Version control
121 130 ===============
122 131
123 In the past, IPython development has been done using `Subversion`__. Recently, we made the transition to using `Bazaar`__ and `Launchpad`__. This makes it much easier for people
124 to contribute code to IPython. Here is a sketch of how to use Bazaar for IPython
125 development. First, you should install Bazaar. After you have done that, make
126 sure that it is working by getting the latest main branch of IPython::
132 In the past, IPython development has been done using `Subversion`__. Recently,
133 we made the transition to using `Bazaar`__ and `Launchpad`__. This makes it
134 much easier for people to contribute code to IPython. Here is a sketch of how
135 to use Bazaar for IPython development. First, you should install Bazaar.
136 After you have done that, make sure that it is working by getting the latest
137 main branch of IPython::
127 138
128 139 $ bzr branch lp:ipython
129 140
@@ -131,17 +142,17 b' Now you can create a new branch for you to do your work in::'
131 142
132 143 $ bzr branch ipython ipython-mybranch
133 144
134 The typical work cycle in this branch will be to make changes in `ipython-mybranch`
135 and then commit those changes using the commit command::
145 The typical work cycle in this branch will be to make changes in
146 ``ipython-mybranch`` and then commit those changes using the commit command::
136 147
137 148 $ ...do work in ipython-mybranch...
138 149 $ bzr ci -m "the commit message goes here"
139 150
140 Please note that since we now don't use an old-style linear ChangeLog
141 (that tends to cause problems with distributed version control
142 systems), you should ensure that your log messages are reasonably
143 detailed. Use a docstring-like approach in the commit messages
144 (including the second line being left *blank*)::
151 Please note that since we now don't use an old-style linear ChangeLog (that
152 tends to cause problems with distributed version control systems), you should
153 ensure that your log messages are reasonably detailed. Use a docstring-like
154 approach in the commit messages (including the second line being left
155 *blank*)::
145 156
146 157 Single line summary of changes being committed.
147 158
@@ -149,27 +160,27 b' detailed. Use a docstring-like approach in the commit messages'
149 160 - including crediting outside contributors if they sent the
150 161 code/bug/idea!
151 162
152 If we couple this with a policy of making single commits for each
153 reasonably atomic change, the bzr log should give an excellent view of
154 the project, and the `--short` log option becomes a nice summary.
163 If we couple this with a policy of making single commits for each reasonably
164 atomic change, the bzr log should give an excellent view of the project, and
165 the `--short` log option becomes a nice summary.
155 166
156 While working with this branch, it is a good idea to merge in changes that have been
157 made upstream in the parent branch. This can be done by doing::
167 While working with this branch, it is a good idea to merge in changes that have
168 been made upstream in the parent branch. This can be done by doing::
158 169
159 170 $ bzr pull
160 171
161 If this command shows that the branches have diverged, then you should do a merge
162 instead::
172 If this command shows that the branches have diverged, then you should do a
173 merge instead::
163 174
164 175 $ bzr merge lp:ipython
165 176
166 If you want others to be able to see your branch, you can create an account with
167 launchpad and push the branch to your own workspace::
177 If you want others to be able to see your branch, you can create an account
178 with launchpad and push the branch to your own workspace::
168 179
169 180 $ bzr push bzr+ssh://<me>@bazaar.launchpad.net/~<me>/+junk/ipython-mybranch
170 181
171 Finally, once the work in your branch is done, you can merge your changes back into
172 the `ipython` branch by using merge::
182 Finally, once the work in your branch is done, you can merge your changes back
183 into the `ipython` branch by using merge::
173 184
174 185 $ cd ipython
175 186 $ merge ../ipython-mybranch
@@ -177,8 +188,9 b' the `ipython` branch by using merge::'
177 188 $ bzr ci -m "Fixing that bug"
178 189 $ bzr push
179 190
180 But this will require you to have write permissions to the `ipython` branch. It you don't
181 you can tell one of the IPython devs about your branch and they can do the merge for you.
191 But this will require you to have write permissions to the `ipython` branch.
192 It you don't you can tell one of the IPython devs about your branch and they
193 can do the merge for you.
182 194
183 195 More information about Bazaar workflows can be found `here`__.
184 196
@@ -193,27 +205,29 b' Documentation'
193 205 Standalone documentation
194 206 ------------------------
195 207
196 All standalone documentation should be written in plain text (``.txt``) files using
197 `reStructuredText`_ for markup and formatting. All such documentation should be placed
198 in the top level directory ``docs`` of the IPython source tree. Or, when appropriate,
199 a suitably named subdirectory should be used. The documentation in this location will
200 serve as the main source for IPython documentation and all existing documentation
201 should be converted to this format.
208 All standalone documentation should be written in plain text (``.txt``) files
209 using `reStructuredText`_ for markup and formatting. All such documentation
210 should be placed in the top level directory ``docs`` of the IPython source
211 tree. Or, when appropriate, a suitably named subdirectory should be used. The
212 documentation in this location will serve as the main source for IPython
213 documentation and all existing documentation should be converted to this
214 format.
202 215
203 In the future, the text files in the ``docs`` directory will be used to generate all
204 forms of documentation for IPython. This include documentation on the IPython website
205 as well as *pdf* documentation.
216 In the future, the text files in the ``docs`` directory will be used to
217 generate all forms of documentation for IPython. This include documentation on
218 the IPython website as well as *pdf* documentation.
206 219
207 220 .. _reStructuredText: http://docutils.sourceforge.net/rst.html
208 221
209 222 Docstring format
210 223 ----------------
211 224
212 Good docstrings are very important. All new code will use `Epydoc`_ for generating API
213 docs, so we will follow the `Epydoc`_ conventions. More specifically, we will use
214 `reStructuredText`_ for markup and formatting, since it is understood by a wide
215 variety of tools. This means that if in the future we have any reason to change from
216 `Epydoc`_ to something else, we'll have fewer transition pains.
225 Good docstrings are very important. All new code will use `Epydoc`_ for
226 generating API docs, so we will follow the `Epydoc`_ conventions. More
227 specifically, we will use `reStructuredText`_ for markup and formatting, since
228 it is understood by a wide variety of tools. This means that if in the future
229 we have any reason to change from `Epydoc`_ to something else, we'll have fewer
230 transition pains.
217 231
218 232 Details about using `reStructuredText`_ for docstrings can be found `here
219 233 <http://epydoc.sourceforge.net/manual-othermarkup.html>`_.
@@ -233,7 +247,8 b' Coding conventions'
233 247 General
234 248 -------
235 249
236 In general, we'll try to follow the standard Python style conventions as described here:
250 In general, we'll try to follow the standard Python style conventions as
251 described here:
237 252
238 253 - `Style Guide for Python Code <http://www.python.org/peps/pep-0008.html>`_
239 254
@@ -250,8 +265,8 b' Other comments:'
250 265 Naming conventions
251 266 ------------------
252 267
253 In terms of naming conventions, we'll follow the guidelines from the `Style Guide for
254 Python Code`_.
268 In terms of naming conventions, we'll follow the guidelines from the `Style
269 Guide for Python Code`_.
255 270
256 271 For all new IPython code (and much existing code is being refactored), we'll use:
257 272
@@ -259,67 +274,81 b" For all new IPython code (and much existing code is being refactored), we'll use"
259 274
260 275 - ``CamelCase`` for class names.
261 276
262 - ``lowercase_with_underscores`` for methods, functions, variables and attributes.
277 - ``lowercase_with_underscores`` for methods, functions, variables and
278 attributes.
263 279
264 This may be confusing as most of the existing IPython codebase uses a different convention (``lowerCamelCase`` for methods and attributes). Slowly, we will move IPython over to the new
265 convention, providing shadow names for backward compatibility in public interfaces.
280 This may be confusing as most of the existing IPython codebase uses a different
281 convention (``lowerCamelCase`` for methods and attributes). Slowly, we will
282 move IPython over to the new convention, providing shadow names for backward
283 compatibility in public interfaces.
266 284
267 There are, however, some important exceptions to these rules. In some cases, IPython
268 code will interface with packages (Twisted, Wx, Qt) that use other conventions. At some level this makes it impossible to adhere to our own standards at all times. In particular, when subclassing classes that use other naming conventions, you must follow their naming conventions. To deal with cases like this, we propose the following policy:
285 There are, however, some important exceptions to these rules. In some cases,
286 IPython code will interface with packages (Twisted, Wx, Qt) that use other
287 conventions. At some level this makes it impossible to adhere to our own
288 standards at all times. In particular, when subclassing classes that use other
289 naming conventions, you must follow their naming conventions. To deal with
290 cases like this, we propose the following policy:
269 291
270 292 - If you are subclassing a class that uses different conventions, use its
271 naming conventions throughout your subclass. Thus, if you are creating a
272 Twisted Protocol class, used Twisted's ``namingSchemeForMethodsAndAttributes.``
273
274 - All IPython's official interfaces should use our conventions. In some cases
275 this will mean that you need to provide shadow names (first implement ``fooBar``
276 and then ``foo_bar = fooBar``). We want to avoid this at all costs, but it
277 will probably be necessary at times. But, please use this sparingly!
278
279 Implementation-specific *private* methods will use ``_single_underscore_prefix``.
280 Names with a leading double underscore will *only* be used in special cases, as they
281 makes subclassing difficult (such names are not easily seen by child classes).
282
283 Occasionally some run-in lowercase names are used, but mostly for very short names or
284 where we are implementing methods very similar to existing ones in a base class (like
285 ``runlines()`` where ``runsource()`` and ``runcode()`` had established precedent).
293 naming conventions throughout your subclass. Thus, if you are creating a
294 Twisted Protocol class, used Twisted's
295 ``namingSchemeForMethodsAndAttributes.``
296
297 - All IPython's official interfaces should use our conventions. In some cases
298 this will mean that you need to provide shadow names (first implement
299 ``fooBar`` and then ``foo_bar = fooBar``). We want to avoid this at all
300 costs, but it will probably be necessary at times. But, please use this
301 sparingly!
302
303 Implementation-specific *private* methods will use
304 ``_single_underscore_prefix``. Names with a leading double underscore will
305 *only* be used in special cases, as they makes subclassing difficult (such
306 names are not easily seen by child classes).
307
308 Occasionally some run-in lowercase names are used, but mostly for very short
309 names or where we are implementing methods very similar to existing ones in a
310 base class (like ``runlines()`` where ``runsource()`` and ``runcode()`` had
311 established precedent).
286 312
287 313 The old IPython codebase has a big mix of classes and modules prefixed with an
288 explicit ``IP``. In Python this is mostly unnecessary, redundant and frowned upon, as
289 namespaces offer cleaner prefixing. The only case where this approach is justified is
290 for classes which are expected to be imported into external namespaces and a very
291 generic name (like Shell) is too likely to clash with something else. We'll need to
292 revisit this issue as we clean up and refactor the code, but in general we should
293 remove as many unnecessary ``IP``/``ip`` prefixes as possible. However, if a prefix
294 seems absolutely necessary the more specific ``IPY`` or ``ipy`` are preferred.
314 explicit ``IP``. In Python this is mostly unnecessary, redundant and frowned
315 upon, as namespaces offer cleaner prefixing. The only case where this approach
316 is justified is for classes which are expected to be imported into external
317 namespaces and a very generic name (like Shell) is too likely to clash with
318 something else. We'll need to revisit this issue as we clean up and refactor
319 the code, but in general we should remove as many unnecessary ``IP``/``ip``
320 prefixes as possible. However, if a prefix seems absolutely necessary the more
321 specific ``IPY`` or ``ipy`` are preferred.
295 322
296 323 .. _devel_testing:
297 324
298 325 Testing system
299 326 ==============
300 327
301 It is extremely important that all code contributed to IPython has tests. Tests should
302 be written as unittests, doctests or as entities that the `Nose`_ testing package will
303 find. Regardless of how the tests are written, we will use `Nose`_ for discovering and
304 running the tests. `Nose`_ will be required to run the IPython test suite, but will
305 not be required to simply use IPython.
328 It is extremely important that all code contributed to IPython has tests. Tests
329 should be written as unittests, doctests or as entities that the `Nose`_
330 testing package will find. Regardless of how the tests are written, we will use
331 `Nose`_ for discovering and running the tests. `Nose`_ will be required to run
332 the IPython test suite, but will not be required to simply use IPython.
306 333
307 334 .. _Nose: http://code.google.com/p/python-nose/
308 335
309 Tests of `Twisted`__ using code should be written by subclassing the ``TestCase`` class
310 that comes with ``twisted.trial.unittest``. When this is done, `Nose`_ will be able to
311 run the tests and the twisted reactor will be handled correctly.
336 Tests of `Twisted`__ using code should be written by subclassing the
337 ``TestCase`` class that comes with ``twisted.trial.unittest``. When this is
338 done, `Nose`_ will be able to run the tests and the twisted reactor will be
339 handled correctly.
312 340
313 341 .. __: http://www.twistedmatrix.com
314 342
315 Each subpackage in IPython should have its own ``tests`` directory that contains all
316 of the tests for that subpackage. This allows each subpackage to be self-contained. If
317 a subpackage has any dependencies beyond the Python standard library, the tests for
318 that subpackage should be skipped if the dependencies are not found. This is very
319 important so users don't get tests failing simply because they don't have dependencies.
343 Each subpackage in IPython should have its own ``tests`` directory that
344 contains all of the tests for that subpackage. This allows each subpackage to
345 be self-contained. If a subpackage has any dependencies beyond the Python
346 standard library, the tests for that subpackage should be skipped if the
347 dependencies are not found. This is very important so users don't get tests
348 failing simply because they don't have dependencies.
320 349
321 We also need to look into use Noses ability to tag tests to allow a more modular
322 approach of running tests.
350 We also need to look into use Noses ability to tag tests to allow a more
351 modular approach of running tests.
323 352
324 353 .. _devel_config:
325 354
@@ -327,23 +356,25 b' Configuration system'
327 356 ====================
328 357
329 358 IPython uses `.ini`_ files for configuration purposes. This represents a huge
330 improvement over the configuration system used in IPython. IPython works with these
331 files using the `ConfigObj`_ package, which IPython includes as
359 improvement over the configuration system used in IPython. IPython works with
360 these files using the `ConfigObj`_ package, which IPython includes as
332 361 ``ipython1/external/configobj.py``.
333 362
334 Currently, we are using raw `ConfigObj`_ objects themselves. Each subpackage of IPython
335 should contain a ``config`` subdirectory that contains all of the configuration
336 information for the subpackage. To see how configuration information is defined (along
337 with defaults) see at the examples in ``ipython1/kernel/config`` and
338 ``ipython1/core/config``. Likewise, to see how the configuration information is used,
339 see examples in ``ipython1/kernel/scripts/ipengine.py``.
340
341 Eventually, we will add a new layer on top of the raw `ConfigObj`_ objects. We are
342 calling this new layer, ``tconfig``, as it will use a `Traits`_-like validation model.
343 We won't actually use `Traits`_, but will implement something similar in pure Python.
344 But, even in this new system, we will still use `ConfigObj`_ and `.ini`_ files
345 underneath the hood. Talk to Fernando if you are interested in working on this part of
346 IPython. The current prototype of ``tconfig`` is located in the IPython sandbox.
363 Currently, we are using raw `ConfigObj`_ objects themselves. Each subpackage of
364 IPython should contain a ``config`` subdirectory that contains all of the
365 configuration information for the subpackage. To see how configuration
366 information is defined (along with defaults) see at the examples in
367 ``ipython1/kernel/config`` and ``ipython1/core/config``. Likewise, to see how
368 the configuration information is used, see examples in
369 ``ipython1/kernel/scripts/ipengine.py``.
370
371 Eventually, we will add a new layer on top of the raw `ConfigObj`_ objects. We
372 are calling this new layer, ``tconfig``, as it will use a `Traits`_-like
373 validation model. We won't actually use `Traits`_, but will implement
374 something similar in pure Python. But, even in this new system, we will still
375 use `ConfigObj`_ and `.ini`_ files underneath the hood. Talk to Fernando if you
376 are interested in working on this part of IPython. The current prototype of
377 ``tconfig`` is located in the IPython sandbox.
347 378
348 379 .. _.ini: http://docs.python.org/lib/module-ConfigParser.html
349 380 .. _ConfigObj: http://www.voidspace.org.uk/python/configobj.html
@@ -352,20 +383,26 b' IPython. The current prototype of ``tconfig`` is located in the IPython sandbox.'
352 383 Installation and testing scenarios
353 384 ==================================
354 385
355 This section outlines the various scenarios that we need to test before we release an IPython version. These scenarios represent different ways of installing IPython and its dependencies.
386 This section outlines the various scenarios that we need to test before we
387 release an IPython version. These scenarios represent different ways of
388 installing IPython and its dependencies.
356 389
357 390 Installation scenarios under Linux and OS X
358 391 -------------------------------------------
359 392
360 1. Install from tarball using `python setup.py install`.
393 1. Install from tarball using ``python setup.py install``.
361 394 a. With only readline+nose dependencies installed.
362 b. With all dependencies installed (readline, zope.interface,
363 Twisted, foolscap, Sphinx, nose, pyOpenSSL).
395 b. With all dependencies installed (readline, zope.interface, Twisted,
396 foolscap, Sphinx, nose, pyOpenSSL).
397
364 398 2. Install using easy_install.
399
365 400 a. With only readline+nose dependencies installed.
366 i. Default dependencies: `easy_install ipython-0.9.beta3-py2.5.egg`
367 ii. Optional dependency sets: `easy_install -f ipython-0.9.beta3-py2.5.egg IPython[kernel,doc,test,security]`
401 i. Default dependencies: ``easy_install ipython-0.9.beta3-py2.5.egg``
402 ii. Optional dependency sets: ``easy_install -f ipython-0.9.beta3-py2.5.egg IPython[kernel,doc,test,security]``
403
368 404 b. With all dependencies already installed.
405
369 406
370 407 Installation scenarios under Win32
371 408 ----------------------------------
@@ -381,17 +418,9 b' Tests to run for these scenarios'
381 418 2. Start a controller and engines and try a few things by hand.
382 419 a. Using ipcluster.
383 420 b. Using ipcontroller/ipengine by hand.
421
384 422 3. Run a few of the parallel examples.
385 423 4. Try the kernel with and without security with and without PyOpenSSL
386 424 installed.
387 425 5. Beat on the IPython terminal a bunch.
388 426 6. Make sure that furl files are being put in proper locations.
389
390
391
392
393
394
395
396
397
@@ -7,3 +7,4 b' Development'
7 7
8 8 development.txt
9 9 roadmap.txt
10 notification_blueprint.txt
@@ -1,4 +1,4 b''
1 .. Notification:
1 .. _notification:
2 2
3 3 ==========================================
4 4 IPython.kernel.core.notification blueprint
@@ -11,37 +11,39 b' The :mod:`IPython.kernel.core.notification` module will provide a simple impleme'
11 11 Functional Requirements
12 12 =======================
13 13 The notification center must:
14 * Provide synchronous notification of events to all registered observers.
15 * Provide typed or labeled notification types
16 * Allow observers to register callbacks for individual or all notification types
17 * Allow observers to register callbacks for events from individual or all notifying objects
18 * Notification to the observer consists of the notification type, notifying object and user-supplied extra information [implementation: as keyword parameters to the registered callback]
19 * Perform as O(1) in the case of no registered observers.
20 * Permit out-of-process or cross-network extension.
21
14 * Provide synchronous notification of events to all registered observers.
15 * Provide typed or labeled notification types
16 * Allow observers to register callbacks for individual or all notification types
17 * Allow observers to register callbacks for events from individual or all notifying objects
18 * Notification to the observer consists of the notification type, notifying object and user-supplied extra information [implementation: as keyword parameters to the registered callback]
19 * Perform as O(1) in the case of no registered observers.
20 * Permit out-of-process or cross-network extension.
21
22 22 What's not included
23 23 ==============================================================
24 24 As written, the :mod:`IPython.kernel.core.notificaiton` module does not:
25 * Provide out-of-process or network notifications [these should be handled by a separate, Twisted aware module in :mod:`IPython.kernel`].
26 * Provide zope.interface-style interfaces for the notification system [these should also be provided by the :mod:`IPython.kernel` module]
27
25 * Provide out-of-process or network notifications [these should be handled by a separate, Twisted aware module in :mod:`IPython.kernel`].
26 * Provide zope.interface-style interfaces for the notification system [these should also be provided by the :mod:`IPython.kernel` module]
27
28 28 Use Cases
29 29 =========
30 30 The following use cases describe the main intended uses of the notificaiton module and illustrate the main success scenario for each use case:
31 31
32 1. Dwight Schroot is writing a frontend for the IPython project. His frontend is stuck in the stone age and must communicate synchronously with an IPython.kernel.core.Interpreter instance. Because code is executed in blocks by the Interpreter, Dwight's UI freezes every time he executes a long block of code. To keep track of the progress of his long running block, Dwight adds the following code to his frontend's set-up code::
33 from IPython.kernel.core.notification import NotificationCenter
34 center = NotificationCenter.sharedNotificationCenter
35 center.registerObserver(self, type=IPython.kernel.core.Interpreter.STDOUT_NOTIFICATION_TYPE, notifying_object=self.interpreter, callback=self.stdout_notification)
36
37 and elsewhere in his front end::
38 def stdout_notification(self, type, notifying_object, out_string=None):
39 self.writeStdOut(out_string)
40
41 If everything works, the Interpreter will (according to its published API) fire a notification via the :data:`IPython.kernel.core.notification.sharedCenter` of type :const:`STD_OUT_NOTIFICATION_TYPE` before writing anything to stdout [it's up to the Intereter implementation to figure out when to do this]. The notificaiton center will then call the registered callbacks for that event type (in this case, Dwight's frontend's stdout_notification method). Again, according to its API, the Interpreter provides an additional keyword argument when firing the notificaiton of out_string, a copy of the string it will write to stdout.
42
43 Like magic, Dwight's frontend is able to provide output, even during long-running calculations. Now if Jim could just convince Dwight to use Twisted...
44
45 2. Boss Hog is writing a frontend for the IPython project. Because Boss Hog is stuck in the stone age, his frontend will be written in a new Fortran-like dialect of python and will run only from the command line. Because he doesn't need any fancy notification system and is used to worrying about every cycle on his rat-wheel powered mini, Boss Hog is adamant that the new notification system not produce any performance penalty. As they say in Hazard county, there's no such thing as a free lunch. If he wanted zero overhead, he should have kept using IPython 0.8. Instead, those tricky Duke boys slide in a suped-up bridge-out jumpin' awkwardly confederate-lovin' notification module that imparts only a constant (and small) performance penalty when the Interpreter (or any other object) fires an event for which there are no registered observers. Of course, the same notificaiton-enabled Interpreter can then be used in frontends that require notifications, thus saving the IPython project from a nasty civil war.
46
47 3. Barry is wrting a frontend for the IPython project. Because Barry's front end is the *new hotness*, it uses an asynchronous event model to communicate with a Twisted :mod:`~IPython.kernel.engineservice` that communicates with the IPython :class:`~IPython.kernel.core.interpreter.Interpreter`. Using the :mod:`IPython.kernel.notification` module, an asynchronous wrapper on the :mod:`IPython.kernel.core.notification` module, Barry's frontend can register for notifications from the interpreter that are delivered asynchronously. Even if Barry's frontend is running on a separate process or even host from the Interpreter, the notifications are delivered, as if by dark and twisted magic. Just like Dwight's frontend, Barry's frontend can now recieve notifications of e.g. writing to stdout/stderr, opening/closing an external file, an exception in the executing code, etc. No newline at end of file
32 1. Dwight Schroot is writing a frontend for the IPython project. His frontend is stuck in the stone age and must communicate synchronously with an IPython.kernel.core.Interpreter instance. Because code is executed in blocks by the Interpreter, Dwight's UI freezes every time he executes a long block of code. To keep track of the progress of his long running block, Dwight adds the following code to his frontend's set-up code::
33
34 from IPython.kernel.core.notification import NotificationCenter
35 center = NotificationCenter.sharedNotificationCenter
36 center.registerObserver(self, type=IPython.kernel.core.Interpreter.STDOUT_NOTIFICATION_TYPE, notifying_object=self.interpreter, callback=self.stdout_notification)
37
38 and elsewhere in his front end::
39
40 def stdout_notification(self, type, notifying_object, out_string=None):
41 self.writeStdOut(out_string)
42
43 If everything works, the Interpreter will (according to its published API) fire a notification via the :data:`IPython.kernel.core.notification.sharedCenter` of type :const:`STD_OUT_NOTIFICATION_TYPE` before writing anything to stdout [it's up to the Intereter implementation to figure out when to do this]. The notificaiton center will then call the registered callbacks for that event type (in this case, Dwight's frontend's stdout_notification method). Again, according to its API, the Interpreter provides an additional keyword argument when firing the notificaiton of out_string, a copy of the string it will write to stdout.
44
45 Like magic, Dwight's frontend is able to provide output, even during long-running calculations. Now if Jim could just convince Dwight to use Twisted...
46
47 2. Boss Hog is writing a frontend for the IPython project. Because Boss Hog is stuck in the stone age, his frontend will be written in a new Fortran-like dialect of python and will run only from the command line. Because he doesn't need any fancy notification system and is used to worrying about every cycle on his rat-wheel powered mini, Boss Hog is adamant that the new notification system not produce any performance penalty. As they say in Hazard county, there's no such thing as a free lunch. If he wanted zero overhead, he should have kept using IPython 0.8. Instead, those tricky Duke boys slide in a suped-up bridge-out jumpin' awkwardly confederate-lovin' notification module that imparts only a constant (and small) performance penalty when the Interpreter (or any other object) fires an event for which there are no registered observers. Of course, the same notificaiton-enabled Interpreter can then be used in frontends that require notifications, thus saving the IPython project from a nasty civil war.
48
49 3. Barry is wrting a frontend for the IPython project. Because Barry's front end is the *new hotness*, it uses an asynchronous event model to communicate with a Twisted :mod:`~IPython.kernel.engineservice` that communicates with the IPython :class:`~IPython.kernel.core.interpreter.Interpreter`. Using the :mod:`IPython.kernel.notification` module, an asynchronous wrapper on the :mod:`IPython.kernel.core.notification` module, Barry's frontend can register for notifications from the interpreter that are delivered asynchronously. Even if Barry's frontend is running on a separate process or even host from the Interpreter, the notifications are delivered, as if by dark and twisted magic. Just like Dwight's frontend, Barry's frontend can now recieve notifications of e.g. writing to stdout/stderr, opening/closing an external file, an exception in the executing code, etc. No newline at end of file
@@ -32,16 +32,21 b' IPython is implemented using a distributed set of processes that communicate usi'
32 32
33 33 We need to build a system that makes it trivial for users to start and manage IPython processes. This system should have the following properties:
34 34
35 * It should possible to do everything through an extremely simple API that users
36 can call from their own Python script. No shell commands should be needed.
37 * This simple API should be configured using standard .ini files.
38 * The system should make it possible to start processes using a number of different
39 approaches: SSH, PBS/Torque, Xgrid, Windows Server, mpirun, etc.
40 * The controller and engine processes should each have a daemon for monitoring,
41 signaling and clean up.
42 * The system should be secure.
43 * The system should work under all the major operating systems, including
44 Windows.
35 * It should possible to do everything through an extremely simple API that users
36 can call from their own Python script. No shell commands should be needed.
37
38 * This simple API should be configured using standard .ini files.
39
40 * The system should make it possible to start processes using a number of different
41 approaches: SSH, PBS/Torque, Xgrid, Windows Server, mpirun, etc.
42
43 * The controller and engine processes should each have a daemon for monitoring,
44 signaling and clean up.
45
46 * The system should be secure.
47
48 * The system should work under all the major operating systems, including
49 Windows.
45 50
46 51 Initial work has begun on the daemon infrastructure, and some of the needed logic is contained in the ipcluster script.
47 52
@@ -57,12 +62,15 b' Security'
57 62
58 63 Currently, IPython has no built in security or security model. Because we would like IPython to be usable on public computer systems and over wide area networks, we need to come up with a robust solution for security. Here are some of the specific things that need to be included:
59 64
60 * User authentication between all processes (engines, controller and clients).
61 * Optional TSL/SSL based encryption of all communication channels.
62 * A good way of picking network ports so multiple users on the same system can
63 run their own controller and engines without interfering with those of others.
64 * A clear model for security that enables users to evaluate the security risks
65 associated with using IPython in various manners.
65 * User authentication between all processes (engines, controller and clients).
66
67 * Optional TSL/SSL based encryption of all communication channels.
68
69 * A good way of picking network ports so multiple users on the same system can
70 run their own controller and engines without interfering with those of others.
71
72 * A clear model for security that enables users to evaluate the security risks
73 associated with using IPython in various manners.
66 74
67 75 For the implementation of this, we plan on using Twisted's support for SSL and authentication. One things that we really should look at is the `Foolscap`_ network protocol, which provides many of these things out of the box.
68 76
@@ -70,6 +78,9 b" For the implementation of this, we plan on using Twisted's support for SSL and a"
70 78
71 79 The security work needs to be done in conjunction with other network protocol stuff.
72 80
81 As of the 0.9 release of IPython, we are using Foolscap and we have implemented
82 a full security model.
83
73 84 Latent performance issues
74 85 -------------------------
75 86
@@ -82,7 +93,7 b' Currently, we have a number of performance issues that are waiting to bite users'
82 93 * Currently, the client to controller connections are done through XML-RPC using
83 94 HTTP 1.0. This is very inefficient as XML-RPC is a very verbose protocol and
84 95 each request must be handled with a new connection. We need to move these network
85 connections over to PB or Foolscap.
96 connections over to PB or Foolscap. Done!
86 97 * We currently don't have a good way of handling large objects in the controller.
87 98 The biggest problem is that because we don't have any way of streaming objects,
88 99 we get lots of temporary copies in the low-level buffers. We need to implement
@@ -16,10 +16,13 b' Will IPython speed my Python code up?'
16 16 Yes and no. When converting a serial code to run in parallel, there often many
17 17 difficulty questions that need to be answered, such as:
18 18
19 * How should data be decomposed onto the set of processors?
20 * What are the data movement patterns?
21 * Can the algorithm be structured to minimize data movement?
22 * Is dynamic load balancing important?
19 * How should data be decomposed onto the set of processors?
20
21 * What are the data movement patterns?
22
23 * Can the algorithm be structured to minimize data movement?
24
25 * Is dynamic load balancing important?
23 26
24 27 We can't answer such questions for you. This is the hard (but fun) work of parallel
25 28 computing. But, once you understand these things IPython will make it easier for you to
@@ -28,9 +31,7 b' resulting parallel code interactively.'
28 31
29 32 With that said, if your problem is trivial to parallelize, IPython has a number of
30 33 different interfaces that will enable you to parallelize things is almost no time at
31 all. A good place to start is the ``map`` method of our `multiengine interface`_.
32
33 .. _multiengine interface: ./parallel_multiengine
34 all. A good place to start is the ``map`` method of our :class:`MultiEngineClient`.
34 35
35 36 What is the best way to use MPI from Python?
36 37 --------------------------------------------
@@ -40,26 +41,33 b' What about all the other parallel computing packages in Python?'
40 41
41 42 Some of the unique characteristic of IPython are:
42 43
43 * IPython is the only architecture that abstracts out the notion of a
44 parallel computation in such a way that new models of parallel computing
45 can be explored quickly and easily. If you don't like the models we
46 provide, you can simply create your own using the capabilities we provide.
47 * IPython is asynchronous from the ground up (we use `Twisted`_).
48 * IPython's architecture is designed to avoid subtle problems
49 that emerge because of Python's global interpreter lock (GIL).
50 * While IPython'1 architecture is designed to support a wide range
51 of novel parallel computing models, it is fully interoperable with
52 traditional MPI applications.
53 * IPython has been used and tested extensively on modern supercomputers.
54 * IPython's networking layers are completely modular. Thus, is
55 straightforward to replace our existing network protocols with
56 high performance alternatives (ones based upon Myranet/Infiniband).
57 * IPython is designed from the ground up to support collaborative
58 parallel computing. This enables multiple users to actively develop
59 and run the *same* parallel computation.
60 * Interactivity is a central goal for us. While IPython does not have
61 to be used interactivly, is can be.
62
44 * IPython is the only architecture that abstracts out the notion of a
45 parallel computation in such a way that new models of parallel computing
46 can be explored quickly and easily. If you don't like the models we
47 provide, you can simply create your own using the capabilities we provide.
48
49 * IPython is asynchronous from the ground up (we use `Twisted`_).
50
51 * IPython's architecture is designed to avoid subtle problems
52 that emerge because of Python's global interpreter lock (GIL).
53
54 * While IPython's architecture is designed to support a wide range
55 of novel parallel computing models, it is fully interoperable with
56 traditional MPI applications.
57
58 * IPython has been used and tested extensively on modern supercomputers.
59
60 * IPython's networking layers are completely modular. Thus, is
61 straightforward to replace our existing network protocols with
62 high performance alternatives (ones based upon Myranet/Infiniband).
63
64 * IPython is designed from the ground up to support collaborative
65 parallel computing. This enables multiple users to actively develop
66 and run the *same* parallel computation.
67
68 * Interactivity is a central goal for us. While IPython does not have
69 to be used interactivly, it can be.
70
63 71 .. _Twisted: http://www.twistedmatrix.com
64 72
65 73 Why The IPython controller a bottleneck in my parallel calculation?
@@ -71,13 +79,17 b' too much data is being pushed and pulled to and from the engines. If your algori'
71 79 is structured in this way, you really should think about alternative ways of
72 80 handling the data movement. Here are some ideas:
73 81
74 1. Have the engines write data to files on the locals disks of the engines.
75 2. Have the engines write data to files on a file system that is shared by
76 the engines.
77 3. Have the engines write data to a database that is shared by the engines.
78 4. Simply keep data in the persistent memory of the engines and move the
79 computation to the data (rather than the data to the computation).
80 5. See if you can pass data directly between engines using MPI.
82 1. Have the engines write data to files on the locals disks of the engines.
83
84 2. Have the engines write data to files on a file system that is shared by
85 the engines.
86
87 3. Have the engines write data to a database that is shared by the engines.
88
89 4. Simply keep data in the persistent memory of the engines and move the
90 computation to the data (rather than the data to the computation).
91
92 5. See if you can pass data directly between engines using MPI.
81 93
82 94 Isn't Python slow to be used for high-performance parallel computing?
83 95 ---------------------------------------------------------------------
@@ -7,50 +7,32 b' History'
7 7 Origins
8 8 =======
9 9
10 The current IPython system grew out of the following three projects:
11
12 * [ipython] by Fernando Pérez. I was working on adding
13 Mathematica-type prompts and a flexible configuration system
14 (something better than $PYTHONSTARTUP) to the standard Python
15 interactive interpreter.
16 * [IPP] by Janko Hauser. Very well organized, great usability. Had
17 an old help system. IPP was used as the 'container' code into
18 which I added the functionality from ipython and LazyPython.
19 * [LazyPython] by Nathan Gray. Simple but very powerful. The quick
20 syntax (auto parens, auto quotes) and verbose/colored tracebacks
21 were all taken from here.
22
23 When I found out about IPP and LazyPython I tried to join all three
24 into a unified system. I thought this could provide a very nice
25 working environment, both for regular programming and scientific
26 computing: shell-like features, IDL/Matlab numerics, Mathematica-type
27 prompt history and great object introspection and help facilities. I
28 think it worked reasonably well, though it was a lot more work than I
29 had initially planned.
30
31
32 Current status
33 ==============
34
35 The above listed features work, and quite well for the most part. But
36 until a major internal restructuring is done (see below), only bug
37 fixing will be done, no other features will be added (unless very minor
38 and well localized in the cleaner parts of the code).
39
40 IPython consists of some 18000 lines of pure python code, of which
41 roughly two thirds is reasonably clean. The rest is, messy code which
42 needs a massive restructuring before any further major work is done.
43 Even the messy code is fairly well documented though, and most of the
44 problems in the (non-existent) class design are well pointed to by a
45 PyChecker run. So the rewriting work isn't that bad, it will just be
46 time-consuming.
47
48
49 Future
50 ------
51
52 See the separate new_design document for details. Ultimately, I would
53 like to see IPython become part of the standard Python distribution as a
54 'big brother with batteries' to the standard Python interactive
55 interpreter. But that will never happen with the current state of the
56 code, so all contributions are welcome. No newline at end of file
10 IPython was starting in 2001 by Fernando Perez. IPython as we know it
11 today grew out of the following three projects:
12
13 * ipython by Fernando Pérez. I was working on adding
14 Mathematica-type prompts and a flexible configuration system
15 (something better than $PYTHONSTARTUP) to the standard Python
16 interactive interpreter.
17 * IPP by Janko Hauser. Very well organized, great usability. Had
18 an old help system. IPP was used as the 'container' code into
19 which I added the functionality from ipython and LazyPython.
20 * LazyPython by Nathan Gray. Simple but very powerful. The quick
21 syntax (auto parens, auto quotes) and verbose/colored tracebacks
22 were all taken from here.
23
24 Here is how Fernando describes it:
25
26 When I found out about IPP and LazyPython I tried to join all three
27 into a unified system. I thought this could provide a very nice
28 working environment, both for regular programming and scientific
29 computing: shell-like features, IDL/Matlab numerics, Mathematica-type
30 prompt history and great object introspection and help facilities. I
31 think it worked reasonably well, though it was a lot more work than I
32 had initially planned.
33
34 Today and how we got here
35 =========================
36
37 This needs to be filled in.
38
@@ -2,11 +2,15 b''
2 2 IPython Documentation
3 3 =====================
4 4
5 Contents
6 ========
5 .. htmlonly::
6
7 :Release: |version|
8 :Date: |today|
9
10 Contents:
7 11
8 12 .. toctree::
9 :maxdepth: 1
13 :maxdepth: 2
10 14
11 15 overview.txt
12 16 install/index.txt
@@ -20,9 +24,9 b' Contents'
20 24 license_and_copyright.txt
21 25 credits.txt
22 26
23 Indices and tables
24 ==================
25 27
26 * :ref:`genindex`
27 * :ref:`modindex`
28 * :ref:`search` No newline at end of file
28 .. htmlonly::
29
30 * :ref:`genindex`
31 * :ref:`modindex`
32 * :ref:`search`
@@ -7,5 +7,4 b' Installation'
7 7 .. toctree::
8 8 :maxdepth: 2
9 9
10 basic.txt
11 advanced.txt
10 install.txt
@@ -8,7 +8,7 b' IPython reference'
8 8
9 9 .. contents::
10 10
11 .. _Command line options:
11 .. _command_line_options:
12 12
13 13 Command-line usage
14 14 ==================
@@ -288,12 +288,13 b' All options with a [no] prepended can be specified in negated form'
288 288 recursive inclusions.
289 289
290 290 -prompt_in1, pi1 <string>
291 Specify the string used for input prompts. Note that if you
292 are using numbered prompts, the number is represented with a
293 '\#' in the string. Don't forget to quote strings with spaces
294 embedded in them. Default: 'In [\#]:'. Sec. Prompts_
295 discusses in detail all the available escapes to customize
296 your prompts.
291
292 Specify the string used for input prompts. Note that if you are using
293 numbered prompts, the number is represented with a '\#' in the
294 string. Don't forget to quote strings with spaces embedded in
295 them. Default: 'In [\#]:'. The :ref:`prompts section <prompts>`
296 discusses in detail all the available escapes to customize your
297 prompts.
297 298
298 299 -prompt_in2, pi2 <string>
299 300 Similar to the previous option, but used for the continuation
@@ -2077,13 +2078,14 b' customizations.'
2077 2078 Access to the standard Python help
2078 2079 ----------------------------------
2079 2080
2080 As of Python 2.1, a help system is available with access to object
2081 docstrings and the Python manuals. Simply type 'help' (no quotes) to
2082 access it. You can also type help(object) to obtain information about a
2083 given object, and help('keyword') for information on a keyword. As noted
2084 in sec. `accessing help`_, you need to properly configure
2085 your environment variable PYTHONDOCS for this feature to work correctly.
2081 As of Python 2.1, a help system is available with access to object docstrings
2082 and the Python manuals. Simply type 'help' (no quotes) to access it. You can
2083 also type help(object) to obtain information about a given object, and
2084 help('keyword') for information on a keyword. As noted :ref:`here
2085 <accessing_help>`, you need to properly configure your environment variable
2086 PYTHONDOCS for this feature to work correctly.
2086 2087
2088 .. _dynamic_object_info:
2087 2089
2088 2090 Dynamic object information
2089 2091 --------------------------
@@ -2126,7 +2128,7 b' are not really defined as separate identifiers. Try for example typing'
2126 2128 {}.get? or after doing import os, type os.path.abspath??.
2127 2129
2128 2130
2129 .. _Readline:
2131 .. _readline:
2130 2132
2131 2133 Readline-based features
2132 2134 -----------------------
@@ -2240,10 +2242,9 b' explanation in your ipythonrc file.'
2240 2242 Session logging and restoring
2241 2243 -----------------------------
2242 2244
2243 You can log all input from a session either by starting IPython with
2244 the command line switches -log or -logfile (see sec. `command line
2245 options`_) or by activating the logging at any moment with the magic
2246 function %logstart.
2245 You can log all input from a session either by starting IPython with the
2246 command line switches -log or -logfile (see :ref:`here <command_line_options>`)
2247 or by activating the logging at any moment with the magic function %logstart.
2247 2248
2248 2249 Log files can later be reloaded with the -logplay option and IPython
2249 2250 will attempt to 'replay' the log by executing all the lines in it, thus
@@ -2279,6 +2280,8 b' resume logging to a file which had previously been started with'
2279 2280 %logstart. They will fail (with an explanation) if you try to use them
2280 2281 before logging has been started.
2281 2282
2283 .. _system_shell_access:
2284
2282 2285 System shell access
2283 2286 -------------------
2284 2287
@@ -2389,7 +2392,7 b" These features are basically a terminal version of Ka-Ping Yee's cgitb"
2389 2392 module, now part of the standard Python library.
2390 2393
2391 2394
2392 .. _Input caching:
2395 .. _input_caching:
2393 2396
2394 2397 Input caching system
2395 2398 --------------------
@@ -2429,7 +2432,7 b' sec. 6.2 <#sec:magic> for more details on the macro system.'
2429 2432 A history function %hist allows you to see any part of your input
2430 2433 history by printing a range of the _i variables.
2431 2434
2432 .. _Output caching:
2435 .. _output_caching:
2433 2436
2434 2437 Output caching system
2435 2438 ---------------------
@@ -3034,7 +3037,7 b' which is being shared by the interactive IPython loop and your GUI'
3034 3037 thread, you should really handle it with thread locking and
3035 3038 syncrhonization properties. The Python documentation discusses these.
3036 3039
3037 .. _Interactive demos:
3040 .. _interactive_demos:
3038 3041
3039 3042 Interactive demos with IPython
3040 3043 ==============================
@@ -3143,21 +3146,17 b' toolkits, including Tk, GTK and WXPython. It also provides a number of'
3143 3146 commands useful for scientific computing, all with a syntax compatible
3144 3147 with that of the popular Matlab program.
3145 3148
3146 IPython accepts the special option -pylab (Sec. `Command line
3147 options`_). This configures it to support matplotlib, honoring the
3148 settings in the .matplotlibrc file. IPython will detect the user's
3149 choice of matplotlib GUI backend, and automatically select the proper
3150 threading model to prevent blocking. It also sets matplotlib in
3151 interactive mode and modifies %run slightly, so that any
3152 matplotlib-based script can be executed using %run and the final
3153 show() command does not block the interactive shell.
3154
3155 The -pylab option must be given first in order for IPython to
3156 configure its threading mode. However, you can still issue other
3157 options afterwards. This allows you to have a matplotlib-based
3158 environment customized with additional modules using the standard
3159 IPython profile mechanism (Sec. Profiles_): ''ipython -pylab -p
3160 myprofile'' will load the profile defined in ipythonrc-myprofile after
3161 configuring matplotlib.
3162
3163
3149 IPython accepts the special option -pylab (see :ref:`here
3150 <command_line_options>`). This configures it to support matplotlib, honoring
3151 the settings in the .matplotlibrc file. IPython will detect the user's choice
3152 of matplotlib GUI backend, and automatically select the proper threading model
3153 to prevent blocking. It also sets matplotlib in interactive mode and modifies
3154 %run slightly, so that any matplotlib-based script can be executed using %run
3155 and the final show() command does not block the interactive shell.
3156
3157 The -pylab option must be given first in order for IPython to configure its
3158 threading mode. However, you can still issue other options afterwards. This
3159 allows you to have a matplotlib-based environment customized with additional
3160 modules using the standard IPython profile mechanism (see :ref:`here
3161 <profiles>`): ``ipython -pylab -p myprofile`` will load the profile defined in
3162 ipythonrc-myprofile after configuring matplotlib.
@@ -24,11 +24,11 b' Tab completion'
24 24 --------------
25 25
26 26 TAB-completion, especially for attributes, is a convenient way to explore the
27 structure of any object you're dealing with. Simply type object_name.<TAB>
28 and a list of the object's attributes will be printed (see readline_ for
29 more). Tab completion also works on file and directory names, which combined
30 with IPython's alias system allows you to do from within IPython many of the
31 things you normally would need the system shell for.
27 structure of any object you're dealing with. Simply type object_name.<TAB> and
28 a list of the object's attributes will be printed (see :ref:`the readline
29 section <readline>` for more). Tab completion also works on file and directory
30 names, which combined with IPython's alias system allows you to do from within
31 IPython many of the things you normally would need the system shell for.
32 32
33 33 Explore your objects
34 34 --------------------
@@ -39,18 +39,18 b' constructor details for classes. The magic commands %pdoc, %pdef, %psource'
39 39 and %pfile will respectively print the docstring, function definition line,
40 40 full source code and the complete file for any object (when they can be
41 41 found). If automagic is on (it is by default), you don't need to type the '%'
42 explicitly. See sec. `dynamic object information`_ for more.
42 explicitly. See :ref:`this section <dynamic_object_info>` for more.
43 43
44 44 The `%run` magic command
45 45 ------------------------
46 46
47 The %run magic command allows you to run any python script and load all of
48 its data directly into the interactive namespace. Since the file is re-read
49 from disk each time, changes you make to it are reflected immediately (in
50 contrast to the behavior of import). I rarely use import for code I am
51 testing, relying on %run instead. See magic_ section for more on this and
52 other magic commands, or type the name of any magic command and ? to get
53 details on it. See also sec. dreload_ for a recursive reload command. %run
47 The %run magic command allows you to run any python script and load all of its
48 data directly into the interactive namespace. Since the file is re-read from
49 disk each time, changes you make to it are reflected immediately (in contrast
50 to the behavior of import). I rarely use import for code I am testing, relying
51 on %run instead. See :ref:`this section <magic>` for more on this and other
52 magic commands, or type the name of any magic command and ? to get details on
53 it. See also :ref:`this section <dreload>` for a recursive reload command. %run
54 54 also has special flags for timing the execution of your scripts (-t) and for
55 55 executing them under the control of either Python's pdb debugger (-d) or
56 56 profiler (-p). With all of these, %run can be used as the main tool for
@@ -60,21 +60,21 b' choice.'
60 60 Debug a Python script
61 61 ---------------------
62 62
63 Use the Python debugger, pdb. The %pdb command allows you to toggle on and
64 off the automatic invocation of an IPython-enhanced pdb debugger (with
65 coloring, tab completion and more) at any uncaught exception. The advantage
66 of this is that pdb starts inside the function where the exception occurred,
67 with all data still available. You can print variables, see code, execute
68 statements and even walk up and down the call stack to track down the true
69 source of the problem (which often is many layers in the stack above where
70 the exception gets triggered). Running programs with %run and pdb active can
71 be an efficient to develop and debug code, in many cases eliminating the need
72 for print statements or external debugging tools. I often simply put a 1/0 in
73 a place where I want to take a look so that pdb gets called, quickly view
74 whatever variables I need to or test various pieces of code and then remove
75 the 1/0. Note also that '%run -d' activates pdb and automatically sets
76 initial breakpoints for you to step through your code, watch variables, etc.
77 See Sec. `Output caching`_ for details.
63 Use the Python debugger, pdb. The %pdb command allows you to toggle on and off
64 the automatic invocation of an IPython-enhanced pdb debugger (with coloring,
65 tab completion and more) at any uncaught exception. The advantage of this is
66 that pdb starts inside the function where the exception occurred, with all data
67 still available. You can print variables, see code, execute statements and even
68 walk up and down the call stack to track down the true source of the problem
69 (which often is many layers in the stack above where the exception gets
70 triggered). Running programs with %run and pdb active can be an efficient to
71 develop and debug code, in many cases eliminating the need for print statements
72 or external debugging tools. I often simply put a 1/0 in a place where I want
73 to take a look so that pdb gets called, quickly view whatever variables I need
74 to or test various pieces of code and then remove the 1/0. Note also that '%run
75 -d' activates pdb and automatically sets initial breakpoints for you to step
76 through your code, watch variables, etc. The :ref:`output caching section
77 <output_caching>` has more details.
78 78
79 79 Use the output cache
80 80 --------------------
@@ -84,7 +84,8 b' and variables named _1, _2, etc. alias them. For example, the result of input'
84 84 line 4 is available either as Out[4] or as _4. Additionally, three variables
85 85 named _, __ and ___ are always kept updated with the for the last three
86 86 results. This allows you to recall any previous result and further use it for
87 new calculations. See Sec. `Output caching`_ for more.
87 new calculations. See :ref:`the output caching section <output_caching>` for
88 more.
88 89
89 90 Suppress output
90 91 ---------------
@@ -102,7 +103,7 b' A similar system exists for caching input. All input is stored in a global'
102 103 list called In , so you can re-execute lines 22 through 28 plus line 34 by
103 104 typing 'exec In[22:29]+In[34]' (using Python slicing notation). If you need
104 105 to execute the same set of lines often, you can assign them to a macro with
105 the %macro function. See sec. `Input caching`_ for more.
106 the %macro function. See :ref:`here <input_caching>` for more.
106 107
107 108 Use your input history
108 109 ----------------------
@@ -134,17 +135,18 b' into Python variables.'
134 135 Use Python variables when calling the shell
135 136 -------------------------------------------
136 137
137 Expand python variables when calling the shell (either via '!' and '!!' or
138 via aliases) by prepending a $ in front of them. You can also expand complete
139 python expressions. See `System shell access`_ for more.
138 Expand python variables when calling the shell (either via '!' and '!!' or via
139 aliases) by prepending a $ in front of them. You can also expand complete
140 python expressions. See :ref:`our shell section <system_shell_access>` for
141 more details.
140 142
141 143 Use profiles
142 144 ------------
143 145
144 146 Use profiles to maintain different configurations (modules to load, function
145 147 definitions, option settings) for particular tasks. You can then have
146 customized versions of IPython for specific purposes. See sec. profiles_ for
147 more.
148 customized versions of IPython for specific purposes. :ref:`This section
149 <profiles>` has more details.
148 150
149 151
150 152 Embed IPython in your programs
@@ -152,7 +154,7 b' Embed IPython in your programs'
152 154
153 155 A few lines of code are enough to load a complete IPython inside your own
154 156 programs, giving you the ability to work with your data interactively after
155 automatic processing has been completed. See sec. embedding_ for more.
157 automatic processing has been completed. See :ref:`here <embedding>` for more.
156 158
157 159 Use the Python profiler
158 160 -----------------------
@@ -166,8 +168,8 b' Use IPython to present interactive demos'
166 168 ----------------------------------------
167 169
168 170 Use the IPython.demo.Demo class to load any Python script as an interactive
169 demo. With a minimal amount of simple markup, you can control the execution
170 of the script, stopping as needed. See sec. `interactive demos`_ for more.
171 demo. With a minimal amount of simple markup, you can control the execution of
172 the script, stopping as needed. See :ref:`here <interactive_demos>` for more.
171 173
172 174 Run doctests
173 175 ------------
@@ -1,56 +1,82 b''
1 1 .. _license:
2 2
3 =============================
4 License and Copyright
5 =============================
3 =====================
4 License and Copyright
5 =====================
6 6
7 This files needs to be updated to reflect what the new COPYING.txt files says about our license and copyright!
7 License
8 =======
8 9
9 IPython is released under the terms of the BSD license, whose general
10 form can be found at: http://www.opensource.org/licenses/bsd-license.php. The full text of the
11 IPython license is reproduced below::
10 IPython is licensed under the terms of the new or revised BSD license, as follows::
12 11
13 IPython is released under a BSD-type license.
12 Copyright (c) 2008, IPython Development Team
14 13
15 Copyright (c) 2001, 2002, 2003, 2004 Fernando Perez
16 <fperez@colorado.edu>.
14 All rights reserved.
17 15
18 Copyright (c) 2001 Janko Hauser <jhauser@zscout.de> and
19 Nathaniel Gray <n8gray@caltech.edu>.
16 Redistribution and use in source and binary forms, with or without modification,
17 are permitted provided that the following conditions are met:
20 18
21 All rights reserved.
19 Redistributions of source code must retain the above copyright notice, this list of
20 conditions and the following disclaimer.
21
22 Redistributions in binary form must reproduce the above copyright notice, this list
23 of conditions and the following disclaimer in the documentation and/or other
24 materials provided with the distribution.
25
26 Neither the name of the IPython Development Team nor the names of its contributors
27 may be used to endorse or promote products derived from this software without
28 specific prior written permission.
29
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
31 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
33 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
34 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
35 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
36 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
37 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
40
41 About the IPython Development Team
42 ==================================
43
44 Fernando Perez began IPython in 2001 based on code from Janko Hauser <jhauser@zscout.de>
45 and Nathaniel Gray <n8gray@caltech.edu>. Fernando is still the project lead.
46
47 The IPython Development Team is the set of all contributors to the IPython project.
48 This includes all of the IPython subprojects. Here is a list of the currently active contributors:
49
50 * Matthieu Brucher
51 * Ondrej Certik
52 * Laurent Dufrechou
53 * Robert Kern
54 * Brian E. Granger
55 * Fernando Perez (project leader)
56 * Benjamin Ragan-Kelley
57 * Ville M. Vainio
58 * Gael Varoququx
59 * Stefan van der Walt
60 * Tech-X Corporation
61 * Barry Wark
62
63 If your name is missing, please add it.
64
65 Our Copyright Policy
66 ====================
67
68 IPython uses a shared copyright model. Each contributor maintains copyright over
69 their contributions to IPython. But, it is important to note that these
70 contributions are typically only changes to the repositories. Thus, the IPython
71 source code, in its entirety is not the copyright of any single person or
72 institution. Instead, it is the collective copyright of the entire IPython
73 Development Team. If individual contributors want to maintain a record of what
74 changes/contributions they have specific copyright on, they should indicate their
75 copyright in the commit message of the change, when they commit the change to
76 one of the IPython repositories.
22 77
23 Redistribution and use in source and binary forms, with or without
24 modification, are permitted provided that the following conditions
25 are met:
26
27 a. Redistributions of source code must retain the above copyright
28 notice, this list of conditions and the following disclaimer.
29
30 b. Redistributions in binary form must reproduce the above copyright
31 notice, this list of conditions and the following disclaimer in the
32 documentation and/or other materials provided with the distribution.
33
34 c. Neither the name of the copyright holders nor the names of any
35 contributors to this software may be used to endorse or promote
36 products derived from this software without specific prior written
37 permission.
38
39 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
40 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
41 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
42 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
43 REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
44 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
45 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
47 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
49 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
50 POSSIBILITY OF SUCH DAMAGE.
51
52 Individual authors are the holders of the copyright for their code and
53 are listed in each file.
78 Miscellaneous
79 =============
54 80
55 81 Some files (DPyGetOpt.py, for example) may be licensed under different
56 82 conditions. Ultimately each file indicates clearly the conditions under
@@ -17,133 +17,161 b' The goal of IPython is to create a comprehensive environment for'
17 17 interactive and exploratory computing. To support, this goal, IPython
18 18 has two main components:
19 19
20 * An enhanced interactive Python shell.
21 * An architecture for interactive parallel computing.
20 * An enhanced interactive Python shell.
21 * An architecture for interactive parallel computing.
22 22
23 23 All of IPython is open source (released under the revised BSD license).
24 24
25 25 Enhanced interactive Python shell
26 26 =================================
27 27
28 IPython's interactive shell (`ipython`), has the following goals:
29
30 1. Provide an interactive shell superior to Python's default. IPython
31 has many features for object introspection, system shell access,
32 and its own special command system for adding functionality when
33 working interactively. It tries to be a very efficient environment
34 both for Python code development and for exploration of problems
35 using Python objects (in situations like data analysis).
36 2. Serve as an embeddable, ready to use interpreter for your own
37 programs. IPython can be started with a single call from inside
38 another program, providing access to the current namespace. This
39 can be very useful both for debugging purposes and for situations
40 where a blend of batch-processing and interactive exploration are
41 needed.
42 3. Offer a flexible framework which can be used as the base
43 environment for other systems with Python as the underlying
44 language. Specifically scientific environments like Mathematica,
45 IDL and Matlab inspired its design, but similar ideas can be
46 useful in many fields.
47 4. Allow interactive testing of threaded graphical toolkits. IPython
48 has support for interactive, non-blocking control of GTK, Qt and
49 WX applications via special threading flags. The normal Python
50 shell can only do this for Tkinter applications.
28 IPython's interactive shell (:command:`ipython`), has the following goals,
29 amongst others:
30
31 1. Provide an interactive shell superior to Python's default. IPython
32 has many features for object introspection, system shell access,
33 and its own special command system for adding functionality when
34 working interactively. It tries to be a very efficient environment
35 both for Python code development and for exploration of problems
36 using Python objects (in situations like data analysis).
37
38 2. Serve as an embeddable, ready to use interpreter for your own
39 programs. IPython can be started with a single call from inside
40 another program, providing access to the current namespace. This
41 can be very useful both for debugging purposes and for situations
42 where a blend of batch-processing and interactive exploration are
43 needed. New in the 0.9 version of IPython is a reusable wxPython
44 based IPython widget.
45
46 3. Offer a flexible framework which can be used as the base
47 environment for other systems with Python as the underlying
48 language. Specifically scientific environments like Mathematica,
49 IDL and Matlab inspired its design, but similar ideas can be
50 useful in many fields.
51
52 4. Allow interactive testing of threaded graphical toolkits. IPython
53 has support for interactive, non-blocking control of GTK, Qt and
54 WX applications via special threading flags. The normal Python
55 shell can only do this for Tkinter applications.
51 56
52 57 Main features of the interactive shell
53 58 --------------------------------------
54 59
55 * Dynamic object introspection. One can access docstrings, function
56 definition prototypes, source code, source files and other details
57 of any object accessible to the interpreter with a single
58 keystroke (:samp:`?`, and using :samp:`??` provides additional detail).
59 * Searching through modules and namespaces with :samp:`*` wildcards, both
60 when using the :samp:`?` system and via the :samp:`%psearch` command.
61 * Completion in the local namespace, by typing :kbd:`TAB` at the prompt.
62 This works for keywords, modules, methods, variables and files in the
63 current directory. This is supported via the readline library, and
64 full access to configuring readline's behavior is provided.
65 Custom completers can be implemented easily for different purposes
66 (system commands, magic arguments etc.)
67 * Numbered input/output prompts with command history (persistent
68 across sessions and tied to each profile), full searching in this
69 history and caching of all input and output.
70 * User-extensible 'magic' commands. A set of commands prefixed with
71 :samp:`%` is available for controlling IPython itself and provides
72 directory control, namespace information and many aliases to
73 common system shell commands.
74 * Alias facility for defining your own system aliases.
75 * Complete system shell access. Lines starting with :samp:`!` are passed
76 directly to the system shell, and using :samp:`!!` or :samp:`var = !cmd`
77 captures shell output into python variables for further use.
78 * Background execution of Python commands in a separate thread.
79 IPython has an internal job manager called jobs, and a
80 conveninence backgrounding magic function called :samp:`%bg`.
81 * The ability to expand python variables when calling the system
82 shell. In a shell command, any python variable prefixed with :samp:`$` is
83 expanded. A double :samp:`$$` allows passing a literal :samp:`$` to the shell (for
84 access to shell and environment variables like :envvar:`PATH`).
85 * Filesystem navigation, via a magic :samp:`%cd` command, along with a
86 persistent bookmark system (using :samp:`%bookmark`) for fast access to
87 frequently visited directories.
88 * A lightweight persistence framework via the :samp:`%store` command, which
89 allows you to save arbitrary Python variables. These get restored
90 automatically when your session restarts.
91 * Automatic indentation (optional) of code as you type (through the
92 readline library).
93 * Macro system for quickly re-executing multiple lines of previous
94 input with a single name. Macros can be stored persistently via
95 :samp:`%store` and edited via :samp:`%edit`.
96 * Session logging (you can then later use these logs as code in your
97 programs). Logs can optionally timestamp all input, and also store
98 session output (marked as comments, so the log remains valid
99 Python source code).
100 * Session restoring: logs can be replayed to restore a previous
101 session to the state where you left it.
102 * Verbose and colored exception traceback printouts. Easier to parse
103 visually, and in verbose mode they produce a lot of useful
104 debugging information (basically a terminal version of the cgitb
105 module).
106 * Auto-parentheses: callable objects can be executed without
107 parentheses: :samp:`sin 3` is automatically converted to :samp:`sin(3)`.
108 * Auto-quoting: using :samp:`,`, or :samp:`;` as the first character forces
109 auto-quoting of the rest of the line: :samp:`,my_function a b` becomes
110 automatically :samp:`my_function("a","b")`, while :samp:`;my_function a b`
111 becomes :samp:`my_function("a b")`.
112 * Extensible input syntax. You can define filters that pre-process
113 user input to simplify input in special situations. This allows
114 for example pasting multi-line code fragments which start with
115 :samp:`>>>` or :samp:`...` such as those from other python sessions or the
116 standard Python documentation.
117 * Flexible configuration system. It uses a configuration file which
118 allows permanent setting of all command-line options, module
119 loading, code and file execution. The system allows recursive file
120 inclusion, so you can have a base file with defaults and layers
121 which load other customizations for particular projects.
122 * Embeddable. You can call IPython as a python shell inside your own
123 python programs. This can be used both for debugging code or for
124 providing interactive abilities to your programs with knowledge
125 about the local namespaces (very useful in debugging and data
126 analysis situations).
127 * Easy debugger access. You can set IPython to call up an enhanced
128 version of the Python debugger (pdb) every time there is an
129 uncaught exception. This drops you inside the code which triggered
130 the exception with all the data live and it is possible to
131 navigate the stack to rapidly isolate the source of a bug. The
132 :samp:`%run` magic command (with the :samp:`-d` option) can run any script under
133 pdb's control, automatically setting initial breakpoints for you.
134 This version of pdb has IPython-specific improvements, including
135 tab-completion and traceback coloring support. For even easier
136 debugger access, try :samp:`%debug` after seeing an exception. winpdb is
137 also supported, see ipy_winpdb extension.
138 * Profiler support. You can run single statements (similar to
139 :samp:`profile.run()`) or complete programs under the profiler's control.
140 While this is possible with standard cProfile or profile modules,
141 IPython wraps this functionality with magic commands (see :samp:`%prun`
142 and :samp:`%run -p`) convenient for rapid interactive work.
143 * Doctest support. The special :samp:`%doctest_mode` command toggles a mode
144 that allows you to paste existing doctests (with leading :samp:`>>>`
145 prompts and whitespace) and uses doctest-compatible prompts and
146 output, so you can use IPython sessions as doctest code.
60 * Dynamic object introspection. One can access docstrings, function
61 definition prototypes, source code, source files and other details
62 of any object accessible to the interpreter with a single
63 keystroke (:samp:`?`, and using :samp:`??` provides additional detail).
64
65 * Searching through modules and namespaces with :samp:`*` wildcards, both
66 when using the :samp:`?` system and via the :samp:`%psearch` command.
67
68 * Completion in the local namespace, by typing :kbd:`TAB` at the prompt.
69 This works for keywords, modules, methods, variables and files in the
70 current directory. This is supported via the readline library, and
71 full access to configuring readline's behavior is provided.
72 Custom completers can be implemented easily for different purposes
73 (system commands, magic arguments etc.)
74
75 * Numbered input/output prompts with command history (persistent
76 across sessions and tied to each profile), full searching in this
77 history and caching of all input and output.
78
79 * User-extensible 'magic' commands. A set of commands prefixed with
80 :samp:`%` is available for controlling IPython itself and provides
81 directory control, namespace information and many aliases to
82 common system shell commands.
83
84 * Alias facility for defining your own system aliases.
85
86 * Complete system shell access. Lines starting with :samp:`!` are passed
87 directly to the system shell, and using :samp:`!!` or :samp:`var = !cmd`
88 captures shell output into python variables for further use.
89
90 * Background execution of Python commands in a separate thread.
91 IPython has an internal job manager called jobs, and a
92 convenience backgrounding magic function called :samp:`%bg`.
93
94 * The ability to expand python variables when calling the system
95 shell. In a shell command, any python variable prefixed with :samp:`$` is
96 expanded. A double :samp:`$$` allows passing a literal :samp:`$` to the shell (for
97 access to shell and environment variables like :envvar:`PATH`).
98
99 * Filesystem navigation, via a magic :samp:`%cd` command, along with a
100 persistent bookmark system (using :samp:`%bookmark`) for fast access to
101 frequently visited directories.
102
103 * A lightweight persistence framework via the :samp:`%store` command, which
104 allows you to save arbitrary Python variables. These get restored
105 automatically when your session restarts.
106
107 * Automatic indentation (optional) of code as you type (through the
108 readline library).
109
110 * Macro system for quickly re-executing multiple lines of previous
111 input with a single name. Macros can be stored persistently via
112 :samp:`%store` and edited via :samp:`%edit`.
113
114 * Session logging (you can then later use these logs as code in your
115 programs). Logs can optionally timestamp all input, and also store
116 session output (marked as comments, so the log remains valid
117 Python source code).
118
119 * Session restoring: logs can be replayed to restore a previous
120 session to the state where you left it.
121
122 * Verbose and colored exception traceback printouts. Easier to parse
123 visually, and in verbose mode they produce a lot of useful
124 debugging information (basically a terminal version of the cgitb
125 module).
126
127 * Auto-parentheses: callable objects can be executed without
128 parentheses: :samp:`sin 3` is automatically converted to :samp:`sin(3)`.
129
130 * Auto-quoting: using :samp:`,`, or :samp:`;` as the first character forces
131 auto-quoting of the rest of the line: :samp:`,my_function a b` becomes
132 automatically :samp:`my_function("a","b")`, while :samp:`;my_function a b`
133 becomes :samp:`my_function("a b")`.
134
135 * Extensible input syntax. You can define filters that pre-process
136 user input to simplify input in special situations. This allows
137 for example pasting multi-line code fragments which start with
138 :samp:`>>>` or :samp:`...` such as those from other python sessions or the
139 standard Python documentation.
140
141 * Flexible configuration system. It uses a configuration file which
142 allows permanent setting of all command-line options, module
143 loading, code and file execution. The system allows recursive file
144 inclusion, so you can have a base file with defaults and layers
145 which load other customizations for particular projects.
146
147 * Embeddable. You can call IPython as a python shell inside your own
148 python programs. This can be used both for debugging code or for
149 providing interactive abilities to your programs with knowledge
150 about the local namespaces (very useful in debugging and data
151 analysis situations).
152
153 * Easy debugger access. You can set IPython to call up an enhanced
154 version of the Python debugger (pdb) every time there is an
155 uncaught exception. This drops you inside the code which triggered
156 the exception with all the data live and it is possible to
157 navigate the stack to rapidly isolate the source of a bug. The
158 :samp:`%run` magic command (with the :samp:`-d` option) can run any script under
159 pdb's control, automatically setting initial breakpoints for you.
160 This version of pdb has IPython-specific improvements, including
161 tab-completion and traceback coloring support. For even easier
162 debugger access, try :samp:`%debug` after seeing an exception. winpdb is
163 also supported, see ipy_winpdb extension.
164
165 * Profiler support. You can run single statements (similar to
166 :samp:`profile.run()`) or complete programs under the profiler's control.
167 While this is possible with standard cProfile or profile modules,
168 IPython wraps this functionality with magic commands (see :samp:`%prun`
169 and :samp:`%run -p`) convenient for rapid interactive work.
170
171 * Doctest support. The special :samp:`%doctest_mode` command toggles a mode
172 that allows you to paste existing doctests (with leading :samp:`>>>`
173 prompts and whitespace) and uses doctest-compatible prompts and
174 output, so you can use IPython sessions as doctest code.
147 175
148 176 Interactive parallel computing
149 177 ==============================
@@ -153,6 +181,37 b' architecture within IPython that allows such hardware to be used quickly and eas'
153 181 from Python. Moreover, this architecture is designed to support interactive and
154 182 collaborative parallel computing.
155 183
184 The main features of this system are:
185
186 * Quickly parallelize Python code from an interactive Python/IPython session.
187
188 * A flexible and dynamic process model that be deployed on anything from
189 multicore workstations to supercomputers.
190
191 * An architecture that supports many different styles of parallelism, from
192 message passing to task farming. And all of these styles can be handled
193 interactively.
194
195 * Both blocking and fully asynchronous interfaces.
196
197 * High level APIs that enable many things to be parallelized in a few lines
198 of code.
199
200 * Write parallel code that will run unchanged on everything from multicore
201 workstations to supercomputers.
202
203 * Full integration with Message Passing libraries (MPI).
204
205 * Capabilities based security model with full encryption of network connections.
206
207 * Share live parallel jobs with other users securely. We call this collaborative
208 parallel computing.
209
210 * Dynamically load balanced task farming system.
211
212 * Robust error handling. Python exceptions raised in parallel execution are
213 gathered and presented to the top-level code.
214
156 215 For more information, see our :ref:`overview <parallel_index>` of using IPython for
157 216 parallel computing.
158 217
@@ -1,12 +1,9 b''
1 1 .. _parallel_index:
2 2
3 3 ====================================
4 Using IPython for Parallel computing
4 Using IPython for parallel computing
5 5 ====================================
6 6
7 User Documentation
8 ==================
9
10 7 .. toctree::
11 8 :maxdepth: 2
12 9
@@ -1,57 +1,68 b''
1 1 .. _ip1par:
2 2
3 ======================================
4 Using IPython for parallel computing
5 ======================================
3 ============================
4 Overview and getting started
5 ============================
6 6
7 7 .. contents::
8 8
9 9 Introduction
10 10 ============
11 11
12 This file gives an overview of IPython. IPython has a sophisticated and
12 This file gives an overview of IPython's sophisticated and
13 13 powerful architecture for parallel and distributed computing. This
14 14 architecture abstracts out parallelism in a very general way, which
15 15 enables IPython to support many different styles of parallelism
16 16 including:
17 17
18 * Single program, multiple data (SPMD) parallelism.
19 * Multiple program, multiple data (MPMD) parallelism.
20 * Message passing using ``MPI``.
21 * Task farming.
22 * Data parallel.
23 * Combinations of these approaches.
24 * Custom user defined approaches.
18 * Single program, multiple data (SPMD) parallelism.
19 * Multiple program, multiple data (MPMD) parallelism.
20 * Message passing using ``MPI``.
21 * Task farming.
22 * Data parallel.
23 * Combinations of these approaches.
24 * Custom user defined approaches.
25 25
26 26 Most importantly, IPython enables all types of parallel applications to
27 27 be developed, executed, debugged and monitored *interactively*. Hence,
28 28 the ``I`` in IPython. The following are some example usage cases for IPython:
29 29
30 * Quickly parallelize algorithms that are embarrassingly parallel
31 using a number of simple approaches. Many simple things can be
32 parallelized interactively in one or two lines of code.
33 * Steer traditional MPI applications on a supercomputer from an
34 IPython session on your laptop.
35 * Analyze and visualize large datasets (that could be remote and/or
36 distributed) interactively using IPython and tools like
37 matplotlib/TVTK.
38 * Develop, test and debug new parallel algorithms
39 (that may use MPI) interactively.
40 * Tie together multiple MPI jobs running on different systems into
41 one giant distributed and parallel system.
42 * Start a parallel job on your cluster and then have a remote
43 collaborator connect to it and pull back data into their
44 local IPython session for plotting and analysis.
45 * Run a set of tasks on a set of CPUs using dynamic load balancing.
30 * Quickly parallelize algorithms that are embarrassingly parallel
31 using a number of simple approaches. Many simple things can be
32 parallelized interactively in one or two lines of code.
33
34 * Steer traditional MPI applications on a supercomputer from an
35 IPython session on your laptop.
36
37 * Analyze and visualize large datasets (that could be remote and/or
38 distributed) interactively using IPython and tools like
39 matplotlib/TVTK.
40
41 * Develop, test and debug new parallel algorithms
42 (that may use MPI) interactively.
43
44 * Tie together multiple MPI jobs running on different systems into
45 one giant distributed and parallel system.
46
47 * Start a parallel job on your cluster and then have a remote
48 collaborator connect to it and pull back data into their
49 local IPython session for plotting and analysis.
50
51 * Run a set of tasks on a set of CPUs using dynamic load balancing.
46 52
47 53 Architecture overview
48 54 =====================
49 55
50 56 The IPython architecture consists of three components:
51 57
52 * The IPython engine.
53 * The IPython controller.
54 * Various controller Clients.
58 * The IPython engine.
59 * The IPython controller.
60 * Various controller clients.
61
62 These components live in the :mod:`IPython.kernel` package and are
63 installed with IPython. They do, however, have additional dependencies
64 that must be installed. For more information, see our
65 :ref:`installation documentation <install_index>`.
55 66
56 67 IPython engine
57 68 ---------------
@@ -75,16 +86,21 b' IPython engines can connect. For each connected engine, the controller'
75 86 manages a queue. All actions that can be performed on the engine go
76 87 through this queue. While the engines themselves block when user code is
77 88 run, the controller hides that from the user to provide a fully
78 asynchronous interface to a set of engines. Because the controller
79 listens on a network port for engines to connect to it, it must be
80 started before any engines are started.
89 asynchronous interface to a set of engines.
90
91 .. note::
92
93 Because the controller listens on a network port for engines to
94 connect to it, it must be started *before* any engines are started.
81 95
82 96 The controller also provides a single point of contact for users who wish
83 97 to utilize the engines connected to the controller. There are different
84 98 ways of working with a controller. In IPython these ways correspond to different interfaces that the controller is adapted to. Currently we have two default interfaces to the controller:
85 99
86 * The MultiEngine interface.
87 * The Task interface.
100 * The MultiEngine interface, which provides the simplest possible way of working
101 with engines interactively.
102 * The Task interface, which provides presents the engines as a load balanced
103 task farming system.
88 104
89 105 Advanced users can easily add new custom interfaces to enable other
90 106 styles of parallelism.
@@ -100,18 +116,37 b' Controller clients'
100 116
101 117 For each controller interface, there is a corresponding client. These
102 118 clients allow users to interact with a set of engines through the
103 interface.
119 interface. Here are the two default clients:
120
121 * The :class:`MultiEngineClient` class.
122 * The :class:`TaskClient` class.
104 123
105 124 Security
106 125 --------
107 126
108 By default (as long as `pyOpenSSL` is installed) all network connections between the controller and engines and the controller and clients are secure. What does this mean? First of all, all of the connections will be encrypted using SSL. Second, the connections are authenticated. We handle authentication in a `capabilities`__ based security model. In this model, a "capability (known in some systems as a key) is a communicable, unforgeable token of authority". Put simply, a capability is like a key to your house. If you have the key to your house, you can get in, if not you can't.
127 By default (as long as `pyOpenSSL` is installed) all network connections between the controller and engines and the controller and clients are secure. What does this mean? First of all, all of the connections will be encrypted using SSL. Second, the connections are authenticated. We handle authentication in a `capabilities`__ based security model. In this model, a "capability (known in some systems as a key) is a communicable, unforgeable token of authority". Put simply, a capability is like a key to your house. If you have the key to your house, you can get in. If not, you can't.
109 128
110 129 .. __: http://en.wikipedia.org/wiki/Capability-based_security
111 130
112 In our architecture, the controller is the only process that listens on network ports, and is thus responsible to creating these keys. In IPython, these keys are known as Foolscap URLs, or FURLs, because of the underlying network protocol we are using. As a user, you don't need to know anything about the details of these FURLs, other than that when the controller starts, it saves a set of FURLs to files named something.furl. The default location of these files is your ~./ipython directory.
131 In our architecture, the controller is the only process that listens on network ports, and is thus responsible to creating these keys. In IPython, these keys are known as Foolscap URLs, or FURLs, because of the underlying network protocol we are using. As a user, you don't need to know anything about the details of these FURLs, other than that when the controller starts, it saves a set of FURLs to files named :file:`something.furl`. The default location of these files is the :file:`~./ipython/security` directory.
113 132
114 To connect and authenticate to the controller an engine or client simply needs to present an appropriate furl (that was originally created by the controller) to the controller. Thus, the .furl files need to be copied to a location where the clients and engines can find them. Typically, this is the ~./ipython directory on the host where the client/engine is running (which could be a different host than the controller). Once the .furl files are copied over, everything should work fine.
133 To connect and authenticate to the controller an engine or client simply needs to present an appropriate furl (that was originally created by the controller) to the controller. Thus, the .furl files need to be copied to a location where the clients and engines can find them. Typically, this is the :file:`~./ipython/security` directory on the host where the client/engine is running (which could be a different host than the controller). Once the .furl files are copied over, everything should work fine.
134
135 Currently, there are three .furl files that the controller creates:
136
137 ipcontroller-engine.furl
138 This ``.furl`` file is the key that gives an engine the ability to connect
139 to a controller.
140
141 ipcontroller-tc.furl
142 This ``.furl`` file is the key that a :class:`TaskClient` must use to
143 connect to the task interface of a controller.
144
145 ipcontroller-mec.furl
146 This ``.furl`` file is the key that a :class:`MultiEngineClient` must use to
147 connect to the multiengine interface of a controller.
148
149 More details of how these ``.furl`` files are used are given below.
115 150
116 151 Getting Started
117 152 ===============
@@ -127,28 +162,40 b' Starting the controller and engine on your local machine'
127 162
128 163 This is the simplest configuration that can be used and is useful for
129 164 testing the system and on machines that have multiple cores and/or
130 multple CPUs. The easiest way of doing this is using the ``ipcluster``
165 multple CPUs. The easiest way of getting started is to use the :command:`ipcluster`
131 166 command::
132 167
133 168 $ ipcluster -n 4
134
169
135 170 This will start an IPython controller and then 4 engines that connect to
136 171 the controller. Lastly, the script will print out the Python commands
137 172 that you can use to connect to the controller. It is that easy.
138 173
139 Underneath the hood, the ``ipcluster`` script uses two other top-level
174 .. warning::
175
176 The :command:`ipcluster` does not currently work on Windows. We are
177 working on it though.
178
179 Underneath the hood, the controller creates ``.furl`` files in the
180 :file:`~./ipython/security` directory. Because the engines are on the
181 same host, they automatically find the needed :file:`ipcontroller-engine.furl`
182 there and use it to connect to the controller.
183
184 The :command:`ipcluster` script uses two other top-level
140 185 scripts that you can also use yourself. These scripts are
141 ``ipcontroller``, which starts the controller and ``ipengine`` which
186 :command:`ipcontroller`, which starts the controller and :command:`ipengine` which
142 187 starts one engine. To use these scripts to start things on your local
143 188 machine, do the following.
144 189
145 190 First start the controller::
146 191
147 $ ipcontroller &
192 $ ipcontroller
148 193
149 194 Next, start however many instances of the engine you want using (repeatedly) the command::
150 195
151 $ ipengine &
196 $ ipengine
197
198 The engines should start and automatically connect to the controller using the ``.furl`` files in :file:`~./ipython/security`. You are now ready to use the controller and engines from IPython.
152 199
153 200 .. warning::
154 201
@@ -156,47 +203,71 b' Next, start however many instances of the engine you want using (repeatedly) the'
156 203 start the controller before the engines, since the engines connect
157 204 to the controller as they get started.
158 205
159 On some platforms you may need to give these commands in the form
160 ``(ipcontroller &)`` and ``(ipengine &)`` for them to work properly. The
161 engines should start and automatically connect to the controller on the
162 default ports, which are chosen for this type of setup. You are now ready
163 to use the controller and engines from IPython.
206 .. note::
164 207
165 Starting the controller and engines on different machines
166 ---------------------------------------------------------
208 On some platforms (OS X), to put the controller and engine into the background
209 you may need to give these commands in the form ``(ipcontroller &)``
210 and ``(ipengine &)`` (with the parentheses) for them to work properly.
167 211
168 This section needs to be updated to reflect the new Foolscap capabilities based
169 model.
170 212
171 Using ``ipcluster`` with ``ssh``
172 --------------------------------
213 Starting the controller and engines on different hosts
214 ------------------------------------------------------
173 215
174 The ``ipcluster`` command can also start a controller and engines using
175 ``ssh``. We need more documentation on this, but for now here is any
176 example startup script::
216 When the controller and engines are running on different hosts, things are
217 slightly more complicated, but the underlying ideas are the same:
177 218
178 controller = dict(host='myhost',
179 engine_port=None, # default is 10105
180 control_port=None,
181 )
219 1. Start the controller on a host using :command:`ipcontroler`.
220 2. Copy :file:`ipcontroller-engine.furl` from :file:`~./ipython/security` on the controller's host to the host where the engines will run.
221 3. Use :command:`ipengine` on the engine's hosts to start the engines.
182 222
183 # keys are hostnames, values are the number of engine on that host
184 engines = dict(node1=2,
185 node2=2,
186 node3=2,
187 node3=2,
188 )
223 The only thing you have to be careful of is to tell :command:`ipengine` where the :file:`ipcontroller-engine.furl` file is located. There are two ways you can do this:
224
225 * Put :file:`ipcontroller-engine.furl` in the :file:`~./ipython/security` directory
226 on the engine's host, where it will be found automatically.
227 * Call :command:`ipengine` with the ``--furl-file=full_path_to_the_file`` flag.
228
229 The ``--furl-file`` flag works like this::
230
231 $ ipengine --furl-file=/path/to/my/ipcontroller-engine.furl
232
233 .. note::
234
235 If the controller's and engine's hosts all have a shared file system
236 (:file:`~./ipython/security` is the same on all of them), then things
237 will just work!
238
239 Make .furl files persistent
240 ---------------------------
241
242 At fist glance it may seem that that managing the ``.furl`` files is a bit annoying. Going back to the house and key analogy, copying the ``.furl`` around each time you start the controller is like having to make a new key everytime you want to unlock the door and enter your house. As with your house, you want to be able to create the key (or ``.furl`` file) once, and then simply use it at any point in the future.
243
244 This is possible. The only thing you have to do is decide what ports the controller will listen on for the engines and clients. This is done as follows::
245
246 $ ipcontroller --client-port=10101 --engine-port=10102
247
248 Then, just copy the furl files over the first time and you are set. You can start and stop the controller and engines any many times as you want in the future, just make sure to tell the controller to use the *same* ports.
249
250 .. note::
251
252 You may ask the question: what ports does the controller listen on if you
253 don't tell is to use specific ones? The default is to use high random port
254 numbers. We do this for two reasons: i) to increase security through obcurity
255 and ii) to multiple controllers on a given host to start and automatically
256 use different ports.
189 257
190 258 Starting engines using ``mpirun``
191 259 ---------------------------------
192 260
193 261 The IPython engines can be started using ``mpirun``/``mpiexec``, even if
194 the engines don't call MPI_Init() or use the MPI API in any way. This is
262 the engines don't call ``MPI_Init()`` or use the MPI API in any way. This is
195 263 supported on modern MPI implementations like `Open MPI`_.. This provides
196 264 an really nice way of starting a bunch of engine. On a system with MPI
197 265 installed you can do::
198 266
199 mpirun -n 4 ipengine --controller-port=10000 --controller-ip=host0
267 mpirun -n 4 ipengine
268
269 to start 4 engine on a cluster. This works even if you don't have any
270 Python-MPI bindings installed.
200 271
201 272 .. _Open MPI: http://www.open-mpi.org/
202 273
@@ -214,12 +285,12 b' Next Steps'
214 285 ==========
215 286
216 287 Once you have started the IPython controller and one or more engines, you
217 are ready to use the engines to do somnething useful. To make sure
288 are ready to use the engines to do something useful. To make sure
218 289 everything is working correctly, try the following commands::
219 290
220 291 In [1]: from IPython.kernel import client
221 292
222 In [2]: mec = client.MultiEngineClient() # This looks for .furl files in ~./ipython
293 In [2]: mec = client.MultiEngineClient()
223 294
224 295 In [4]: mec.get_ids()
225 296 Out[4]: [0, 1, 2, 3]
@@ -239,4 +310,18 b' everything is working correctly, try the following commands::'
239 310 [3] In [1]: print "Hello World"
240 311 [3] Out[1]: Hello World
241 312
242 If this works, you are ready to learn more about the :ref:`MultiEngine <parallelmultiengine>` and :ref:`Task <paralleltask>` interfaces to the controller.
313 Remember, a client also needs to present a ``.furl`` file to the controller. How does this happen? When a multiengine client is created with no arguments, the client tries to find the corresponding ``.furl`` file in the local :file:`~./ipython/security` directory. If it finds it, you are set. If you have put the ``.furl`` file in a different location or it has a different name, create the client like this::
314
315 mec = client.MultiEngineClient('/path/to/my/ipcontroller-mec.furl')
316
317 Same thing hold true of creating a task client::
318
319 tc = client.TaskClient('/path/to/my/ipcontroller-tc.furl')
320
321 You are now ready to learn more about the :ref:`MultiEngine <parallelmultiengine>` and :ref:`Task <paralleltask>` interfaces to the controller.
322
323 .. note::
324
325 Don't forget that the engine, multiengine client and task client all have
326 *different* furl files. You must move *each* of these around to an appropriate
327 location so that the engines and clients can use them to connect to the controller.
@@ -1,57 +1,115 b''
1 1 .. _parallelmultiengine:
2 2
3 =================================
4 IPython's MultiEngine interface
5 =================================
3 ===============================
4 IPython's multiengine interface
5 ===============================
6 6
7 7 .. contents::
8 8
9 The MultiEngine interface represents one possible way of working with a
10 set of IPython engines. The basic idea behind the MultiEngine interface is
11 that the capabilities of each engine are explicitly exposed to the user.
12 Thus, in the MultiEngine interface, each engine is given an id that is
13 used to identify the engine and give it work to do. This interface is very
14 intuitive and is designed with interactive usage in mind, and is thus the
15 best place for new users of IPython to begin.
9 The multiengine interface represents one possible way of working with a set of
10 IPython engines. The basic idea behind the multiengine interface is that the
11 capabilities of each engine are directly and explicitly exposed to the user.
12 Thus, in the multiengine interface, each engine is given an id that is used to
13 identify the engine and give it work to do. This interface is very intuitive
14 and is designed with interactive usage in mind, and is thus the best place for
15 new users of IPython to begin.
16 16
17 17 Starting the IPython controller and engines
18 18 ===========================================
19 19
20 20 To follow along with this tutorial, you will need to start the IPython
21 controller and four IPython engines. The simplest way of doing this is to
22 use the ``ipcluster`` command::
21 controller and four IPython engines. The simplest way of doing this is to use
22 the :command:`ipcluster` command::
23 23
24 24 $ ipcluster -n 4
25 25
26 For more detailed information about starting the controller and engines, see our :ref:`introduction <ip1par>` to using IPython for parallel computing.
26 For more detailed information about starting the controller and engines, see
27 our :ref:`introduction <ip1par>` to using IPython for parallel computing.
27 28
28 29 Creating a ``MultiEngineClient`` instance
29 30 =========================================
30 31
31 The first step is to import the IPython ``client`` module and then create a ``MultiEngineClient`` instance::
32 The first step is to import the IPython :mod:`IPython.kernel.client` module
33 and then create a :class:`MultiEngineClient` instance::
32 34
33 35 In [1]: from IPython.kernel import client
34 36
35 37 In [2]: mec = client.MultiEngineClient()
36 38
37 To make sure there are engines connected to the controller, use can get a list of engine ids::
39 This form assumes that the :file:`ipcontroller-mec.furl` is in the
40 :file:`~./ipython/security` directory on the client's host. If not, the
41 location of the ``.furl`` file must be given as an argument to the
42 constructor::
43
44 In[2]: mec = client.MultiEngineClient('/path/to/my/ipcontroller-mec.furl')
45
46 To make sure there are engines connected to the controller, use can get a list
47 of engine ids::
38 48
39 49 In [3]: mec.get_ids()
40 50 Out[3]: [0, 1, 2, 3]
41 51
42 52 Here we see that there are four engines ready to do work for us.
43 53
54 Quick and easy parallelism
55 ==========================
56
57 In many cases, you simply want to apply a Python function to a sequence of objects, but *in parallel*. The multiengine interface provides two simple ways of accomplishing this: a parallel version of :func:`map` and ``@parallel`` function decorator.
58
59 Parallel map
60 ------------
61
62 Python's builtin :func:`map` functions allows a function to be applied to a
63 sequence element-by-element. This type of code is typically trivial to
64 parallelize. In fact, the multiengine interface in IPython already has a
65 parallel version of :meth:`map` that works just like its serial counterpart::
66
67 In [63]: serial_result = map(lambda x:x**10, range(32))
68
69 In [64]: parallel_result = mec.map(lambda x:x**10, range(32))
70
71 In [65]: serial_result==parallel_result
72 Out[65]: True
73
74 .. note::
75
76 The multiengine interface version of :meth:`map` does not do any load
77 balancing. For a load balanced version, see the task interface.
78
79 .. seealso::
80
81 The :meth:`map` method has a number of options that can be controlled by
82 the :meth:`mapper` method. See its docstring for more information.
83
84 Parallel function decorator
85 ---------------------------
86
87 Parallel functions are just like normal function, but they can be called on sequences and *in parallel*. The multiengine interface provides a decorator that turns any Python function into a parallel function::
88
89 In [10]: @mec.parallel()
90 ....: def f(x):
91 ....: return 10.0*x**4
92 ....:
93
94 In [11]: f(range(32)) # this is done in parallel
95 Out[11]:
96 [0.0,10.0,160.0,...]
97
98 See the docstring for the :meth:`parallel` decorator for options.
99
44 100 Running Python commands
45 101 =======================
46 102
47 The most basic type of operation that can be performed on the engines is to execute Python code. Executing Python code can be done in blocking or non-blocking mode (blocking is default) using the ``execute`` method.
103 The most basic type of operation that can be performed on the engines is to
104 execute Python code. Executing Python code can be done in blocking or
105 non-blocking mode (blocking is default) using the :meth:`execute` method.
48 106
49 107 Blocking execution
50 108 ------------------
51 109
52 In blocking mode, the ``MultiEngineClient`` object (called ``mec`` in
110 In blocking mode, the :class:`MultiEngineClient` object (called ``mec`` in
53 111 these examples) submits the command to the controller, which places the
54 command in the engines' queues for execution. The ``execute`` call then
112 command in the engines' queues for execution. The :meth:`execute` call then
55 113 blocks until the engines are done executing the command::
56 114
57 115 # The default is to run on all engines
@@ -71,7 +129,8 b' blocks until the engines are done executing the command::'
71 129 [2] In [2]: b=10
72 130 [3] In [2]: b=10
73 131
74 Python commands can be executed on specific engines by calling execute using the ``targets`` keyword argument::
132 Python commands can be executed on specific engines by calling execute using
133 the ``targets`` keyword argument::
75 134
76 135 In [6]: mec.execute('c=a+b',targets=[0,2])
77 136 Out[6]:
@@ -102,7 +161,9 b' Python commands can be executed on specific engines by calling execute using the'
102 161 [3] In [4]: print c
103 162 [3] Out[4]: -5
104 163
105 This example also shows one of the most important things about the IPython engines: they have a persistent user namespaces. The ``execute`` method returns a Python ``dict`` that contains useful information::
164 This example also shows one of the most important things about the IPython
165 engines: they have a persistent user namespaces. The :meth:`execute` method
166 returns a Python ``dict`` that contains useful information::
106 167
107 168 In [9]: result_dict = mec.execute('d=10; print d')
108 169
@@ -118,10 +179,12 b' This example also shows one of the most important things about the IPython engin'
118 179 Non-blocking execution
119 180 ----------------------
120 181
121 In non-blocking mode, ``execute`` submits the command to be executed and then returns a
122 ``PendingResult`` object immediately. The ``PendingResult`` object gives you a way of getting a
123 result at a later time through its ``get_result`` method or ``r`` attribute. This allows you to
124 quickly submit long running commands without blocking your local Python/IPython session::
182 In non-blocking mode, :meth:`execute` submits the command to be executed and
183 then returns a :class:`PendingResult` object immediately. The
184 :class:`PendingResult` object gives you a way of getting a result at a later
185 time through its :meth:`get_result` method or :attr:`r` attribute. This allows
186 you to quickly submit long running commands without blocking your local
187 Python/IPython session::
125 188
126 189 # In blocking mode
127 190 In [6]: mec.execute('import time')
@@ -159,7 +222,10 b' quickly submit long running commands without blocking your local Python/IPython '
159 222 [2] In [3]: time.sleep(10)
160 223 [3] In [3]: time.sleep(10)
161 224
162 Often, it is desirable to wait until a set of ``PendingResult`` objects are done. For this, there is a the method ``barrier``. This method takes a tuple of ``PendingResult`` objects and blocks until all of the associated results are ready::
225 Often, it is desirable to wait until a set of :class:`PendingResult` objects
226 are done. For this, there is a the method :meth:`barrier`. This method takes a
227 tuple of :class:`PendingResult` objects and blocks until all of the associated
228 results are ready::
163 229
164 230 In [72]: mec.block=False
165 231
@@ -182,14 +248,16 b' Often, it is desirable to wait until a set of ``PendingResult`` objects are done'
182 248 The ``block`` and ``targets`` keyword arguments and attributes
183 249 --------------------------------------------------------------
184 250
185 Most commands in the multiengine interface (like ``execute``) accept ``block`` and ``targets``
186 as keyword arguments. As we have seen above, these keyword arguments control the blocking mode
187 and which engines the command is applied to. The ``MultiEngineClient`` class also has ``block``
188 and ``targets`` attributes that control the default behavior when the keyword arguments are not
189 provided. Thus the following logic is used for ``block`` and ``targets``:
251 Most methods in the multiengine interface (like :meth:`execute`) accept
252 ``block`` and ``targets`` as keyword arguments. As we have seen above, these
253 keyword arguments control the blocking mode and which engines the command is
254 applied to. The :class:`MultiEngineClient` class also has :attr:`block` and
255 :attr:`targets` attributes that control the default behavior when the keyword
256 arguments are not provided. Thus the following logic is used for :attr:`block`
257 and :attr:`targets`:
190 258
191 * If no keyword argument is provided, the instance attributes are used.
192 * Keyword argument, if provided override the instance attributes.
259 * If no keyword argument is provided, the instance attributes are used.
260 * Keyword argument, if provided override the instance attributes.
193 261
194 262 The following examples demonstrate how to use the instance attributes::
195 263
@@ -225,14 +293,19 b' The following examples demonstrate how to use the instance attributes::'
225 293 [3] In [6]: b=10; print b
226 294 [3] Out[6]: 10
227 295
228 The ``block`` and ``targets`` instance attributes also determine the behavior of the parallel
229 magic commands...
296 The :attr:`block` and :attr:`targets` instance attributes also determine the
297 behavior of the parallel magic commands.
230 298
231 299
232 300 Parallel magic commands
233 301 -----------------------
234 302
235 We provide a few IPython magic commands (``%px``, ``%autopx`` and ``%result``) that make it more pleasant to execute Python commands on the engines interactively. These are simply shortcuts to ``execute`` and ``get_result``. The ``%px`` magic executes a single Python command on the engines specified by the `magicTargets``targets` attribute of the ``MultiEngineClient`` instance (by default this is 'all')::
303 We provide a few IPython magic commands (``%px``, ``%autopx`` and ``%result``)
304 that make it more pleasant to execute Python commands on the engines
305 interactively. These are simply shortcuts to :meth:`execute` and
306 :meth:`get_result`. The ``%px`` magic executes a single Python command on the
307 engines specified by the :attr:`targets` attribute of the
308 :class:`MultiEngineClient` instance (by default this is ``'all'``)::
236 309
237 310 # Make this MultiEngineClient active for parallel magic commands
238 311 In [23]: mec.activate()
@@ -277,7 +350,9 b' We provide a few IPython magic commands (``%px``, ``%autopx`` and ``%result``) t'
277 350 [3] In [9]: print numpy.linalg.eigvals(a)
278 351 [3] Out[9]: [ 0.83664764 -0.25602658]
279 352
280 The ``%result`` magic gets and prints the stdin/stdout/stderr of the last command executed on each engine. It is simply a shortcut to the ``get_result`` method::
353 The ``%result`` magic gets and prints the stdin/stdout/stderr of the last
354 command executed on each engine. It is simply a shortcut to the
355 :meth:`get_result` method::
281 356
282 357 In [29]: %result
283 358 Out[29]:
@@ -294,7 +369,8 b' The ``%result`` magic gets and prints the stdin/stdout/stderr of the last comman'
294 369 [3] In [9]: print numpy.linalg.eigvals(a)
295 370 [3] Out[9]: [ 0.83664764 -0.25602658]
296 371
297 The ``%autopx`` magic switches to a mode where everything you type is executed on the engines given by the ``targets`` attribute::
372 The ``%autopx`` magic switches to a mode where everything you type is executed
373 on the engines given by the :attr:`targets` attribute::
298 374
299 375 In [30]: mec.block=False
300 376
@@ -335,51 +411,19 b' The ``%autopx`` magic switches to a mode where everything you type is executed o'
335 411 [3] In [12]: print "Average max eigenvalue is: ", sum(max_evals)/len(max_evals)
336 412 [3] Out[12]: Average max eigenvalue is: 10.1158837784
337 413
338 Using the ``with`` statement of Python 2.5
339 ------------------------------------------
340 414
341 Python 2.5 introduced the ``with`` statement. The ``MultiEngineClient`` can be used with the ``with`` statement to execute a block of code on the engines indicated by the ``targets`` attribute::
415 Moving Python objects around
416 ============================
342 417
343 In [3]: with mec:
344 ...: client.remote() # Required so the following code is not run locally
345 ...: a = 10
346 ...: b = 30
347 ...: c = a+b
348 ...:
349 ...:
350
351 In [4]: mec.get_result()
352 Out[4]:
353 <Results List>
354 [0] In [1]: a = 10
355 b = 30
356 c = a+b
357
358 [1] In [1]: a = 10
359 b = 30
360 c = a+b
361
362 [2] In [1]: a = 10
363 b = 30
364 c = a+b
365
366 [3] In [1]: a = 10
367 b = 30
368 c = a+b
369
370 This is basically another way of calling execute, but one with allows you to avoid writing code in strings. When used in this way, the attributes ``targets`` and ``block`` are used to control how the code is executed. For now, if you run code in non-blocking mode you won't have access to the ``PendingResult``.
371
372 Moving Python object around
373 ===========================
374
375 In addition to executing code on engines, you can transfer Python objects to and from your
376 IPython session and the engines. In IPython, these operations are called ``push`` (sending an
377 object to the engines) and ``pull`` (getting an object from the engines).
418 In addition to executing code on engines, you can transfer Python objects to
419 and from your IPython session and the engines. In IPython, these operations
420 are called :meth:`push` (sending an object to the engines) and :meth:`pull`
421 (getting an object from the engines).
378 422
379 423 Basic push and pull
380 424 -------------------
381 425
382 Here are some examples of how you use ``push`` and ``pull``::
426 Here are some examples of how you use :meth:`push` and :meth:`pull`::
383 427
384 428 In [38]: mec.push(dict(a=1.03234,b=3453))
385 429 Out[38]: [None, None, None, None]
@@ -415,7 +459,8 b' Here are some examples of how you use ``push`` and ``pull``::'
415 459 [3] In [13]: print c
416 460 [3] Out[13]: speed
417 461
418 In non-blocking mode ``push`` and ``pull`` also return ``PendingResult`` objects::
462 In non-blocking mode :meth:`push` and :meth:`pull` also return
463 :class:`PendingResult` objects::
419 464
420 465 In [47]: mec.block=False
421 466
@@ -428,7 +473,11 b' In non-blocking mode ``push`` and ``pull`` also return ``PendingResult`` objects'
428 473 Push and pull for functions
429 474 ---------------------------
430 475
431 Functions can also be pushed and pulled using ``push_function`` and ``pull_function``::
476 Functions can also be pushed and pulled using :meth:`push_function` and
477 :meth:`pull_function`::
478
479
480 In [52]: mec.block=True
432 481
433 482 In [53]: def f(x):
434 483 ....: return 2.0*x**4
@@ -466,7 +515,10 b' Functions can also be pushed and pulled using ``push_function`` and ``pull_funct'
466 515 Dictionary interface
467 516 --------------------
468 517
469 As a shorthand to ``push`` and ``pull``, the ``MultiEngineClient`` class implements some of the Python dictionary interface. This make the remote namespaces of the engines appear as a local dictionary. Underneath, this uses ``push`` and ``pull``::
518 As a shorthand to :meth:`push` and :meth:`pull`, the
519 :class:`MultiEngineClient` class implements some of the Python dictionary
520 interface. This make the remote namespaces of the engines appear as a local
521 dictionary. Underneath, this uses :meth:`push` and :meth:`pull`::
470 522
471 523 In [50]: mec.block=True
472 524
@@ -478,11 +530,13 b' As a shorthand to ``push`` and ``pull``, the ``MultiEngineClient`` class impleme'
478 530 Scatter and gather
479 531 ------------------
480 532
481 Sometimes it is useful to partition a sequence and push the partitions to different engines. In
482 MPI language, this is know as scatter/gather and we follow that terminology. However, it is
483 important to remember that in IPython ``scatter`` is from the interactive IPython session to
484 the engines and ``gather`` is from the engines back to the interactive IPython session. For
485 scatter/gather operations between engines, MPI should be used::
533 Sometimes it is useful to partition a sequence and push the partitions to
534 different engines. In MPI language, this is know as scatter/gather and we
535 follow that terminology. However, it is important to remember that in
536 IPython's :class:`MultiEngineClient` class, :meth:`scatter` is from the
537 interactive IPython session to the engines and :meth:`gather` is from the
538 engines back to the interactive IPython session. For scatter/gather operations
539 between engines, MPI should be used::
486 540
487 541 In [58]: mec.scatter('a',range(16))
488 542 Out[58]: [None, None, None, None]
@@ -510,24 +564,12 b' scatter/gather operations between engines, MPI should be used::'
510 564 Other things to look at
511 565 =======================
512 566
513 Parallel map
514 ------------
515
516 Python's builtin ``map`` functions allows a function to be applied to a sequence element-by-element. This type of code is typically trivial to parallelize. In fact, the MultiEngine interface in IPython already has a parallel version of ``map`` that works just like its serial counterpart::
517
518 In [63]: serial_result = map(lambda x:x**10, range(32))
519
520 In [64]: parallel_result = mec.map(lambda x:x**10, range(32))
521
522 In [65]: serial_result==parallel_result
523 Out[65]: True
524
525 As you would expect, the parallel version of ``map`` is also influenced by the ``block`` and ``targets`` keyword arguments and attributes.
526
527 567 How to do parallel list comprehensions
528 568 --------------------------------------
529 569
530 In many cases list comprehensions are nicer than using the map function. While we don't have fully parallel list comprehensions, it is simple to get the basic effect using ``scatter`` and ``gather``::
570 In many cases list comprehensions are nicer than using the map function. While
571 we don't have fully parallel list comprehensions, it is simple to get the
572 basic effect using :meth:`scatter` and :meth:`gather`::
531 573
532 574 In [66]: mec.scatter('x',range(64))
533 575 Out[66]: [None, None, None, None]
@@ -547,10 +589,16 b' In many cases list comprehensions are nicer than using the map function. While '
547 589 In [69]: print y
548 590 [0, 1, 1024, 59049, 1048576, 9765625, 60466176, 282475249, 1073741824,...]
549 591
550 Parallel Exceptions
592 Parallel exceptions
551 593 -------------------
552 594
553 In the MultiEngine interface, parallel commands can raise Python exceptions, just like serial commands. But, it is a little subtle, because a single parallel command can actually raise multiple exceptions (one for each engine the command was run on). To express this idea, the MultiEngine interface has a ``CompositeError`` exception class that will be raised in most cases. The ``CompositeError`` class is a special type of exception that wraps one or more other types of exceptions. Here is how it works::
595 In the multiengine interface, parallel commands can raise Python exceptions,
596 just like serial commands. But, it is a little subtle, because a single
597 parallel command can actually raise multiple exceptions (one for each engine
598 the command was run on). To express this idea, the MultiEngine interface has a
599 :exc:`CompositeError` exception class that will be raised in most cases. The
600 :exc:`CompositeError` class is a special type of exception that wraps one or
601 more other types of exceptions. Here is how it works::
554 602
555 603 In [76]: mec.block=True
556 604
@@ -580,7 +628,7 b' In the MultiEngine interface, parallel commands can raise Python exceptions, jus'
580 628 [2:execute]: ZeroDivisionError: integer division or modulo by zero
581 629 [3:execute]: ZeroDivisionError: integer division or modulo by zero
582 630
583 Notice how the error message printed when ``CompositeError`` is raised has information about the individual exceptions that were raised on each engine. If you want, you can even raise one of these original exceptions::
631 Notice how the error message printed when :exc:`CompositeError` is raised has information about the individual exceptions that were raised on each engine. If you want, you can even raise one of these original exceptions::
584 632
585 633 In [80]: try:
586 634 ....: mec.execute('1/0')
@@ -602,7 +650,9 b' Notice how the error message printed when ``CompositeError`` is raised has infor'
602 650
603 651 ZeroDivisionError: integer division or modulo by zero
604 652
605 If you are working in IPython, you can simple type ``%debug`` after one of these ``CompositeError`` is raised, and inspect the exception instance::
653 If you are working in IPython, you can simple type ``%debug`` after one of
654 these :exc:`CompositeError` exceptions is raised, and inspect the exception
655 instance::
606 656
607 657 In [81]: mec.execute('1/0')
608 658 ---------------------------------------------------------------------------
@@ -679,6 +729,11 b' If you are working in IPython, you can simple type ``%debug`` after one of these'
679 729
680 730 ZeroDivisionError: integer division or modulo by zero
681 731
732 .. note::
733
734 The above example appears to be broken right now because of a change in
735 how we are using Twisted.
736
682 737 All of this same error handling magic even works in non-blocking mode::
683 738
684 739 In [83]: mec.block=False
@@ -1,240 +1,93 b''
1 1 .. _paralleltask:
2 2
3 =================================
4 The IPython Task interface
5 =================================
3 ==========================
4 The IPython task interface
5 ==========================
6 6
7 7 .. contents::
8 8
9 The ``Task`` interface to the controller presents the engines as a fault tolerant, dynamic load-balanced system or workers. Unlike the ``MultiEngine`` interface, in the ``Task`` interface, the user have no direct access to individual engines. In some ways, this interface is simpler, but in other ways it is more powerful. Best of all the user can use both of these interfaces at the same time to take advantage or both of their strengths. When the user can break up the user's work into segments that do not depend on previous execution, the ``Task`` interface is ideal. But it also has more power and flexibility, allowing the user to guide the distribution of jobs, without having to assign Tasks to engines explicitly.
9 The task interface to the controller presents the engines as a fault tolerant, dynamic load-balanced system or workers. Unlike the multiengine interface, in the task interface, the user have no direct access to individual engines. In some ways, this interface is simpler, but in other ways it is more powerful.
10
11 Best of all the user can use both of these interfaces running at the same time to take advantage or both of their strengths. When the user can break up the user's work into segments that do not depend on previous execution, the task interface is ideal. But it also has more power and flexibility, allowing the user to guide the distribution of jobs, without having to assign tasks to engines explicitly.
10 12
11 13 Starting the IPython controller and engines
12 14 ===========================================
13 15
14 To follow along with this tutorial, the user will need to start the IPython
15 controller and four IPython engines. The simplest way of doing this is to
16 use the ``ipcluster`` command::
16 To follow along with this tutorial, you will need to start the IPython
17 controller and four IPython engines. The simplest way of doing this is to use
18 the :command:`ipcluster` command::
17 19
18 20 $ ipcluster -n 4
19 21
20 For more detailed information about starting the controller and engines, see our :ref:`introduction <ip1par>` to using IPython for parallel computing.
22 For more detailed information about starting the controller and engines, see
23 our :ref:`introduction <ip1par>` to using IPython for parallel computing.
24
25 Creating a ``TaskClient`` instance
26 =========================================
27
28 The first step is to import the IPython :mod:`IPython.kernel.client` module
29 and then create a :class:`TaskClient` instance::
30
31 In [1]: from IPython.kernel import client
32
33 In [2]: tc = client.TaskClient()
34
35 This form assumes that the :file:`ipcontroller-tc.furl` is in the
36 :file:`~./ipython/security` directory on the client's host. If not, the
37 location of the ``.furl`` file must be given as an argument to the
38 constructor::
39
40 In[2]: mec = client.TaskClient('/path/to/my/ipcontroller-tc.furl')
41
42 Quick and easy parallelism
43 ==========================
44
45 In many cases, you simply want to apply a Python function to a sequence of objects, but *in parallel*. Like the multiengine interface, the task interface provides two simple ways of accomplishing this: a parallel version of :func:`map` and ``@parallel`` function decorator. However, the verions in the task interface have one important difference: they are dynamically load balanced. Thus, if the execution time per item varies significantly, you should use the versions in the task interface.
46
47 Parallel map
48 ------------
49
50 The parallel :meth:`map` in the task interface is similar to that in the multiengine interface::
51
52 In [63]: serial_result = map(lambda x:x**10, range(32))
53
54 In [64]: parallel_result = tc.map(lambda x:x**10, range(32))
55
56 In [65]: serial_result==parallel_result
57 Out[65]: True
58
59 Parallel function decorator
60 ---------------------------
61
62 Parallel functions are just like normal function, but they can be called on sequences and *in parallel*. The multiengine interface provides a decorator that turns any Python function into a parallel function::
21 63
22 The magic here is that this single controller and set of engines is running both the MultiEngine and ``Task`` interfaces simultaneously.
64 In [10]: @tc.parallel()
65 ....: def f(x):
66 ....: return 10.0*x**4
67 ....:
23 68
24 QuickStart Task Farming
25 =======================
69 In [11]: f(range(32)) # this is done in parallel
70 Out[11]:
71 [0.0,10.0,160.0,...]
26 72
27 First, a quick example of how to start running the most basic Tasks.
28 The first step is to import the IPython ``client`` module and then create a ``TaskClient`` instance::
29
30 In [1]: from IPython.kernel import client
31
32 In [2]: tc = client.TaskClient()
73 More details
74 ============
33 75
34 Then the user wrap the commands the user want to run in Tasks::
76 The :class:`TaskClient` has many more powerful features that allow quite a bit of flexibility in how tasks are defined and run. The next places to look are in the following classes:
35 77
36 In [3]: tasklist = []
37 In [4]: for n in range(1000):
38 ... tasklist.append(client.Task("a = %i"%n, pull="a"))
78 * :class:`IPython.kernel.client.TaskClient`
79 * :class:`IPython.kernel.client.StringTask`
80 * :class:`IPython.kernel.client.MapTask`
39 81
40 The first argument of the ``Task`` constructor is a string, the command to be executed. The most important optional keyword argument is ``pull``, which can be a string or list of strings, and it specifies the variable names to be saved as results of the ``Task``.
82 The following is an overview of how to use these classes together:
41 83
42 Next, the user need to submit the Tasks to the ``TaskController`` with the ``TaskClient``::
84 1. Create a :class:`TaskClient`.
85 2. Create one or more instances of :class:`StringTask` or :class:`MapTask`
86 to define your tasks.
87 3. Submit your tasks to using the :meth:`run` method of your
88 :class:`TaskClient` instance.
89 4. Use :meth:`TaskClient.get_task_result` to get the results of the
90 tasks.
43 91
44 In [5]: taskids = [ tc.run(t) for t in tasklist ]
92 We are in the process of developing more detailed information about the task interface. For now, the docstrings of the :class:`TaskClient`, :class:`StringTask` and :class:`MapTask` classes should be consulted.
45 93
46 This will give the user a list of the TaskIDs used by the controller to keep track of the Tasks and their results. Now at some point the user are going to want to get those results back. The ``barrier`` method allows the user to wait for the Tasks to finish running::
47
48 In [6]: tc.barrier(taskids)
49
50 This command will block until all the Tasks in ``taskids`` have finished. Now, the user probably want to look at the user's results::
51
52 In [7]: task_results = [ tc.get_task_result(taskid) for taskid in taskids ]
53
54 Now the user have a list of ``TaskResult`` objects, which have the actual result as a dictionary, but also keep track of some useful metadata about the ``Task``::
55
56 In [8]: tr = ``Task``_results[73]
57
58 In [9]: tr
59 Out[9]: ``TaskResult``[ID:73]:{'a':73}
60
61 In [10]: tr.engineid
62 Out[10]: 1
63
64 In [11]: tr.submitted, tr.completed, tr.duration
65 Out[11]: ("2008/03/08 03:41:42", "2008/03/08 03:41:44", 2.12345)
66
67 The actual results are stored in a dictionary, ``tr.results``, and a namespace object ``tr.ns`` which accesses the result keys by attribute::
68
69 In [12]: tr.results['a']
70 Out[12]: 73
71
72 In [13]: tr.ns.a
73 Out[13]: 73
74
75 That should cover the basics of running simple Tasks. There are several more powerful things the user can do with Tasks covered later. The most useful probably being using a ``MutiEngineClient`` interface to initialize all the engines with the import dependencies necessary to run the user's Tasks.
76
77 There are many options for running and managing Tasks. The best way to learn further about the ``Task`` interface is to study the examples in ``docs/examples``. If the user do so and learn a lots about this interface, we encourage the user to expand this documentation about the ``Task`` system.
78
79 Overview of the Task System
80 ===========================
81
82 The user's view of the ``Task`` system has three basic objects: The ``TaskClient``, the ``Task``, and the ``TaskResult``. The names of these three objects well indicate their role.
83
84 The ``TaskClient`` is the user's ``Task`` farming connection to the IPython cluster. Unlike the ``MultiEngineClient``, the ``TaskControler`` handles all the scheduling and distribution of work, so the ``TaskClient`` has no notion of engines, it just submits Tasks and requests their results. The Tasks are described as ``Task`` objects, and their results are wrapped in ``TaskResult`` objects. Thus, there are very few necessary methods for the user to manage.
85
86 Inside the task system is a Scheduler object, which assigns tasks to workers. The default scheduler is a simple FIFO queue. Subclassing the Scheduler should be easy, just implementing your own priority system.
87
88 The TaskClient
89 ==============
90
91 The ``TaskClient`` is the object the user use to connect to the ``Controller`` that is managing the user's Tasks. It is the analog of the ``MultiEngineClient`` for the standard IPython multiplexing interface. As with all client interfaces, the first step is to import the IPython Client Module::
92
93 In [1]: from IPython.kernel import client
94
95 Just as with the ``MultiEngineClient``, the user create the ``TaskClient`` with a tuple, containing the ip-address and port of the ``Controller``. the ``client`` module conveniently has the default address of the ``Task`` interface of the controller. Creating a default ``TaskClient`` object would be done with this::
96
97 In [2]: tc = client.TaskClient(client.default_task_address)
98
99 or, if the user want to specify a non default location of the ``Controller``, the user can specify explicitly::
100
101 In [3]: tc = client.TaskClient(("192.168.1.1", 10113))
102
103 As discussed earlier, the ``TaskClient`` only has a few basic methods.
104
105 * ``tc.run(task)``
106 ``run`` is the method by which the user submits Tasks. It takes exactly one argument, a ``Task`` object. All the advanced control of ``Task`` behavior is handled by properties of the ``Task`` object, rather than the submission command, so they will be discussed later in the `Task`_ section. ``run`` returns an integer, the ``Task``ID by which the ``Task`` and its results can be tracked and retrieved::
107
108 In [4]: ``Task``ID = tc.run(``Task``)
109
110 * ``tc.get_task_result(taskid, block=``False``)``
111 ``get_task_result`` is the method by which results are retrieved. It takes a single integer argument, the ``Task``ID`` of the result the user wish to retrieve. ``get_task_result`` also takes a keyword argument ``block``. ``block`` specifies whether the user actually want to wait for the result. If ``block`` is false, as it is by default, ``get_task_result`` will return immediately. If the ``Task`` has completed, it will return the ``TaskResult`` object for that ``Task``. But if the ``Task`` has not completed, it will return ``None``. If the user specify ``block=``True``, then ``get_task_result`` will wait for the ``Task`` to complete, and always return the ``TaskResult`` for the requested ``Task``.
112 * ``tc.barrier(taskid(s))``
113 ``barrier`` is a synchronization method. It takes exactly one argument, a ``Task``ID or list of taskIDs. ``barrier`` will block until all the specified Tasks have completed. In practice, a barrier is often called between the ``Task`` submission section of the code and the result gathering section::
114
115 In [5]: taskIDs = [ tc.run(``Task``) for ``Task`` in myTasks ]
116
117 In [6]: tc.get_task_result(taskIDs[-1]) is None
118 Out[6]: ``True``
119
120 In [7]: tc.barrier(``Task``ID)
121
122 In [8]: results = [ tc.get_task_result(tid) for tid in taskIDs ]
123
124 * ``tc.queue_status(verbose=``False``)``
125 ``queue_status`` is a method for querying the state of the ``TaskControler``. ``queue_status`` returns a dict of the form::
126
127 {'scheduled': Tasks that have been submitted but yet run
128 'pending' : Tasks that are currently running
129 'succeeded': Tasks that have completed successfully
130 'failed' : Tasks that have finished with a failure
131 }
132
133 if @verbose is not specified (or is ``False``), then the values of the dict are integers - the number of Tasks in each state. if @verbose is ``True``, then each element in the dict is a list of the taskIDs in that state::
134
135 In [8]: tc.queue_status()
136 Out[8]: {'scheduled': 4,
137 'pending' : 2,
138 'succeeded': 5,
139 'failed' : 1
140 }
141
142 In [9]: tc.queue_status(verbose=True)
143 Out[9]: {'scheduled': [8,9,10,11],
144 'pending' : [6,7],
145 'succeeded': [0,1,2,4,5],
146 'failed' : [3]
147 }
148
149 * ``tc.abort(taskid)``
150 ``abort`` allows the user to abort Tasks that have already been submitted. ``abort`` will always return immediately. If the ``Task`` has completed, ``abort`` will raise an ``IndexError ``Task`` Already Completed``. An obvious case for ``abort`` would be where the user submits a long-running ``Task`` with a number of retries (see ``Task``_ section for how to specify retries) in an interactive session, but realizes there has been a typo. The user can then abort the ``Task``, preventing certain failures from cluttering up the queue. It can also be used for parallel search-type problems, where only one ``Task`` will give the solution, so once the user find the solution, the user would want to abort all remaining Tasks to prevent wasted work.
151 * ``tc.spin()``
152 ``spin`` simply triggers the scheduler in the ``TaskControler``. Under most normal circumstances, this will do nothing. The primary known usage case involves the ``Task`` dependency (see `Dependencies`_). The dependency is a function of an Engine's ``properties``, but changing the ``properties`` via the ``MutliEngineClient`` does not trigger a reschedule event. The main example case for this requires the following event sequence:
153 * ``engine`` is available, ``Task`` is submitted, but ``engine`` does not have ``Task``'s dependencies.
154 * ``engine`` gets necessary dependencies while no new Tasks are submitted or completed.
155 * now ``engine`` can run ``Task``, but a ``Task`` event is required for the ``TaskControler`` to try scheduling ``Task`` again.
156
157 ``spin`` is just an empty ping method to ensure that the Controller has scheduled all available Tasks, and should not be needed under most normal circumstances.
158
159 That covers the ``TaskClient``, a simple interface to the cluster. With this, the user can submit jobs (and abort if necessary), request their results, synchronize on arbitrary subsets of jobs.
160
161 .. _task: The Task Object
162
163 The Task Object
164 ===============
165
166 The ``Task`` is the basic object for describing a job. It can be used in a very simple manner, where the user just specifies a command string to be executed as the ``Task``. The usage of this first argument is exactly the same as the ``execute`` method of the ``MultiEngine`` (in fact, ``execute`` is called to run the code)::
167
168 In [1]: t = client.Task("a = str(id)")
169
170 This ``Task`` would run, and store the string representation of the ``id`` element in ``a`` in each worker's namespace, but it is fairly useless because the user does not know anything about the state of the ``worker`` on which it ran at the time of retrieving results. It is important that each ``Task`` not expect the state of the ``worker`` to persist after the ``Task`` is completed.
171 There are many different situations for using ``Task`` Farming, and the ``Task`` object has many attributes for use in customizing the ``Task`` behavior. All of a ``Task``'s attributes may be specified in the constructor, through keyword arguments, or after ``Task`` construction through attribute assignment.
172
173 Data Attributes
174 ***************
175 It is likely that the user may want to move data around before or after executing the ``Task``. We provide methods of sending data to initialize the worker's namespace, and specifying what data to bring back as the ``Task``'s results.
176
177 * pull = []
178 The obvious case is as above, where ``t`` would execute and store the result of ``myfunc`` in ``a``, it is likely that the user would want to bring ``a`` back to their namespace. This is done through the ``pull`` attribute. ``pull`` can be a string or list of strings, and it specifies the names of variables to be retrieved. The ``TaskResult`` object retrieved by ``get_task_result`` will have a dictionary of keys and values, and the ``Task``'s ``pull`` attribute determines what goes into it::
179
180 In [2]: t = client.Task("a = str(id)", pull = "a")
181
182 In [3]: t = client.Task("a = str(id)", pull = ["a", "id"])
183
184 * push = {}
185 A user might also want to initialize some data into the namespace before the code part of the ``Task`` is run. Enter ``push``. ``push`` is a dictionary of key/value pairs to be loaded from the user's namespace into the worker's immediately before execution::
186
187 In [4]: t = client.Task("a = f(submitted)", push=dict(submitted=time.time()), pull="a")
188
189 push and pull result directly in calling an ``engine``'s ``push`` and ``pull`` methods before and after ``Task`` execution respectively, and thus their api is the same.
190
191 Namespace Cleaning
192 ******************
193 When a user is running a large number of Tasks, it is likely that the namespace of the worker's could become cluttered. Some Tasks might be sensitive to clutter, while others might be known to cause namespace pollution. For these reasons, Tasks have two boolean attributes for cleaning up the namespace.
194
195 * ``clear_after``
196 if clear_after is specified ``True``, the worker on which the ``Task`` was run will be reset (via ``engine.reset``) upon completion of the ``Task``. This can be useful for both Tasks that produce clutter or Tasks whose intermediate data one might wish to be kept private::
197
198 In [5]: t = client.Task("a = range(1e10)", pull = "a",clear_after=True)
199
200
201 * ``clear_before``
202 as one might guess, clear_before is identical to ``clear_after``, but it takes place before the ``Task`` is run. This ensures that the ``Task`` runs on a fresh worker::
203
204 In [6]: t = client.Task("a = globals()", pull = "a",clear_before=True)
205
206 Of course, a user can both at the same time, ensuring that all workers are clear except when they are currently running a job. Both of these default to ``False``.
207
208 Fault Tolerance
209 ***************
210 It is possible that Tasks might fail, and there are a variety of reasons this could happen. One might be that the worker it was running on disconnected, and there was nothing wrong with the ``Task`` itself. With the fault tolerance attributes of the ``Task``, the user can specify how many times to resubmit the ``Task``, and what to do if it never succeeds.
211
212 * ``retries``
213 ``retries`` is an integer, specifying the number of times a ``Task`` is to be retried. It defaults to zero. It is often a good idea for this number to be 1 or 2, to protect the ``Task`` from disconnecting engines, but not a large number. If a ``Task`` is failing 100 times, there is probably something wrong with the ``Task``. The canonical bad example:
214
215 In [7]: t = client.Task("os.kill(os.getpid(), 9)", retries=99)
216
217 This would actually take down 100 workers.
218
219 * ``recovery_task``
220 ``recovery_task`` is another ``Task`` object, to be run in the event of the original ``Task`` still failing after running out of retries. Since ``recovery_task`` is another ``Task`` object, it can have its own ``recovery_task``. The chain of Tasks is limitless, except loops are not allowed (that would be bad!).
221
222 Dependencies
223 ************
224 Dependencies are the most powerful part of the ``Task`` farming system, because it allows the user to do some classification of the workers, and guide the ``Task`` distribution without meddling with the controller directly. It makes use of two objects - the ``Task``'s ``depend`` attribute, and the engine's ``properties``. See the `MultiEngine`_ reference for how to use engine properties. The engine properties api exists for extending IPython, allowing conditional execution and new controllers that make decisions based on properties of its engines. Currently the ``Task`` dependency is the only internal use of the properties api.
225
226 .. _MultiEngine: ./parallel_multiengine
227
228 The ``depend`` attribute of a ``Task`` must be a function of exactly one argument, the worker's properties dictionary, and it should return ``True`` if the ``Task`` should be allowed to run on the worker and ``False`` if not. The usage in the controller is fault tolerant, so exceptions raised by ``Task.depend`` will be ignored and functionally equivalent to always returning ``False``. Tasks`` with invalid ``depend`` functions will never be assigned to a worker::
229
230 In [8]: def dep(properties):
231 ... return properties["RAM"] > 2**32 # have at least 4GB
232 In [9]: t = client.Task("a = bigfunc()", depend=dep)
233
234 It is important to note that assignment of values to the properties dict is done entirely by the user, either locally (in the engine) using the EngineAPI, or remotely, through the ``MultiEngineClient``'s get/set_properties methods.
235
236
237
238
239
240
@@ -10,17 +10,15 b' echo'
10 10 echo "Releasing IPython version $version"
11 11 echo "=================================="
12 12
13 echo "Marking ChangeLog with release information and making NEWS file..."
14
15 # Clean up build/dist directories
16 rm -rf $ipdir/build/*
17 rm -rf $ipdir/dist/*
18
19 13 # Perform local backup
20 14 cd $ipdir/tools
21 15 ./make_tarball.py
22 16 mv ipython-*.tgz $ipbackupdir
23 17
18 # Clean up build/dist directories
19 rm -rf $ipdir/build/*
20 rm -rf $ipdir/dist/*
21
24 22 # Build source and binary distros
25 23 cd $ipdir
26 24 ./setup.py sdist --formats=gztar
@@ -28,8 +26,8 b' cd $ipdir'
28 26 # Build version-specific RPMs, where we must use the --python option to ensure
29 27 # that the resulting RPM is really built with the requested python version (so
30 28 # things go to lib/python2.X/...)
31 python2.4 ./setup.py bdist_rpm --binary-only --release=py24 --python=/usr/bin/python2.4
32 python2.5 ./setup.py bdist_rpm --binary-only --release=py25 --python=/usr/bin/python2.5
29 #python2.4 ./setup.py bdist_rpm --binary-only --release=py24 --python=/usr/bin/python2.4
30 #python2.5 ./setup.py bdist_rpm --binary-only --release=py25 --python=/usr/bin/python2.5
33 31
34 32 # Build eggs
35 33 python2.4 ./setup_bdist_egg.py
@@ -15,8 +15,8 b' cd $ipdir'
15 15 ./setup.py sdist --formats=gztar
16 16
17 17 # Build rpms
18 #python2.4 ./setup.py bdist_rpm --binary-only --release=py24 --python=/usr/bin/python2.4
19 #python2.5 ./setup.py bdist_rpm --binary-only --release=py25 --python=/usr/bin/python2.5
18 python2.4 ./setup.py bdist_rpm --binary-only --release=py24 --python=/usr/bin/python2.4
19 python2.5 ./setup.py bdist_rpm --binary-only --release=py25 --python=/usr/bin/python2.5
20 20
21 21 # Build eggs
22 22 python2.4 ./setup_bdist_egg.py
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now