Show More
@@ -0,0 +1,4 b'' | |||||
|
1 | # IPython-specific files and pattersn that bzr should ignore | |||
|
2 | docs/dist | |||
|
3 | docs/build/* | |||
|
4 | docs/source/api/generated |
@@ -0,0 +1,132 b'' | |||||
|
1 | """ Use pretty.py for configurable pretty-printing. | |||
|
2 | ||||
|
3 | Register pretty-printers for types using ipy_pretty.for_type() or | |||
|
4 | ipy_pretty.for_type_by_name(). For example, to use the example pretty-printer | |||
|
5 | for numpy dtype objects, add the following to your ipy_user_conf.py:: | |||
|
6 | ||||
|
7 | from IPython.Extensions import ipy_pretty | |||
|
8 | ||||
|
9 | ipy_pretty.activate() | |||
|
10 | ||||
|
11 | # If you want to have numpy always imported anyways: | |||
|
12 | import numpy | |||
|
13 | ipy_pretty.for_type(numpy.dtype, ipy_pretty.dtype_pprinter) | |||
|
14 | ||||
|
15 | # If you don't want to have numpy imported until it needs to be: | |||
|
16 | ipy_pretty.for_type_by_name('numpy', 'dtype', ipy_pretty.dtype_pprinter) | |||
|
17 | """ | |||
|
18 | ||||
|
19 | import IPython.ipapi | |||
|
20 | from IPython.genutils import Term | |||
|
21 | ||||
|
22 | from IPython.external import pretty | |||
|
23 | ||||
|
24 | ip = IPython.ipapi.get() | |||
|
25 | ||||
|
26 | ||||
|
27 | #### Implementation ############################################################ | |||
|
28 | ||||
|
29 | def pretty_result_display(self, arg): | |||
|
30 | """ Uber-pretty-printing display hook. | |||
|
31 | ||||
|
32 | Called for displaying the result to the user. | |||
|
33 | """ | |||
|
34 | ||||
|
35 | if ip.options.pprint: | |||
|
36 | verbose = getattr(ip.options, 'pretty_verbose', False) | |||
|
37 | out = pretty.pretty(arg, verbose=verbose) | |||
|
38 | if '\n' in out: | |||
|
39 | # So that multi-line strings line up with the left column of | |||
|
40 | # the screen, instead of having the output prompt mess up | |||
|
41 | # their first line. | |||
|
42 | Term.cout.write('\n') | |||
|
43 | print >>Term.cout, out | |||
|
44 | else: | |||
|
45 | raise TryNext | |||
|
46 | ||||
|
47 | ||||
|
48 | #### API ####################################################################### | |||
|
49 | ||||
|
50 | # Expose the for_type and for_type_by_name functions for easier use. | |||
|
51 | for_type = pretty.for_type | |||
|
52 | for_type_by_name = pretty.for_type_by_name | |||
|
53 | ||||
|
54 | ||||
|
55 | # FIXME: write deactivate(). We need a way to remove a hook. | |||
|
56 | def activate(): | |||
|
57 | """ Activate this extension. | |||
|
58 | """ | |||
|
59 | ip.set_hook('result_display', pretty_result_display, priority=99) | |||
|
60 | ||||
|
61 | ||||
|
62 | #### Example pretty-printers ################################################### | |||
|
63 | ||||
|
64 | def dtype_pprinter(obj, p, cycle): | |||
|
65 | """ A pretty-printer for numpy dtype objects. | |||
|
66 | """ | |||
|
67 | if cycle: | |||
|
68 | return p.text('dtype(...)') | |||
|
69 | if obj.fields is None: | |||
|
70 | p.text(repr(obj)) | |||
|
71 | else: | |||
|
72 | p.begin_group(7, 'dtype([') | |||
|
73 | for i, field in enumerate(obj.descr): | |||
|
74 | if i > 0: | |||
|
75 | p.text(',') | |||
|
76 | p.breakable() | |||
|
77 | p.pretty(field) | |||
|
78 | p.end_group(7, '])') | |||
|
79 | ||||
|
80 | ||||
|
81 | #### Tests ##################################################################### | |||
|
82 | ||||
|
83 | def test_pretty(): | |||
|
84 | """ | |||
|
85 | In [1]: from IPython.Extensions import ipy_pretty | |||
|
86 | ||||
|
87 | In [2]: ipy_pretty.activate() | |||
|
88 | ||||
|
89 | In [3]: class A(object): | |||
|
90 | ...: def __repr__(self): | |||
|
91 | ...: return 'A()' | |||
|
92 | ...: | |||
|
93 | ...: | |||
|
94 | ||||
|
95 | In [4]: a = A() | |||
|
96 | ||||
|
97 | In [5]: a | |||
|
98 | Out[5]: A() | |||
|
99 | ||||
|
100 | In [6]: def a_pretty_printer(obj, p, cycle): | |||
|
101 | ...: p.text('<A>') | |||
|
102 | ...: | |||
|
103 | ...: | |||
|
104 | ||||
|
105 | In [7]: ipy_pretty.for_type(A, a_pretty_printer) | |||
|
106 | ||||
|
107 | In [8]: a | |||
|
108 | Out[8]: <A> | |||
|
109 | ||||
|
110 | In [9]: class B(object): | |||
|
111 | ...: def __repr__(self): | |||
|
112 | ...: return 'B()' | |||
|
113 | ...: | |||
|
114 | ...: | |||
|
115 | ||||
|
116 | In [10]: B.__module__, B.__name__ | |||
|
117 | Out[10]: ('__main__', 'B') | |||
|
118 | ||||
|
119 | In [11]: def b_pretty_printer(obj, p, cycle): | |||
|
120 | ....: p.text('<B>') | |||
|
121 | ....: | |||
|
122 | ....: | |||
|
123 | ||||
|
124 | In [12]: ipy_pretty.for_type_by_name('__main__', 'B', b_pretty_printer) | |||
|
125 | ||||
|
126 | In [13]: b = B() | |||
|
127 | ||||
|
128 | In [14]: b | |||
|
129 | Out[14]: <B> | |||
|
130 | """ | |||
|
131 | assert False, "This should only be doctested, not run." | |||
|
132 |
This diff has been collapsed as it changes many lines, (705 lines changed) Show them Hide them | |||||
@@ -0,0 +1,705 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | """ | |||
|
3 | pretty | |||
|
4 | ~~ | |||
|
5 | ||||
|
6 | Python advanced pretty printer. This pretty printer is intended to | |||
|
7 | replace the old `pprint` python module which does not allow developers | |||
|
8 | to provide their own pretty print callbacks. | |||
|
9 | ||||
|
10 | This module is based on ruby's `prettyprint.rb` library by `Tanaka Akira`. | |||
|
11 | ||||
|
12 | ||||
|
13 | Example Usage | |||
|
14 | ============= | |||
|
15 | ||||
|
16 | To directly print the representation of an object use `pprint`:: | |||
|
17 | ||||
|
18 | from pretty import pprint | |||
|
19 | pprint(complex_object) | |||
|
20 | ||||
|
21 | To get a string of the output use `pretty`:: | |||
|
22 | ||||
|
23 | from pretty import pretty | |||
|
24 | string = pretty(complex_object) | |||
|
25 | ||||
|
26 | ||||
|
27 | Extending | |||
|
28 | ========= | |||
|
29 | ||||
|
30 | The pretty library allows developers to add pretty printing rules for their | |||
|
31 | own objects. This process is straightforward. All you have to do is to | |||
|
32 | add a `__pretty__` method to your object and call the methods on the | |||
|
33 | pretty printer passed:: | |||
|
34 | ||||
|
35 | class MyObject(object): | |||
|
36 | ||||
|
37 | def __pretty__(self, p, cycle): | |||
|
38 | ... | |||
|
39 | ||||
|
40 | Depending on the python version you want to support you have two | |||
|
41 | possibilities. The following list shows the python 2.5 version and the | |||
|
42 | compatibility one. | |||
|
43 | ||||
|
44 | ||||
|
45 | Here the example implementation of a `__pretty__` method for a list | |||
|
46 | subclass for python 2.5 and higher (python 2.5 requires the with statement | |||
|
47 | __future__ import):: | |||
|
48 | ||||
|
49 | class MyList(list): | |||
|
50 | ||||
|
51 | def __pretty__(self, p, cycle): | |||
|
52 | if cycle: | |||
|
53 | p.text('MyList(...)') | |||
|
54 | else: | |||
|
55 | with p.group(8, 'MyList([', '])'): | |||
|
56 | for idx, item in enumerate(self): | |||
|
57 | if idx: | |||
|
58 | p.text(',') | |||
|
59 | p.breakable() | |||
|
60 | p.pretty(item) | |||
|
61 | ||||
|
62 | The `cycle` parameter is `True` if pretty detected a cycle. You *have* to | |||
|
63 | react to that or the result is an infinite loop. `p.text()` just adds | |||
|
64 | non breaking text to the output, `p.breakable()` either adds a whitespace | |||
|
65 | or breaks here. If you pass it an argument it's used instead of the | |||
|
66 | default space. `p.pretty` prettyprints another object using the pretty print | |||
|
67 | method. | |||
|
68 | ||||
|
69 | The first parameter to the `group` function specifies the extra indentation | |||
|
70 | of the next line. In this example the next item will either be not | |||
|
71 | breaked (if the items are short enough) or aligned with the right edge of | |||
|
72 | the opening bracked of `MyList`. | |||
|
73 | ||||
|
74 | If you want to support python 2.4 and lower you can use this code:: | |||
|
75 | ||||
|
76 | class MyList(list): | |||
|
77 | ||||
|
78 | def __pretty__(self, p, cycle): | |||
|
79 | if cycle: | |||
|
80 | p.text('MyList(...)') | |||
|
81 | else: | |||
|
82 | p.begin_group(8, 'MyList([') | |||
|
83 | for idx, item in enumerate(self): | |||
|
84 | if idx: | |||
|
85 | p.text(',') | |||
|
86 | p.breakable() | |||
|
87 | p.pretty(item) | |||
|
88 | p.end_group(8, '])') | |||
|
89 | ||||
|
90 | If you just want to indent something you can use the group function | |||
|
91 | without open / close parameters. Under python 2.5 you can also use this | |||
|
92 | code:: | |||
|
93 | ||||
|
94 | with p.indent(2): | |||
|
95 | ... | |||
|
96 | ||||
|
97 | Or under python2.4 you might want to modify ``p.indentation`` by hand but | |||
|
98 | this is rather ugly. | |||
|
99 | ||||
|
100 | :copyright: 2007 by Armin Ronacher. | |||
|
101 | Portions (c) 2009 by Robert Kern. | |||
|
102 | :license: BSD License. | |||
|
103 | """ | |||
|
104 | import __future__ | |||
|
105 | import sys | |||
|
106 | import types | |||
|
107 | import re | |||
|
108 | import datetime | |||
|
109 | from StringIO import StringIO | |||
|
110 | from collections import deque | |||
|
111 | ||||
|
112 | ||||
|
113 | __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter', | |||
|
114 | 'for_type', 'for_type_by_name'] | |||
|
115 | ||||
|
116 | ||||
|
117 | _re_pattern_type = type(re.compile('')) | |||
|
118 | ||||
|
119 | ||||
|
120 | def pretty(obj, verbose=False, max_width=79, newline='\n'): | |||
|
121 | """ | |||
|
122 | Pretty print the object's representation. | |||
|
123 | """ | |||
|
124 | stream = StringIO() | |||
|
125 | printer = RepresentationPrinter(stream, verbose, max_width, newline) | |||
|
126 | printer.pretty(obj) | |||
|
127 | printer.flush() | |||
|
128 | return stream.getvalue() | |||
|
129 | ||||
|
130 | ||||
|
131 | def pprint(obj, verbose=False, max_width=79, newline='\n'): | |||
|
132 | """ | |||
|
133 | Like `pretty` but print to stdout. | |||
|
134 | """ | |||
|
135 | printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline) | |||
|
136 | printer.pretty(obj) | |||
|
137 | printer.flush() | |||
|
138 | sys.stdout.write(newline) | |||
|
139 | sys.stdout.flush() | |||
|
140 | ||||
|
141 | ||||
|
142 | # add python2.5 context managers if we have the with statement feature | |||
|
143 | if hasattr(__future__, 'with_statement'): exec ''' | |||
|
144 | from __future__ import with_statement | |||
|
145 | from contextlib import contextmanager | |||
|
146 | ||||
|
147 | class _PrettyPrinterBase(object): | |||
|
148 | ||||
|
149 | @contextmanager | |||
|
150 | def indent(self, indent): | |||
|
151 | """with statement support for indenting/dedenting.""" | |||
|
152 | self.indentation += indent | |||
|
153 | try: | |||
|
154 | yield | |||
|
155 | finally: | |||
|
156 | self.indentation -= indent | |||
|
157 | ||||
|
158 | @contextmanager | |||
|
159 | def group(self, indent=0, open='', close=''): | |||
|
160 | """like begin_group / end_group but for the with statement.""" | |||
|
161 | self.begin_group(indent, open) | |||
|
162 | try: | |||
|
163 | with self.indent(indent): | |||
|
164 | yield | |||
|
165 | finally: | |||
|
166 | self.end_group(indent, close) | |||
|
167 | ''' | |||
|
168 | else: | |||
|
169 | class _PrettyPrinterBase(object): | |||
|
170 | ||||
|
171 | def _unsupported(self, *a, **kw): | |||
|
172 | """unsupported operation""" | |||
|
173 | raise RuntimeError('not available in this python version') | |||
|
174 | group = indent = _unsupported | |||
|
175 | del _unsupported | |||
|
176 | ||||
|
177 | ||||
|
178 | class PrettyPrinter(_PrettyPrinterBase): | |||
|
179 | """ | |||
|
180 | Baseclass for the `RepresentationPrinter` prettyprinter that is used to | |||
|
181 | generate pretty reprs of objects. Contrary to the `RepresentationPrinter` | |||
|
182 | this printer knows nothing about the default pprinters or the `__pretty__` | |||
|
183 | callback method. | |||
|
184 | """ | |||
|
185 | ||||
|
186 | def __init__(self, output, max_width=79, newline='\n'): | |||
|
187 | self.output = output | |||
|
188 | self.max_width = max_width | |||
|
189 | self.newline = newline | |||
|
190 | self.output_width = 0 | |||
|
191 | self.buffer_width = 0 | |||
|
192 | self.buffer = deque() | |||
|
193 | ||||
|
194 | root_group = Group(0) | |||
|
195 | self.group_stack = [root_group] | |||
|
196 | self.group_queue = GroupQueue(root_group) | |||
|
197 | self.indentation = 0 | |||
|
198 | ||||
|
199 | def _break_outer_groups(self): | |||
|
200 | while self.max_width < self.output_width + self.buffer_width: | |||
|
201 | group = self.group_queue.deq() | |||
|
202 | if not group: | |||
|
203 | return | |||
|
204 | while group.breakables: | |||
|
205 | x = self.buffer.popleft() | |||
|
206 | self.output_width = x.output(self.output, self.output_width) | |||
|
207 | self.buffer_width -= x.width | |||
|
208 | while self.buffer and isinstance(self.buffer[0], Text): | |||
|
209 | x = self.buffer.popleft() | |||
|
210 | self.output_width = x.output(self.output, self.output_width) | |||
|
211 | self.buffer_width -= x.width | |||
|
212 | ||||
|
213 | def text(self, obj): | |||
|
214 | """Add literal text to the output.""" | |||
|
215 | width = len(obj) | |||
|
216 | if self.buffer: | |||
|
217 | text = self.buffer[-1] | |||
|
218 | if not isinstance(text, Text): | |||
|
219 | text = Text() | |||
|
220 | self.buffer.append(text) | |||
|
221 | text.add(obj, width) | |||
|
222 | self.buffer_width += width | |||
|
223 | self._break_outer_groups() | |||
|
224 | else: | |||
|
225 | self.output.write(obj) | |||
|
226 | self.output_width += width | |||
|
227 | ||||
|
228 | def breakable(self, sep=' '): | |||
|
229 | """ | |||
|
230 | Add a breakable separator to the output. This does not mean that it | |||
|
231 | will automatically break here. If no breaking on this position takes | |||
|
232 | place the `sep` is inserted which default to one space. | |||
|
233 | """ | |||
|
234 | width = len(sep) | |||
|
235 | group = self.group_stack[-1] | |||
|
236 | if group.want_break: | |||
|
237 | self.flush() | |||
|
238 | self.output.write(self.newline) | |||
|
239 | self.output.write(' ' * self.indentation) | |||
|
240 | self.output_width = self.indentation | |||
|
241 | self.buffer_width = 0 | |||
|
242 | else: | |||
|
243 | self.buffer.append(Breakable(sep, width, self)) | |||
|
244 | self.buffer_width += width | |||
|
245 | self._break_outer_groups() | |||
|
246 | ||||
|
247 | ||||
|
248 | def begin_group(self, indent=0, open=''): | |||
|
249 | """ | |||
|
250 | Begin a group. If you want support for python < 2.5 which doesn't has | |||
|
251 | the with statement this is the preferred way: | |||
|
252 | ||||
|
253 | p.begin_group(1, '{') | |||
|
254 | ... | |||
|
255 | p.end_group(1, '}') | |||
|
256 | ||||
|
257 | The python 2.5 expression would be this: | |||
|
258 | ||||
|
259 | with p.group(1, '{', '}'): | |||
|
260 | ... | |||
|
261 | ||||
|
262 | The first parameter specifies the indentation for the next line (usually | |||
|
263 | the width of the opening text), the second the opening text. All | |||
|
264 | parameters are optional. | |||
|
265 | """ | |||
|
266 | if open: | |||
|
267 | self.text(open) | |||
|
268 | group = Group(self.group_stack[-1].depth + 1) | |||
|
269 | self.group_stack.append(group) | |||
|
270 | self.group_queue.enq(group) | |||
|
271 | self.indentation += indent | |||
|
272 | ||||
|
273 | def end_group(self, dedent=0, close=''): | |||
|
274 | """End a group. See `begin_group` for more details.""" | |||
|
275 | self.indentation -= dedent | |||
|
276 | group = self.group_stack.pop() | |||
|
277 | if not group.breakables: | |||
|
278 | self.group_queue.remove(group) | |||
|
279 | if close: | |||
|
280 | self.text(close) | |||
|
281 | ||||
|
282 | def flush(self): | |||
|
283 | """Flush data that is left in the buffer.""" | |||
|
284 | for data in self.buffer: | |||
|
285 | self.output_width += data.output(self.output, self.output_width) | |||
|
286 | self.buffer.clear() | |||
|
287 | self.buffer_width = 0 | |||
|
288 | ||||
|
289 | ||||
|
290 | def _get_mro(obj_class): | |||
|
291 | """ Get a reasonable method resolution order of a class and its superclasses | |||
|
292 | for both old-style and new-style classes. | |||
|
293 | """ | |||
|
294 | if not hasattr(obj_class, '__mro__'): | |||
|
295 | # Old-style class. Mix in object to make a fake new-style class. | |||
|
296 | try: | |||
|
297 | obj_class = type(obj_class.__name__, (obj_class, object), {}) | |||
|
298 | except TypeError: | |||
|
299 | # Old-style extension type that does not descend from object. | |||
|
300 | # FIXME: try to construct a more thorough MRO. | |||
|
301 | mro = [obj_class] | |||
|
302 | else: | |||
|
303 | mro = obj_class.__mro__[1:-1] | |||
|
304 | else: | |||
|
305 | mro = obj_class.__mro__ | |||
|
306 | return mro | |||
|
307 | ||||
|
308 | ||||
|
309 | class RepresentationPrinter(PrettyPrinter): | |||
|
310 | """ | |||
|
311 | Special pretty printer that has a `pretty` method that calls the pretty | |||
|
312 | printer for a python object. | |||
|
313 | ||||
|
314 | This class stores processing data on `self` so you must *never* use | |||
|
315 | this class in a threaded environment. Always lock it or reinstanciate | |||
|
316 | it. | |||
|
317 | ||||
|
318 | Instances also have a verbose flag callbacks can access to control their | |||
|
319 | output. For example the default instance repr prints all attributes and | |||
|
320 | methods that are not prefixed by an underscore if the printer is in | |||
|
321 | verbose mode. | |||
|
322 | """ | |||
|
323 | ||||
|
324 | def __init__(self, output, verbose=False, max_width=79, newline='\n'): | |||
|
325 | PrettyPrinter.__init__(self, output, max_width, newline) | |||
|
326 | self.verbose = verbose | |||
|
327 | self.stack = [] | |||
|
328 | ||||
|
329 | def pretty(self, obj): | |||
|
330 | """Pretty print the given object.""" | |||
|
331 | obj_id = id(obj) | |||
|
332 | cycle = obj_id in self.stack | |||
|
333 | self.stack.append(obj_id) | |||
|
334 | self.begin_group() | |||
|
335 | try: | |||
|
336 | obj_class = getattr(obj, '__class__', None) or type(obj) | |||
|
337 | if hasattr(obj_class, '__pretty__'): | |||
|
338 | return obj_class.__pretty__(obj, self, cycle) | |||
|
339 | try: | |||
|
340 | printer = _singleton_pprinters[obj_id] | |||
|
341 | except (TypeError, KeyError): | |||
|
342 | pass | |||
|
343 | else: | |||
|
344 | return printer(obj, self, cycle) | |||
|
345 | for cls in _get_mro(obj_class): | |||
|
346 | if cls in _type_pprinters: | |||
|
347 | return _type_pprinters[cls](obj, self, cycle) | |||
|
348 | else: | |||
|
349 | printer = self._in_deferred_types(cls) | |||
|
350 | if printer is not None: | |||
|
351 | return printer(obj, self, cycle) | |||
|
352 | return _default_pprint(obj, self, cycle) | |||
|
353 | finally: | |||
|
354 | self.end_group() | |||
|
355 | self.stack.pop() | |||
|
356 | ||||
|
357 | def _in_deferred_types(self, cls): | |||
|
358 | """ | |||
|
359 | Check if the given class is specified in the deferred type registry. | |||
|
360 | ||||
|
361 | Returns the printer from the registry if it exists, and None if the | |||
|
362 | class is not in the registry. Successful matches will be moved to the | |||
|
363 | regular type registry for future use. | |||
|
364 | """ | |||
|
365 | mod = getattr(cls, '__module__', None) | |||
|
366 | name = getattr(cls, '__name__', None) | |||
|
367 | key = (mod, name) | |||
|
368 | printer = None | |||
|
369 | if key in _deferred_type_pprinters: | |||
|
370 | # Move the printer over to the regular registry. | |||
|
371 | printer = _deferred_type_pprinters.pop(key) | |||
|
372 | _type_pprinters[cls] = printer | |||
|
373 | return printer | |||
|
374 | ||||
|
375 | ||||
|
376 | ||||
|
377 | class Printable(object): | |||
|
378 | ||||
|
379 | def output(self, stream, output_width): | |||
|
380 | return output_width | |||
|
381 | ||||
|
382 | ||||
|
383 | class Text(Printable): | |||
|
384 | ||||
|
385 | def __init__(self): | |||
|
386 | self.objs = [] | |||
|
387 | self.width = 0 | |||
|
388 | ||||
|
389 | def output(self, stream, output_width): | |||
|
390 | for obj in self.objs: | |||
|
391 | stream.write(obj) | |||
|
392 | return output_width + self.width | |||
|
393 | ||||
|
394 | def add(self, obj, width): | |||
|
395 | self.objs.append(obj) | |||
|
396 | self.width += width | |||
|
397 | ||||
|
398 | ||||
|
399 | class Breakable(Printable): | |||
|
400 | ||||
|
401 | def __init__(self, seq, width, pretty): | |||
|
402 | self.obj = seq | |||
|
403 | self.width = width | |||
|
404 | self.pretty = pretty | |||
|
405 | self.indentation = pretty.indentation | |||
|
406 | self.group = pretty.group_stack[-1] | |||
|
407 | self.group.breakables.append(self) | |||
|
408 | ||||
|
409 | def output(self, stream, output_width): | |||
|
410 | self.group.breakables.popleft() | |||
|
411 | if self.group.want_break: | |||
|
412 | stream.write(self.pretty.newline) | |||
|
413 | stream.write(' ' * self.indentation) | |||
|
414 | return self.indentation | |||
|
415 | if not self.group.breakables: | |||
|
416 | self.pretty.group_queue.remove(self.group) | |||
|
417 | stream.write(self.obj) | |||
|
418 | return output_width + self.width | |||
|
419 | ||||
|
420 | ||||
|
421 | class Group(Printable): | |||
|
422 | ||||
|
423 | def __init__(self, depth): | |||
|
424 | self.depth = depth | |||
|
425 | self.breakables = deque() | |||
|
426 | self.want_break = False | |||
|
427 | ||||
|
428 | ||||
|
429 | class GroupQueue(object): | |||
|
430 | ||||
|
431 | def __init__(self, *groups): | |||
|
432 | self.queue = [] | |||
|
433 | for group in groups: | |||
|
434 | self.enq(group) | |||
|
435 | ||||
|
436 | def enq(self, group): | |||
|
437 | depth = group.depth | |||
|
438 | while depth > len(self.queue) - 1: | |||
|
439 | self.queue.append([]) | |||
|
440 | self.queue[depth].append(group) | |||
|
441 | ||||
|
442 | def deq(self): | |||
|
443 | for stack in self.queue: | |||
|
444 | for idx, group in enumerate(reversed(stack)): | |||
|
445 | if group.breakables: | |||
|
446 | del stack[idx] | |||
|
447 | group.want_break = True | |||
|
448 | return group | |||
|
449 | for group in stack: | |||
|
450 | group.want_break = True | |||
|
451 | del stack[:] | |||
|
452 | ||||
|
453 | def remove(self, group): | |||
|
454 | try: | |||
|
455 | self.queue[group.depth].remove(group) | |||
|
456 | except ValueError: | |||
|
457 | pass | |||
|
458 | ||||
|
459 | ||||
|
460 | _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__) | |||
|
461 | ||||
|
462 | ||||
|
463 | def _default_pprint(obj, p, cycle): | |||
|
464 | """ | |||
|
465 | The default print function. Used if an object does not provide one and | |||
|
466 | it's none of the builtin objects. | |||
|
467 | """ | |||
|
468 | klass = getattr(obj, '__class__', None) or type(obj) | |||
|
469 | if getattr(klass, '__repr__', None) not in _baseclass_reprs: | |||
|
470 | # A user-provided repr. | |||
|
471 | p.text(repr(obj)) | |||
|
472 | return | |||
|
473 | p.begin_group(1, '<') | |||
|
474 | p.pretty(klass) | |||
|
475 | p.text(' at 0x%x' % id(obj)) | |||
|
476 | if cycle: | |||
|
477 | p.text(' ...') | |||
|
478 | elif p.verbose: | |||
|
479 | first = True | |||
|
480 | for key in dir(obj): | |||
|
481 | if not key.startswith('_'): | |||
|
482 | try: | |||
|
483 | value = getattr(obj, key) | |||
|
484 | except AttributeError: | |||
|
485 | continue | |||
|
486 | if isinstance(value, types.MethodType): | |||
|
487 | continue | |||
|
488 | if not first: | |||
|
489 | p.text(',') | |||
|
490 | p.breakable() | |||
|
491 | p.text(key) | |||
|
492 | p.text('=') | |||
|
493 | step = len(key) + 1 | |||
|
494 | p.indentation += step | |||
|
495 | p.pretty(value) | |||
|
496 | p.indentation -= step | |||
|
497 | first = False | |||
|
498 | p.end_group(1, '>') | |||
|
499 | ||||
|
500 | ||||
|
501 | def _seq_pprinter_factory(start, end): | |||
|
502 | """ | |||
|
503 | Factory that returns a pprint function useful for sequences. Used by | |||
|
504 | the default pprint for tuples, dicts, lists, sets and frozensets. | |||
|
505 | """ | |||
|
506 | def inner(obj, p, cycle): | |||
|
507 | if cycle: | |||
|
508 | return p.text(start + '...' + end) | |||
|
509 | step = len(start) | |||
|
510 | p.begin_group(step, start) | |||
|
511 | for idx, x in enumerate(obj): | |||
|
512 | if idx: | |||
|
513 | p.text(',') | |||
|
514 | p.breakable() | |||
|
515 | p.pretty(x) | |||
|
516 | if len(obj) == 1 and type(obj) is tuple: | |||
|
517 | # Special case for 1-item tuples. | |||
|
518 | p.text(',') | |||
|
519 | p.end_group(step, end) | |||
|
520 | return inner | |||
|
521 | ||||
|
522 | ||||
|
523 | def _dict_pprinter_factory(start, end): | |||
|
524 | """ | |||
|
525 | Factory that returns a pprint function used by the default pprint of | |||
|
526 | dicts and dict proxies. | |||
|
527 | """ | |||
|
528 | def inner(obj, p, cycle): | |||
|
529 | if cycle: | |||
|
530 | return p.text('{...}') | |||
|
531 | p.begin_group(1, start) | |||
|
532 | keys = obj.keys() | |||
|
533 | try: | |||
|
534 | keys.sort() | |||
|
535 | except Exception, e: | |||
|
536 | # Sometimes the keys don't sort. | |||
|
537 | pass | |||
|
538 | for idx, key in enumerate(keys): | |||
|
539 | if idx: | |||
|
540 | p.text(',') | |||
|
541 | p.breakable() | |||
|
542 | p.pretty(key) | |||
|
543 | p.text(': ') | |||
|
544 | p.pretty(obj[key]) | |||
|
545 | p.end_group(1, end) | |||
|
546 | return inner | |||
|
547 | ||||
|
548 | ||||
|
549 | def _super_pprint(obj, p, cycle): | |||
|
550 | """The pprint for the super type.""" | |||
|
551 | p.begin_group(8, '<super: ') | |||
|
552 | p.pretty(obj.__self_class__) | |||
|
553 | p.text(',') | |||
|
554 | p.breakable() | |||
|
555 | p.pretty(obj.__self__) | |||
|
556 | p.end_group(8, '>') | |||
|
557 | ||||
|
558 | ||||
|
559 | def _re_pattern_pprint(obj, p, cycle): | |||
|
560 | """The pprint function for regular expression patterns.""" | |||
|
561 | p.text('re.compile(') | |||
|
562 | pattern = repr(obj.pattern) | |||
|
563 | if pattern[:1] in 'uU': | |||
|
564 | pattern = pattern[1:] | |||
|
565 | prefix = 'ur' | |||
|
566 | else: | |||
|
567 | prefix = 'r' | |||
|
568 | pattern = prefix + pattern.replace('\\\\', '\\') | |||
|
569 | p.text(pattern) | |||
|
570 | if obj.flags: | |||
|
571 | p.text(',') | |||
|
572 | p.breakable() | |||
|
573 | done_one = False | |||
|
574 | for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL', | |||
|
575 | 'UNICODE', 'VERBOSE', 'DEBUG'): | |||
|
576 | if obj.flags & getattr(re, flag): | |||
|
577 | if done_one: | |||
|
578 | p.text('|') | |||
|
579 | p.text('re.' + flag) | |||
|
580 | done_one = True | |||
|
581 | p.text(')') | |||
|
582 | ||||
|
583 | ||||
|
584 | def _type_pprint(obj, p, cycle): | |||
|
585 | """The pprint for classes and types.""" | |||
|
586 | if obj.__module__ in ('__builtin__', 'exceptions'): | |||
|
587 | name = obj.__name__ | |||
|
588 | else: | |||
|
589 | name = obj.__module__ + '.' + obj.__name__ | |||
|
590 | p.text(name) | |||
|
591 | ||||
|
592 | ||||
|
593 | def _repr_pprint(obj, p, cycle): | |||
|
594 | """A pprint that just redirects to the normal repr function.""" | |||
|
595 | p.text(repr(obj)) | |||
|
596 | ||||
|
597 | ||||
|
598 | def _function_pprint(obj, p, cycle): | |||
|
599 | """Base pprint for all functions and builtin functions.""" | |||
|
600 | if obj.__module__ in ('__builtin__', 'exceptions') or not obj.__module__: | |||
|
601 | name = obj.__name__ | |||
|
602 | else: | |||
|
603 | name = obj.__module__ + '.' + obj.__name__ | |||
|
604 | p.text('<function %s>' % name) | |||
|
605 | ||||
|
606 | ||||
|
607 | def _exception_pprint(obj, p, cycle): | |||
|
608 | """Base pprint for all exceptions.""" | |||
|
609 | if obj.__class__.__module__ == 'exceptions': | |||
|
610 | name = obj.__class__.__name__ | |||
|
611 | else: | |||
|
612 | name = '%s.%s' % ( | |||
|
613 | obj.__class__.__module__, | |||
|
614 | obj.__class__.__name__ | |||
|
615 | ) | |||
|
616 | step = len(name) + 1 | |||
|
617 | p.begin_group(step, '(') | |||
|
618 | for idx, arg in enumerate(getattr(obj, 'args', ())): | |||
|
619 | if idx: | |||
|
620 | p.text(',') | |||
|
621 | p.breakable() | |||
|
622 | p.pretty(arg) | |||
|
623 | p.end_group(step, ')') | |||
|
624 | ||||
|
625 | ||||
|
626 | #: the exception base | |||
|
627 | try: | |||
|
628 | _exception_base = BaseException | |||
|
629 | except NameError: | |||
|
630 | _exception_base = Exception | |||
|
631 | ||||
|
632 | ||||
|
633 | #: printers for builtin types | |||
|
634 | _type_pprinters = { | |||
|
635 | int: _repr_pprint, | |||
|
636 | long: _repr_pprint, | |||
|
637 | float: _repr_pprint, | |||
|
638 | str: _repr_pprint, | |||
|
639 | unicode: _repr_pprint, | |||
|
640 | tuple: _seq_pprinter_factory('(', ')'), | |||
|
641 | list: _seq_pprinter_factory('[', ']'), | |||
|
642 | dict: _dict_pprinter_factory('{', '}'), | |||
|
643 | types.DictProxyType: _dict_pprinter_factory('<dictproxy {', '}>'), | |||
|
644 | set: _seq_pprinter_factory('set([', '])'), | |||
|
645 | frozenset: _seq_pprinter_factory('frozenset([', '])'), | |||
|
646 | super: _super_pprint, | |||
|
647 | _re_pattern_type: _re_pattern_pprint, | |||
|
648 | type: _type_pprint, | |||
|
649 | types.ClassType: _type_pprint, | |||
|
650 | types.FunctionType: _function_pprint, | |||
|
651 | types.BuiltinFunctionType: _function_pprint, | |||
|
652 | types.SliceType: _repr_pprint, | |||
|
653 | types.MethodType: _repr_pprint, | |||
|
654 | xrange: _repr_pprint, | |||
|
655 | datetime.datetime: _repr_pprint, | |||
|
656 | datetime.timedelta: _repr_pprint, | |||
|
657 | _exception_base: _exception_pprint | |||
|
658 | } | |||
|
659 | ||||
|
660 | #: printers for types specified by name | |||
|
661 | _deferred_type_pprinters = { | |||
|
662 | } | |||
|
663 | ||||
|
664 | def for_type(typ, func): | |||
|
665 | """ | |||
|
666 | Add a pretty printer for a given type. | |||
|
667 | """ | |||
|
668 | oldfunc = _type_pprinters.get(typ, None) | |||
|
669 | if func is not None: | |||
|
670 | # To support easy restoration of old pprinters, we need to ignore Nones. | |||
|
671 | _type_pprinters[typ] = func | |||
|
672 | return oldfunc | |||
|
673 | ||||
|
674 | def for_type_by_name(type_module, type_name, func): | |||
|
675 | """ | |||
|
676 | Add a pretty printer for a type specified by the module and name of a type | |||
|
677 | rather than the type object itself. | |||
|
678 | """ | |||
|
679 | key = (type_module, type_name) | |||
|
680 | oldfunc = _deferred_type_pprinters.get(key, None) | |||
|
681 | if func is not None: | |||
|
682 | # To support easy restoration of old pprinters, we need to ignore Nones. | |||
|
683 | _deferred_type_pprinters[key] = func | |||
|
684 | return oldfunc | |||
|
685 | ||||
|
686 | ||||
|
687 | #: printers for the default singletons | |||
|
688 | _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis, | |||
|
689 | NotImplemented]), _repr_pprint) | |||
|
690 | ||||
|
691 | ||||
|
692 | if __name__ == '__main__': | |||
|
693 | from random import randrange | |||
|
694 | class Foo(object): | |||
|
695 | def __init__(self): | |||
|
696 | self.foo = 1 | |||
|
697 | self.bar = re.compile(r'\s+') | |||
|
698 | self.blub = dict.fromkeys(range(30), randrange(1, 40)) | |||
|
699 | self.hehe = 23424.234234 | |||
|
700 | self.list = ["blub", "blah", self] | |||
|
701 | ||||
|
702 | def get_foo(self): | |||
|
703 | print "foo" | |||
|
704 | ||||
|
705 | pprint(Foo(), verbose=True) |
@@ -0,0 +1,34 b'' | |||||
|
1 | """Test code for https://bugs.launchpad.net/ipython/+bug/239054 | |||
|
2 | ||||
|
3 | WARNING: this script exits IPython! It MUST be run in a subprocess. | |||
|
4 | ||||
|
5 | When you run the following script from CPython it prints: | |||
|
6 | __init__ is here | |||
|
7 | __del__ is here | |||
|
8 | ||||
|
9 | and creates the __del__.txt file | |||
|
10 | ||||
|
11 | When you run it from IPython it prints: | |||
|
12 | __init__ is here | |||
|
13 | ||||
|
14 | When you exit() or Exit from IPython neothing is printed and no file is created | |||
|
15 | (the file thing is to make sure __del__ is really never called and not that | |||
|
16 | just the output is eaten). | |||
|
17 | ||||
|
18 | Note that if you call %reset in IPython then everything is Ok. | |||
|
19 | ||||
|
20 | IPython should do the equivalent of %reset and release all the references it | |||
|
21 | holds before exit. This behavior is important when working with binding objects | |||
|
22 | that rely on __del__. If the current behavior has some use case then I suggest | |||
|
23 | to add a configuration option to IPython to control it. | |||
|
24 | """ | |||
|
25 | import sys | |||
|
26 | ||||
|
27 | class A(object): | |||
|
28 | def __del__(self): | |||
|
29 | print 'object A deleted' | |||
|
30 | ||||
|
31 | a = A() | |||
|
32 | ||||
|
33 | # Now, we force an exit, the caller will check that the del printout was given | |||
|
34 | _ip.IP.ask_exit() |
@@ -0,0 +1,26 b'' | |||||
|
1 | """Simple script to instantiate a class for testing %run""" | |||
|
2 | ||||
|
3 | import sys | |||
|
4 | ||||
|
5 | # An external test will check that calls to f() work after %run | |||
|
6 | class foo: pass | |||
|
7 | ||||
|
8 | def f(): | |||
|
9 | return foo() | |||
|
10 | ||||
|
11 | # We also want to ensure that while objects remain available for immediate | |||
|
12 | # access, objects from *previous* runs of the same script get collected, to | |||
|
13 | # avoid accumulating massive amounts of old references. | |||
|
14 | class C(object): | |||
|
15 | def __init__(self,name): | |||
|
16 | self.name = name | |||
|
17 | ||||
|
18 | def __del__(self): | |||
|
19 | print 'Deleting object:',self.name | |||
|
20 | ||||
|
21 | try: | |||
|
22 | name = sys.argv[1] | |||
|
23 | except IndexError: | |||
|
24 | pass | |||
|
25 | else: | |||
|
26 | c = C(name) |
@@ -0,0 +1,17 b'' | |||||
|
1 | """Tests for the key iplib module, where the main ipython class is defined. | |||
|
2 | """ | |||
|
3 | ||||
|
4 | import nose.tools as nt | |||
|
5 | ||||
|
6 | ||||
|
7 | def test_reset(): | |||
|
8 | """reset must clear most namespaces.""" | |||
|
9 | ip = _ip.IP | |||
|
10 | ip.reset() # first, it should run without error | |||
|
11 | # Then, check that most namespaces end up empty | |||
|
12 | for ns in ip.ns_refs_table: | |||
|
13 | if ns is ip.user_ns: | |||
|
14 | # The user namespace is reset with some data, so we can't check for | |||
|
15 | # it being empty | |||
|
16 | continue | |||
|
17 | nt.assert_equals(len(ns),0) |
@@ -0,0 +1,33 b'' | |||||
|
1 | #!/usr/bin/env python | |||
|
2 | """Script to auto-generate our API docs. | |||
|
3 | """ | |||
|
4 | # stdlib imports | |||
|
5 | import os | |||
|
6 | import sys | |||
|
7 | ||||
|
8 | # local imports | |||
|
9 | sys.path.append(os.path.abspath('sphinxext')) | |||
|
10 | from apigen import ApiDocWriter | |||
|
11 | ||||
|
12 | #***************************************************************************** | |||
|
13 | if __name__ == '__main__': | |||
|
14 | pjoin = os.path.join | |||
|
15 | package = 'IPython' | |||
|
16 | outdir = pjoin('source','api','generated') | |||
|
17 | docwriter = ApiDocWriter(package,rst_extension='.txt') | |||
|
18 | docwriter.package_skip_patterns += [r'\.fixes$', | |||
|
19 | r'\.externals$', | |||
|
20 | r'\.Extensions', | |||
|
21 | r'\.kernel.config', | |||
|
22 | r'\.attic', | |||
|
23 | ] | |||
|
24 | docwriter.module_skip_patterns += [ r'\.FakeModule', | |||
|
25 | r'\.cocoa', | |||
|
26 | r'\.ipdoctest', | |||
|
27 | r'\.Gnuplot', | |||
|
28 | ] | |||
|
29 | docwriter.write_api_docs(outdir) | |||
|
30 | docwriter.write_index(outdir, 'gen', | |||
|
31 | relative_to = pjoin('source','api') | |||
|
32 | ) | |||
|
33 | print '%d files written' % len(docwriter.written_modules) |
@@ -0,0 +1,12 b'' | |||||
|
1 | .. _api-index: | |||
|
2 | ||||
|
3 | ################### | |||
|
4 | The IPython API | |||
|
5 | ################### | |||
|
6 | ||||
|
7 | .. htmlonly:: | |||
|
8 | ||||
|
9 | :Release: |version| | |||
|
10 | :Date: |today| | |||
|
11 | ||||
|
12 | .. include:: generated/gen.txt |
@@ -0,0 +1,141 b'' | |||||
|
1 | ============== | |||
|
2 | Coding guide | |||
|
3 | ============== | |||
|
4 | ||||
|
5 | ||||
|
6 | Coding conventions | |||
|
7 | ================== | |||
|
8 | ||||
|
9 | In general, we'll try to follow the standard Python style conventions as | |||
|
10 | described in Python's `PEP 8`_, the official Python Style Guide. | |||
|
11 | ||||
|
12 | .. _PEP 8: http://www.python.org/peps/pep-0008.html | |||
|
13 | ||||
|
14 | Other comments: | |||
|
15 | ||||
|
16 | - In a large file, top level classes and functions should be separated by 2-3 | |||
|
17 | lines to make it easier to separate them visually. | |||
|
18 | ||||
|
19 | - Use 4 spaces for indentation, *never* use hard tabs. | |||
|
20 | ||||
|
21 | - Keep the ordering of methods the same in classes that have the same methods. | |||
|
22 | This is particularly true for classes that implement similar interfaces and | |||
|
23 | for interfaces that are similar. | |||
|
24 | ||||
|
25 | Naming conventions | |||
|
26 | ------------------ | |||
|
27 | ||||
|
28 | In terms of naming conventions, we'll follow the guidelines of PEP 8. Some of | |||
|
29 | the existing code doesn't honor this perfectly, but for all new IPython code | |||
|
30 | (and much existing code is being refactored), we'll use: | |||
|
31 | ||||
|
32 | - All ``lowercase`` module names. | |||
|
33 | ||||
|
34 | - ``CamelCase`` for class names. | |||
|
35 | ||||
|
36 | - ``lowercase_with_underscores`` for methods, functions, variables and | |||
|
37 | attributes. | |||
|
38 | ||||
|
39 | This may be confusing as some of the existing codebase uses a different | |||
|
40 | convention (``lowerCamelCase`` for methods and attributes). Slowly, we will | |||
|
41 | move IPython over to the new convention, providing shadow names for backward | |||
|
42 | compatibility in public interfaces. | |||
|
43 | ||||
|
44 | There are, however, some important exceptions to these rules. In some cases, | |||
|
45 | IPython code will interface with packages (Twisted, Wx, Qt) that use other | |||
|
46 | conventions. At some level this makes it impossible to adhere to our own | |||
|
47 | standards at all times. In particular, when subclassing classes that use other | |||
|
48 | naming conventions, you must follow their naming conventions. To deal with | |||
|
49 | cases like this, we propose the following policy: | |||
|
50 | ||||
|
51 | - If you are subclassing a class that uses different conventions, use its | |||
|
52 | naming conventions throughout your subclass. Thus, if you are creating a | |||
|
53 | Twisted Protocol class, used Twisted's | |||
|
54 | ``namingSchemeForMethodsAndAttributes.`` | |||
|
55 | ||||
|
56 | - All IPython's official interfaces should use our conventions. In some cases | |||
|
57 | this will mean that you need to provide shadow names (first implement | |||
|
58 | ``fooBar`` and then ``foo_bar = fooBar``). We want to avoid this at all | |||
|
59 | costs, but it will probably be necessary at times. But, please use this | |||
|
60 | sparingly! | |||
|
61 | ||||
|
62 | Implementation-specific *private* methods will use | |||
|
63 | ``_single_underscore_prefix``. Names with a leading double underscore will | |||
|
64 | *only* be used in special cases, as they makes subclassing difficult (such | |||
|
65 | names are not easily seen by child classes). | |||
|
66 | ||||
|
67 | Occasionally some run-in lowercase names are used, but mostly for very short | |||
|
68 | names or where we are implementing methods very similar to existing ones in a | |||
|
69 | base class (like ``runlines()`` where ``runsource()`` and ``runcode()`` had | |||
|
70 | established precedent). | |||
|
71 | ||||
|
72 | The old IPython codebase has a big mix of classes and modules prefixed with an | |||
|
73 | explicit ``IP``. In Python this is mostly unnecessary, redundant and frowned | |||
|
74 | upon, as namespaces offer cleaner prefixing. The only case where this approach | |||
|
75 | is justified is for classes which are expected to be imported into external | |||
|
76 | namespaces and a very generic name (like Shell) is too likely to clash with | |||
|
77 | something else. We'll need to revisit this issue as we clean up and refactor | |||
|
78 | the code, but in general we should remove as many unnecessary ``IP``/``ip`` | |||
|
79 | prefixes as possible. However, if a prefix seems absolutely necessary the more | |||
|
80 | specific ``IPY`` or ``ipy`` are preferred. | |||
|
81 | ||||
|
82 | ||||
|
83 | .. _devel-testing: | |||
|
84 | ||||
|
85 | Testing system | |||
|
86 | ============== | |||
|
87 | ||||
|
88 | It is extremely important that all code contributed to IPython has tests. Tests | |||
|
89 | should be written as unittests, doctests or as entities that the `Nose`_ | |||
|
90 | testing package will find. Regardless of how the tests are written, we will use | |||
|
91 | `Nose`_ for discovering and running the tests. `Nose`_ will be required to run | |||
|
92 | the IPython test suite, but will not be required to simply use IPython. | |||
|
93 | ||||
|
94 | .. _Nose: http://code.google.com/p/python-nose/ | |||
|
95 | ||||
|
96 | Tests of `Twisted`__ using code should be written by subclassing the | |||
|
97 | ``TestCase`` class that comes with ``twisted.trial.unittest``. When this is | |||
|
98 | done, `Nose`_ will be able to run the tests and the twisted reactor will be | |||
|
99 | handled correctly. | |||
|
100 | ||||
|
101 | .. __: http://www.twistedmatrix.com | |||
|
102 | ||||
|
103 | Each subpackage in IPython should have its own ``tests`` directory that | |||
|
104 | contains all of the tests for that subpackage. This allows each subpackage to | |||
|
105 | be self-contained. If a subpackage has any dependencies beyond the Python | |||
|
106 | standard library, the tests for that subpackage should be skipped if the | |||
|
107 | dependencies are not found. This is very important so users don't get tests | |||
|
108 | failing simply because they don't have dependencies. | |||
|
109 | ||||
|
110 | We also need to look into use Noses ability to tag tests to allow a more | |||
|
111 | modular approach of running tests. | |||
|
112 | ||||
|
113 | .. _devel-config: | |||
|
114 | ||||
|
115 | Configuration system | |||
|
116 | ==================== | |||
|
117 | ||||
|
118 | IPython uses `.ini`_ files for configuration purposes. This represents a huge | |||
|
119 | improvement over the configuration system used in IPython. IPython works with | |||
|
120 | these files using the `ConfigObj`_ package, which IPython includes as | |||
|
121 | ``ipython1/external/configobj.py``. | |||
|
122 | ||||
|
123 | Currently, we are using raw `ConfigObj`_ objects themselves. Each subpackage of | |||
|
124 | IPython should contain a ``config`` subdirectory that contains all of the | |||
|
125 | configuration information for the subpackage. To see how configuration | |||
|
126 | information is defined (along with defaults) see at the examples in | |||
|
127 | ``ipython1/kernel/config`` and ``ipython1/core/config``. Likewise, to see how | |||
|
128 | the configuration information is used, see examples in | |||
|
129 | ``ipython1/kernel/scripts/ipengine.py``. | |||
|
130 | ||||
|
131 | Eventually, we will add a new layer on top of the raw `ConfigObj`_ objects. We | |||
|
132 | are calling this new layer, ``tconfig``, as it will use a `Traits`_-like | |||
|
133 | validation model. We won't actually use `Traits`_, but will implement | |||
|
134 | something similar in pure Python. But, even in this new system, we will still | |||
|
135 | use `ConfigObj`_ and `.ini`_ files underneath the hood. Talk to Fernando if you | |||
|
136 | are interested in working on this part of IPython. The current prototype of | |||
|
137 | ``tconfig`` is located in the IPython sandbox. | |||
|
138 | ||||
|
139 | .. _.ini: http://docs.python.org/lib/module-ConfigParser.html | |||
|
140 | .. _ConfigObj: http://www.voidspace.org.uk/python/configobj.html | |||
|
141 | .. _Traits: http://code.enthought.com/traits/ |
@@ -0,0 +1,103 b'' | |||||
|
1 | .. _documenting-ipython: | |||
|
2 | ||||
|
3 | ===================== | |||
|
4 | Documenting IPython | |||
|
5 | ===================== | |||
|
6 | ||||
|
7 | Standalone documentation | |||
|
8 | ======================== | |||
|
9 | ||||
|
10 | All standalone documentation should be written in plain text (``.txt``) files | |||
|
11 | using `reStructuredText`_ for markup and formatting. All such documentation | |||
|
12 | should be placed in the top level directory ``docs`` of the IPython source | |||
|
13 | tree. Or, when appropriate, a suitably named subdirectory should be used. The | |||
|
14 | documentation in this location will serve as the main source for IPython | |||
|
15 | documentation and all existing documentation should be converted to this | |||
|
16 | format. | |||
|
17 | ||||
|
18 | The actual HTML and PDF docs are built using the Sphinx_ documentation | |||
|
19 | generation tool. Sphinx has been adopted as the default documentation tool for | |||
|
20 | Python itself as of version 2.6, as well as by a number of projects that | |||
|
21 | IPython is related with, such as numpy, scipy, matplotlib, sage and nipy. | |||
|
22 | ||||
|
23 | .. _reStructuredText: http://docutils.sourceforge.net/rst.html | |||
|
24 | .. _Sphinx: http://sphinx.pocoo.org/ | |||
|
25 | ||||
|
26 | ||||
|
27 | The rest of this document is mostly taken from the `matploblib | |||
|
28 | documentation`__; we are using a number of Sphinx tools and extensions written | |||
|
29 | by the matplotlib team and will mostly follow their conventions, which are | |||
|
30 | nicely spelled out in their guide. What follows is thus a lightly adapted | |||
|
31 | version of the matplotlib documentation guide, taken with permission from the | |||
|
32 | MPL team. | |||
|
33 | ||||
|
34 | .. __: http://matplotlib.sourceforge.net/devel/documenting_mpl.html | |||
|
35 | ||||
|
36 | ||||
|
37 | A bit of Python code:: | |||
|
38 | ||||
|
39 | for i in range(10): | |||
|
40 | print i, | |||
|
41 | print "A big number:",2**34 | |||
|
42 | ||||
|
43 | An interactive Python session:: | |||
|
44 | ||||
|
45 | >>> from IPython import genutils | |||
|
46 | >>> genutils.get_ipython_dir() | |||
|
47 | '/home/fperez/.ipython' | |||
|
48 | ||||
|
49 | ||||
|
50 | An IPython session: | |||
|
51 | ||||
|
52 | .. code-block:: ipython | |||
|
53 | ||||
|
54 | In [7]: import IPython | |||
|
55 | ||||
|
56 | In [8]: print "This IPython is version:",IPython.__version__ | |||
|
57 | This IPython is version: 0.9.1 | |||
|
58 | ||||
|
59 | In [9]: 2+4 | |||
|
60 | Out[9]: 6 | |||
|
61 | ||||
|
62 | ||||
|
63 | A bit of shell code: | |||
|
64 | ||||
|
65 | .. code-block:: bash | |||
|
66 | ||||
|
67 | cd /tmp | |||
|
68 | echo "My home directory is: $HOME" | |||
|
69 | ls | |||
|
70 | ||||
|
71 | ||||
|
72 | Docstring format | |||
|
73 | ================ | |||
|
74 | ||||
|
75 | Good docstrings are very important. Unfortunately, Python itself only provides | |||
|
76 | a rather loose standard for docstrings (`PEP 257`_), and there is no universally | |||
|
77 | accepted convention for all the different parts of a complete docstring. | |||
|
78 | However, the NumPy project has established a very reasonable standard, and has | |||
|
79 | developed some tools to support the smooth inclusion of such docstrings in | |||
|
80 | Sphinx-generated manuals. Rather than inventing yet another pseudo-standard, | |||
|
81 | IPython will be henceforth documented using the NumPy conventions; we carry | |||
|
82 | copies of some of the NumPy support tools to remain self-contained, but share | |||
|
83 | back upstream with NumPy any improvements or fixes we may make to the tools. | |||
|
84 | ||||
|
85 | The `NumPy documentation guidelines`_ contain detailed information on this | |||
|
86 | standard, and for a quick overview, the NumPy `example docstring`_ is a useful | |||
|
87 | read. | |||
|
88 | ||||
|
89 | As in the past IPython used epydoc, currently many docstrings still use epydoc | |||
|
90 | conventions. We will update them as we go, but all new code should be fully | |||
|
91 | documented using the NumPy standard. | |||
|
92 | ||||
|
93 | .. _PEP 257: http://www.python.org/peps/pep-0257.html | |||
|
94 | .. _NumPy documentation guidelines: http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines | |||
|
95 | ||||
|
96 | .. _example docstring: http://projects.scipy.org/numpy/browser/trunk/doc/EXAMPLE_DOCSTRING.txt | |||
|
97 | ||||
|
98 | Additional PEPs of interest regarding documentation of code. While both of | |||
|
99 | these were rejected, the ideas therein form much of the basis of docutils (the | |||
|
100 | machinery to process reStructuredText): | |||
|
101 | ||||
|
102 | - `Docstring Processing System Framework <http://www.python.org/peps/pep-0256.html>`_ | |||
|
103 | - `Docutils Design Specification <http://www.python.org/peps/pep-0258.html>`_ |
1 | NO CONTENT: new file 100644, binary diff hidden |
|
NO CONTENT: new file 100644, binary diff hidden |
1 | NO CONTENT: new file 100644, binary diff hidden |
|
NO CONTENT: new file 100644, binary diff hidden |
@@ -0,0 +1,246 b'' | |||||
|
1 | ================================== | |||
|
2 | IPython/Vision Beam Pattern Demo | |||
|
3 | ================================== | |||
|
4 | ||||
|
5 | ||||
|
6 | Installing and testing IPython at OSC systems | |||
|
7 | ============================================= | |||
|
8 | ||||
|
9 | All components were installed from source and I have my environment set up to | |||
|
10 | include ~/usr/local in my various necessary paths ($PATH, $PYTHONPATH, etc). | |||
|
11 | Other than a slow filesystem for unpacking tarballs, the install went without a | |||
|
12 | hitch. For each needed component, I just downloaded the source tarball, | |||
|
13 | unpacked it via:: | |||
|
14 | ||||
|
15 | tar xzf (or xjf if it's bz2) filename.tar.{gz,bz2} | |||
|
16 | ||||
|
17 | and then installed them (including IPython itself) with:: | |||
|
18 | ||||
|
19 | cd dirname/ # path to unpacked tarball | |||
|
20 | python setup.py install --prefix=~/usr/local/ | |||
|
21 | ||||
|
22 | The components I installed are listed below. For each one I give the main | |||
|
23 | project link as well as a direct one to the file I actually dowloaded and used. | |||
|
24 | ||||
|
25 | - nose, used for testing: | |||
|
26 | http://somethingaboutorange.com/mrl/projects/nose/ | |||
|
27 | http://somethingaboutorange.com/mrl/projects/nose/nose-0.10.3.tar.gz | |||
|
28 | ||||
|
29 | - Zope interface, used to declare interfaces in twisted and ipython. Note: | |||
|
30 | you must get this from the page linked below and not fro the defaul | |||
|
31 | one(http://www.zope.org/Products/ZopeInterface) because the latter has an | |||
|
32 | older version, it hasn't been updated in a long time. This pypi link has | |||
|
33 | the current release (3.4.1 as of this writing): | |||
|
34 | http://pypi.python.org/pypi/zope.interface | |||
|
35 | http://pypi.python.org/packages/source/z/zope.interface/zope.interface-3.4.1.tar.gz | |||
|
36 | ||||
|
37 | - pyopenssl, security layer used by foolscap. Note: version 0.7 *must* be | |||
|
38 | used: | |||
|
39 | http://sourceforge.net/projects/pyopenssl/ | |||
|
40 | http://downloads.sourceforge.net/pyopenssl/pyOpenSSL-0.6.tar.gz?modtime=1212595285&big_mirror=0 | |||
|
41 | ||||
|
42 | ||||
|
43 | - Twisted, used for all networking: | |||
|
44 | http://twistedmatrix.com/trac/wiki/Downloads | |||
|
45 | http://tmrc.mit.edu/mirror/twisted/Twisted/8.1/Twisted-8.1.0.tar.bz2 | |||
|
46 | ||||
|
47 | - Foolscap, used for managing connections securely: | |||
|
48 | http://foolscap.lothar.com/trac | |||
|
49 | http://foolscap.lothar.com/releases/foolscap-0.3.1.tar.gz | |||
|
50 | ||||
|
51 | ||||
|
52 | - IPython itself: | |||
|
53 | http://ipython.scipy.org/ | |||
|
54 | http://ipython.scipy.org/dist/ipython-0.9.1.tar.gz | |||
|
55 | ||||
|
56 | ||||
|
57 | I then ran the ipython test suite via:: | |||
|
58 | ||||
|
59 | iptest -vv | |||
|
60 | ||||
|
61 | and it passed with only:: | |||
|
62 | ||||
|
63 | ====================================================================== | |||
|
64 | ERROR: testGetResult_2 | |||
|
65 | ---------------------------------------------------------------------- | |||
|
66 | DirtyReactorAggregateError: Reactor was unclean. | |||
|
67 | Selectables: | |||
|
68 | <Negotiation #0 on 10105> | |||
|
69 | ||||
|
70 | ---------------------------------------------------------------------- | |||
|
71 | Ran 419 tests in 33.971s | |||
|
72 | ||||
|
73 | FAILED (SKIP=4, errors=1) | |||
|
74 | ||||
|
75 | In three more runs of the test suite I was able to reproduce this error | |||
|
76 | sometimes but not always; for now I think we can move on but we need to | |||
|
77 | investigate further. Especially if we start seeing problems in real use (the | |||
|
78 | test suite stresses the networking layer in particular ways that aren't | |||
|
79 | necessarily typical of normal use). | |||
|
80 | ||||
|
81 | Next, I started an 8-engine cluster via:: | |||
|
82 | ||||
|
83 | perez@opt-login01[~]> ipcluster -n 8 | |||
|
84 | Starting controller: Controller PID: 30845 | |||
|
85 | ^X Starting engines: Engines PIDs: [30846, 30847, 30848, 30849, | |||
|
86 | 30850, 30851, 30852, 30853] | |||
|
87 | Log files: /home/perez/.ipython/log/ipcluster-30845-* | |||
|
88 | ||||
|
89 | Your cluster is up and running. | |||
|
90 | ||||
|
91 | [... etc] | |||
|
92 | ||||
|
93 | and in a separate ipython session checked that the cluster is running and I can | |||
|
94 | access all the engines:: | |||
|
95 | ||||
|
96 | In [1]: from IPython.kernel import client | |||
|
97 | ||||
|
98 | In [2]: mec = client.MultiEngineClient() | |||
|
99 | ||||
|
100 | In [3]: mec.get_ids() | |||
|
101 | Out[3]: [0, 1, 2, 3, 4, 5, 6, 7] | |||
|
102 | ||||
|
103 | and run trivial code in them (after importing the ``random`` module in all | |||
|
104 | engines):: | |||
|
105 | ||||
|
106 | In [11]: mec.execute("x=random.randint(0,10)") | |||
|
107 | Out[11]: | |||
|
108 | <Results List> | |||
|
109 | [0] In [3]: x=random.randint(0,10) | |||
|
110 | [1] In [3]: x=random.randint(0,10) | |||
|
111 | [2] In [3]: x=random.randint(0,10) | |||
|
112 | [3] In [3]: x=random.randint(0,10) | |||
|
113 | [4] In [3]: x=random.randint(0,10) | |||
|
114 | [5] In [3]: x=random.randint(0,10) | |||
|
115 | [6] In [3]: x=random.randint(0,10) | |||
|
116 | [7] In [3]: x=random.randint(0,10) | |||
|
117 | ||||
|
118 | In [12]: mec.pull('x') | |||
|
119 | Out[12]: [10, 0, 8, 10, 2, 9, 10, 7] | |||
|
120 | ||||
|
121 | ||||
|
122 | We'll continue conducting more complex tests later, including instaling Vision | |||
|
123 | locally and running the beam demo. | |||
|
124 | ||||
|
125 | ||||
|
126 | Michel's original instructions | |||
|
127 | ============================== | |||
|
128 | ||||
|
129 | I got a Vision network that reproduces the beam pattern demo working: | |||
|
130 | ||||
|
131 | .. image:: vision_beam_pattern.png | |||
|
132 | :width: 400 | |||
|
133 | :target: vision_beam_pattern.png | |||
|
134 | :align: center | |||
|
135 | ||||
|
136 | ||||
|
137 | I created a package called beamPattern that provides the function run() in its | |||
|
138 | __init__.py file. | |||
|
139 | ||||
|
140 | A subpackage beamPattern/VisionInterface provides Vision nodes for: | |||
|
141 | ||||
|
142 | - computing Elevation and Azimuth from a 3D vector | |||
|
143 | ||||
|
144 | - Reading .mat files | |||
|
145 | ||||
|
146 | - taking the results gathered from the engines and creating the output that a | |||
|
147 | single engine would have had produced | |||
|
148 | ||||
|
149 | The Mec node connect to a controller. In my network it was local but an furl | |||
|
150 | can be specified to connect to a remote controller. | |||
|
151 | ||||
|
152 | The PRun Func node is from the IPython library of nodes. the import statement | |||
|
153 | is used to get the run function from the beamPattern package and bu puting | |||
|
154 | "run" in the function entry of this node we push this function to the engines. | |||
|
155 | In addition to the node will create input ports for all arguments of the | |||
|
156 | function being pushed (i.e. the run function) | |||
|
157 | ||||
|
158 | The second input port on PRun Fun take an integer specifying the rank of the | |||
|
159 | argument we want to scatter. All other arguments will be pushed to the engines. | |||
|
160 | ||||
|
161 | The ElevAzim node has a 3D vector widget and computes the El And Az values | |||
|
162 | which are passed into the PRun Fun node through the ports created | |||
|
163 | automatically. The Mat node allows to select the .mat file, reads it and passed | |||
|
164 | the data to the locdata port created automatically on PRun Func | |||
|
165 | ||||
|
166 | The calculation is executed in parallel, and the results are gathered and | |||
|
167 | output. Instead of having a list of 3 vectors we nd up with a list of n*3 | |||
|
168 | vectors where n is the number of engines. unpackDectorResults will turn it into | |||
|
169 | a list of 3. We then plot x, y, and 10*log10(z) | |||
|
170 | ||||
|
171 | ||||
|
172 | Installation | |||
|
173 | ------------ | |||
|
174 | ||||
|
175 | - inflate beamPattern into the site-packages directory for the MGL tools. | |||
|
176 | ||||
|
177 | - place the appended IPythonNodes.py and StandardNodes.py into the Vision | |||
|
178 | package of the MGL tools. | |||
|
179 | ||||
|
180 | - place the appended items.py in the NetworkEditor package of the MGL tools | |||
|
181 | ||||
|
182 | - run vision for the network beamPat5_net.py:: | |||
|
183 | ||||
|
184 | vision beamPat5_net.py | |||
|
185 | ||||
|
186 | Once the network is running, you can: | |||
|
187 | ||||
|
188 | - double click on the MEC node and either use an emptty string for the furl to | |||
|
189 | connect to a local engine or cut and paste the furl to the engine you want to | |||
|
190 | use | |||
|
191 | ||||
|
192 | - click on the yellow lighting bold to run the network. | |||
|
193 | ||||
|
194 | - Try modifying the MAT file or change the Vector used top compute elevation | |||
|
195 | and Azimut. | |||
|
196 | ||||
|
197 | ||||
|
198 | Fernando's notes | |||
|
199 | ================ | |||
|
200 | ||||
|
201 | - I had to install IPython and all its dependencies for the python used by the | |||
|
202 | MGL tools. | |||
|
203 | ||||
|
204 | - Then I had to install scipy 0.6.0 for it, since the nodes needed Scipy. To | |||
|
205 | do this I sourced the mglenv.sh script and then ran:: | |||
|
206 | ||||
|
207 | python setup.py install --prefix=~/usr/opt/mgl | |||
|
208 | ||||
|
209 | ||||
|
210 | Using PBS | |||
|
211 | ========= | |||
|
212 | ||||
|
213 | The following PBS script can be used to start the engines:: | |||
|
214 | ||||
|
215 | #PBS -N bgranger-ipython | |||
|
216 | #PBS -j oe | |||
|
217 | #PBS -l walltime=00:10:00 | |||
|
218 | #PBS -l nodes=4:ppn=4 | |||
|
219 | ||||
|
220 | cd $PBS_O_WORKDIR | |||
|
221 | export PATH=$HOME/usr/local/bin | |||
|
222 | export PYTHONPATH=$HOME/usr/local/lib/python2.4/site-packages | |||
|
223 | /usr/local/bin/mpiexec -n 16 ipengine | |||
|
224 | ||||
|
225 | ||||
|
226 | If this file is called ``ipython_pbs.sh``, then the in one login windows | |||
|
227 | (i.e. on the head-node -- ``opt-login01.osc.edu``), run ``ipcontroller``. In | |||
|
228 | another login window on the same node, run the above script:: | |||
|
229 | ||||
|
230 | qsub ipython_pbs.sh | |||
|
231 | ||||
|
232 | If you look at the first window, you will see some diagnostic output | |||
|
233 | from ipcontroller. You can then get the furl from your own | |||
|
234 | ``~/.ipython/security`` directory and then connect to it remotely. | |||
|
235 | ||||
|
236 | You might need to set up an SSH tunnel, however; if this doesn't work as | |||
|
237 | advertised:: | |||
|
238 | ||||
|
239 | ssh -L 10115:localhost:10105 bic | |||
|
240 | ||||
|
241 | ||||
|
242 | Links to other resources | |||
|
243 | ======================== | |||
|
244 | ||||
|
245 | - http://www.osc.edu/~unpingco/glenn_NewLynx2_Demo.avi | |||
|
246 |
@@ -0,0 +1,426 b'' | |||||
|
1 | """Attempt to generate templates for module reference with Sphinx | |||
|
2 | ||||
|
3 | XXX - we exclude extension modules | |||
|
4 | ||||
|
5 | To include extension modules, first identify them as valid in the | |||
|
6 | ``_uri2path`` method, then handle them in the ``_parse_module`` script. | |||
|
7 | ||||
|
8 | We get functions and classes by parsing the text of .py files. | |||
|
9 | Alternatively we could import the modules for discovery, and we'd have | |||
|
10 | to do that for extension modules. This would involve changing the | |||
|
11 | ``_parse_module`` method to work via import and introspection, and | |||
|
12 | might involve changing ``discover_modules`` (which determines which | |||
|
13 | files are modules, and therefore which module URIs will be passed to | |||
|
14 | ``_parse_module``). | |||
|
15 | ||||
|
16 | NOTE: this is a modified version of a script originally shipped with the | |||
|
17 | PyMVPA project, which we've adapted for NIPY use. PyMVPA is an MIT-licensed | |||
|
18 | project.""" | |||
|
19 | ||||
|
20 | # Stdlib imports | |||
|
21 | import os | |||
|
22 | import re | |||
|
23 | ||||
|
24 | # Functions and classes | |||
|
25 | class ApiDocWriter(object): | |||
|
26 | ''' Class for automatic detection and parsing of API docs | |||
|
27 | to Sphinx-parsable reST format''' | |||
|
28 | ||||
|
29 | # only separating first two levels | |||
|
30 | rst_section_levels = ['*', '=', '-', '~', '^'] | |||
|
31 | ||||
|
32 | def __init__(self, | |||
|
33 | package_name, | |||
|
34 | rst_extension='.rst', | |||
|
35 | package_skip_patterns=None, | |||
|
36 | module_skip_patterns=None, | |||
|
37 | ): | |||
|
38 | ''' Initialize package for parsing | |||
|
39 | ||||
|
40 | Parameters | |||
|
41 | ---------- | |||
|
42 | package_name : string | |||
|
43 | Name of the top-level package. *package_name* must be the | |||
|
44 | name of an importable package | |||
|
45 | rst_extension : string, optional | |||
|
46 | Extension for reST files, default '.rst' | |||
|
47 | package_skip_patterns : None or sequence of {strings, regexps} | |||
|
48 | Sequence of strings giving URIs of packages to be excluded | |||
|
49 | Operates on the package path, starting at (including) the | |||
|
50 | first dot in the package path, after *package_name* - so, | |||
|
51 | if *package_name* is ``sphinx``, then ``sphinx.util`` will | |||
|
52 | result in ``.util`` being passed for earching by these | |||
|
53 | regexps. If is None, gives default. Default is: | |||
|
54 | ['\.tests$'] | |||
|
55 | module_skip_patterns : None or sequence | |||
|
56 | Sequence of strings giving URIs of modules to be excluded | |||
|
57 | Operates on the module name including preceding URI path, | |||
|
58 | back to the first dot after *package_name*. For example | |||
|
59 | ``sphinx.util.console`` results in the string to search of | |||
|
60 | ``.util.console`` | |||
|
61 | If is None, gives default. Default is: | |||
|
62 | ['\.setup$', '\._'] | |||
|
63 | ''' | |||
|
64 | if package_skip_patterns is None: | |||
|
65 | package_skip_patterns = ['\\.tests$'] | |||
|
66 | if module_skip_patterns is None: | |||
|
67 | module_skip_patterns = ['\\.setup$', '\\._'] | |||
|
68 | self.package_name = package_name | |||
|
69 | self.rst_extension = rst_extension | |||
|
70 | self.package_skip_patterns = package_skip_patterns | |||
|
71 | self.module_skip_patterns = module_skip_patterns | |||
|
72 | ||||
|
73 | def get_package_name(self): | |||
|
74 | return self._package_name | |||
|
75 | ||||
|
76 | def set_package_name(self, package_name): | |||
|
77 | ''' Set package_name | |||
|
78 | ||||
|
79 | >>> docwriter = ApiDocWriter('sphinx') | |||
|
80 | >>> import sphinx | |||
|
81 | >>> docwriter.root_path == sphinx.__path__[0] | |||
|
82 | True | |||
|
83 | >>> docwriter.package_name = 'docutils' | |||
|
84 | >>> import docutils | |||
|
85 | >>> docwriter.root_path == docutils.__path__[0] | |||
|
86 | True | |||
|
87 | ''' | |||
|
88 | # It's also possible to imagine caching the module parsing here | |||
|
89 | self._package_name = package_name | |||
|
90 | self.root_module = __import__(package_name) | |||
|
91 | self.root_path = self.root_module.__path__[0] | |||
|
92 | self.written_modules = None | |||
|
93 | ||||
|
94 | package_name = property(get_package_name, set_package_name, None, | |||
|
95 | 'get/set package_name') | |||
|
96 | ||||
|
97 | def _get_object_name(self, line): | |||
|
98 | ''' Get second token in line | |||
|
99 | >>> docwriter = ApiDocWriter('sphinx') | |||
|
100 | >>> docwriter._get_object_name(" def func(): ") | |||
|
101 | 'func' | |||
|
102 | >>> docwriter._get_object_name(" class Klass(object): ") | |||
|
103 | 'Klass' | |||
|
104 | >>> docwriter._get_object_name(" class Klass: ") | |||
|
105 | 'Klass' | |||
|
106 | ''' | |||
|
107 | name = line.split()[1].split('(')[0].strip() | |||
|
108 | # in case we have classes which are not derived from object | |||
|
109 | # ie. old style classes | |||
|
110 | return name.rstrip(':') | |||
|
111 | ||||
|
112 | def _uri2path(self, uri): | |||
|
113 | ''' Convert uri to absolute filepath | |||
|
114 | ||||
|
115 | Parameters | |||
|
116 | ---------- | |||
|
117 | uri : string | |||
|
118 | URI of python module to return path for | |||
|
119 | ||||
|
120 | Returns | |||
|
121 | ------- | |||
|
122 | path : None or string | |||
|
123 | Returns None if there is no valid path for this URI | |||
|
124 | Otherwise returns absolute file system path for URI | |||
|
125 | ||||
|
126 | Examples | |||
|
127 | -------- | |||
|
128 | >>> docwriter = ApiDocWriter('sphinx') | |||
|
129 | >>> import sphinx | |||
|
130 | >>> modpath = sphinx.__path__[0] | |||
|
131 | >>> res = docwriter._uri2path('sphinx.builder') | |||
|
132 | >>> res == os.path.join(modpath, 'builder.py') | |||
|
133 | True | |||
|
134 | >>> res = docwriter._uri2path('sphinx') | |||
|
135 | >>> res == os.path.join(modpath, '__init__.py') | |||
|
136 | True | |||
|
137 | >>> docwriter._uri2path('sphinx.does_not_exist') | |||
|
138 | ||||
|
139 | ''' | |||
|
140 | if uri == self.package_name: | |||
|
141 | return os.path.join(self.root_path, '__init__.py') | |||
|
142 | path = uri.replace('.', os.path.sep) | |||
|
143 | path = path.replace(self.package_name + os.path.sep, '') | |||
|
144 | path = os.path.join(self.root_path, path) | |||
|
145 | # XXX maybe check for extensions as well? | |||
|
146 | if os.path.exists(path + '.py'): # file | |||
|
147 | path += '.py' | |||
|
148 | elif os.path.exists(os.path.join(path, '__init__.py')): | |||
|
149 | path = os.path.join(path, '__init__.py') | |||
|
150 | else: | |||
|
151 | return None | |||
|
152 | return path | |||
|
153 | ||||
|
154 | def _path2uri(self, dirpath): | |||
|
155 | ''' Convert directory path to uri ''' | |||
|
156 | relpath = dirpath.replace(self.root_path, self.package_name) | |||
|
157 | if relpath.startswith(os.path.sep): | |||
|
158 | relpath = relpath[1:] | |||
|
159 | return relpath.replace(os.path.sep, '.') | |||
|
160 | ||||
|
161 | def _parse_module(self, uri): | |||
|
162 | ''' Parse module defined in *uri* ''' | |||
|
163 | filename = self._uri2path(uri) | |||
|
164 | if filename is None: | |||
|
165 | # nothing that we could handle here. | |||
|
166 | return ([],[]) | |||
|
167 | f = open(filename, 'rt') | |||
|
168 | functions, classes = self._parse_lines(f) | |||
|
169 | f.close() | |||
|
170 | return functions, classes | |||
|
171 | ||||
|
172 | def _parse_lines(self, linesource): | |||
|
173 | ''' Parse lines of text for functions and classes ''' | |||
|
174 | functions = [] | |||
|
175 | classes = [] | |||
|
176 | for line in linesource: | |||
|
177 | if line.startswith('def ') and line.count('('): | |||
|
178 | # exclude private stuff | |||
|
179 | name = self._get_object_name(line) | |||
|
180 | if not name.startswith('_'): | |||
|
181 | functions.append(name) | |||
|
182 | elif line.startswith('class '): | |||
|
183 | # exclude private stuff | |||
|
184 | name = self._get_object_name(line) | |||
|
185 | if not name.startswith('_'): | |||
|
186 | classes.append(name) | |||
|
187 | else: | |||
|
188 | pass | |||
|
189 | functions.sort() | |||
|
190 | classes.sort() | |||
|
191 | return functions, classes | |||
|
192 | ||||
|
193 | def generate_api_doc(self, uri): | |||
|
194 | '''Make autodoc documentation template string for a module | |||
|
195 | ||||
|
196 | Parameters | |||
|
197 | ---------- | |||
|
198 | uri : string | |||
|
199 | python location of module - e.g 'sphinx.builder' | |||
|
200 | ||||
|
201 | Returns | |||
|
202 | ------- | |||
|
203 | S : string | |||
|
204 | Contents of API doc | |||
|
205 | ''' | |||
|
206 | # get the names of all classes and functions | |||
|
207 | functions, classes = self._parse_module(uri) | |||
|
208 | if not len(functions) and not len(classes): | |||
|
209 | print 'WARNING: Empty -',uri # dbg | |||
|
210 | return '' | |||
|
211 | ||||
|
212 | # Make a shorter version of the uri that omits the package name for | |||
|
213 | # titles | |||
|
214 | uri_short = re.sub(r'^%s\.' % self.package_name,'',uri) | |||
|
215 | ||||
|
216 | ad = '.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n' | |||
|
217 | ||||
|
218 | chap_title = uri_short | |||
|
219 | ad += (chap_title+'\n'+ self.rst_section_levels[1] * len(chap_title) | |||
|
220 | + '\n\n') | |||
|
221 | ||||
|
222 | # Set the chapter title to read 'module' for all modules except for the | |||
|
223 | # main packages | |||
|
224 | if '.' in uri: | |||
|
225 | title = 'Module: :mod:`' + uri_short + '`' | |||
|
226 | else: | |||
|
227 | title = ':mod:`' + uri_short + '`' | |||
|
228 | ad += title + '\n' + self.rst_section_levels[2] * len(title) | |||
|
229 | ||||
|
230 | if len(classes): | |||
|
231 | ad += '\nInheritance diagram for ``%s``:\n\n' % uri | |||
|
232 | ad += '.. inheritance-diagram:: %s \n' % uri | |||
|
233 | ad += ' :parts: 3\n' | |||
|
234 | ||||
|
235 | ad += '\n.. automodule:: ' + uri + '\n' | |||
|
236 | ad += '\n.. currentmodule:: ' + uri + '\n' | |||
|
237 | multi_class = len(classes) > 1 | |||
|
238 | multi_fx = len(functions) > 1 | |||
|
239 | if multi_class: | |||
|
240 | ad += '\n' + 'Classes' + '\n' + \ | |||
|
241 | self.rst_section_levels[2] * 7 + '\n' | |||
|
242 | elif len(classes) and multi_fx: | |||
|
243 | ad += '\n' + 'Class' + '\n' + \ | |||
|
244 | self.rst_section_levels[2] * 5 + '\n' | |||
|
245 | for c in classes: | |||
|
246 | ad += '\n:class:`' + c + '`\n' \ | |||
|
247 | + self.rst_section_levels[multi_class + 2 ] * \ | |||
|
248 | (len(c)+9) + '\n\n' | |||
|
249 | ad += '\n.. autoclass:: ' + c + '\n' | |||
|
250 | # must NOT exclude from index to keep cross-refs working | |||
|
251 | ad += ' :members:\n' \ | |||
|
252 | ' :undoc-members:\n' \ | |||
|
253 | ' :show-inheritance:\n' \ | |||
|
254 | '\n' \ | |||
|
255 | ' .. automethod:: __init__\n' | |||
|
256 | if multi_fx: | |||
|
257 | ad += '\n' + 'Functions' + '\n' + \ | |||
|
258 | self.rst_section_levels[2] * 9 + '\n\n' | |||
|
259 | elif len(functions) and multi_class: | |||
|
260 | ad += '\n' + 'Function' + '\n' + \ | |||
|
261 | self.rst_section_levels[2] * 8 + '\n\n' | |||
|
262 | for f in functions: | |||
|
263 | # must NOT exclude from index to keep cross-refs working | |||
|
264 | ad += '\n.. autofunction:: ' + uri + '.' + f + '\n\n' | |||
|
265 | return ad | |||
|
266 | ||||
|
267 | def _survives_exclude(self, matchstr, match_type): | |||
|
268 | ''' Returns True if *matchstr* does not match patterns | |||
|
269 | ||||
|
270 | ``self.package_name`` removed from front of string if present | |||
|
271 | ||||
|
272 | Examples | |||
|
273 | -------- | |||
|
274 | >>> dw = ApiDocWriter('sphinx') | |||
|
275 | >>> dw._survives_exclude('sphinx.okpkg', 'package') | |||
|
276 | True | |||
|
277 | >>> dw.package_skip_patterns.append('^\\.badpkg$') | |||
|
278 | >>> dw._survives_exclude('sphinx.badpkg', 'package') | |||
|
279 | False | |||
|
280 | >>> dw._survives_exclude('sphinx.badpkg', 'module') | |||
|
281 | True | |||
|
282 | >>> dw._survives_exclude('sphinx.badmod', 'module') | |||
|
283 | True | |||
|
284 | >>> dw.module_skip_patterns.append('^\\.badmod$') | |||
|
285 | >>> dw._survives_exclude('sphinx.badmod', 'module') | |||
|
286 | False | |||
|
287 | ''' | |||
|
288 | if match_type == 'module': | |||
|
289 | patterns = self.module_skip_patterns | |||
|
290 | elif match_type == 'package': | |||
|
291 | patterns = self.package_skip_patterns | |||
|
292 | else: | |||
|
293 | raise ValueError('Cannot interpret match type "%s"' | |||
|
294 | % match_type) | |||
|
295 | # Match to URI without package name | |||
|
296 | L = len(self.package_name) | |||
|
297 | if matchstr[:L] == self.package_name: | |||
|
298 | matchstr = matchstr[L:] | |||
|
299 | for pat in patterns: | |||
|
300 | try: | |||
|
301 | pat.search | |||
|
302 | except AttributeError: | |||
|
303 | pat = re.compile(pat) | |||
|
304 | if pat.search(matchstr): | |||
|
305 | return False | |||
|
306 | return True | |||
|
307 | ||||
|
308 | def discover_modules(self): | |||
|
309 | ''' Return module sequence discovered from ``self.package_name`` | |||
|
310 | ||||
|
311 | ||||
|
312 | Parameters | |||
|
313 | ---------- | |||
|
314 | None | |||
|
315 | ||||
|
316 | Returns | |||
|
317 | ------- | |||
|
318 | mods : sequence | |||
|
319 | Sequence of module names within ``self.package_name`` | |||
|
320 | ||||
|
321 | Examples | |||
|
322 | -------- | |||
|
323 | >>> dw = ApiDocWriter('sphinx') | |||
|
324 | >>> mods = dw.discover_modules() | |||
|
325 | >>> 'sphinx.util' in mods | |||
|
326 | True | |||
|
327 | >>> dw.package_skip_patterns.append('\.util$') | |||
|
328 | >>> 'sphinx.util' in dw.discover_modules() | |||
|
329 | False | |||
|
330 | >>> | |||
|
331 | ''' | |||
|
332 | modules = [self.package_name] | |||
|
333 | # raw directory parsing | |||
|
334 | for dirpath, dirnames, filenames in os.walk(self.root_path): | |||
|
335 | # Check directory names for packages | |||
|
336 | root_uri = self._path2uri(os.path.join(self.root_path, | |||
|
337 | dirpath)) | |||
|
338 | for dirname in dirnames[:]: # copy list - we modify inplace | |||
|
339 | package_uri = '.'.join((root_uri, dirname)) | |||
|
340 | if (self._uri2path(package_uri) and | |||
|
341 | self._survives_exclude(package_uri, 'package')): | |||
|
342 | modules.append(package_uri) | |||
|
343 | else: | |||
|
344 | dirnames.remove(dirname) | |||
|
345 | # Check filenames for modules | |||
|
346 | for filename in filenames: | |||
|
347 | module_name = filename[:-3] | |||
|
348 | module_uri = '.'.join((root_uri, module_name)) | |||
|
349 | if (self._uri2path(module_uri) and | |||
|
350 | self._survives_exclude(module_uri, 'module')): | |||
|
351 | modules.append(module_uri) | |||
|
352 | return sorted(modules) | |||
|
353 | ||||
|
354 | def write_modules_api(self, modules,outdir): | |||
|
355 | # write the list | |||
|
356 | written_modules = [] | |||
|
357 | for m in modules: | |||
|
358 | api_str = self.generate_api_doc(m) | |||
|
359 | if not api_str: | |||
|
360 | continue | |||
|
361 | # write out to file | |||
|
362 | outfile = os.path.join(outdir, | |||
|
363 | m + self.rst_extension) | |||
|
364 | fileobj = open(outfile, 'wt') | |||
|
365 | fileobj.write(api_str) | |||
|
366 | fileobj.close() | |||
|
367 | written_modules.append(m) | |||
|
368 | self.written_modules = written_modules | |||
|
369 | ||||
|
370 | def write_api_docs(self, outdir): | |||
|
371 | """Generate API reST files. | |||
|
372 | ||||
|
373 | Parameters | |||
|
374 | ---------- | |||
|
375 | outdir : string | |||
|
376 | Directory name in which to store files | |||
|
377 | We create automatic filenames for each module | |||
|
378 | ||||
|
379 | Returns | |||
|
380 | ------- | |||
|
381 | None | |||
|
382 | ||||
|
383 | Notes | |||
|
384 | ----- | |||
|
385 | Sets self.written_modules to list of written modules | |||
|
386 | """ | |||
|
387 | if not os.path.exists(outdir): | |||
|
388 | os.mkdir(outdir) | |||
|
389 | # compose list of modules | |||
|
390 | modules = self.discover_modules() | |||
|
391 | self.write_modules_api(modules,outdir) | |||
|
392 | ||||
|
393 | def write_index(self, outdir, froot='gen', relative_to=None): | |||
|
394 | """Make a reST API index file from written files | |||
|
395 | ||||
|
396 | Parameters | |||
|
397 | ---------- | |||
|
398 | path : string | |||
|
399 | Filename to write index to | |||
|
400 | outdir : string | |||
|
401 | Directory to which to write generated index file | |||
|
402 | froot : string, optional | |||
|
403 | root (filename without extension) of filename to write to | |||
|
404 | Defaults to 'gen'. We add ``self.rst_extension``. | |||
|
405 | relative_to : string | |||
|
406 | path to which written filenames are relative. This | |||
|
407 | component of the written file path will be removed from | |||
|
408 | outdir, in the generated index. Default is None, meaning, | |||
|
409 | leave path as it is. | |||
|
410 | """ | |||
|
411 | if self.written_modules is None: | |||
|
412 | raise ValueError('No modules written') | |||
|
413 | # Get full filename path | |||
|
414 | path = os.path.join(outdir, froot+self.rst_extension) | |||
|
415 | # Path written into index is relative to rootpath | |||
|
416 | if relative_to is not None: | |||
|
417 | relpath = outdir.replace(relative_to + os.path.sep, '') | |||
|
418 | else: | |||
|
419 | relpath = outdir | |||
|
420 | idx = open(path,'wt') | |||
|
421 | w = idx.write | |||
|
422 | w('.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n') | |||
|
423 | w('.. toctree::\n\n') | |||
|
424 | for f in self.written_modules: | |||
|
425 | w(' %s\n' % os.path.join(relpath,f)) | |||
|
426 | idx.close() |
@@ -0,0 +1,497 b'' | |||||
|
1 | """Extract reference documentation from the NumPy source tree. | |||
|
2 | ||||
|
3 | """ | |||
|
4 | ||||
|
5 | import inspect | |||
|
6 | import textwrap | |||
|
7 | import re | |||
|
8 | import pydoc | |||
|
9 | from StringIO import StringIO | |||
|
10 | from warnings import warn | |||
|
11 | 4 | |||
|
12 | class Reader(object): | |||
|
13 | """A line-based string reader. | |||
|
14 | ||||
|
15 | """ | |||
|
16 | def __init__(self, data): | |||
|
17 | """ | |||
|
18 | Parameters | |||
|
19 | ---------- | |||
|
20 | data : str | |||
|
21 | String with lines separated by '\n'. | |||
|
22 | ||||
|
23 | """ | |||
|
24 | if isinstance(data,list): | |||
|
25 | self._str = data | |||
|
26 | else: | |||
|
27 | self._str = data.split('\n') # store string as list of lines | |||
|
28 | ||||
|
29 | self.reset() | |||
|
30 | ||||
|
31 | def __getitem__(self, n): | |||
|
32 | return self._str[n] | |||
|
33 | ||||
|
34 | def reset(self): | |||
|
35 | self._l = 0 # current line nr | |||
|
36 | ||||
|
37 | def read(self): | |||
|
38 | if not self.eof(): | |||
|
39 | out = self[self._l] | |||
|
40 | self._l += 1 | |||
|
41 | return out | |||
|
42 | else: | |||
|
43 | return '' | |||
|
44 | ||||
|
45 | def seek_next_non_empty_line(self): | |||
|
46 | for l in self[self._l:]: | |||
|
47 | if l.strip(): | |||
|
48 | break | |||
|
49 | else: | |||
|
50 | self._l += 1 | |||
|
51 | ||||
|
52 | def eof(self): | |||
|
53 | return self._l >= len(self._str) | |||
|
54 | ||||
|
55 | def read_to_condition(self, condition_func): | |||
|
56 | start = self._l | |||
|
57 | for line in self[start:]: | |||
|
58 | if condition_func(line): | |||
|
59 | return self[start:self._l] | |||
|
60 | self._l += 1 | |||
|
61 | if self.eof(): | |||
|
62 | return self[start:self._l+1] | |||
|
63 | return [] | |||
|
64 | ||||
|
65 | def read_to_next_empty_line(self): | |||
|
66 | self.seek_next_non_empty_line() | |||
|
67 | def is_empty(line): | |||
|
68 | return not line.strip() | |||
|
69 | return self.read_to_condition(is_empty) | |||
|
70 | ||||
|
71 | def read_to_next_unindented_line(self): | |||
|
72 | def is_unindented(line): | |||
|
73 | return (line.strip() and (len(line.lstrip()) == len(line))) | |||
|
74 | return self.read_to_condition(is_unindented) | |||
|
75 | ||||
|
76 | def peek(self,n=0): | |||
|
77 | if self._l + n < len(self._str): | |||
|
78 | return self[self._l + n] | |||
|
79 | else: | |||
|
80 | return '' | |||
|
81 | ||||
|
82 | def is_empty(self): | |||
|
83 | return not ''.join(self._str).strip() | |||
|
84 | ||||
|
85 | ||||
|
86 | class NumpyDocString(object): | |||
|
87 | def __init__(self,docstring): | |||
|
88 | docstring = textwrap.dedent(docstring).split('\n') | |||
|
89 | ||||
|
90 | self._doc = Reader(docstring) | |||
|
91 | self._parsed_data = { | |||
|
92 | 'Signature': '', | |||
|
93 | 'Summary': [''], | |||
|
94 | 'Extended Summary': [], | |||
|
95 | 'Parameters': [], | |||
|
96 | 'Returns': [], | |||
|
97 | 'Raises': [], | |||
|
98 | 'Warns': [], | |||
|
99 | 'Other Parameters': [], | |||
|
100 | 'Attributes': [], | |||
|
101 | 'Methods': [], | |||
|
102 | 'See Also': [], | |||
|
103 | 'Notes': [], | |||
|
104 | 'Warnings': [], | |||
|
105 | 'References': '', | |||
|
106 | 'Examples': '', | |||
|
107 | 'index': {} | |||
|
108 | } | |||
|
109 | ||||
|
110 | self._parse() | |||
|
111 | ||||
|
112 | def __getitem__(self,key): | |||
|
113 | return self._parsed_data[key] | |||
|
114 | ||||
|
115 | def __setitem__(self,key,val): | |||
|
116 | if not self._parsed_data.has_key(key): | |||
|
117 | warn("Unknown section %s" % key) | |||
|
118 | else: | |||
|
119 | self._parsed_data[key] = val | |||
|
120 | ||||
|
121 | def _is_at_section(self): | |||
|
122 | self._doc.seek_next_non_empty_line() | |||
|
123 | ||||
|
124 | if self._doc.eof(): | |||
|
125 | return False | |||
|
126 | ||||
|
127 | l1 = self._doc.peek().strip() # e.g. Parameters | |||
|
128 | ||||
|
129 | if l1.startswith('.. index::'): | |||
|
130 | return True | |||
|
131 | ||||
|
132 | l2 = self._doc.peek(1).strip() # ---------- or ========== | |||
|
133 | return l2.startswith('-'*len(l1)) or l2.startswith('='*len(l1)) | |||
|
134 | ||||
|
135 | def _strip(self,doc): | |||
|
136 | i = 0 | |||
|
137 | j = 0 | |||
|
138 | for i,line in enumerate(doc): | |||
|
139 | if line.strip(): break | |||
|
140 | ||||
|
141 | for j,line in enumerate(doc[::-1]): | |||
|
142 | if line.strip(): break | |||
|
143 | ||||
|
144 | return doc[i:len(doc)-j] | |||
|
145 | ||||
|
146 | def _read_to_next_section(self): | |||
|
147 | section = self._doc.read_to_next_empty_line() | |||
|
148 | ||||
|
149 | while not self._is_at_section() and not self._doc.eof(): | |||
|
150 | if not self._doc.peek(-1).strip(): # previous line was empty | |||
|
151 | section += [''] | |||
|
152 | ||||
|
153 | section += self._doc.read_to_next_empty_line() | |||
|
154 | ||||
|
155 | return section | |||
|
156 | ||||
|
157 | def _read_sections(self): | |||
|
158 | while not self._doc.eof(): | |||
|
159 | data = self._read_to_next_section() | |||
|
160 | name = data[0].strip() | |||
|
161 | ||||
|
162 | if name.startswith('..'): # index section | |||
|
163 | yield name, data[1:] | |||
|
164 | elif len(data) < 2: | |||
|
165 | yield StopIteration | |||
|
166 | else: | |||
|
167 | yield name, self._strip(data[2:]) | |||
|
168 | ||||
|
169 | def _parse_param_list(self,content): | |||
|
170 | r = Reader(content) | |||
|
171 | params = [] | |||
|
172 | while not r.eof(): | |||
|
173 | header = r.read().strip() | |||
|
174 | if ' : ' in header: | |||
|
175 | arg_name, arg_type = header.split(' : ')[:2] | |||
|
176 | else: | |||
|
177 | arg_name, arg_type = header, '' | |||
|
178 | ||||
|
179 | desc = r.read_to_next_unindented_line() | |||
|
180 | desc = dedent_lines(desc) | |||
|
181 | ||||
|
182 | params.append((arg_name,arg_type,desc)) | |||
|
183 | ||||
|
184 | return params | |||
|
185 | ||||
|
186 | ||||
|
187 | _name_rgx = re.compile(r"^\s*(:(?P<role>\w+):`(?P<name>[a-zA-Z0-9_.-]+)`|" | |||
|
188 | r" (?P<name2>[a-zA-Z0-9_.-]+))\s*", re.X) | |||
|
189 | def _parse_see_also(self, content): | |||
|
190 | """ | |||
|
191 | func_name : Descriptive text | |||
|
192 | continued text | |||
|
193 | another_func_name : Descriptive text | |||
|
194 | func_name1, func_name2, :meth:`func_name`, func_name3 | |||
|
195 | ||||
|
196 | """ | |||
|
197 | items = [] | |||
|
198 | ||||
|
199 | def parse_item_name(text): | |||
|
200 | """Match ':role:`name`' or 'name'""" | |||
|
201 | m = self._name_rgx.match(text) | |||
|
202 | if m: | |||
|
203 | g = m.groups() | |||
|
204 | if g[1] is None: | |||
|
205 | return g[3], None | |||
|
206 | else: | |||
|
207 | return g[2], g[1] | |||
|
208 | raise ValueError("%s is not a item name" % text) | |||
|
209 | ||||
|
210 | def push_item(name, rest): | |||
|
211 | if not name: | |||
|
212 | return | |||
|
213 | name, role = parse_item_name(name) | |||
|
214 | items.append((name, list(rest), role)) | |||
|
215 | del rest[:] | |||
|
216 | ||||
|
217 | current_func = None | |||
|
218 | rest = [] | |||
|
219 | ||||
|
220 | for line in content: | |||
|
221 | if not line.strip(): continue | |||
|
222 | ||||
|
223 | m = self._name_rgx.match(line) | |||
|
224 | if m and line[m.end():].strip().startswith(':'): | |||
|
225 | push_item(current_func, rest) | |||
|
226 | current_func, line = line[:m.end()], line[m.end():] | |||
|
227 | rest = [line.split(':', 1)[1].strip()] | |||
|
228 | if not rest[0]: | |||
|
229 | rest = [] | |||
|
230 | elif not line.startswith(' '): | |||
|
231 | push_item(current_func, rest) | |||
|
232 | current_func = None | |||
|
233 | if ',' in line: | |||
|
234 | for func in line.split(','): | |||
|
235 | push_item(func, []) | |||
|
236 | elif line.strip(): | |||
|
237 | current_func = line | |||
|
238 | elif current_func is not None: | |||
|
239 | rest.append(line.strip()) | |||
|
240 | push_item(current_func, rest) | |||
|
241 | return items | |||
|
242 | ||||
|
243 | def _parse_index(self, section, content): | |||
|
244 | """ | |||
|
245 | .. index: default | |||
|
246 | :refguide: something, else, and more | |||
|
247 | ||||
|
248 | """ | |||
|
249 | def strip_each_in(lst): | |||
|
250 | return [s.strip() for s in lst] | |||
|
251 | ||||
|
252 | out = {} | |||
|
253 | section = section.split('::') | |||
|
254 | if len(section) > 1: | |||
|
255 | out['default'] = strip_each_in(section[1].split(','))[0] | |||
|
256 | for line in content: | |||
|
257 | line = line.split(':') | |||
|
258 | if len(line) > 2: | |||
|
259 | out[line[1]] = strip_each_in(line[2].split(',')) | |||
|
260 | return out | |||
|
261 | ||||
|
262 | def _parse_summary(self): | |||
|
263 | """Grab signature (if given) and summary""" | |||
|
264 | if self._is_at_section(): | |||
|
265 | return | |||
|
266 | ||||
|
267 | summary = self._doc.read_to_next_empty_line() | |||
|
268 | summary_str = " ".join([s.strip() for s in summary]).strip() | |||
|
269 | if re.compile('^([\w., ]+=)?\s*[\w\.]+\(.*\)$').match(summary_str): | |||
|
270 | self['Signature'] = summary_str | |||
|
271 | if not self._is_at_section(): | |||
|
272 | self['Summary'] = self._doc.read_to_next_empty_line() | |||
|
273 | else: | |||
|
274 | self['Summary'] = summary | |||
|
275 | ||||
|
276 | if not self._is_at_section(): | |||
|
277 | self['Extended Summary'] = self._read_to_next_section() | |||
|
278 | ||||
|
279 | def _parse(self): | |||
|
280 | self._doc.reset() | |||
|
281 | self._parse_summary() | |||
|
282 | ||||
|
283 | for (section,content) in self._read_sections(): | |||
|
284 | if not section.startswith('..'): | |||
|
285 | section = ' '.join([s.capitalize() for s in section.split(' ')]) | |||
|
286 | if section in ('Parameters', 'Attributes', 'Methods', | |||
|
287 | 'Returns', 'Raises', 'Warns'): | |||
|
288 | self[section] = self._parse_param_list(content) | |||
|
289 | elif section.startswith('.. index::'): | |||
|
290 | self['index'] = self._parse_index(section, content) | |||
|
291 | elif section == 'See Also': | |||
|
292 | self['See Also'] = self._parse_see_also(content) | |||
|
293 | else: | |||
|
294 | self[section] = content | |||
|
295 | ||||
|
296 | # string conversion routines | |||
|
297 | ||||
|
298 | def _str_header(self, name, symbol='-'): | |||
|
299 | return [name, len(name)*symbol] | |||
|
300 | ||||
|
301 | def _str_indent(self, doc, indent=4): | |||
|
302 | out = [] | |||
|
303 | for line in doc: | |||
|
304 | out += [' '*indent + line] | |||
|
305 | return out | |||
|
306 | ||||
|
307 | def _str_signature(self): | |||
|
308 | if self['Signature']: | |||
|
309 | return [self['Signature'].replace('*','\*')] + [''] | |||
|
310 | else: | |||
|
311 | return [''] | |||
|
312 | ||||
|
313 | def _str_summary(self): | |||
|
314 | if self['Summary']: | |||
|
315 | return self['Summary'] + [''] | |||
|
316 | else: | |||
|
317 | return [] | |||
|
318 | ||||
|
319 | def _str_extended_summary(self): | |||
|
320 | if self['Extended Summary']: | |||
|
321 | return self['Extended Summary'] + [''] | |||
|
322 | else: | |||
|
323 | return [] | |||
|
324 | ||||
|
325 | def _str_param_list(self, name): | |||
|
326 | out = [] | |||
|
327 | if self[name]: | |||
|
328 | out += self._str_header(name) | |||
|
329 | for param,param_type,desc in self[name]: | |||
|
330 | out += ['%s : %s' % (param, param_type)] | |||
|
331 | out += self._str_indent(desc) | |||
|
332 | out += [''] | |||
|
333 | return out | |||
|
334 | ||||
|
335 | def _str_section(self, name): | |||
|
336 | out = [] | |||
|
337 | if self[name]: | |||
|
338 | out += self._str_header(name) | |||
|
339 | out += self[name] | |||
|
340 | out += [''] | |||
|
341 | return out | |||
|
342 | ||||
|
343 | def _str_see_also(self, func_role): | |||
|
344 | if not self['See Also']: return [] | |||
|
345 | out = [] | |||
|
346 | out += self._str_header("See Also") | |||
|
347 | last_had_desc = True | |||
|
348 | for func, desc, role in self['See Also']: | |||
|
349 | if role: | |||
|
350 | link = ':%s:`%s`' % (role, func) | |||
|
351 | elif func_role: | |||
|
352 | link = ':%s:`%s`' % (func_role, func) | |||
|
353 | else: | |||
|
354 | link = "`%s`_" % func | |||
|
355 | if desc or last_had_desc: | |||
|
356 | out += [''] | |||
|
357 | out += [link] | |||
|
358 | else: | |||
|
359 | out[-1] += ", %s" % link | |||
|
360 | if desc: | |||
|
361 | out += self._str_indent([' '.join(desc)]) | |||
|
362 | last_had_desc = True | |||
|
363 | else: | |||
|
364 | last_had_desc = False | |||
|
365 | out += [''] | |||
|
366 | return out | |||
|
367 | ||||
|
368 | def _str_index(self): | |||
|
369 | idx = self['index'] | |||
|
370 | out = [] | |||
|
371 | out += ['.. index:: %s' % idx.get('default','')] | |||
|
372 | for section, references in idx.iteritems(): | |||
|
373 | if section == 'default': | |||
|
374 | continue | |||
|
375 | out += [' :%s: %s' % (section, ', '.join(references))] | |||
|
376 | return out | |||
|
377 | ||||
|
378 | def __str__(self, func_role=''): | |||
|
379 | out = [] | |||
|
380 | out += self._str_signature() | |||
|
381 | out += self._str_summary() | |||
|
382 | out += self._str_extended_summary() | |||
|
383 | for param_list in ('Parameters','Returns','Raises'): | |||
|
384 | out += self._str_param_list(param_list) | |||
|
385 | out += self._str_section('Warnings') | |||
|
386 | out += self._str_see_also(func_role) | |||
|
387 | for s in ('Notes','References','Examples'): | |||
|
388 | out += self._str_section(s) | |||
|
389 | out += self._str_index() | |||
|
390 | return '\n'.join(out) | |||
|
391 | ||||
|
392 | ||||
|
393 | def indent(str,indent=4): | |||
|
394 | indent_str = ' '*indent | |||
|
395 | if str is None: | |||
|
396 | return indent_str | |||
|
397 | lines = str.split('\n') | |||
|
398 | return '\n'.join(indent_str + l for l in lines) | |||
|
399 | ||||
|
400 | def dedent_lines(lines): | |||
|
401 | """Deindent a list of lines maximally""" | |||
|
402 | return textwrap.dedent("\n".join(lines)).split("\n") | |||
|
403 | ||||
|
404 | def header(text, style='-'): | |||
|
405 | return text + '\n' + style*len(text) + '\n' | |||
|
406 | ||||
|
407 | ||||
|
408 | class FunctionDoc(NumpyDocString): | |||
|
409 | def __init__(self, func, role='func', doc=None): | |||
|
410 | self._f = func | |||
|
411 | self._role = role # e.g. "func" or "meth" | |||
|
412 | if doc is None: | |||
|
413 | doc = inspect.getdoc(func) or '' | |||
|
414 | try: | |||
|
415 | NumpyDocString.__init__(self, doc) | |||
|
416 | except ValueError, e: | |||
|
417 | print '*'*78 | |||
|
418 | print "ERROR: '%s' while parsing `%s`" % (e, self._f) | |||
|
419 | print '*'*78 | |||
|
420 | #print "Docstring follows:" | |||
|
421 | #print doclines | |||
|
422 | #print '='*78 | |||
|
423 | ||||
|
424 | if not self['Signature']: | |||
|
425 | func, func_name = self.get_func() | |||
|
426 | try: | |||
|
427 | # try to read signature | |||
|
428 | argspec = inspect.getargspec(func) | |||
|
429 | argspec = inspect.formatargspec(*argspec) | |||
|
430 | argspec = argspec.replace('*','\*') | |||
|
431 | signature = '%s%s' % (func_name, argspec) | |||
|
432 | except TypeError, e: | |||
|
433 | signature = '%s()' % func_name | |||
|
434 | self['Signature'] = signature | |||
|
435 | ||||
|
436 | def get_func(self): | |||
|
437 | func_name = getattr(self._f, '__name__', self.__class__.__name__) | |||
|
438 | if inspect.isclass(self._f): | |||
|
439 | func = getattr(self._f, '__call__', self._f.__init__) | |||
|
440 | else: | |||
|
441 | func = self._f | |||
|
442 | return func, func_name | |||
|
443 | ||||
|
444 | def __str__(self): | |||
|
445 | out = '' | |||
|
446 | ||||
|
447 | func, func_name = self.get_func() | |||
|
448 | signature = self['Signature'].replace('*', '\*') | |||
|
449 | ||||
|
450 | roles = {'func': 'function', | |||
|
451 | 'meth': 'method'} | |||
|
452 | ||||
|
453 | if self._role: | |||
|
454 | if not roles.has_key(self._role): | |||
|
455 | print "Warning: invalid role %s" % self._role | |||
|
456 | out += '.. %s:: %s\n \n\n' % (roles.get(self._role,''), | |||
|
457 | func_name) | |||
|
458 | ||||
|
459 | out += super(FunctionDoc, self).__str__(func_role=self._role) | |||
|
460 | return out | |||
|
461 | ||||
|
462 | ||||
|
463 | class ClassDoc(NumpyDocString): | |||
|
464 | def __init__(self,cls,modulename='',func_doc=FunctionDoc,doc=None): | |||
|
465 | if not inspect.isclass(cls): | |||
|
466 | raise ValueError("Initialise using a class. Got %r" % cls) | |||
|
467 | self._cls = cls | |||
|
468 | ||||
|
469 | if modulename and not modulename.endswith('.'): | |||
|
470 | modulename += '.' | |||
|
471 | self._mod = modulename | |||
|
472 | self._name = cls.__name__ | |||
|
473 | self._func_doc = func_doc | |||
|
474 | ||||
|
475 | if doc is None: | |||
|
476 | doc = pydoc.getdoc(cls) | |||
|
477 | ||||
|
478 | NumpyDocString.__init__(self, doc) | |||
|
479 | ||||
|
480 | @property | |||
|
481 | def methods(self): | |||
|
482 | return [name for name,func in inspect.getmembers(self._cls) | |||
|
483 | if not name.startswith('_') and callable(func)] | |||
|
484 | ||||
|
485 | def __str__(self): | |||
|
486 | out = '' | |||
|
487 | out += super(ClassDoc, self).__str__() | |||
|
488 | out += "\n\n" | |||
|
489 | ||||
|
490 | #for m in self.methods: | |||
|
491 | # print "Parsing `%s`" % m | |||
|
492 | # out += str(self._func_doc(getattr(self._cls,m), 'meth')) + '\n\n' | |||
|
493 | # out += '.. index::\n single: %s; %s\n\n' % (self._name, m) | |||
|
494 | ||||
|
495 | return out | |||
|
496 | ||||
|
497 |
@@ -0,0 +1,136 b'' | |||||
|
1 | import re, inspect, textwrap, pydoc | |||
|
2 | from docscrape import NumpyDocString, FunctionDoc, ClassDoc | |||
|
3 | ||||
|
4 | class SphinxDocString(NumpyDocString): | |||
|
5 | # string conversion routines | |||
|
6 | def _str_header(self, name, symbol='`'): | |||
|
7 | return ['.. rubric:: ' + name, ''] | |||
|
8 | ||||
|
9 | def _str_field_list(self, name): | |||
|
10 | return [':' + name + ':'] | |||
|
11 | ||||
|
12 | def _str_indent(self, doc, indent=4): | |||
|
13 | out = [] | |||
|
14 | for line in doc: | |||
|
15 | out += [' '*indent + line] | |||
|
16 | return out | |||
|
17 | ||||
|
18 | def _str_signature(self): | |||
|
19 | return [''] | |||
|
20 | if self['Signature']: | |||
|
21 | return ['``%s``' % self['Signature']] + [''] | |||
|
22 | else: | |||
|
23 | return [''] | |||
|
24 | ||||
|
25 | def _str_summary(self): | |||
|
26 | return self['Summary'] + [''] | |||
|
27 | ||||
|
28 | def _str_extended_summary(self): | |||
|
29 | return self['Extended Summary'] + [''] | |||
|
30 | ||||
|
31 | def _str_param_list(self, name): | |||
|
32 | out = [] | |||
|
33 | if self[name]: | |||
|
34 | out += self._str_field_list(name) | |||
|
35 | out += [''] | |||
|
36 | for param,param_type,desc in self[name]: | |||
|
37 | out += self._str_indent(['**%s** : %s' % (param.strip(), | |||
|
38 | param_type)]) | |||
|
39 | out += [''] | |||
|
40 | out += self._str_indent(desc,8) | |||
|
41 | out += [''] | |||
|
42 | return out | |||
|
43 | ||||
|
44 | def _str_section(self, name): | |||
|
45 | out = [] | |||
|
46 | if self[name]: | |||
|
47 | out += self._str_header(name) | |||
|
48 | out += [''] | |||
|
49 | content = textwrap.dedent("\n".join(self[name])).split("\n") | |||
|
50 | out += content | |||
|
51 | out += [''] | |||
|
52 | return out | |||
|
53 | ||||
|
54 | def _str_see_also(self, func_role): | |||
|
55 | out = [] | |||
|
56 | if self['See Also']: | |||
|
57 | see_also = super(SphinxDocString, self)._str_see_also(func_role) | |||
|
58 | out = ['.. seealso::', ''] | |||
|
59 | out += self._str_indent(see_also[2:]) | |||
|
60 | return out | |||
|
61 | ||||
|
62 | def _str_warnings(self): | |||
|
63 | out = [] | |||
|
64 | if self['Warnings']: | |||
|
65 | out = ['.. warning::', ''] | |||
|
66 | out += self._str_indent(self['Warnings']) | |||
|
67 | return out | |||
|
68 | ||||
|
69 | def _str_index(self): | |||
|
70 | idx = self['index'] | |||
|
71 | out = [] | |||
|
72 | if len(idx) == 0: | |||
|
73 | return out | |||
|
74 | ||||
|
75 | out += ['.. index:: %s' % idx.get('default','')] | |||
|
76 | for section, references in idx.iteritems(): | |||
|
77 | if section == 'default': | |||
|
78 | continue | |||
|
79 | elif section == 'refguide': | |||
|
80 | out += [' single: %s' % (', '.join(references))] | |||
|
81 | else: | |||
|
82 | out += [' %s: %s' % (section, ','.join(references))] | |||
|
83 | return out | |||
|
84 | ||||
|
85 | def _str_references(self): | |||
|
86 | out = [] | |||
|
87 | if self['References']: | |||
|
88 | out += self._str_header('References') | |||
|
89 | if isinstance(self['References'], str): | |||
|
90 | self['References'] = [self['References']] | |||
|
91 | out.extend(self['References']) | |||
|
92 | out += [''] | |||
|
93 | return out | |||
|
94 | ||||
|
95 | def __str__(self, indent=0, func_role="obj"): | |||
|
96 | out = [] | |||
|
97 | out += self._str_signature() | |||
|
98 | out += self._str_index() + [''] | |||
|
99 | out += self._str_summary() | |||
|
100 | out += self._str_extended_summary() | |||
|
101 | for param_list in ('Parameters', 'Attributes', 'Methods', | |||
|
102 | 'Returns','Raises'): | |||
|
103 | out += self._str_param_list(param_list) | |||
|
104 | out += self._str_warnings() | |||
|
105 | out += self._str_see_also(func_role) | |||
|
106 | out += self._str_section('Notes') | |||
|
107 | out += self._str_references() | |||
|
108 | out += self._str_section('Examples') | |||
|
109 | out = self._str_indent(out,indent) | |||
|
110 | return '\n'.join(out) | |||
|
111 | ||||
|
112 | class SphinxFunctionDoc(SphinxDocString, FunctionDoc): | |||
|
113 | pass | |||
|
114 | ||||
|
115 | class SphinxClassDoc(SphinxDocString, ClassDoc): | |||
|
116 | pass | |||
|
117 | ||||
|
118 | def get_doc_object(obj, what=None, doc=None): | |||
|
119 | if what is None: | |||
|
120 | if inspect.isclass(obj): | |||
|
121 | what = 'class' | |||
|
122 | elif inspect.ismodule(obj): | |||
|
123 | what = 'module' | |||
|
124 | elif callable(obj): | |||
|
125 | what = 'function' | |||
|
126 | else: | |||
|
127 | what = 'object' | |||
|
128 | if what == 'class': | |||
|
129 | return SphinxClassDoc(obj, '', func_doc=SphinxFunctionDoc, doc=doc) | |||
|
130 | elif what in ('function', 'method'): | |||
|
131 | return SphinxFunctionDoc(obj, '', doc=doc) | |||
|
132 | else: | |||
|
133 | if doc is None: | |||
|
134 | doc = pydoc.getdoc(obj) | |||
|
135 | return SphinxDocString(doc) | |||
|
136 |
@@ -0,0 +1,116 b'' | |||||
|
1 | """ | |||
|
2 | ======== | |||
|
3 | numpydoc | |||
|
4 | ======== | |||
|
5 | ||||
|
6 | Sphinx extension that handles docstrings in the Numpy standard format. [1] | |||
|
7 | ||||
|
8 | It will: | |||
|
9 | ||||
|
10 | - Convert Parameters etc. sections to field lists. | |||
|
11 | - Convert See Also section to a See also entry. | |||
|
12 | - Renumber references. | |||
|
13 | - Extract the signature from the docstring, if it can't be determined otherwise. | |||
|
14 | ||||
|
15 | .. [1] http://projects.scipy.org/scipy/numpy/wiki/CodingStyleGuidelines#docstring-standard | |||
|
16 | ||||
|
17 | """ | |||
|
18 | ||||
|
19 | import os, re, pydoc | |||
|
20 | from docscrape_sphinx import get_doc_object, SphinxDocString | |||
|
21 | import inspect | |||
|
22 | ||||
|
23 | def mangle_docstrings(app, what, name, obj, options, lines, | |||
|
24 | reference_offset=[0]): | |||
|
25 | if what == 'module': | |||
|
26 | # Strip top title | |||
|
27 | title_re = re.compile(r'^\s*[#*=]{4,}\n[a-z0-9 -]+\n[#*=]{4,}\s*', | |||
|
28 | re.I|re.S) | |||
|
29 | lines[:] = title_re.sub('', "\n".join(lines)).split("\n") | |||
|
30 | else: | |||
|
31 | doc = get_doc_object(obj, what, "\n".join(lines)) | |||
|
32 | lines[:] = str(doc).split("\n") | |||
|
33 | ||||
|
34 | if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \ | |||
|
35 | obj.__name__: | |||
|
36 | if hasattr(obj, '__module__'): | |||
|
37 | v = dict(full_name="%s.%s" % (obj.__module__, obj.__name__)) | |||
|
38 | else: | |||
|
39 | v = dict(full_name=obj.__name__) | |||
|
40 | lines += ['', '.. htmlonly::', ''] | |||
|
41 | lines += [' %s' % x for x in | |||
|
42 | (app.config.numpydoc_edit_link % v).split("\n")] | |||
|
43 | ||||
|
44 | # replace reference numbers so that there are no duplicates | |||
|
45 | references = [] | |||
|
46 | for l in lines: | |||
|
47 | l = l.strip() | |||
|
48 | if l.startswith('.. ['): | |||
|
49 | try: | |||
|
50 | references.append(int(l[len('.. ['):l.index(']')])) | |||
|
51 | except ValueError: | |||
|
52 | print "WARNING: invalid reference in %s docstring" % name | |||
|
53 | ||||
|
54 | # Start renaming from the biggest number, otherwise we may | |||
|
55 | # overwrite references. | |||
|
56 | references.sort() | |||
|
57 | if references: | |||
|
58 | for i, line in enumerate(lines): | |||
|
59 | for r in references: | |||
|
60 | new_r = reference_offset[0] + r | |||
|
61 | lines[i] = lines[i].replace('[%d]_' % r, | |||
|
62 | '[%d]_' % new_r) | |||
|
63 | lines[i] = lines[i].replace('.. [%d]' % r, | |||
|
64 | '.. [%d]' % new_r) | |||
|
65 | ||||
|
66 | reference_offset[0] += len(references) | |||
|
67 | ||||
|
68 | def mangle_signature(app, what, name, obj, options, sig, retann): | |||
|
69 | # Do not try to inspect classes that don't define `__init__` | |||
|
70 | if (inspect.isclass(obj) and | |||
|
71 | 'initializes x; see ' in pydoc.getdoc(obj.__init__)): | |||
|
72 | return '', '' | |||
|
73 | ||||
|
74 | if not (callable(obj) or hasattr(obj, '__argspec_is_invalid_')): return | |||
|
75 | if not hasattr(obj, '__doc__'): return | |||
|
76 | ||||
|
77 | doc = SphinxDocString(pydoc.getdoc(obj)) | |||
|
78 | if doc['Signature']: | |||
|
79 | sig = re.sub("^[^(]*", "", doc['Signature']) | |||
|
80 | return sig, '' | |||
|
81 | ||||
|
82 | def initialize(app): | |||
|
83 | try: | |||
|
84 | app.connect('autodoc-process-signature', mangle_signature) | |||
|
85 | except: | |||
|
86 | monkeypatch_sphinx_ext_autodoc() | |||
|
87 | ||||
|
88 | def setup(app, get_doc_object_=get_doc_object): | |||
|
89 | global get_doc_object | |||
|
90 | get_doc_object = get_doc_object_ | |||
|
91 | ||||
|
92 | app.connect('autodoc-process-docstring', mangle_docstrings) | |||
|
93 | app.connect('builder-inited', initialize) | |||
|
94 | app.add_config_value('numpydoc_edit_link', None, True) | |||
|
95 | ||||
|
96 | #------------------------------------------------------------------------------ | |||
|
97 | # Monkeypatch sphinx.ext.autodoc to accept argspecless autodocs (Sphinx < 0.5) | |||
|
98 | #------------------------------------------------------------------------------ | |||
|
99 | ||||
|
100 | def monkeypatch_sphinx_ext_autodoc(): | |||
|
101 | global _original_format_signature | |||
|
102 | import sphinx.ext.autodoc | |||
|
103 | ||||
|
104 | if sphinx.ext.autodoc.format_signature is our_format_signature: | |||
|
105 | return | |||
|
106 | ||||
|
107 | print "[numpydoc] Monkeypatching sphinx.ext.autodoc ..." | |||
|
108 | _original_format_signature = sphinx.ext.autodoc.format_signature | |||
|
109 | sphinx.ext.autodoc.format_signature = our_format_signature | |||
|
110 | ||||
|
111 | def our_format_signature(what, obj): | |||
|
112 | r = mangle_signature(None, what, None, obj, None, None, None) | |||
|
113 | if r is not None: | |||
|
114 | return r[0] | |||
|
115 | else: | |||
|
116 | return _original_format_signature(what, obj) |
@@ -0,0 +1,130 b'' | |||||
|
1 | # Simple makefile to rapidly deploy IPython with all its dependencies. | |||
|
2 | ||||
|
3 | # Configuration section. The version numbers and paths declared here may | |||
|
4 | # change with each release. | |||
|
5 | ||||
|
6 | # IPython version | |||
|
7 | IPYTHON_VER=0.9.1 | |||
|
8 | ||||
|
9 | # Declare here version numbers of all the dependencies | |||
|
10 | PYOPENSSL_VER=0.6 | |||
|
11 | ZOPE_INTERFACE_VER=3.4.1 | |||
|
12 | TWISTED_VER=8.1.0 | |||
|
13 | FOOLSCAP_VER=0.3.1 | |||
|
14 | NOSE_VER=0.10.3 | |||
|
15 | ||||
|
16 | # Repository URLs for all packages. Make sure these are correct for each | |||
|
17 | # release, since projects may change paths! | |||
|
18 | IPYTHON_REPO=http://ipython.scipy.org/dist | |||
|
19 | PYOPENSSL_REPO=http://downloads.sourceforge.net/pyopenssl | |||
|
20 | ZOPE_INTERFACE_REPO=http://pypi.python.org/packages/source/z/zope.interface | |||
|
21 | TWISTED_REPO=http://tmrc.mit.edu/mirror/twisted/Twisted/8.1 | |||
|
22 | FOOLSCAP_REPO=http://foolscap.lothar.com/releases | |||
|
23 | NOSE_REPO=http://somethingaboutorange.com/mrl/projects/nose | |||
|
24 | ||||
|
25 | #----------------------------------------------------------------------------- | |||
|
26 | # Main code begins. There shouldn't be much to change here with each release. | |||
|
27 | # | |||
|
28 | ||||
|
29 | # Hand-written files to ship in self-contained tarball | |||
|
30 | SOURCES=pkginstall pkginstall.cfg Makefile README.txt README.html | |||
|
31 | ||||
|
32 | # Versions of tarballs we ship | |||
|
33 | IPYTHON=ipython-$(IPYTHON_VER).tar.gz | |||
|
34 | IP_ALLDEPS=ipython-alldeps-$(IPYTHON_VER) | |||
|
35 | ||||
|
36 | PYOPENSSL=pyOpenSSL-$(PYOPENSSL_VER).tar.gz | |||
|
37 | ZOPE_INTERFACE=zope.interface-$(ZOPE_INTERFACE_VER).tar.gz | |||
|
38 | NOSE=nose-$(NOSE_VER).tar.gz | |||
|
39 | TWISTED=Twisted-$(TWISTED_VER).tar.bz2 | |||
|
40 | FOOLSCAP=foolscap-$(FOOLSCAP_VER).tar.gz | |||
|
41 | ||||
|
42 | TARBALLS=$(PYOPENSSL) $(ZOPE_INTERFACE) $(TWISTED) $(FOOLSCAP) \ | |||
|
43 | $(NOSE) $(IPYTHON) | |||
|
44 | ||||
|
45 | # URLs for downloads | |||
|
46 | ||||
|
47 | #----------------------------------------------------------------------------- | |||
|
48 | # Target declaration | |||
|
49 | # | |||
|
50 | ||||
|
51 | # Targets to install, in correct dependency order | |||
|
52 | install: pyopenssl zope.interface twisted foolscap nose ipython | |||
|
53 | echo | |||
|
54 | echo "IPython Installation finished." | |||
|
55 | echo "You can now run the ipython test suite by running:" | |||
|
56 | echo "iptest" | |||
|
57 | echo "If all tests pass, you can delete this entire directory." | |||
|
58 | echo | |||
|
59 | ||||
|
60 | # Download targets | |||
|
61 | download: $(TARBALLS) | |||
|
62 | ||||
|
63 | $(IPYTHON): | |||
|
64 | wget $(IPYTHON_REPO)/$(IPYTHON) | |||
|
65 | ||||
|
66 | $(PYOPENSSL): | |||
|
67 | wget $(PYOPENSSL_REPO)/$(PYOPENSSL) | |||
|
68 | ||||
|
69 | $(ZOPE_INTERFACE): | |||
|
70 | wget $(ZOPE_INTERFACE_REPO)/$(ZOPE_INTERFACE) | |||
|
71 | ||||
|
72 | $(TWISTED): | |||
|
73 | wget $(TWISTED_REPO)/$(TWISTED) | |||
|
74 | ||||
|
75 | $(FOOLSCAP): | |||
|
76 | wget $(FOOLSCAP_REPO)/$(FOOLSCAP) | |||
|
77 | ||||
|
78 | $(NOSE): | |||
|
79 | wget $(NOSE_REPO)/$(NOSE) | |||
|
80 | ||||
|
81 | ||||
|
82 | # The calls to pkginstall must use the actual Python package name | |||
|
83 | nose: $(NOSE) | |||
|
84 | ./pkginstall nose | |||
|
85 | ||||
|
86 | zope.interface: $(ZOPE_INTERFACE) | |||
|
87 | ./pkginstall zope.interface zope | |||
|
88 | ||||
|
89 | pyopenssl: $(PYOPENSSL) | |||
|
90 | ./pkginstall pyOpenSSL OpenSSL | |||
|
91 | ||||
|
92 | twisted: $(TWISTED) | |||
|
93 | ./pkginstall Twisted | |||
|
94 | ||||
|
95 | foolscap: $(FOOLSCAP) | |||
|
96 | ./pkginstall foolscap | |||
|
97 | ||||
|
98 | ipython: $(IPYTHON) | |||
|
99 | ./pkginstall ipython IPython | |||
|
100 | ||||
|
101 | # Distribution targets | |||
|
102 | dist: $(IP_ALLDEPS).tar | |||
|
103 | ||||
|
104 | $(IP_ALLDEPS).tar: download readme | |||
|
105 | -mkdir $(IP_ALLDEPS) | |||
|
106 | -ln $(SOURCES) $(TARBALLS) $(IP_ALLDEPS)/ | |||
|
107 | tar cf $(IP_ALLDEPS).tar $(IP_ALLDEPS) | |||
|
108 | rm -rf $(IP_ALLDEPS) | |||
|
109 | ||||
|
110 | readme: README.html | |||
|
111 | ||||
|
112 | README.html: README.txt | |||
|
113 | rst2html README.txt > README.html | |||
|
114 | ||||
|
115 | # Auxiliary targets | |||
|
116 | upload: dist | |||
|
117 | rsync -e ssh -av README.html $(IP_ALLDEPS).tar \ | |||
|
118 | ipython@ipython.scipy.org:www/dist/alldeps | |||
|
119 | ||||
|
120 | clean: | |||
|
121 | ls -p | grep /$ | xargs rm -rf | |||
|
122 | rm -f $(IP_ALLDEPS)* *~ | |||
|
123 | ||||
|
124 | distclean: clean | |||
|
125 | rm -f $(TARBALLS) | |||
|
126 | rm README.html | |||
|
127 | ||||
|
128 | info: | |||
|
129 | echo "TARBALLS" | |||
|
130 | echo $(TARBALLS) |
@@ -0,0 +1,109 b'' | |||||
|
1 | =========================================================== | |||
|
2 | Self-contained IPython installation with all dependencies | |||
|
3 | =========================================================== | |||
|
4 | ||||
|
5 | This is a self-contained source distribution of IPython with all its | |||
|
6 | *non-graphical* dependencies, that installs in a single ``make`` call to your | |||
|
7 | home directory (by default) or any location of your choice. | |||
|
8 | ||||
|
9 | This distribution is meant for developer-type usage in Unix environments, it is | |||
|
10 | *not* an easy way to get IPython working on Windows, since it assumes the | |||
|
11 | presence of a working compiler and development tools. | |||
|
12 | ||||
|
13 | Currently, the distribution contains:: | |||
|
14 | ||||
|
15 | ipython-0.9.1.tar.gz | |||
|
16 | pyOpenSSL-0.6.tar.gz | |||
|
17 | zope.interface-3.4.1.tar.gz | |||
|
18 | Twisted-8.1.0.tar.bz2 | |||
|
19 | foolscap-0.3.1.tar.gz | |||
|
20 | nose-0.10.3.tar.gz | |||
|
21 | ||||
|
22 | ||||
|
23 | Usage | |||
|
24 | ===== | |||
|
25 | ||||
|
26 | Download the single tarball where this README file lives and unpack it. If | |||
|
27 | your system is already configured as described below, these lines will do the | |||
|
28 | whole job:: | |||
|
29 | ||||
|
30 | wget http://ipython.scipy.org/dist/alldeps/ipython-alldeps-0.9.1.tar | |||
|
31 | tar xf ipython-alldeps-0.9.1.tar | |||
|
32 | cd ipython-alldeps-0.9.1 | |||
|
33 | make | |||
|
34 | ||||
|
35 | If all goes well, then just type:: | |||
|
36 | ||||
|
37 | iptest | |||
|
38 | ||||
|
39 | to run IPython's test suite. | |||
|
40 | ||||
|
41 | ||||
|
42 | It is meant to be used in an environment where you have your ``$PATH``, | |||
|
43 | ``$PYTHONPATH``, etc variables properly configured, so that the installation of | |||
|
44 | packages can be made with (using ``~/usr/local`` as an example):: | |||
|
45 | ||||
|
46 | python setup.py install --prefix=~/usr/local | |||
|
47 | ||||
|
48 | For an explanation of how to do this, see below. | |||
|
49 | ||||
|
50 | You can configure the default prefix used by editing the file | |||
|
51 | ``pkginstall.cfg``, where you can also override the python version used for the | |||
|
52 | process. If your system is configured in this manner, you can simply type:: | |||
|
53 | ||||
|
54 | make | |||
|
55 | ||||
|
56 | and this will build and install all of IPython's non-graphical dependencies on | |||
|
57 | your system, assuming you have Python, a compiler, the Python headers and the | |||
|
58 | SSL headers available. | |||
|
59 | ||||
|
60 | ||||
|
61 | .. _environment_configuration: | |||
|
62 | ||||
|
63 | Environment configuration | |||
|
64 | ========================= | |||
|
65 | ||||
|
66 | Below is an example of what to put in your ``~/.bashrc`` file to configure your | |||
|
67 | environment as described in this document, in a reasonably portable manner that | |||
|
68 | takes 64-bit operating systems into account:: | |||
|
69 | ||||
|
70 | # For processor dependent config | |||
|
71 | MACHINE=$(uname -m) | |||
|
72 | ||||
|
73 | # Python version information | |||
|
74 | PYVER=$(python -ESV 2>&1) | |||
|
75 | PYVER_MINOR=${PYVER#Python } | |||
|
76 | PYVER_MAJOR=${PYVER_MINOR:0:3} | |||
|
77 | ||||
|
78 | function export_paths { | |||
|
79 | # Export useful paths based on a common prefix | |||
|
80 | ||||
|
81 | # Input: a path prefix | |||
|
82 | ||||
|
83 | local prefix=$1 | |||
|
84 | local pp | |||
|
85 | local lp | |||
|
86 | local pypath=python${PYVER_MAJOR}/site-packages | |||
|
87 | ||||
|
88 | # Compute paths with 64-bit specifics | |||
|
89 | if [[ $MACHINE == "x86_64" ]]; then | |||
|
90 | lp=$prefix/lib64:$prefix/lib | |||
|
91 | pp=$prefix/lib64/$pypath:$prefix/lib/$pypath | |||
|
92 | else | |||
|
93 | lp=$prefix/lib | |||
|
94 | pp=$prefix/lib/$pypath | |||
|
95 | fi | |||
|
96 | ||||
|
97 | # Set paths based on given prefix | |||
|
98 | export PATH=$prefix/bin:$PATH | |||
|
99 | export CPATH=$prefix/include:$CPATH | |||
|
100 | export LD_LIBRARY_PATH=$lp:$LD_LIBRARY_PATH | |||
|
101 | export LIBRARY_PATH=$lp:$LIBRARY_PATH | |||
|
102 | export PYTHONPATH=$pp:$PYTHONPATH | |||
|
103 | } | |||
|
104 | ||||
|
105 | # Actually call the export function to set the paths. If you want more than | |||
|
106 | # one such prefix, note that the call *prepends* the new prefix to the | |||
|
107 | # existing paths, so later calls take priority. | |||
|
108 | ||||
|
109 | export_paths $HOME/usr/local |
@@ -0,0 +1,119 b'' | |||||
|
1 | #!/bin/bash | |||
|
2 | # | |||
|
3 | # Simple installation shell script for Python packages. | |||
|
4 | # | |||
|
5 | # Usage: | |||
|
6 | # pkginstall PAKPREFIX [PYPACKAGE] | |||
|
7 | # | |||
|
8 | # PAKPREFIX: prefix of the package as distributed in the tarball. | |||
|
9 | # | |||
|
10 | # PYPACKAGE: name of the Python package as it will end up installed. If not | |||
|
11 | # given, it defaults to PAKPREFIX. | |||
|
12 | # | |||
|
13 | ||||
|
14 | #----------------------------------------------------------------------------- | |||
|
15 | # Process command-line args | |||
|
16 | # | |||
|
17 | PAKPREFIX=$1 | |||
|
18 | PYPACKAGE=${2:-$PAKPREFIX} | |||
|
19 | ||||
|
20 | #----------------------------------------------------------------------------- | |||
|
21 | # Configure main variables | |||
|
22 | # | |||
|
23 | # Defaults for variables that the .cfg file may override. | |||
|
24 | PYTHON_DEFAULT=python | |||
|
25 | PREFIX_DEFAULT=$HOME/usr/local | |||
|
26 | ||||
|
27 | # Read config file which may declare user values for these variables. | |||
|
28 | source ./pkginstall.cfg | |||
|
29 | ||||
|
30 | # Set the variables we'll actually use, either from the config file or from our | |||
|
31 | # defaults. | |||
|
32 | PYTHON=${PYTHON-${PYTHON_DEFAULT}} | |||
|
33 | PREFIX=${PREFIX-${PREFIX_DEFAULT}} | |||
|
34 | ||||
|
35 | #----------------------------------------------------------------------------- | |||
|
36 | # 'Main' code begins | |||
|
37 | # | |||
|
38 | ||||
|
39 | # Find the actual python executable path | |||
|
40 | PYTHONX=$(which $PYTHON) | |||
|
41 | if [[ ! -x $PYTHONX ]]; then | |||
|
42 | echo "ERROR: no python executable found at given path: $PYTHON" | |||
|
43 | echo "Aborting." | |||
|
44 | exit 1 | |||
|
45 | fi | |||
|
46 | ||||
|
47 | # Python version information. PYTHONV holds a versioned string used to build | |||
|
48 | # the site-packages path for the actual Python version we'll use. | |||
|
49 | PYVER=$($PYTHONX -ESV 2>&1) | |||
|
50 | PYVER_MINOR=${PYVER#Python } | |||
|
51 | PYVER_MAJOR=${PYVER_MINOR:0:3} | |||
|
52 | PYTHONV=python${PYVER_MAJOR} | |||
|
53 | ||||
|
54 | # Set prefixes and other variables for the installation path. | |||
|
55 | SITEPKG=${PREFIX}/lib/${PYTHONV}/site-packages | |||
|
56 | SITEPKG64=${PREFIX}/lib64/${PYTHONV}/site-packages | |||
|
57 | ||||
|
58 | # User diagnostics of current config | |||
|
59 | echo "Configuration:" | |||
|
60 | echo " PYTHON : $PYTHON" | |||
|
61 | echo " PYTHONX : $PYTHONX" | |||
|
62 | echo " PREFIX : $PREFIX" | |||
|
63 | echo " SITEPKG : $SITEPKG" | |||
|
64 | echo " SITEPKG64: $SITEPKG64" | |||
|
65 | ||||
|
66 | # Find tarball | |||
|
67 | tarball=$(ls *$PAKPREFIX*.tar.*) | |||
|
68 | ||||
|
69 | if [[ -z $tarball ]]; then | |||
|
70 | echo "ERROR: tarball not found for $PYPACKAGE" | |||
|
71 | exit 1 | |||
|
72 | fi | |||
|
73 | ||||
|
74 | # Figure out the name of the directory and compression format to use to unpack | |||
|
75 | pakdir=$(echo $tarball | awk -F '.tar.' '{print $1}') | |||
|
76 | tarfmt=$(echo $tarball | awk -F '.tar.' '{print $2}') | |||
|
77 | ||||
|
78 | if [[ $tarfmt == "gz" ]]; then | |||
|
79 | tarflag="z" | |||
|
80 | else | |||
|
81 | tarflag="j" | |||
|
82 | fi | |||
|
83 | ||||
|
84 | # Unpack the tarball if needed | |||
|
85 | if [[ ! -d $pakdir ]]; then | |||
|
86 | echo "Unpacking tarball: $tarball" | |||
|
87 | tar -x -${tarflag} -f $tarball | |||
|
88 | ||||
|
89 | if [[ ! -d $pakdir ]]; then | |||
|
90 | echo "Tarball $tarball unpacked to unexpected path, aborting" | |||
|
91 | exit 1 | |||
|
92 | fi | |||
|
93 | fi | |||
|
94 | ||||
|
95 | # Remove existing ${PYPACKAGE} to make sure the build doesn't pick up spurious | |||
|
96 | # things. We don't touch the bin/ dir or anything else because it's hard to | |||
|
97 | # know what goes there in advance. But this should prevent most serious | |||
|
98 | # problems. | |||
|
99 | rm -rf $SITEPKG/${PYPACKAGE} | |||
|
100 | rm -rf $SITEPKG/${PYPACKAGE}*.egg | |||
|
101 | rm -rf $SITEPKG/${PYPACKAGE}*.egg-info | |||
|
102 | ||||
|
103 | rm -rf $SITEPKG64/${PYPACKAGE} | |||
|
104 | rm -rf $SITEPKG64/${PYPACKAGE}*.egg | |||
|
105 | rm -rf $SITEPKG64/${PYPACKAGE}*.egg-info | |||
|
106 | ||||
|
107 | # Make/install phase | |||
|
108 | ||||
|
109 | # Set python search path correctly | |||
|
110 | export PYTHONPATH=$SITEPKG:$SITEPKG64:$PYTHONPATH | |||
|
111 | ||||
|
112 | # Ensure install dirs exist | |||
|
113 | mkdir -p $SITEPKG | |||
|
114 | mkdir -p $SITEPKG64 | |||
|
115 | ||||
|
116 | cd ${pakdir} | |||
|
117 | rm -rf build dist | |||
|
118 | $PYTHONX setup.py clean | |||
|
119 | time $PYTHONX setup.py install --prefix=$PREFIX |
@@ -0,0 +1,27 b'' | |||||
|
1 | # -*- sh -*- | |||
|
2 | # | |||
|
3 | # Configuration for the pkginstall script. | |||
|
4 | # This script uses bash syntax, as it will be sourced by a bash script. | |||
|
5 | ||||
|
6 | # Uncomment and set the variables you want, otherwise pkginstall has sensible | |||
|
7 | # defaults predefined. These can also be declared either as environment | |||
|
8 | # variables (which can be done by the makefile calling this script). | |||
|
9 | ||||
|
10 | #----------------------------------------------------------------------------- | |||
|
11 | # | |||
|
12 | # Executable for Python. | |||
|
13 | # | |||
|
14 | # You can set this to an explicit full path if you don't want the default | |||
|
15 | # (simply 'python') to be the version used to install this package. | |||
|
16 | ||||
|
17 | #PYTHON=python | |||
|
18 | ||||
|
19 | #----------------------------------------------------------------------------- | |||
|
20 | # | |||
|
21 | # Default prefix. | |||
|
22 | # | |||
|
23 | # This should be a valid input the setup.py script as the --prefix argument. | |||
|
24 | # That is, your $PYTHONPATH should contain $PREFIX/lib/pythonX.Y/site-packages, | |||
|
25 | # your $PATH should contain $PREFIX/bin, etc. | |||
|
26 | ||||
|
27 | #PREFIX=$HOME/usr/local |
@@ -1,7 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """Tools for coloring text in ANSI terminals. |
|
2 | """Tools for coloring text in ANSI terminals. | |
3 |
|
3 | """ | ||
4 | $Id: ColorANSI.py 2167 2007-03-21 06:57:50Z fperez $""" |
|
|||
5 |
|
4 | |||
6 | #***************************************************************************** |
|
5 | #***************************************************************************** | |
7 | # Copyright (C) 2002-2006 Fernando Perez. <fperez@colorado.edu> |
|
6 | # Copyright (C) 2002-2006 Fernando Perez. <fperez@colorado.edu> | |
@@ -10,10 +9,6 b' $Id: ColorANSI.py 2167 2007-03-21 06:57:50Z fperez $"""' | |||||
10 | # the file COPYING, distributed as part of this software. |
|
9 | # the file COPYING, distributed as part of this software. | |
11 | #***************************************************************************** |
|
10 | #***************************************************************************** | |
12 |
|
11 | |||
13 | from IPython import Release |
|
|||
14 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
15 | __license__ = Release.license |
|
|||
16 |
|
||||
17 | __all__ = ['TermColors','InputTermColors','ColorScheme','ColorSchemeTable'] |
|
12 | __all__ = ['TermColors','InputTermColors','ColorScheme','ColorSchemeTable'] | |
18 |
|
13 | |||
19 | import os |
|
14 | import os |
@@ -1,7 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """Configuration loader |
|
2 | """Configuration loader | |
3 |
|
3 | """ | ||
4 | $Id: ConfigLoader.py 1005 2006-01-12 08:39:26Z fperez $""" |
|
|||
5 |
|
4 | |||
6 | #***************************************************************************** |
|
5 | #***************************************************************************** | |
7 | # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu> |
|
6 | # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu> | |
@@ -10,10 +9,6 b' $Id: ConfigLoader.py 1005 2006-01-12 08:39:26Z fperez $"""' | |||||
10 | # the file COPYING, distributed as part of this software. |
|
9 | # the file COPYING, distributed as part of this software. | |
11 | #***************************************************************************** |
|
10 | #***************************************************************************** | |
12 |
|
11 | |||
13 | from IPython import Release |
|
|||
14 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
15 | __license__ = Release.license |
|
|||
16 |
|
||||
17 | import exceptions |
|
12 | import exceptions | |
18 | import os |
|
13 | import os | |
19 | from pprint import pprint |
|
14 | from pprint import pprint | |
@@ -73,14 +68,14 b' class ConfigLoader:' | |||||
73 | # avoid including the same file more than once |
|
68 | # avoid including the same file more than once | |
74 | if fname in self.included: |
|
69 | if fname in self.included: | |
75 | return data |
|
70 | return data | |
76 | Xinfo = ultraTB.AutoFormattedTB() |
|
71 | Xinfo = ultraTB.AutoFormattedTB(color_scheme='NoColor') | |
77 | if convert==None and recurse_key : convert = {qwflat:recurse_key} |
|
72 | if convert==None and recurse_key : convert = {qwflat:recurse_key} | |
78 | # for production, change warn to 0: |
|
73 | # for production, change warn to 0: | |
79 | data.merge(read_dict(fname,convert,fs=self.field_sep,strip=1, |
|
74 | data.merge(read_dict(fname,convert,fs=self.field_sep,strip=1, | |
80 | warn=0,no_empty=0,**kw)) |
|
75 | warn=0,no_empty=0,**kw)) | |
81 | # keep track of successfully loaded files |
|
76 | # keep track of successfully loaded files | |
82 | self.included.append(fname) |
|
77 | self.included.append(fname) | |
83 |
if recurse_key in data |
|
78 | if recurse_key in data: | |
84 | for incfilename in data[recurse_key]: |
|
79 | for incfilename in data[recurse_key]: | |
85 | found=0 |
|
80 | found=0 | |
86 | try: |
|
81 | try: |
@@ -1,20 +1,20 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """sys.excepthook for IPython itself, leaves a detailed report on disk. |
|
2 | """sys.excepthook for IPython itself, leaves a detailed report on disk. | |
3 |
|
3 | |||
4 | $Id: CrashHandler.py 2908 2007-12-30 21:07:46Z vivainio $""" |
|
4 | ||
|
5 | Authors | |||
|
6 | ------- | |||
|
7 | - Fernando Perez <Fernando.Perez@berkeley.edu> | |||
|
8 | """ | |||
5 |
|
9 | |||
6 | #***************************************************************************** |
|
10 | #***************************************************************************** | |
7 | # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu> |
|
11 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
12 | # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu> | |||
8 | # |
|
13 | # | |
9 | # Distributed under the terms of the BSD License. The full license is in |
|
14 | # Distributed under the terms of the BSD License. The full license is in | |
10 | # the file COPYING, distributed as part of this software. |
|
15 | # the file COPYING, distributed as part of this software. | |
11 | #***************************************************************************** |
|
16 | #***************************************************************************** | |
12 |
|
17 | |||
13 | from IPython import Release |
|
|||
14 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
15 | __license__ = Release.license |
|
|||
16 | __version__ = Release.version |
|
|||
17 |
|
||||
18 | #**************************************************************************** |
|
18 | #**************************************************************************** | |
19 | # Required modules |
|
19 | # Required modules | |
20 |
|
20 | |||
@@ -23,10 +23,12 b' import os' | |||||
23 | import sys |
|
23 | import sys | |
24 | from pprint import pprint,pformat |
|
24 | from pprint import pprint,pformat | |
25 |
|
25 | |||
26 | # Homebrewed |
|
26 | # Our own | |
27 |
from IPython |
|
27 | from IPython import Release | |
28 | from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names |
|
|||
29 | from IPython import ultraTB |
|
28 | from IPython import ultraTB | |
|
29 | from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names | |||
|
30 | from IPython.Itpl import Itpl,itpl,printpl | |||
|
31 | ||||
30 | from IPython.genutils import * |
|
32 | from IPython.genutils import * | |
31 |
|
33 | |||
32 | #**************************************************************************** |
|
34 | #**************************************************************************** | |
@@ -166,7 +168,7 b' $self.bug_tracker' | |||||
166 |
|
168 | |||
167 | rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n') |
|
169 | rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n') | |
168 | rpt_add('IPython version: %s \n\n' % Release.version) |
|
170 | rpt_add('IPython version: %s \n\n' % Release.version) | |
169 |
rpt_add(' |
|
171 | rpt_add('BZR revision : %s \n\n' % Release.revision) | |
170 | rpt_add('Platform info : os.name -> %s, sys.platform -> %s' % |
|
172 | rpt_add('Platform info : os.name -> %s, sys.platform -> %s' % | |
171 | (os.name,sys.platform) ) |
|
173 | (os.name,sys.platform) ) | |
172 | rpt_add(sec_sep+'Current user configuration structure:\n\n') |
|
174 | rpt_add(sec_sep+'Current user configuration structure:\n\n') | |
@@ -193,7 +195,7 b' class IPythonCrashHandler(CrashHandler):' | |||||
193 |
|
195 | |||
194 | # Set argument defaults |
|
196 | # Set argument defaults | |
195 | app_name = 'IPython' |
|
197 | app_name = 'IPython' | |
196 |
bug_tracker = 'http |
|
198 | bug_tracker = 'https://bugs.launchpad.net/ipython/+filebug' | |
197 | contact_name,contact_email = Release.authors[AUTHOR_CONTACT][:2] |
|
199 | contact_name,contact_email = Release.authors[AUTHOR_CONTACT][:2] | |
198 | crash_report_fname = 'IPython_crash_report.txt' |
|
200 | crash_report_fname = 'IPython_crash_report.txt' | |
199 | # Call parent constructor |
|
201 | # Call parent constructor | |
@@ -210,7 +212,7 b' class IPythonCrashHandler(CrashHandler):' | |||||
210 |
|
212 | |||
211 | rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n') |
|
213 | rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n') | |
212 | rpt_add('IPython version: %s \n\n' % Release.version) |
|
214 | rpt_add('IPython version: %s \n\n' % Release.version) | |
213 |
rpt_add(' |
|
215 | rpt_add('BZR revision : %s \n\n' % Release.revision) | |
214 | rpt_add('Platform info : os.name -> %s, sys.platform -> %s' % |
|
216 | rpt_add('Platform info : os.name -> %s, sys.platform -> %s' % | |
215 | (os.name,sys.platform) ) |
|
217 | (os.name,sys.platform) ) | |
216 | rpt_add(sec_sep+'Current user configuration structure:\n\n') |
|
218 | rpt_add(sec_sep+'Current user configuration structure:\n\n') |
@@ -1,8 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """DPyGetOpt -- Demiurge Python GetOptions Module |
|
2 | """DPyGetOpt -- Demiurge Python GetOptions Module | |
3 |
|
3 | |||
4 | $Id: DPyGetOpt.py 2872 2007-11-25 17:58:05Z fperez $ |
|
|||
5 |
|
||||
6 | This module is modeled after perl's Getopt::Long module-- which |
|
4 | This module is modeled after perl's Getopt::Long module-- which | |
7 | is, in turn, modeled after GNU's extended getopt() function. |
|
5 | is, in turn, modeled after GNU's extended getopt() function. | |
8 |
|
6 | |||
@@ -32,8 +30,7 b" characters; ie-- 'foo|bar|baz=f@' specifies that all -foo, -bar," | |||||
32 | and -baz options that appear on within the parsed argument list |
|
30 | and -baz options that appear on within the parsed argument list | |
33 | must have a real number argument and that the accumulated list |
|
31 | must have a real number argument and that the accumulated list | |
34 | of values will be available under the name 'foo' |
|
32 | of values will be available under the name 'foo' | |
35 |
|
33 | """ | ||
36 | $Id: DPyGetOpt.py 2872 2007-11-25 17:58:05Z fperez $""" |
|
|||
37 |
|
34 | |||
38 | #***************************************************************************** |
|
35 | #***************************************************************************** | |
39 | # |
|
36 | # |
@@ -13,9 +13,7 b' The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor' | |||||
13 | changes. Licensing should therefore be under the standard Python terms. For |
|
13 | changes. Licensing should therefore be under the standard Python terms. For | |
14 | details on the PSF (Python Software Foundation) standard license, see: |
|
14 | details on the PSF (Python Software Foundation) standard license, see: | |
15 |
|
15 | |||
16 | http://www.python.org/2.2.3/license.html |
|
16 | http://www.python.org/2.2.3/license.html""" | |
17 |
|
||||
18 | $Id: Debugger.py 2913 2007-12-31 12:42:14Z vivainio $""" |
|
|||
19 |
|
17 | |||
20 | #***************************************************************************** |
|
18 | #***************************************************************************** | |
21 | # |
|
19 | # | |
@@ -27,10 +25,6 b' $Id: Debugger.py 2913 2007-12-31 12:42:14Z vivainio $"""' | |||||
27 | # |
|
25 | # | |
28 | #***************************************************************************** |
|
26 | #***************************************************************************** | |
29 |
|
27 | |||
30 | from IPython import Release |
|
|||
31 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
32 | __license__ = 'Python' |
|
|||
33 |
|
||||
34 | import bdb |
|
28 | import bdb | |
35 | import cmd |
|
29 | import cmd | |
36 | import linecache |
|
30 | import linecache | |
@@ -39,7 +33,7 b' import sys' | |||||
39 |
|
33 | |||
40 | from IPython import PyColorize, ColorANSI, ipapi |
|
34 | from IPython import PyColorize, ColorANSI, ipapi | |
41 | from IPython.genutils import Term |
|
35 | from IPython.genutils import Term | |
42 |
from IPython.excolors import |
|
36 | from IPython.excolors import exception_colors | |
43 |
|
37 | |||
44 | # See if we can use pydb. |
|
38 | # See if we can use pydb. | |
45 | has_pydb = False |
|
39 | has_pydb = False | |
@@ -210,7 +204,7 b' class Pdb(OldPdb):' | |||||
210 |
|
204 | |||
211 | # Create color table: we copy the default one from the traceback |
|
205 | # Create color table: we copy the default one from the traceback | |
212 | # module and add a few attributes needed for debugging |
|
206 | # module and add a few attributes needed for debugging | |
213 |
self.color_scheme_table = |
|
207 | self.color_scheme_table = exception_colors() | |
214 |
|
208 | |||
215 | # shorthands |
|
209 | # shorthands | |
216 | C = ColorANSI.TermColors |
|
210 | C = ColorANSI.TermColors | |
@@ -257,8 +251,7 b' class Pdb(OldPdb):' | |||||
257 |
|
251 | |||
258 | # Create color table: we copy the default one from the traceback |
|
252 | # Create color table: we copy the default one from the traceback | |
259 | # module and add a few attributes needed for debugging |
|
253 | # module and add a few attributes needed for debugging | |
260 | ExceptionColors.set_active_scheme(color_scheme) |
|
254 | self.color_scheme_table = exception_colors() | |
261 | self.color_scheme_table = ExceptionColors.copy() |
|
|||
262 |
|
255 | |||
263 | # shorthands |
|
256 | # shorthands | |
264 | C = ColorANSI.TermColors |
|
257 | C = ColorANSI.TermColors |
@@ -4,8 +4,7 b'' | |||||
4 | We define a special input line filter to allow typing lines which begin with |
|
4 | We define a special input line filter to allow typing lines which begin with | |
5 | '~', '/' or '.'. If one of those strings is encountered, it is automatically |
|
5 | '~', '/' or '.'. If one of those strings is encountered, it is automatically | |
6 | executed. |
|
6 | executed. | |
7 |
|
7 | """ | ||
8 | $Id: InterpreterExec.py 2724 2007-09-07 08:05:38Z fperez $""" |
|
|||
9 |
|
8 | |||
10 | #***************************************************************************** |
|
9 | #***************************************************************************** | |
11 | # Copyright (C) 2004 W.J. van der Laan <gnufnork@hetdigitalegat.nl> |
|
10 | # Copyright (C) 2004 W.J. van der Laan <gnufnork@hetdigitalegat.nl> | |
@@ -15,11 +14,6 b' $Id: InterpreterExec.py 2724 2007-09-07 08:05:38Z fperez $"""' | |||||
15 | # the file COPYING, distributed as part of this software. |
|
14 | # the file COPYING, distributed as part of this software. | |
16 | #***************************************************************************** |
|
15 | #***************************************************************************** | |
17 |
|
16 | |||
18 | from IPython import Release |
|
|||
19 | __author__ = 'W.J. van der Laan <gnufnork@hetdigitalegat.nl>, '\ |
|
|||
20 | '%s <%s>' % Release.authors['Fernando'] |
|
|||
21 | __license__ = Release.license |
|
|||
22 |
|
||||
23 | # TODO: deprecated |
|
17 | # TODO: deprecated | |
24 | def prefilter_shell(self,line,continuation): |
|
18 | def prefilter_shell(self,line,continuation): | |
25 | """Alternate prefilter, modified for shell-like functionality. |
|
19 | """Alternate prefilter, modified for shell-like functionality. |
@@ -48,19 +48,21 b' In [4]: >>> for i in range(len(a)):' | |||||
48 | 2 a |
|
48 | 2 a | |
49 | 3 little |
|
49 | 3 little | |
50 | 4 lamb |
|
50 | 4 lamb | |
|
51 | ||||
|
52 | ||||
|
53 | Authors | |||
|
54 | ------- | |||
|
55 | - Fernando Perez <Fernando.Perez@berkeley.edu> | |||
51 | """ |
|
56 | """ | |
52 |
|
57 | |||
53 | #***************************************************************************** |
|
58 | #***************************************************************************** | |
54 | # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu> |
|
59 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
60 | # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu> | |||
55 | # |
|
61 | # | |
56 | # Distributed under the terms of the BSD License. The full license is in |
|
62 | # Distributed under the terms of the BSD License. The full license is in | |
57 | # the file COPYING, distributed as part of this software. |
|
63 | # the file COPYING, distributed as part of this software. | |
58 | #***************************************************************************** |
|
64 | #***************************************************************************** | |
59 |
|
65 | |||
60 | from IPython import Release |
|
|||
61 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
62 | __license__ = Release.license |
|
|||
63 |
|
||||
64 | # This file is an example of how to modify IPython's line-processing behavior |
|
66 | # This file is an example of how to modify IPython's line-processing behavior | |
65 | # without touching the internal code. We'll define an alternate pre-processing |
|
67 | # without touching the internal code. We'll define an alternate pre-processing | |
66 | # stage which allows a special form of input (which is invalid Python syntax) |
|
68 | # stage which allows a special form of input (which is invalid Python syntax) |
@@ -12,18 +12,19 b' g = 9.8 m/s**2' | |||||
12 | a = 2.3 m/s^2 # ^ -> ** automatically |
|
12 | a = 2.3 m/s^2 # ^ -> ** automatically | |
13 |
|
13 | |||
14 | All other input is processed normally. |
|
14 | All other input is processed normally. | |
|
15 | ||||
|
16 | Authors | |||
|
17 | ------- | |||
|
18 | - Fernando Perez <Fernando.Perez@berkeley.edu> | |||
15 | """ |
|
19 | """ | |
16 | #***************************************************************************** |
|
20 | #***************************************************************************** | |
17 | # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu> |
|
21 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
22 | # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu> | |||
18 | # |
|
23 | # | |
19 | # Distributed under the terms of the BSD License. The full license is in |
|
24 | # Distributed under the terms of the BSD License. The full license is in | |
20 | # the file COPYING, distributed as part of this software. |
|
25 | # the file COPYING, distributed as part of this software. | |
21 | #***************************************************************************** |
|
26 | #***************************************************************************** | |
22 |
|
27 | |||
23 | from IPython import Release |
|
|||
24 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
25 | __license__ = Release.license |
|
|||
26 |
|
||||
27 | # This file is an example of how to modify IPython's line-processing behavior |
|
28 | # This file is an example of how to modify IPython's line-processing behavior | |
28 | # without touching the internal code. We'll define an alternate pre-processing |
|
29 | # without touching the internal code. We'll define an alternate pre-processing | |
29 | # stage which allows a special form of input (which is invalid Python syntax) |
|
30 | # stage which allows a special form of input (which is invalid Python syntax) |
@@ -6,19 +6,21 b' special method syntax. This just means moving them out to the global' | |||||
6 | namespace. |
|
6 | namespace. | |
7 |
|
7 | |||
8 | This module should always be loaded *after* math or Numeric, so it can |
|
8 | This module should always be loaded *after* math or Numeric, so it can | |
9 |
overwrite math functions with the versions that handle units. |
|
9 | overwrite math functions with the versions that handle units. | |
|
10 | ||||
|
11 | Authors | |||
|
12 | ------- | |||
|
13 | - Fernando Perez <Fernando.Perez@berkeley.edu> | |||
|
14 | """ | |||
10 |
|
15 | |||
11 | #***************************************************************************** |
|
16 | #***************************************************************************** | |
12 | # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu> |
|
17 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
18 | # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu> | |||
13 | # |
|
19 | # | |
14 | # Distributed under the terms of the BSD License. The full license is in |
|
20 | # Distributed under the terms of the BSD License. The full license is in | |
15 | # the file COPYING, distributed as part of this software. |
|
21 | # the file COPYING, distributed as part of this software. | |
16 | #***************************************************************************** |
|
22 | #***************************************************************************** | |
17 |
|
23 | |||
18 | from IPython import Release |
|
|||
19 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
20 | __license__ = Release.license |
|
|||
21 |
|
||||
22 | from Scientific.Physics.PhysicalQuantities import PhysicalQuantity |
|
24 | from Scientific.Physics.PhysicalQuantities import PhysicalQuantity | |
23 |
|
25 | |||
24 | # This code can be set up to work with Numeric or with math for providing the |
|
26 | # This code can be set up to work with Numeric or with math for providing the |
@@ -5,43 +5,65 b' import IPython.ipapi' | |||||
5 | import gc |
|
5 | import gc | |
6 | ip = IPython.ipapi.get() |
|
6 | ip = IPython.ipapi.get() | |
7 |
|
7 | |||
8 |
|
||||
9 | def clear_f(self,arg): |
|
8 | def clear_f(self,arg): | |
10 | """ Clear various data (e.g. stored history data) |
|
9 | """ Clear various data (e.g. stored history data) | |
11 |
|
10 | |||
12 | %clear out - clear output history |
|
|||
13 | %clear in - clear input history |
|
11 | %clear in - clear input history | |
|
12 | %clear out - clear output history | |||
14 | %clear shadow_compress - Compresses shadow history (to speed up ipython) |
|
13 | %clear shadow_compress - Compresses shadow history (to speed up ipython) | |
15 | %clear shadow_nuke - permanently erase all entries in shadow history |
|
14 | %clear shadow_nuke - permanently erase all entries in shadow history | |
16 | %clear dhist - clear dir history |
|
15 | %clear dhist - clear dir history | |
|
16 | %clear array - clear only variables that are NumPy arrays | |||
|
17 | ||||
|
18 | Examples: | |||
|
19 | ||||
|
20 | In [1]: clear in | |||
|
21 | Flushing input history | |||
|
22 | ||||
|
23 | In [2]: clear shadow_compress | |||
|
24 | Compressing shadow history | |||
|
25 | ||||
|
26 | In [3]: clear shadow_nuke | |||
|
27 | Erased all keys from shadow history | |||
|
28 | ||||
|
29 | In [4]: clear dhist | |||
|
30 | Clearing directory history | |||
17 | """ |
|
31 | """ | |
18 |
|
32 | |||
19 | api = self.getapi() |
|
33 | api = self.getapi() | |
|
34 | user_ns = self.user_ns # local lookup, heavily used | |||
|
35 | ||||
|
36 | ||||
20 | for target in arg.split(): |
|
37 | for target in arg.split(): | |
|
38 | ||||
21 | if target == 'out': |
|
39 | if target == 'out': | |
22 |
print "Flushing output cache (%d entries)" % len( |
|
40 | print "Flushing output cache (%d entries)" % len(user_ns['_oh']) | |
23 | self.outputcache.flush() |
|
41 | self.outputcache.flush() | |
|
42 | ||||
24 | elif target == 'in': |
|
43 | elif target == 'in': | |
25 | print "Flushing input history" |
|
44 | print "Flushing input history" | |
26 | from IPython import iplib |
|
|||
27 | pc = self.outputcache.prompt_count + 1 |
|
45 | pc = self.outputcache.prompt_count + 1 | |
28 | for n in range(1, pc): |
|
46 | for n in range(1, pc): | |
29 | key = '_i'+`n` |
|
47 | key = '_i'+`n` | |
|
48 | user_ns.pop(key,None) | |||
30 | try: |
|
49 | try: | |
31 |
del |
|
50 | del user_ns[key] | |
32 | except: pass |
|
51 | except: pass | |
33 | # must be done in-place |
|
52 | # must be done in-place | |
34 | self.input_hist[:] = ['\n'] * pc |
|
53 | self.input_hist[:] = ['\n'] * pc | |
35 | self.input_hist_raw[:] = ['\n'] * pc |
|
54 | self.input_hist_raw[:] = ['\n'] * pc | |
|
55 | ||||
36 | elif target == 'array': |
|
56 | elif target == 'array': | |
|
57 | # Support cleaning up numpy arrays | |||
37 | try: |
|
58 | try: | |
38 | pylab=ip.IP.pylab |
|
59 | from numpy import ndarray | |
39 | for x in self.user_ns.keys(): |
|
60 | # This must be done with items and not iteritems because we're | |
40 | if isinstance(self.user_ns[x],pylab.arraytype): |
|
61 | # going to modify the dict in-place. | |
41 | del self.user_ns[x] |
|
62 | for x,val in user_ns.items(): | |
|
63 | if isinstance(val,ndarray): | |||
|
64 | del user_ns[x] | |||
42 | except AttributeError: |
|
65 | except AttributeError: | |
43 |
print "Clear array only |
|
66 | print "Clear array only works if Numpy is available." | |
44 | gc.collect() |
|
|||
45 |
|
67 | |||
46 | elif target == 'shadow_compress': |
|
68 | elif target == 'shadow_compress': | |
47 | print "Compressing shadow history" |
|
69 | print "Compressing shadow history" | |
@@ -51,16 +73,15 b' def clear_f(self,arg):' | |||||
51 | print "Erased all keys from shadow history " |
|
73 | print "Erased all keys from shadow history " | |
52 | for k in ip.db.keys('shadowhist/*'): |
|
74 | for k in ip.db.keys('shadowhist/*'): | |
53 | del ip.db[k] |
|
75 | del ip.db[k] | |
|
76 | ||||
54 | elif target == 'dhist': |
|
77 | elif target == 'dhist': | |
55 | print "Clearing directory history" |
|
78 | print "Clearing directory history" | |
56 |
del |
|
79 | del user_ns['_dh'][:] | |
57 |
|
80 | |||
58 |
|
81 | gc.collect() | ||
|
82 | ||||
|
83 | # Activate the extension | |||
59 | ip.expose_magic("clear",clear_f) |
|
84 | ip.expose_magic("clear",clear_f) | |
60 | import ipy_completers |
|
85 | import ipy_completers | |
61 | ipy_completers.quick_completer( |
|
86 | ipy_completers.quick_completer( | |
62 | '%clear','in out shadow_nuke shadow_compress dhist') |
|
87 | '%clear','in out shadow_nuke shadow_compress dhist') | |
63 |
|
||||
64 |
|
||||
65 |
|
||||
66 |
|
@@ -6,9 +6,6 b' Provides' | |||||
6 | var = %magic blah blah |
|
6 | var = %magic blah blah | |
7 |
|
7 | |||
8 | var = !ls |
|
8 | var = !ls | |
9 |
|
||||
10 | $Id: genutils.py 1077 2006-01-24 18:15:27Z vivainio $ |
|
|||
11 |
|
||||
12 | """ |
|
9 | """ | |
13 |
|
10 | |||
14 | import IPython.ipapi |
|
11 | import IPython.ipapi |
@@ -1,19 +1,22 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | # |
|
2 | """ An ipython profile for zope and plone. | |
|
3 | ||||
|
4 | Some ideas stolen from http://www.tomster.org. | |||
|
5 | ||||
|
6 | ||||
|
7 | Authors | |||
|
8 | ------- | |||
|
9 | - Stefan Eletzhofer <stefan.eletzhofer@inquant.de> | |||
|
10 | """ | |||
|
11 | ||||
3 | # File: ipy_profile_zope.py |
|
12 | # File: ipy_profile_zope.py | |
4 | # |
|
13 | # | |
5 | # Copyright (c) InQuant GmbH |
|
14 | # Copyright (c) InQuant GmbH | |
6 | # |
|
15 | # | |
7 | # An ipython profile for zope and plone. Some ideas |
|
|||
8 | # stolen from http://www.tomster.org. |
|
|||
9 | # |
|
16 | # | |
10 | # Distributed under the terms of the BSD License. The full license is in |
|
17 | # Distributed under the terms of the BSD License. The full license is in | |
11 | # the file COPYING, distributed as part of this software. |
|
18 | # the file COPYING, distributed as part of this software. | |
12 |
|
19 | |||
13 | __author__ = """Stefan Eletzhofer <stefan.eletzhofer@inquant.de>""" |
|
|||
14 | __docformat__ = 'plaintext' |
|
|||
15 | __revision__ = "$Revision$" |
|
|||
16 |
|
||||
17 | from IPython import ipapi |
|
20 | from IPython import ipapi | |
18 | from IPython import Release |
|
21 | from IPython import Release | |
19 | from types import StringType |
|
22 | from types import StringType |
@@ -7,6 +7,16 b' Usage:' | |||||
7 |
|
7 | |||
8 | %wdb pass |
|
8 | %wdb pass | |
9 | Change the password (e.g. if you have forgotten the old one) |
|
9 | Change the password (e.g. if you have forgotten the old one) | |
|
10 | ||||
|
11 | ||||
|
12 | Notes | |||
|
13 | ----- | |||
|
14 | ||||
|
15 | **WARNING**: As of March 2009 (IPython 0.10), WinPdb has a known bug, which | |||
|
16 | causes PyTables to become impossible to import if winpdb is loaded. Therefore, | |||
|
17 | if you need PyTables, do *not* use this extension. | |||
|
18 | ||||
|
19 | For more details: https://bugs.launchpad.net/ipython/+bug/249036 | |||
10 | """ |
|
20 | """ | |
11 |
|
21 | |||
12 | import os |
|
22 | import os |
@@ -40,8 +40,6 b' import UserDict' | |||||
40 | import warnings |
|
40 | import warnings | |
41 | import glob |
|
41 | import glob | |
42 |
|
42 | |||
43 | from sets import Set as set |
|
|||
44 |
|
||||
45 | def gethashfile(key): |
|
43 | def gethashfile(key): | |
46 | return ("%02x" % abs(hash(key) % 256))[-2:] |
|
44 | return ("%02x" % abs(hash(key) % 256))[-2:] | |
47 |
|
45 |
@@ -3,8 +3,6 b'' | |||||
3 | %store magic for lightweight persistence. |
|
3 | %store magic for lightweight persistence. | |
4 |
|
4 | |||
5 | Stores variables, aliases etc. in PickleShare database. |
|
5 | Stores variables, aliases etc. in PickleShare database. | |
6 |
|
||||
7 | $Id: iplib.py 1107 2006-01-30 19:02:20Z vivainio $ |
|
|||
8 | """ |
|
6 | """ | |
9 |
|
7 | |||
10 | import IPython.ipapi |
|
8 | import IPython.ipapi |
@@ -4,8 +4,7 b' Class which mimics a module.' | |||||
4 |
|
4 | |||
5 | Needed to allow pickle to correctly resolve namespaces during IPython |
|
5 | Needed to allow pickle to correctly resolve namespaces during IPython | |
6 | sessions. |
|
6 | sessions. | |
7 |
|
7 | """ | ||
8 | $Id: FakeModule.py 2754 2007-09-09 10:16:59Z fperez $""" |
|
|||
9 |
|
8 | |||
10 | #***************************************************************************** |
|
9 | #***************************************************************************** | |
11 | # Copyright (C) 2002-2004 Fernando Perez. <fperez@colorado.edu> |
|
10 | # Copyright (C) 2002-2004 Fernando Perez. <fperez@colorado.edu> |
@@ -12,8 +12,7 b' This module is meant to be used as a drop-in replacement to the original' | |||||
12 | Gnuplot, so it should be safe to do: |
|
12 | Gnuplot, so it should be safe to do: | |
13 |
|
13 | |||
14 | import IPython.Gnuplot2 as Gnuplot |
|
14 | import IPython.Gnuplot2 as Gnuplot | |
15 |
|
15 | """ | ||
16 | $Id: Gnuplot2.py 1210 2006-03-13 01:19:31Z fperez $""" |
|
|||
17 |
|
16 | |||
18 | import cStringIO |
|
17 | import cStringIO | |
19 | import os |
|
18 | import os |
@@ -9,8 +9,7 b' http://gnuplot-py.sourceforge.net/' | |||||
9 | See gphelp() below for details on the services offered by this module. |
|
9 | See gphelp() below for details on the services offered by this module. | |
10 |
|
10 | |||
11 | Inspired by a suggestion/request from Arnd Baecker. |
|
11 | Inspired by a suggestion/request from Arnd Baecker. | |
12 |
|
12 | """ | ||
13 | $Id: GnuplotInteractive.py 389 2004-10-09 07:59:30Z fperez $""" |
|
|||
14 |
|
13 | |||
15 | __all__ = ['Gnuplot','gp','gp_new','plot','plot2','splot','replot', |
|
14 | __all__ = ['Gnuplot','gp','gp_new','plot','plot2','splot','replot', | |
16 | 'hardcopy','gpdata','gpfile','gpstring','gpfunc','gpgrid', |
|
15 | 'hardcopy','gpdata','gpfile','gpstring','gpfunc','gpgrid', |
@@ -47,8 +47,7 b' can be downloaded from:' | |||||
47 | http://gnuplot-py.sourceforge.net/ |
|
47 | http://gnuplot-py.sourceforge.net/ | |
48 |
|
48 | |||
49 | Inspired by a suggestion/request from Arnd Baecker. |
|
49 | Inspired by a suggestion/request from Arnd Baecker. | |
50 |
|
50 | """ | ||
51 | $Id: GnuplotRuntime.py 389 2004-10-09 07:59:30Z fperez $""" |
|
|||
52 |
|
51 | |||
53 | __all__ = ['Gnuplot','gp','gp_new','Data','File','Func','GridData', |
|
52 | __all__ = ['Gnuplot','gp','gp_new','Data','File','Func','GridData', | |
54 | 'pm3d_config','eps_fix_bbox'] |
|
53 | 'pm3d_config','eps_fix_bbox'] |
@@ -27,7 +27,7 b' how to do interpolation:' | |||||
27 | import Itpl |
|
27 | import Itpl | |
28 | sys.stdout = Itpl.filter() |
|
28 | sys.stdout = Itpl.filter() | |
29 | f = "fancy" |
|
29 | f = "fancy" | |
30 |
print "Is |
|
30 | print "Is this not $f?" | |
31 | print "Standard output has been replaced with a $sys.stdout object." |
|
31 | print "Standard output has been replaced with a $sys.stdout object." | |
32 | sys.stdout = Itpl.unfilter() |
|
32 | sys.stdout = Itpl.unfilter() | |
33 | print "Okay, back $to $normal." |
|
33 | print "Okay, back $to $normal." | |
@@ -43,9 +43,7 b' each time the instance is evaluated with str(instance). For example:' | |||||
43 | print str(s) |
|
43 | print str(s) | |
44 | foo = "bar" |
|
44 | foo = "bar" | |
45 | print str(s) |
|
45 | print str(s) | |
46 |
|
46 | """ | ||
47 | $Id: Itpl.py 2918 2007-12-31 14:34:47Z vivainio $ |
|
|||
48 | """ # ' -> close an open quote for stupid emacs |
|
|||
49 |
|
47 | |||
50 | #***************************************************************************** |
|
48 | #***************************************************************************** | |
51 | # |
|
49 | # |
@@ -1,8 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """ |
|
2 | """ | |
3 | Logger class for IPython's logging facilities. |
|
3 | Logger class for IPython's logging facilities. | |
4 |
|
||||
5 | $Id: Logger.py 2875 2007-11-26 08:37:39Z fperez $ |
|
|||
6 | """ |
|
4 | """ | |
7 |
|
5 | |||
8 | #***************************************************************************** |
|
6 | #***************************************************************************** | |
@@ -16,11 +14,6 b' $Id: Logger.py 2875 2007-11-26 08:37:39Z fperez $' | |||||
16 | #**************************************************************************** |
|
14 | #**************************************************************************** | |
17 | # Modules and globals |
|
15 | # Modules and globals | |
18 |
|
16 | |||
19 | from IPython import Release |
|
|||
20 | __author__ = '%s <%s>\n%s <%s>' % \ |
|
|||
21 | ( Release.authors['Janko'] + Release.authors['Fernando'] ) |
|
|||
22 | __license__ = Release.license |
|
|||
23 |
|
||||
24 | # Python standard modules |
|
17 | # Python standard modules | |
25 | import glob |
|
18 | import glob | |
26 | import os |
|
19 | import os |
@@ -1,7 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """Magic functions for InteractiveShell. |
|
2 | """Magic functions for InteractiveShell. | |
3 |
|
3 | """ | ||
4 | $Id: Magic.py 2996 2008-01-30 06:31:39Z fperez $""" |
|
|||
5 |
|
4 | |||
6 | #***************************************************************************** |
|
5 | #***************************************************************************** | |
7 | # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and |
|
6 | # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and | |
@@ -14,11 +13,6 b' $Id: Magic.py 2996 2008-01-30 06:31:39Z fperez $"""' | |||||
14 | #**************************************************************************** |
|
13 | #**************************************************************************** | |
15 | # Modules and globals |
|
14 | # Modules and globals | |
16 |
|
15 | |||
17 | from IPython import Release |
|
|||
18 | __author__ = '%s <%s>\n%s <%s>' % \ |
|
|||
19 | ( Release.authors['Janko'] + Release.authors['Fernando'] ) |
|
|||
20 | __license__ = Release.license |
|
|||
21 |
|
||||
22 | # Python standard modules |
|
16 | # Python standard modules | |
23 | import __builtin__ |
|
17 | import __builtin__ | |
24 | import bdb |
|
18 | import bdb | |
@@ -35,7 +29,6 b' import textwrap' | |||||
35 | from cStringIO import StringIO |
|
29 | from cStringIO import StringIO | |
36 | from getopt import getopt,GetoptError |
|
30 | from getopt import getopt,GetoptError | |
37 | from pprint import pprint, pformat |
|
31 | from pprint import pprint, pformat | |
38 | from sets import Set |
|
|||
39 |
|
32 | |||
40 | # cProfile was added in Python2.5 |
|
33 | # cProfile was added in Python2.5 | |
41 | try: |
|
34 | try: | |
@@ -75,7 +68,7 b' def compress_dhist(dh):' | |||||
75 | head, tail = dh[:-10], dh[-10:] |
|
68 | head, tail = dh[:-10], dh[-10:] | |
76 |
|
69 | |||
77 | newhead = [] |
|
70 | newhead = [] | |
78 |
done = |
|
71 | done = set() | |
79 | for h in head: |
|
72 | for h in head: | |
80 | if h in done: |
|
73 | if h in done: | |
81 | continue |
|
74 | continue | |
@@ -149,7 +142,7 b' python-profiler package from non-free.""")' | |||||
149 | filter(inst_magic,self.__dict__.keys()) + \ |
|
142 | filter(inst_magic,self.__dict__.keys()) + \ | |
150 | filter(inst_bound_magic,self.__class__.__dict__.keys()) |
|
143 | filter(inst_bound_magic,self.__class__.__dict__.keys()) | |
151 | out = [] |
|
144 | out = [] | |
152 |
for fn in |
|
145 | for fn in set(magics): | |
153 | out.append(fn.replace('magic_','',1)) |
|
146 | out.append(fn.replace('magic_','',1)) | |
154 | out.sort() |
|
147 | out.sort() | |
155 | return out |
|
148 | return out | |
@@ -1054,10 +1047,33 b' Currently the magic system has the following functions:\\n"""' | |||||
1054 | def magic_reset(self, parameter_s=''): |
|
1047 | def magic_reset(self, parameter_s=''): | |
1055 | """Resets the namespace by removing all names defined by the user. |
|
1048 | """Resets the namespace by removing all names defined by the user. | |
1056 |
|
1049 | |||
1057 |
Input/Output history are left around in case you need them. |
|
1050 | Input/Output history are left around in case you need them. | |
|
1051 | ||||
|
1052 | Parameters | |||
|
1053 | ---------- | |||
|
1054 | -y : force reset without asking for confirmation. | |||
|
1055 | ||||
|
1056 | Examples | |||
|
1057 | -------- | |||
|
1058 | In [6]: a = 1 | |||
|
1059 | ||||
|
1060 | In [7]: a | |||
|
1061 | Out[7]: 1 | |||
|
1062 | ||||
|
1063 | In [8]: 'a' in _ip.user_ns | |||
|
1064 | Out[8]: True | |||
1058 |
|
|
1065 | ||
1059 | ans = self.shell.ask_yes_no( |
|
1066 | In [9]: %reset -f | |
1060 | "Once deleted, variables cannot be recovered. Proceed (y/[n])? ") |
|
1067 | ||
|
1068 | In [10]: 'a' in _ip.user_ns | |||
|
1069 | Out[10]: False | |||
|
1070 | """ | |||
|
1071 | ||||
|
1072 | if parameter_s == '-f': | |||
|
1073 | ans = True | |||
|
1074 | else: | |||
|
1075 | ans = self.shell.ask_yes_no( | |||
|
1076 | "Once deleted, variables cannot be recovered. Proceed (y/[n])? ") | |||
1061 | if not ans: |
|
1077 | if not ans: | |
1062 | print 'Nothing done.' |
|
1078 | print 'Nothing done.' | |
1063 | return |
|
1079 | return | |
@@ -1067,7 +1083,7 b' Currently the magic system has the following functions:\\n"""' | |||||
1067 |
|
1083 | |||
1068 | # Also flush the private list of module references kept for script |
|
1084 | # Also flush the private list of module references kept for script | |
1069 | # execution protection |
|
1085 | # execution protection | |
1070 |
self.shell. |
|
1086 | self.shell.clear_main_mod_cache() | |
1071 |
|
1087 | |||
1072 | def magic_logstart(self,parameter_s=''): |
|
1088 | def magic_logstart(self,parameter_s=''): | |
1073 | """Start logging anywhere in a session. |
|
1089 | """Start logging anywhere in a session. | |
@@ -1426,7 +1442,8 b' Currently the magic system has the following functions:\\n"""' | |||||
1426 | return None |
|
1442 | return None | |
1427 |
|
1443 | |||
1428 | @testdec.skip_doctest |
|
1444 | @testdec.skip_doctest | |
1429 |
def magic_run(self, parameter_s ='',runner=None |
|
1445 | def magic_run(self, parameter_s ='',runner=None, | |
|
1446 | file_finder=get_py_filename): | |||
1430 | """Run the named file inside IPython as a program. |
|
1447 | """Run the named file inside IPython as a program. | |
1431 |
|
1448 | |||
1432 | Usage:\\ |
|
1449 | Usage:\\ | |
@@ -1541,7 +1558,7 b' Currently the magic system has the following functions:\\n"""' | |||||
1541 | mode='list',list_all=1) |
|
1558 | mode='list',list_all=1) | |
1542 |
|
1559 | |||
1543 | try: |
|
1560 | try: | |
1544 |
filename = |
|
1561 | filename = file_finder(arg_lst[0]) | |
1545 | except IndexError: |
|
1562 | except IndexError: | |
1546 | warn('you must provide at least a filename.') |
|
1563 | warn('you must provide at least a filename.') | |
1547 | print '\n%run:\n',OInspect.getdoc(self.magic_run) |
|
1564 | print '\n%run:\n',OInspect.getdoc(self.magic_run) | |
@@ -1577,10 +1594,13 b' Currently the magic system has the following functions:\\n"""' | |||||
1577 | main_mod = FakeModule() |
|
1594 | main_mod = FakeModule() | |
1578 | prog_ns = main_mod.__dict__ |
|
1595 | prog_ns = main_mod.__dict__ | |
1579 | prog_ns['__name__'] = name |
|
1596 | prog_ns['__name__'] = name | |
|
1597 | ||||
1580 | # The shell MUST hold a reference to main_mod so after %run exits, |
|
1598 | # The shell MUST hold a reference to main_mod so after %run exits, | |
1581 | # the python deletion mechanism doesn't zero it out (leaving |
|
1599 | # the python deletion mechanism doesn't zero it out (leaving | |
1582 | # dangling references) |
|
1600 | # dangling references). However, we should drop old versions of | |
1583 | self.shell._user_main_modules.append(main_mod) |
|
1601 | # main_mod. There is now a proper API to manage this caching in | |
|
1602 | # the main shell object, we use that. | |||
|
1603 | self.shell.cache_main_mod(main_mod) | |||
1584 |
|
1604 | |||
1585 | # Since '%run foo' emulates 'python foo.py' at the cmd line, we must |
|
1605 | # Since '%run foo' emulates 'python foo.py' at the cmd line, we must | |
1586 | # set the __file__ global in the script's namespace |
|
1606 | # set the __file__ global in the script's namespace |
@@ -5,8 +5,6 b' Uses syntax highlighting for presenting the various information elements.' | |||||
5 |
|
5 | |||
6 | Similar in spirit to the inspect module, but all calls take a name argument to |
|
6 | Similar in spirit to the inspect module, but all calls take a name argument to | |
7 | reference the name under which an object is being read. |
|
7 | reference the name under which an object is being read. | |
8 |
|
||||
9 | $Id: OInspect.py 2843 2007-10-15 21:22:32Z fperez $ |
|
|||
10 | """ |
|
8 | """ | |
11 |
|
9 | |||
12 | #***************************************************************************** |
|
10 | #***************************************************************************** | |
@@ -16,10 +14,6 b' $Id: OInspect.py 2843 2007-10-15 21:22:32Z fperez $' | |||||
16 | # the file COPYING, distributed as part of this software. |
|
14 | # the file COPYING, distributed as part of this software. | |
17 | #***************************************************************************** |
|
15 | #***************************************************************************** | |
18 |
|
16 | |||
19 | from IPython import Release |
|
|||
20 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
21 | __license__ = Release.license |
|
|||
22 |
|
||||
23 | __all__ = ['Inspector','InspectColors'] |
|
17 | __all__ = ['Inspector','InspectColors'] | |
24 |
|
18 | |||
25 | # stdlib modules |
|
19 | # stdlib modules |
@@ -1,7 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """Class to trap stdout and stderr and log them separately. |
|
2 | """Class to trap stdout and stderr and log them separately. | |
3 |
|
3 | """ | ||
4 | $Id: OutputTrap.py 958 2005-12-27 23:17:51Z fperez $""" |
|
|||
5 |
|
4 | |||
6 | #***************************************************************************** |
|
5 | #***************************************************************************** | |
7 | # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu> |
|
6 | # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu> | |
@@ -10,10 +9,6 b' $Id: OutputTrap.py 958 2005-12-27 23:17:51Z fperez $"""' | |||||
10 | # the file COPYING, distributed as part of this software. |
|
9 | # the file COPYING, distributed as part of this software. | |
11 | #***************************************************************************** |
|
10 | #***************************************************************************** | |
12 |
|
11 | |||
13 | from IPython import Release |
|
|||
14 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
15 | __license__ = Release.license |
|
|||
16 |
|
||||
17 | import exceptions |
|
12 | import exceptions | |
18 | import sys |
|
13 | import sys | |
19 | from cStringIO import StringIO |
|
14 | from cStringIO import StringIO |
@@ -1,21 +1,16 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """ |
|
2 | """ | |
3 | Classes for handling input/output prompts. |
|
3 | Classes for handling input/output prompts. | |
4 |
|
4 | """ | ||
5 | $Id: Prompts.py 3026 2008-02-07 16:03:16Z vivainio $""" |
|
|||
6 |
|
5 | |||
7 | #***************************************************************************** |
|
6 | #***************************************************************************** | |
8 | # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu> |
|
7 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
8 | # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu> | |||
9 | # |
|
9 | # | |
10 | # Distributed under the terms of the BSD License. The full license is in |
|
10 | # Distributed under the terms of the BSD License. The full license is in | |
11 | # the file COPYING, distributed as part of this software. |
|
11 | # the file COPYING, distributed as part of this software. | |
12 | #***************************************************************************** |
|
12 | #***************************************************************************** | |
13 |
|
13 | |||
14 | from IPython import Release |
|
|||
15 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
16 | __license__ = Release.license |
|
|||
17 | __version__ = Release.version |
|
|||
18 |
|
||||
19 | #**************************************************************************** |
|
14 | #**************************************************************************** | |
20 | # Required modules |
|
15 | # Required modules | |
21 | import __builtin__ |
|
16 | import __builtin__ | |
@@ -26,11 +21,13 b' import time' | |||||
26 |
|
21 | |||
27 | # IPython's own |
|
22 | # IPython's own | |
28 | from IPython import ColorANSI |
|
23 | from IPython import ColorANSI | |
29 |
from IPython |
|
24 | from IPython import Release | |
|
25 | from IPython.external.Itpl import ItplNS | |||
|
26 | from IPython.ipapi import TryNext | |||
30 | from IPython.ipstruct import Struct |
|
27 | from IPython.ipstruct import Struct | |
31 | from IPython.macro import Macro |
|
28 | from IPython.macro import Macro | |
|
29 | ||||
32 | from IPython.genutils import * |
|
30 | from IPython.genutils import * | |
33 | from IPython.ipapi import TryNext |
|
|||
34 |
|
31 | |||
35 | #**************************************************************************** |
|
32 | #**************************************************************************** | |
36 | #Color schemes for Prompts. |
|
33 | #Color schemes for Prompts. | |
@@ -168,7 +165,7 b' prompt_specials_color = {' | |||||
168 | # Carriage return |
|
165 | # Carriage return | |
169 | r'\r': '\r', |
|
166 | r'\r': '\r', | |
170 | # Release version |
|
167 | # Release version | |
171 |
r'\v': |
|
168 | r'\v': Release.version, | |
172 | # Root symbol ($ or #) |
|
169 | # Root symbol ($ or #) | |
173 | r'\$': ROOT_SYMBOL, |
|
170 | r'\$': ROOT_SYMBOL, | |
174 | } |
|
171 | } |
@@ -1,34 +1,33 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """ |
|
2 | """ | |
3 |
|
|
3 | Class and program to colorize python source code for ANSI terminals. | |
4 |
|
4 | |||
5 |
|
|
5 | Based on an HTML code highlighter by Jurgen Hermann found at: | |
6 |
|
|
6 | http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298 | |
7 |
|
7 | |||
8 |
|
|
8 | Modifications by Fernando Perez (fperez@colorado.edu). | |
9 |
|
9 | |||
10 |
|
|
10 | Information on the original HTML highlighter follows: | |
11 |
|
||||
12 | MoinMoin - Python Source Parser |
|
|||
13 |
|
11 | |||
14 | Title: Colorize Python source using the built-in tokenizer |
|
12 | MoinMoin - Python Source Parser | |
15 |
|
||||
16 | Submitter: Jurgen Hermann |
|
|||
17 | Last Updated:2001/04/06 |
|
|||
18 |
|
||||
19 | Version no:1.2 |
|
|||
20 |
|
13 | |||
21 | Description: |
|
14 | Title: Colorize Python source using the built-in tokenizer | |
22 |
|
15 | |||
23 | This code is part of MoinMoin (http://moin.sourceforge.net/) and converts |
|
16 | Submitter: Jurgen Hermann | |
24 | Python source code to HTML markup, rendering comments, keywords, |
|
17 | Last Updated:2001/04/06 | |
25 | operators, numeric and string literals in different colors. |
|
|||
26 |
|
18 | |||
27 | It shows how to use the built-in keyword, token and tokenize modules to |
|
19 | Version no:1.2 | |
28 | scan Python source code and re-emit it with no changes to its original |
|
|||
29 | formatting (which is the hard part). |
|
|||
30 |
|
20 | |||
31 | $Id: PyColorize.py 2586 2007-08-06 19:30:09Z vivainio $""" |
|
21 | Description: | |
|
22 | ||||
|
23 | This code is part of MoinMoin (http://moin.sourceforge.net/) and converts | |||
|
24 | Python source code to HTML markup, rendering comments, keywords, | |||
|
25 | operators, numeric and string literals in different colors. | |||
|
26 | ||||
|
27 | It shows how to use the built-in keyword, token and tokenize modules to | |||
|
28 | scan Python source code and re-emit it with no changes to its original | |||
|
29 | formatting (which is the hard part). | |||
|
30 | """ | |||
32 |
|
31 | |||
33 | __all__ = ['ANSICodeColors','Parser'] |
|
32 | __all__ = ['ANSICodeColors','Parser'] | |
34 |
|
33 |
@@ -3,8 +3,7 b'' | |||||
3 |
|
3 | |||
4 | All the matplotlib support code was co-developed with John Hunter, |
|
4 | All the matplotlib support code was co-developed with John Hunter, | |
5 | matplotlib's author. |
|
5 | matplotlib's author. | |
6 |
|
6 | """ | ||
7 | $Id: Shell.py 3024 2008-02-07 15:34:42Z darren.dale $""" |
|
|||
8 |
|
7 | |||
9 | #***************************************************************************** |
|
8 | #***************************************************************************** | |
10 | # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu> |
|
9 | # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu> | |
@@ -13,10 +12,6 b' $Id: Shell.py 3024 2008-02-07 15:34:42Z darren.dale $"""' | |||||
13 | # the file COPYING, distributed as part of this software. |
|
12 | # the file COPYING, distributed as part of this software. | |
14 | #***************************************************************************** |
|
13 | #***************************************************************************** | |
15 |
|
14 | |||
16 | from IPython import Release |
|
|||
17 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
18 | __license__ = Release.license |
|
|||
19 |
|
||||
20 | # Code begins |
|
15 | # Code begins | |
21 | # Stdlib imports |
|
16 | # Stdlib imports | |
22 | import __builtin__ |
|
17 | import __builtin__ |
@@ -1,5 +1,4 b'' | |||||
1 | # -*- Mode: Shell-Script -*- Not really, but shows comments correctly |
|
1 | # -*- Mode: Shell-Script -*- Not really, but shows comments correctly | |
2 | # $Id: ipythonrc 2156 2007-03-19 02:32:19Z fperez $ |
|
|||
3 |
|
2 | |||
4 | #*************************************************************************** |
|
3 | #*************************************************************************** | |
5 | # |
|
4 | # |
@@ -25,12 +25,12 b' IPython tries to:' | |||||
25 |
|
25 | |||
26 | iii - serve as an embeddable, ready to go interpreter for your own programs. |
|
26 | iii - serve as an embeddable, ready to go interpreter for your own programs. | |
27 |
|
27 | |||
28 |
IPython requires Python 2. |
|
28 | IPython requires Python 2.4 or newer. | |
29 |
|
29 | """ | ||
30 | $Id: __init__.py 2399 2007-05-26 10:23:10Z vivainio $""" |
|
|||
31 |
|
30 | |||
32 | #***************************************************************************** |
|
31 | #***************************************************************************** | |
33 | # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu> |
|
32 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
33 | # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu> | |||
34 | # |
|
34 | # | |
35 | # Distributed under the terms of the BSD License. The full license is in |
|
35 | # Distributed under the terms of the BSD License. The full license is in | |
36 | # the file COPYING, distributed as part of this software. |
|
36 | # the file COPYING, distributed as part of this software. |
@@ -17,8 +17,6 b' http://folk.uio.no/hpl/scripting' | |||||
17 |
|
17 | |||
18 | (although ultimately no code from this text was used, as IPython's system is a |
|
18 | (although ultimately no code from this text was used, as IPython's system is a | |
19 | separate implementation). |
|
19 | separate implementation). | |
20 |
|
||||
21 | $Id: background_jobs.py 994 2006-01-08 08:29:44Z fperez $ |
|
|||
22 | """ |
|
20 | """ | |
23 |
|
21 | |||
24 | #***************************************************************************** |
|
22 | #***************************************************************************** | |
@@ -28,10 +26,6 b' $Id: background_jobs.py 994 2006-01-08 08:29:44Z fperez $' | |||||
28 | # the file COPYING, distributed as part of this software. |
|
26 | # the file COPYING, distributed as part of this software. | |
29 | #***************************************************************************** |
|
27 | #***************************************************************************** | |
30 |
|
28 | |||
31 | from IPython import Release |
|
|||
32 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
33 | __license__ = Release.license |
|
|||
34 |
|
||||
35 | # Code begins |
|
29 | # Code begins | |
36 | import sys |
|
30 | import sys | |
37 | import threading |
|
31 | import threading |
@@ -6,7 +6,6 b' upstream and were accepted as of Python 2.3, but we need a lot more' | |||||
6 | functionality specific to IPython, so this module will continue to live as an |
|
6 | functionality specific to IPython, so this module will continue to live as an | |
7 | IPython-specific utility. |
|
7 | IPython-specific utility. | |
8 |
|
8 | |||
9 | --------------------------------------------------------------------------- |
|
|||
10 | Original rlcompleter documentation: |
|
9 | Original rlcompleter documentation: | |
11 |
|
10 | |||
12 | This requires the latest extension to the readline module (the |
|
11 | This requires the latest extension to the readline module (the |
@@ -12,8 +12,7 b' Alternatively, you can add a dreload builtin alongside normal reload with:' | |||||
12 | >>> __builtin__.dreload = deep_reload.reload |
|
12 | >>> __builtin__.dreload = deep_reload.reload | |
13 |
|
13 | |||
14 | This code is almost entirely based on knee.py from the standard library. |
|
14 | This code is almost entirely based on knee.py from the standard library. | |
15 |
|
15 | """ | ||
16 | $Id: deep_reload.py 958 2005-12-27 23:17:51Z fperez $""" |
|
|||
17 |
|
16 | |||
18 | #***************************************************************************** |
|
17 | #***************************************************************************** | |
19 | # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu> |
|
18 | # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu> | |
@@ -22,12 +21,6 b' $Id: deep_reload.py 958 2005-12-27 23:17:51Z fperez $"""' | |||||
22 | # the file COPYING, distributed as part of this software. |
|
21 | # the file COPYING, distributed as part of this software. | |
23 | #***************************************************************************** |
|
22 | #***************************************************************************** | |
24 |
|
23 | |||
25 | from IPython import Release # do it explicitly so pydoc can see it - pydoc bug |
|
|||
26 | __author__ = '%s <%s>' % Release.authors['Nathan'] |
|
|||
27 | __license__ = Release.license |
|
|||
28 | __version__ = "0.5" |
|
|||
29 | __date__ = "21 August 2001" |
|
|||
30 |
|
||||
31 | import __builtin__ |
|
24 | import __builtin__ | |
32 | import imp |
|
25 | import imp | |
33 | import sys |
|
26 | import sys |
@@ -1,8 +1,7 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """ |
|
2 | """ | |
3 | Color schemes for exception handling code in IPython. |
|
3 | Color schemes for exception handling code in IPython. | |
4 |
|
4 | """ | ||
5 | $Id: Prompts.py 638 2005-07-18 03:01:41Z fperez $""" |
|
|||
6 |
|
5 | |||
7 | #***************************************************************************** |
|
6 | #***************************************************************************** | |
8 | # Copyright (C) 2005-2006 Fernando Perez <fperez@colorado.edu> |
|
7 | # Copyright (C) 2005-2006 Fernando Perez <fperez@colorado.edu> | |
@@ -11,99 +10,128 b' $Id: Prompts.py 638 2005-07-18 03:01:41Z fperez $"""' | |||||
11 | # the file COPYING, distributed as part of this software. |
|
10 | # the file COPYING, distributed as part of this software. | |
12 | #***************************************************************************** |
|
11 | #***************************************************************************** | |
13 |
|
12 | |||
14 | from IPython import Release |
|
|||
15 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
16 | __license__ = Release.license |
|
|||
17 | __version__ = Release.version |
|
|||
18 |
|
||||
19 | #**************************************************************************** |
|
13 | #**************************************************************************** | |
20 | # Required modules |
|
14 | # Required modules | |
21 | from IPython.ColorANSI import ColorSchemeTable, TermColors, ColorScheme |
|
15 | from IPython.ColorANSI import ColorSchemeTable, TermColors, ColorScheme | |
22 |
|
16 | |||
23 | ExceptionColors = ColorSchemeTable() |
|
17 | def exception_colors(): | |
24 |
|
18 | """Return a color table with fields for exception reporting. | ||
25 | # Populate it with color schemes |
|
19 | ||
26 | C = TermColors # shorthand and local lookup |
|
20 | The table is an instance of ColorSchemeTable with schemes added for | |
27 | ExceptionColors.add_scheme(ColorScheme( |
|
21 | 'Linux', 'LightBG' and 'NoColor' and fields for exception handling filled | |
28 | 'NoColor', |
|
22 | in. | |
29 | # The color to be used for the top line |
|
23 | ||
30 | topline = C.NoColor, |
|
24 | Examples: | |
31 |
|
|
25 | ||
32 | # The colors to be used in the traceback |
|
26 | >>> ec = exception_colors() | |
33 | filename = C.NoColor, |
|
27 | >>> ec.active_scheme_name | |
34 | lineno = C.NoColor, |
|
28 | '' | |
35 | name = C.NoColor, |
|
29 | >>> print ec.active_colors | |
36 | vName = C.NoColor, |
|
30 | None | |
37 | val = C.NoColor, |
|
31 | ||
38 | em = C.NoColor, |
|
32 | Now we activate a color scheme: | |
39 |
|
33 | >>> ec.set_active_scheme('NoColor') | ||
40 | # Emphasized colors for the last frame of the traceback |
|
34 | >>> ec.active_scheme_name | |
41 | normalEm = C.NoColor, |
|
35 | 'NoColor' | |
42 | filenameEm = C.NoColor, |
|
36 | >>> ec.active_colors.keys() | |
43 | linenoEm = C.NoColor, |
|
37 | ['em', 'caret', '__allownew', 'name', 'val', 'vName', 'Normal', 'normalEm', | |
44 | nameEm = C.NoColor, |
|
38 | 'filename', 'linenoEm', 'excName', 'lineno', 'valEm', 'filenameEm', | |
45 | valEm = C.NoColor, |
|
39 | 'nameEm', 'line', 'topline'] | |
46 |
|
|
40 | """ | |
47 | # Colors for printing the exception |
|
|||
48 | excName = C.NoColor, |
|
|||
49 | line = C.NoColor, |
|
|||
50 | caret = C.NoColor, |
|
|||
51 | Normal = C.NoColor |
|
|||
52 | )) |
|
|||
53 |
|
||||
54 | # make some schemes as instances so we can copy them for modification easily |
|
|||
55 | ExceptionColors.add_scheme(ColorScheme( |
|
|||
56 | 'Linux', |
|
|||
57 | # The color to be used for the top line |
|
|||
58 | topline = C.LightRed, |
|
|||
59 |
|
||||
60 | # The colors to be used in the traceback |
|
|||
61 | filename = C.Green, |
|
|||
62 | lineno = C.Green, |
|
|||
63 | name = C.Purple, |
|
|||
64 | vName = C.Cyan, |
|
|||
65 | val = C.Green, |
|
|||
66 | em = C.LightCyan, |
|
|||
67 |
|
||||
68 | # Emphasized colors for the last frame of the traceback |
|
|||
69 | normalEm = C.LightCyan, |
|
|||
70 | filenameEm = C.LightGreen, |
|
|||
71 | linenoEm = C.LightGreen, |
|
|||
72 | nameEm = C.LightPurple, |
|
|||
73 | valEm = C.LightBlue, |
|
|||
74 |
|
||||
75 | # Colors for printing the exception |
|
|||
76 | excName = C.LightRed, |
|
|||
77 | line = C.Yellow, |
|
|||
78 | caret = C.White, |
|
|||
79 | Normal = C.Normal |
|
|||
80 | )) |
|
|||
81 |
|
||||
82 | # For light backgrounds, swap dark/light colors |
|
|||
83 | ExceptionColors.add_scheme(ColorScheme( |
|
|||
84 | 'LightBG', |
|
|||
85 | # The color to be used for the top line |
|
|||
86 | topline = C.Red, |
|
|||
87 |
|
41 | |||
88 | # The colors to be used in the traceback |
|
42 | ex_colors = ColorSchemeTable() | |
89 | filename = C.LightGreen, |
|
43 | ||
90 | lineno = C.LightGreen, |
|
44 | # Populate it with color schemes | |
91 | name = C.LightPurple, |
|
45 | C = TermColors # shorthand and local lookup | |
92 | vName = C.Cyan, |
|
46 | ex_colors.add_scheme(ColorScheme( | |
93 | val = C.LightGreen, |
|
47 | 'NoColor', | |
94 | em = C.Cyan, |
|
48 | # The color to be used for the top line | |
95 |
|
49 | topline = C.NoColor, | ||
96 | # Emphasized colors for the last frame of the traceback |
|
50 | ||
97 | normalEm = C.Cyan, |
|
51 | # The colors to be used in the traceback | |
98 |
filename |
|
52 | filename = C.NoColor, | |
99 |
lineno |
|
53 | lineno = C.NoColor, | |
100 |
name |
|
54 | name = C.NoColor, | |
101 |
va |
|
55 | vName = C.NoColor, | |
102 |
|
56 | val = C.NoColor, | ||
103 | # Colors for printing the exception |
|
57 | em = C.NoColor, | |
104 | excName = C.Red, |
|
58 | ||
105 | #line = C.Brown, # brown often is displayed as yellow |
|
59 | # Emphasized colors for the last frame of the traceback | |
106 | line = C.Red, |
|
60 | normalEm = C.NoColor, | |
107 | caret = C.Normal, |
|
61 | filenameEm = C.NoColor, | |
108 | Normal = C.Normal |
|
62 | linenoEm = C.NoColor, | |
109 | )) |
|
63 | nameEm = C.NoColor, | |
|
64 | valEm = C.NoColor, | |||
|
65 | ||||
|
66 | # Colors for printing the exception | |||
|
67 | excName = C.NoColor, | |||
|
68 | line = C.NoColor, | |||
|
69 | caret = C.NoColor, | |||
|
70 | Normal = C.NoColor | |||
|
71 | )) | |||
|
72 | ||||
|
73 | # make some schemes as instances so we can copy them for modification easily | |||
|
74 | ex_colors.add_scheme(ColorScheme( | |||
|
75 | 'Linux', | |||
|
76 | # The color to be used for the top line | |||
|
77 | topline = C.LightRed, | |||
|
78 | ||||
|
79 | # The colors to be used in the traceback | |||
|
80 | filename = C.Green, | |||
|
81 | lineno = C.Green, | |||
|
82 | name = C.Purple, | |||
|
83 | vName = C.Cyan, | |||
|
84 | val = C.Green, | |||
|
85 | em = C.LightCyan, | |||
|
86 | ||||
|
87 | # Emphasized colors for the last frame of the traceback | |||
|
88 | normalEm = C.LightCyan, | |||
|
89 | filenameEm = C.LightGreen, | |||
|
90 | linenoEm = C.LightGreen, | |||
|
91 | nameEm = C.LightPurple, | |||
|
92 | valEm = C.LightBlue, | |||
|
93 | ||||
|
94 | # Colors for printing the exception | |||
|
95 | excName = C.LightRed, | |||
|
96 | line = C.Yellow, | |||
|
97 | caret = C.White, | |||
|
98 | Normal = C.Normal | |||
|
99 | )) | |||
|
100 | ||||
|
101 | # For light backgrounds, swap dark/light colors | |||
|
102 | ex_colors.add_scheme(ColorScheme( | |||
|
103 | 'LightBG', | |||
|
104 | # The color to be used for the top line | |||
|
105 | topline = C.Red, | |||
|
106 | ||||
|
107 | # The colors to be used in the traceback | |||
|
108 | filename = C.LightGreen, | |||
|
109 | lineno = C.LightGreen, | |||
|
110 | name = C.LightPurple, | |||
|
111 | vName = C.Cyan, | |||
|
112 | val = C.LightGreen, | |||
|
113 | em = C.Cyan, | |||
|
114 | ||||
|
115 | # Emphasized colors for the last frame of the traceback | |||
|
116 | normalEm = C.Cyan, | |||
|
117 | filenameEm = C.Green, | |||
|
118 | linenoEm = C.Green, | |||
|
119 | nameEm = C.Purple, | |||
|
120 | valEm = C.Blue, | |||
|
121 | ||||
|
122 | # Colors for printing the exception | |||
|
123 | excName = C.Red, | |||
|
124 | #line = C.Brown, # brown often is displayed as yellow | |||
|
125 | line = C.Red, | |||
|
126 | caret = C.Normal, | |||
|
127 | Normal = C.Normal, | |||
|
128 | )) | |||
|
129 | ||||
|
130 | return ex_colors | |||
|
131 | ||||
|
132 | ||||
|
133 | # For backwards compatibility, keep around a single global object. Note that | |||
|
134 | # this should NOT be used, the factory function should be used instead, since | |||
|
135 | # these objects are stateful and it's very easy to get strange bugs if any code | |||
|
136 | # modifies the module-level object's state. | |||
|
137 | ExceptionColors = exception_colors() |
@@ -27,7 +27,7 b' how to do interpolation:' | |||||
27 | import Itpl |
|
27 | import Itpl | |
28 | sys.stdout = Itpl.filter() |
|
28 | sys.stdout = Itpl.filter() | |
29 | f = "fancy" |
|
29 | f = "fancy" | |
30 |
print "Is |
|
30 | print "Is this not $f?" | |
31 | print "Standard output has been replaced with a $sys.stdout object." |
|
31 | print "Standard output has been replaced with a $sys.stdout object." | |
32 | sys.stdout = Itpl.unfilter() |
|
32 | sys.stdout = Itpl.unfilter() | |
33 | print "Okay, back $to $normal." |
|
33 | print "Okay, back $to $normal." | |
@@ -43,9 +43,7 b' each time the instance is evaluated with str(instance). For example:' | |||||
43 | print str(s) |
|
43 | print str(s) | |
44 | foo = "bar" |
|
44 | foo = "bar" | |
45 | print str(s) |
|
45 | print str(s) | |
46 |
|
46 | """ | ||
47 | $Id: Itpl.py 2305 2007-05-04 05:34:42Z bgranger $ |
|
|||
48 | """ # ' -> close an open quote for stupid emacs |
|
|||
49 |
|
47 | |||
50 | #***************************************************************************** |
|
48 | #***************************************************************************** | |
51 | # |
|
49 | # |
@@ -73,8 +73,6 b' __version__ = "0.2"' | |||||
73 |
|
73 | |||
74 |
|
74 | |||
75 | import os,glob,fnmatch,sys,re |
|
75 | import os,glob,fnmatch,sys,re | |
76 | from sets import Set as set |
|
|||
77 |
|
||||
78 |
|
76 | |||
79 | def expand(flist,exp_dirs = False): |
|
77 | def expand(flist,exp_dirs = False): | |
80 | """ Expand the glob(s) in flist. |
|
78 | """ Expand the glob(s) in flist. |
@@ -1,11 +1,9 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """ |
|
2 | """General purpose utilities. | |
3 | General purpose utilities. |
|
|||
4 |
|
3 | |||
5 | This is a grab-bag of stuff I find useful in most programs I write. Some of |
|
4 | This is a grab-bag of stuff I find useful in most programs I write. Some of | |
6 | these things are also convenient when working at the command line. |
|
5 | these things are also convenient when working at the command line. | |
7 |
|
6 | """ | ||
8 | $Id: genutils.py 2998 2008-01-31 10:06:04Z vivainio $""" |
|
|||
9 |
|
7 | |||
10 | #***************************************************************************** |
|
8 | #***************************************************************************** | |
11 | # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu> |
|
9 | # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu> | |
@@ -14,10 +12,6 b' $Id: genutils.py 2998 2008-01-31 10:06:04Z vivainio $"""' | |||||
14 | # the file COPYING, distributed as part of this software. |
|
12 | # the file COPYING, distributed as part of this software. | |
15 | #***************************************************************************** |
|
13 | #***************************************************************************** | |
16 |
|
14 | |||
17 | from IPython import Release |
|
|||
18 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
19 | __license__ = Release.license |
|
|||
20 |
|
||||
21 | #**************************************************************************** |
|
15 | #**************************************************************************** | |
22 | # required modules from the Python standard library |
|
16 | # required modules from the Python standard library | |
23 | import __main__ |
|
17 | import __main__ | |
@@ -928,12 +922,15 b' def get_home_dir():' | |||||
928 | # first, check py2exe distribution root directory for _ipython. |
|
922 | # first, check py2exe distribution root directory for _ipython. | |
929 | # This overrides all. Normally does not exist. |
|
923 | # This overrides all. Normally does not exist. | |
930 |
|
924 | |||
931 | if '\\library.zip\\' in IPython.__file__.lower(): |
|
925 | if hasattr(sys, "frozen"): #Is frozen by py2exe | |
932 | root, rest = IPython.__file__.lower().split('library.zip') |
|
926 | if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file | |
933 | if isdir(root + '_ipython'): |
|
927 | root, rest = IPython.__file__.lower().split('library.zip') | |
934 | os.environ["IPYKITROOT"] = root.rstrip('\\') |
|
928 | else: | |
935 | return root |
|
929 | root=os.path.join(os.path.split(IPython.__file__)[0],"../../") | |
936 |
|
930 | root=os.path.abspath(root).rstrip('\\') | ||
|
931 | if isdir(os.path.join(root, '_ipython')): | |||
|
932 | os.environ["IPYKITROOT"] = root | |||
|
933 | return root | |||
937 | try: |
|
934 | try: | |
938 | homedir = env['HOME'] |
|
935 | homedir = env['HOME'] | |
939 | if not isdir(homedir): |
|
936 | if not isdir(homedir): | |
@@ -953,7 +950,7 b' def get_home_dir():' | |||||
953 | if not isdir(homedir): |
|
950 | if not isdir(homedir): | |
954 | raise HomeDirError |
|
951 | raise HomeDirError | |
955 | return homedir |
|
952 | return homedir | |
956 | except: |
|
953 | except KeyError: | |
957 | try: |
|
954 | try: | |
958 | # Use the registry to get the 'My Documents' folder. |
|
955 | # Use the registry to get the 'My Documents' folder. | |
959 | import _winreg as wreg |
|
956 | import _winreg as wreg | |
@@ -992,8 +989,8 b' def get_ipython_dir():' | |||||
992 | ipdir_def = '_ipython' |
|
989 | ipdir_def = '_ipython' | |
993 | home_dir = get_home_dir() |
|
990 | home_dir = get_home_dir() | |
994 | ipdir = os.path.abspath(os.environ.get('IPYTHONDIR', |
|
991 | ipdir = os.path.abspath(os.environ.get('IPYTHONDIR', | |
995 | os.path.join(home_dir,ipdir_def))) |
|
992 | os.path.join(home_dir, ipdir_def))) | |
996 | return ipdir |
|
993 | return ipdir.decode(sys.getfilesystemencoding()) | |
997 |
|
994 | |||
998 | def get_security_dir(): |
|
995 | def get_security_dir(): | |
999 | """Get the IPython security directory. |
|
996 | """Get the IPython security directory. | |
@@ -1234,11 +1231,11 b' def esc_quotes(strng):' | |||||
1234 | def make_quoted_expr(s): |
|
1231 | def make_quoted_expr(s): | |
1235 | """Return string s in appropriate quotes, using raw string if possible. |
|
1232 | """Return string s in appropriate quotes, using raw string if possible. | |
1236 |
|
1233 | |||
1237 | Effectively this turns string: cd \ao\ao\ |
|
1234 | XXX - example removed because it caused encoding errors in documentation | |
1238 | to: r"cd \ao\ao\_"[:-1] |
|
1235 | generation. We need a new example that doesn't contain invalid chars. | |
1239 |
|
||||
1240 | Note the use of raw string and padding at the end to allow trailing backslash. |
|
|||
1241 |
|
1236 | |||
|
1237 | Note the use of raw string and padding at the end to allow trailing | |||
|
1238 | backslash. | |||
1242 | """ |
|
1239 | """ | |
1243 |
|
1240 | |||
1244 | tail = '' |
|
1241 | tail = '' |
@@ -62,11 +62,10 b' class _Helper(object):' | |||||
62 | ############################################################################## |
|
62 | ############################################################################## | |
63 | class _CodeExecutor(ThreadEx): |
|
63 | class _CodeExecutor(ThreadEx): | |
64 | ''' Thread that execute ipython code ''' |
|
64 | ''' Thread that execute ipython code ''' | |
65 |
def __init__(self, instance |
|
65 | def __init__(self, instance): | |
66 | ThreadEx.__init__(self) |
|
66 | ThreadEx.__init__(self) | |
67 | self.instance = instance |
|
67 | self.instance = instance | |
68 | self._afterExecute = after |
|
68 | ||
69 |
|
||||
70 | def run(self): |
|
69 | def run(self): | |
71 | '''Thread main loop''' |
|
70 | '''Thread main loop''' | |
72 | try: |
|
71 | try: | |
@@ -74,7 +73,7 b' class _CodeExecutor(ThreadEx):' | |||||
74 | self.instance._help_text = None |
|
73 | self.instance._help_text = None | |
75 | self.instance._execute() |
|
74 | self.instance._execute() | |
76 | # used for uper class to generate event after execution |
|
75 | # used for uper class to generate event after execution | |
77 |
self._after |
|
76 | self.instance._after_execute() | |
78 |
|
77 | |||
79 | except KeyboardInterrupt: |
|
78 | except KeyboardInterrupt: | |
80 | pass |
|
79 | pass | |
@@ -114,8 +113,7 b' class NonBlockingIPShell(object):' | |||||
114 | ''' |
|
113 | ''' | |
115 | #ipython0 initialisation |
|
114 | #ipython0 initialisation | |
116 | self._IP = None |
|
115 | self._IP = None | |
117 | self._term = None |
|
116 | self.init_ipython0(argv, user_ns, user_global_ns, | |
118 | self.initIpython0(argv, user_ns, user_global_ns, |
|
|||
119 | cin, cout, cerr, |
|
117 | cin, cout, cerr, | |
120 | ask_exit_handler) |
|
118 | ask_exit_handler) | |
121 |
|
119 | |||
@@ -127,33 +125,32 b' class NonBlockingIPShell(object):' | |||||
127 |
|
125 | |||
128 | #thread working vars |
|
126 | #thread working vars | |
129 | self._line_to_execute = '' |
|
127 | self._line_to_execute = '' | |
130 |
|
128 | self._threading = True | ||
|
129 | ||||
131 | #vars that will be checked by GUI loop to handle thread states... |
|
130 | #vars that will be checked by GUI loop to handle thread states... | |
132 | #will be replaced later by PostEvent GUI funtions... |
|
131 | #will be replaced later by PostEvent GUI funtions... | |
133 | self._doc_text = None |
|
132 | self._doc_text = None | |
134 | self._help_text = None |
|
133 | self._help_text = None | |
135 | self._add_button = None |
|
134 | self._add_button = None | |
136 |
|
135 | |||
137 |
def init |
|
136 | def init_ipython0(self, argv=[], user_ns={}, user_global_ns=None, | |
138 | cin=None, cout=None, cerr=None, |
|
137 | cin=None, cout=None, cerr=None, | |
139 | ask_exit_handler=None): |
|
138 | ask_exit_handler=None): | |
140 | ''' Initialize an ithon0 instance ''' |
|
139 | ''' Initialize an ipython0 instance ''' | |
141 |
|
140 | |||
142 |
#first we redefine in/out/error functions of IPython |
|
141 | #first we redefine in/out/error functions of IPython | |
|
142 | #BUG: we've got a limitation form ipython0 there | |||
|
143 | #only one instance can be instanciated else tehre will be | |||
|
144 | #cin/cout/cerr clash... | |||
143 | if cin: |
|
145 | if cin: | |
144 |
IPython. |
|
146 | IPython.genutils.Term.cin = cin | |
145 | if cout: |
|
147 | if cout: | |
146 |
IPython. |
|
148 | IPython.genutils.Term.cout = cout | |
147 | if cerr: |
|
149 | if cerr: | |
148 |
IPython. |
|
150 | IPython.genutils.Term.cerr = cerr | |
149 |
|
151 | |||
150 | # This is to get rid of the blockage that accurs during |
|
|||
151 | # IPython.Shell.InteractiveShell.user_setup() |
|
|||
152 | IPython.iplib.raw_input = lambda x: None |
|
|||
153 |
|
||||
154 | self._term = IPython.genutils.IOTerm(cin=cin, cout=cout, cerr=cerr) |
|
|||
155 |
|
||||
156 | excepthook = sys.excepthook |
|
152 | excepthook = sys.excepthook | |
|
153 | ||||
157 | #Hack to save sys.displayhook, because ipython seems to overwrite it... |
|
154 | #Hack to save sys.displayhook, because ipython seems to overwrite it... | |
158 | self.sys_displayhook_ori = sys.displayhook |
|
155 | self.sys_displayhook_ori = sys.displayhook | |
159 |
|
156 | |||
@@ -163,7 +160,8 b' class NonBlockingIPShell(object):' | |||||
163 | embedded=True, |
|
160 | embedded=True, | |
164 | shell_class=IPython.Shell.InteractiveShell) |
|
161 | shell_class=IPython.Shell.InteractiveShell) | |
165 |
|
162 | |||
166 | #we restore sys.displayhook |
|
163 | #we save ipython0 displayhook and we restore sys.displayhook | |
|
164 | self.displayhook = sys.displayhook | |||
167 | sys.displayhook = self.sys_displayhook_ori |
|
165 | sys.displayhook = self.sys_displayhook_ori | |
168 |
|
166 | |||
169 | #we replace IPython default encoding by wx locale encoding |
|
167 | #we replace IPython default encoding by wx locale encoding | |
@@ -173,11 +171,12 b' class NonBlockingIPShell(object):' | |||||
173 | #we replace the ipython default pager by our pager |
|
171 | #we replace the ipython default pager by our pager | |
174 | self._IP.set_hook('show_in_pager', self._pager) |
|
172 | self._IP.set_hook('show_in_pager', self._pager) | |
175 |
|
173 | |||
176 |
#we replace the ipython default shell command caller |
|
174 | #we replace the ipython default shell command caller | |
|
175 | #by our shell handler | |||
177 | self._IP.set_hook('shell_hook', self._shell) |
|
176 | self._IP.set_hook('shell_hook', self._shell) | |
178 |
|
177 | |||
179 | #we replace the ipython default input command caller by our method |
|
178 | #we replace the ipython default input command caller by our method | |
180 | IPython.iplib.raw_input_original = self._raw_input |
|
179 | IPython.iplib.raw_input_original = self._raw_input_original | |
181 | #we replace the ipython default exit command by our method |
|
180 | #we replace the ipython default exit command by our method | |
182 | self._IP.exit = ask_exit_handler |
|
181 | self._IP.exit = ask_exit_handler | |
183 | #we replace the help command |
|
182 | #we replace the help command | |
@@ -186,26 +185,68 b' class NonBlockingIPShell(object):' | |||||
186 | #we disable cpase magic... until we found a way to use it properly. |
|
185 | #we disable cpase magic... until we found a way to use it properly. | |
187 | #import IPython.ipapi |
|
186 | #import IPython.ipapi | |
188 | ip = IPython.ipapi.get() |
|
187 | ip = IPython.ipapi.get() | |
189 |
def bypass |
|
188 | def bypass_magic(self, arg): | |
190 | print '%this magic is currently disabled.' |
|
189 | print '%this magic is currently disabled.' | |
191 |
ip.expose_magic('cpaste', bypass |
|
190 | ip.expose_magic('cpaste', bypass_magic) | |
|
191 | ||||
|
192 | import __builtin__ | |||
|
193 | __builtin__.raw_input = self._raw_input | |||
192 |
|
194 | |||
193 | sys.excepthook = excepthook |
|
195 | sys.excepthook = excepthook | |
194 |
|
196 | |||
195 |
#----------------------- Thread management section ---------------------- |
|
197 | #----------------------- Thread management section ---------------------- | |
196 |
def do |
|
198 | def do_execute(self, line): | |
197 | """ |
|
199 | """ | |
198 | Tell the thread to process the 'line' command |
|
200 | Tell the thread to process the 'line' command | |
199 | """ |
|
201 | """ | |
200 |
|
202 | |||
201 | self._line_to_execute = line |
|
203 | self._line_to_execute = line | |
202 | #we launch the ipython line execution in a thread to make it interruptible |
|
204 | ||
203 | #with include it in self namespace to be able to call ce.raise_exc(KeyboardInterrupt) |
|
205 | if self._threading: | |
204 | self.ce = _CodeExecutor(self, self._afterExecute) |
|
206 | #we launch the ipython line execution in a thread to make it | |
205 | self.ce.start() |
|
207 | #interruptible with include it in self namespace to be able | |
206 |
|
208 | #to call ce.raise_exc(KeyboardInterrupt) | ||
207 | #----------------------- IPython management section ---------------------- |
|
209 | self.ce = _CodeExecutor(self) | |
208 | def getDocText(self): |
|
210 | self.ce.start() | |
|
211 | else: | |||
|
212 | try: | |||
|
213 | self._doc_text = None | |||
|
214 | self._help_text = None | |||
|
215 | self._execute() | |||
|
216 | # used for uper class to generate event after execution | |||
|
217 | self._after_execute() | |||
|
218 | ||||
|
219 | except KeyboardInterrupt: | |||
|
220 | pass | |||
|
221 | ||||
|
222 | #----------------------- IPython management section ---------------------- | |||
|
223 | def get_threading(self): | |||
|
224 | """ | |||
|
225 | Returns threading status, is set to True, then each command sent to | |||
|
226 | the interpreter will be executed in a separated thread allowing, | |||
|
227 | for example, breaking a long running commands. | |||
|
228 | Disallowing it, permits better compatibilty with instance that is embedding | |||
|
229 | IPython instance. | |||
|
230 | ||||
|
231 | @return: Execution method | |||
|
232 | @rtype: bool | |||
|
233 | """ | |||
|
234 | return self._threading | |||
|
235 | ||||
|
236 | def set_threading(self, state): | |||
|
237 | """ | |||
|
238 | Sets threading state, if set to True, then each command sent to | |||
|
239 | the interpreter will be executed in a separated thread allowing, | |||
|
240 | for example, breaking a long running commands. | |||
|
241 | Disallowing it, permits better compatibilty with instance that is embedding | |||
|
242 | IPython instance. | |||
|
243 | ||||
|
244 | @param state: Sets threading state | |||
|
245 | @type bool | |||
|
246 | """ | |||
|
247 | self._threading = state | |||
|
248 | ||||
|
249 | def get_doc_text(self): | |||
209 | """ |
|
250 | """ | |
210 | Returns the output of the processing that need to be paged (if any) |
|
251 | Returns the output of the processing that need to be paged (if any) | |
211 |
|
252 | |||
@@ -214,7 +255,7 b' class NonBlockingIPShell(object):' | |||||
214 | """ |
|
255 | """ | |
215 | return self._doc_text |
|
256 | return self._doc_text | |
216 |
|
257 | |||
217 |
def get |
|
258 | def get_help_text(self): | |
218 | """ |
|
259 | """ | |
219 | Returns the output of the processing that need to be paged via help pager(if any) |
|
260 | Returns the output of the processing that need to be paged via help pager(if any) | |
220 |
|
261 | |||
@@ -223,7 +264,7 b' class NonBlockingIPShell(object):' | |||||
223 | """ |
|
264 | """ | |
224 | return self._help_text |
|
265 | return self._help_text | |
225 |
|
266 | |||
226 |
def get |
|
267 | def get_banner(self): | |
227 | """ |
|
268 | """ | |
228 | Returns the IPython banner for useful info on IPython instance |
|
269 | Returns the IPython banner for useful info on IPython instance | |
229 |
|
270 | |||
@@ -232,7 +273,7 b' class NonBlockingIPShell(object):' | |||||
232 | """ |
|
273 | """ | |
233 | return self._IP.BANNER |
|
274 | return self._IP.BANNER | |
234 |
|
275 | |||
235 |
def get |
|
276 | def get_prompt_count(self): | |
236 | """ |
|
277 | """ | |
237 | Returns the prompt number. |
|
278 | Returns the prompt number. | |
238 | Each time a user execute a line in the IPython shell the prompt count is increased |
|
279 | Each time a user execute a line in the IPython shell the prompt count is increased | |
@@ -242,7 +283,7 b' class NonBlockingIPShell(object):' | |||||
242 | """ |
|
283 | """ | |
243 | return self._IP.outputcache.prompt_count |
|
284 | return self._IP.outputcache.prompt_count | |
244 |
|
285 | |||
245 |
def get |
|
286 | def get_prompt(self): | |
246 | """ |
|
287 | """ | |
247 | Returns current prompt inside IPython instance |
|
288 | Returns current prompt inside IPython instance | |
248 | (Can be In [...]: ot ...:) |
|
289 | (Can be In [...]: ot ...:) | |
@@ -252,7 +293,7 b' class NonBlockingIPShell(object):' | |||||
252 | """ |
|
293 | """ | |
253 | return self._prompt |
|
294 | return self._prompt | |
254 |
|
295 | |||
255 |
def get |
|
296 | def get_indentation(self): | |
256 | """ |
|
297 | """ | |
257 | Returns the current indentation level |
|
298 | Returns the current indentation level | |
258 | Usefull to put the caret at the good start position if we want to do autoindentation. |
|
299 | Usefull to put the caret at the good start position if we want to do autoindentation. | |
@@ -262,7 +303,7 b' class NonBlockingIPShell(object):' | |||||
262 | """ |
|
303 | """ | |
263 | return self._IP.indent_current_nsp |
|
304 | return self._IP.indent_current_nsp | |
264 |
|
305 | |||
265 |
def update |
|
306 | def update_namespace(self, ns_dict): | |
266 | ''' |
|
307 | ''' | |
267 | Add the current dictionary to the shell namespace. |
|
308 | Add the current dictionary to the shell namespace. | |
268 |
|
309 | |||
@@ -286,7 +327,7 b' class NonBlockingIPShell(object):' | |||||
286 | possibilities = self._IP.complete(split_line[-1]) |
|
327 | possibilities = self._IP.complete(split_line[-1]) | |
287 | if possibilities: |
|
328 | if possibilities: | |
288 |
|
329 | |||
289 |
def _common |
|
330 | def _common_prefix(str1, str2): | |
290 | ''' |
|
331 | ''' | |
291 | Reduction function. returns common prefix of two given strings. |
|
332 | Reduction function. returns common prefix of two given strings. | |
292 |
|
333 | |||
@@ -302,13 +343,13 b' class NonBlockingIPShell(object):' | |||||
302 | if not str2.startswith(str1[:i+1]): |
|
343 | if not str2.startswith(str1[:i+1]): | |
303 | return str1[:i] |
|
344 | return str1[:i] | |
304 | return str1 |
|
345 | return str1 | |
305 |
common_prefix = reduce(_common |
|
346 | common_prefix = reduce(_common_prefix, possibilities) | |
306 | completed = line[:-len(split_line[-1])]+common_prefix |
|
347 | completed = line[:-len(split_line[-1])]+common_prefix | |
307 | else: |
|
348 | else: | |
308 | completed = line |
|
349 | completed = line | |
309 | return completed, possibilities |
|
350 | return completed, possibilities | |
310 |
|
351 | |||
311 |
def history |
|
352 | def history_back(self): | |
312 | ''' |
|
353 | ''' | |
313 | Provides one history command back. |
|
354 | Provides one history command back. | |
314 |
|
355 | |||
@@ -320,10 +361,10 b' class NonBlockingIPShell(object):' | |||||
320 | while((history == '' or history == '\n') and self._history_level >0): |
|
361 | while((history == '' or history == '\n') and self._history_level >0): | |
321 | if self._history_level >= 1: |
|
362 | if self._history_level >= 1: | |
322 | self._history_level -= 1 |
|
363 | self._history_level -= 1 | |
323 |
history = self._get |
|
364 | history = self._get_history() | |
324 | return history |
|
365 | return history | |
325 |
|
366 | |||
326 |
def history |
|
367 | def history_forward(self): | |
327 | ''' |
|
368 | ''' | |
328 | Provides one history command forward. |
|
369 | Provides one history command forward. | |
329 |
|
370 | |||
@@ -333,38 +374,38 b' class NonBlockingIPShell(object):' | |||||
333 | history = '' |
|
374 | history = '' | |
334 | #the below while loop is used to suppress empty history lines |
|
375 | #the below while loop is used to suppress empty history lines | |
335 | while((history == '' or history == '\n') \ |
|
376 | while((history == '' or history == '\n') \ | |
336 |
and self._history_level <= self._get |
|
377 | and self._history_level <= self._get_history_max_index()): | |
337 |
if self._history_level < self._get |
|
378 | if self._history_level < self._get_history_max_index(): | |
338 | self._history_level += 1 |
|
379 | self._history_level += 1 | |
339 |
history = self._get |
|
380 | history = self._get_history() | |
340 | else: |
|
381 | else: | |
341 |
if self._history_level == self._get |
|
382 | if self._history_level == self._get_history_max_index(): | |
342 |
history = self._get |
|
383 | history = self._get_history() | |
343 | self._history_level += 1 |
|
384 | self._history_level += 1 | |
344 | else: |
|
385 | else: | |
345 | history = '' |
|
386 | history = '' | |
346 | return history |
|
387 | return history | |
347 |
|
388 | |||
348 |
def init |
|
389 | def init_history_index(self): | |
349 | ''' |
|
390 | ''' | |
350 | set history to last command entered |
|
391 | set history to last command entered | |
351 | ''' |
|
392 | ''' | |
352 |
self._history_level = self._get |
|
393 | self._history_level = self._get_history_max_index()+1 | |
353 |
|
394 | |||
354 | #----------------------- IPython PRIVATE management section -------------- |
|
395 | #----------------------- IPython PRIVATE management section -------------- | |
355 |
def _after |
|
396 | def _after_execute(self): | |
356 | ''' |
|
397 | ''' | |
357 | Can be redefined to generate post event after excution is done |
|
398 | Can be redefined to generate post event after excution is done | |
358 | ''' |
|
399 | ''' | |
359 | pass |
|
400 | pass | |
360 |
|
401 | |||
361 |
|
|
402 | def _ask_exit(self): | |
362 |
|
|
403 | ''' | |
363 |
|
|
404 | Can be redefined to generate post event to exit the Ipython shell | |
364 |
|
|
405 | ''' | |
365 |
|
|
406 | pass | |
366 |
|
407 | |||
367 |
def _get |
|
408 | def _get_history_max_index(self): | |
368 | ''' |
|
409 | ''' | |
369 | returns the max length of the history buffer |
|
410 | returns the max length of the history buffer | |
370 |
|
411 | |||
@@ -373,7 +414,7 b' class NonBlockingIPShell(object):' | |||||
373 | ''' |
|
414 | ''' | |
374 | return len(self._IP.input_hist_raw)-1 |
|
415 | return len(self._IP.input_hist_raw)-1 | |
375 |
|
416 | |||
376 |
def _get |
|
417 | def _get_history(self): | |
377 | ''' |
|
418 | ''' | |
378 | Get's the command string of the current history level. |
|
419 | Get's the command string of the current history level. | |
379 |
|
420 | |||
@@ -388,7 +429,7 b' class NonBlockingIPShell(object):' | |||||
388 | This function is used as a callback replacment to IPython help pager function |
|
429 | This function is used as a callback replacment to IPython help pager function | |
389 |
|
430 | |||
390 | It puts the 'text' value inside the self._help_text string that can be retrived via |
|
431 | It puts the 'text' value inside the self._help_text string that can be retrived via | |
391 |
get |
|
432 | get_help_text function. | |
392 | ''' |
|
433 | ''' | |
393 | if self._help_text == None: |
|
434 | if self._help_text == None: | |
394 | self._help_text = text |
|
435 | self._help_text = text | |
@@ -400,11 +441,11 b' class NonBlockingIPShell(object):' | |||||
400 | This function is used as a callback replacment to IPython pager function |
|
441 | This function is used as a callback replacment to IPython pager function | |
401 |
|
442 | |||
402 | It puts the 'text' value inside the self._doc_text string that can be retrived via |
|
443 | It puts the 'text' value inside the self._doc_text string that can be retrived via | |
403 |
get |
|
444 | get_doc_text function. | |
404 | ''' |
|
445 | ''' | |
405 | self._doc_text = text |
|
446 | self._doc_text = text | |
406 |
|
447 | |||
407 | def _raw_input(self, prompt=''): |
|
448 | def _raw_input_original(self, prompt=''): | |
408 | ''' |
|
449 | ''' | |
409 | Custom raw_input() replacement. Get's current line from console buffer. |
|
450 | Custom raw_input() replacement. Get's current line from console buffer. | |
410 |
|
451 | |||
@@ -416,13 +457,21 b' class NonBlockingIPShell(object):' | |||||
416 | ''' |
|
457 | ''' | |
417 | return self._line_to_execute |
|
458 | return self._line_to_execute | |
418 |
|
459 | |||
|
460 | def _raw_input(self, prompt=''): | |||
|
461 | """ A replacement from python's raw_input. | |||
|
462 | """ | |||
|
463 | raise NotImplementedError | |||
|
464 | ||||
419 | def _execute(self): |
|
465 | def _execute(self): | |
420 | ''' |
|
466 | ''' | |
421 | Executes the current line provided by the shell object. |
|
467 | Executes the current line provided by the shell object. | |
422 | ''' |
|
468 | ''' | |
|
469 | ||||
423 | orig_stdout = sys.stdout |
|
470 | orig_stdout = sys.stdout | |
424 | sys.stdout = IPython.Shell.Term.cout |
|
471 | sys.stdout = IPython.Shell.Term.cout | |
425 |
|
472 | #self.sys_displayhook_ori = sys.displayhook | ||
|
473 | #sys.displayhook = self.displayhook | |||
|
474 | ||||
426 | try: |
|
475 | try: | |
427 | line = self._IP.raw_input(None, self._iter_more) |
|
476 | line = self._IP.raw_input(None, self._iter_more) | |
428 | if self._IP.autoindent: |
|
477 | if self._IP.autoindent: | |
@@ -440,8 +489,10 b' class NonBlockingIPShell(object):' | |||||
440 | except: |
|
489 | except: | |
441 | self._IP.showtraceback() |
|
490 | self._IP.showtraceback() | |
442 | else: |
|
491 | else: | |
|
492 | self._IP.write(str(self._IP.outputcache.prompt_out).strip()) | |||
443 | self._iter_more = self._IP.push(line) |
|
493 | self._iter_more = self._IP.push(line) | |
444 |
if (self._IP.SyntaxTB.last_syntax_error and |
|
494 | if (self._IP.SyntaxTB.last_syntax_error and \ | |
|
495 | self._IP.rc.autoedit_syntax): | |||
445 | self._IP.edit_syntax_error() |
|
496 | self._IP.edit_syntax_error() | |
446 | if self._iter_more: |
|
497 | if self._iter_more: | |
447 | self._prompt = str(self._IP.outputcache.prompt2).strip() |
|
498 | self._prompt = str(self._IP.outputcache.prompt2).strip() | |
@@ -450,8 +501,10 b' class NonBlockingIPShell(object):' | |||||
450 | else: |
|
501 | else: | |
451 | self._prompt = str(self._IP.outputcache.prompt1).strip() |
|
502 | self._prompt = str(self._IP.outputcache.prompt1).strip() | |
452 | self._IP.indent_current_nsp = 0 #we set indentation to 0 |
|
503 | self._IP.indent_current_nsp = 0 #we set indentation to 0 | |
|
504 | ||||
453 | sys.stdout = orig_stdout |
|
505 | sys.stdout = orig_stdout | |
454 |
|
506 | #sys.displayhook = self.sys_displayhook_ori | ||
|
507 | ||||
455 | def _shell(self, ip, cmd): |
|
508 | def _shell(self, ip, cmd): | |
456 | ''' |
|
509 | ''' | |
457 | Replacement method to allow shell commands without them blocking. |
|
510 | Replacement method to allow shell commands without them blocking. | |
@@ -462,7 +515,8 b' class NonBlockingIPShell(object):' | |||||
462 | @type cmd: string |
|
515 | @type cmd: string | |
463 | ''' |
|
516 | ''' | |
464 | stdin, stdout = os.popen4(cmd) |
|
517 | stdin, stdout = os.popen4(cmd) | |
465 |
result = stdout.read().decode('cp437'). |
|
518 | result = stdout.read().decode('cp437').\ | |
|
519 | encode(locale.getpreferredencoding()) | |||
466 | #we use print command because the shell command is called |
|
520 | #we use print command because the shell command is called | |
467 | #inside IPython instance and thus is redirected to thread cout |
|
521 | #inside IPython instance and thus is redirected to thread cout | |
468 | #"\x01\x1b[1;36m\x02" <-- add colour to the text... |
|
522 | #"\x01\x1b[1;36m\x02" <-- add colour to the text... |
@@ -29,17 +29,21 b' class IPythonHistoryPanel(wx.Panel):' | |||||
29 | self.filter_magic = wx.CheckBox(self, -1, "%: Magic keys") |
|
29 | self.filter_magic = wx.CheckBox(self, -1, "%: Magic keys") | |
30 |
|
30 | |||
31 | self.options={'filter_empty':{'value':'True', |
|
31 | self.options={'filter_empty':{'value':'True', | |
32 |
|
|
32 | 'checkbox':self.filter_empty, \ | |
33 |
' |
|
33 | 'True':True,'False':False, | |
|
34 | 'setfunc':lambda x:None}, | |||
34 | 'filter_doc':{'value':'True', |
|
35 | 'filter_doc':{'value':'True', | |
35 |
|
|
36 | 'checkbox':self.filter_doc, \ | |
36 |
' |
|
37 | 'True':True,'False':False, | |
|
38 | 'setfunc':lambda x:None}, | |||
37 | 'filter_cmd':{'value':'True', |
|
39 | 'filter_cmd':{'value':'True', | |
38 |
|
|
40 | 'checkbox':self.filter_cmd, \ | |
39 |
' |
|
41 | 'True':True,'False':False, | |
|
42 | 'setfunc':lambda x:None}, | |||
40 | 'filter_magic':{'value':'True', |
|
43 | 'filter_magic':{'value':'True', | |
41 |
|
|
44 | 'checkbox':self.filter_magic, \ | |
42 |
' |
|
45 | 'True':True,'False':False, | |
|
46 | 'setfunc':lambda x:None}, | |||
43 | } |
|
47 | } | |
44 | self.reloadOptions(self.options) |
|
48 | self.reloadOptions(self.options) | |
45 |
|
49 | |||
@@ -199,51 +203,81 b' class PythonSTC(stc.StyledTextCtrl):' | |||||
199 | self.SetLayoutCache(stc.STC_CACHE_PAGE) |
|
203 | self.SetLayoutCache(stc.STC_CACHE_PAGE) | |
200 |
|
204 | |||
201 | # Setup a margin to hold fold markers |
|
205 | # Setup a margin to hold fold markers | |
202 | #self.SetFoldFlags(16) ### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER? |
|
206 | #self.SetFoldFlags(16) | |
|
207 | ### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER? | |||
203 | self.SetMarginType(2, stc.STC_MARGIN_SYMBOL) |
|
208 | self.SetMarginType(2, stc.STC_MARGIN_SYMBOL) | |
204 | self.SetMarginMask(2, stc.STC_MASK_FOLDERS) |
|
209 | self.SetMarginMask(2, stc.STC_MASK_FOLDERS) | |
205 | self.SetMarginSensitive(2, True) |
|
210 | self.SetMarginSensitive(2, True) | |
206 | self.SetMarginWidth(2, 12) |
|
211 | self.SetMarginWidth(2, 12) | |
207 |
|
212 | |||
208 | if self.fold_symbols == 0: |
|
213 | if self.fold_symbols == 0: | |
209 |
# Arrow pointing right for contracted folders, |
|
214 | # Arrow pointing right for contracted folders, | |
210 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_ARROWDOWN, "black", "black") |
|
215 | # arrow pointing down for expanded | |
211 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDER |
|
216 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \ | |
212 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_EMPTY, "black", "black") |
|
217 | stc.STC_MARK_ARROWDOWN, "black", "black") | |
213 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDER |
|
218 | self.MarkerDefine(stc.STC_MARKNUM_FOLDER, \ | |
214 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black") |
|
219 | stc.STC_MARK_ARROW, "black", "black") | |
215 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDER |
|
220 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, \ | |
216 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black") |
|
221 | stc.STC_MARK_EMPTY, "black", "black") | |
|
222 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, \ | |||
|
223 | stc.STC_MARK_EMPTY, "black", "black") | |||
|
224 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, \ | |||
|
225 | stc.STC_MARK_EMPTY, "white", "black") | |||
|
226 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, \ | |||
|
227 | stc.STC_MARK_EMPTY, "white", "black") | |||
|
228 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \ | |||
|
229 | stc.STC_MARK_EMPTY, "white", "black") | |||
217 |
|
230 | |||
218 | elif self.fold_symbols == 1: |
|
231 | elif self.fold_symbols == 1: | |
219 | # Plus for contracted folders, minus for expanded |
|
232 | # Plus for contracted folders, minus for expanded | |
220 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, |
|
233 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \ | |
221 |
|
|
234 | stc.STC_MARK_MINUS, "white", "black") | |
222 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDER |
|
235 | self.MarkerDefine(stc.STC_MARKNUM_FOLDER, \ | |
223 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_EMPTY, "white", "black") |
|
236 | stc.STC_MARK_PLUS, "white", "black") | |
224 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDER |
|
237 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, \ | |
225 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black") |
|
238 | stc.STC_MARK_EMPTY, "white", "black") | |
226 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDER |
|
239 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, \ | |
|
240 | stc.STC_MARK_EMPTY, "white", "black") | |||
|
241 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, \ | |||
|
242 | stc.STC_MARK_EMPTY, "white", "black") | |||
|
243 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, \ | |||
|
244 | stc.STC_MARK_EMPTY, "white", "black") | |||
|
245 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \ | |||
|
246 | stc.STC_MARK_EMPTY, "white", "black") | |||
227 |
|
247 | |||
228 | elif self.fold_symbols == 2: |
|
248 | elif self.fold_symbols == 2: | |
229 | # Like a flattened tree control using circular headers and curved joins |
|
249 | # Like a flattened tree control using circular headers and curved joins | |
230 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, |
|
250 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \ | |
231 |
|
|
251 | stc.STC_MARK_CIRCLEMINUS, "white", "#404040") | |
232 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDER |
|
252 | self.MarkerDefine(stc.STC_MARKNUM_FOLDER, \ | |
233 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNERCURVE, "white", "#404040") |
|
253 | stc.STC_MARK_CIRCLEPLUS, "white", "#404040") | |
234 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDER |
|
254 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, \ | |
235 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040") |
|
255 | stc.STC_MARK_VLINE, "white", "#404040") | |
236 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDER |
|
256 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, \ | |
|
257 | stc.STC_MARK_LCORNERCURVE, "white", "#404040") | |||
|
258 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, \ | |||
|
259 | stc.STC_MARK_CIRCLEPLUSCONNECTED, "white", "#404040") | |||
|
260 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, \ | |||
|
261 | stc.STC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040") | |||
|
262 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \ | |||
|
263 | stc.STC_MARK_TCORNERCURVE, "white", "#404040") | |||
237 |
|
264 | |||
238 | elif self.fold_symbols == 3: |
|
265 | elif self.fold_symbols == 3: | |
239 | # Like a flattened tree control using square headers |
|
266 | # Like a flattened tree control using square headers | |
240 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, |
|
267 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \ | |
241 |
|
|
268 | stc.STC_MARK_BOXMINUS, "white", "#808080") | |
242 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDER |
|
269 | self.MarkerDefine(stc.STC_MARKNUM_FOLDER, \ | |
243 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNER, "white", "#808080") |
|
270 | stc.STC_MARK_BOXPLUS, "white", "#808080") | |
244 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDER |
|
271 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, \ | |
245 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080") |
|
272 | stc.STC_MARK_VLINE, "white", "#808080") | |
246 |
self.MarkerDefine(stc.STC_MARKNUM_FOLDER |
|
273 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, \ | |
|
274 | stc.STC_MARK_LCORNER, "white", "#808080") | |||
|
275 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, \ | |||
|
276 | stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080") | |||
|
277 | self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, \ | |||
|
278 | stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080") | |||
|
279 | self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \ | |||
|
280 | stc.STC_MARK_TCORNER, "white", "#808080") | |||
247 |
|
281 | |||
248 |
|
282 | |||
249 | self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI) |
|
283 | self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI) | |
@@ -363,7 +397,7 b' class PythonSTC(stc.StyledTextCtrl):' | |||||
363 | if braceAtCaret < 0: |
|
397 | if braceAtCaret < 0: | |
364 | charAfter = self.GetCharAt(caretPos) |
|
398 | charAfter = self.GetCharAt(caretPos) | |
365 | styleAfter = self.GetStyleAt(caretPos) |
|
399 | styleAfter = self.GetStyleAt(caretPos) | |
366 |
|
400 | |||
367 | if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR: |
|
401 | if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR: | |
368 | braceAtCaret = caretPos |
|
402 | braceAtCaret = caretPos | |
369 |
|
403 |
@@ -1,5 +1,5 b'' | |||||
1 | #!/usr/bin/python |
|
1 | #!/usr/bin/python | |
2 |
# -*- coding: |
|
2 | # -*- coding: utf-8 -*- | |
3 | ''' |
|
3 | ''' | |
4 | Provides IPython WX console widgets. |
|
4 | Provides IPython WX console widgets. | |
5 |
|
5 | |||
@@ -19,7 +19,7 b' available under the terms of the BSD which accompanies this distribution, and' | |||||
19 | is available at U{http://www.opensource.org/licenses/bsd-license.php} |
|
19 | is available at U{http://www.opensource.org/licenses/bsd-license.php} | |
20 | ''' |
|
20 | ''' | |
21 |
|
21 | |||
22 |
__version__ = 0. |
|
22 | __version__ = 0.9 | |
23 | __author__ = "Laurent Dufrechou" |
|
23 | __author__ = "Laurent Dufrechou" | |
24 | __email__ = "laurent.dufrechou _at_ gmail.com" |
|
24 | __email__ = "laurent.dufrechou _at_ gmail.com" | |
25 | __license__ = "BSD" |
|
25 | __license__ = "BSD" | |
@@ -33,6 +33,8 b' from StringIO import StringIO' | |||||
33 | import sys |
|
33 | import sys | |
34 | import codecs |
|
34 | import codecs | |
35 | import locale |
|
35 | import locale | |
|
36 | import time | |||
|
37 | ||||
36 | for enc in (locale.getpreferredencoding(), |
|
38 | for enc in (locale.getpreferredencoding(), | |
37 | sys.getfilesystemencoding(), |
|
39 | sys.getfilesystemencoding(), | |
38 | sys.getdefaultencoding()): |
|
40 | sys.getdefaultencoding()): | |
@@ -63,17 +65,43 b' class WxNonBlockingIPShell(NonBlockingIPShell):' | |||||
63 | self.parent = parent |
|
65 | self.parent = parent | |
64 |
|
66 | |||
65 | self.ask_exit_callback = ask_exit_handler |
|
67 | self.ask_exit_callback = ask_exit_handler | |
66 |
self._IP.exit = self._ask |
|
68 | self._IP.exit = self._ask_exit | |
67 |
|
69 | |||
68 | def addGUIShortcut(self, text, func): |
|
70 | def addGUIShortcut(self, text, func): | |
69 | wx.CallAfter(self.parent.add_button_handler, |
|
71 | wx.CallAfter(self.parent.add_button_handler, | |
70 | button_info={ 'text':text, |
|
72 | button_info={ 'text':text, | |
71 | 'func':self.parent.doExecuteLine(func)}) |
|
73 | 'func':self.parent.doExecuteLine(func)}) | |
72 |
|
74 | |||
73 |
def _ |
|
75 | def _raw_input(self, prompt=''): | |
|
76 | """ A replacement from python's raw_input. | |||
|
77 | """ | |||
|
78 | self.answer = None | |||
|
79 | if(self._threading == True): | |||
|
80 | wx.CallAfter(self._yesNoBox, prompt) | |||
|
81 | while self.answer is None: | |||
|
82 | time.sleep(.1) | |||
|
83 | else: | |||
|
84 | self._yesNoBox(prompt) | |||
|
85 | return self.answer | |||
|
86 | ||||
|
87 | def _yesNoBox(self, prompt): | |||
|
88 | """ yes/no box managed with wx.CallAfter jsut in case caler is executed in a thread""" | |||
|
89 | dlg = wx.TextEntryDialog( | |||
|
90 | self.parent, prompt, | |||
|
91 | 'Input requested', 'Python') | |||
|
92 | dlg.SetValue("") | |||
|
93 | ||||
|
94 | answer = '' | |||
|
95 | if dlg.ShowModal() == wx.ID_OK: | |||
|
96 | answer = dlg.GetValue() | |||
|
97 | ||||
|
98 | dlg.Destroy() | |||
|
99 | self.answer = answer | |||
|
100 | ||||
|
101 | def _ask_exit(self): | |||
74 | wx.CallAfter(self.ask_exit_callback, ()) |
|
102 | wx.CallAfter(self.ask_exit_callback, ()) | |
75 |
|
103 | |||
76 |
def _after |
|
104 | def _after_execute(self): | |
77 | wx.CallAfter(self.parent.evtStateExecuteDone, ()) |
|
105 | wx.CallAfter(self.parent.evtStateExecuteDone, ()) | |
78 |
|
106 | |||
79 |
|
107 | |||
@@ -249,22 +277,15 b' class WxConsoleView(stc.StyledTextCtrl):' | |||||
249 | @type text: string |
|
277 | @type text: string | |
250 | ''' |
|
278 | ''' | |
251 | try: |
|
279 | try: | |
252 | #print >>sys.__stdout__,'entering' |
|
|||
253 | wx.MutexGuiEnter() |
|
280 | wx.MutexGuiEnter() | |
254 | #print >>sys.__stdout__,'locking the GUI' |
|
|||
255 |
|
281 | |||
256 | #be sure not to be interrutpted before the MutexGuiLeave! |
|
282 | #be sure not to be interrutpted before the MutexGuiLeave! | |
257 | self.write(text) |
|
283 | self.write(text) | |
258 |
|
284 | |||
259 | #print >>sys.__stdout__,'done' |
|
|||
260 |
|
||||
261 | except KeyboardInterrupt: |
|
285 | except KeyboardInterrupt: | |
262 | #print >>sys.__stdout__,'got keyboard interrupt' |
|
|||
263 | wx.MutexGuiLeave() |
|
286 | wx.MutexGuiLeave() | |
264 | #print >>sys.__stdout__,'interrupt unlock the GUI' |
|
|||
265 | raise KeyboardInterrupt |
|
287 | raise KeyboardInterrupt | |
266 | wx.MutexGuiLeave() |
|
288 | wx.MutexGuiLeave() | |
267 | #print >>sys.__stdout__,'normal unlock the GUI' |
|
|||
268 |
|
289 | |||
269 |
|
290 | |||
270 | def write(self, text): |
|
291 | def write(self, text): | |
@@ -419,7 +440,7 b' class WxConsoleView(stc.StyledTextCtrl):' | |||||
419 | self.AutoCompSetIgnoreCase(False) |
|
440 | self.AutoCompSetIgnoreCase(False) | |
420 | self.AutoCompSetAutoHide(False) |
|
441 | self.AutoCompSetAutoHide(False) | |
421 | #let compute the length ot last word |
|
442 | #let compute the length ot last word | |
422 | splitter = [' ', '(', '[', '{'] |
|
443 | splitter = [' ', '(', '[', '{','='] | |
423 | last_word = self.getCurrentLine() |
|
444 | last_word = self.getCurrentLine() | |
424 | for breaker in splitter: |
|
445 | for breaker in splitter: | |
425 | last_word = last_word.split(breaker)[-1] |
|
446 | last_word = last_word.split(breaker)[-1] | |
@@ -439,7 +460,6 b' class WxConsoleView(stc.StyledTextCtrl):' | |||||
439 | @return: Return True if event as been catched. |
|
460 | @return: Return True if event as been catched. | |
440 | @rtype: boolean |
|
461 | @rtype: boolean | |
441 | ''' |
|
462 | ''' | |
442 |
|
||||
443 | if not self.AutoCompActive(): |
|
463 | if not self.AutoCompActive(): | |
444 | if event.GetKeyCode() == wx.WXK_HOME: |
|
464 | if event.GetKeyCode() == wx.WXK_HOME: | |
445 | if event.Modifiers == wx.MOD_NONE: |
|
465 | if event.Modifiers == wx.MOD_NONE: | |
@@ -554,24 +574,30 b' class IPShellWidget(wx.Panel):' | |||||
554 | #with intro='' |
|
574 | #with intro='' | |
555 | if intro is None: |
|
575 | if intro is None: | |
556 | welcome_text = "Welcome to WxIPython Shell.\n\n" |
|
576 | welcome_text = "Welcome to WxIPython Shell.\n\n" | |
557 |
welcome_text+= self.IP.get |
|
577 | welcome_text+= self.IP.get_banner() | |
558 | welcome_text+= "!command -> Execute command in shell\n" |
|
578 | welcome_text+= "!command -> Execute command in shell\n" | |
559 | welcome_text+= "TAB -> Autocompletion\n" |
|
579 | welcome_text+= "TAB -> Autocompletion\n" | |
560 | else: |
|
580 | else: | |
561 | welcome_text = intro |
|
581 | welcome_text = intro | |
562 |
|
582 | |||
563 | self.text_ctrl = WxConsoleView(self, |
|
583 | self.text_ctrl = WxConsoleView(self, | |
564 |
self.IP.get |
|
584 | self.IP.get_prompt(), | |
565 | intro=welcome_text, |
|
585 | intro=welcome_text, | |
566 | background_color=background_color) |
|
586 | background_color=background_color) | |
567 |
|
587 | |||
568 | self.cout.write = self.text_ctrl.asyncWrite |
|
|||
569 |
|
||||
570 | option_text = wx.StaticText(self, -1, "Options:") |
|
588 | option_text = wx.StaticText(self, -1, "Options:") | |
571 | self.completion_option = wx.CheckBox(self, -1, "Scintilla Completion") |
|
589 | self.completion_option = wx.CheckBox(self, -1, "Scintilla Completion") | |
|
590 | self.completion_option.SetToolTip(wx.ToolTip( | |||
|
591 | "Selects the completion type:\nEither Ipython default style or Scintilla one")) | |||
572 | #self.completion_option.SetValue(False) |
|
592 | #self.completion_option.SetValue(False) | |
573 | self.background_option = wx.CheckBox(self, -1, "White Background") |
|
593 | self.background_option = wx.CheckBox(self, -1, "White Background") | |
|
594 | self.background_option.SetToolTip(wx.ToolTip( | |||
|
595 | "Selects the back ground color: BLACK or WHITE")) | |||
574 | #self.background_option.SetValue(False) |
|
596 | #self.background_option.SetValue(False) | |
|
597 | self.threading_option = wx.CheckBox(self, -1, "Execute in thread") | |||
|
598 | self.threading_option.SetToolTip(wx.ToolTip( | |||
|
599 | "Use threading: infinite loop don't freeze the GUI and commands can be breaked\nNo threading: maximum compatibility")) | |||
|
600 | #self.threading_option.SetValue(False) | |||
575 |
|
601 | |||
576 | self.options={'completion':{'value':'IPYTHON', |
|
602 | self.options={'completion':{'value':'IPYTHON', | |
577 | 'checkbox':self.completion_option,'STC':True,'IPYTHON':False, |
|
603 | 'checkbox':self.completion_option,'STC':True,'IPYTHON':False, | |
@@ -579,12 +605,20 b' class IPShellWidget(wx.Panel):' | |||||
579 | 'background_color':{'value':'BLACK', |
|
605 | 'background_color':{'value':'BLACK', | |
580 | 'checkbox':self.background_option,'WHITE':True,'BLACK':False, |
|
606 | 'checkbox':self.background_option,'WHITE':True,'BLACK':False, | |
581 | 'setfunc':self.text_ctrl.setBackgroundColor}, |
|
607 | 'setfunc':self.text_ctrl.setBackgroundColor}, | |
|
608 | 'threading':{'value':'True', | |||
|
609 | 'checkbox':self.threading_option,'True':True,'False':False, | |||
|
610 | 'setfunc':self.IP.set_threading}, | |||
582 | } |
|
611 | } | |
|
612 | ||||
|
613 | #self.cout.write dEfault option is asynchroneous because default sate is threading ON | |||
|
614 | self.cout.write = self.text_ctrl.asyncWrite | |||
|
615 | #we reloard options | |||
583 | self.reloadOptions(self.options) |
|
616 | self.reloadOptions(self.options) | |
584 |
|
617 | |||
585 | self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.keyPress) |
|
618 | self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.keyPress) | |
586 | self.completion_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionCompletion) |
|
619 | self.completion_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionCompletion) | |
587 | self.background_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionBackgroundColor) |
|
620 | self.background_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionBackgroundColor) | |
|
621 | self.threading_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionThreading) | |||
588 |
|
622 | |||
589 | ### making the layout of the panel ### |
|
623 | ### making the layout of the panel ### | |
590 | sizer = wx.BoxSizer(wx.VERTICAL) |
|
624 | sizer = wx.BoxSizer(wx.VERTICAL) | |
@@ -596,7 +630,9 b' class IPShellWidget(wx.Panel):' | |||||
596 | (5, 5), |
|
630 | (5, 5), | |
597 | (self.completion_option, 0, wx.ALIGN_CENTER_VERTICAL), |
|
631 | (self.completion_option, 0, wx.ALIGN_CENTER_VERTICAL), | |
598 | (8, 8), |
|
632 | (8, 8), | |
599 | (self.background_option, 0, wx.ALIGN_CENTER_VERTICAL) |
|
633 | (self.background_option, 0, wx.ALIGN_CENTER_VERTICAL), | |
|
634 | (8, 8), | |||
|
635 | (self.threading_option, 0, wx.ALIGN_CENTER_VERTICAL) | |||
600 | ]) |
|
636 | ]) | |
601 | self.SetAutoLayout(True) |
|
637 | self.SetAutoLayout(True) | |
602 | sizer.Fit(self) |
|
638 | sizer.Fit(self) | |
@@ -619,13 +655,15 b' class IPShellWidget(wx.Panel):' | |||||
619 | self.text_ctrl.write('\n') |
|
655 | self.text_ctrl.write('\n') | |
620 | lines_to_execute = lines.replace('\t',' '*4) |
|
656 | lines_to_execute = lines.replace('\t',' '*4) | |
621 | lines_to_execute = lines_to_execute.replace('\r','') |
|
657 | lines_to_execute = lines_to_execute.replace('\r','') | |
622 |
self.IP.do |
|
658 | self.IP.do_execute(lines_to_execute.encode(ENCODING)) | |
623 | self.updateHistoryTracker(lines) |
|
659 | self.updateHistoryTracker(lines) | |
|
660 | if(self.text_ctrl.getCursorPos()!=0): | |||
|
661 | self.text_ctrl.removeCurrentLine() | |||
624 | self.setCurrentState('WAIT_END_OF_EXECUTION') |
|
662 | self.setCurrentState('WAIT_END_OF_EXECUTION') | |
625 |
|
663 | |||
626 | def evtStateExecuteDone(self,evt): |
|
664 | def evtStateExecuteDone(self,evt): | |
627 |
self.doc = self.IP.get |
|
665 | self.doc = self.IP.get_doc_text() | |
628 |
self.help = self.IP.get |
|
666 | self.help = self.IP.get_help_text() | |
629 | if self.doc: |
|
667 | if self.doc: | |
630 | self.pager_lines = self.doc[7:].split('\n') |
|
668 | self.pager_lines = self.doc[7:].split('\n') | |
631 | self.pager_state = 'INIT' |
|
669 | self.pager_state = 'INIT' | |
@@ -637,15 +675,17 b' class IPShellWidget(wx.Panel):' | |||||
637 | self.setCurrentState('SHOW_DOC') |
|
675 | self.setCurrentState('SHOW_DOC') | |
638 | self.pager(self.help) |
|
676 | self.pager(self.help) | |
639 | else: |
|
677 | else: | |
|
678 | if(self.text_ctrl.getCursorPos()!=0): | |||
|
679 | self.text_ctrl.removeCurrentLine() | |||
640 | self.stateShowPrompt() |
|
680 | self.stateShowPrompt() | |
641 |
|
681 | |||
642 | def stateShowPrompt(self): |
|
682 | def stateShowPrompt(self): | |
643 | self.setCurrentState('SHOW_PROMPT') |
|
683 | self.setCurrentState('SHOW_PROMPT') | |
644 |
self.text_ctrl.setPrompt(self.IP.get |
|
684 | self.text_ctrl.setPrompt(self.IP.get_prompt()) | |
645 |
self.text_ctrl.setIndentation(self.IP.get |
|
685 | self.text_ctrl.setIndentation(self.IP.get_indentation()) | |
646 |
self.text_ctrl.setPromptCount(self.IP.get |
|
686 | self.text_ctrl.setPromptCount(self.IP.get_prompt_count()) | |
647 | self.text_ctrl.showPrompt() |
|
687 | self.text_ctrl.showPrompt() | |
648 |
self.IP.init |
|
688 | self.IP.init_history_index() | |
649 | self.setCurrentState('IDLE') |
|
689 | self.setCurrentState('IDLE') | |
650 |
|
690 | |||
651 | def setCurrentState(self, state): |
|
691 | def setCurrentState(self, state): | |
@@ -751,11 +791,11 b' class IPShellWidget(wx.Panel):' | |||||
751 |
|
791 | |||
752 | if self.cur_state == 'IDLE': |
|
792 | if self.cur_state == 'IDLE': | |
753 | if event.KeyCode == wx.WXK_UP: |
|
793 | if event.KeyCode == wx.WXK_UP: | |
754 |
history = self.IP.history |
|
794 | history = self.IP.history_back() | |
755 | self.text_ctrl.writeHistory(history) |
|
795 | self.text_ctrl.writeHistory(history) | |
756 | return |
|
796 | return | |
757 | if event.KeyCode == wx.WXK_DOWN: |
|
797 | if event.KeyCode == wx.WXK_DOWN: | |
758 |
history = self.IP.history |
|
798 | history = self.IP.history_forward() | |
759 | self.text_ctrl.writeHistory(history) |
|
799 | self.text_ctrl.writeHistory(history) | |
760 | return |
|
800 | return | |
761 | if event.KeyCode == wx.WXK_TAB: |
|
801 | if event.KeyCode == wx.WXK_TAB: | |
@@ -802,7 +842,20 b' class IPShellWidget(wx.Panel):' | |||||
802 | self.updateOptionTracker('background_color', |
|
842 | self.updateOptionTracker('background_color', | |
803 | self.options['background_color']['value']) |
|
843 | self.options['background_color']['value']) | |
804 | self.text_ctrl.SetFocus() |
|
844 | self.text_ctrl.SetFocus() | |
805 |
|
845 | |||
|
846 | def evtCheckOptionThreading(self, event): | |||
|
847 | if event.IsChecked(): | |||
|
848 | self.options['threading']['value']='True' | |||
|
849 | self.IP.set_threading(True) | |||
|
850 | self.cout.write = self.text_ctrl.asyncWrite | |||
|
851 | else: | |||
|
852 | self.options['threading']['value']='False' | |||
|
853 | self.IP.set_threading(False) | |||
|
854 | self.cout.write = self.text_ctrl.write | |||
|
855 | self.updateOptionTracker('threading', | |||
|
856 | self.options['threading']['value']) | |||
|
857 | self.text_ctrl.SetFocus() | |||
|
858 | ||||
806 | def getOptions(self): |
|
859 | def getOptions(self): | |
807 | return self.options |
|
860 | return self.options | |
808 |
|
861 | |||
@@ -813,7 +866,13 b' class IPShellWidget(wx.Panel):' | |||||
813 | self.options[key]['checkbox'].SetValue(self.options[key][value]) |
|
866 | self.options[key]['checkbox'].SetValue(self.options[key][value]) | |
814 | self.options[key]['setfunc'](value) |
|
867 | self.options[key]['setfunc'](value) | |
815 |
|
868 | |||
816 |
|
869 | if self.options['threading']['value']=='True': | ||
|
870 | self.IP.set_threading(True) | |||
|
871 | self.cout.write = self.text_ctrl.asyncWrite | |||
|
872 | else: | |||
|
873 | self.IP.set_threading(False) | |||
|
874 | self.cout.write = self.text_ctrl.write | |||
|
875 | ||||
817 | #------------------------ Hook Section ----------------------------------- |
|
876 | #------------------------ Hook Section ----------------------------------- | |
818 | def updateOptionTracker(self,name,value): |
|
877 | def updateOptionTracker(self,name,value): | |
819 | ''' |
|
878 | ''' | |
@@ -881,5 +940,3 b" if __name__ == '__main__':" | |||||
881 | shell = frame.shell |
|
940 | shell = frame.shell | |
882 |
|
941 | |||
883 | app.MainLoop() |
|
942 | app.MainLoop() | |
884 |
|
||||
885 |
|
@@ -10,10 +10,18 b' from wx.lib.wordwrap import wordwrap' | |||||
10 | from IPython.gui.wx.ipython_view import IPShellWidget |
|
10 | from IPython.gui.wx.ipython_view import IPShellWidget | |
11 | from IPython.gui.wx.ipython_history import IPythonHistoryPanel |
|
11 | from IPython.gui.wx.ipython_history import IPythonHistoryPanel | |
12 |
|
12 | |||
|
13 | #used to invoke ipython1 wx implementation | |||
|
14 | ### FIXME ### temporary disabled due to interference with 'show_in_pager' hook | |||
|
15 | is_sync_frontend_ok = False | |||
|
16 | try: | |||
|
17 | from IPython.frontend.wx.ipythonx import IPythonXController | |||
|
18 | except ImportError: | |||
|
19 | is_sync_frontend_ok = False | |||
|
20 | ||||
13 | #used to create options.conf file in user directory |
|
21 | #used to create options.conf file in user directory | |
14 | from IPython.ipapi import get |
|
22 | from IPython.ipapi import get | |
15 |
|
23 | |||
16 |
__version__ = 0. |
|
24 | __version__ = 0.91 | |
17 | __author__ = "Laurent Dufrechou" |
|
25 | __author__ = "Laurent Dufrechou" | |
18 | __email__ = "laurent.dufrechou _at_ gmail.com" |
|
26 | __email__ = "laurent.dufrechou _at_ gmail.com" | |
19 | __license__ = "BSD" |
|
27 | __license__ = "BSD" | |
@@ -27,7 +35,7 b' class MyFrame(wx.Frame):' | |||||
27 | application with movables windows""" |
|
35 | application with movables windows""" | |
28 | def __init__(self, parent=None, id=-1, title="WxIPython", |
|
36 | def __init__(self, parent=None, id=-1, title="WxIPython", | |
29 | pos=wx.DefaultPosition, |
|
37 | pos=wx.DefaultPosition, | |
30 | size=(800, 600), style=wx.DEFAULT_FRAME_STYLE): |
|
38 | size=(800, 600), style=wx.DEFAULT_FRAME_STYLE, sync_ok=False): | |
31 | wx.Frame.__init__(self, parent, id, title, pos, size, style) |
|
39 | wx.Frame.__init__(self, parent, id, title, pos, size, style) | |
32 | self._mgr = wx.aui.AuiManager() |
|
40 | self._mgr = wx.aui.AuiManager() | |
33 |
|
41 | |||
@@ -41,12 +49,18 b' class MyFrame(wx.Frame):' | |||||
41 |
|
49 | |||
42 | self.ipython_panel = IPShellWidget(self,background_color = "BLACK") |
|
50 | self.ipython_panel = IPShellWidget(self,background_color = "BLACK") | |
43 | #self.ipython_panel = IPShellWidget(self,background_color = "WHITE") |
|
51 | #self.ipython_panel = IPShellWidget(self,background_color = "WHITE") | |
44 |
|
52 | if(sync_ok): | ||
|
53 | self.ipython_panel2 = IPythonXController(self) | |||
|
54 | else: | |||
|
55 | self.ipython_panel2 = None | |||
45 | self.ipython_panel.setHistoryTrackerHook(self.history_panel.write) |
|
56 | self.ipython_panel.setHistoryTrackerHook(self.history_panel.write) | |
46 | self.ipython_panel.setStatusTrackerHook(self.updateStatus) |
|
57 | self.ipython_panel.setStatusTrackerHook(self.updateStatus) | |
47 | self.ipython_panel.setAskExitHandler(self.OnExitDlg) |
|
58 | self.ipython_panel.setAskExitHandler(self.OnExitDlg) | |
48 | self.ipython_panel.setOptionTrackerHook(self.optionSave) |
|
59 | self.ipython_panel.setOptionTrackerHook(self.optionSave) | |
49 |
|
60 | |||
|
61 | #Create a notebook to display different IPython shell implementations | |||
|
62 | self.nb = wx.aui.AuiNotebook(self) | |||
|
63 | ||||
50 | self.optionLoad() |
|
64 | self.optionLoad() | |
51 |
|
65 | |||
52 | self.statusbar = self.createStatus() |
|
66 | self.statusbar = self.createStatus() | |
@@ -55,7 +69,11 b' class MyFrame(wx.Frame):' | |||||
55 | ######################################################################## |
|
69 | ######################################################################## | |
56 | ### add the panes to the manager |
|
70 | ### add the panes to the manager | |
57 | # main panels |
|
71 | # main panels | |
58 |
self._mgr.AddPane(self. |
|
72 | self._mgr.AddPane(self.nb , wx.CENTER, "IPython Shells") | |
|
73 | self.nb.AddPage(self.ipython_panel , "IPython0 Shell") | |||
|
74 | if(sync_ok): | |||
|
75 | self.nb.AddPage(self.ipython_panel2, "IPython1 Synchroneous Shell") | |||
|
76 | ||||
59 | self._mgr.AddPane(self.history_panel , wx.RIGHT, "IPython history") |
|
77 | self._mgr.AddPane(self.history_panel , wx.RIGHT, "IPython history") | |
60 |
|
78 | |||
61 | # now we specify some panel characteristics |
|
79 | # now we specify some panel characteristics | |
@@ -77,7 +95,10 b' class MyFrame(wx.Frame):' | |||||
77 | warn_text = 'Hello from IPython and wxPython.\n' |
|
95 | warn_text = 'Hello from IPython and wxPython.\n' | |
78 | warn_text +='Please Note that this work is still EXPERIMENTAL\n' |
|
96 | warn_text +='Please Note that this work is still EXPERIMENTAL\n' | |
79 | warn_text +='It does NOT emulate currently all the IPython functions.\n' |
|
97 | warn_text +='It does NOT emulate currently all the IPython functions.\n' | |
80 |
|
98 | warn_text +="\nIf you use MATPLOTLIB with show() you'll need to deactivate the THREADING option.\n" | ||
|
99 | if(not sync_ok): | |||
|
100 | warn_text +="\n->No twisted package detected, IPython1 example deactivated." | |||
|
101 | ||||
81 | dlg = wx.MessageDialog(self, |
|
102 | dlg = wx.MessageDialog(self, | |
82 | warn_text, |
|
103 | warn_text, | |
83 | 'Warning Box', |
|
104 | 'Warning Box', | |
@@ -146,13 +167,6 b' class MyFrame(wx.Frame):' | |||||
146 | about_menu = wx.Menu() |
|
167 | about_menu = wx.Menu() | |
147 | about_menu.Append(wx.ID_HIGHEST+3, "About") |
|
168 | about_menu.Append(wx.ID_HIGHEST+3, "About") | |
148 |
|
169 | |||
149 | #view_menu.AppendSeparator() |
|
|||
150 | #options_menu = wx.Menu() |
|
|||
151 | #options_menu.AppendCheckItem(wx.ID_HIGHEST+7, "Allow Floating") |
|
|||
152 | #options_menu.AppendCheckItem(wx.ID_HIGHEST+8, "Transparent Hint") |
|
|||
153 | #options_menu.AppendCheckItem(wx.ID_HIGHEST+9, "Transparent Hint Fade-in") |
|
|||
154 |
|
||||
155 |
|
||||
156 | mb.Append(file_menu, "File") |
|
170 | mb.Append(file_menu, "File") | |
157 | mb.Append(view_menu, "View") |
|
171 | mb.Append(view_menu, "View") | |
158 | mb.Append(about_menu, "About") |
|
172 | mb.Append(about_menu, "About") | |
@@ -233,17 +247,17 b' class MyFrame(wx.Frame):' | |||||
233 | #----------------------------------------- |
|
247 | #----------------------------------------- | |
234 | class MyApp(wx.PySimpleApp): |
|
248 | class MyApp(wx.PySimpleApp): | |
235 | """Creating our application""" |
|
249 | """Creating our application""" | |
236 | def __init__(self): |
|
250 | def __init__(self, sync_ok=False): | |
237 | wx.PySimpleApp.__init__(self) |
|
251 | wx.PySimpleApp.__init__(self) | |
238 |
|
252 | |||
239 | self.frame = MyFrame() |
|
253 | self.frame = MyFrame(sync_ok=sync_ok) | |
240 | self.frame.Show() |
|
254 | self.frame.Show() | |
241 |
|
255 | |||
242 | #----------------------------------------- |
|
256 | #----------------------------------------- | |
243 | #Main loop |
|
257 | #Main loop | |
244 | #----------------------------------------- |
|
258 | #----------------------------------------- | |
245 | def main(): |
|
259 | def main(): | |
246 | app = MyApp() |
|
260 | app = MyApp(is_sync_frontend_ok) | |
247 | app.SetTopWindow(app.frame) |
|
261 | app.SetTopWindow(app.frame) | |
248 | app.MainLoop() |
|
262 | app.MainLoop() | |
249 |
|
263 |
@@ -1,5 +1,4 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
||||
3 | """ History related magics and functionality """ |
|
2 | """ History related magics and functionality """ | |
4 |
|
3 | |||
5 | # Stdlib imports |
|
4 | # Stdlib imports | |
@@ -7,7 +6,7 b' import fnmatch' | |||||
7 | import os |
|
6 | import os | |
8 |
|
7 | |||
9 | # IPython imports |
|
8 | # IPython imports | |
10 | from IPython.genutils import Term, ask_yes_no |
|
9 | from IPython.genutils import Term, ask_yes_no, warn | |
11 | import IPython.ipapi |
|
10 | import IPython.ipapi | |
12 |
|
11 | |||
13 | def magic_history(self, parameter_s = ''): |
|
12 | def magic_history(self, parameter_s = ''): | |
@@ -47,8 +46,6 b" def magic_history(self, parameter_s = ''):" | |||||
47 | -f FILENAME: instead of printing the output to the screen, redirect it to |
|
46 | -f FILENAME: instead of printing the output to the screen, redirect it to | |
48 | the given file. The file is always overwritten, though IPython asks for |
|
47 | the given file. The file is always overwritten, though IPython asks for | |
49 | confirmation first if it already exists. |
|
48 | confirmation first if it already exists. | |
50 |
|
||||
51 |
|
||||
52 | """ |
|
49 | """ | |
53 |
|
50 | |||
54 | ip = self.api |
|
51 | ip = self.api | |
@@ -62,31 +59,28 b" def magic_history(self, parameter_s = ''):" | |||||
62 | try: |
|
59 | try: | |
63 | outfname = opts['f'] |
|
60 | outfname = opts['f'] | |
64 | except KeyError: |
|
61 | except KeyError: | |
65 | outfile = Term.cout |
|
62 | outfile = Term.cout # default | |
66 | # We don't want to close stdout at the end! |
|
63 | # We don't want to close stdout at the end! | |
67 | close_at_end = False |
|
64 | close_at_end = False | |
68 | else: |
|
65 | else: | |
69 | if os.path.exists(outfname): |
|
66 | if os.path.exists(outfname): | |
70 |
|
|
67 | if not ask_yes_no("File %r exists. Overwrite?" % outfname): | |
71 | if not ans: |
|
|||
72 | print 'Aborting.' |
|
68 | print 'Aborting.' | |
73 | return |
|
69 | return | |
74 | else: |
|
|||
75 | outfile = open(outfname,'w') |
|
|||
76 | close_at_end = True |
|
|||
77 |
|
||||
78 |
|
70 | |||
79 | if opts.has_key('t'): |
|
71 | outfile = open(outfname,'w') | |
|
72 | close_at_end = True | |||
|
73 | ||||
|
74 | if 't' in opts: | |||
80 | input_hist = shell.input_hist |
|
75 | input_hist = shell.input_hist | |
81 | elif opts.has_key('r'): |
|
76 | elif 'r' in opts: | |
82 | input_hist = shell.input_hist_raw |
|
77 | input_hist = shell.input_hist_raw | |
83 | else: |
|
78 | else: | |
84 | input_hist = shell.input_hist |
|
79 | input_hist = shell.input_hist | |
85 |
|
80 | |||
86 |
|
||||
87 | default_length = 40 |
|
81 | default_length = 40 | |
88 | pattern = None |
|
82 | pattern = None | |
89 | if opts.has_key('g'): |
|
83 | if 'g' in opts: | |
90 | init = 1 |
|
84 | init = 1 | |
91 | final = len(input_hist) |
|
85 | final = len(input_hist) | |
92 | parts = parameter_s.split(None,1) |
|
86 | parts = parameter_s.split(None,1) | |
@@ -138,13 +132,11 b" def magic_history(self, parameter_s = ''):" | |||||
138 | outfile.close() |
|
132 | outfile.close() | |
139 |
|
133 | |||
140 |
|
134 | |||
141 |
|
||||
142 | def magic_hist(self, parameter_s=''): |
|
135 | def magic_hist(self, parameter_s=''): | |
143 | """Alternate name for %history.""" |
|
136 | """Alternate name for %history.""" | |
144 | return self.magic_history(parameter_s) |
|
137 | return self.magic_history(parameter_s) | |
145 |
|
138 | |||
146 |
|
139 | |||
147 |
|
||||
148 | def rep_f(self, arg): |
|
140 | def rep_f(self, arg): | |
149 | r""" Repeat a command, or get command to input line for editing |
|
141 | r""" Repeat a command, or get command to input line for editing | |
150 |
|
142 | |||
@@ -173,11 +165,9 b' def rep_f(self, arg):' | |||||
173 | %rep foo |
|
165 | %rep foo | |
174 |
|
166 | |||
175 | Place the most recent line that has the substring "foo" to next input. |
|
167 | Place the most recent line that has the substring "foo" to next input. | |
176 | (e.g. 'svn ci -m foobar'). |
|
168 | (e.g. 'svn ci -m foobar'). | |
177 |
|
||||
178 | """ |
|
169 | """ | |
179 |
|
170 | |||
180 |
|
||||
181 | opts,args = self.parse_options(arg,'',mode='list') |
|
171 | opts,args = self.parse_options(arg,'',mode='list') | |
182 | ip = self.api |
|
172 | ip = self.api | |
183 | if not args: |
|
173 | if not args: | |
@@ -206,7 +196,6 b' def rep_f(self, arg):' | |||||
206 | ip.set_next_input(str(h).rstrip()) |
|
196 | ip.set_next_input(str(h).rstrip()) | |
207 | return |
|
197 | return | |
208 |
|
198 | |||
209 |
|
||||
210 | try: |
|
199 | try: | |
211 | lines = self.extract_input_slices(args, True) |
|
200 | lines = self.extract_input_slices(args, True) | |
212 | print "lines",lines |
|
201 | print "lines",lines | |
@@ -215,7 +204,6 b' def rep_f(self, arg):' | |||||
215 | print "Not found in recent history:", args |
|
204 | print "Not found in recent history:", args | |
216 |
|
205 | |||
217 |
|
206 | |||
218 |
|
||||
219 | _sentinel = object() |
|
207 | _sentinel = object() | |
220 |
|
208 | |||
221 | class ShadowHist: |
|
209 | class ShadowHist: | |
@@ -259,23 +247,12 b' class ShadowHist:' | |||||
259 | if k == idx: |
|
247 | if k == idx: | |
260 | return v |
|
248 | return v | |
261 |
|
249 | |||
262 | def test_shist(): |
|
|||
263 | from IPython.Extensions import pickleshare |
|
|||
264 | db = pickleshare.PickleShareDB('~/shist') |
|
|||
265 | s = ShadowHist(db) |
|
|||
266 | s.add('hello') |
|
|||
267 | s.add('world') |
|
|||
268 | s.add('hello') |
|
|||
269 | s.add('hello') |
|
|||
270 | s.add('karhu') |
|
|||
271 | print "all",s.all() |
|
|||
272 | print s.get(2) |
|
|||
273 |
|
250 | |||
274 | def init_ipython(ip): |
|
251 | def init_ipython(ip): | |
|
252 | import ipy_completers | |||
|
253 | ||||
275 | ip.expose_magic("rep",rep_f) |
|
254 | ip.expose_magic("rep",rep_f) | |
276 | ip.expose_magic("hist",magic_hist) |
|
255 | ip.expose_magic("hist",magic_hist) | |
277 | ip.expose_magic("history",magic_history) |
|
256 | ip.expose_magic("history",magic_history) | |
278 |
|
257 | |||
279 | import ipy_completers |
|
|||
280 | ipy_completers.quick_completer('%hist' ,'-g -t -r -n') |
|
258 | ipy_completers.quick_completer('%hist' ,'-g -t -r -n') | |
281 | #test_shist() |
|
@@ -32,8 +32,7 b" ip.set_hook('editor', calljed)" | |||||
32 |
|
32 | |||
33 | You can then enable the functionality by doing 'import myiphooks' |
|
33 | You can then enable the functionality by doing 'import myiphooks' | |
34 | somewhere in your configuration files or ipython command line. |
|
34 | somewhere in your configuration files or ipython command line. | |
35 |
|
35 | """ | ||
36 | $Id: hooks.py 2998 2008-01-31 10:06:04Z vivainio $""" |
|
|||
37 |
|
36 | |||
38 | #***************************************************************************** |
|
37 | #***************************************************************************** | |
39 | # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu> |
|
38 | # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu> | |
@@ -42,11 +41,7 b' $Id: hooks.py 2998 2008-01-31 10:06:04Z vivainio $"""' | |||||
42 | # the file COPYING, distributed as part of this software. |
|
41 | # the file COPYING, distributed as part of this software. | |
43 | #***************************************************************************** |
|
42 | #***************************************************************************** | |
44 |
|
43 | |||
45 | from IPython import Release |
|
|||
46 | from IPython import ipapi |
|
44 | from IPython import ipapi | |
47 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
48 | __license__ = Release.license |
|
|||
49 | __version__ = Release.version |
|
|||
50 |
|
45 | |||
51 | import os,bisect |
|
46 | import os,bisect | |
52 | from genutils import Term,shell |
|
47 | from genutils import Term,shell |
@@ -24,7 +24,6 b' That way the module is imported at startup and you can have all your' | |||||
24 | personal configuration (as opposed to boilerplate ipythonrc-PROFILENAME |
|
24 | personal configuration (as opposed to boilerplate ipythonrc-PROFILENAME | |
25 | stuff) in there. |
|
25 | stuff) in there. | |
26 |
|
26 | |||
27 | ----------------------------------------------- |
|
|||
28 | import IPython.ipapi |
|
27 | import IPython.ipapi | |
29 | ip = IPython.ipapi.get() |
|
28 | ip = IPython.ipapi.get() | |
30 |
|
29 | |||
@@ -187,7 +186,6 b' class IPApi(object):' | |||||
187 | self.set_custom_exc = ip.set_custom_exc |
|
186 | self.set_custom_exc = ip.set_custom_exc | |
188 |
|
187 | |||
189 | self.user_ns = ip.user_ns |
|
188 | self.user_ns = ip.user_ns | |
190 | self.user_ns['_ip'] = self |
|
|||
191 |
|
189 | |||
192 | self.set_crash_handler = ip.set_crash_handler |
|
190 | self.set_crash_handler = ip.set_crash_handler | |
193 |
|
191 |
@@ -2,10 +2,9 b'' | |||||
2 | """ |
|
2 | """ | |
3 | IPython -- An enhanced Interactive Python |
|
3 | IPython -- An enhanced Interactive Python | |
4 |
|
4 | |||
5 |
Requires Python 2. |
|
5 | Requires Python 2.4 or newer. | |
6 |
|
6 | |||
7 | This file contains all the classes and helper functions specific to IPython. |
|
7 | This file contains all the classes and helper functions specific to IPython. | |
8 |
|
||||
9 | """ |
|
8 | """ | |
10 |
|
9 | |||
11 | #***************************************************************************** |
|
10 | #***************************************************************************** | |
@@ -27,12 +26,6 b' This file contains all the classes and helper functions specific to IPython.' | |||||
27 | #**************************************************************************** |
|
26 | #**************************************************************************** | |
28 | # Modules and globals |
|
27 | # Modules and globals | |
29 |
|
28 | |||
30 | from IPython import Release |
|
|||
31 | __author__ = '%s <%s>\n%s <%s>' % \ |
|
|||
32 | ( Release.authors['Janko'] + Release.authors['Fernando'] ) |
|
|||
33 | __license__ = Release.license |
|
|||
34 | __version__ = Release.version |
|
|||
35 |
|
||||
36 | # Python standard modules |
|
29 | # Python standard modules | |
37 | import __main__ |
|
30 | import __main__ | |
38 | import __builtin__ |
|
31 | import __builtin__ | |
@@ -54,9 +47,6 b' import sys' | |||||
54 | import tempfile |
|
47 | import tempfile | |
55 | import traceback |
|
48 | import traceback | |
56 | import types |
|
49 | import types | |
57 | import warnings |
|
|||
58 | warnings.filterwarnings('ignore', r'.*sets module*') |
|
|||
59 | from sets import Set |
|
|||
60 | from pprint import pprint, pformat |
|
50 | from pprint import pprint, pformat | |
61 |
|
51 | |||
62 | # IPython's own modules |
|
52 | # IPython's own modules | |
@@ -292,6 +282,13 b' class InteractiveShell(object,Magic):' | |||||
292 | # This is the namespace where all normal user variables live |
|
282 | # This is the namespace where all normal user variables live | |
293 | self.user_ns = user_ns |
|
283 | self.user_ns = user_ns | |
294 | self.user_global_ns = user_global_ns |
|
284 | self.user_global_ns = user_global_ns | |
|
285 | ||||
|
286 | # An auxiliary namespace that checks what parts of the user_ns were | |||
|
287 | # loaded at startup, so we can list later only variables defined in | |||
|
288 | # actual interactive use. Since it is always a subset of user_ns, it | |||
|
289 | # doesn't need to be seaparately tracked in the ns_table | |||
|
290 | self.user_config_ns = {} | |||
|
291 | ||||
295 | # A namespace to keep track of internal data structures to prevent |
|
292 | # A namespace to keep track of internal data structures to prevent | |
296 | # them from cluttering user-visible stuff. Will be updated later |
|
293 | # them from cluttering user-visible stuff. Will be updated later | |
297 | self.internal_ns = {} |
|
294 | self.internal_ns = {} | |
@@ -301,6 +298,24 b' class InteractiveShell(object,Magic):' | |||||
301 | # of positional arguments of the alias. |
|
298 | # of positional arguments of the alias. | |
302 | self.alias_table = {} |
|
299 | self.alias_table = {} | |
303 |
|
300 | |||
|
301 | # Now that FakeModule produces a real module, we've run into a nasty | |||
|
302 | # problem: after script execution (via %run), the module where the user | |||
|
303 | # code ran is deleted. Now that this object is a true module (needed | |||
|
304 | # so docetst and other tools work correctly), the Python module | |||
|
305 | # teardown mechanism runs over it, and sets to None every variable | |||
|
306 | # present in that module. Top-level references to objects from the | |||
|
307 | # script survive, because the user_ns is updated with them. However, | |||
|
308 | # calling functions defined in the script that use other things from | |||
|
309 | # the script will fail, because the function's closure had references | |||
|
310 | # to the original objects, which are now all None. So we must protect | |||
|
311 | # these modules from deletion by keeping a cache. To avoid keeping | |||
|
312 | # stale modules around (we only need the one from the last run), we use | |||
|
313 | # a dict keyed with the full path to the script, so only the last | |||
|
314 | # version of the module is held in the cache. The %reset command will | |||
|
315 | # flush this cache. See the cache_main_mod() and clear_main_mod_cache() | |||
|
316 | # methods for details on use. | |||
|
317 | self._user_main_modules = {} | |||
|
318 | ||||
304 | # A table holding all the namespaces IPython deals with, so that |
|
319 | # A table holding all the namespaces IPython deals with, so that | |
305 | # introspection facilities can search easily. |
|
320 | # introspection facilities can search easily. | |
306 | self.ns_table = {'user':user_ns, |
|
321 | self.ns_table = {'user':user_ns, | |
@@ -309,9 +324,14 b' class InteractiveShell(object,Magic):' | |||||
309 | 'internal':self.internal_ns, |
|
324 | 'internal':self.internal_ns, | |
310 | 'builtin':__builtin__.__dict__ |
|
325 | 'builtin':__builtin__.__dict__ | |
311 | } |
|
326 | } | |
312 | # The user namespace MUST have a pointer to the shell itself. |
|
|||
313 | self.user_ns[name] = self |
|
|||
314 |
|
327 | |||
|
328 | # Similarly, track all namespaces where references can be held and that | |||
|
329 | # we can safely clear (so it can NOT include builtin). This one can be | |||
|
330 | # a simple list. | |||
|
331 | self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns, | |||
|
332 | self.alias_table, self.internal_ns, | |||
|
333 | self._user_main_modules ] | |||
|
334 | ||||
315 | # We need to insert into sys.modules something that looks like a |
|
335 | # We need to insert into sys.modules something that looks like a | |
316 | # module but which accesses the IPython namespace, for shelve and |
|
336 | # module but which accesses the IPython namespace, for shelve and | |
317 | # pickle to work interactively. Normally they rely on getting |
|
337 | # pickle to work interactively. Normally they rely on getting | |
@@ -336,28 +356,13 b' class InteractiveShell(object,Magic):' | |||||
336 | #print "pickle hack in place" # dbg |
|
356 | #print "pickle hack in place" # dbg | |
337 | #print 'main_name:',main_name # dbg |
|
357 | #print 'main_name:',main_name # dbg | |
338 | sys.modules[main_name] = FakeModule(self.user_ns) |
|
358 | sys.modules[main_name] = FakeModule(self.user_ns) | |
339 |
|
359 | |||
340 | # Now that FakeModule produces a real module, we've run into a nasty |
|
|||
341 | # problem: after script execution (via %run), the module where the user |
|
|||
342 | # code ran is deleted. Now that this object is a true module (needed |
|
|||
343 | # so docetst and other tools work correctly), the Python module |
|
|||
344 | # teardown mechanism runs over it, and sets to None every variable |
|
|||
345 | # present in that module. This means that later calls to functions |
|
|||
346 | # defined in the script (which have become interactively visible after |
|
|||
347 | # script exit) fail, because they hold references to objects that have |
|
|||
348 | # become overwritten into None. The only solution I see right now is |
|
|||
349 | # to protect every FakeModule used by %run by holding an internal |
|
|||
350 | # reference to it. This private list will be used for that. The |
|
|||
351 | # %reset command will flush it as well. |
|
|||
352 | self._user_main_modules = [] |
|
|||
353 |
|
||||
354 | # List of input with multi-line handling. |
|
360 | # List of input with multi-line handling. | |
355 | # Fill its zero entry, user counter starts at 1 |
|
361 | self.input_hist = InputList() | |
356 | self.input_hist = InputList(['\n']) |
|
|||
357 | # This one will hold the 'raw' input history, without any |
|
362 | # This one will hold the 'raw' input history, without any | |
358 | # pre-processing. This will allow users to retrieve the input just as |
|
363 | # pre-processing. This will allow users to retrieve the input just as | |
359 | # it was exactly typed in by the user, with %hist -r. |
|
364 | # it was exactly typed in by the user, with %hist -r. | |
360 |
self.input_hist_raw = InputList( |
|
365 | self.input_hist_raw = InputList() | |
361 |
|
366 | |||
362 | # list of visited directories |
|
367 | # list of visited directories | |
363 | try: |
|
368 | try: | |
@@ -383,17 +388,7 b' class InteractiveShell(object,Magic):' | |||||
383 | no_alias[key] = 1 |
|
388 | no_alias[key] = 1 | |
384 | no_alias.update(__builtin__.__dict__) |
|
389 | no_alias.update(__builtin__.__dict__) | |
385 | self.no_alias = no_alias |
|
390 | self.no_alias = no_alias | |
386 |
|
||||
387 | # make global variables for user access to these |
|
|||
388 | self.user_ns['_ih'] = self.input_hist |
|
|||
389 | self.user_ns['_oh'] = self.output_hist |
|
|||
390 | self.user_ns['_dh'] = self.dir_hist |
|
|||
391 |
|
||||
392 | # user aliases to input and output histories |
|
|||
393 | self.user_ns['In'] = self.input_hist |
|
|||
394 | self.user_ns['Out'] = self.output_hist |
|
|||
395 |
|
391 | |||
396 | self.user_ns['_sh'] = IPython.shadowns |
|
|||
397 | # Object variable to store code object waiting execution. This is |
|
392 | # Object variable to store code object waiting execution. This is | |
398 | # used mainly by the multithreaded shells, but it can come in handy in |
|
393 | # used mainly by the multithreaded shells, but it can come in handy in | |
399 | # other situations. No need to use a Queue here, since it's a single |
|
394 | # other situations. No need to use a Queue here, since it's a single | |
@@ -586,11 +581,13 b' class InteractiveShell(object,Magic):' | |||||
586 | else: |
|
581 | else: | |
587 | auto_alias = () |
|
582 | auto_alias = () | |
588 | self.auto_alias = [s.split(None,1) for s in auto_alias] |
|
583 | self.auto_alias = [s.split(None,1) for s in auto_alias] | |
589 |
|
||||
590 |
|
584 | |||
591 | # Produce a public API instance |
|
585 | # Produce a public API instance | |
592 | self.api = IPython.ipapi.IPApi(self) |
|
586 | self.api = IPython.ipapi.IPApi(self) | |
593 |
|
587 | |||
|
588 | # Initialize all user-visible namespaces | |||
|
589 | self.init_namespaces() | |||
|
590 | ||||
594 | # Call the actual (public) initializer |
|
591 | # Call the actual (public) initializer | |
595 | self.init_auto_alias() |
|
592 | self.init_auto_alias() | |
596 |
|
593 | |||
@@ -601,10 +598,6 b' class InteractiveShell(object,Magic):' | |||||
601 |
|
598 | |||
602 | #TODO: remove this, redundant |
|
599 | #TODO: remove this, redundant | |
603 | self.add_builtins() |
|
600 | self.add_builtins() | |
604 |
|
||||
605 |
|
||||
606 |
|
||||
607 |
|
||||
608 | # end __init__ |
|
601 | # end __init__ | |
609 |
|
602 | |||
610 | def var_expand(self,cmd,depth=0): |
|
603 | def var_expand(self,cmd,depth=0): | |
@@ -633,16 +626,15 b' class InteractiveShell(object,Magic):' | |||||
633 | """ |
|
626 | """ | |
634 | rc = self.rc |
|
627 | rc = self.rc | |
635 | try: |
|
628 | try: | |
636 |
self.db = pickleshare.PickleShareDB(rc.ipythondir + "/db") |
|
629 | self.db = pickleshare.PickleShareDB(rc.ipythondir + "/db") | |
637 | except exceptions.UnicodeDecodeError: |
|
630 | except exceptions.UnicodeDecodeError: | |
638 | print "Your ipythondir can't be decoded to unicode!" |
|
631 | print "Your ipythondir can't be decoded to unicode!" | |
639 | print "Please set HOME environment variable to something that" |
|
632 | print "Please set HOME environment variable to something that" | |
640 | print r"only has ASCII characters, e.g. c:\home" |
|
633 | print r"only has ASCII characters, e.g. c:\home" | |
641 | print "Now it is",rc.ipythondir |
|
634 | print "Now it is",rc.ipythondir | |
642 | sys.exit() |
|
635 | sys.exit() | |
643 |
self.shadowhist = IPython.history.ShadowHist(self.db) |
|
636 | self.shadowhist = IPython.history.ShadowHist(self.db) | |
644 |
|
637 | |||
645 |
|
||||
646 | def post_config_initialization(self): |
|
638 | def post_config_initialization(self): | |
647 | """Post configuration init method |
|
639 | """Post configuration init method | |
648 |
|
640 | |||
@@ -662,7 +654,6 b' class InteractiveShell(object,Magic):' | |||||
662 | # Load readline proper |
|
654 | # Load readline proper | |
663 | if rc.readline: |
|
655 | if rc.readline: | |
664 | self.init_readline() |
|
656 | self.init_readline() | |
665 |
|
||||
666 |
|
657 | |||
667 | # local shortcut, this is used a LOT |
|
658 | # local shortcut, this is used a LOT | |
668 | self.log = self.logger.log |
|
659 | self.log = self.logger.log | |
@@ -729,6 +720,39 b' class InteractiveShell(object,Magic):' | |||||
729 | if batchrun and not self.rc.interact: |
|
720 | if batchrun and not self.rc.interact: | |
730 | self.ask_exit() |
|
721 | self.ask_exit() | |
731 |
|
722 | |||
|
723 | def init_namespaces(self): | |||
|
724 | """Initialize all user-visible namespaces to their minimum defaults. | |||
|
725 | ||||
|
726 | Certain history lists are also initialized here, as they effectively | |||
|
727 | act as user namespaces. | |||
|
728 | ||||
|
729 | Note | |||
|
730 | ---- | |||
|
731 | All data structures here are only filled in, they are NOT reset by this | |||
|
732 | method. If they were not empty before, data will simply be added to | |||
|
733 | therm. | |||
|
734 | """ | |||
|
735 | # The user namespace MUST have a pointer to the shell itself. | |||
|
736 | self.user_ns[self.name] = self | |||
|
737 | ||||
|
738 | # Store the public api instance | |||
|
739 | self.user_ns['_ip'] = self.api | |||
|
740 | ||||
|
741 | # make global variables for user access to the histories | |||
|
742 | self.user_ns['_ih'] = self.input_hist | |||
|
743 | self.user_ns['_oh'] = self.output_hist | |||
|
744 | self.user_ns['_dh'] = self.dir_hist | |||
|
745 | ||||
|
746 | # user aliases to input and output histories | |||
|
747 | self.user_ns['In'] = self.input_hist | |||
|
748 | self.user_ns['Out'] = self.output_hist | |||
|
749 | ||||
|
750 | self.user_ns['_sh'] = IPython.shadowns | |||
|
751 | ||||
|
752 | # Fill the history zero entry, user counter starts at 1 | |||
|
753 | self.input_hist.append('\n') | |||
|
754 | self.input_hist_raw.append('\n') | |||
|
755 | ||||
732 | def add_builtins(self): |
|
756 | def add_builtins(self): | |
733 | """Store ipython references into the builtin namespace. |
|
757 | """Store ipython references into the builtin namespace. | |
734 |
|
758 | |||
@@ -909,7 +933,6 b' class InteractiveShell(object,Magic):' | |||||
909 | call_pdb = property(_get_call_pdb,_set_call_pdb,None, |
|
933 | call_pdb = property(_get_call_pdb,_set_call_pdb,None, | |
910 | 'Control auto-activation of pdb at exceptions') |
|
934 | 'Control auto-activation of pdb at exceptions') | |
911 |
|
935 | |||
912 |
|
||||
913 | # These special functions get installed in the builtin namespace, to |
|
936 | # These special functions get installed in the builtin namespace, to | |
914 | # provide programmatic (pure python) access to magics, aliases and system |
|
937 | # provide programmatic (pure python) access to magics, aliases and system | |
915 | # calls. This is important for logging, user scripting, and more. |
|
938 | # calls. This is important for logging, user scripting, and more. | |
@@ -1139,7 +1162,8 b' IPython will create a minimal default configuration for you.' | |||||
1139 | inif = 'ipythonrc.ini' |
|
1162 | inif = 'ipythonrc.ini' | |
1140 | else: |
|
1163 | else: | |
1141 | inif = 'ipythonrc' |
|
1164 | inif = 'ipythonrc' | |
1142 |
minimal_setup = {'ipy_user_conf.py' : 'import ipy_defaults', |
|
1165 | minimal_setup = {'ipy_user_conf.py' : 'import ipy_defaults', | |
|
1166 | inif : '# intentionally left blank' } | |||
1143 | os.makedirs(ipythondir, mode = 0777) |
|
1167 | os.makedirs(ipythondir, mode = 0777) | |
1144 | for f, cont in minimal_setup.items(): |
|
1168 | for f, cont in minimal_setup.items(): | |
1145 | open(ipythondir + '/' + f,'w').write(cont) |
|
1169 | open(ipythondir + '/' + f,'w').write(cont) | |
@@ -1257,7 +1281,27 b' want to merge them back into the new files.""" % locals()' | |||||
1257 | except OSError: |
|
1281 | except OSError: | |
1258 | pass |
|
1282 | pass | |
1259 |
|
1283 | |||
|
1284 | # Clear all user namespaces to release all references cleanly. | |||
|
1285 | self.reset() | |||
|
1286 | ||||
|
1287 | # Run user hooks | |||
1260 | self.hooks.shutdown_hook() |
|
1288 | self.hooks.shutdown_hook() | |
|
1289 | ||||
|
1290 | def reset(self): | |||
|
1291 | """Clear all internal namespaces. | |||
|
1292 | ||||
|
1293 | Note that this is much more aggressive than %reset, since it clears | |||
|
1294 | fully all namespaces, as well as all input/output lists. | |||
|
1295 | """ | |||
|
1296 | for ns in self.ns_refs_table: | |||
|
1297 | ns.clear() | |||
|
1298 | ||||
|
1299 | # Clear input and output histories | |||
|
1300 | self.input_hist[:] = [] | |||
|
1301 | self.input_hist_raw[:] = [] | |||
|
1302 | self.output_hist.clear() | |||
|
1303 | # Restore the user namespaces to minimal usability | |||
|
1304 | self.init_namespaces() | |||
1261 |
|
1305 | |||
1262 | def savehist(self): |
|
1306 | def savehist(self): | |
1263 | """Save input history to a file (via readline library).""" |
|
1307 | """Save input history to a file (via readline library).""" | |
@@ -1298,7 +1342,6 b' want to merge them back into the new files.""" % locals()' | |||||
1298 | finally: |
|
1342 | finally: | |
1299 | readline.read_history_file(self.histfile) |
|
1343 | readline.read_history_file(self.histfile) | |
1300 | return wrapper |
|
1344 | return wrapper | |
1301 |
|
||||
1302 |
|
1345 | |||
1303 | def pre_readline(self): |
|
1346 | def pre_readline(self): | |
1304 | """readline hook to be used at the start of each line. |
|
1347 | """readline hook to be used at the start of each line. | |
@@ -1371,6 +1414,7 b' want to merge them back into the new files.""" % locals()' | |||||
1371 | # not run as the syntax for libedit is different. |
|
1414 | # not run as the syntax for libedit is different. | |
1372 | if not readline.uses_libedit: |
|
1415 | if not readline.uses_libedit: | |
1373 | for rlcommand in self.rc.readline_parse_and_bind: |
|
1416 | for rlcommand in self.rc.readline_parse_and_bind: | |
|
1417 | #print "loading rl:",rlcommand # dbg | |||
1374 | readline.parse_and_bind(rlcommand) |
|
1418 | readline.parse_and_bind(rlcommand) | |
1375 |
|
1419 | |||
1376 | # remove some chars from the delimiters list |
|
1420 | # remove some chars from the delimiters list | |
@@ -1396,7 +1440,59 b' want to merge them back into the new files.""" % locals()' | |||||
1396 | if self.rc.quiet: |
|
1440 | if self.rc.quiet: | |
1397 | return True |
|
1441 | return True | |
1398 | return ask_yes_no(prompt,default) |
|
1442 | return ask_yes_no(prompt,default) | |
1399 |
|
1443 | |||
|
1444 | def cache_main_mod(self,mod): | |||
|
1445 | """Cache a main module. | |||
|
1446 | ||||
|
1447 | When scripts are executed via %run, we must keep a reference to their | |||
|
1448 | __main__ module (a FakeModule instance) around so that Python doesn't | |||
|
1449 | clear it, rendering objects defined therein useless. | |||
|
1450 | ||||
|
1451 | This method keeps said reference in a private dict, keyed by the | |||
|
1452 | absolute path of the module object (which corresponds to the script | |||
|
1453 | path). This way, for multiple executions of the same script we only | |||
|
1454 | keep one copy of __main__ (the last one), thus preventing memory leaks | |||
|
1455 | from old references while allowing the objects from the last execution | |||
|
1456 | to be accessible. | |||
|
1457 | ||||
|
1458 | Parameters | |||
|
1459 | ---------- | |||
|
1460 | mod : a module object | |||
|
1461 | ||||
|
1462 | Examples | |||
|
1463 | -------- | |||
|
1464 | ||||
|
1465 | In [10]: import IPython | |||
|
1466 | ||||
|
1467 | In [11]: _ip.IP.cache_main_mod(IPython) | |||
|
1468 | ||||
|
1469 | In [12]: IPython.__file__ in _ip.IP._user_main_modules | |||
|
1470 | Out[12]: True | |||
|
1471 | """ | |||
|
1472 | self._user_main_modules[os.path.abspath(mod.__file__) ] = mod | |||
|
1473 | ||||
|
1474 | def clear_main_mod_cache(self): | |||
|
1475 | """Clear the cache of main modules. | |||
|
1476 | ||||
|
1477 | Mainly for use by utilities like %reset. | |||
|
1478 | ||||
|
1479 | Examples | |||
|
1480 | -------- | |||
|
1481 | ||||
|
1482 | In [15]: import IPython | |||
|
1483 | ||||
|
1484 | In [16]: _ip.IP.cache_main_mod(IPython) | |||
|
1485 | ||||
|
1486 | In [17]: len(_ip.IP._user_main_modules) > 0 | |||
|
1487 | Out[17]: True | |||
|
1488 | ||||
|
1489 | In [18]: _ip.IP.clear_main_mod_cache() | |||
|
1490 | ||||
|
1491 | In [19]: len(_ip.IP._user_main_modules) == 0 | |||
|
1492 | Out[19]: True | |||
|
1493 | """ | |||
|
1494 | self._user_main_modules.clear() | |||
|
1495 | ||||
1400 | def _should_recompile(self,e): |
|
1496 | def _should_recompile(self,e): | |
1401 | """Utility routine for edit_syntax_error""" |
|
1497 | """Utility routine for edit_syntax_error""" | |
1402 |
|
1498 | |||
@@ -1556,8 +1652,6 b' want to merge them back into the new files.""" % locals()' | |||||
1556 | self.set_completer() |
|
1652 | self.set_completer() | |
1557 | except KeyboardInterrupt: |
|
1653 | except KeyboardInterrupt: | |
1558 | self.write("\nKeyboardInterrupt\n") |
|
1654 | self.write("\nKeyboardInterrupt\n") | |
1559 |
|
||||
1560 |
|
||||
1561 |
|
1655 | |||
1562 | def mainloop(self,banner=None): |
|
1656 | def mainloop(self,banner=None): | |
1563 | """Creates the local namespace and starts the mainloop. |
|
1657 | """Creates the local namespace and starts the mainloop. | |
@@ -1585,7 +1679,9 b' want to merge them back into the new files.""" % locals()' | |||||
1585 | try: |
|
1679 | try: | |
1586 | self.interact(banner) |
|
1680 | self.interact(banner) | |
1587 | #self.interact_with_readline() |
|
1681 | #self.interact_with_readline() | |
1588 | # XXX for testing of a readline-decoupled repl loop, call interact_with_readline above |
|
1682 | ||
|
1683 | # XXX for testing of a readline-decoupled repl loop, call | |||
|
1684 | # interact_with_readline above | |||
1589 |
|
1685 | |||
1590 | break |
|
1686 | break | |
1591 | except KeyboardInterrupt: |
|
1687 | except KeyboardInterrupt: | |
@@ -1866,7 +1962,7 b' want to merge them back into the new files.""" % locals()' | |||||
1866 | """ |
|
1962 | """ | |
1867 | line = fn + " " + rest |
|
1963 | line = fn + " " + rest | |
1868 |
|
1964 | |||
1869 |
done = |
|
1965 | done = set() | |
1870 | while 1: |
|
1966 | while 1: | |
1871 | pre,fn,rest = prefilter.splitUserInput(line, |
|
1967 | pre,fn,rest = prefilter.splitUserInput(line, | |
1872 | prefilter.shell_line_split) |
|
1968 | prefilter.shell_line_split) | |
@@ -1978,7 +2074,6 b' want to merge them back into the new files.""" % locals()' | |||||
1978 | # NOT skip even a blank line if we are in a code block (more is |
|
2074 | # NOT skip even a blank line if we are in a code block (more is | |
1979 | # true) |
|
2075 | # true) | |
1980 |
|
2076 | |||
1981 |
|
||||
1982 | if line or more: |
|
2077 | if line or more: | |
1983 | # push to raw history, so hist line numbers stay in sync |
|
2078 | # push to raw history, so hist line numbers stay in sync | |
1984 | self.input_hist_raw.append("# " + line + "\n") |
|
2079 | self.input_hist_raw.append("# " + line + "\n") |
@@ -5,32 +5,28 b' IPython -- An enhanced Interactive Python' | |||||
5 | Requires Python 2.1 or better. |
|
5 | Requires Python 2.1 or better. | |
6 |
|
6 | |||
7 | This file contains the main make_IPython() starter function. |
|
7 | This file contains the main make_IPython() starter function. | |
8 |
|
8 | """ | ||
9 | $Id: ipmaker.py 2930 2008-01-11 07:03:11Z vivainio $""" |
|
|||
10 |
|
9 | |||
11 | #***************************************************************************** |
|
10 | #***************************************************************************** | |
12 | # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu> |
|
11 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
12 | # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu> | |||
13 | # |
|
13 | # | |
14 | # Distributed under the terms of the BSD License. The full license is in |
|
14 | # Distributed under the terms of the BSD License. The full license is in | |
15 | # the file COPYING, distributed as part of this software. |
|
15 | # the file COPYING, distributed as part of this software. | |
16 | #***************************************************************************** |
|
16 | #***************************************************************************** | |
17 |
|
17 | |||
18 | from IPython import Release |
|
|||
19 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
20 | __license__ = Release.license |
|
|||
21 | __version__ = Release.version |
|
|||
22 |
|
||||
23 | try: |
|
18 | try: | |
24 | credits._Printer__data = """ |
|
19 | credits._Printer__data = """ | |
25 | Python: %s |
|
20 | Python: %s | |
26 |
|
21 | |||
27 | IPython: Fernando Perez, Janko Hauser, Nathan Gray, and many users. |
|
22 | IPython: The IPython Development Team. | |
28 | See http://ipython.scipy.org for more information.""" \ |
|
23 | See http://ipython.scipy.org for more information.""" \ | |
29 | % credits._Printer__data |
|
24 | % credits._Printer__data | |
30 |
|
25 | |||
31 | copyright._Printer__data += """ |
|
26 | copyright._Printer__data += """ | |
32 |
|
27 | |||
33 | Copyright (c) 2001-2004 Fernando Perez, Janko Hauser, Nathan Gray. |
|
28 | Copyright (c) 2008-2009 The IPython Development Team. | |
|
29 | Copyright (c) 2001-2007 Fernando Perez, Janko Hauser, Nathan Gray. | |||
34 | All Rights Reserved.""" |
|
30 | All Rights Reserved.""" | |
35 | except NameError: |
|
31 | except NameError: | |
36 | # Can happen if ipython was started with 'python -S', so that site.py is |
|
32 | # Can happen if ipython was started with 'python -S', so that site.py is | |
@@ -51,6 +47,7 b' from pprint import pprint,pformat' | |||||
51 |
|
47 | |||
52 | # Our own |
|
48 | # Our own | |
53 | from IPython import DPyGetOpt |
|
49 | from IPython import DPyGetOpt | |
|
50 | from IPython import Release | |||
54 | from IPython.ipstruct import Struct |
|
51 | from IPython.ipstruct import Struct | |
55 | from IPython.OutputTrap import OutputTrap |
|
52 | from IPython.OutputTrap import OutputTrap | |
56 | from IPython.ConfigLoader import ConfigLoader |
|
53 | from IPython.ConfigLoader import ConfigLoader | |
@@ -108,8 +105,6 b' def make_IPython(argv=None,user_ns=None,user_global_ns=None,debug=1,' | |||||
108 | IP.user_ns['help'] = _Helper() |
|
105 | IP.user_ns['help'] = _Helper() | |
109 | except ImportError: |
|
106 | except ImportError: | |
110 | warn('help() not available - check site.py') |
|
107 | warn('help() not available - check site.py') | |
111 | IP.user_config_ns = {} |
|
|||
112 |
|
||||
113 |
|
108 | |||
114 | if DEVDEBUG: |
|
109 | if DEVDEBUG: | |
115 | # For developer debugging only (global flag) |
|
110 | # For developer debugging only (global flag) | |
@@ -121,7 +116,7 b' def make_IPython(argv=None,user_ns=None,user_global_ns=None,debug=1,' | |||||
121 | 'for more information.\n' |
|
116 | 'for more information.\n' | |
122 | % (sys.version.split('\n')[0],), |
|
117 | % (sys.version.split('\n')[0],), | |
123 | "IPython %s -- An enhanced Interactive Python." |
|
118 | "IPython %s -- An enhanced Interactive Python." | |
124 |
% ( |
|
119 | % (Release.version,), | |
125 | """\ |
|
120 | """\ | |
126 | ? -> Introduction and overview of IPython's features. |
|
121 | ? -> Introduction and overview of IPython's features. | |
127 | %quickref -> Quick reference. |
|
122 | %quickref -> Quick reference. | |
@@ -131,20 +126,15 b" object? -> Details about 'object'. ?object also works, ?? prints more." | |||||
131 |
|
126 | |||
132 | IP.usage = interactive_usage |
|
127 | IP.usage = interactive_usage | |
133 |
|
128 | |||
134 | # Platform-dependent suffix and directory names. We use _ipython instead |
|
129 | # Platform-dependent suffix. | |
135 | # of .ipython under win32 b/c there's software that breaks with .named |
|
|||
136 | # directories on that platform. |
|
|||
137 | if os.name == 'posix': |
|
130 | if os.name == 'posix': | |
138 | rc_suffix = '' |
|
131 | rc_suffix = '' | |
139 | ipdir_def = '.ipython' |
|
|||
140 | else: |
|
132 | else: | |
141 | rc_suffix = '.ini' |
|
133 | rc_suffix = '.ini' | |
142 | ipdir_def = '_ipython' |
|
|||
143 |
|
134 | |||
144 | # default directory for configuration |
|
135 | # default directory for configuration | |
145 | ipythondir_def = os.path.abspath(os.environ.get('IPYTHONDIR', |
|
136 | ipythondir_def = get_ipython_dir() | |
146 | os.path.join(IP.home_dir,ipdir_def))) |
|
137 | ||
147 |
|
||||
148 | sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran |
|
138 | sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran | |
149 |
|
139 | |||
150 | # we need the directory where IPython itself is installed |
|
140 | # we need the directory where IPython itself is installed | |
@@ -335,7 +325,7 b" object? -> Details about 'object'. ?object also works, ?? prints more." | |||||
335 | sys.exit() |
|
325 | sys.exit() | |
336 |
|
326 | |||
337 | if opts_all.Version: |
|
327 | if opts_all.Version: | |
338 |
print |
|
328 | print Release.version | |
339 | sys.exit() |
|
329 | sys.exit() | |
340 |
|
330 | |||
341 | if opts_all.magic_docstrings: |
|
331 | if opts_all.magic_docstrings: |
@@ -1,7 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """Mimic C structs with lots of extra functionality. |
|
2 | """Mimic C structs with lots of extra functionality. | |
3 |
|
3 | """ | ||
4 | $Id: ipstruct.py 1950 2006-11-28 19:15:35Z vivainio $""" |
|
|||
5 |
|
4 | |||
6 | #***************************************************************************** |
|
5 | #***************************************************************************** | |
7 | # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu> |
|
6 | # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu> | |
@@ -10,10 +9,6 b' $Id: ipstruct.py 1950 2006-11-28 19:15:35Z vivainio $"""' | |||||
10 | # the file COPYING, distributed as part of this software. |
|
9 | # the file COPYING, distributed as part of this software. | |
11 | #***************************************************************************** |
|
10 | #***************************************************************************** | |
12 |
|
11 | |||
13 | from IPython import Release |
|
|||
14 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
15 | __license__ = Release.license |
|
|||
16 |
|
||||
17 | __all__ = ['Struct'] |
|
12 | __all__ = ['Struct'] | |
18 |
|
13 | |||
19 | import types |
|
14 | import types | |
@@ -163,8 +158,22 b' class Struct:' | |||||
163 | return self.__dict__[key] |
|
158 | return self.__dict__[key] | |
164 |
|
159 | |||
165 | def __contains__(self,key): |
|
160 | def __contains__(self,key): | |
166 |
"""Allows use of the 'in' operator. |
|
161 | """Allows use of the 'in' operator. | |
167 | return self.__dict__.has_key(key) |
|
162 | ||
|
163 | Examples: | |||
|
164 | >>> s = Struct(x=1) | |||
|
165 | >>> 'x' in s | |||
|
166 | True | |||
|
167 | >>> 'y' in s | |||
|
168 | False | |||
|
169 | >>> s[4] = None | |||
|
170 | >>> 4 in s | |||
|
171 | True | |||
|
172 | >>> s.z = None | |||
|
173 | >>> 'z' in s | |||
|
174 | True | |||
|
175 | """ | |||
|
176 | return key in self.__dict__ | |||
168 |
|
177 | |||
169 | def __iadd__(self,other): |
|
178 | def __iadd__(self,other): | |
170 | """S += S2 is a shorthand for S.merge(S2).""" |
|
179 | """S += S2 is a shorthand for S.merge(S2).""" | |
@@ -246,12 +255,13 b' class Struct:' | |||||
246 | Optionally, one or more key=value pairs can be given at the end for |
|
255 | Optionally, one or more key=value pairs can be given at the end for | |
247 | direct update.""" |
|
256 | direct update.""" | |
248 |
|
257 | |||
249 |
# The funny name __loc_data__ is to prevent a common variable name |
|
258 | # The funny name __loc_data__ is to prevent a common variable name | |
250 |
# could be a fieled of a Struct to collide with this |
|
259 | # which could be a fieled of a Struct to collide with this | |
251 |
# would arise if the function is called with a |
|
260 | # parameter. The problem would arise if the function is called with a | |
252 |
# that a user means to add as a Struct |
|
261 | # keyword with this same name that a user means to add as a Struct | |
|
262 | # field. | |||
253 | newdict = Struct.__make_dict(self,__loc_data__,**kw) |
|
263 | newdict = Struct.__make_dict(self,__loc_data__,**kw) | |
254 | for k,v in newdict.items(): |
|
264 | for k,v in newdict.iteritems(): | |
255 | self[k] = v |
|
265 | self[k] = v | |
256 |
|
266 | |||
257 | def merge(self,__loc_data__=None,__conflict_solve=None,**kw): |
|
267 | def merge(self,__loc_data__=None,__conflict_solve=None,**kw): |
@@ -1,6 +1,10 b'' | |||||
1 | # encoding: utf-8 |
|
1 | # encoding: utf-8 | |
|
2 | """Classes for handling input/output prompts. | |||
2 |
|
|
3 | ||
3 | """Classes for handling input/output prompts.""" |
|
4 | Authors | |
|
5 | ------- | |||
|
6 | - Fernando Perez <Fernando.Perez@berkeley.edu> | |||
|
7 | """ | |||
4 |
|
8 | |||
5 | __docformat__ = "restructuredtext en" |
|
9 | __docformat__ = "restructuredtext en" | |
6 |
|
10 | |||
@@ -15,12 +19,6 b' __docformat__ = "restructuredtext en"' | |||||
15 | # Imports |
|
19 | # Imports | |
16 | #------------------------------------------------------------------------------- |
|
20 | #------------------------------------------------------------------------------- | |
17 |
|
21 | |||
18 | from IPython import Release |
|
|||
19 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
20 | __license__ = Release.license |
|
|||
21 | __version__ = Release.version |
|
|||
22 |
|
||||
23 | #**************************************************************************** |
|
|||
24 | # Required modules |
|
22 | # Required modules | |
25 | import __builtin__ |
|
23 | import __builtin__ | |
26 | import os |
|
24 | import os | |
@@ -32,12 +30,11 b' import time' | |||||
32 | from IPython.external.Itpl import ItplNS |
|
30 | from IPython.external.Itpl import ItplNS | |
33 | from macro import Macro |
|
31 | from macro import Macro | |
34 |
|
32 | |||
35 | # Temporarily use this until it is ported to ipython1 |
|
|||
36 |
|
||||
37 | from IPython import ColorANSI |
|
33 | from IPython import ColorANSI | |
|
34 | from IPython import Release | |||
|
35 | from IPython.ipapi import TryNext | |||
38 | from IPython.ipstruct import Struct |
|
36 | from IPython.ipstruct import Struct | |
39 | from IPython.genutils import * |
|
37 | from IPython.genutils import * | |
40 | from IPython.ipapi import TryNext |
|
|||
41 |
|
38 | |||
42 | #**************************************************************************** |
|
39 | #**************************************************************************** | |
43 | #Color schemes for Prompts. |
|
40 | #Color schemes for Prompts. | |
@@ -159,7 +156,7 b' prompt_specials_color = {' | |||||
159 | # Carriage return |
|
156 | # Carriage return | |
160 | r'\r': '\r', |
|
157 | r'\r': '\r', | |
161 | # Release version |
|
158 | # Release version | |
162 |
r'\v': |
|
159 | r'\v': Release.version, | |
163 | # Root symbol ($ or #) |
|
160 | # Root symbol ($ or #) | |
164 | r'\$': ROOT_SYMBOL, |
|
161 | r'\$': ROOT_SYMBOL, | |
165 | } |
|
162 | } |
@@ -1,5 +1,4 b'' | |||||
1 |
# |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
||||
3 | """ |
|
2 | """ | |
4 | ultraTB.py -- Spice up your tracebacks! |
|
3 | ultraTB.py -- Spice up your tracebacks! | |
5 |
|
4 | |||
@@ -60,26 +59,15 b' ColorSchemeTable class. Currently the following exist:' | |||||
60 | You can implement other color schemes easily, the syntax is fairly |
|
59 | You can implement other color schemes easily, the syntax is fairly | |
61 | self-explanatory. Please send back new schemes you develop to the author for |
|
60 | self-explanatory. Please send back new schemes you develop to the author for | |
62 | possible inclusion in future releases. |
|
61 | possible inclusion in future releases. | |
|
62 | """ | |||
63 |
|
63 | |||
64 | $Id: ultraTB.py 2480 2007-07-06 19:33:43Z fperez $""" |
|
64 | #***************************************************************************** | |
65 |
|
65 | # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu> | ||
66 | __docformat__ = "restructuredtext en" |
|
66 | # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu> | |
67 |
|
||||
68 | #------------------------------------------------------------------------------- |
|
|||
69 | # Copyright (C) 2008 The IPython Development Team |
|
|||
70 | # |
|
67 | # | |
71 | # Distributed under the terms of the BSD License. The full license is in |
|
68 | # Distributed under the terms of the BSD License. The full license is in | |
72 | # the file COPYING, distributed as part of this software. |
|
69 | # the file COPYING, distributed as part of this software. | |
73 | #------------------------------------------------------------------------------- |
|
70 | #***************************************************************************** | |
74 |
|
||||
75 | #------------------------------------------------------------------------------- |
|
|||
76 | # Imports |
|
|||
77 | #------------------------------------------------------------------------------- |
|
|||
78 |
|
||||
79 | from IPython import Release |
|
|||
80 | __author__ = '%s <%s>\n%s <%s>' % (Release.authors['Nathan']+ |
|
|||
81 | Release.authors['Fernando']) |
|
|||
82 | __license__ = Release.license |
|
|||
83 |
|
71 | |||
84 | # Required modules |
|
72 | # Required modules | |
85 | import inspect |
|
73 | import inspect | |
@@ -104,7 +92,7 b' from inspect import getsourcefile, getfile, getmodule,\\' | |||||
104 | # Modified pdb which doesn't damage IPython's readline handling |
|
92 | # Modified pdb which doesn't damage IPython's readline handling | |
105 | from IPython import Debugger, PyColorize |
|
93 | from IPython import Debugger, PyColorize | |
106 | from IPython.ipstruct import Struct |
|
94 | from IPython.ipstruct import Struct | |
107 |
from IPython.excolors import |
|
95 | from IPython.excolors import exception_colors | |
108 | from IPython.genutils import Term,uniq_stable,error,info |
|
96 | from IPython.genutils import Term,uniq_stable,error,info | |
109 |
|
97 | |||
110 | # Globals |
|
98 | # Globals | |
@@ -141,11 +129,18 b' def findsource(object):' | |||||
141 | FIXED version with which we monkeypatch the stdlib to work around a bug.""" |
|
129 | FIXED version with which we monkeypatch the stdlib to work around a bug.""" | |
142 |
|
130 | |||
143 | file = getsourcefile(object) or getfile(object) |
|
131 | file = getsourcefile(object) or getfile(object) | |
144 | module = getmodule(object, file) |
|
132 | # If the object is a frame, then trying to get the globals dict from its | |
145 | if module: |
|
133 | # module won't work. Instead, the frame object itself has the globals | |
146 | lines = linecache.getlines(file, module.__dict__) |
|
134 | # dictionary. | |
|
135 | globals_dict = None | |||
|
136 | if inspect.isframe(object): | |||
|
137 | # XXX: can this ever be false? | |||
|
138 | globals_dict = object.f_globals | |||
147 | else: |
|
139 | else: | |
148 |
l |
|
140 | module = getmodule(object, file) | |
|
141 | if module: | |||
|
142 | globals_dict = module.__dict__ | |||
|
143 | lines = linecache.getlines(file, globals_dict) | |||
149 | if not lines: |
|
144 | if not lines: | |
150 | raise IOError('could not get source code') |
|
145 | raise IOError('could not get source code') | |
151 |
|
146 | |||
@@ -202,11 +197,31 b' def findsource(object):' | |||||
202 | if sys.version_info[:2] >= (2,5): |
|
197 | if sys.version_info[:2] >= (2,5): | |
203 | inspect.findsource = findsource |
|
198 | inspect.findsource = findsource | |
204 |
|
199 | |||
|
200 | def fix_frame_records_filenames(records): | |||
|
201 | """Try to fix the filenames in each record from inspect.getinnerframes(). | |||
|
202 | ||||
|
203 | Particularly, modules loaded from within zip files have useless filenames | |||
|
204 | attached to their code object, and inspect.getinnerframes() just uses it. | |||
|
205 | """ | |||
|
206 | fixed_records = [] | |||
|
207 | for frame, filename, line_no, func_name, lines, index in records: | |||
|
208 | # Look inside the frame's globals dictionary for __file__, which should | |||
|
209 | # be better. | |||
|
210 | better_fn = frame.f_globals.get('__file__', None) | |||
|
211 | if isinstance(better_fn, str): | |||
|
212 | # Check the type just in case someone did something weird with | |||
|
213 | # __file__. It might also be None if the error occurred during | |||
|
214 | # import. | |||
|
215 | filename = better_fn | |||
|
216 | fixed_records.append((frame, filename, line_no, func_name, lines, index)) | |||
|
217 | return fixed_records | |||
|
218 | ||||
|
219 | ||||
205 | def _fixed_getinnerframes(etb, context=1,tb_offset=0): |
|
220 | def _fixed_getinnerframes(etb, context=1,tb_offset=0): | |
206 | import linecache |
|
221 | import linecache | |
207 | LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5 |
|
222 | LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5 | |
208 |
|
223 | |||
209 | records = inspect.getinnerframes(etb, context) |
|
224 | records = fix_frame_records_filenames(inspect.getinnerframes(etb, context)) | |
210 |
|
225 | |||
211 | # If the error is at the console, don't build any context, since it would |
|
226 | # If the error is at the console, don't build any context, since it would | |
212 | # otherwise produce 5 blank lines printed out (there is no file at the |
|
227 | # otherwise produce 5 blank lines printed out (there is no file at the | |
@@ -299,7 +314,7 b' class TBTools:' | |||||
299 | self.call_pdb = call_pdb |
|
314 | self.call_pdb = call_pdb | |
300 |
|
315 | |||
301 | # Create color table |
|
316 | # Create color table | |
302 |
self.color_scheme_table = |
|
317 | self.color_scheme_table = exception_colors() | |
303 |
|
318 | |||
304 | self.set_colors(color_scheme) |
|
319 | self.set_colors(color_scheme) | |
305 | self.old_scheme = color_scheme # save initial value for toggles |
|
320 | self.old_scheme = color_scheme # save initial value for toggles | |
@@ -356,8 +371,8 b' class ListTB(TBTools):' | |||||
356 |
|
371 | |||
357 | def __call__(self, etype, value, elist): |
|
372 | def __call__(self, etype, value, elist): | |
358 | Term.cout.flush() |
|
373 | Term.cout.flush() | |
359 | Term.cerr.flush() |
|
|||
360 | print >> Term.cerr, self.text(etype,value,elist) |
|
374 | print >> Term.cerr, self.text(etype,value,elist) | |
|
375 | Term.cerr.flush() | |||
361 |
|
376 | |||
362 | def text(self,etype, value, elist,context=5): |
|
377 | def text(self,etype, value, elist,context=5): | |
363 | """Return a color formatted string with the traceback info.""" |
|
378 | """Return a color formatted string with the traceback info.""" | |
@@ -424,7 +439,8 b' class ListTB(TBTools):' | |||||
424 |
|
439 | |||
425 | Also lifted nearly verbatim from traceback.py |
|
440 | Also lifted nearly verbatim from traceback.py | |
426 | """ |
|
441 | """ | |
427 |
|
442 | |||
|
443 | have_filedata = False | |||
428 | Colors = self.Colors |
|
444 | Colors = self.Colors | |
429 | list = [] |
|
445 | list = [] | |
430 | try: |
|
446 | try: | |
@@ -438,8 +454,9 b' class ListTB(TBTools):' | |||||
438 | try: |
|
454 | try: | |
439 | msg, (filename, lineno, offset, line) = value |
|
455 | msg, (filename, lineno, offset, line) = value | |
440 | except: |
|
456 | except: | |
441 |
|
|
457 | have_filedata = False | |
442 | else: |
|
458 | else: | |
|
459 | have_filedata = True | |||
443 | #print 'filename is',filename # dbg |
|
460 | #print 'filename is',filename # dbg | |
444 | if not filename: filename = "<string>" |
|
461 | if not filename: filename = "<string>" | |
445 | list.append('%s File %s"%s"%s, line %s%d%s\n' % \ |
|
462 | list.append('%s File %s"%s"%s, line %s%d%s\n' % \ | |
@@ -469,6 +486,12 b' class ListTB(TBTools):' | |||||
469 | Colors.Normal, s)) |
|
486 | Colors.Normal, s)) | |
470 | else: |
|
487 | else: | |
471 | list.append('%s\n' % str(stype)) |
|
488 | list.append('%s\n' % str(stype)) | |
|
489 | ||||
|
490 | # vds:>> | |||
|
491 | if have_filedata: | |||
|
492 | __IPYTHON__.hooks.synchronize_with_editor(filename, lineno, 0) | |||
|
493 | # vds:<< | |||
|
494 | ||||
472 | return list |
|
495 | return list | |
473 |
|
496 | |||
474 | def _some_str(self, value): |
|
497 | def _some_str(self, value): | |
@@ -780,6 +803,15 b' class VerboseTB(TBTools):' | |||||
780 | for name in names: |
|
803 | for name in names: | |
781 | value = text_repr(getattr(evalue, name)) |
|
804 | value = text_repr(getattr(evalue, name)) | |
782 | exception.append('\n%s%s = %s' % (indent, name, value)) |
|
805 | exception.append('\n%s%s = %s' % (indent, name, value)) | |
|
806 | ||||
|
807 | # vds: >> | |||
|
808 | if records: | |||
|
809 | filepath, lnum = records[-1][1:3] | |||
|
810 | #print "file:", str(file), "linenb", str(lnum) # dbg | |||
|
811 | filepath = os.path.abspath(filepath) | |||
|
812 | __IPYTHON__.hooks.synchronize_with_editor(filepath, lnum, 0) | |||
|
813 | # vds: << | |||
|
814 | ||||
783 | # return all our info assembled as a single string |
|
815 | # return all our info assembled as a single string | |
784 | return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) ) |
|
816 | return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) ) | |
785 |
|
817 | |||
@@ -834,8 +866,8 b' class VerboseTB(TBTools):' | |||||
834 | (etype, evalue, etb) = info or sys.exc_info() |
|
866 | (etype, evalue, etb) = info or sys.exc_info() | |
835 | self.tb = etb |
|
867 | self.tb = etb | |
836 | Term.cout.flush() |
|
868 | Term.cout.flush() | |
837 | Term.cerr.flush() |
|
|||
838 | print >> Term.cerr, self.text(etype, evalue, etb) |
|
869 | print >> Term.cerr, self.text(etype, evalue, etb) | |
|
870 | Term.cerr.flush() | |||
839 |
|
871 | |||
840 | # Changed so an instance can just be called as VerboseTB_inst() and print |
|
872 | # Changed so an instance can just be called as VerboseTB_inst() and print | |
841 | # out the right info on its own. |
|
873 | # out the right info on its own. | |
@@ -845,7 +877,10 b' class VerboseTB(TBTools):' | |||||
845 | self.handler() |
|
877 | self.handler() | |
846 | else: |
|
878 | else: | |
847 | self.handler((etype, evalue, etb)) |
|
879 | self.handler((etype, evalue, etb)) | |
848 | self.debugger() |
|
880 | try: | |
|
881 | self.debugger() | |||
|
882 | except KeyboardInterrupt: | |||
|
883 | print "\nKeyboardInterrupt" | |||
849 |
|
884 | |||
850 | #---------------------------------------------------------------------------- |
|
885 | #---------------------------------------------------------------------------- | |
851 | class FormattedTB(VerboseTB,ListTB): |
|
886 | class FormattedTB(VerboseTB,ListTB): | |
@@ -953,14 +988,17 b' class AutoFormattedTB(FormattedTB):' | |||||
953 | if out is None: |
|
988 | if out is None: | |
954 | out = Term.cerr |
|
989 | out = Term.cerr | |
955 | Term.cout.flush() |
|
990 | Term.cout.flush() | |
956 | out.flush() |
|
|||
957 | if tb_offset is not None: |
|
991 | if tb_offset is not None: | |
958 | tb_offset, self.tb_offset = self.tb_offset, tb_offset |
|
992 | tb_offset, self.tb_offset = self.tb_offset, tb_offset | |
959 | print >> out, self.text(etype, evalue, etb) |
|
993 | print >> out, self.text(etype, evalue, etb) | |
960 | self.tb_offset = tb_offset |
|
994 | self.tb_offset = tb_offset | |
961 | else: |
|
995 | else: | |
962 | print >> out, self.text(etype, evalue, etb) |
|
996 | print >> out, self.text(etype, evalue, etb) | |
963 | self.debugger() |
|
997 | out.flush() | |
|
998 | try: | |||
|
999 | self.debugger() | |||
|
1000 | except KeyboardInterrupt: | |||
|
1001 | print "\nKeyboardInterrupt" | |||
964 |
|
1002 | |||
965 | def text(self,etype=None,value=None,tb=None,context=5,mode=None): |
|
1003 | def text(self,etype=None,value=None,tb=None,context=5,mode=None): | |
966 | if etype is None: |
|
1004 | if etype is None: |
@@ -70,8 +70,8 b' def esc_quotes(strng):' | |||||
70 | def make_quoted_expr(s): |
|
70 | def make_quoted_expr(s): | |
71 | """Return string s in appropriate quotes, using raw string if possible. |
|
71 | """Return string s in appropriate quotes, using raw string if possible. | |
72 |
|
72 | |||
73 | Effectively this turns string: cd \ao\ao\ |
|
73 | XXX - example removed because it caused encoding errors in documentation | |
74 | to: r"cd \ao\ao\_"[:-1] |
|
74 | generation. We need a new example that doesn't contain invalid chars. | |
75 |
|
75 | |||
76 | Note the use of raw string and padding at the end to allow trailing |
|
76 | Note the use of raw string and padding at the end to allow trailing | |
77 | backslash. |
|
77 | backslash. |
@@ -693,7 +693,7 b' class QueuedEngine(object):' | |||||
693 | @queue |
|
693 | @queue | |
694 | def execute(self, lines): |
|
694 | def execute(self, lines): | |
695 | pass |
|
695 | pass | |
696 |
|
696 | |||
697 | @queue |
|
697 | @queue | |
698 | def push(self, namespace): |
|
698 | def push(self, namespace): | |
699 | pass |
|
699 | pass |
@@ -335,7 +335,7 b' class MultiEngine(ControllerAdapterBase):' | |||||
335 | #--------------------------------------------------------------------------- |
|
335 | #--------------------------------------------------------------------------- | |
336 | # IEngineMultiplexer methods |
|
336 | # IEngineMultiplexer methods | |
337 | #--------------------------------------------------------------------------- |
|
337 | #--------------------------------------------------------------------------- | |
338 |
|
|
338 | ||
339 | def execute(self, lines, targets='all'): |
|
339 | def execute(self, lines, targets='all'): | |
340 | return self._performOnEnginesAndGatherBoth('execute', lines, targets=targets) |
|
340 | return self._performOnEnginesAndGatherBoth('execute', lines, targets=targets) | |
341 |
|
341 |
@@ -131,7 +131,7 b' class FCSynchronousMultiEngineFromMultiEngine(Referenceable):' | |||||
131 | def _addDeferredIDCallback(self, did, callback, *args, **kwargs): |
|
131 | def _addDeferredIDCallback(self, did, callback, *args, **kwargs): | |
132 | self._deferredIDCallbacks[did] = (callback, args, kwargs) |
|
132 | self._deferredIDCallbacks[did] = (callback, args, kwargs) | |
133 | return did |
|
133 | return did | |
134 |
|
|
134 | ||
135 | #--------------------------------------------------------------------------- |
|
135 | #--------------------------------------------------------------------------- | |
136 | # IEngineMultiplexer related methods |
|
136 | # IEngineMultiplexer related methods | |
137 | #--------------------------------------------------------------------------- |
|
137 | #--------------------------------------------------------------------------- | |
@@ -346,7 +346,7 b' class FCFullSynchronousMultiEngineClient(object):' | |||||
346 | #--------------------------------------------------------------------------- |
|
346 | #--------------------------------------------------------------------------- | |
347 | # IEngineMultiplexer related methods |
|
347 | # IEngineMultiplexer related methods | |
348 | #--------------------------------------------------------------------------- |
|
348 | #--------------------------------------------------------------------------- | |
349 |
|
|
349 | ||
350 | def execute(self, lines, targets='all', block=True): |
|
350 | def execute(self, lines, targets='all', block=True): | |
351 | d = self.remote_reference.callRemote('execute', lines, targets, block) |
|
351 | d = self.remote_reference.callRemote('execute', lines, targets, block) | |
352 | d.addCallback(self.unpackage) |
|
352 | d.addCallback(self.unpackage) |
1 | NO CONTENT: modified file chmod 100644 => 100755 |
|
NO CONTENT: modified file chmod 100644 => 100755 |
@@ -18,19 +18,24 b' import os' | |||||
18 | import re |
|
18 | import re | |
19 | import sys |
|
19 | import sys | |
20 | import signal |
|
20 | import signal | |
|
21 | import tempfile | |||
21 | pjoin = os.path.join |
|
22 | pjoin = os.path.join | |
22 |
|
23 | |||
23 | from twisted.internet import reactor, defer |
|
24 | from twisted.internet import reactor, defer | |
24 | from twisted.internet.protocol import ProcessProtocol |
|
25 | from twisted.internet.protocol import ProcessProtocol | |
25 | from twisted.python import failure, log |
|
|||
26 | from twisted.internet.error import ProcessDone, ProcessTerminated |
|
26 | from twisted.internet.error import ProcessDone, ProcessTerminated | |
27 | from twisted.internet.utils import getProcessOutput |
|
27 | from twisted.internet.utils import getProcessOutput | |
|
28 | from twisted.python import failure, log | |||
28 |
|
29 | |||
29 | from IPython.external import argparse |
|
30 | from IPython.external import argparse | |
30 | from IPython.external import Itpl |
|
31 | from IPython.external import Itpl | |
|
32 | from IPython.genutils import get_ipython_dir, num_cpus | |||
|
33 | from IPython.kernel.fcutil import have_crypto | |||
|
34 | from IPython.kernel.error import SecurityError | |||
|
35 | from IPython.kernel.fcutil import have_crypto | |||
31 | from IPython.kernel.twistedutil import gatherBoth |
|
36 | from IPython.kernel.twistedutil import gatherBoth | |
32 | from IPython.kernel.util import printer |
|
37 | from IPython.kernel.util import printer | |
33 | from IPython.genutils import get_ipython_dir, num_cpus |
|
38 | ||
34 |
|
39 | |||
35 | #----------------------------------------------------------------------------- |
|
40 | #----------------------------------------------------------------------------- | |
36 | # General process handling code |
|
41 | # General process handling code | |
@@ -42,8 +47,11 b' def find_exe(cmd):' | |||||
42 | except ImportError: |
|
47 | except ImportError: | |
43 | raise ImportError('you need to have pywin32 installed for this to work') |
|
48 | raise ImportError('you need to have pywin32 installed for this to work') | |
44 | else: |
|
49 | else: | |
45 | (path, offest) = win32api.SearchPath(os.environ['PATH'],cmd) |
|
50 | try: | |
46 | return path |
|
51 | (path, offest) = win32api.SearchPath(os.environ['PATH'],cmd + '.exe') | |
|
52 | except: | |||
|
53 | (path, offset) = win32api.SearchPath(os.environ['PATH'],cmd + '.bat') | |||
|
54 | return path | |||
47 |
|
55 | |||
48 | class ProcessStateError(Exception): |
|
56 | class ProcessStateError(Exception): | |
49 | pass |
|
57 | pass | |
@@ -74,10 +82,10 b' class LauncherProcessProtocol(ProcessProtocol):' | |||||
74 | ) |
|
82 | ) | |
75 | else: |
|
83 | else: | |
76 | raise UnknownStatus("unknown exit status, this is probably a bug in Twisted") |
|
84 | raise UnknownStatus("unknown exit status, this is probably a bug in Twisted") | |
77 |
|
85 | |||
78 | def outReceived(self, data): |
|
86 | def outReceived(self, data): | |
79 | log.msg(data) |
|
87 | log.msg(data) | |
80 |
|
88 | |||
81 | def errReceived(self, data): |
|
89 | def errReceived(self, data): | |
82 | log.err(data) |
|
90 | log.err(data) | |
83 |
|
91 | |||
@@ -171,7 +179,13 b' class ControllerLauncher(ProcessLauncher):' | |||||
171 |
|
179 | |||
172 | def __init__(self, extra_args=None): |
|
180 | def __init__(self, extra_args=None): | |
173 | if sys.platform == 'win32': |
|
181 | if sys.platform == 'win32': | |
174 | args = [find_exe('ipcontroller.bat')] |
|
182 | # This logic is needed because the ipcontroller script doesn't | |
|
183 | # always get installed in the same way or in the same location. | |||
|
184 | from IPython.kernel.scripts import ipcontroller | |||
|
185 | script_location = ipcontroller.__file__.replace('.pyc', '.py') | |||
|
186 | # The -u option here turns on unbuffered output, which is required | |||
|
187 | # on Win32 to prevent wierd conflict and problems with Twisted | |||
|
188 | args = [find_exe('python'), '-u', script_location] | |||
175 | else: |
|
189 | else: | |
176 | args = ['ipcontroller'] |
|
190 | args = ['ipcontroller'] | |
177 | self.extra_args = extra_args |
|
191 | self.extra_args = extra_args | |
@@ -185,7 +199,13 b' class EngineLauncher(ProcessLauncher):' | |||||
185 |
|
199 | |||
186 | def __init__(self, extra_args=None): |
|
200 | def __init__(self, extra_args=None): | |
187 | if sys.platform == 'win32': |
|
201 | if sys.platform == 'win32': | |
188 | args = [find_exe('ipengine.bat')] |
|
202 | # This logic is needed because the ipcontroller script doesn't | |
|
203 | # always get installed in the same way or in the same location. | |||
|
204 | from IPython.kernel.scripts import ipengine | |||
|
205 | script_location = ipengine.__file__.replace('.pyc', '.py') | |||
|
206 | # The -u option here turns on unbuffered output, which is required | |||
|
207 | # on Win32 to prevent wierd conflict and problems with Twisted | |||
|
208 | args = [find_exe('python'), '-u', script_location] | |||
189 | else: |
|
209 | else: | |
190 | args = ['ipengine'] |
|
210 | args = ['ipengine'] | |
191 | self.extra_args = extra_args |
|
211 | self.extra_args = extra_args | |
@@ -253,7 +273,7 b' class BatchEngineSet(object):' | |||||
253 | self.context = {} |
|
273 | self.context = {} | |
254 | self.context.update(kwargs) |
|
274 | self.context.update(kwargs) | |
255 | self.batch_file = self.template_file+'-run' |
|
275 | self.batch_file = self.template_file+'-run' | |
256 |
|
276 | |||
257 | def parse_job_id(self, output): |
|
277 | def parse_job_id(self, output): | |
258 | m = re.match(self.job_id_regexp, output) |
|
278 | m = re.match(self.job_id_regexp, output) | |
259 | if m is not None: |
|
279 | if m is not None: | |
@@ -273,7 +293,7 b' class BatchEngineSet(object):' | |||||
273 | f = open(self.batch_file,'w') |
|
293 | f = open(self.batch_file,'w') | |
274 | f.write(script_as_string) |
|
294 | f.write(script_as_string) | |
275 | f.close() |
|
295 | f.close() | |
276 |
|
296 | |||
277 | def handle_error(self, f): |
|
297 | def handle_error(self, f): | |
278 | f.printTraceback() |
|
298 | f.printTraceback() | |
279 | f.raiseException() |
|
299 | f.raiseException() | |
@@ -285,7 +305,7 b' class BatchEngineSet(object):' | |||||
285 | d.addCallback(self.parse_job_id) |
|
305 | d.addCallback(self.parse_job_id) | |
286 | d.addErrback(self.handle_error) |
|
306 | d.addErrback(self.handle_error) | |
287 | return d |
|
307 | return d | |
288 |
|
|
308 | ||
289 | def kill(self): |
|
309 | def kill(self): | |
290 | d = getProcessOutput(self.delete_command, |
|
310 | d = getProcessOutput(self.delete_command, | |
291 | [self.job_id],env=os.environ) |
|
311 | [self.job_id],env=os.environ) | |
@@ -301,6 +321,140 b' class PBSEngineSet(BatchEngineSet):' | |||||
301 | BatchEngineSet.__init__(self, template_file, **kwargs) |
|
321 | BatchEngineSet.__init__(self, template_file, **kwargs) | |
302 |
|
322 | |||
303 |
|
323 | |||
|
324 | sshx_template="""#!/bin/sh | |||
|
325 | "$@" &> /dev/null & | |||
|
326 | echo $! | |||
|
327 | """ | |||
|
328 | ||||
|
329 | engine_killer_template="""#!/bin/sh | |||
|
330 | ps -fu `whoami` | grep '[i]pengine' | awk '{print $2}' | xargs kill -TERM | |||
|
331 | """ | |||
|
332 | ||||
|
333 | class SSHEngineSet(object): | |||
|
334 | sshx_template=sshx_template | |||
|
335 | engine_killer_template=engine_killer_template | |||
|
336 | ||||
|
337 | def __init__(self, engine_hosts, sshx=None, ipengine="ipengine"): | |||
|
338 | """Start a controller on localhost and engines using ssh. | |||
|
339 | ||||
|
340 | The engine_hosts argument is a dict with hostnames as keys and | |||
|
341 | the number of engine (int) as values. sshx is the name of a local | |||
|
342 | file that will be used to run remote commands. This file is used | |||
|
343 | to setup the environment properly. | |||
|
344 | """ | |||
|
345 | ||||
|
346 | self.temp_dir = tempfile.gettempdir() | |||
|
347 | if sshx is not None: | |||
|
348 | self.sshx = sshx | |||
|
349 | else: | |||
|
350 | # Write the sshx.sh file locally from our template. | |||
|
351 | self.sshx = os.path.join( | |||
|
352 | self.temp_dir, | |||
|
353 | '%s-main-sshx.sh' % os.environ['USER'] | |||
|
354 | ) | |||
|
355 | f = open(self.sshx, 'w') | |||
|
356 | f.writelines(self.sshx_template) | |||
|
357 | f.close() | |||
|
358 | self.engine_command = ipengine | |||
|
359 | self.engine_hosts = engine_hosts | |||
|
360 | # Write the engine killer script file locally from our template. | |||
|
361 | self.engine_killer = os.path.join( | |||
|
362 | self.temp_dir, | |||
|
363 | '%s-local-engine_killer.sh' % os.environ['USER'] | |||
|
364 | ) | |||
|
365 | f = open(self.engine_killer, 'w') | |||
|
366 | f.writelines(self.engine_killer_template) | |||
|
367 | f.close() | |||
|
368 | ||||
|
369 | def start(self, send_furl=False): | |||
|
370 | dlist = [] | |||
|
371 | for host in self.engine_hosts.keys(): | |||
|
372 | count = self.engine_hosts[host] | |||
|
373 | d = self._start(host, count, send_furl) | |||
|
374 | dlist.append(d) | |||
|
375 | return gatherBoth(dlist, consumeErrors=True) | |||
|
376 | ||||
|
377 | def _start(self, hostname, count=1, send_furl=False): | |||
|
378 | if send_furl: | |||
|
379 | d = self._scp_furl(hostname) | |||
|
380 | else: | |||
|
381 | d = defer.succeed(None) | |||
|
382 | d.addCallback(lambda r: self._scp_sshx(hostname)) | |||
|
383 | d.addCallback(lambda r: self._ssh_engine(hostname, count)) | |||
|
384 | return d | |||
|
385 | ||||
|
386 | def _scp_furl(self, hostname): | |||
|
387 | scp_cmd = "scp ~/.ipython/security/ipcontroller-engine.furl %s:.ipython/security/" % (hostname) | |||
|
388 | cmd_list = scp_cmd.split() | |||
|
389 | cmd_list[1] = os.path.expanduser(cmd_list[1]) | |||
|
390 | log.msg('Copying furl file: %s' % scp_cmd) | |||
|
391 | d = getProcessOutput(cmd_list[0], cmd_list[1:], env=os.environ) | |||
|
392 | return d | |||
|
393 | ||||
|
394 | def _scp_sshx(self, hostname): | |||
|
395 | scp_cmd = "scp %s %s:%s/%s-sshx.sh" % ( | |||
|
396 | self.sshx, hostname, | |||
|
397 | self.temp_dir, os.environ['USER'] | |||
|
398 | ) | |||
|
399 | ||||
|
400 | log.msg("Copying sshx: %s" % scp_cmd) | |||
|
401 | sshx_scp = scp_cmd.split() | |||
|
402 | d = getProcessOutput(sshx_scp[0], sshx_scp[1:], env=os.environ) | |||
|
403 | return d | |||
|
404 | ||||
|
405 | def _ssh_engine(self, hostname, count): | |||
|
406 | exec_engine = "ssh %s sh %s/%s-sshx.sh %s" % ( | |||
|
407 | hostname, self.temp_dir, | |||
|
408 | os.environ['USER'], self.engine_command | |||
|
409 | ) | |||
|
410 | cmds = exec_engine.split() | |||
|
411 | dlist = [] | |||
|
412 | log.msg("about to start engines...") | |||
|
413 | for i in range(count): | |||
|
414 | log.msg('Starting engines: %s' % exec_engine) | |||
|
415 | d = getProcessOutput(cmds[0], cmds[1:], env=os.environ) | |||
|
416 | dlist.append(d) | |||
|
417 | return gatherBoth(dlist, consumeErrors=True) | |||
|
418 | ||||
|
419 | def kill(self): | |||
|
420 | dlist = [] | |||
|
421 | for host in self.engine_hosts.keys(): | |||
|
422 | d = self._killall(host) | |||
|
423 | dlist.append(d) | |||
|
424 | return gatherBoth(dlist, consumeErrors=True) | |||
|
425 | ||||
|
426 | def _killall(self, hostname): | |||
|
427 | d = self._scp_engine_killer(hostname) | |||
|
428 | d.addCallback(lambda r: self._ssh_kill(hostname)) | |||
|
429 | # d.addErrback(self._exec_err) | |||
|
430 | return d | |||
|
431 | ||||
|
432 | def _scp_engine_killer(self, hostname): | |||
|
433 | scp_cmd = "scp %s %s:%s/%s-engine_killer.sh" % ( | |||
|
434 | self.engine_killer, | |||
|
435 | hostname, | |||
|
436 | self.temp_dir, | |||
|
437 | os.environ['USER'] | |||
|
438 | ) | |||
|
439 | cmds = scp_cmd.split() | |||
|
440 | log.msg('Copying engine_killer: %s' % scp_cmd) | |||
|
441 | d = getProcessOutput(cmds[0], cmds[1:], env=os.environ) | |||
|
442 | return d | |||
|
443 | ||||
|
444 | def _ssh_kill(self, hostname): | |||
|
445 | kill_cmd = "ssh %s sh %s/%s-engine_killer.sh" % ( | |||
|
446 | hostname, | |||
|
447 | self.temp_dir, | |||
|
448 | os.environ['USER'] | |||
|
449 | ) | |||
|
450 | log.msg('Killing engine: %s' % kill_cmd) | |||
|
451 | kill_cmd = kill_cmd.split() | |||
|
452 | d = getProcessOutput(kill_cmd[0], kill_cmd[1:], env=os.environ) | |||
|
453 | return d | |||
|
454 | ||||
|
455 | def _exec_err(self, r): | |||
|
456 | log.msg(r) | |||
|
457 | ||||
304 | #----------------------------------------------------------------------------- |
|
458 | #----------------------------------------------------------------------------- | |
305 | # Main functions for the different types of clusters |
|
459 | # Main functions for the different types of clusters | |
306 | #----------------------------------------------------------------------------- |
|
460 | #----------------------------------------------------------------------------- | |
@@ -311,13 +465,28 b' class PBSEngineSet(BatchEngineSet):' | |||||
311 | # The main functions should then just parse the command line arguments, create |
|
465 | # The main functions should then just parse the command line arguments, create | |
312 | # the appropriate class and call a 'start' method. |
|
466 | # the appropriate class and call a 'start' method. | |
313 |
|
467 | |||
314 | def main_local(args): |
|
468 | def check_security(args, cont_args): | |
315 | cont_args = [] |
|
469 | if (not args.x or not args.y) and not have_crypto: | |
316 | cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller')) |
|
470 | log.err(""" | |
|
471 | OpenSSL/pyOpenSSL is not available, so we can't run in secure mode. | |||
|
472 | Try running ipcluster with the -xy flags: ipcluster local -xy -n 4""") | |||
|
473 | reactor.stop() | |||
|
474 | return False | |||
317 | if args.x: |
|
475 | if args.x: | |
318 | cont_args.append('-x') |
|
476 | cont_args.append('-x') | |
319 | if args.y: |
|
477 | if args.y: | |
320 | cont_args.append('-y') |
|
478 | cont_args.append('-y') | |
|
479 | return True | |||
|
480 | ||||
|
481 | ||||
|
482 | def main_local(args): | |||
|
483 | cont_args = [] | |||
|
484 | cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller')) | |||
|
485 | ||||
|
486 | # Check security settings before proceeding | |||
|
487 | if not check_security(args, cont_args): | |||
|
488 | return | |||
|
489 | ||||
321 | cl = ControllerLauncher(extra_args=cont_args) |
|
490 | cl = ControllerLauncher(extra_args=cont_args) | |
322 | dstart = cl.start() |
|
491 | dstart = cl.start() | |
323 | def start_engines(cont_pid): |
|
492 | def start_engines(cont_pid): | |
@@ -343,13 +512,15 b' def main_local(args):' | |||||
343 | dstart.addCallback(delay_start) |
|
512 | dstart.addCallback(delay_start) | |
344 | dstart.addErrback(lambda f: f.raiseException()) |
|
513 | dstart.addErrback(lambda f: f.raiseException()) | |
345 |
|
514 | |||
|
515 | ||||
346 | def main_mpirun(args): |
|
516 | def main_mpirun(args): | |
347 | cont_args = [] |
|
517 | cont_args = [] | |
348 | cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller')) |
|
518 | cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller')) | |
349 | if args.x: |
|
519 | ||
350 | cont_args.append('-x') |
|
520 | # Check security settings before proceeding | |
351 | if args.y: |
|
521 | if not check_security(args, cont_args): | |
352 | cont_args.append('-y') |
|
522 | return | |
|
523 | ||||
353 | cl = ControllerLauncher(extra_args=cont_args) |
|
524 | cl = ControllerLauncher(extra_args=cont_args) | |
354 | dstart = cl.start() |
|
525 | dstart = cl.start() | |
355 | def start_engines(cont_pid): |
|
526 | def start_engines(cont_pid): | |
@@ -379,13 +550,15 b' def main_mpirun(args):' | |||||
379 | dstart.addCallback(delay_start) |
|
550 | dstart.addCallback(delay_start) | |
380 | dstart.addErrback(lambda f: f.raiseException()) |
|
551 | dstart.addErrback(lambda f: f.raiseException()) | |
381 |
|
552 | |||
|
553 | ||||
382 | def main_pbs(args): |
|
554 | def main_pbs(args): | |
383 | cont_args = [] |
|
555 | cont_args = [] | |
384 | cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller')) |
|
556 | cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller')) | |
385 | if args.x: |
|
557 | ||
386 | cont_args.append('-x') |
|
558 | # Check security settings before proceeding | |
387 | if args.y: |
|
559 | if not check_security(args, cont_args): | |
388 | cont_args.append('-y') |
|
560 | return | |
|
561 | ||||
389 | cl = ControllerLauncher(extra_args=cont_args) |
|
562 | cl = ControllerLauncher(extra_args=cont_args) | |
390 | dstart = cl.start() |
|
563 | dstart = cl.start() | |
391 | def start_engines(r): |
|
564 | def start_engines(r): | |
@@ -402,6 +575,49 b' def main_pbs(args):' | |||||
402 | dstart.addErrback(lambda f: f.raiseException()) |
|
575 | dstart.addErrback(lambda f: f.raiseException()) | |
403 |
|
576 | |||
404 |
|
577 | |||
|
578 | def main_ssh(args): | |||
|
579 | """Start a controller on localhost and engines using ssh. | |||
|
580 | ||||
|
581 | Your clusterfile should look like:: | |||
|
582 | ||||
|
583 | send_furl = False # True, if you want | |||
|
584 | engines = { | |||
|
585 | 'engine_host1' : engine_count, | |||
|
586 | 'engine_host2' : engine_count2 | |||
|
587 | } | |||
|
588 | """ | |||
|
589 | clusterfile = {} | |||
|
590 | execfile(args.clusterfile, clusterfile) | |||
|
591 | if not clusterfile.has_key('send_furl'): | |||
|
592 | clusterfile['send_furl'] = False | |||
|
593 | ||||
|
594 | cont_args = [] | |||
|
595 | cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller')) | |||
|
596 | ||||
|
597 | # Check security settings before proceeding | |||
|
598 | if not check_security(args, cont_args): | |||
|
599 | return | |||
|
600 | ||||
|
601 | cl = ControllerLauncher(extra_args=cont_args) | |||
|
602 | dstart = cl.start() | |||
|
603 | def start_engines(cont_pid): | |||
|
604 | ssh_set = SSHEngineSet(clusterfile['engines'], sshx=args.sshx) | |||
|
605 | def shutdown(signum, frame): | |||
|
606 | d = ssh_set.kill() | |||
|
607 | # d.addErrback(log.err) | |||
|
608 | cl.interrupt_then_kill(1.0) | |||
|
609 | reactor.callLater(2.0, reactor.stop) | |||
|
610 | signal.signal(signal.SIGINT,shutdown) | |||
|
611 | d = ssh_set.start(clusterfile['send_furl']) | |||
|
612 | return d | |||
|
613 | ||||
|
614 | def delay_start(cont_pid): | |||
|
615 | reactor.callLater(1.0, start_engines, cont_pid) | |||
|
616 | ||||
|
617 | dstart.addCallback(delay_start) | |||
|
618 | dstart.addErrback(lambda f: f.raiseException()) | |||
|
619 | ||||
|
620 | ||||
405 | def get_args(): |
|
621 | def get_args(): | |
406 | base_parser = argparse.ArgumentParser(add_help=False) |
|
622 | base_parser = argparse.ArgumentParser(add_help=False) | |
407 | base_parser.add_argument( |
|
623 | base_parser.add_argument( | |
@@ -473,6 +689,27 b' def get_args():' | |||||
473 | default='pbs.template' |
|
689 | default='pbs.template' | |
474 | ) |
|
690 | ) | |
475 | parser_pbs.set_defaults(func=main_pbs) |
|
691 | parser_pbs.set_defaults(func=main_pbs) | |
|
692 | ||||
|
693 | parser_ssh = subparsers.add_parser( | |||
|
694 | 'ssh', | |||
|
695 | help='run a cluster using ssh, should have ssh-keys setup', | |||
|
696 | parents=[base_parser] | |||
|
697 | ) | |||
|
698 | parser_ssh.add_argument( | |||
|
699 | '--clusterfile', | |||
|
700 | type=str, | |||
|
701 | dest='clusterfile', | |||
|
702 | help='python file describing the cluster', | |||
|
703 | default='clusterfile.py', | |||
|
704 | ) | |||
|
705 | parser_ssh.add_argument( | |||
|
706 | '--sshx', | |||
|
707 | type=str, | |||
|
708 | dest='sshx', | |||
|
709 | help='sshx launcher helper' | |||
|
710 | ) | |||
|
711 | parser_ssh.set_defaults(func=main_ssh) | |||
|
712 | ||||
476 | args = parser.parse_args() |
|
713 | args = parser.parse_args() | |
477 | return args |
|
714 | return args | |
478 |
|
715 |
1 | NO CONTENT: modified file chmod 100644 => 100755 |
|
NO CONTENT: modified file chmod 100644 => 100755 |
1 | NO CONTENT: modified file chmod 100644 => 100755 |
|
NO CONTENT: modified file chmod 100644 => 100755 |
1 | NO CONTENT: modified file chmod 100644 => 100755 |
|
NO CONTENT: modified file chmod 100644 => 100755 |
1 | NO CONTENT: modified file chmod 100644 => 100755 |
|
NO CONTENT: modified file chmod 100644 => 100755 |
@@ -49,8 +49,8 b" validCommands = ['a=5'," | |||||
49 | time.sleep(0.1)""", |
|
49 | time.sleep(0.1)""", | |
50 | """from math import cos; |
|
50 | """from math import cos; | |
51 | x = 1.0*cos(0.5)""", # Semicolons lead to Discard ast nodes that should be discarded |
|
51 | x = 1.0*cos(0.5)""", # Semicolons lead to Discard ast nodes that should be discarded | |
52 |
""" |
|
52 | """s = 1 | |
53 |
s = |
|
53 | s = set() | |
54 | """, # Trailing whitespace should be allowed. |
|
54 | """, # Trailing whitespace should be allowed. | |
55 | """import math |
|
55 | """import math | |
56 | math.cos(1.0)""", # Test a method call with a discarded return value |
|
56 | math.cos(1.0)""", # Test a method call with a discarded return value |
@@ -9,7 +9,6 b'' | |||||
9 |
|
9 | |||
10 | import IPython.ipapi |
|
10 | import IPython.ipapi | |
11 |
|
11 | |||
12 |
|
||||
13 | from IPython.genutils import Term |
|
12 | from IPython.genutils import Term | |
14 | from IPython.ipapi import IPyAutocall |
|
13 | from IPython.ipapi import IPyAutocall | |
15 |
|
14 | |||
@@ -41,4 +40,4 b' class Macro(IPyAutocall):' | |||||
41 |
|
40 | |||
42 | def __getstate__(self): |
|
41 | def __getstate__(self): | |
43 | """ needed for safe pickling via %store """ |
|
42 | """ needed for safe pickling via %store """ | |
44 | return {'value': self.value} No newline at end of file |
|
43 | return {'value': self.value} |
@@ -4,8 +4,7 b' A set of convenient utilities for numerical work.' | |||||
4 |
|
4 | |||
5 | Most of this module requires Numerical Python or is meant to be used with it. |
|
5 | Most of this module requires Numerical Python or is meant to be used with it. | |
6 | See http://www.pfdubois.com/numpy for details. |
|
6 | See http://www.pfdubois.com/numpy for details. | |
7 |
|
7 | """ | ||
8 | $Id: numutils.py 958 2005-12-27 23:17:51Z fperez $""" |
|
|||
9 |
|
8 | |||
10 | #***************************************************************************** |
|
9 | #***************************************************************************** | |
11 | # Copyright (C) 2001-2005 Fernando Perez <fperez@colorado.edu> |
|
10 | # Copyright (C) 2001-2005 Fernando Perez <fperez@colorado.edu> | |
@@ -14,10 +13,6 b' $Id: numutils.py 958 2005-12-27 23:17:51Z fperez $"""' | |||||
14 | # the file COPYING, distributed as part of this software. |
|
13 | # the file COPYING, distributed as part of this software. | |
15 | #***************************************************************************** |
|
14 | #***************************************************************************** | |
16 |
|
15 | |||
17 | from IPython import Release |
|
|||
18 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
19 | __license__ = Release.license |
|
|||
20 |
|
||||
21 | __all__ = ['sum_flat','mean_flat','rms_flat','base_repr','binary_repr', |
|
16 | __all__ = ['sum_flat','mean_flat','rms_flat','base_repr','binary_repr', | |
22 | 'amin','amax','amap','zeros_like','empty_like', |
|
17 | 'amin','amax','amap','zeros_like','empty_like', | |
23 | 'frange','diagonal_matrix','identity', |
|
18 | 'frange','diagonal_matrix','identity', |
@@ -12,10 +12,6 b' for your operation system, from platutils_PLATFORMNAME module.' | |||||
12 | # the file COPYING, distributed as part of this software. |
|
12 | # the file COPYING, distributed as part of this software. | |
13 | #***************************************************************************** |
|
13 | #***************************************************************************** | |
14 |
|
14 | |||
15 | from IPython import Release |
|
|||
16 | __author__ = '%s <%s>' % Release.authors['Ville'] |
|
|||
17 | __license__ = Release.license |
|
|||
18 |
|
||||
19 | import os |
|
15 | import os | |
20 | import sys |
|
16 | import sys | |
21 |
|
17 | |||
@@ -35,8 +31,26 b' else:' | |||||
35 | # Functionality that's logically common to all platforms goes here, each |
|
31 | # Functionality that's logically common to all platforms goes here, each | |
36 | # platform-specific module only provides the bits that are OS-dependent. |
|
32 | # platform-specific module only provides the bits that are OS-dependent. | |
37 |
|
33 | |||
38 | def freeze_term_title(): |
|
34 | # XXX - I'm still not happy with a module global for this, but at least now | |
39 | _platutils.ignore_termtitle = True |
|
35 | # there is a public, cross-platform way of toggling the term title control on | |
|
36 | # and off. We should make this a stateful object later on so that each user | |||
|
37 | # can have its own instance if needed. | |||
|
38 | def toggle_set_term_title(val): | |||
|
39 | """Control whether set_term_title is active or not. | |||
|
40 | ||||
|
41 | set_term_title() allows writing to the console titlebar. In embedded | |||
|
42 | widgets this can cause problems, so this call can be used to toggle it on | |||
|
43 | or off as needed. | |||
|
44 | ||||
|
45 | The default state of the module is for the function to be disabled. | |||
|
46 | ||||
|
47 | Parameters | |||
|
48 | ---------- | |||
|
49 | val : bool | |||
|
50 | If True, set_term_title() actually writes to the terminal (using the | |||
|
51 | appropriate platform-specific module). If False, it is a no-op. | |||
|
52 | """ | |||
|
53 | _platutils.ignore_termtitle = not(val) | |||
40 |
|
54 | |||
41 |
|
55 | |||
42 | def set_term_title(title): |
|
56 | def set_term_title(title): | |
@@ -45,3 +59,12 b' def set_term_title(title):' | |||||
45 | if _platutils.ignore_termtitle: |
|
59 | if _platutils.ignore_termtitle: | |
46 | return |
|
60 | return | |
47 | _platutils.set_term_title(title) |
|
61 | _platutils.set_term_title(title) | |
|
62 | ||||
|
63 | ||||
|
64 | #----------------------------------------------------------------------------- | |||
|
65 | # Deprecated functions | |||
|
66 | #----------------------------------------------------------------------------- | |||
|
67 | def freeze_term_title(): | |||
|
68 | warnings.warn("This function is deprecated, use toggle_set_term_title()") | |||
|
69 | _platutils.ignore_termtitle = True | |||
|
70 |
@@ -3,19 +3,20 b'' | |||||
3 |
|
3 | |||
4 | This has empty implementation of the platutils functions, used for |
|
4 | This has empty implementation of the platutils functions, used for | |
5 | unsupported operating systems. |
|
5 | unsupported operating systems. | |
|
6 | ||||
|
7 | Authors | |||
|
8 | ------- | |||
|
9 | - Ville Vainio <vivainio@gmail.com> | |||
6 | """ |
|
10 | """ | |
7 |
|
11 | |||
8 | #***************************************************************************** |
|
12 | #***************************************************************************** | |
9 | # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu> |
|
13 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
14 | # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu> | |||
10 | # |
|
15 | # | |
11 | # Distributed under the terms of the BSD License. The full license is in |
|
16 | # Distributed under the terms of the BSD License. The full license is in | |
12 | # the file COPYING, distributed as part of this software. |
|
17 | # the file COPYING, distributed as part of this software. | |
13 | #***************************************************************************** |
|
18 | #***************************************************************************** | |
14 |
|
19 | |||
15 | from IPython import Release |
|
|||
16 | __author__ = '%s <%s>' % Release.authors['Ville'] |
|
|||
17 | __license__ = Release.license |
|
|||
18 |
|
||||
19 | # This variable is part of the expected API of the module: |
|
20 | # This variable is part of the expected API of the module: | |
20 | ignore_termtitle = True |
|
21 | ignore_termtitle = True | |
21 |
|
22 |
@@ -12,14 +12,10 b' to use these functions in platform agnostic fashion.' | |||||
12 | # the file COPYING, distributed as part of this software. |
|
12 | # the file COPYING, distributed as part of this software. | |
13 | #***************************************************************************** |
|
13 | #***************************************************************************** | |
14 |
|
14 | |||
15 | from IPython import Release |
|
|||
16 | __author__ = '%s <%s>' % Release.authors['Ville'] |
|
|||
17 | __license__ = Release.license |
|
|||
18 |
|
||||
19 | import sys |
|
15 | import sys | |
20 | import os |
|
16 | import os | |
21 |
|
17 | |||
22 |
ignore_termtitle = |
|
18 | ignore_termtitle = True | |
23 |
|
19 | |||
24 | def _dummy_op(*a, **b): |
|
20 | def _dummy_op(*a, **b): | |
25 | """ A no-op function """ |
|
21 | """ A no-op function """ | |
@@ -27,7 +23,7 b' def _dummy_op(*a, **b):' | |||||
27 | def _set_term_title_xterm(title): |
|
23 | def _set_term_title_xterm(title): | |
28 | """ Change virtual terminal title in xterm-workalikes """ |
|
24 | """ Change virtual terminal title in xterm-workalikes """ | |
29 |
|
25 | |||
30 |
sys.stdout.write('\033] |
|
26 | sys.stdout.write('\033]0;%s\007' % title) | |
31 |
|
27 | |||
32 |
|
28 | |||
33 | if os.environ.get('TERM','') == 'xterm': |
|
29 | if os.environ.get('TERM','') == 'xterm': |
@@ -12,13 +12,9 b' to use these functions in platform agnostic fashion.' | |||||
12 | # the file COPYING, distributed as part of this software. |
|
12 | # the file COPYING, distributed as part of this software. | |
13 | #***************************************************************************** |
|
13 | #***************************************************************************** | |
14 |
|
14 | |||
15 | from IPython import Release |
|
|||
16 | __author__ = '%s <%s>' % Release.authors['Ville'] |
|
|||
17 | __license__ = Release.license |
|
|||
18 |
|
||||
19 | import os |
|
15 | import os | |
20 |
|
16 | |||
21 |
ignore_termtitle = |
|
17 | ignore_termtitle = True | |
22 |
|
18 | |||
23 | try: |
|
19 | try: | |
24 | import ctypes |
|
20 | import ctypes |
@@ -5,8 +5,7 b" Readline is used throughout IPython as 'import IPython.rlineimpl as readline'." | |||||
5 |
|
5 | |||
6 | In addition to normal readline stuff, this module provides have_readline |
|
6 | In addition to normal readline stuff, this module provides have_readline | |
7 | boolean and _outputfile variable used in genutils. |
|
7 | boolean and _outputfile variable used in genutils. | |
8 |
|
8 | """ | ||
9 | $Id: Magic.py 1096 2006-01-28 20:08:02Z vivainio $""" |
|
|||
10 |
|
9 | |||
11 | import sys |
|
10 | import sys | |
12 |
|
11 | |||
@@ -53,4 +52,4 b' if have_readline:' | |||||
53 | _rl.clear_history |
|
52 | _rl.clear_history | |
54 | except AttributeError: |
|
53 | except AttributeError: | |
55 | def clear_history(): pass |
|
54 | def clear_history(): pass | |
56 | _rl.clear_history = clear_history No newline at end of file |
|
55 | _rl.clear_history = clear_history |
@@ -1,6 +1,13 b'' | |||||
1 | from IPython.genutils import Term,warn,error,flag_calls, ask_yes_no |
|
1 | """Some globals used by the main Shell classes. | |
|
2 | """ | |||
|
3 | ||||
|
4 | #----------------------------------------------------------------------------- | |||
|
5 | # Module imports | |||
|
6 | #----------------------------------------------------------------------------- | |||
2 |
|
7 | |||
3 | import thread,inspect |
|
8 | # stdlib | |
|
9 | import inspect | |||
|
10 | import thread | |||
4 |
|
11 | |||
5 | try: |
|
12 | try: | |
6 | import ctypes |
|
13 | import ctypes | |
@@ -8,8 +15,12 b' try:' | |||||
8 | except ImportError: |
|
15 | except ImportError: | |
9 | HAS_CTYPES = False |
|
16 | HAS_CTYPES = False | |
10 |
|
17 | |||
|
18 | # our own | |||
|
19 | from IPython.genutils import Term,warn,error,flag_calls, ask_yes_no | |||
11 |
|
20 | |||
|
21 | #----------------------------------------------------------------------------- | |||
12 | # Globals |
|
22 | # Globals | |
|
23 | #----------------------------------------------------------------------------- | |||
13 | # global flag to pass around information about Ctrl-C without exceptions |
|
24 | # global flag to pass around information about Ctrl-C without exceptions | |
14 | KBINT = False |
|
25 | KBINT = False | |
15 |
|
26 | |||
@@ -22,13 +33,11 b' MAIN_THREAD_ID = thread.get_ident()' | |||||
22 | # Tag when runcode() is active, for exception handling |
|
33 | # Tag when runcode() is active, for exception handling | |
23 | CODE_RUN = None |
|
34 | CODE_RUN = None | |
24 |
|
35 | |||
25 |
|
||||
26 | #----------------------------------------------------------------------------- |
|
36 | #----------------------------------------------------------------------------- | |
27 | # This class is trivial now, but I want to have it in to publish a clean |
|
37 | # This class is trivial now, but I want to have it in to publish a clean | |
28 | # interface. Later when the internals are reorganized, code that uses this |
|
38 | # interface. Later when the internals are reorganized, code that uses this | |
29 | # shouldn't have to change. |
|
39 | # shouldn't have to change. | |
30 |
|
40 | |||
31 |
|
||||
32 | if HAS_CTYPES: |
|
41 | if HAS_CTYPES: | |
33 | # Add async exception support. Trick taken from: |
|
42 | # Add async exception support. Trick taken from: | |
34 | # http://sebulba.wikispaces.com/recipe+thread2 |
|
43 | # http://sebulba.wikispaces.com/recipe+thread2 | |
@@ -81,16 +90,12 b' else:' | |||||
81 | # Set global flag so that runsource can know that Ctrl-C was hit |
|
90 | # Set global flag so that runsource can know that Ctrl-C was hit | |
82 | KBINT = True |
|
91 | KBINT = True | |
83 |
|
92 | |||
|
93 | ||||
84 | def run_in_frontend(src): |
|
94 | def run_in_frontend(src): | |
85 |
""" Check if source snippet can be run in the REPL thread, as opposed to |
|
95 | """ Check if source snippet can be run in the REPL thread, as opposed to | |
86 |
|
96 | GUI mainloop (to prevent unnecessary hanging of mainloop). | ||
87 | (to prevent unnecessary hanging of mainloop). |
|
|||
88 |
|
||||
89 | """ |
|
97 | """ | |
90 |
|
98 | |||
91 | if src.startswith('_ip.system(') and not '\n' in src: |
|
99 | if src.startswith('_ip.system(') and not '\n' in src: | |
92 | return True |
|
100 | return True | |
93 | return False |
|
101 | return False | |
94 |
|
||||
95 |
|
||||
96 |
|
@@ -8,7 +8,6 b' import re' | |||||
8 | from IPython.hooks import CommandChainDispatcher |
|
8 | from IPython.hooks import CommandChainDispatcher | |
9 | import IPython.hooks |
|
9 | import IPython.hooks | |
10 |
|
10 | |||
11 |
|
||||
12 | # Code begins |
|
11 | # Code begins | |
13 | class StrDispatch(object): |
|
12 | class StrDispatch(object): | |
14 | """Dispatch (lookup) a set of strings / regexps for match. |
|
13 | """Dispatch (lookup) a set of strings / regexps for match. |
@@ -1,12 +1,10 b'' | |||||
1 | """Decorators for labeling test objects. |
|
1 | """Decorators for labeling test objects. | |
2 |
|
2 | |||
3 | Decorators that merely return a modified version of the original |
|
3 | Decorators that merely return a modified version of the original function | |
4 |
|
|
4 | object are straightforward. Decorators that return a new function object need | |
5 | function object need to use |
|
5 | to use nose.tools.make_decorator(original_function)(decorator) in returning the | |
6 | nose.tools.make_decorator(original_function)(decorator) in returning |
|
6 | decorator, in order to preserve metadata such as function name, setup and | |
7 | the decorator, in order to preserve metadata such as function name, |
|
7 | teardown functions and so on - see nose.tools for more information. | |
8 | setup and teardown functions and so on - see nose.tools for more |
|
|||
9 | information. |
|
|||
10 |
|
8 | |||
11 | This module provides a set of useful decorators meant to be ready to use in |
|
9 | This module provides a set of useful decorators meant to be ready to use in | |
12 | your own tests. See the bottom of the file for the ready-made ones, and if you |
|
10 | your own tests. See the bottom of the file for the ready-made ones, and if you | |
@@ -115,6 +113,115 b' def make_label_dec(label,ds=None):' | |||||
115 |
|
113 | |||
116 | return decor |
|
114 | return decor | |
117 |
|
115 | |||
|
116 | ||||
|
117 | # Inspired by numpy's skipif, but uses the full apply_wrapper utility to | |||
|
118 | # preserve function metadata better and allows the skip condition to be a | |||
|
119 | # callable. | |||
|
120 | def skipif(skip_condition, msg=None): | |||
|
121 | ''' Make function raise SkipTest exception if skip_condition is true | |||
|
122 | ||||
|
123 | Parameters | |||
|
124 | ---------- | |||
|
125 | skip_condition : bool or callable. | |||
|
126 | Flag to determine whether to skip test. If the condition is a | |||
|
127 | callable, it is used at runtime to dynamically make the decision. This | |||
|
128 | is useful for tests that may require costly imports, to delay the cost | |||
|
129 | until the test suite is actually executed. | |||
|
130 | msg : string | |||
|
131 | Message to give on raising a SkipTest exception | |||
|
132 | ||||
|
133 | Returns | |||
|
134 | ------- | |||
|
135 | decorator : function | |||
|
136 | Decorator, which, when applied to a function, causes SkipTest | |||
|
137 | to be raised when the skip_condition was True, and the function | |||
|
138 | to be called normally otherwise. | |||
|
139 | ||||
|
140 | Notes | |||
|
141 | ----- | |||
|
142 | You will see from the code that we had to further decorate the | |||
|
143 | decorator with the nose.tools.make_decorator function in order to | |||
|
144 | transmit function name, and various other metadata. | |||
|
145 | ''' | |||
|
146 | ||||
|
147 | def skip_decorator(f): | |||
|
148 | # Local import to avoid a hard nose dependency and only incur the | |||
|
149 | # import time overhead at actual test-time. | |||
|
150 | import nose | |||
|
151 | ||||
|
152 | # Allow for both boolean or callable skip conditions. | |||
|
153 | if callable(skip_condition): | |||
|
154 | skip_val = lambda : skip_condition() | |||
|
155 | else: | |||
|
156 | skip_val = lambda : skip_condition | |||
|
157 | ||||
|
158 | def get_msg(func,msg=None): | |||
|
159 | """Skip message with information about function being skipped.""" | |||
|
160 | if msg is None: out = 'Test skipped due to test condition.' | |||
|
161 | else: out = msg | |||
|
162 | return "Skipping test: %s. %s" % (func.__name__,out) | |||
|
163 | ||||
|
164 | # We need to define *two* skippers because Python doesn't allow both | |||
|
165 | # return with value and yield inside the same function. | |||
|
166 | def skipper_func(*args, **kwargs): | |||
|
167 | """Skipper for normal test functions.""" | |||
|
168 | if skip_val(): | |||
|
169 | raise nose.SkipTest(get_msg(f,msg)) | |||
|
170 | else: | |||
|
171 | return f(*args, **kwargs) | |||
|
172 | ||||
|
173 | def skipper_gen(*args, **kwargs): | |||
|
174 | """Skipper for test generators.""" | |||
|
175 | if skip_val(): | |||
|
176 | raise nose.SkipTest(get_msg(f,msg)) | |||
|
177 | else: | |||
|
178 | for x in f(*args, **kwargs): | |||
|
179 | yield x | |||
|
180 | ||||
|
181 | # Choose the right skipper to use when building the actual generator. | |||
|
182 | if nose.util.isgenerator(f): | |||
|
183 | skipper = skipper_gen | |||
|
184 | else: | |||
|
185 | skipper = skipper_func | |||
|
186 | ||||
|
187 | return nose.tools.make_decorator(f)(skipper) | |||
|
188 | ||||
|
189 | return skip_decorator | |||
|
190 | ||||
|
191 | # A version with the condition set to true, common case just to attacha message | |||
|
192 | # to a skip decorator | |||
|
193 | def skip(msg=None): | |||
|
194 | """Decorator factory - mark a test function for skipping from test suite. | |||
|
195 | ||||
|
196 | :Parameters: | |||
|
197 | msg : string | |||
|
198 | Optional message to be added. | |||
|
199 | ||||
|
200 | :Returns: | |||
|
201 | decorator : function | |||
|
202 | Decorator, which, when applied to a function, causes SkipTest | |||
|
203 | to be raised, with the optional message added. | |||
|
204 | """ | |||
|
205 | ||||
|
206 | return skipif(True,msg) | |||
|
207 | ||||
|
208 | ||||
|
209 | #----------------------------------------------------------------------------- | |||
|
210 | # Utility functions for decorators | |||
|
211 | def numpy_not_available(): | |||
|
212 | """Can numpy be imported? Returns true if numpy does NOT import. | |||
|
213 | ||||
|
214 | This is used to make a decorator to skip tests that require numpy to be | |||
|
215 | available, but delay the 'import numpy' to test execution time. | |||
|
216 | """ | |||
|
217 | try: | |||
|
218 | import numpy | |||
|
219 | np_not_avail = False | |||
|
220 | except ImportError: | |||
|
221 | np_not_avail = True | |||
|
222 | ||||
|
223 | return np_not_avail | |||
|
224 | ||||
118 | #----------------------------------------------------------------------------- |
|
225 | #----------------------------------------------------------------------------- | |
119 | # Decorators for public use |
|
226 | # Decorators for public use | |
120 |
|
227 | |||
@@ -125,36 +232,23 b" skip_doctest = make_label_dec('skip_doctest'," | |||||
125 | omit from testing, while preserving the docstring for introspection, help, |
|
232 | omit from testing, while preserving the docstring for introspection, help, | |
126 | etc.""") |
|
233 | etc.""") | |
127 |
|
234 | |||
128 | def skip(msg=''): |
|
235 | # Decorators to skip certain tests on specific platforms. | |
129 | """Decorator - mark a test function for skipping from test suite. |
|
236 | skip_win32 = skipif(sys.platform == 'win32', | |
130 |
|
237 | "This test does not run under Windows") | ||
131 | This function *is* already a decorator, it is not a factory like |
|
238 | skip_linux = skipif(sys.platform == 'linux2', | |
132 | make_label_dec or some of those in decorators_numpy. |
|
239 | "This test does not run under Linux") | |
133 |
|
240 | skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X") | ||
134 | :Parameters: |
|
|||
135 |
|
||||
136 | func : function |
|
|||
137 | Test function to be skipped |
|
|||
138 |
|
||||
139 | msg : string |
|
|||
140 | Optional message to be added. |
|
|||
141 | """ |
|
|||
142 |
|
||||
143 | import nose |
|
|||
144 |
|
||||
145 | def inner(func): |
|
|||
146 |
|
241 | |||
147 | def wrapper(*a,**k): |
|
|||
148 | if msg: out = '\n'+msg |
|
|||
149 | else: out = '' |
|
|||
150 | raise nose.SkipTest("Skipping test for function: %s%s" % |
|
|||
151 | (func.__name__,out)) |
|
|||
152 |
|
242 | |||
153 | return apply_wrapper(wrapper,func) |
|
243 | # Decorators to skip tests if not on specific platforms. | |
|
244 | skip_if_not_win32 = skipif(sys.platform != 'win32', | |||
|
245 | "This test only runs under Windows") | |||
|
246 | skip_if_not_linux = skipif(sys.platform != 'linux2', | |||
|
247 | "This test only runs under Linux") | |||
|
248 | skip_if_not_osx = skipif(sys.platform != 'darwin', | |||
|
249 | "This test only runs under OSX") | |||
154 |
|
250 | |||
155 | return inner |
|
251 | # Other skip decorators | |
|
252 | skipif_not_numpy = skipif(numpy_not_available,"This test requires numpy") | |||
156 |
|
253 | |||
157 | # Decorators to skip certain tests on specific platforms. |
|
254 | skipknownfailure = skip('This test is known to fail') | |
158 | skip_win32 = skipif(sys.platform=='win32',"This test does not run under Windows") |
|
|||
159 | skip_linux = skipif(sys.platform=='linux2',"This test does not run under Linux") |
|
|||
160 | skip_osx = skipif(sys.platform=='darwin',"This test does not run under OSX") |
|
@@ -46,13 +46,16 b' def setastest(tf=True):' | |||||
46 | return t |
|
46 | return t | |
47 | return set_test |
|
47 | return set_test | |
48 |
|
48 | |||
49 | def skipif(skip_condition, msg=None): |
|
49 | def skipif(skip_condition=True, msg=None): | |
50 | ''' Make function raise SkipTest exception if skip_condition is true |
|
50 | ''' Make function raise SkipTest exception if skip_condition is true | |
51 |
|
51 | |||
52 | Parameters |
|
52 | Parameters | |
53 | --------- |
|
53 | ---------- | |
54 | skip_condition : bool |
|
54 | skip_condition : bool or callable. | |
55 |
|
|
55 | Flag to determine whether to skip test. If the condition is a | |
|
56 | callable, it is used at runtime to dynamically make the decision. This | |||
|
57 | is useful for tests that may require costly imports, to delay the cost | |||
|
58 | until the test suite is actually executed. | |||
56 | msg : string |
|
59 | msg : string | |
57 | Message to give on raising a SkipTest exception |
|
60 | Message to give on raising a SkipTest exception | |
58 |
|
61 |
@@ -1,16 +1,52 b'' | |||||
1 | #!/usr/bin/env python |
|
|||
2 |
|
|
1 | # -*- coding: utf-8 -*- | |
3 | """IPython Test Suite Runner. |
|
2 | """IPython Test Suite Runner. | |
|
3 | ||||
|
4 | This module provides a main entry point to a user script to test IPython itself | |||
|
5 | from the command line. The main() routine can be used in a similar manner to | |||
|
6 | the ``nosetests`` script, and it takes similar arguments, but if no arguments | |||
|
7 | are given it defaults to testing all of IPython. This should be preferred to | |||
|
8 | using plain ``nosetests`` because a number of nose plugins necessary to test | |||
|
9 | IPython correctly are automatically configured by this code. | |||
4 | """ |
|
10 | """ | |
5 |
|
11 | |||
|
12 | #----------------------------------------------------------------------------- | |||
|
13 | # Module imports | |||
|
14 | #----------------------------------------------------------------------------- | |||
|
15 | ||||
|
16 | # stdlib | |||
6 | import sys |
|
17 | import sys | |
7 | import warnings |
|
18 | import warnings | |
8 |
|
19 | |||
9 | from nose.core import TestProgram |
|
20 | # third-party | |
10 | import nose.plugins.builtin |
|
21 | import nose.plugins.builtin | |
|
22 | from nose.core import TestProgram | |||
11 |
|
23 | |||
|
24 | # Our own imports | |||
12 | from IPython.testing.plugin.ipdoctest import IPythonDoctest |
|
25 | from IPython.testing.plugin.ipdoctest import IPythonDoctest | |
13 |
|
26 | |||
|
27 | #----------------------------------------------------------------------------- | |||
|
28 | # Constants and globals | |||
|
29 | #----------------------------------------------------------------------------- | |||
|
30 | ||||
|
31 | # For the IPythonDoctest plugin, we need to exclude certain patterns that cause | |||
|
32 | # testing problems. We should strive to minimize the number of skipped | |||
|
33 | # modules, since this means untested code. As the testing machinery | |||
|
34 | # solidifies, this list should eventually become empty. | |||
|
35 | EXCLUDE = ['IPython/external/', | |||
|
36 | 'IPython/platutils_win32', | |||
|
37 | 'IPython/frontend/cocoa', | |||
|
38 | 'IPython_doctest_plugin', | |||
|
39 | 'IPython/Gnuplot', | |||
|
40 | 'IPython/Extensions/ipy_', | |||
|
41 | 'IPython/Extensions/clearcmd', | |||
|
42 | 'IPython/Extensions/PhysicalQIn', | |||
|
43 | 'IPython/Extensions/scitedirector', | |||
|
44 | ] | |||
|
45 | ||||
|
46 | #----------------------------------------------------------------------------- | |||
|
47 | # Functions and classes | |||
|
48 | #----------------------------------------------------------------------------- | |||
|
49 | ||||
14 | def main(): |
|
50 | def main(): | |
15 | """Run the IPython test suite. |
|
51 | """Run the IPython test suite. | |
16 | """ |
|
52 | """ | |
@@ -18,36 +54,45 b' def main():' | |||||
18 | warnings.filterwarnings('ignore', |
|
54 | warnings.filterwarnings('ignore', | |
19 | 'This will be removed soon. Use IPython.testing.util instead') |
|
55 | 'This will be removed soon. Use IPython.testing.util instead') | |
20 |
|
56 | |||
21 |
|
57 | argv = sys.argv + [ | ||
22 | # construct list of plugins, omitting the existing doctest plugin |
|
58 | # Loading ipdoctest causes problems with Twisted. | |
23 | plugins = [IPythonDoctest()] |
|
59 | # I am removing this as a temporary fix to get the | |
|
60 | # test suite back into working shape. Our nose | |||
|
61 | # plugin needs to be gone through with a fine | |||
|
62 | # toothed comb to find what is causing the problem. | |||
|
63 | # '--with-ipdoctest', | |||
|
64 | '--doctest-tests','--doctest-extension=txt', | |||
|
65 | '--detailed-errors', | |||
|
66 | ||||
|
67 | # We add --exe because of setuptools' imbecility (it | |||
|
68 | # blindly does chmod +x on ALL files). Nose does the | |||
|
69 | # right thing and it tries to avoid executables, | |||
|
70 | # setuptools unfortunately forces our hand here. This | |||
|
71 | # has been discussed on the distutils list and the | |||
|
72 | # setuptools devs refuse to fix this problem! | |||
|
73 | '--exe', | |||
|
74 | ] | |||
|
75 | ||||
|
76 | # Detect if any tests were required by explicitly calling an IPython | |||
|
77 | # submodule or giving a specific path | |||
|
78 | has_tests = False | |||
|
79 | for arg in sys.argv: | |||
|
80 | if 'IPython' in arg or arg.endswith('.py') or \ | |||
|
81 | (':' in arg and '.py' in arg): | |||
|
82 | has_tests = True | |||
|
83 | break | |||
|
84 | # If nothing was specifically requested, test full IPython | |||
|
85 | if not has_tests: | |||
|
86 | argv.append('IPython') | |||
|
87 | ||||
|
88 | # Construct list of plugins, omitting the existing doctest plugin. | |||
|
89 | plugins = [IPythonDoctest(EXCLUDE)] | |||
24 | for p in nose.plugins.builtin.plugins: |
|
90 | for p in nose.plugins.builtin.plugins: | |
25 | plug = p() |
|
91 | plug = p() | |
26 | if plug.name == 'doctest': |
|
92 | if plug.name == 'doctest': | |
27 | continue |
|
93 | continue | |
28 |
|
94 | |||
29 | #print 'adding plugin:',plug.name # dbg |
|
95 | #print '*** adding plugin:',plug.name # dbg | |
30 | plugins.append(plug) |
|
96 | plugins.append(plug) | |
31 |
|
97 | |||
32 | argv = sys.argv + ['--doctest-tests','--doctest-extension=txt', |
|
|||
33 | '--detailed-errors', |
|
|||
34 |
|
||||
35 | # We add --exe because of setuptools' imbecility (it |
|
|||
36 | # blindly does chmod +x on ALL files). Nose does the |
|
|||
37 | # right thing and it tries to avoid executables, |
|
|||
38 | # setuptools unfortunately forces our hand here. This |
|
|||
39 | # has been discussed on the distutils list and the |
|
|||
40 | # setuptools devs refuse to fix this problem! |
|
|||
41 | '--exe', |
|
|||
42 | ] |
|
|||
43 |
|
||||
44 | has_ip = False |
|
|||
45 | for arg in sys.argv: |
|
|||
46 | if 'IPython' in arg: |
|
|||
47 | has_ip = True |
|
|||
48 | break |
|
|||
49 |
|
||||
50 | if not has_ip: |
|
|||
51 | argv.append('IPython') |
|
|||
52 |
|
||||
53 | TestProgram(argv=argv,plugins=plugins) |
|
98 | TestProgram(argv=argv,plugins=plugins) |
@@ -36,8 +36,8 b' deco:' | |||||
36 | magic: plugin |
|
36 | magic: plugin | |
37 | $(NOSE) IPython.Magic |
|
37 | $(NOSE) IPython.Magic | |
38 |
|
38 | |||
39 |
|
|
39 | excolors: plugin | |
40 |
$(NOSE) IPython. |
|
40 | $(NOSE) IPython.excolors | |
41 |
|
41 | |||
42 | iplib: plugin |
|
42 | iplib: plugin | |
43 | $(NOSE) IPython.iplib |
|
43 | $(NOSE) IPython.iplib |
@@ -29,9 +29,6 b' def ipfunc():' | |||||
29 |
|
29 | |||
30 | In [1]: import os |
|
30 | In [1]: import os | |
31 |
|
31 | |||
32 | In [2]: cd / |
|
|||
33 | / |
|
|||
34 |
|
||||
35 | In [3]: 2+3 |
|
32 | In [3]: 2+3 | |
36 | Out[3]: 5 |
|
33 | Out[3]: 5 | |
37 |
|
34 |
@@ -65,13 +65,28 b' log = logging.getLogger(__name__)' | |||||
65 | # test globals. Once we move over to a clean magic system, this will be done |
|
65 | # test globals. Once we move over to a clean magic system, this will be done | |
66 | # with much less ugliness. |
|
66 | # with much less ugliness. | |
67 |
|
67 | |||
|
68 | class py_file_finder(object): | |||
|
69 | def __init__(self,test_filename): | |||
|
70 | self.test_filename = test_filename | |||
|
71 | ||||
|
72 | def __call__(self,name): | |||
|
73 | from IPython.genutils import get_py_filename | |||
|
74 | try: | |||
|
75 | return get_py_filename(name) | |||
|
76 | except IOError: | |||
|
77 | test_dir = os.path.dirname(self.test_filename) | |||
|
78 | new_path = os.path.join(test_dir,name) | |||
|
79 | return get_py_filename(new_path) | |||
|
80 | ||||
|
81 | ||||
68 | def _run_ns_sync(self,arg_s,runner=None): |
|
82 | def _run_ns_sync(self,arg_s,runner=None): | |
69 | """Modified version of %run that syncs testing namespaces. |
|
83 | """Modified version of %run that syncs testing namespaces. | |
70 |
|
84 | |||
71 | This is strictly needed for running doctests that call %run. |
|
85 | This is strictly needed for running doctests that call %run. | |
72 | """ |
|
86 | """ | |
73 |
|
87 | |||
74 | out = _ip.IP.magic_run_ori(arg_s,runner) |
|
88 | finder = py_file_finder(_run_ns_sync.test_filename) | |
|
89 | out = _ip.IP.magic_run_ori(arg_s,runner,finder) | |||
75 | _run_ns_sync.test_globs.update(_ip.user_ns) |
|
90 | _run_ns_sync.test_globs.update(_ip.user_ns) | |
76 | return out |
|
91 | return out | |
77 |
|
92 | |||
@@ -129,8 +144,7 b' def start_ipython():' | |||||
129 |
|
144 | |||
130 | # Start IPython instance. We customize it to start with minimal frills. |
|
145 | # Start IPython instance. We customize it to start with minimal frills. | |
131 | user_ns,global_ns = IPython.ipapi.make_user_namespaces(ipnsdict(),dict()) |
|
146 | user_ns,global_ns = IPython.ipapi.make_user_namespaces(ipnsdict(),dict()) | |
132 |
|
147 | IPython.Shell.IPShell(['--colors=NoColor','--noterm_title'], | ||
133 | IPython.Shell.IPShell(['--classic','--noterm_title'], |
|
|||
134 | user_ns,global_ns) |
|
148 | user_ns,global_ns) | |
135 |
|
149 | |||
136 | # Deactivate the various python system hooks added by ipython for |
|
150 | # Deactivate the various python system hooks added by ipython for | |
@@ -172,13 +186,19 b' def is_extension_module(filename):' | |||||
172 | return os.path.splitext(filename)[1].lower() in ('.so','.pyd') |
|
186 | return os.path.splitext(filename)[1].lower() in ('.so','.pyd') | |
173 |
|
187 | |||
174 |
|
188 | |||
175 |
class |
|
189 | class DocTestSkip(object): | |
|
190 | """Object wrapper for doctests to be skipped.""" | |||
|
191 | ||||
|
192 | ds_skip = """Doctest to skip. | |||
|
193 | >>> 1 #doctest: +SKIP | |||
|
194 | """ | |||
|
195 | ||||
176 | def __init__(self,obj): |
|
196 | def __init__(self,obj): | |
177 | self.obj = obj |
|
197 | self.obj = obj | |
178 |
|
198 | |||
179 | def __getattribute__(self,key): |
|
199 | def __getattribute__(self,key): | |
180 | if key == '__doc__': |
|
200 | if key == '__doc__': | |
181 |
return |
|
201 | return DocTestSkip.ds_skip | |
182 | else: |
|
202 | else: | |
183 | return getattr(object.__getattribute__(self,'obj'),key) |
|
203 | return getattr(object.__getattribute__(self,'obj'),key) | |
184 |
|
204 | |||
@@ -222,7 +242,7 b' class DocTestFinder(doctest.DocTestFinder):' | |||||
222 |
|
242 | |||
223 | if hasattr(obj,"skip_doctest"): |
|
243 | if hasattr(obj,"skip_doctest"): | |
224 | #print 'SKIPPING DOCTEST FOR:',obj # dbg |
|
244 | #print 'SKIPPING DOCTEST FOR:',obj # dbg | |
225 |
obj = |
|
245 | obj = DocTestSkip(obj) | |
226 |
|
246 | |||
227 | doctest.DocTestFinder._find(self,tests, obj, name, module, |
|
247 | doctest.DocTestFinder._find(self,tests, obj, name, module, | |
228 | source_lines, globs, seen) |
|
248 | source_lines, globs, seen) | |
@@ -372,7 +392,6 b' class DocTestCase(doctests.DocTestCase):' | |||||
372 | self._dt_test.globs = _ip.IP.user_ns |
|
392 | self._dt_test.globs = _ip.IP.user_ns | |
373 |
|
393 | |||
374 | doctests.DocTestCase.setUp(self) |
|
394 | doctests.DocTestCase.setUp(self) | |
375 |
|
||||
376 |
|
395 | |||
377 |
|
396 | |||
378 | # A simple subclassing of the original with a different class name, so we can |
|
397 | # A simple subclassing of the original with a different class name, so we can | |
@@ -444,7 +463,11 b' class IPDocTestParser(doctest.DocTestParser):' | |||||
444 | """Convert input IPython source into valid Python.""" |
|
463 | """Convert input IPython source into valid Python.""" | |
445 | out = [] |
|
464 | out = [] | |
446 | newline = out.append |
|
465 | newline = out.append | |
447 | for lnum,line in enumerate(source.splitlines()): |
|
466 | #print 'IPSRC:\n',source,'\n###' # dbg | |
|
467 | # The input source must be first stripped of all bracketing whitespace | |||
|
468 | # and turned into lines, so it looks to the parser like regular user | |||
|
469 | # input | |||
|
470 | for lnum,line in enumerate(source.strip().splitlines()): | |||
448 | newline(_ip.IP.prefilter(line,lnum>0)) |
|
471 | newline(_ip.IP.prefilter(line,lnum>0)) | |
449 | newline('') # ensure a closing newline, needed by doctest |
|
472 | newline('') # ensure a closing newline, needed by doctest | |
450 | #print "PYSRC:", '\n'.join(out) # dbg |
|
473 | #print "PYSRC:", '\n'.join(out) # dbg | |
@@ -638,7 +661,8 b' class IPDocTestRunner(doctest.DocTestRunner,object):' | |||||
638 | # when called (rather than unconconditionally updating test.globs here |
|
661 | # when called (rather than unconconditionally updating test.globs here | |
639 | # for all examples, most of which won't be calling %run anyway). |
|
662 | # for all examples, most of which won't be calling %run anyway). | |
640 | _run_ns_sync.test_globs = test.globs |
|
663 | _run_ns_sync.test_globs = test.globs | |
641 |
|
664 | _run_ns_sync.test_filename = test.filename | ||
|
665 | ||||
642 | return super(IPDocTestRunner,self).run(test, |
|
666 | return super(IPDocTestRunner,self).run(test, | |
643 | compileflags,out,clear_globs) |
|
667 | compileflags,out,clear_globs) | |
644 |
|
668 | |||
@@ -656,6 +680,22 b' class ExtensionDoctest(doctests.Doctest):' | |||||
656 | name = 'extdoctest' # call nosetests with --with-extdoctest |
|
680 | name = 'extdoctest' # call nosetests with --with-extdoctest | |
657 | enabled = True |
|
681 | enabled = True | |
658 |
|
682 | |||
|
683 | def __init__(self,exclude_patterns=None): | |||
|
684 | """Create a new ExtensionDoctest plugin. | |||
|
685 | ||||
|
686 | Parameters | |||
|
687 | ---------- | |||
|
688 | ||||
|
689 | exclude_patterns : sequence of strings, optional | |||
|
690 | These patterns are compiled as regular expressions, subsequently used | |||
|
691 | to exclude any filename which matches them from inclusion in the test | |||
|
692 | suite (using pattern.search(), NOT pattern.match() ). | |||
|
693 | """ | |||
|
694 | if exclude_patterns is None: | |||
|
695 | exclude_patterns = [] | |||
|
696 | self.exclude_patterns = map(re.compile,exclude_patterns) | |||
|
697 | doctests.Doctest.__init__(self) | |||
|
698 | ||||
659 | def options(self, parser, env=os.environ): |
|
699 | def options(self, parser, env=os.environ): | |
660 | Plugin.options(self, parser, env) |
|
700 | Plugin.options(self, parser, env) | |
661 | parser.add_option('--doctest-tests', action='store_true', |
|
701 | parser.add_option('--doctest-tests', action='store_true', | |
@@ -688,6 +728,7 b' class ExtensionDoctest(doctests.Doctest):' | |||||
688 | self.globs = None |
|
728 | self.globs = None | |
689 | self.extraglobs = None |
|
729 | self.extraglobs = None | |
690 |
|
730 | |||
|
731 | ||||
691 | def loadTestsFromExtensionModule(self,filename): |
|
732 | def loadTestsFromExtensionModule(self,filename): | |
692 | bpath,mod = os.path.split(filename) |
|
733 | bpath,mod = os.path.split(filename) | |
693 | modname = os.path.splitext(mod)[0] |
|
734 | modname = os.path.splitext(mod)[0] | |
@@ -703,8 +744,8 b' class ExtensionDoctest(doctests.Doctest):' | |||||
703 | # a few modifications to control output checking. |
|
744 | # a few modifications to control output checking. | |
704 |
|
745 | |||
705 | def loadTestsFromModule(self, module): |
|
746 | def loadTestsFromModule(self, module): | |
706 | #print 'lTM',module # dbg |
|
747 | #print '*** ipdoctest - lTM',module # dbg | |
707 |
|
748 | |||
708 | if not self.matches(module.__name__): |
|
749 | if not self.matches(module.__name__): | |
709 | log.debug("Doctest doesn't want module %s", module) |
|
750 | log.debug("Doctest doesn't want module %s", module) | |
710 | return |
|
751 | return | |
@@ -733,8 +774,6 b' class ExtensionDoctest(doctests.Doctest):' | |||||
733 |
|
774 | |||
734 |
|
775 | |||
735 | def loadTestsFromFile(self, filename): |
|
776 | def loadTestsFromFile(self, filename): | |
736 | #print 'lTF',filename # dbg |
|
|||
737 |
|
||||
738 | if is_extension_module(filename): |
|
777 | if is_extension_module(filename): | |
739 | for t in self.loadTestsFromExtensionModule(filename): |
|
778 | for t in self.loadTestsFromExtensionModule(filename): | |
740 | yield t |
|
779 | yield t | |
@@ -761,22 +800,10 b' class ExtensionDoctest(doctests.Doctest):' | |||||
761 | Modified version that accepts extension modules as valid containers for |
|
800 | Modified version that accepts extension modules as valid containers for | |
762 | doctests. |
|
801 | doctests. | |
763 | """ |
|
802 | """ | |
764 |
print ' |
|
803 | #print '*** ipdoctest- wantFile:',filename # dbg | |
765 |
|
804 | |||
766 | # XXX - temporarily hardcoded list, will move to driver later |
|
805 | for pat in self.exclude_patterns: | |
767 | exclude = ['IPython/external/', |
|
806 | if pat.search(filename): | |
768 | 'IPython/platutils_win32', |
|
|||
769 | 'IPython/frontend/cocoa', |
|
|||
770 | 'IPython_doctest_plugin', |
|
|||
771 | 'IPython/Gnuplot', |
|
|||
772 | 'IPython/Extensions/ipy_', |
|
|||
773 | 'IPython/Extensions/PhysicalQIn', |
|
|||
774 | 'IPython/Extensions/scitedirector', |
|
|||
775 | 'IPython/testing/plugin', |
|
|||
776 | ] |
|
|||
777 |
|
||||
778 | for fex in exclude: |
|
|||
779 | if fex in filename: # substring |
|
|||
780 | #print '###>>> SKIP:',filename # dbg |
|
807 | #print '###>>> SKIP:',filename # dbg | |
781 | return False |
|
808 | return False | |
782 |
|
809 | |||
@@ -791,6 +818,23 b' class IPythonDoctest(ExtensionDoctest):' | |||||
791 | """ |
|
818 | """ | |
792 | name = 'ipdoctest' # call nosetests with --with-ipdoctest |
|
819 | name = 'ipdoctest' # call nosetests with --with-ipdoctest | |
793 | enabled = True |
|
820 | enabled = True | |
|
821 | ||||
|
822 | def makeTest(self, obj, parent): | |||
|
823 | """Look for doctests in the given object, which will be a | |||
|
824 | function, method or class. | |||
|
825 | """ | |||
|
826 | # always use whitespace and ellipsis options | |||
|
827 | optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS | |||
|
828 | ||||
|
829 | doctests = self.finder.find(obj, module=getmodule(parent)) | |||
|
830 | if doctests: | |||
|
831 | for test in doctests: | |||
|
832 | if len(test.examples) == 0: | |||
|
833 | continue | |||
|
834 | ||||
|
835 | yield DocTestCase(test, obj=obj, | |||
|
836 | optionflags=optionflags, | |||
|
837 | checker=self.checker) | |||
794 |
|
838 | |||
795 | def configure(self, options, config): |
|
839 | def configure(self, options, config): | |
796 |
|
840 |
@@ -15,18 +15,277 b' __docformat__ = "restructuredtext en"' | |||||
15 | # Imports |
|
15 | # Imports | |
16 | #----------------------------------------------------------------------------- |
|
16 | #----------------------------------------------------------------------------- | |
17 |
|
17 | |||
|
18 | # stdlib | |||
|
19 | import os | |||
|
20 | import shutil | |||
|
21 | import sys | |||
|
22 | import tempfile | |||
|
23 | ||||
|
24 | from os.path import join, abspath, split | |||
|
25 | ||||
|
26 | # third-party | |||
|
27 | import nose.tools as nt | |||
|
28 | ||||
|
29 | from nose import with_setup | |||
|
30 | from nose.tools import raises | |||
|
31 | ||||
|
32 | # Our own | |||
|
33 | import IPython | |||
18 | from IPython import genutils |
|
34 | from IPython import genutils | |
|
35 | from IPython.testing.decorators import skipif, skip_if_not_win32 | |||
|
36 | ||||
|
37 | # Platform-dependent imports | |||
|
38 | try: | |||
|
39 | import _winreg as wreg | |||
|
40 | except ImportError: | |||
|
41 | #Fake _winreg module on none windows platforms | |||
|
42 | import new | |||
|
43 | sys.modules["_winreg"] = new.module("_winreg") | |||
|
44 | import _winreg as wreg | |||
|
45 | #Add entries that needs to be stubbed by the testing code | |||
|
46 | (wreg.OpenKey, wreg.QueryValueEx,) = (None, None) | |||
|
47 | ||||
|
48 | #----------------------------------------------------------------------------- | |||
|
49 | # Globals | |||
|
50 | #----------------------------------------------------------------------------- | |||
|
51 | env = os.environ | |||
|
52 | TEST_FILE_PATH = split(abspath(__file__))[0] | |||
|
53 | TMP_TEST_DIR = tempfile.mkdtemp() | |||
|
54 | HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir") | |||
|
55 | IP_TEST_DIR = join(HOME_TEST_DIR,'_ipython') | |||
|
56 | # | |||
|
57 | # Setup/teardown functions/decorators | |||
|
58 | # | |||
|
59 | ||||
|
60 | def setup(): | |||
|
61 | """Setup testenvironment for the module: | |||
|
62 | ||||
|
63 | - Adds dummy home dir tree | |||
|
64 | """ | |||
|
65 | # Do not mask exceptions here. In particular, catching WindowsError is a | |||
|
66 | # problem because that exception is only defined on Windows... | |||
|
67 | os.makedirs(IP_TEST_DIR) | |||
|
68 | ||||
|
69 | def teardown(): | |||
|
70 | """Teardown testenvironment for the module: | |||
|
71 | ||||
|
72 | - Remove dummy home dir tree | |||
|
73 | """ | |||
|
74 | # Note: we remove the parent test dir, which is the root of all test | |||
|
75 | # subdirs we may have created. Use shutil instead of os.removedirs, so | |||
|
76 | # that non-empty directories are all recursively removed. | |||
|
77 | shutil.rmtree(TMP_TEST_DIR) | |||
|
78 | ||||
|
79 | ||||
|
80 | def setup_environment(): | |||
|
81 | """Setup testenvironment for some functions that are tested | |||
|
82 | in this module. In particular this functions stores attributes | |||
|
83 | and other things that we need to stub in some test functions. | |||
|
84 | This needs to be done on a function level and not module level because | |||
|
85 | each testfunction needs a pristine environment. | |||
|
86 | """ | |||
|
87 | global oldstuff, platformstuff | |||
|
88 | oldstuff = (env.copy(), os.name, genutils.get_home_dir, IPython.__file__,) | |||
|
89 | ||||
|
90 | if os.name == 'nt': | |||
|
91 | platformstuff = (wreg.OpenKey, wreg.QueryValueEx,) | |||
|
92 | ||||
|
93 | if 'IPYTHONDIR' in env: | |||
|
94 | del env['IPYTHONDIR'] | |||
|
95 | ||||
|
96 | def teardown_environment(): | |||
|
97 | """Restore things that were remebered by the setup_environment function | |||
|
98 | """ | |||
|
99 | (oldenv, os.name, genutils.get_home_dir, IPython.__file__,) = oldstuff | |||
|
100 | for key in env.keys(): | |||
|
101 | if key not in oldenv: | |||
|
102 | del env[key] | |||
|
103 | env.update(oldenv) | |||
|
104 | if hasattr(sys, 'frozen'): | |||
|
105 | del sys.frozen | |||
|
106 | if os.name == 'nt': | |||
|
107 | (wreg.OpenKey, wreg.QueryValueEx,) = platformstuff | |||
|
108 | ||||
|
109 | # Build decorator that uses the setup_environment/setup_environment | |||
|
110 | with_enivronment = with_setup(setup_environment, teardown_environment) | |||
|
111 | ||||
|
112 | ||||
|
113 | # | |||
|
114 | # Tests for get_home_dir | |||
|
115 | # | |||
|
116 | ||||
|
117 | @skip_if_not_win32 | |||
|
118 | @with_enivronment | |||
|
119 | def test_get_home_dir_1(): | |||
|
120 | """Testcase for py2exe logic, un-compressed lib | |||
|
121 | """ | |||
|
122 | sys.frozen = True | |||
|
123 | ||||
|
124 | #fake filename for IPython.__init__ | |||
|
125 | IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py")) | |||
|
126 | ||||
|
127 | home_dir = genutils.get_home_dir() | |||
|
128 | nt.assert_equal(home_dir, abspath(HOME_TEST_DIR)) | |||
|
129 | ||||
|
130 | @skip_if_not_win32 | |||
|
131 | @with_enivronment | |||
|
132 | def test_get_home_dir_2(): | |||
|
133 | """Testcase for py2exe logic, compressed lib | |||
|
134 | """ | |||
|
135 | sys.frozen = True | |||
|
136 | #fake filename for IPython.__init__ | |||
|
137 | IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower() | |||
|
138 | ||||
|
139 | home_dir = genutils.get_home_dir() | |||
|
140 | nt.assert_equal(home_dir, abspath(HOME_TEST_DIR).lower()) | |||
|
141 | ||||
|
142 | @with_enivronment | |||
|
143 | def test_get_home_dir_3(): | |||
|
144 | """Testcase $HOME is set, then use its value as home directory.""" | |||
|
145 | env["HOME"] = HOME_TEST_DIR | |||
|
146 | home_dir = genutils.get_home_dir() | |||
|
147 | nt.assert_equal(home_dir, env["HOME"]) | |||
|
148 | ||||
|
149 | @with_enivronment | |||
|
150 | def test_get_home_dir_4(): | |||
|
151 | """Testcase $HOME is not set, os=='poix'. | |||
|
152 | This should fail with HomeDirError""" | |||
|
153 | ||||
|
154 | os.name = 'posix' | |||
|
155 | if 'HOME' in env: del env['HOME'] | |||
|
156 | nt.assert_raises(genutils.HomeDirError, genutils.get_home_dir) | |||
|
157 | ||||
|
158 | @skip_if_not_win32 | |||
|
159 | @with_enivronment | |||
|
160 | def test_get_home_dir_5(): | |||
|
161 | """Testcase $HOME is not set, os=='nt' | |||
|
162 | env['HOMEDRIVE'],env['HOMEPATH'] points to path.""" | |||
|
163 | ||||
|
164 | os.name = 'nt' | |||
|
165 | if 'HOME' in env: del env['HOME'] | |||
|
166 | env['HOMEDRIVE'], env['HOMEPATH'] = os.path.splitdrive(HOME_TEST_DIR) | |||
19 |
|
167 | |||
|
168 | home_dir = genutils.get_home_dir() | |||
|
169 | nt.assert_equal(home_dir, abspath(HOME_TEST_DIR)) | |||
|
170 | ||||
|
171 | @skip_if_not_win32 | |||
|
172 | @with_enivronment | |||
|
173 | def test_get_home_dir_6(): | |||
|
174 | """Testcase $HOME is not set, os=='nt' | |||
|
175 | env['HOMEDRIVE'],env['HOMEPATH'] do not point to path. | |||
|
176 | env['USERPROFILE'] points to path | |||
|
177 | """ | |||
|
178 | ||||
|
179 | os.name = 'nt' | |||
|
180 | if 'HOME' in env: del env['HOME'] | |||
|
181 | env['HOMEDRIVE'], env['HOMEPATH'] = os.path.abspath(TEST_FILE_PATH), "DOES NOT EXIST" | |||
|
182 | env["USERPROFILE"] = abspath(HOME_TEST_DIR) | |||
|
183 | ||||
|
184 | home_dir = genutils.get_home_dir() | |||
|
185 | nt.assert_equal(home_dir, abspath(HOME_TEST_DIR)) | |||
|
186 | ||||
|
187 | # Should we stub wreg fully so we can run the test on all platforms? | |||
|
188 | @skip_if_not_win32 | |||
|
189 | @with_enivronment | |||
|
190 | def test_get_home_dir_7(): | |||
|
191 | """Testcase $HOME is not set, os=='nt' | |||
|
192 | env['HOMEDRIVE'],env['HOMEPATH'], env['USERPROFILE'] missing | |||
|
193 | """ | |||
|
194 | os.name = 'nt' | |||
|
195 | if 'HOME' in env: del env['HOME'] | |||
|
196 | if 'HOMEDRIVE' in env: del env['HOMEDRIVE'] | |||
|
197 | ||||
|
198 | #Stub windows registry functions | |||
|
199 | def OpenKey(x, y): | |||
|
200 | class key: | |||
|
201 | def Close(self): | |||
|
202 | pass | |||
|
203 | return key() | |||
|
204 | def QueryValueEx(x, y): | |||
|
205 | return [abspath(HOME_TEST_DIR)] | |||
|
206 | ||||
|
207 | wreg.OpenKey = OpenKey | |||
|
208 | wreg.QueryValueEx = QueryValueEx | |||
20 |
|
209 | |||
21 | def test_get_home_dir(): |
|
|||
22 | """Make sure we can get the home directory.""" |
|
|||
23 | home_dir = genutils.get_home_dir() |
|
210 | home_dir = genutils.get_home_dir() | |
|
211 | nt.assert_equal(home_dir, abspath(HOME_TEST_DIR)) | |||
|
212 | ||||
|
213 | ||||
|
214 | # | |||
|
215 | # Tests for get_ipython_dir | |||
|
216 | # | |||
|
217 | ||||
|
218 | @with_enivronment | |||
|
219 | def test_get_ipython_dir_1(): | |||
|
220 | """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions.""" | |||
|
221 | env['IPYTHONDIR'] = "someplace/.ipython" | |||
|
222 | ipdir = genutils.get_ipython_dir() | |||
|
223 | nt.assert_equal(ipdir, os.path.abspath("someplace/.ipython")) | |||
24 |
|
224 | |||
25 | def test_get_ipython_dir(): |
|
225 | ||
26 | """Make sure we can get the ipython directory.""" |
|
226 | @with_enivronment | |
|
227 | def test_get_ipython_dir_2(): | |||
|
228 | """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions.""" | |||
|
229 | genutils.get_home_dir = lambda : "someplace" | |||
|
230 | os.name = "posix" | |||
|
231 | ipdir = genutils.get_ipython_dir() | |||
|
232 | nt.assert_equal(ipdir, os.path.abspath(os.path.join("someplace", ".ipython"))) | |||
|
233 | ||||
|
234 | @with_enivronment | |||
|
235 | def test_get_ipython_dir_3(): | |||
|
236 | """test_get_ipython_dir_3, Testcase to see if we can call get_ipython_dir without Exceptions.""" | |||
|
237 | genutils.get_home_dir = lambda : "someplace" | |||
|
238 | os.name = "nt" | |||
27 | ipdir = genutils.get_ipython_dir() |
|
239 | ipdir = genutils.get_ipython_dir() | |
|
240 | nt.assert_equal(ipdir, os.path.abspath(os.path.join("someplace", "_ipython"))) | |||
|
241 | ||||
|
242 | ||||
|
243 | # | |||
|
244 | # Tests for get_security_dir | |||
|
245 | # | |||
28 |
|
246 | |||
|
247 | @with_enivronment | |||
29 | def test_get_security_dir(): |
|
248 | def test_get_security_dir(): | |
30 | """Make sure we can get the ipython/security directory.""" |
|
249 | """Testcase to see if we can call get_security_dir without Exceptions.""" | |
31 | sdir = genutils.get_security_dir() |
|
250 | sdir = genutils.get_security_dir() | |
32 | No newline at end of file |
|
251 | ||
|
252 | ||||
|
253 | # | |||
|
254 | # Tests for popkey | |||
|
255 | # | |||
|
256 | ||||
|
257 | def test_popkey_1(): | |||
|
258 | """test_popkey_1, Basic usage test of popkey | |||
|
259 | """ | |||
|
260 | dct = dict(a=1, b=2, c=3) | |||
|
261 | nt.assert_equal(genutils.popkey(dct, "a"), 1) | |||
|
262 | nt.assert_equal(dct, dict(b=2, c=3)) | |||
|
263 | nt.assert_equal(genutils.popkey(dct, "b"), 2) | |||
|
264 | nt.assert_equal(dct, dict(c=3)) | |||
|
265 | nt.assert_equal(genutils.popkey(dct, "c"), 3) | |||
|
266 | nt.assert_equal(dct, dict()) | |||
|
267 | ||||
|
268 | def test_popkey_2(): | |||
|
269 | """test_popkey_2, Test to see that popkey of non occuring keys | |||
|
270 | generates a KeyError exception | |||
|
271 | """ | |||
|
272 | dct = dict(a=1, b=2, c=3) | |||
|
273 | nt.assert_raises(KeyError, genutils.popkey, dct, "d") | |||
|
274 | ||||
|
275 | def test_popkey_3(): | |||
|
276 | """test_popkey_3, Tests to see that popkey calls returns the correct value | |||
|
277 | and that the key/value was removed from the dict. | |||
|
278 | """ | |||
|
279 | dct = dict(a=1, b=2, c=3) | |||
|
280 | nt.assert_equal(genutils.popkey(dct, "A", 13), 13) | |||
|
281 | nt.assert_equal(dct, dict(a=1, b=2, c=3)) | |||
|
282 | nt.assert_equal(genutils.popkey(dct, "B", 14), 14) | |||
|
283 | nt.assert_equal(dct, dict(a=1, b=2, c=3)) | |||
|
284 | nt.assert_equal(genutils.popkey(dct, "C", 15), 15) | |||
|
285 | nt.assert_equal(dct, dict(a=1, b=2, c=3)) | |||
|
286 | nt.assert_equal(genutils.popkey(dct, "a"), 1) | |||
|
287 | nt.assert_equal(dct, dict(b=2, c=3)) | |||
|
288 | nt.assert_equal(genutils.popkey(dct, "b"), 2) | |||
|
289 | nt.assert_equal(dct, dict(c=3)) | |||
|
290 | nt.assert_equal(genutils.popkey(dct, "c"), 3) | |||
|
291 | nt.assert_equal(dct, dict()) |
@@ -1,8 +1,21 b'' | |||||
1 |
""" |
|
1 | """Tests for various magic functions. | |
2 |
|
||||
3 | Needs to be run by nose (to make ipython session available) |
|
|||
4 |
|
2 | |||
|
3 | Needs to be run by nose (to make ipython session available). | |||
5 | """ |
|
4 | """ | |
|
5 | ||||
|
6 | # Standard library imports | |||
|
7 | import os | |||
|
8 | import sys | |||
|
9 | ||||
|
10 | # Third-party imports | |||
|
11 | import nose.tools as nt | |||
|
12 | ||||
|
13 | # From our own code | |||
|
14 | from IPython.testing import decorators as dec | |||
|
15 | ||||
|
16 | #----------------------------------------------------------------------------- | |||
|
17 | # Test functions begin | |||
|
18 | ||||
6 | def test_rehashx(): |
|
19 | def test_rehashx(): | |
7 | # clear up everything |
|
20 | # clear up everything | |
8 | _ip.IP.alias_table.clear() |
|
21 | _ip.IP.alias_table.clear() | |
@@ -19,3 +32,104 b' def test_rehashx():' | |||||
19 | # rehashx must fill up syscmdlist |
|
32 | # rehashx must fill up syscmdlist | |
20 | scoms = _ip.db['syscmdlist'] |
|
33 | scoms = _ip.db['syscmdlist'] | |
21 | assert len(scoms) > 10 |
|
34 | assert len(scoms) > 10 | |
|
35 | ||||
|
36 | ||||
|
37 | def doctest_run_ns(): | |||
|
38 | """Classes declared %run scripts must be instantiable afterwards. | |||
|
39 | ||||
|
40 | In [11]: run tclass | |||
|
41 | ||||
|
42 | In [12]: isinstance(f(),foo) | |||
|
43 | Out[12]: True | |||
|
44 | """ | |||
|
45 | ||||
|
46 | ||||
|
47 | def doctest_run_ns2(): | |||
|
48 | """Classes declared %run scripts must be instantiable afterwards. | |||
|
49 | ||||
|
50 | In [3]: run tclass.py | |||
|
51 | ||||
|
52 | In [4]: run tclass first_pass | |||
|
53 | ||||
|
54 | In [5]: run tclass second_pass | |||
|
55 | Deleting object: first_pass | |||
|
56 | """ | |||
|
57 | ||||
|
58 | ||||
|
59 | def doctest_hist_f(): | |||
|
60 | """Test %hist -f with temporary filename. | |||
|
61 | ||||
|
62 | In [9]: import tempfile | |||
|
63 | ||||
|
64 | In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-') | |||
|
65 | ||||
|
66 | In [11]: %history -n -f $tfile 3 | |||
|
67 | """ | |||
|
68 | ||||
|
69 | ||||
|
70 | def doctest_hist_r(): | |||
|
71 | """Test %hist -r | |||
|
72 | ||||
|
73 | XXX - This test is not recording the output correctly. Not sure why... | |||
|
74 | ||||
|
75 | In [6]: x=1 | |||
|
76 | ||||
|
77 | In [7]: hist -n -r 2 | |||
|
78 | x=1 # random | |||
|
79 | hist -n -r 2 # random | |||
|
80 | """ | |||
|
81 | ||||
|
82 | ||||
|
83 | def test_obj_del(): | |||
|
84 | """Test that object's __del__ methods are called on exit.""" | |||
|
85 | test_dir = os.path.dirname(__file__) | |||
|
86 | del_file = os.path.join(test_dir,'obj_del.py') | |||
|
87 | out = _ip.IP.getoutput('ipython %s' % del_file) | |||
|
88 | nt.assert_equals(out,'object A deleted') | |||
|
89 | ||||
|
90 | ||||
|
91 | def test_shist(): | |||
|
92 | # Simple tests of ShadowHist class - test generator. | |||
|
93 | import os, shutil, tempfile | |||
|
94 | ||||
|
95 | from IPython.Extensions import pickleshare | |||
|
96 | from IPython.history import ShadowHist | |||
|
97 | ||||
|
98 | tfile = tempfile.mktemp('','tmp-ipython-') | |||
|
99 | ||||
|
100 | db = pickleshare.PickleShareDB(tfile) | |||
|
101 | s = ShadowHist(db) | |||
|
102 | s.add('hello') | |||
|
103 | s.add('world') | |||
|
104 | s.add('hello') | |||
|
105 | s.add('hello') | |||
|
106 | s.add('karhu') | |||
|
107 | ||||
|
108 | yield nt.assert_equals,s.all(),[(1, 'hello'), (2, 'world'), (3, 'karhu')] | |||
|
109 | ||||
|
110 | yield nt.assert_equal,s.get(2),'world' | |||
|
111 | ||||
|
112 | shutil.rmtree(tfile) | |||
|
113 | ||||
|
114 | @dec.skipif_not_numpy | |||
|
115 | def test_numpy_clear_array_undec(): | |||
|
116 | _ip.ex('import numpy as np') | |||
|
117 | _ip.ex('a = np.empty(2)') | |||
|
118 | ||||
|
119 | yield nt.assert_true,'a' in _ip.user_ns | |||
|
120 | _ip.magic('clear array') | |||
|
121 | yield nt.assert_false,'a' in _ip.user_ns | |||
|
122 | ||||
|
123 | ||||
|
124 | @dec.skip() | |||
|
125 | def test_fail_dec(*a,**k): | |||
|
126 | yield nt.assert_true, False | |||
|
127 | ||||
|
128 | @dec.skip('This one shouldn not run') | |||
|
129 | def test_fail_dec2(*a,**k): | |||
|
130 | yield nt.assert_true, False | |||
|
131 | ||||
|
132 | @dec.skipknownfailure | |||
|
133 | def test_fail_dec3(*a,**k): | |||
|
134 | yield nt.assert_true, False | |||
|
135 |
@@ -1,3 +1,7 b'' | |||||
|
1 | """Twisted shell support. | |||
|
2 | ||||
|
3 | XXX - This module is missing proper docs. | |||
|
4 | """ | |||
1 | import sys |
|
5 | import sys | |
2 |
|
6 | |||
3 | from twisted.internet import reactor, threads |
|
7 | from twisted.internet import reactor, threads |
@@ -59,8 +59,7 b' ColorSchemeTable class. Currently the following exist:' | |||||
59 | You can implement other color schemes easily, the syntax is fairly |
|
59 | You can implement other color schemes easily, the syntax is fairly | |
60 | self-explanatory. Please send back new schemes you develop to the author for |
|
60 | self-explanatory. Please send back new schemes you develop to the author for | |
61 | possible inclusion in future releases. |
|
61 | possible inclusion in future releases. | |
62 |
|
62 | """ | ||
63 | $Id: ultraTB.py 2908 2007-12-30 21:07:46Z vivainio $""" |
|
|||
64 |
|
63 | |||
65 | #***************************************************************************** |
|
64 | #***************************************************************************** | |
66 | # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu> |
|
65 | # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu> | |
@@ -70,11 +69,6 b' $Id: ultraTB.py 2908 2007-12-30 21:07:46Z vivainio $"""' | |||||
70 | # the file COPYING, distributed as part of this software. |
|
69 | # the file COPYING, distributed as part of this software. | |
71 | #***************************************************************************** |
|
70 | #***************************************************************************** | |
72 |
|
71 | |||
73 | from IPython import Release |
|
|||
74 | __author__ = '%s <%s>\n%s <%s>' % (Release.authors['Nathan']+ |
|
|||
75 | Release.authors['Fernando']) |
|
|||
76 | __license__ = Release.license |
|
|||
77 |
|
||||
78 | # Required modules |
|
72 | # Required modules | |
79 | import inspect |
|
73 | import inspect | |
80 | import keyword |
|
74 | import keyword | |
@@ -98,7 +92,7 b' from inspect import getsourcefile, getfile, getmodule,\\' | |||||
98 | # Modified pdb which doesn't damage IPython's readline handling |
|
92 | # Modified pdb which doesn't damage IPython's readline handling | |
99 | from IPython import Debugger, PyColorize |
|
93 | from IPython import Debugger, PyColorize | |
100 | from IPython.ipstruct import Struct |
|
94 | from IPython.ipstruct import Struct | |
101 |
from IPython.excolors import |
|
95 | from IPython.excolors import exception_colors | |
102 | from IPython.genutils import Term,uniq_stable,error,info |
|
96 | from IPython.genutils import Term,uniq_stable,error,info | |
103 |
|
97 | |||
104 | # Globals |
|
98 | # Globals | |
@@ -320,7 +314,7 b' class TBTools:' | |||||
320 | self.call_pdb = call_pdb |
|
314 | self.call_pdb = call_pdb | |
321 |
|
315 | |||
322 | # Create color table |
|
316 | # Create color table | |
323 |
self.color_scheme_table = |
|
317 | self.color_scheme_table = exception_colors() | |
324 |
|
318 | |||
325 | self.set_colors(color_scheme) |
|
319 | self.set_colors(color_scheme) | |
326 | self.old_scheme = color_scheme # save initial value for toggles |
|
320 | self.old_scheme = color_scheme # save initial value for toggles |
@@ -6,13 +6,6 b'' | |||||
6 | # the file COPYING, distributed as part of this software. |
|
6 | # the file COPYING, distributed as part of this software. | |
7 | #***************************************************************************** |
|
7 | #***************************************************************************** | |
8 |
|
8 | |||
9 | # $Id: usage.py 2723 2007-09-07 07:44:16Z fperez $ |
|
|||
10 |
|
||||
11 | from IPython import Release |
|
|||
12 | __author__ = '%s <%s>' % Release.authors['Fernando'] |
|
|||
13 | __license__ = Release.license |
|
|||
14 | __version__ = Release.version |
|
|||
15 |
|
||||
16 | __doc__ = """ |
|
9 | __doc__ = """ | |
17 | IPython -- An enhanced Interactive Python |
|
10 | IPython -- An enhanced Interactive Python | |
18 | ========================================= |
|
11 | ========================================= | |
@@ -650,5 +643,3 b' or python names.' | |||||
650 | The following magic functions are currently available: |
|
643 | The following magic functions are currently available: | |
651 |
|
644 | |||
652 | """ |
|
645 | """ | |
653 |
|
||||
654 |
|
@@ -1,7 +1,9 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """Support for wildcard pattern matching in object inspection. |
|
2 | """Support for wildcard pattern matching in object inspection. | |
3 |
|
3 | |||
4 | $Id: OInspect.py 608 2005-07-06 17:52:32Z fperez $ |
|
4 | Authors | |
|
5 | ------- | |||
|
6 | - Jörgen Stenarson <jorgen.stenarson@bostream.nu> | |||
5 | """ |
|
7 | """ | |
6 |
|
8 | |||
7 | #***************************************************************************** |
|
9 | #***************************************************************************** | |
@@ -11,10 +13,6 b' $Id: OInspect.py 608 2005-07-06 17:52:32Z fperez $' | |||||
11 | # the file COPYING, distributed as part of this software. |
|
13 | # the file COPYING, distributed as part of this software. | |
12 | #***************************************************************************** |
|
14 | #***************************************************************************** | |
13 |
|
15 | |||
14 | from IPython import Release |
|
|||
15 | __author__ = "Jörgen Stenarson <jorgen.stenarson@bostream.nu>" |
|
|||
16 | __license__ = Release.license |
|
|||
17 |
|
||||
18 | import __builtin__ |
|
16 | import __builtin__ | |
19 | import exceptions |
|
17 | import exceptions | |
20 | import pdb |
|
18 | import pdb |
@@ -5,13 +5,14 b'' | |||||
5 | SPHINXOPTS = |
|
5 | SPHINXOPTS = | |
6 | SPHINXBUILD = sphinx-build |
|
6 | SPHINXBUILD = sphinx-build | |
7 | PAPER = |
|
7 | PAPER = | |
|
8 | SRCDIR = source | |||
8 |
|
9 | |||
9 | # Internal variables. |
|
10 | # Internal variables. | |
10 | PAPEROPT_a4 = -D latex_paper_size=a4 |
|
11 | PAPEROPT_a4 = -D latex_paper_size=a4 | |
11 | PAPEROPT_letter = -D latex_paper_size=letter |
|
12 | PAPEROPT_letter = -D latex_paper_size=letter | |
12 |
ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) |
|
13 | ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SRCDIR) | |
13 |
|
14 | |||
14 | .PHONY: help clean html web pickle htmlhelp latex changes linkcheck |
|
15 | .PHONY: help clean html web pickle htmlhelp latex changes linkcheck api | |
15 |
|
16 | |||
16 | help: |
|
17 | help: | |
17 | @echo "Please use \`make <target>' where <target> is one of" |
|
18 | @echo "Please use \`make <target>' where <target> is one of" | |
@@ -28,7 +29,7 b' help:' | |||||
28 | @echo "dist all, and then puts the results in dist/" |
|
29 | @echo "dist all, and then puts the results in dist/" | |
29 |
|
30 | |||
30 | clean: |
|
31 | clean: | |
31 | -rm -rf build/* dist/* |
|
32 | -rm -rf build/* dist/* $(SRCDIR)/api/generated | |
32 |
|
33 | |||
33 | pdf: latex |
|
34 | pdf: latex | |
34 | cd build/latex && make all-pdf |
|
35 | cd build/latex && make all-pdf | |
@@ -41,12 +42,16 b' dist: clean all' | |||||
41 | cp -al build/html dist/ |
|
42 | cp -al build/html dist/ | |
42 | @echo "Build finished. Final docs are in dist/" |
|
43 | @echo "Build finished. Final docs are in dist/" | |
43 |
|
44 | |||
44 | html: |
|
45 | html: api | |
45 | mkdir -p build/html build/doctrees |
|
46 | mkdir -p build/html build/doctrees | |
46 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html |
|
47 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html | |
47 | @echo |
|
48 | @echo | |
48 | @echo "Build finished. The HTML pages are in build/html." |
|
49 | @echo "Build finished. The HTML pages are in build/html." | |
49 |
|
50 | |||
|
51 | api: | |||
|
52 | python autogen_api.py | |||
|
53 | @echo "Build API docs finished." | |||
|
54 | ||||
50 | pickle: |
|
55 | pickle: | |
51 | mkdir -p build/pickle build/doctrees |
|
56 | mkdir -p build/pickle build/doctrees | |
52 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle |
|
57 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle |
@@ -27,6 +27,9 b' Release dev' | |||||
27 | New features |
|
27 | New features | |
28 | ------------ |
|
28 | ------------ | |
29 |
|
29 | |||
|
30 | * The new ipcluster now has a fully working ssh mode that should work on | |||
|
31 | Linux, Unix and OS X. Thanks to Vishal Vatsa for implementing this! | |||
|
32 | ||||
30 | * The wonderful TextMate editor can now be used with %edit on OS X. Thanks |
|
33 | * The wonderful TextMate editor can now be used with %edit on OS X. Thanks | |
31 | to Matt Foster for this patch. |
|
34 | to Matt Foster for this patch. | |
32 |
|
35 | |||
@@ -59,6 +62,8 b' New features' | |||||
59 | Bug fixes |
|
62 | Bug fixes | |
60 | --------- |
|
63 | --------- | |
61 |
|
64 | |||
|
65 | * Numerous bugs on Windows with the new ipcluster have been fixed. | |||
|
66 | ||||
62 | * The ipengine and ipcontroller scripts now handle missing furl files |
|
67 | * The ipengine and ipcontroller scripts now handle missing furl files | |
63 | more gracefully by giving better error messages. |
|
68 | more gracefully by giving better error messages. | |
64 |
|
69 |
@@ -36,9 +36,13 b" execfile('../../IPython/Release.py',iprelease)" | |||||
36 | # Add any Sphinx extension module names here, as strings. They can be extensions |
|
36 | # Add any Sphinx extension module names here, as strings. They can be extensions | |
37 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. |
|
37 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. | |
38 | extensions = ['sphinx.ext.autodoc', |
|
38 | extensions = ['sphinx.ext.autodoc', | |
39 | 'inheritance_diagram', 'only_directives', |
|
39 | 'sphinx.ext.doctest', | |
|
40 | ||||
|
41 | 'only_directives', | |||
|
42 | 'inheritance_diagram', | |||
40 | 'ipython_console_highlighting', |
|
43 | 'ipython_console_highlighting', | |
41 | # 'plot_directive', # disabled for now, needs matplotlib |
|
44 | # 'plot_directive', # disabled for now, needs matplotlib | |
|
45 | 'numpydoc', # to preprocess docstrings | |||
42 | ] |
|
46 | ] | |
43 |
|
47 | |||
44 | # Add any paths that contain templates here, relative to this directory. |
|
48 | # Add any paths that contain templates here, relative to this directory. |
@@ -1,11 +1,14 b'' | |||||
1 | ================== |
|
1 | =========================== | |
2 | Development |
|
2 | IPython Developer's Guide | |
3 | ================== |
|
3 | =========================== | |
4 |
|
4 | |||
5 | .. toctree:: |
|
5 | .. toctree:: | |
6 | :maxdepth: 2 |
|
6 | :maxdepth: 2 | |
7 |
|
7 | |||
8 |
|
|
8 | overview.txt | |
|
9 | coding_guide.txt | |||
|
10 | doc_guide.txt | |||
9 | roadmap.txt |
|
11 | roadmap.txt | |
|
12 | ||||
10 | notification_blueprint.txt |
|
13 | notification_blueprint.txt | |
11 | config_blueprint.txt |
|
14 | config_blueprint.txt |
@@ -17,7 +17,29 b' How to contribute to IPython' | |||||
17 |
|
17 | |||
18 | IPython development is done using Bazaar [Bazaar]_ and Launchpad [Launchpad]_. |
|
18 | IPython development is done using Bazaar [Bazaar]_ and Launchpad [Launchpad]_. | |
19 | This makes it easy for people to contribute to the development of IPython. |
|
19 | This makes it easy for people to contribute to the development of IPython. | |
20 | Here is a sketch of how to get going. |
|
20 | There are several ways in which you can join in. | |
|
21 | ||||
|
22 | If you have a small change that you want to send to the team, you can edit your | |||
|
23 | bazaar checkout of IPython (see below) in-place, and ask bazaar for the | |||
|
24 | differences:: | |||
|
25 | ||||
|
26 | $ cd /path/to/your/copy/of/ipython | |||
|
27 | $ bzr diff > my_fixes.diff | |||
|
28 | ||||
|
29 | This produces a patch file with your fixes, which we can apply to the source | |||
|
30 | tree. This file should then be attached to a ticket in our `bug tracker | |||
|
31 | <https://bugs.launchpad.net/ipython>`_, indicating what it does. | |||
|
32 | ||||
|
33 | This model of creating small, self-contained patches works very well and there | |||
|
34 | are open source projects that do their entire development this way. However, | |||
|
35 | in IPython we have found that for tracking larger changes, making use of | |||
|
36 | bazaar's full capabilities in conjunction with Launchpad's code hosting | |||
|
37 | services makes for a much better experience. | |||
|
38 | ||||
|
39 | Making your own branch of IPython allows you to refine your changes over time, | |||
|
40 | track the development of the main team, and propose your own full version of | |||
|
41 | the code for others to use and review, with a minimum amount of fuss. The next | |||
|
42 | parts of this document will explain how to do this. | |||
21 |
|
43 | |||
22 | Install Bazaar and create a Launchpad account |
|
44 | Install Bazaar and create a Launchpad account | |
23 | --------------------------------------------- |
|
45 | --------------------------------------------- | |
@@ -102,12 +124,16 b' commands::' | |||||
102 | $ bzr merge ../ipython |
|
124 | $ bzr merge ../ipython | |
103 | $ bzr commit -m "Merging changes from trunk" |
|
125 | $ bzr commit -m "Merging changes from trunk" | |
104 |
|
126 | |||
105 |
Along the way, you should also run the IPython test suite. You can do this |
|
127 | Along the way, you should also run the IPython test suite. You can do this | |
|
128 | using the :command:`iptest` command (which is basically a customized version of | |||
|
129 | :command:`nosetests`):: | |||
106 |
|
130 | |||
107 | $ cd |
|
131 | $ cd | |
108 | $ iptest |
|
132 | $ iptest | |
109 |
|
133 | |||
110 |
The :command:`iptest` command will also pick up and run any tests you have |
|
134 | The :command:`iptest` command will also pick up and run any tests you have | |
|
135 | written. See :ref:`_devel_testing` for further details on the testing system. | |||
|
136 | ||||
111 |
|
137 | |||
112 | Post your branch and request a code review |
|
138 | Post your branch and request a code review | |
113 | ------------------------------------------ |
|
139 | ------------------------------------------ | |
@@ -151,7 +177,8 b' source tree. The documentation in this location will serve as the main source' | |||||
151 | for IPython documentation and all existing documentation should be converted |
|
177 | for IPython documentation and all existing documentation should be converted | |
152 | to this format. |
|
178 | to this format. | |
153 |
|
179 | |||
154 |
To build the final documentation, we use Sphinx [Sphinx]_. Once you have |
|
180 | To build the final documentation, we use Sphinx [Sphinx]_. Once you have | |
|
181 | Sphinx installed, you can build the html docs yourself by doing:: | |||
155 |
|
182 | |||
156 | $ cd ipython-mybranch/docs |
|
183 | $ cd ipython-mybranch/docs | |
157 | $ make html |
|
184 | $ make html | |
@@ -198,7 +225,8 b' Naming conventions' | |||||
198 | In terms of naming conventions, we'll follow the guidelines from the `Style |
|
225 | In terms of naming conventions, we'll follow the guidelines from the `Style | |
199 | Guide for Python Code`_. |
|
226 | Guide for Python Code`_. | |
200 |
|
227 | |||
201 |
For all new IPython code (and much existing code is being refactored), we'll |
|
228 | For all new IPython code (and much existing code is being refactored), we'll | |
|
229 | use: | |||
202 |
|
230 | |||
203 | * All ``lowercase`` module names. |
|
231 | * All ``lowercase`` module names. | |
204 |
|
232 | |||
@@ -270,17 +298,119 b' twisted reactor will be handled correctly.' | |||||
270 |
|
298 | |||
271 | Each subpackage in IPython should have its own :file:`tests` directory that |
|
299 | Each subpackage in IPython should have its own :file:`tests` directory that | |
272 | contains all of the tests for that subpackage. This allows each subpackage to |
|
300 | contains all of the tests for that subpackage. This allows each subpackage to | |
273 | be self-contained. If a subpackage has any dependencies beyond the Python |
|
301 | be self-contained. A good convention to follow is to have a file named | |
274 | standard library, the tests for that subpackage should be skipped if the |
|
302 | :file:`test_foo.py` for each module :file:`foo.py` in the package. This makes | |
275 | dependencies are not found. This is very important so users don't get tests |
|
303 | it easy to organize the tests, though like most conventions, it's OK to break | |
276 | failing simply because they don't have dependencies. |
|
304 | it if logic and common sense dictate otherwise. | |
277 |
|
305 | |||
278 | To run the IPython test suite, use the :command:`iptest` command that is installed with IPython:: |
|
306 | If a subpackage has any dependencies beyond the Python standard library, the | |
|
307 | tests for that subpackage should be skipped if the dependencies are not | |||
|
308 | found. This is very important so users don't get tests failing simply because | |||
|
309 | they don't have dependencies. We ship a set of decorators in the | |||
|
310 | :mod:`IPython.testing` package to tag tests that may be platform-specific or | |||
|
311 | otherwise may have restrictions; if the existing ones don't fit your needs, add | |||
|
312 | a new decorator in that location so other tests can reuse it. | |||
|
313 | ||||
|
314 | To run the IPython test suite, use the :command:`iptest` command that is | |||
|
315 | installed with IPython (if you are using IPython in-place, without installing | |||
|
316 | it, you can find this script in the :file:`scripts` directory):: | |||
279 |
|
317 | |||
280 | $ iptest |
|
318 | $ iptest | |
281 |
|
319 | |||
282 | This command runs Nose with the proper options and extensions. |
|
320 | This command runs Nose with the proper options and extensions. By default, | |
283 |
|
321 | :command:`iptest` runs the entire IPython test suite (skipping tests that may | ||
|
322 | be platform-specific or which depend on tools you may not have). But you can | |||
|
323 | also use it to run only one specific test file, or a specific test function. | |||
|
324 | For example, this will run only the :file:`test_magic` file from the test | |||
|
325 | suite:: | |||
|
326 | ||||
|
327 | $ iptest IPython.tests.test_magic | |||
|
328 | ---------------------------------------------------------------------- | |||
|
329 | Ran 10 tests in 0.348s | |||
|
330 | ||||
|
331 | OK (SKIP=3) | |||
|
332 | Deleting object: second_pass | |||
|
333 | ||||
|
334 | while the ``path:function`` syntax allows you to select a specific function in | |||
|
335 | that file to run:: | |||
|
336 | ||||
|
337 | $ iptest IPython.tests.test_magic:test_obj_del | |||
|
338 | ---------------------------------------------------------------------- | |||
|
339 | Ran 1 test in 0.204s | |||
|
340 | ||||
|
341 | OK | |||
|
342 | ||||
|
343 | Since :command:`iptest` is based on nosetests, you can pass it any regular | |||
|
344 | nosetests option. For example, you can use ``--pdb`` or ``--pdb-failures`` to | |||
|
345 | automatically activate the interactive Pdb debugger on errors or failures. See | |||
|
346 | the nosetests documentation for further details. | |||
|
347 | ||||
|
348 | A few tips for writing tests | |||
|
349 | ---------------------------- | |||
|
350 | ||||
|
351 | You can write tests either as normal test files, using all the conventions that | |||
|
352 | Nose recognizes, or as doctests. Note that *all* IPython functions should have | |||
|
353 | at least one example that serves as a doctest, whenever technically feasible. | |||
|
354 | However, example doctests should only be in the main docstring if they are *a | |||
|
355 | good example*, i.e. if they convey useful information about the function. If | |||
|
356 | you simply would like to write a test as a doctest, put it in a separate test | |||
|
357 | file and write a no-op function whose only purpose is its docstring. | |||
|
358 | ||||
|
359 | Note, however, that in a file named :file:`test_X`, functions whose only test | |||
|
360 | is their docstring (as a doctest) and which have no test functionality of their | |||
|
361 | own, should be called *doctest_foo* instead of *test_foo*, otherwise they get | |||
|
362 | double-counted (the empty function call is counted as a test, which just | |||
|
363 | inflates tests numbers artificially). This restriction does not apply to | |||
|
364 | functions in files with other names, due to how Nose discovers tests. | |||
|
365 | ||||
|
366 | You can use IPython examples in your docstrings. Those can make full use of | |||
|
367 | IPython functionality (magics, variable substitution, etc), but be careful to | |||
|
368 | keep them generic enough that they run identically on all Operating Systems. | |||
|
369 | ||||
|
370 | The prompts in your doctests can be either of the plain Python ``>>>`` variety | |||
|
371 | or ``In [1]:`` IPython style. Since this is the IPython system, after all, we | |||
|
372 | encourage you to use IPython prompts throughout, unless you are illustrating a | |||
|
373 | specific aspect of the normal prompts (such as the ``%doctest_mode`` magic). | |||
|
374 | ||||
|
375 | If a test isn't safe to run inside the main nose process (e.g. because it loads | |||
|
376 | a GUI toolkit), consider running it in a subprocess and capturing its output | |||
|
377 | for evaluation and test decision later. Here is an example of how to do it, by | |||
|
378 | relying on the builtin ``_ip`` object that contains the public IPython api as | |||
|
379 | defined in :mod:`IPython.ipapi`:: | |||
|
380 | ||||
|
381 | def test_obj_del(): | |||
|
382 | """Test that object's __del__ methods are called on exit.""" | |||
|
383 | test_dir = os.path.dirname(__file__) | |||
|
384 | del_file = os.path.join(test_dir,'obj_del.py') | |||
|
385 | out = _ip.IP.getoutput('ipython %s' % del_file) | |||
|
386 | nt.assert_equals(out,'object A deleted') | |||
|
387 | ||||
|
388 | ||||
|
389 | ||||
|
390 | If a doctest contains input whose output you don't want to verify identically | |||
|
391 | via doctest (random output, an object id, etc), you can mark a docstring with | |||
|
392 | ``#random``. All of these test will have their code executed but no output | |||
|
393 | checking will be done:: | |||
|
394 | ||||
|
395 | >>> 1+3 | |||
|
396 | junk goes here... # random | |||
|
397 | ||||
|
398 | >>> 1+2 | |||
|
399 | again, anything goes #random | |||
|
400 | if multiline, the random mark is only needed once. | |||
|
401 | ||||
|
402 | >>> 1+2 | |||
|
403 | You can also put the random marker at the end: | |||
|
404 | # random | |||
|
405 | ||||
|
406 | >>> 1+2 | |||
|
407 | # random | |||
|
408 | .. or at the beginning. | |||
|
409 | ||||
|
410 | In a case where you want an *entire* docstring to be executed but not verified | |||
|
411 | (this only serves to check that the code runs without crashing, so it should be | |||
|
412 | used very sparingly), you can put ``# all-random`` in the docstring. | |||
|
413 | ||||
284 | .. _devel_config: |
|
414 | .. _devel_config: | |
285 |
|
415 | |||
286 | Release checklist |
|
416 | Release checklist | |
@@ -303,6 +433,20 b' Most of the release process is automated by the :file:`release` script in the' | |||||
303 |
|
433 | |||
304 | #. Celebrate! |
|
434 | #. Celebrate! | |
305 |
|
435 | |||
|
436 | Porting to 3.0 | |||
|
437 | ============== | |||
|
438 | ||||
|
439 | There are no definite plans for porting of IPython to python 3. The major | |||
|
440 | issue is the dependency on twisted framework for the networking/threading | |||
|
441 | stuff. It is possible that it the traditional IPython interactive console | |||
|
442 | could be ported more easily since it has no such dependency. Here are a few | |||
|
443 | things that will need to be considered when doing such a port especially | |||
|
444 | if we want to have a codebase that works directly on both 2.x and 3.x. | |||
|
445 | ||||
|
446 | 1. The syntax for exceptions changed (PEP 3110). The old | |||
|
447 | `except exc, var` changed to `except exc as var`. At last | |||
|
448 | count there was 78 occurences of this usage in the codebase | |||
|
449 | ||||
306 | .. [Bazaar] Bazaar. http://bazaar-vcs.org/ |
|
450 | .. [Bazaar] Bazaar. http://bazaar-vcs.org/ | |
307 | .. [Launchpad] Launchpad. http://www.launchpad.net/ipython |
|
451 | .. [Launchpad] Launchpad. http://www.launchpad.net/ipython | |
308 | .. [reStructuredText] reStructuredText. http://docutils.sourceforge.net/rst.html |
|
452 | .. [reStructuredText] reStructuredText. http://docutils.sourceforge.net/rst.html |
@@ -17,10 +17,11 b' IPython Documentation' | |||||
17 | interactive/index.txt |
|
17 | interactive/index.txt | |
18 | parallel/index.txt |
|
18 | parallel/index.txt | |
19 | config/index.txt |
|
19 | config/index.txt | |
20 | changes.txt |
|
|||
21 | development/index.txt |
|
|||
22 | faq.txt |
|
20 | faq.txt | |
23 | history.txt |
|
21 | history.txt | |
|
22 | changes.txt | |||
|
23 | development/index.txt | |||
|
24 | api/index.txt | |||
24 | license_and_copyright.txt |
|
25 | license_and_copyright.txt | |
25 | credits.txt |
|
26 | credits.txt | |
26 |
|
27 |
@@ -1,8 +1,8 b'' | |||||
1 | .. _install_index: |
|
1 | .. _install_index: | |
2 |
|
2 | |||
3 |
============ |
|
3 | ============ | |
4 | Installation |
|
4 | Installation | |
5 |
============ |
|
5 | ============ | |
6 |
|
6 | |||
7 | .. toctree:: |
|
7 | .. toctree:: | |
8 | :maxdepth: 2 |
|
8 | :maxdepth: 2 |
@@ -1,29 +1,45 b'' | |||||
1 | Overview |
|
1 | Overview | |
2 | ======== |
|
2 | ======== | |
3 |
|
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. |
|
4 | This document describes the steps required to install IPython. IPython is | |
|
5 | organized into a number of subpackages, each of which has its own dependencies. | |||
|
6 | All of the subpackages come with IPython, so you don't need to download and | |||
|
7 | install them separately. However, to use a given subpackage, you will need to | |||
|
8 | install all of its dependencies. | |||
5 |
|
9 | |||
6 |
|
10 | |||
7 | Please let us know if you have problems installing IPython or any of its |
|
11 | Please let us know if you have problems installing IPython or any of its | |
8 |
dependencies. IPython requires Python version 2.4 or greater. |
|
12 | dependencies. IPython requires Python version 2.4 or greater. Light testing | |
9 | IPython with the upcoming 2.6 or 3.0 versions. |
|
13 | has been done on version 2.6, and so far everything looks fine. We have *not* | |
|
14 | yet started to port IPython to Python 3.0, where the language changes are much | |||
|
15 | more significant. | |||
10 |
|
16 | |||
11 | .. warning:: |
|
17 | .. warning:: | |
12 |
|
18 | |||
13 |
IPython will not work with Python 2. |
|
19 | IPython will not work with Python 2.4 or below. | |
14 |
|
20 | |||
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. |
|
21 | Some of the installation approaches use the :mod:`setuptools` package and its | |
|
22 | :command:`easy_install` command line program. In many scenarios, this provides | |||
|
23 | the most simple method of installing IPython and its dependencies. It is not | |||
|
24 | required though. More information about :mod:`setuptools` can be found on its | |||
|
25 | website. | |||
16 |
|
26 | |||
17 |
More general information about installing Python packages can be found in |
|
27 | More general information about installing Python packages can be found in | |
|
28 | Python's documentation at http://www.python.org/doc/. | |||
18 |
|
29 | |||
19 | Quickstart |
|
30 | Quickstart | |
20 | ========== |
|
31 | ========== | |
21 |
|
32 | |||
22 |
If you have :mod:`setuptools` installed and you are on OS X or Linux (not |
|
33 | If you have :mod:`setuptools` installed and you are on OS X or Linux (not | |
|
34 | Windows), the following will download and install IPython *and* the main | |||
|
35 | optional dependencies:: | |||
23 |
|
36 | |||
24 | $ easy_install ipython[kernel,security,test] |
|
37 | $ easy_install ipython[kernel,security,test] | |
25 |
|
38 | |||
26 | This will get Twisted, zope.interface and Foolscap, which are needed for IPython's parallel computing features as well as the nose package, which will enable you to run IPython's test suite. To run IPython's test suite, use the :command:`iptest` command:: |
|
39 | This will get Twisted, zope.interface and Foolscap, which are needed for | |
|
40 | IPython's parallel computing features as well as the nose package, which will | |||
|
41 | enable you to run IPython's test suite. To run IPython's test suite, use the | |||
|
42 | :command:`iptest` command:: | |||
27 |
|
43 | |||
28 | $ iptest |
|
44 | $ iptest | |
29 |
|
45 | |||
@@ -32,12 +48,19 b' Read on for more specific details and instructions for Windows.' | |||||
32 | Installing IPython itself |
|
48 | Installing IPython itself | |
33 | ========================= |
|
49 | ========================= | |
34 |
|
50 | |||
35 | 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`. |
|
51 | Given a properly built Python, the basic interactive IPython shell will work | |
|
52 | with no external dependencies. However, some Python distributions | |||
|
53 | (particularly on Windows and OS X), don't come with a working :mod:`readline` | |||
|
54 | module. The IPython shell will work without :mod:`readline`, but will lack | |||
|
55 | many features that users depend on, such as tab completion and command line | |||
|
56 | editing. See below for details of how to make sure you have a working | |||
|
57 | :mod:`readline`. | |||
36 |
|
58 | |||
37 | Installation using easy_install |
|
59 | Installation using easy_install | |
38 | ------------------------------- |
|
60 | ------------------------------- | |
39 |
|
61 | |||
40 |
If you have :mod:`setuptools` installed, the easiest way of getting IPython is |
|
62 | If you have :mod:`setuptools` installed, the easiest way of getting IPython is | |
|
63 | to simple use :command:`easy_install`:: | |||
41 |
|
64 | |||
42 | $ easy_install ipython |
|
65 | $ easy_install ipython | |
43 |
|
66 | |||
@@ -46,68 +69,91 b" That's it." | |||||
46 | Installation from source |
|
69 | Installation from source | |
47 | ------------------------ |
|
70 | ------------------------ | |
48 |
|
71 | |||
49 | 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:: |
|
72 | If you don't want to use :command:`easy_install`, or don't have it installed, | |
|
73 | just grab the latest stable build of IPython from `here | |||
|
74 | <http://ipython.scipy.org/dist/>`_. Then do the following:: | |||
50 |
|
75 | |||
51 | $ tar -xzf ipython.tar.gz |
|
76 | $ tar -xzf ipython.tar.gz | |
52 | $ cd ipython |
|
77 | $ cd ipython | |
53 | $ python setup.py install |
|
78 | $ python setup.py install | |
54 |
|
79 | |||
55 |
If you are installing to a location (like ``/usr/local``) that requires higher |
|
80 | If you are installing to a location (like ``/usr/local``) that requires higher | |
|
81 | permissions, you may need to run the last command with :command:`sudo`. | |||
56 |
|
82 | |||
57 | Windows |
|
83 | Windows | |
58 | ------- |
|
84 | ------- | |
59 |
|
85 | |||
60 | 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: |
|
86 | There are a few caveats for Windows users. The main issue is that a basic | |
|
87 | ``python setup.py install`` approach won't create ``.bat`` file or Start Menu | |||
|
88 | shortcuts, which most users want. To get an installation with these, there are | |||
|
89 | two choices: | |||
61 |
|
90 | |||
62 |
1. |
|
91 | 1. Install using :command:`easy_install`. | |
63 |
|
92 | |||
64 |
2. |
|
93 | 2. Install using our binary ``.exe`` Windows installer, which can be found at | |
|
94 | `here <http://ipython.scipy.org/dist/>`_ | |||
65 |
|
95 | |||
66 |
3. |
|
96 | 3. Install from source, but using :mod:`setuptools` (``python setupegg.py | |
|
97 | install``). | |||
67 |
|
98 | |||
68 | Installing the development version |
|
99 | Installing the development version | |
69 | ---------------------------------- |
|
100 | ---------------------------------- | |
70 |
|
101 | |||
71 |
It is also possible to install the development version of IPython from our |
|
102 | It is also possible to install the development version of IPython from our | |
72 | repository. To do this you will need to have Bazaar installed on your system. Then just do:: |
|
103 | `Bazaar <http://bazaar-vcs.org/>`_ source code repository. To do this you will | |
|
104 | need to have Bazaar installed on your system. Then just do:: | |||
73 |
|
105 | |||
74 | $ bzr branch lp:ipython |
|
106 | $ bzr branch lp:ipython | |
75 | $ cd ipython |
|
107 | $ cd ipython | |
76 | $ python setup.py install |
|
108 | $ python setup.py install | |
77 |
|
109 | |||
78 |
Again, this last step on Windows won't create ``.bat`` files or Start Menu |
|
110 | Again, this last step on Windows won't create ``.bat`` files or Start Menu | |
|
111 | shortcuts, so you will have to use one of the other approaches listed above. | |||
79 |
|
112 | |||
80 |
Some users want to be able to follow the development branch as it changes. If |
|
113 | Some users want to be able to follow the development branch as it changes. If | |
|
114 | you have :mod:`setuptools` installed, this is easy. Simply replace the last | |||
|
115 | step by:: | |||
81 |
|
116 | |||
82 | $ python setupegg.py develop |
|
117 | $ python setupegg.py develop | |
83 |
|
118 | |||
84 |
This creates links in the right places and installs the command line script to |
|
119 | This creates links in the right places and installs the command line script to | |
|
120 | the appropriate places. Then, if you want to update your IPython at any time, | |||
|
121 | just do:: | |||
85 |
|
122 | |||
86 | $ bzr pull |
|
123 | $ bzr pull | |
87 |
|
124 | |||
88 | Basic optional dependencies |
|
125 | Basic optional dependencies | |
89 | =========================== |
|
126 | =========================== | |
90 |
|
127 | |||
91 |
There are a number of basic optional dependencies that most users will want to |
|
128 | There are a number of basic optional dependencies that most users will want to | |
|
129 | get. These are: | |||
92 |
|
130 | |||
93 | * readline (for command line editing, tab completion, etc.) |
|
131 | * readline (for command line editing, tab completion, etc.) | |
94 | * nose (to run the IPython test suite) |
|
132 | * nose (to run the IPython test suite) | |
95 | * pexpect (to use things like irunner) |
|
133 | * pexpect (to use things like irunner) | |
96 |
|
134 | |||
97 |
If you are comfortable installing these things yourself, have at it, otherwise |
|
135 | If you are comfortable installing these things yourself, have at it, otherwise | |
|
136 | read on for more details. | |||
98 |
|
137 | |||
99 | readline |
|
138 | readline | |
100 | -------- |
|
139 | -------- | |
101 |
|
140 | |||
102 | 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: |
|
141 | In principle, all Python distributions should come with a working | |
|
142 | :mod:`readline` module. But, reality is not quite that simple. There are two | |||
|
143 | common situations where you won't have a working :mod:`readline` module: | |||
103 |
|
144 | |||
104 | * If you are using the built-in Python on Mac OS X. |
|
145 | * If you are using the built-in Python on Mac OS X. | |
105 |
|
146 | |||
106 | * If you are running Windows, which doesn't have a :mod:`readline` module. |
|
147 | * If you are running Windows, which doesn't have a :mod:`readline` module. | |
107 |
|
148 | |||
108 | 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. |
|
149 | On OS X, the built-in Python doesn't not have :mod:`readline` because of | |
|
150 | license issues. Starting with OS X 10.5 (Leopard), Apple's built-in Python has | |||
|
151 | a BSD-licensed not-quite-compatible readline replacement. As of IPython 0.9, | |||
|
152 | many of the issues related to the differences between readline and libedit have | |||
|
153 | been resolved. For many users, libedit may be sufficient. | |||
109 |
|
154 | |||
110 |
Most users on OS X will want to get the full :mod:`readline` module. To get a |
|
155 | Most users on OS X will want to get the full :mod:`readline` module. To get a | |
|
156 | working :mod:`readline` module, just do (with :mod:`setuptools` installed):: | |||
111 |
|
157 | |||
112 | $ easy_install readline |
|
158 | $ easy_install readline | |
113 |
|
159 | |||
@@ -117,20 +163,22 b' Most users on OS X will want to get the full :mod:`readline` module. To get a w' | |||||
117 | official python.org binaries) already have readline installed so |
|
163 | official python.org binaries) already have readline installed so | |
118 | you don't have to do this step. |
|
164 | you don't have to do this step. | |
119 |
|
165 | |||
120 |
If needed, the readline egg can be build and installed from source (see the |
|
166 | If needed, the readline egg can be build and installed from source (see the | |
|
167 | wiki page at http://ipython.scipy.org/moin/InstallationOSXLeopard). | |||
121 |
|
168 | |||
122 | On Windows, you will need the PyReadline module. PyReadline is a separate, |
|
169 | On Windows, you will need the PyReadline module. PyReadline is a separate, | |
123 | Windows only implementation of readline that uses native Windows calls through |
|
170 | Windows only implementation of readline that uses native Windows calls through | |
124 | :mod:`ctypes`. The easiest way of installing PyReadline is you use the binary |
|
171 | :mod:`ctypes`. The easiest way of installing PyReadline is you use the binary | |
125 | installer available `here <http://ipython.scipy.org/dist/>`_. The |
|
172 | installer available `here <http://ipython.scipy.org/dist/>`_. The :mod:`ctypes` | |
126 |
|
|
173 | module, which comes with Python 2.5 and greater, is required by PyReadline. It | |
127 | PyReadline. It is available for Python 2.4 at |
|
174 | is available for Python 2.4 at http://python.net/crew/theller/ctypes. | |
128 | http://python.net/crew/theller/ctypes. |
|
|||
129 |
|
175 | |||
130 | nose |
|
176 | nose | |
131 | ---- |
|
177 | ---- | |
132 |
|
178 | |||
133 | 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`:: |
|
179 | To run the IPython test suite you will need the :mod:`nose` package. Nose | |
|
180 | provides a great way of sniffing out and running all of the IPython tests. The | |||
|
181 | simplest way of getting nose, is to use :command:`easy_install`:: | |||
134 |
|
182 | |||
135 | $ easy_install nose |
|
183 | $ easy_install nose | |
136 |
|
184 | |||
@@ -138,7 +186,9 b' Another way of getting this is to do::' | |||||
138 |
|
186 | |||
139 | $ easy_install ipython[test] |
|
187 | $ easy_install ipython[test] | |
140 |
|
188 | |||
141 | 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:: |
|
189 | For more installation options, see the `nose website | |
|
190 | <http://somethingaboutorange.com/mrl/projects/nose/>`_. Once you have nose | |||
|
191 | installed, you can run IPython's test suite using the iptest command:: | |||
142 |
|
192 | |||
143 | $ iptest |
|
193 | $ iptest | |
144 |
|
194 | |||
@@ -146,7 +196,8 b' For more installation options, see the `nose website <http://somethingaboutorang' | |||||
146 | pexpect |
|
196 | pexpect | |
147 | ------- |
|
197 | ------- | |
148 |
|
198 | |||
149 |
The `pexpect <http://www.noah.org/wiki/Pexpect>`_ package is used in IPython's |
|
199 | The `pexpect <http://www.noah.org/wiki/Pexpect>`_ package is used in IPython's | |
|
200 | :command:`irunner` script. On Unix platforms (including OS X), just do:: | |||
150 |
|
201 | |||
151 | $ easy_install pexpect |
|
202 | $ easy_install pexpect | |
152 |
|
203 | |||
@@ -155,7 +206,9 b' Windows users are out of luck as pexpect does not run there.' | |||||
155 | Dependencies for IPython.kernel (parallel computing) |
|
206 | Dependencies for IPython.kernel (parallel computing) | |
156 | ==================================================== |
|
207 | ==================================================== | |
157 |
|
208 | |||
158 | 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: |
|
209 | The IPython kernel provides a nice architecture for parallel computing. The | |
|
210 | main focus of this architecture is on interactive parallel computing. These | |||
|
211 | features require a number of additional packages: | |||
159 |
|
212 | |||
160 | * zope.interface (yep, we use interfaces) |
|
213 | * zope.interface (yep, we use interfaces) | |
161 | * Twisted (asynchronous networking framework) |
|
214 | * Twisted (asynchronous networking framework) | |
@@ -170,14 +223,17 b' On a Unix style platform (including OS X), if you want to use :mod:`setuptools`,' | |||||
170 | zope.interface and Twisted |
|
223 | zope.interface and Twisted | |
171 | -------------------------- |
|
224 | -------------------------- | |
172 |
|
225 | |||
173 |
Twisted [Twisted]_ and zope.interface [ZopeInterface]_ are used for networking |
|
226 | Twisted [Twisted]_ and zope.interface [ZopeInterface]_ are used for networking | |
174 |
style platforms (including OS X), the simplest way of |
|
227 | related things. On Unix style platforms (including OS X), the simplest way of | |
175 | use :command:`easy_install`:: |
|
228 | getting the these is to use :command:`easy_install`:: | |
176 |
|
229 | |||
177 | $ easy_install zope.interface |
|
230 | $ easy_install zope.interface | |
178 | $ easy_install Twisted |
|
231 | $ easy_install Twisted | |
179 |
|
232 | |||
180 | 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. |
|
233 | Of course, you can also download the source tarballs from the `Twisted website | |
|
234 | <twistedmatrix.org>`_ and the `zope.interface page at PyPI | |||
|
235 | <http://pypi.python.org/pypi/zope.interface>`_ and do the usual ``python | |||
|
236 | setup.py install`` if you prefer. | |||
181 |
|
237 | |||
182 | 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. |
|
238 | 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. | |
183 |
|
239 | |||
@@ -190,12 +246,15 b' On all platforms a simple::' | |||||
190 |
|
246 | |||
191 | $ easy_install foolscap |
|
247 | $ easy_install foolscap | |
192 |
|
248 | |||
193 |
should work. You can also download the source tarballs from the `Foolscap |
|
249 | should work. You can also download the source tarballs from the `Foolscap | |
|
250 | website <http://foolscap.lothar.com/trac>`_ and do ``python setup.py install`` | |||
|
251 | if you prefer. | |||
194 |
|
252 | |||
195 | pyOpenSSL |
|
253 | pyOpenSSL | |
196 | --------- |
|
254 | --------- | |
197 |
|
255 | |||
198 |
IPython requires an older version of pyOpenSSL [pyOpenSSL]_ (0.6 rather than |
|
256 | IPython requires an older version of pyOpenSSL [pyOpenSSL]_ (0.6 rather than | |
|
257 | the current 0.7). There are a couple of options for getting this: | |||
199 |
|
258 | |||
200 | 1. Most Linux distributions have packages for pyOpenSSL. |
|
259 | 1. Most Linux distributions have packages for pyOpenSSL. | |
201 | 2. The built-in Python 2.5 on OS X 10.5 already has it installed. |
|
260 | 2. The built-in Python 2.5 on OS X 10.5 already has it installed. | |
@@ -209,9 +268,14 b' Dependencies for IPython.frontend (the IPython GUI)' | |||||
209 | wxPython |
|
268 | wxPython | |
210 | -------- |
|
269 | -------- | |
211 |
|
270 | |||
212 | 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/>`_. |
|
271 | Starting with IPython 0.9, IPython has a new IPython.frontend package that has | |
|
272 | a nice wxPython based IPython GUI. As you would expect, this GUI requires | |||
|
273 | wxPython. Most Linux distributions have wxPython packages available and the | |||
|
274 | built-in Python on OS X comes with wxPython preinstalled. For Windows, a | |||
|
275 | binary installer is available on the `wxPython website | |||
|
276 | <http://www.wxpython.org/>`_. | |||
213 |
|
277 | |||
214 | .. [Twisted] Twisted matrix. http://twistedmatrix.org |
|
278 | .. [Twisted] Twisted matrix. http://twistedmatrix.org | |
215 | .. [ZopeInterface] http://pypi.python.org/pypi/zope.interface |
|
279 | .. [ZopeInterface] http://pypi.python.org/pypi/zope.interface | |
216 | .. [Foolscap] Foolscap network protocol. http://foolscap.lothar.com/trac |
|
280 | .. [Foolscap] Foolscap network protocol. http://foolscap.lothar.com/trac | |
217 | .. [pyOpenSSL] pyOpenSSL. http://pyopenssl.sourceforge.net No newline at end of file |
|
281 | .. [pyOpenSSL] pyOpenSSL. http://pyopenssl.sourceforge.net |
This diff has been collapsed as it changes many lines, (1571 lines changed) Show them Hide them | |||||
@@ -490,9 +490,9 b' following example defines a new magic command, %impall::' | |||||
490 | ip.expose_magic('impall', doimp) |
|
490 | ip.expose_magic('impall', doimp) | |
491 |
|
491 | |||
492 | You can also define your own aliased names for magic functions. In your |
|
492 | You can also define your own aliased names for magic functions. In your | |
493 | ipythonrc file, placing a line like: |
|
493 | ipythonrc file, placing a line like:: | |
494 |
|
494 | |||
495 | execute __IP.magic_cl = __IP.magic_clear |
|
495 | execute __IP.magic_cl = __IP.magic_clear | |
496 |
|
496 | |||
497 | will define %cl as a new name for %clear. |
|
497 | will define %cl as a new name for %clear. | |
498 |
|
498 | |||
@@ -502,1572 +502,9 b' magic functions at any time and their docstrings. You can also type' | |||||
502 | information on the '?' system) to get information about any particular |
|
502 | information on the '?' system) to get information about any particular | |
503 | magic function you are interested in. |
|
503 | magic function you are interested in. | |
504 |
|
504 | |||
|
505 | The API documentation for the :mod:`IPython.Magic` module contains the full | |||
|
506 | docstrings of all currently available magic commands. | |||
505 |
|
507 | |||
506 | Magic commands |
|
|||
507 | -------------- |
|
|||
508 |
|
||||
509 | The rest of this section is automatically generated for each release |
|
|||
510 | from the docstrings in the IPython code. Therefore the formatting is |
|
|||
511 | somewhat minimal, but this method has the advantage of having |
|
|||
512 | information always in sync with the code. |
|
|||
513 |
|
||||
514 | A list of all the magic commands available in IPython's default |
|
|||
515 | installation follows. This is similar to what you'll see by simply |
|
|||
516 | typing %magic at the prompt, but that will also give you information |
|
|||
517 | about magic commands you may have added as part of your personal |
|
|||
518 | customizations. |
|
|||
519 |
|
||||
520 | .. magic_start |
|
|||
521 |
|
||||
522 | **%Exit**:: |
|
|||
523 |
|
||||
524 | Exit IPython without confirmation. |
|
|||
525 |
|
||||
526 | **%Pprint**:: |
|
|||
527 |
|
||||
528 | Toggle pretty printing on/off. |
|
|||
529 |
|
||||
530 | **%alias**:: |
|
|||
531 |
|
||||
532 | Define an alias for a system command. |
|
|||
533 |
|
||||
534 | '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd' |
|
|||
535 |
|
||||
536 | Then, typing 'alias_name params' will execute the system command 'cmd |
|
|||
537 | params' (from your underlying operating system). |
|
|||
538 |
|
||||
539 | Aliases have lower precedence than magic functions and Python normal |
|
|||
540 | variables, so if 'foo' is both a Python variable and an alias, the |
|
|||
541 | alias can not be executed until 'del foo' removes the Python variable. |
|
|||
542 |
|
||||
543 | You can use the %l specifier in an alias definition to represent the |
|
|||
544 | whole line when the alias is called. For example: |
|
|||
545 |
|
||||
546 | In [2]: alias all echo "Input in brackets: <%l>"\ |
|
|||
547 | In [3]: all hello world\ |
|
|||
548 | Input in brackets: <hello world> |
|
|||
549 |
|
||||
550 | You can also define aliases with parameters using %s specifiers (one |
|
|||
551 | per parameter): |
|
|||
552 |
|
||||
553 | In [1]: alias parts echo first %s second %s\ |
|
|||
554 | In [2]: %parts A B\ |
|
|||
555 | first A second B\ |
|
|||
556 | In [3]: %parts A\ |
|
|||
557 | Incorrect number of arguments: 2 expected.\ |
|
|||
558 | parts is an alias to: 'echo first %s second %s' |
|
|||
559 |
|
||||
560 | Note that %l and %s are mutually exclusive. You can only use one or |
|
|||
561 | the other in your aliases. |
|
|||
562 |
|
||||
563 | Aliases expand Python variables just like system calls using ! or !! |
|
|||
564 | do: all expressions prefixed with '$' get expanded. For details of |
|
|||
565 | the semantic rules, see PEP-215: |
|
|||
566 | http://www.python.org/peps/pep-0215.html. This is the library used by |
|
|||
567 | IPython for variable expansion. If you want to access a true shell |
|
|||
568 | variable, an extra $ is necessary to prevent its expansion by IPython: |
|
|||
569 |
|
||||
570 | In [6]: alias show echo\ |
|
|||
571 | In [7]: PATH='A Python string'\ |
|
|||
572 | In [8]: show $PATH\ |
|
|||
573 | A Python string\ |
|
|||
574 | In [9]: show $$PATH\ |
|
|||
575 | /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:... |
|
|||
576 |
|
||||
577 | You can use the alias facility to acess all of $PATH. See the %rehash |
|
|||
578 | and %rehashx functions, which automatically create aliases for the |
|
|||
579 | contents of your $PATH. |
|
|||
580 |
|
||||
581 | If called with no parameters, %alias prints the current alias table. |
|
|||
582 |
|
||||
583 | **%autocall**:: |
|
|||
584 |
|
||||
585 | Make functions callable without having to type parentheses. |
|
|||
586 |
|
||||
587 | Usage: |
|
|||
588 |
|
||||
589 | %autocall [mode] |
|
|||
590 |
|
||||
591 | The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the |
|
|||
592 | value is toggled on and off (remembering the previous state). |
|
|||
593 |
|
||||
594 | In more detail, these values mean: |
|
|||
595 |
|
||||
596 | 0 -> fully disabled |
|
|||
597 |
|
||||
598 | 1 -> active, but do not apply if there are no arguments on the line. |
|
|||
599 |
|
||||
600 | In this mode, you get: |
|
|||
601 |
|
||||
602 | In [1]: callable |
|
|||
603 | Out[1]: <built-in function callable> |
|
|||
604 |
|
||||
605 | In [2]: callable 'hello' |
|
|||
606 | ------> callable('hello') |
|
|||
607 | Out[2]: False |
|
|||
608 |
|
||||
609 | 2 -> Active always. Even if no arguments are present, the callable |
|
|||
610 | object is called: |
|
|||
611 |
|
||||
612 | In [4]: callable |
|
|||
613 | ------> callable() |
|
|||
614 |
|
||||
615 | Note that even with autocall off, you can still use '/' at the start of |
|
|||
616 | a line to treat the first argument on the command line as a function |
|
|||
617 | and add parentheses to it: |
|
|||
618 |
|
||||
619 | In [8]: /str 43 |
|
|||
620 | ------> str(43) |
|
|||
621 | Out[8]: '43' |
|
|||
622 |
|
||||
623 | **%autoindent**:: |
|
|||
624 |
|
||||
625 | Toggle autoindent on/off (if available). |
|
|||
626 |
|
||||
627 | **%automagic**:: |
|
|||
628 |
|
||||
629 | Make magic functions callable without having to type the initial %. |
|
|||
630 |
|
||||
631 | Without argumentsl toggles on/off (when off, you must call it as |
|
|||
632 | %automagic, of course). With arguments it sets the value, and you can |
|
|||
633 | use any of (case insensitive): |
|
|||
634 |
|
||||
635 | - on,1,True: to activate |
|
|||
636 |
|
||||
637 | - off,0,False: to deactivate. |
|
|||
638 |
|
||||
639 | Note that magic functions have lowest priority, so if there's a |
|
|||
640 | variable whose name collides with that of a magic fn, automagic won't |
|
|||
641 | work for that function (you get the variable instead). However, if you |
|
|||
642 | delete the variable (del var), the previously shadowed magic function |
|
|||
643 | becomes visible to automagic again. |
|
|||
644 |
|
||||
645 | **%bg**:: |
|
|||
646 |
|
||||
647 | Run a job in the background, in a separate thread. |
|
|||
648 |
|
||||
649 | For example, |
|
|||
650 |
|
||||
651 | %bg myfunc(x,y,z=1) |
|
|||
652 |
|
||||
653 | will execute 'myfunc(x,y,z=1)' in a background thread. As soon as the |
|
|||
654 | execution starts, a message will be printed indicating the job |
|
|||
655 | number. If your job number is 5, you can use |
|
|||
656 |
|
||||
657 | myvar = jobs.result(5) or myvar = jobs[5].result |
|
|||
658 |
|
||||
659 | to assign this result to variable 'myvar'. |
|
|||
660 |
|
||||
661 | IPython has a job manager, accessible via the 'jobs' object. You can |
|
|||
662 | type jobs? to get more information about it, and use jobs.<TAB> to see |
|
|||
663 | its attributes. All attributes not starting with an underscore are |
|
|||
664 | meant for public use. |
|
|||
665 |
|
||||
666 | In particular, look at the jobs.new() method, which is used to create |
|
|||
667 | new jobs. This magic %bg function is just a convenience wrapper |
|
|||
668 | around jobs.new(), for expression-based jobs. If you want to create a |
|
|||
669 | new job with an explicit function object and arguments, you must call |
|
|||
670 | jobs.new() directly. |
|
|||
671 |
|
||||
672 | The jobs.new docstring also describes in detail several important |
|
|||
673 | caveats associated with a thread-based model for background job |
|
|||
674 | execution. Type jobs.new? for details. |
|
|||
675 |
|
||||
676 | You can check the status of all jobs with jobs.status(). |
|
|||
677 |
|
||||
678 | The jobs variable is set by IPython into the Python builtin namespace. |
|
|||
679 | If you ever declare a variable named 'jobs', you will shadow this |
|
|||
680 | name. You can either delete your global jobs variable to regain |
|
|||
681 | access to the job manager, or make a new name and assign it manually |
|
|||
682 | to the manager (stored in IPython's namespace). For example, to |
|
|||
683 | assign the job manager to the Jobs name, use: |
|
|||
684 |
|
||||
685 | Jobs = __builtins__.jobs |
|
|||
686 |
|
||||
687 | **%bookmark**:: |
|
|||
688 |
|
||||
689 | Manage IPython's bookmark system. |
|
|||
690 |
|
||||
691 | %bookmark <name> - set bookmark to current dir |
|
|||
692 | %bookmark <name> <dir> - set bookmark to <dir> |
|
|||
693 | %bookmark -l - list all bookmarks |
|
|||
694 | %bookmark -d <name> - remove bookmark |
|
|||
695 | %bookmark -r - remove all bookmarks |
|
|||
696 |
|
||||
697 | You can later on access a bookmarked folder with: |
|
|||
698 | %cd -b <name> |
|
|||
699 | or simply '%cd <name>' if there is no directory called <name> AND |
|
|||
700 | there is such a bookmark defined. |
|
|||
701 |
|
||||
702 | Your bookmarks persist through IPython sessions, but they are |
|
|||
703 | associated with each profile. |
|
|||
704 |
|
||||
705 | **%cd**:: |
|
|||
706 |
|
||||
707 | Change the current working directory. |
|
|||
708 |
|
||||
709 | This command automatically maintains an internal list of directories |
|
|||
710 | you visit during your IPython session, in the variable _dh. The |
|
|||
711 | command %dhist shows this history nicely formatted. You can also |
|
|||
712 | do 'cd -<tab>' to see directory history conveniently. |
|
|||
713 |
|
||||
714 | Usage: |
|
|||
715 |
|
||||
716 | cd 'dir': changes to directory 'dir'. |
|
|||
717 |
|
||||
718 | cd -: changes to the last visited directory. |
|
|||
719 |
|
||||
720 | cd -<n>: changes to the n-th directory in the directory history. |
|
|||
721 |
|
||||
722 | cd -b <bookmark_name>: jump to a bookmark set by %bookmark |
|
|||
723 | (note: cd <bookmark_name> is enough if there is no |
|
|||
724 | directory <bookmark_name>, but a bookmark with the name exists.) |
|
|||
725 | 'cd -b <tab>' allows you to tab-complete bookmark names. |
|
|||
726 |
|
||||
727 | Options: |
|
|||
728 |
|
||||
729 | -q: quiet. Do not print the working directory after the cd command is |
|
|||
730 | executed. By default IPython's cd command does print this directory, |
|
|||
731 | since the default prompts do not display path information. |
|
|||
732 |
|
||||
733 | Note that !cd doesn't work for this purpose because the shell where |
|
|||
734 | !command runs is immediately discarded after executing 'command'. |
|
|||
735 |
|
||||
736 | **%clear**:: |
|
|||
737 |
|
||||
738 | Clear various data (e.g. stored history data) |
|
|||
739 |
|
||||
740 | %clear out - clear output history |
|
|||
741 | %clear in - clear input history |
|
|||
742 | %clear shadow_compress - Compresses shadow history (to speed up ipython) |
|
|||
743 | %clear shadow_nuke - permanently erase all entries in shadow history |
|
|||
744 | %clear dhist - clear dir history |
|
|||
745 |
|
||||
746 | **%color_info**:: |
|
|||
747 |
|
||||
748 | Toggle color_info. |
|
|||
749 |
|
||||
750 | The color_info configuration parameter controls whether colors are |
|
|||
751 | used for displaying object details (by things like %psource, %pfile or |
|
|||
752 | the '?' system). This function toggles this value with each call. |
|
|||
753 |
|
||||
754 | Note that unless you have a fairly recent pager (less works better |
|
|||
755 | than more) in your system, using colored object information displays |
|
|||
756 | will not work properly. Test it and see. |
|
|||
757 |
|
||||
758 | **%colors**:: |
|
|||
759 |
|
||||
760 | Switch color scheme for prompts, info system and exception handlers. |
|
|||
761 |
|
||||
762 | Currently implemented schemes: NoColor, Linux, LightBG. |
|
|||
763 |
|
||||
764 | Color scheme names are not case-sensitive. |
|
|||
765 |
|
||||
766 | **%cpaste**:: |
|
|||
767 |
|
||||
768 | Allows you to paste & execute a pre-formatted code block from clipboard |
|
|||
769 |
|
||||
770 | You must terminate the block with '--' (two minus-signs) alone on the |
|
|||
771 | line. You can also provide your own sentinel with '%paste -s %%' ('%%' |
|
|||
772 | is the new sentinel for this operation) |
|
|||
773 |
|
||||
774 | The block is dedented prior to execution to enable execution of method |
|
|||
775 | definitions. '>' and '+' characters at the beginning of a line are |
|
|||
776 | ignored, to allow pasting directly from e-mails or diff files. The |
|
|||
777 | executed block is also assigned to variable named 'pasted_block' for |
|
|||
778 | later editing with '%edit pasted_block'. |
|
|||
779 |
|
||||
780 | You can also pass a variable name as an argument, e.g. '%cpaste foo'. |
|
|||
781 | This assigns the pasted block to variable 'foo' as string, without |
|
|||
782 | dedenting or executing it. |
|
|||
783 |
|
||||
784 | Do not be alarmed by garbled output on Windows (it's a readline bug). |
|
|||
785 | Just press enter and type -- (and press enter again) and the block |
|
|||
786 | will be what was just pasted. |
|
|||
787 |
|
||||
788 | IPython statements (magics, shell escapes) are not supported (yet). |
|
|||
789 |
|
||||
790 | **%debug**:: |
|
|||
791 |
|
||||
792 | Activate the interactive debugger in post-mortem mode. |
|
|||
793 |
|
||||
794 | If an exception has just occurred, this lets you inspect its stack |
|
|||
795 | frames interactively. Note that this will always work only on the last |
|
|||
796 | traceback that occurred, so you must call this quickly after an |
|
|||
797 | exception that you wish to inspect has fired, because if another one |
|
|||
798 | occurs, it clobbers the previous one. |
|
|||
799 |
|
||||
800 | If you want IPython to automatically do this on every exception, see |
|
|||
801 | the %pdb magic for more details. |
|
|||
802 |
|
||||
803 | **%dhist**:: |
|
|||
804 |
|
||||
805 | Print your history of visited directories. |
|
|||
806 |
|
||||
807 | %dhist -> print full history\ |
|
|||
808 | %dhist n -> print last n entries only\ |
|
|||
809 | %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\ |
|
|||
810 |
|
||||
811 | This history is automatically maintained by the %cd command, and |
|
|||
812 | always available as the global list variable _dh. You can use %cd -<n> |
|
|||
813 | to go to directory number <n>. |
|
|||
814 |
|
||||
815 | Note that most of time, you should view directory history by entering |
|
|||
816 | cd -<TAB>. |
|
|||
817 |
|
||||
818 | **%dirs**:: |
|
|||
819 |
|
||||
820 | Return the current directory stack. |
|
|||
821 |
|
||||
822 | **%doctest_mode**:: |
|
|||
823 |
|
||||
824 | Toggle doctest mode on and off. |
|
|||
825 |
|
||||
826 | This mode allows you to toggle the prompt behavior between normal |
|
|||
827 | IPython prompts and ones that are as similar to the default IPython |
|
|||
828 | interpreter as possible. |
|
|||
829 |
|
||||
830 | It also supports the pasting of code snippets that have leading '>>>' |
|
|||
831 | and '...' prompts in them. This means that you can paste doctests from |
|
|||
832 | files or docstrings (even if they have leading whitespace), and the |
|
|||
833 | code will execute correctly. You can then use '%history -tn' to see |
|
|||
834 | the translated history without line numbers; this will give you the |
|
|||
835 | input after removal of all the leading prompts and whitespace, which |
|
|||
836 | can be pasted back into an editor. |
|
|||
837 |
|
||||
838 | With these features, you can switch into this mode easily whenever you |
|
|||
839 | need to do testing and changes to doctests, without having to leave |
|
|||
840 | your existing IPython session. |
|
|||
841 |
|
||||
842 | **%ed**:: |
|
|||
843 |
|
||||
844 | Alias to %edit. |
|
|||
845 |
|
||||
846 | **%edit**:: |
|
|||
847 |
|
||||
848 | Bring up an editor and execute the resulting code. |
|
|||
849 |
|
||||
850 | Usage: |
|
|||
851 | %edit [options] [args] |
|
|||
852 |
|
||||
853 | %edit runs IPython's editor hook. The default version of this hook is |
|
|||
854 | set to call the __IPYTHON__.rc.editor command. This is read from your |
|
|||
855 | environment variable $EDITOR. If this isn't found, it will default to |
|
|||
856 | vi under Linux/Unix and to notepad under Windows. See the end of this |
|
|||
857 | docstring for how to change the editor hook. |
|
|||
858 |
|
||||
859 | You can also set the value of this editor via the command line option |
|
|||
860 | '-editor' or in your ipythonrc file. This is useful if you wish to use |
|
|||
861 | specifically for IPython an editor different from your typical default |
|
|||
862 | (and for Windows users who typically don't set environment variables). |
|
|||
863 |
|
||||
864 | This command allows you to conveniently edit multi-line code right in |
|
|||
865 | your IPython session. |
|
|||
866 |
|
||||
867 | If called without arguments, %edit opens up an empty editor with a |
|
|||
868 | temporary file and will execute the contents of this file when you |
|
|||
869 | close it (don't forget to save it!). |
|
|||
870 |
|
||||
871 |
|
||||
872 | Options: |
|
|||
873 |
|
||||
874 | -n <number>: open the editor at a specified line number. By default, |
|
|||
875 | the IPython editor hook uses the unix syntax 'editor +N filename', but |
|
|||
876 | you can configure this by providing your own modified hook if your |
|
|||
877 | favorite editor supports line-number specifications with a different |
|
|||
878 | syntax. |
|
|||
879 |
|
||||
880 | -p: this will call the editor with the same data as the previous time |
|
|||
881 | it was used, regardless of how long ago (in your current session) it |
|
|||
882 | was. |
|
|||
883 |
|
||||
884 | -r: use 'raw' input. This option only applies to input taken from the |
|
|||
885 | user's history. By default, the 'processed' history is used, so that |
|
|||
886 | magics are loaded in their transformed version to valid Python. If |
|
|||
887 | this option is given, the raw input as typed as the command line is |
|
|||
888 | used instead. When you exit the editor, it will be executed by |
|
|||
889 | IPython's own processor. |
|
|||
890 |
|
||||
891 | -x: do not execute the edited code immediately upon exit. This is |
|
|||
892 | mainly useful if you are editing programs which need to be called with |
|
|||
893 | command line arguments, which you can then do using %run. |
|
|||
894 |
|
||||
895 |
|
||||
896 | Arguments: |
|
|||
897 |
|
||||
898 | If arguments are given, the following possibilites exist: |
|
|||
899 |
|
||||
900 | - The arguments are numbers or pairs of colon-separated numbers (like |
|
|||
901 | 1 4:8 9). These are interpreted as lines of previous input to be |
|
|||
902 | loaded into the editor. The syntax is the same of the %macro command. |
|
|||
903 |
|
||||
904 | - If the argument doesn't start with a number, it is evaluated as a |
|
|||
905 | variable and its contents loaded into the editor. You can thus edit |
|
|||
906 | any string which contains python code (including the result of |
|
|||
907 | previous edits). |
|
|||
908 |
|
||||
909 | - If the argument is the name of an object (other than a string), |
|
|||
910 | IPython will try to locate the file where it was defined and open the |
|
|||
911 | editor at the point where it is defined. You can use `%edit function` |
|
|||
912 | to load an editor exactly at the point where 'function' is defined, |
|
|||
913 | edit it and have the file be executed automatically. |
|
|||
914 |
|
||||
915 | If the object is a macro (see %macro for details), this opens up your |
|
|||
916 | specified editor with a temporary file containing the macro's data. |
|
|||
917 | Upon exit, the macro is reloaded with the contents of the file. |
|
|||
918 |
|
||||
919 | Note: opening at an exact line is only supported under Unix, and some |
|
|||
920 | editors (like kedit and gedit up to Gnome 2.8) do not understand the |
|
|||
921 | '+NUMBER' parameter necessary for this feature. Good editors like |
|
|||
922 | (X)Emacs, vi, jed, pico and joe all do. |
|
|||
923 |
|
||||
924 | - If the argument is not found as a variable, IPython will look for a |
|
|||
925 | file with that name (adding .py if necessary) and load it into the |
|
|||
926 | editor. It will execute its contents with execfile() when you exit, |
|
|||
927 | loading any code in the file into your interactive namespace. |
|
|||
928 |
|
||||
929 | After executing your code, %edit will return as output the code you |
|
|||
930 | typed in the editor (except when it was an existing file). This way |
|
|||
931 | you can reload the code in further invocations of %edit as a variable, |
|
|||
932 | via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of |
|
|||
933 | the output. |
|
|||
934 |
|
||||
935 | Note that %edit is also available through the alias %ed. |
|
|||
936 |
|
||||
937 | This is an example of creating a simple function inside the editor and |
|
|||
938 | then modifying it. First, start up the editor: |
|
|||
939 |
|
||||
940 | In [1]: ed\ |
|
|||
941 | Editing... done. Executing edited code...\ |
|
|||
942 | Out[1]: 'def foo():\n print "foo() was defined in an editing session"\n' |
|
|||
943 |
|
||||
944 | We can then call the function foo(): |
|
|||
945 |
|
||||
946 | In [2]: foo()\ |
|
|||
947 | foo() was defined in an editing session |
|
|||
948 |
|
||||
949 | Now we edit foo. IPython automatically loads the editor with the |
|
|||
950 | (temporary) file where foo() was previously defined: |
|
|||
951 |
|
||||
952 | In [3]: ed foo\ |
|
|||
953 | Editing... done. Executing edited code... |
|
|||
954 |
|
||||
955 | And if we call foo() again we get the modified version: |
|
|||
956 |
|
||||
957 | In [4]: foo()\ |
|
|||
958 | foo() has now been changed! |
|
|||
959 |
|
||||
960 | Here is an example of how to edit a code snippet successive |
|
|||
961 | times. First we call the editor: |
|
|||
962 |
|
||||
963 | In [8]: ed\ |
|
|||
964 | Editing... done. Executing edited code...\ |
|
|||
965 | hello\ |
|
|||
966 | Out[8]: "print 'hello'\n" |
|
|||
967 |
|
||||
968 | Now we call it again with the previous output (stored in _): |
|
|||
969 |
|
||||
970 | In [9]: ed _\ |
|
|||
971 | Editing... done. Executing edited code...\ |
|
|||
972 | hello world\ |
|
|||
973 | Out[9]: "print 'hello world'\n" |
|
|||
974 |
|
||||
975 | Now we call it with the output #8 (stored in _8, also as Out[8]): |
|
|||
976 |
|
||||
977 | In [10]: ed _8\ |
|
|||
978 | Editing... done. Executing edited code...\ |
|
|||
979 | hello again\ |
|
|||
980 | Out[10]: "print 'hello again'\n" |
|
|||
981 |
|
||||
982 |
|
||||
983 | Changing the default editor hook: |
|
|||
984 |
|
||||
985 | If you wish to write your own editor hook, you can put it in a |
|
|||
986 | configuration file which you load at startup time. The default hook |
|
|||
987 | is defined in the IPython.hooks module, and you can use that as a |
|
|||
988 | starting example for further modifications. That file also has |
|
|||
989 | general instructions on how to set a new hook for use once you've |
|
|||
990 | defined it. |
|
|||
991 |
|
||||
992 | **%env**:: |
|
|||
993 |
|
||||
994 | List environment variables. |
|
|||
995 |
|
||||
996 | **%exit**:: |
|
|||
997 |
|
||||
998 | Exit IPython, confirming if configured to do so. |
|
|||
999 |
|
||||
1000 | You can configure whether IPython asks for confirmation upon exit by |
|
|||
1001 | setting the confirm_exit flag in the ipythonrc file. |
|
|||
1002 |
|
||||
1003 | **%hist**:: |
|
|||
1004 |
|
||||
1005 | Alternate name for %history. |
|
|||
1006 |
|
||||
1007 | **%history**:: |
|
|||
1008 |
|
||||
1009 | Print input history (_i<n> variables), with most recent last. |
|
|||
1010 |
|
||||
1011 | %history -> print at most 40 inputs (some may be multi-line)\ |
|
|||
1012 | %history n -> print at most n inputs\ |
|
|||
1013 | %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\ |
|
|||
1014 |
|
||||
1015 | Each input's number <n> is shown, and is accessible as the |
|
|||
1016 | automatically generated variable _i<n>. Multi-line statements are |
|
|||
1017 | printed starting at a new line for easy copy/paste. |
|
|||
1018 |
|
||||
1019 |
|
||||
1020 | Options: |
|
|||
1021 |
|
||||
1022 | -n: do NOT print line numbers. This is useful if you want to get a |
|
|||
1023 | printout of many lines which can be directly pasted into a text |
|
|||
1024 | editor. |
|
|||
1025 |
|
||||
1026 | This feature is only available if numbered prompts are in use. |
|
|||
1027 |
|
||||
1028 | -t: (default) print the 'translated' history, as IPython understands it. |
|
|||
1029 | IPython filters your input and converts it all into valid Python source |
|
|||
1030 | before executing it (things like magics or aliases are turned into |
|
|||
1031 | function calls, for example). With this option, you'll see the native |
|
|||
1032 | history instead of the user-entered version: '%cd /' will be seen as |
|
|||
1033 | '_ip.magic("%cd /")' instead of '%cd /'. |
|
|||
1034 |
|
||||
1035 | -r: print the 'raw' history, i.e. the actual commands you typed. |
|
|||
1036 |
|
||||
1037 | -g: treat the arg as a pattern to grep for in (full) history. |
|
|||
1038 | This includes the "shadow history" (almost all commands ever written). |
|
|||
1039 | Use '%hist -g' to show full shadow history (may be very long). |
|
|||
1040 | In shadow history, every index nuwber starts with 0. |
|
|||
1041 |
|
||||
1042 | -f FILENAME: instead of printing the output to the screen, redirect it to |
|
|||
1043 | the given file. The file is always overwritten, though IPython asks for |
|
|||
1044 | confirmation first if it already exists. |
|
|||
1045 |
|
||||
1046 | **%logoff**:: |
|
|||
1047 |
|
||||
1048 | Temporarily stop logging. |
|
|||
1049 |
|
||||
1050 | You must have previously started logging. |
|
|||
1051 |
|
||||
1052 | **%logon**:: |
|
|||
1053 |
|
||||
1054 | Restart logging. |
|
|||
1055 |
|
||||
1056 | This function is for restarting logging which you've temporarily |
|
|||
1057 | stopped with %logoff. For starting logging for the first time, you |
|
|||
1058 | must use the %logstart function, which allows you to specify an |
|
|||
1059 | optional log filename. |
|
|||
1060 |
|
||||
1061 | **%logstart**:: |
|
|||
1062 |
|
||||
1063 | Start logging anywhere in a session. |
|
|||
1064 |
|
||||
1065 | %logstart [-o|-r|-t] [log_name [log_mode]] |
|
|||
1066 |
|
||||
1067 | If no name is given, it defaults to a file named 'ipython_log.py' in your |
|
|||
1068 | current directory, in 'rotate' mode (see below). |
|
|||
1069 |
|
||||
1070 | '%logstart name' saves to file 'name' in 'backup' mode. It saves your |
|
|||
1071 | history up to that point and then continues logging. |
|
|||
1072 |
|
||||
1073 | %logstart takes a second optional parameter: logging mode. This can be one |
|
|||
1074 | of (note that the modes are given unquoted):\ |
|
|||
1075 | append: well, that says it.\ |
|
|||
1076 | backup: rename (if exists) to name~ and start name.\ |
|
|||
1077 | global: single logfile in your home dir, appended to.\ |
|
|||
1078 | over : overwrite existing log.\ |
|
|||
1079 | rotate: create rotating logs name.1~, name.2~, etc. |
|
|||
1080 |
|
||||
1081 | Options: |
|
|||
1082 |
|
||||
1083 | -o: log also IPython's output. In this mode, all commands which |
|
|||
1084 | generate an Out[NN] prompt are recorded to the logfile, right after |
|
|||
1085 | their corresponding input line. The output lines are always |
|
|||
1086 | prepended with a '#[Out]# ' marker, so that the log remains valid |
|
|||
1087 | Python code. |
|
|||
1088 |
|
||||
1089 | Since this marker is always the same, filtering only the output from |
|
|||
1090 | a log is very easy, using for example a simple awk call: |
|
|||
1091 |
|
||||
1092 | awk -F'#\[Out\]# ' '{if($2) {print $2}}' ipython_log.py |
|
|||
1093 |
|
||||
1094 | -r: log 'raw' input. Normally, IPython's logs contain the processed |
|
|||
1095 | input, so that user lines are logged in their final form, converted |
|
|||
1096 | into valid Python. For example, %Exit is logged as |
|
|||
1097 | '_ip.magic("Exit"). If the -r flag is given, all input is logged |
|
|||
1098 | exactly as typed, with no transformations applied. |
|
|||
1099 |
|
||||
1100 | -t: put timestamps before each input line logged (these are put in |
|
|||
1101 | comments). |
|
|||
1102 |
|
||||
1103 | **%logstate**:: |
|
|||
1104 |
|
||||
1105 | Print the status of the logging system. |
|
|||
1106 |
|
||||
1107 | **%logstop**:: |
|
|||
1108 |
|
||||
1109 | Fully stop logging and close log file. |
|
|||
1110 |
|
||||
1111 | In order to start logging again, a new %logstart call needs to be made, |
|
|||
1112 | possibly (though not necessarily) with a new filename, mode and other |
|
|||
1113 | options. |
|
|||
1114 |
|
||||
1115 | **%lsmagic**:: |
|
|||
1116 |
|
||||
1117 | List currently available magic functions. |
|
|||
1118 |
|
||||
1119 | **%macro**:: |
|
|||
1120 |
|
||||
1121 | Define a set of input lines as a macro for future re-execution. |
|
|||
1122 |
|
||||
1123 | Usage:\ |
|
|||
1124 | %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ... |
|
|||
1125 |
|
||||
1126 | Options: |
|
|||
1127 |
|
||||
1128 | -r: use 'raw' input. By default, the 'processed' history is used, |
|
|||
1129 | so that magics are loaded in their transformed version to valid |
|
|||
1130 | Python. If this option is given, the raw input as typed as the |
|
|||
1131 | command line is used instead. |
|
|||
1132 |
|
||||
1133 | This will define a global variable called `name` which is a string |
|
|||
1134 | made of joining the slices and lines you specify (n1,n2,... numbers |
|
|||
1135 | above) from your input history into a single string. This variable |
|
|||
1136 | acts like an automatic function which re-executes those lines as if |
|
|||
1137 | you had typed them. You just type 'name' at the prompt and the code |
|
|||
1138 | executes. |
|
|||
1139 |
|
||||
1140 | The notation for indicating number ranges is: n1-n2 means 'use line |
|
|||
1141 | numbers n1,...n2' (the endpoint is included). That is, '5-7' means |
|
|||
1142 | using the lines numbered 5,6 and 7. |
|
|||
1143 |
|
||||
1144 | Note: as a 'hidden' feature, you can also use traditional python slice |
|
|||
1145 | notation, where N:M means numbers N through M-1. |
|
|||
1146 |
|
||||
1147 | For example, if your history contains (%hist prints it): |
|
|||
1148 |
|
||||
1149 | 44: x=1\ |
|
|||
1150 | 45: y=3\ |
|
|||
1151 | 46: z=x+y\ |
|
|||
1152 | 47: print x\ |
|
|||
1153 | 48: a=5\ |
|
|||
1154 | 49: print 'x',x,'y',y\ |
|
|||
1155 |
|
||||
1156 | you can create a macro with lines 44 through 47 (included) and line 49 |
|
|||
1157 | called my_macro with: |
|
|||
1158 |
|
||||
1159 | In [51]: %macro my_macro 44-47 49 |
|
|||
1160 |
|
||||
1161 | Now, typing `my_macro` (without quotes) will re-execute all this code |
|
|||
1162 | in one pass. |
|
|||
1163 |
|
||||
1164 | You don't need to give the line-numbers in order, and any given line |
|
|||
1165 | number can appear multiple times. You can assemble macros with any |
|
|||
1166 | lines from your input history in any order. |
|
|||
1167 |
|
||||
1168 | The macro is a simple object which holds its value in an attribute, |
|
|||
1169 | but IPython's display system checks for macros and executes them as |
|
|||
1170 | code instead of printing them when you type their name. |
|
|||
1171 |
|
||||
1172 | You can view a macro's contents by explicitly printing it with: |
|
|||
1173 |
|
||||
1174 | 'print macro_name'. |
|
|||
1175 |
|
||||
1176 | For one-off cases which DON'T contain magic function calls in them you |
|
|||
1177 | can obtain similar results by explicitly executing slices from your |
|
|||
1178 | input history with: |
|
|||
1179 |
|
||||
1180 | In [60]: exec In[44:48]+In[49] |
|
|||
1181 |
|
||||
1182 | **%magic**:: |
|
|||
1183 |
|
||||
1184 | Print information about the magic function system. |
|
|||
1185 |
|
||||
1186 | **%mglob**:: |
|
|||
1187 |
|
||||
1188 | This program allows specifying filenames with "mglob" mechanism. |
|
|||
1189 | Supported syntax in globs (wilcard matching patterns):: |
|
|||
1190 |
|
||||
1191 | *.cpp ?ellowo* |
|
|||
1192 | - obvious. Differs from normal glob in that dirs are not included. |
|
|||
1193 | Unix users might want to write this as: "*.cpp" "?ellowo*" |
|
|||
1194 | rec:/usr/share=*.txt,*.doc |
|
|||
1195 | - get all *.txt and *.doc under /usr/share, |
|
|||
1196 | recursively |
|
|||
1197 | rec:/usr/share |
|
|||
1198 | - All files under /usr/share, recursively |
|
|||
1199 | rec:*.py |
|
|||
1200 | - All .py files under current working dir, recursively |
|
|||
1201 | foo |
|
|||
1202 | - File or dir foo |
|
|||
1203 | !*.bak readme* |
|
|||
1204 | - readme*, exclude files ending with .bak |
|
|||
1205 | !.svn/ !.hg/ !*_Data/ rec:. |
|
|||
1206 | - Skip .svn, .hg, foo_Data dirs (and their subdirs) in recurse. |
|
|||
1207 | Trailing / is the key, \ does not work! |
|
|||
1208 | dir:foo |
|
|||
1209 | - the directory foo if it exists (not files in foo) |
|
|||
1210 | dir:* |
|
|||
1211 | - all directories in current folder |
|
|||
1212 | foo.py bar.* !h* rec:*.py |
|
|||
1213 | - Obvious. !h* exclusion only applies for rec:*.py. |
|
|||
1214 | foo.py is *not* included twice. |
|
|||
1215 | @filelist.txt |
|
|||
1216 | - All files listed in 'filelist.txt' file, on separate lines. |
|
|||
1217 |
|
||||
1218 | **%page**:: |
|
|||
1219 |
|
||||
1220 | Pretty print the object and display it through a pager. |
|
|||
1221 |
|
||||
1222 | %page [options] OBJECT |
|
|||
1223 |
|
||||
1224 | If no object is given, use _ (last output). |
|
|||
1225 |
|
||||
1226 | Options: |
|
|||
1227 |
|
||||
1228 | -r: page str(object), don't pretty-print it. |
|
|||
1229 |
|
||||
1230 | **%pdb**:: |
|
|||
1231 |
|
||||
1232 | Control the automatic calling of the pdb interactive debugger. |
|
|||
1233 |
|
||||
1234 | Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without |
|
|||
1235 | argument it works as a toggle. |
|
|||
1236 |
|
||||
1237 | When an exception is triggered, IPython can optionally call the |
|
|||
1238 | interactive pdb debugger after the traceback printout. %pdb toggles |
|
|||
1239 | this feature on and off. |
|
|||
1240 |
|
||||
1241 | The initial state of this feature is set in your ipythonrc |
|
|||
1242 | configuration file (the variable is called 'pdb'). |
|
|||
1243 |
|
||||
1244 | If you want to just activate the debugger AFTER an exception has fired, |
|
|||
1245 | without having to type '%pdb on' and rerunning your code, you can use |
|
|||
1246 | the %debug magic. |
|
|||
1247 |
|
||||
1248 | **%pdef**:: |
|
|||
1249 |
|
||||
1250 | Print the definition header for any callable object. |
|
|||
1251 |
|
||||
1252 | If the object is a class, print the constructor information. |
|
|||
1253 |
|
||||
1254 | **%pdoc**:: |
|
|||
1255 |
|
||||
1256 | Print the docstring for an object. |
|
|||
1257 |
|
||||
1258 | If the given object is a class, it will print both the class and the |
|
|||
1259 | constructor docstrings. |
|
|||
1260 |
|
||||
1261 | **%pfile**:: |
|
|||
1262 |
|
||||
1263 | Print (or run through pager) the file where an object is defined. |
|
|||
1264 |
|
||||
1265 | The file opens at the line where the object definition begins. IPython |
|
|||
1266 | will honor the environment variable PAGER if set, and otherwise will |
|
|||
1267 | do its best to print the file in a convenient form. |
|
|||
1268 |
|
||||
1269 | If the given argument is not an object currently defined, IPython will |
|
|||
1270 | try to interpret it as a filename (automatically adding a .py extension |
|
|||
1271 | if needed). You can thus use %pfile as a syntax highlighting code |
|
|||
1272 | viewer. |
|
|||
1273 |
|
||||
1274 | **%pinfo**:: |
|
|||
1275 |
|
||||
1276 | Provide detailed information about an object. |
|
|||
1277 |
|
||||
1278 | '%pinfo object' is just a synonym for object? or ?object. |
|
|||
1279 |
|
||||
1280 | **%popd**:: |
|
|||
1281 |
|
||||
1282 | Change to directory popped off the top of the stack. |
|
|||
1283 |
|
||||
1284 | **%profile**:: |
|
|||
1285 |
|
||||
1286 | Print your currently active IPyhton profile. |
|
|||
1287 |
|
||||
1288 | **%prun**:: |
|
|||
1289 |
|
||||
1290 | Run a statement through the python code profiler. |
|
|||
1291 |
|
||||
1292 | Usage:\ |
|
|||
1293 | %prun [options] statement |
|
|||
1294 |
|
||||
1295 | The given statement (which doesn't require quote marks) is run via the |
|
|||
1296 | python profiler in a manner similar to the profile.run() function. |
|
|||
1297 | Namespaces are internally managed to work correctly; profile.run |
|
|||
1298 | cannot be used in IPython because it makes certain assumptions about |
|
|||
1299 | namespaces which do not hold under IPython. |
|
|||
1300 |
|
||||
1301 | Options: |
|
|||
1302 |
|
||||
1303 | -l <limit>: you can place restrictions on what or how much of the |
|
|||
1304 | profile gets printed. The limit value can be: |
|
|||
1305 |
|
||||
1306 | * A string: only information for function names containing this string |
|
|||
1307 | is printed. |
|
|||
1308 |
|
||||
1309 | * An integer: only these many lines are printed. |
|
|||
1310 |
|
||||
1311 | * A float (between 0 and 1): this fraction of the report is printed |
|
|||
1312 | (for example, use a limit of 0.4 to see the topmost 40% only). |
|
|||
1313 |
|
||||
1314 | You can combine several limits with repeated use of the option. For |
|
|||
1315 | example, '-l __init__ -l 5' will print only the topmost 5 lines of |
|
|||
1316 | information about class constructors. |
|
|||
1317 |
|
||||
1318 | -r: return the pstats.Stats object generated by the profiling. This |
|
|||
1319 | object has all the information about the profile in it, and you can |
|
|||
1320 | later use it for further analysis or in other functions. |
|
|||
1321 |
|
||||
1322 | -s <key>: sort profile by given key. You can provide more than one key |
|
|||
1323 | by using the option several times: '-s key1 -s key2 -s key3...'. The |
|
|||
1324 | default sorting key is 'time'. |
|
|||
1325 |
|
||||
1326 | The following is copied verbatim from the profile documentation |
|
|||
1327 | referenced below: |
|
|||
1328 |
|
||||
1329 | When more than one key is provided, additional keys are used as |
|
|||
1330 | secondary criteria when the there is equality in all keys selected |
|
|||
1331 | before them. |
|
|||
1332 |
|
||||
1333 | Abbreviations can be used for any key names, as long as the |
|
|||
1334 | abbreviation is unambiguous. The following are the keys currently |
|
|||
1335 | defined: |
|
|||
1336 |
|
||||
1337 | Valid Arg Meaning\ |
|
|||
1338 | "calls" call count\ |
|
|||
1339 | "cumulative" cumulative time\ |
|
|||
1340 | "file" file name\ |
|
|||
1341 | "module" file name\ |
|
|||
1342 | "pcalls" primitive call count\ |
|
|||
1343 | "line" line number\ |
|
|||
1344 | "name" function name\ |
|
|||
1345 | "nfl" name/file/line\ |
|
|||
1346 | "stdname" standard name\ |
|
|||
1347 | "time" internal time |
|
|||
1348 |
|
||||
1349 | Note that all sorts on statistics are in descending order (placing |
|
|||
1350 | most time consuming items first), where as name, file, and line number |
|
|||
1351 | searches are in ascending order (i.e., alphabetical). The subtle |
|
|||
1352 | distinction between "nfl" and "stdname" is that the standard name is a |
|
|||
1353 | sort of the name as printed, which means that the embedded line |
|
|||
1354 | numbers get compared in an odd way. For example, lines 3, 20, and 40 |
|
|||
1355 | would (if the file names were the same) appear in the string order |
|
|||
1356 | "20" "3" and "40". In contrast, "nfl" does a numeric compare of the |
|
|||
1357 | line numbers. In fact, sort_stats("nfl") is the same as |
|
|||
1358 | sort_stats("name", "file", "line"). |
|
|||
1359 |
|
||||
1360 | -T <filename>: save profile results as shown on screen to a text |
|
|||
1361 | file. The profile is still shown on screen. |
|
|||
1362 |
|
||||
1363 | -D <filename>: save (via dump_stats) profile statistics to given |
|
|||
1364 | filename. This data is in a format understod by the pstats module, and |
|
|||
1365 | is generated by a call to the dump_stats() method of profile |
|
|||
1366 | objects. The profile is still shown on screen. |
|
|||
1367 |
|
||||
1368 | If you want to run complete programs under the profiler's control, use |
|
|||
1369 | '%run -p [prof_opts] filename.py [args to program]' where prof_opts |
|
|||
1370 | contains profiler specific options as described here. |
|
|||
1371 |
|
||||
1372 | You can read the complete documentation for the profile module with:\ |
|
|||
1373 | In [1]: import profile; profile.help() |
|
|||
1374 |
|
||||
1375 | **%psearch**:: |
|
|||
1376 |
|
||||
1377 | Search for object in namespaces by wildcard. |
|
|||
1378 |
|
||||
1379 | %psearch [options] PATTERN [OBJECT TYPE] |
|
|||
1380 |
|
||||
1381 | Note: ? can be used as a synonym for %psearch, at the beginning or at |
|
|||
1382 | the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the |
|
|||
1383 | rest of the command line must be unchanged (options come first), so |
|
|||
1384 | for example the following forms are equivalent |
|
|||
1385 |
|
||||
1386 | %psearch -i a* function |
|
|||
1387 | -i a* function? |
|
|||
1388 | ?-i a* function |
|
|||
1389 |
|
||||
1390 | Arguments: |
|
|||
1391 |
|
||||
1392 | PATTERN |
|
|||
1393 |
|
||||
1394 | where PATTERN is a string containing * as a wildcard similar to its |
|
|||
1395 | use in a shell. The pattern is matched in all namespaces on the |
|
|||
1396 | search path. By default objects starting with a single _ are not |
|
|||
1397 | matched, many IPython generated objects have a single |
|
|||
1398 | underscore. The default is case insensitive matching. Matching is |
|
|||
1399 | also done on the attributes of objects and not only on the objects |
|
|||
1400 | in a module. |
|
|||
1401 |
|
||||
1402 | [OBJECT TYPE] |
|
|||
1403 |
|
||||
1404 | Is the name of a python type from the types module. The name is |
|
|||
1405 | given in lowercase without the ending type, ex. StringType is |
|
|||
1406 | written string. By adding a type here only objects matching the |
|
|||
1407 | given type are matched. Using all here makes the pattern match all |
|
|||
1408 | types (this is the default). |
|
|||
1409 |
|
||||
1410 | Options: |
|
|||
1411 |
|
||||
1412 | -a: makes the pattern match even objects whose names start with a |
|
|||
1413 | single underscore. These names are normally ommitted from the |
|
|||
1414 | search. |
|
|||
1415 |
|
||||
1416 | -i/-c: make the pattern case insensitive/sensitive. If neither of |
|
|||
1417 | these options is given, the default is read from your ipythonrc |
|
|||
1418 | file. The option name which sets this value is |
|
|||
1419 | 'wildcards_case_sensitive'. If this option is not specified in your |
|
|||
1420 | ipythonrc file, IPython's internal default is to do a case sensitive |
|
|||
1421 | search. |
|
|||
1422 |
|
||||
1423 | -e/-s NAMESPACE: exclude/search a given namespace. The pattern you |
|
|||
1424 | specifiy can be searched in any of the following namespaces: |
|
|||
1425 | 'builtin', 'user', 'user_global','internal', 'alias', where |
|
|||
1426 | 'builtin' and 'user' are the search defaults. Note that you should |
|
|||
1427 | not use quotes when specifying namespaces. |
|
|||
1428 |
|
||||
1429 | 'Builtin' contains the python module builtin, 'user' contains all |
|
|||
1430 | user data, 'alias' only contain the shell aliases and no python |
|
|||
1431 | objects, 'internal' contains objects used by IPython. The |
|
|||
1432 | 'user_global' namespace is only used by embedded IPython instances, |
|
|||
1433 | and it contains module-level globals. You can add namespaces to the |
|
|||
1434 | search with -s or exclude them with -e (these options can be given |
|
|||
1435 | more than once). |
|
|||
1436 |
|
||||
1437 | Examples: |
|
|||
1438 |
|
||||
1439 | %psearch a* -> objects beginning with an a |
|
|||
1440 | %psearch -e builtin a* -> objects NOT in the builtin space starting in a |
|
|||
1441 | %psearch a* function -> all functions beginning with an a |
|
|||
1442 | %psearch re.e* -> objects beginning with an e in module re |
|
|||
1443 | %psearch r*.e* -> objects that start with e in modules starting in r |
|
|||
1444 | %psearch r*.* string -> all strings in modules beginning with r |
|
|||
1445 |
|
||||
1446 | Case sensitve search: |
|
|||
1447 |
|
||||
1448 | %psearch -c a* list all object beginning with lower case a |
|
|||
1449 |
|
||||
1450 | Show objects beginning with a single _: |
|
|||
1451 |
|
||||
1452 | %psearch -a _* list objects beginning with a single underscore |
|
|||
1453 |
|
||||
1454 | **%psource**:: |
|
|||
1455 |
|
||||
1456 | Print (or run through pager) the source code for an object. |
|
|||
1457 |
|
||||
1458 | **%pushd**:: |
|
|||
1459 |
|
||||
1460 | Place the current dir on stack and change directory. |
|
|||
1461 |
|
||||
1462 | Usage:\ |
|
|||
1463 | %pushd ['dirname'] |
|
|||
1464 |
|
||||
1465 | **%pwd**:: |
|
|||
1466 |
|
||||
1467 | Return the current working directory path. |
|
|||
1468 |
|
||||
1469 | **%pycat**:: |
|
|||
1470 |
|
||||
1471 | Show a syntax-highlighted file through a pager. |
|
|||
1472 |
|
||||
1473 | This magic is similar to the cat utility, but it will assume the file |
|
|||
1474 | to be Python source and will show it with syntax highlighting. |
|
|||
1475 |
|
||||
1476 | **%quickref**:: |
|
|||
1477 |
|
||||
1478 | Show a quick reference sheet |
|
|||
1479 |
|
||||
1480 | **%quit**:: |
|
|||
1481 |
|
||||
1482 | Exit IPython, confirming if configured to do so (like %exit) |
|
|||
1483 |
|
||||
1484 | **%r**:: |
|
|||
1485 |
|
||||
1486 | Repeat previous input. |
|
|||
1487 |
|
||||
1488 | Note: Consider using the more powerfull %rep instead! |
|
|||
1489 |
|
||||
1490 | If given an argument, repeats the previous command which starts with |
|
|||
1491 | the same string, otherwise it just repeats the previous input. |
|
|||
1492 |
|
||||
1493 | Shell escaped commands (with ! as first character) are not recognized |
|
|||
1494 | by this system, only pure python code and magic commands. |
|
|||
1495 |
|
||||
1496 | **%rehashdir**:: |
|
|||
1497 |
|
||||
1498 | Add executables in all specified dirs to alias table |
|
|||
1499 |
|
||||
1500 | Usage: |
|
|||
1501 |
|
||||
1502 | %rehashdir c:/bin;c:/tools |
|
|||
1503 | - Add all executables under c:/bin and c:/tools to alias table, in |
|
|||
1504 | order to make them directly executable from any directory. |
|
|||
1505 |
|
||||
1506 | Without arguments, add all executables in current directory. |
|
|||
1507 |
|
||||
1508 | **%rehashx**:: |
|
|||
1509 |
|
||||
1510 | Update the alias table with all executable files in $PATH. |
|
|||
1511 |
|
||||
1512 | This version explicitly checks that every entry in $PATH is a file |
|
|||
1513 | with execute access (os.X_OK), so it is much slower than %rehash. |
|
|||
1514 |
|
||||
1515 | Under Windows, it checks executability as a match agains a |
|
|||
1516 | '|'-separated string of extensions, stored in the IPython config |
|
|||
1517 | variable win_exec_ext. This defaults to 'exe|com|bat'. |
|
|||
1518 |
|
||||
1519 | This function also resets the root module cache of module completer, |
|
|||
1520 | used on slow filesystems. |
|
|||
1521 |
|
||||
1522 | **%rep**:: |
|
|||
1523 |
|
||||
1524 | Repeat a command, or get command to input line for editing |
|
|||
1525 |
|
||||
1526 | - %rep (no arguments): |
|
|||
1527 |
|
||||
1528 | Place a string version of last computation result (stored in the special '_' |
|
|||
1529 | variable) to the next input prompt. Allows you to create elaborate command |
|
|||
1530 | lines without using copy-paste:: |
|
|||
1531 |
|
||||
1532 | $ l = ["hei", "vaan"] |
|
|||
1533 | $ "".join(l) |
|
|||
1534 | ==> heivaan |
|
|||
1535 | $ %rep |
|
|||
1536 | $ heivaan_ <== cursor blinking |
|
|||
1537 |
|
||||
1538 | %rep 45 |
|
|||
1539 |
|
||||
1540 | Place history line 45 to next input prompt. Use %hist to find out the |
|
|||
1541 | number. |
|
|||
1542 |
|
||||
1543 | %rep 1-4 6-7 3 |
|
|||
1544 |
|
||||
1545 | Repeat the specified lines immediately. Input slice syntax is the same as |
|
|||
1546 | in %macro and %save. |
|
|||
1547 |
|
||||
1548 | %rep foo |
|
|||
1549 |
|
||||
1550 | Place the most recent line that has the substring "foo" to next input. |
|
|||
1551 | (e.g. 'svn ci -m foobar'). |
|
|||
1552 |
|
||||
1553 | **%reset**:: |
|
|||
1554 |
|
||||
1555 | Resets the namespace by removing all names defined by the user. |
|
|||
1556 |
|
||||
1557 | Input/Output history are left around in case you need them. |
|
|||
1558 |
|
||||
1559 | **%run**:: |
|
|||
1560 |
|
||||
1561 | Run the named file inside IPython as a program. |
|
|||
1562 |
|
||||
1563 | Usage:\ |
|
|||
1564 | %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args] |
|
|||
1565 |
|
||||
1566 | Parameters after the filename are passed as command-line arguments to |
|
|||
1567 | the program (put in sys.argv). Then, control returns to IPython's |
|
|||
1568 | prompt. |
|
|||
1569 |
|
||||
1570 | This is similar to running at a system prompt:\ |
|
|||
1571 | $ python file args\ |
|
|||
1572 | but with the advantage of giving you IPython's tracebacks, and of |
|
|||
1573 | loading all variables into your interactive namespace for further use |
|
|||
1574 | (unless -p is used, see below). |
|
|||
1575 |
|
||||
1576 | The file is executed in a namespace initially consisting only of |
|
|||
1577 | __name__=='__main__' and sys.argv constructed as indicated. It thus |
|
|||
1578 | sees its environment as if it were being run as a stand-alone program |
|
|||
1579 | (except for sharing global objects such as previously imported |
|
|||
1580 | modules). But after execution, the IPython interactive namespace gets |
|
|||
1581 | updated with all variables defined in the program (except for __name__ |
|
|||
1582 | and sys.argv). This allows for very convenient loading of code for |
|
|||
1583 | interactive work, while giving each program a 'clean sheet' to run in. |
|
|||
1584 |
|
||||
1585 | Options: |
|
|||
1586 |
|
||||
1587 | -n: __name__ is NOT set to '__main__', but to the running file's name |
|
|||
1588 | without extension (as python does under import). This allows running |
|
|||
1589 | scripts and reloading the definitions in them without calling code |
|
|||
1590 | protected by an ' if __name__ == "__main__" ' clause. |
|
|||
1591 |
|
||||
1592 | -i: run the file in IPython's namespace instead of an empty one. This |
|
|||
1593 | is useful if you are experimenting with code written in a text editor |
|
|||
1594 | which depends on variables defined interactively. |
|
|||
1595 |
|
||||
1596 | -e: ignore sys.exit() calls or SystemExit exceptions in the script |
|
|||
1597 | being run. This is particularly useful if IPython is being used to |
|
|||
1598 | run unittests, which always exit with a sys.exit() call. In such |
|
|||
1599 | cases you are interested in the output of the test results, not in |
|
|||
1600 | seeing a traceback of the unittest module. |
|
|||
1601 |
|
||||
1602 | -t: print timing information at the end of the run. IPython will give |
|
|||
1603 | you an estimated CPU time consumption for your script, which under |
|
|||
1604 | Unix uses the resource module to avoid the wraparound problems of |
|
|||
1605 | time.clock(). Under Unix, an estimate of time spent on system tasks |
|
|||
1606 | is also given (for Windows platforms this is reported as 0.0). |
|
|||
1607 |
|
||||
1608 | If -t is given, an additional -N<N> option can be given, where <N> |
|
|||
1609 | must be an integer indicating how many times you want the script to |
|
|||
1610 | run. The final timing report will include total and per run results. |
|
|||
1611 |
|
||||
1612 | For example (testing the script uniq_stable.py): |
|
|||
1613 |
|
||||
1614 | In [1]: run -t uniq_stable |
|
|||
1615 |
|
||||
1616 | IPython CPU timings (estimated):\ |
|
|||
1617 | User : 0.19597 s.\ |
|
|||
1618 | System: 0.0 s.\ |
|
|||
1619 |
|
||||
1620 | In [2]: run -t -N5 uniq_stable |
|
|||
1621 |
|
||||
1622 | IPython CPU timings (estimated):\ |
|
|||
1623 | Total runs performed: 5\ |
|
|||
1624 | Times : Total Per run\ |
|
|||
1625 | User : 0.910862 s, 0.1821724 s.\ |
|
|||
1626 | System: 0.0 s, 0.0 s. |
|
|||
1627 |
|
||||
1628 | -d: run your program under the control of pdb, the Python debugger. |
|
|||
1629 | This allows you to execute your program step by step, watch variables, |
|
|||
1630 | etc. Internally, what IPython does is similar to calling: |
|
|||
1631 |
|
||||
1632 | pdb.run('execfile("YOURFILENAME")') |
|
|||
1633 |
|
||||
1634 | with a breakpoint set on line 1 of your file. You can change the line |
|
|||
1635 | number for this automatic breakpoint to be <N> by using the -bN option |
|
|||
1636 | (where N must be an integer). For example: |
|
|||
1637 |
|
||||
1638 | %run -d -b40 myscript |
|
|||
1639 |
|
||||
1640 | will set the first breakpoint at line 40 in myscript.py. Note that |
|
|||
1641 | the first breakpoint must be set on a line which actually does |
|
|||
1642 | something (not a comment or docstring) for it to stop execution. |
|
|||
1643 |
|
||||
1644 | When the pdb debugger starts, you will see a (Pdb) prompt. You must |
|
|||
1645 | first enter 'c' (without qoutes) to start execution up to the first |
|
|||
1646 | breakpoint. |
|
|||
1647 |
|
||||
1648 | Entering 'help' gives information about the use of the debugger. You |
|
|||
1649 | can easily see pdb's full documentation with "import pdb;pdb.help()" |
|
|||
1650 | at a prompt. |
|
|||
1651 |
|
||||
1652 | -p: run program under the control of the Python profiler module (which |
|
|||
1653 | prints a detailed report of execution times, function calls, etc). |
|
|||
1654 |
|
||||
1655 | You can pass other options after -p which affect the behavior of the |
|
|||
1656 | profiler itself. See the docs for %prun for details. |
|
|||
1657 |
|
||||
1658 | In this mode, the program's variables do NOT propagate back to the |
|
|||
1659 | IPython interactive namespace (because they remain in the namespace |
|
|||
1660 | where the profiler executes them). |
|
|||
1661 |
|
||||
1662 | Internally this triggers a call to %prun, see its documentation for |
|
|||
1663 | details on the options available specifically for profiling. |
|
|||
1664 |
|
||||
1665 | There is one special usage for which the text above doesn't apply: |
|
|||
1666 | if the filename ends with .ipy, the file is run as ipython script, |
|
|||
1667 | just as if the commands were written on IPython prompt. |
|
|||
1668 |
|
||||
1669 | **%runlog**:: |
|
|||
1670 |
|
||||
1671 | Run files as logs. |
|
|||
1672 |
|
||||
1673 | Usage:\ |
|
|||
1674 | %runlog file1 file2 ... |
|
|||
1675 |
|
||||
1676 | Run the named files (treating them as log files) in sequence inside |
|
|||
1677 | the interpreter, and return to the prompt. This is much slower than |
|
|||
1678 | %run because each line is executed in a try/except block, but it |
|
|||
1679 | allows running files with syntax errors in them. |
|
|||
1680 |
|
||||
1681 | Normally IPython will guess when a file is one of its own logfiles, so |
|
|||
1682 | you can typically use %run even for logs. This shorthand allows you to |
|
|||
1683 | force any file to be treated as a log file. |
|
|||
1684 |
|
||||
1685 | **%save**:: |
|
|||
1686 |
|
||||
1687 | Save a set of lines to a given filename. |
|
|||
1688 |
|
||||
1689 | Usage:\ |
|
|||
1690 | %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ... |
|
|||
1691 |
|
||||
1692 | Options: |
|
|||
1693 |
|
||||
1694 | -r: use 'raw' input. By default, the 'processed' history is used, |
|
|||
1695 | so that magics are loaded in their transformed version to valid |
|
|||
1696 | Python. If this option is given, the raw input as typed as the |
|
|||
1697 | command line is used instead. |
|
|||
1698 |
|
||||
1699 | This function uses the same syntax as %macro for line extraction, but |
|
|||
1700 | instead of creating a macro it saves the resulting string to the |
|
|||
1701 | filename you specify. |
|
|||
1702 |
|
||||
1703 | It adds a '.py' extension to the file if you don't do so yourself, and |
|
|||
1704 | it asks for confirmation before overwriting existing files. |
|
|||
1705 |
|
||||
1706 | **%sc**:: |
|
|||
1707 |
|
||||
1708 | Shell capture - execute a shell command and capture its output. |
|
|||
1709 |
|
||||
1710 | DEPRECATED. Suboptimal, retained for backwards compatibility. |
|
|||
1711 |
|
||||
1712 | You should use the form 'var = !command' instead. Example: |
|
|||
1713 |
|
||||
1714 | "%sc -l myfiles = ls ~" should now be written as |
|
|||
1715 |
|
||||
1716 | "myfiles = !ls ~" |
|
|||
1717 |
|
||||
1718 | myfiles.s, myfiles.l and myfiles.n still apply as documented |
|
|||
1719 | below. |
|
|||
1720 |
|
||||
1721 | -- |
|
|||
1722 | %sc [options] varname=command |
|
|||
1723 |
|
||||
1724 | IPython will run the given command using commands.getoutput(), and |
|
|||
1725 | will then update the user's interactive namespace with a variable |
|
|||
1726 | called varname, containing the value of the call. Your command can |
|
|||
1727 | contain shell wildcards, pipes, etc. |
|
|||
1728 |
|
||||
1729 | The '=' sign in the syntax is mandatory, and the variable name you |
|
|||
1730 | supply must follow Python's standard conventions for valid names. |
|
|||
1731 |
|
||||
1732 | (A special format without variable name exists for internal use) |
|
|||
1733 |
|
||||
1734 | Options: |
|
|||
1735 |
|
||||
1736 | -l: list output. Split the output on newlines into a list before |
|
|||
1737 | assigning it to the given variable. By default the output is stored |
|
|||
1738 | as a single string. |
|
|||
1739 |
|
||||
1740 | -v: verbose. Print the contents of the variable. |
|
|||
1741 |
|
||||
1742 | In most cases you should not need to split as a list, because the |
|
|||
1743 | returned value is a special type of string which can automatically |
|
|||
1744 | provide its contents either as a list (split on newlines) or as a |
|
|||
1745 | space-separated string. These are convenient, respectively, either |
|
|||
1746 | for sequential processing or to be passed to a shell command. |
|
|||
1747 |
|
||||
1748 | For example: |
|
|||
1749 |
|
||||
1750 | # Capture into variable a |
|
|||
1751 | In [9]: sc a=ls *py |
|
|||
1752 |
|
||||
1753 | # a is a string with embedded newlines |
|
|||
1754 | In [10]: a |
|
|||
1755 | Out[10]: 'setup.py win32_manual_post_install.py' |
|
|||
1756 |
|
||||
1757 | # which can be seen as a list: |
|
|||
1758 | In [11]: a.l |
|
|||
1759 | Out[11]: ['setup.py', 'win32_manual_post_install.py'] |
|
|||
1760 |
|
||||
1761 | # or as a whitespace-separated string: |
|
|||
1762 | In [12]: a.s |
|
|||
1763 | Out[12]: 'setup.py win32_manual_post_install.py' |
|
|||
1764 |
|
||||
1765 | # a.s is useful to pass as a single command line: |
|
|||
1766 | In [13]: !wc -l $a.s |
|
|||
1767 | 146 setup.py |
|
|||
1768 | 130 win32_manual_post_install.py |
|
|||
1769 | 276 total |
|
|||
1770 |
|
||||
1771 | # while the list form is useful to loop over: |
|
|||
1772 | In [14]: for f in a.l: |
|
|||
1773 | ....: !wc -l $f |
|
|||
1774 | ....: |
|
|||
1775 | 146 setup.py |
|
|||
1776 | 130 win32_manual_post_install.py |
|
|||
1777 |
|
||||
1778 | Similiarly, the lists returned by the -l option are also special, in |
|
|||
1779 | the sense that you can equally invoke the .s attribute on them to |
|
|||
1780 | automatically get a whitespace-separated string from their contents: |
|
|||
1781 |
|
||||
1782 | In [1]: sc -l b=ls *py |
|
|||
1783 |
|
||||
1784 | In [2]: b |
|
|||
1785 | Out[2]: ['setup.py', 'win32_manual_post_install.py'] |
|
|||
1786 |
|
||||
1787 | In [3]: b.s |
|
|||
1788 | Out[3]: 'setup.py win32_manual_post_install.py' |
|
|||
1789 |
|
||||
1790 | In summary, both the lists and strings used for ouptut capture have |
|
|||
1791 | the following special attributes: |
|
|||
1792 |
|
||||
1793 | .l (or .list) : value as list. |
|
|||
1794 | .n (or .nlstr): value as newline-separated string. |
|
|||
1795 | .s (or .spstr): value as space-separated string. |
|
|||
1796 |
|
||||
1797 | **%store**:: |
|
|||
1798 |
|
||||
1799 | Lightweight persistence for python variables. |
|
|||
1800 |
|
||||
1801 | Example: |
|
|||
1802 |
|
||||
1803 | ville@badger[~]|1> A = ['hello',10,'world']\ |
|
|||
1804 | ville@badger[~]|2> %store A\ |
|
|||
1805 | ville@badger[~]|3> Exit |
|
|||
1806 |
|
||||
1807 | (IPython session is closed and started again...) |
|
|||
1808 |
|
||||
1809 | ville@badger:~$ ipython -p pysh\ |
|
|||
1810 | ville@badger[~]|1> print A |
|
|||
1811 |
|
||||
1812 | ['hello', 10, 'world'] |
|
|||
1813 |
|
||||
1814 | Usage: |
|
|||
1815 |
|
||||
1816 | %store - Show list of all variables and their current values\ |
|
|||
1817 | %store <var> - Store the *current* value of the variable to disk\ |
|
|||
1818 | %store -d <var> - Remove the variable and its value from storage\ |
|
|||
1819 | %store -z - Remove all variables from storage\ |
|
|||
1820 | %store -r - Refresh all variables from store (delete current vals)\ |
|
|||
1821 | %store foo >a.txt - Store value of foo to new file a.txt\ |
|
|||
1822 | %store foo >>a.txt - Append value of foo to file a.txt\ |
|
|||
1823 |
|
||||
1824 | It should be noted that if you change the value of a variable, you |
|
|||
1825 | need to %store it again if you want to persist the new value. |
|
|||
1826 |
|
||||
1827 | Note also that the variables will need to be pickleable; most basic |
|
|||
1828 | python types can be safely %stored. |
|
|||
1829 |
|
||||
1830 | Also aliases can be %store'd across sessions. |
|
|||
1831 |
|
||||
1832 | **%sx**:: |
|
|||
1833 |
|
||||
1834 | Shell execute - run a shell command and capture its output. |
|
|||
1835 |
|
||||
1836 | %sx command |
|
|||
1837 |
|
||||
1838 | IPython will run the given command using commands.getoutput(), and |
|
|||
1839 | return the result formatted as a list (split on '\n'). Since the |
|
|||
1840 | output is _returned_, it will be stored in ipython's regular output |
|
|||
1841 | cache Out[N] and in the '_N' automatic variables. |
|
|||
1842 |
|
||||
1843 | Notes: |
|
|||
1844 |
|
||||
1845 | 1) If an input line begins with '!!', then %sx is automatically |
|
|||
1846 | invoked. That is, while: |
|
|||
1847 | !ls |
|
|||
1848 | causes ipython to simply issue system('ls'), typing |
|
|||
1849 | !!ls |
|
|||
1850 | is a shorthand equivalent to: |
|
|||
1851 | %sx ls |
|
|||
1852 |
|
||||
1853 | 2) %sx differs from %sc in that %sx automatically splits into a list, |
|
|||
1854 | like '%sc -l'. The reason for this is to make it as easy as possible |
|
|||
1855 | to process line-oriented shell output via further python commands. |
|
|||
1856 | %sc is meant to provide much finer control, but requires more |
|
|||
1857 | typing. |
|
|||
1858 |
|
||||
1859 | 3) Just like %sc -l, this is a list with special attributes: |
|
|||
1860 |
|
||||
1861 | .l (or .list) : value as list. |
|
|||
1862 | .n (or .nlstr): value as newline-separated string. |
|
|||
1863 | .s (or .spstr): value as whitespace-separated string. |
|
|||
1864 |
|
||||
1865 | This is very useful when trying to use such lists as arguments to |
|
|||
1866 | system commands. |
|
|||
1867 |
|
||||
1868 | **%system_verbose**:: |
|
|||
1869 |
|
||||
1870 | Set verbose printing of system calls. |
|
|||
1871 |
|
||||
1872 | If called without an argument, act as a toggle |
|
|||
1873 |
|
||||
1874 | **%time**:: |
|
|||
1875 |
|
||||
1876 | Time execution of a Python statement or expression. |
|
|||
1877 |
|
||||
1878 | The CPU and wall clock times are printed, and the value of the |
|
|||
1879 | expression (if any) is returned. Note that under Win32, system time |
|
|||
1880 | is always reported as 0, since it can not be measured. |
|
|||
1881 |
|
||||
1882 | This function provides very basic timing functionality. In Python |
|
|||
1883 | 2.3, the timeit module offers more control and sophistication, so this |
|
|||
1884 | could be rewritten to use it (patches welcome). |
|
|||
1885 |
|
||||
1886 | Some examples: |
|
|||
1887 |
|
||||
1888 | In [1]: time 2**128 |
|
|||
1889 | CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s |
|
|||
1890 | Wall time: 0.00 |
|
|||
1891 | Out[1]: 340282366920938463463374607431768211456L |
|
|||
1892 |
|
||||
1893 | In [2]: n = 1000000 |
|
|||
1894 |
|
||||
1895 | In [3]: time sum(range(n)) |
|
|||
1896 | CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s |
|
|||
1897 | Wall time: 1.37 |
|
|||
1898 | Out[3]: 499999500000L |
|
|||
1899 |
|
||||
1900 | In [4]: time print 'hello world' |
|
|||
1901 | hello world |
|
|||
1902 | CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s |
|
|||
1903 | Wall time: 0.00 |
|
|||
1904 |
|
||||
1905 | Note that the time needed by Python to compile the given expression |
|
|||
1906 | will be reported if it is more than 0.1s. In this example, the |
|
|||
1907 | actual exponentiation is done by Python at compilation time, so while |
|
|||
1908 | the expression can take a noticeable amount of time to compute, that |
|
|||
1909 | time is purely due to the compilation: |
|
|||
1910 |
|
||||
1911 | In [5]: time 3**9999; |
|
|||
1912 | CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s |
|
|||
1913 | Wall time: 0.00 s |
|
|||
1914 |
|
||||
1915 | In [6]: time 3**999999; |
|
|||
1916 | CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s |
|
|||
1917 | Wall time: 0.00 s |
|
|||
1918 | Compiler : 0.78 s |
|
|||
1919 |
|
||||
1920 | **%timeit**:: |
|
|||
1921 |
|
||||
1922 | Time execution of a Python statement or expression |
|
|||
1923 |
|
||||
1924 | Usage:\ |
|
|||
1925 | %timeit [-n<N> -r<R> [-t|-c]] statement |
|
|||
1926 |
|
||||
1927 | Time execution of a Python statement or expression using the timeit |
|
|||
1928 | module. |
|
|||
1929 |
|
||||
1930 | Options: |
|
|||
1931 | -n<N>: execute the given statement <N> times in a loop. If this value |
|
|||
1932 | is not given, a fitting value is chosen. |
|
|||
1933 |
|
||||
1934 | -r<R>: repeat the loop iteration <R> times and take the best result. |
|
|||
1935 | Default: 3 |
|
|||
1936 |
|
||||
1937 | -t: use time.time to measure the time, which is the default on Unix. |
|
|||
1938 | This function measures wall time. |
|
|||
1939 |
|
||||
1940 | -c: use time.clock to measure the time, which is the default on |
|
|||
1941 | Windows and measures wall time. On Unix, resource.getrusage is used |
|
|||
1942 | instead and returns the CPU user time. |
|
|||
1943 |
|
||||
1944 | -p<P>: use a precision of <P> digits to display the timing result. |
|
|||
1945 | Default: 3 |
|
|||
1946 |
|
||||
1947 |
|
||||
1948 | Examples:\ |
|
|||
1949 | In [1]: %timeit pass |
|
|||
1950 | 10000000 loops, best of 3: 53.3 ns per loop |
|
|||
1951 |
|
||||
1952 | In [2]: u = None |
|
|||
1953 |
|
||||
1954 | In [3]: %timeit u is None |
|
|||
1955 | 10000000 loops, best of 3: 184 ns per loop |
|
|||
1956 |
|
||||
1957 | In [4]: %timeit -r 4 u == None |
|
|||
1958 | 1000000 loops, best of 4: 242 ns per loop |
|
|||
1959 |
|
||||
1960 | In [5]: import time |
|
|||
1961 |
|
||||
1962 | In [6]: %timeit -n1 time.sleep(2) |
|
|||
1963 | 1 loops, best of 3: 2 s per loop |
|
|||
1964 |
|
||||
1965 |
|
||||
1966 | The times reported by %timeit will be slightly higher than those |
|
|||
1967 | reported by the timeit.py script when variables are accessed. This is |
|
|||
1968 | due to the fact that %timeit executes the statement in the namespace |
|
|||
1969 | of the shell, compared with timeit.py, which uses a single setup |
|
|||
1970 | statement to import function or create variables. Generally, the bias |
|
|||
1971 | does not matter as long as results from timeit.py are not mixed with |
|
|||
1972 | those from %timeit. |
|
|||
1973 |
|
||||
1974 | **%unalias**:: |
|
|||
1975 |
|
||||
1976 | Remove an alias |
|
|||
1977 |
|
||||
1978 | **%upgrade**:: |
|
|||
1979 |
|
||||
1980 | Upgrade your IPython installation |
|
|||
1981 |
|
||||
1982 | This will copy the config files that don't yet exist in your |
|
|||
1983 | ipython dir from the system config dir. Use this after upgrading |
|
|||
1984 | IPython if you don't wish to delete your .ipython dir. |
|
|||
1985 |
|
||||
1986 | Call with -nolegacy to get rid of ipythonrc* files (recommended for |
|
|||
1987 | new users) |
|
|||
1988 |
|
||||
1989 | **%which**:: |
|
|||
1990 |
|
||||
1991 | %which <cmd> => search PATH for files matching cmd. Also scans aliases. |
|
|||
1992 |
|
||||
1993 | Traverses PATH and prints all files (not just executables!) that match the |
|
|||
1994 | pattern on command line. Probably more useful in finding stuff |
|
|||
1995 | interactively than 'which', which only prints the first matching item. |
|
|||
1996 |
|
||||
1997 | Also discovers and expands aliases, so you'll see what will be executed |
|
|||
1998 | when you call an alias. |
|
|||
1999 |
|
||||
2000 | Example: |
|
|||
2001 |
|
||||
2002 | [~]|62> %which d |
|
|||
2003 | d -> ls -F --color=auto |
|
|||
2004 | == c:\cygwin\bin\ls.exe |
|
|||
2005 | c:\cygwin\bin\d.exe |
|
|||
2006 |
|
||||
2007 | [~]|64> %which diff* |
|
|||
2008 | diff3 -> diff3 |
|
|||
2009 | == c:\cygwin\bin\diff3.exe |
|
|||
2010 | diff -> diff |
|
|||
2011 | == c:\cygwin\bin\diff.exe |
|
|||
2012 | c:\cygwin\bin\diff.exe |
|
|||
2013 | c:\cygwin\bin\diff3.exe |
|
|||
2014 |
|
||||
2015 | **%who**:: |
|
|||
2016 |
|
||||
2017 | Print all interactive variables, with some minimal formatting. |
|
|||
2018 |
|
||||
2019 | If any arguments are given, only variables whose type matches one of |
|
|||
2020 | these are printed. For example: |
|
|||
2021 |
|
||||
2022 | %who function str |
|
|||
2023 |
|
||||
2024 | will only list functions and strings, excluding all other types of |
|
|||
2025 | variables. To find the proper type names, simply use type(var) at a |
|
|||
2026 | command line to see how python prints type names. For example: |
|
|||
2027 |
|
||||
2028 | In [1]: type('hello')\ |
|
|||
2029 | Out[1]: <type 'str'> |
|
|||
2030 |
|
||||
2031 | indicates that the type name for strings is 'str'. |
|
|||
2032 |
|
||||
2033 | %who always excludes executed names loaded through your configuration |
|
|||
2034 | file and things which are internal to IPython. |
|
|||
2035 |
|
||||
2036 | This is deliberate, as typically you may load many modules and the |
|
|||
2037 | purpose of %who is to show you only what you've manually defined. |
|
|||
2038 |
|
||||
2039 | **%who_ls**:: |
|
|||
2040 |
|
||||
2041 | Return a sorted list of all interactive variables. |
|
|||
2042 |
|
||||
2043 | If arguments are given, only variables of types matching these |
|
|||
2044 | arguments are returned. |
|
|||
2045 |
|
||||
2046 | **%whos**:: |
|
|||
2047 |
|
||||
2048 | Like %who, but gives some extra information about each variable. |
|
|||
2049 |
|
||||
2050 | The same type filtering of %who can be applied here. |
|
|||
2051 |
|
||||
2052 | For all variables, the type is printed. Additionally it prints: |
|
|||
2053 |
|
||||
2054 | - For {},[],(): their length. |
|
|||
2055 |
|
||||
2056 | - For numpy and Numeric arrays, a summary with shape, number of |
|
|||
2057 | elements, typecode and size in memory. |
|
|||
2058 |
|
||||
2059 | - Everything else: a string representation, snipping their middle if |
|
|||
2060 | too long. |
|
|||
2061 |
|
||||
2062 | **%xmode**:: |
|
|||
2063 |
|
||||
2064 | Switch modes for the exception handlers. |
|
|||
2065 |
|
||||
2066 | Valid modes: Plain, Context and Verbose. |
|
|||
2067 |
|
||||
2068 | If called without arguments, acts as a toggle. |
|
|||
2069 |
|
||||
2070 | .. magic_end |
|
|||
2071 |
|
508 | |||
2072 | Access to the standard Python help |
|
509 | Access to the standard Python help | |
2073 | ---------------------------------- |
|
510 | ---------------------------------- |
@@ -91,10 +91,10 b' Main features of the interactive shell' | |||||
91 | IPython has an internal job manager called jobs, and a |
|
91 | IPython has an internal job manager called jobs, and a | |
92 | convenience backgrounding magic function called :samp:`%bg`. |
|
92 | convenience backgrounding magic function called :samp:`%bg`. | |
93 |
|
93 | |||
94 | * The ability to expand python variables when calling the system |
|
94 | * The ability to expand python variables when calling the system shell. In a | |
95 |
shell |
|
95 | shell command, any python variable prefixed with :samp:`$` is expanded. A | |
96 |
|
|
96 | double :samp:`$$` allows passing a literal :samp:`$` to the shell (for access | |
97 |
|
|
97 | to shell and environment variables like :envvar:`PATH`). | |
98 |
|
98 | |||
99 | * Filesystem navigation, via a magic :samp:`%cd` command, along with a |
|
99 | * Filesystem navigation, via a magic :samp:`%cd` command, along with a | |
100 | persistent bookmark system (using :samp:`%bookmark`) for fast access to |
|
100 | persistent bookmark system (using :samp:`%bookmark`) for fast access to | |
@@ -150,17 +150,16 b' Main features of the interactive shell' | |||||
150 | about the local namespaces (very useful in debugging and data |
|
150 | about the local namespaces (very useful in debugging and data | |
151 | analysis situations). |
|
151 | analysis situations). | |
152 |
|
152 | |||
153 | * Easy debugger access. You can set IPython to call up an enhanced |
|
153 | * Easy debugger access. You can set IPython to call up an enhanced version of | |
154 |
|
|
154 | the Python debugger (pdb) every time there is an uncaught exception. This | |
155 |
|
|
155 | drops you inside the code which triggered the exception with all the data | |
156 | the exception with all the data live and it is possible to |
|
156 | live and it is possible to navigate the stack to rapidly isolate the source | |
157 | navigate the stack to rapidly isolate the source of a bug. The |
|
157 | of a bug. The :samp:`%run` magic command (with the :samp:`-d` option) can run | |
158 | :samp:`%run` magic command (with the :samp:`-d` option) can run any script under |
|
158 | any script under pdb's control, automatically setting initial breakpoints for | |
159 | pdb's control, automatically setting initial breakpoints for you. |
|
159 | you. This version of pdb has IPython-specific improvements, including | |
160 | This version of pdb has IPython-specific improvements, including |
|
160 | tab-completion and traceback coloring support. For even easier debugger | |
161 | tab-completion and traceback coloring support. For even easier |
|
161 | access, try :samp:`%debug` after seeing an exception. winpdb is also | |
162 | debugger access, try :samp:`%debug` after seeing an exception. winpdb is |
|
162 | supported, see ipy_winpdb extension. | |
163 | also supported, see ipy_winpdb extension. |
|
|||
164 |
|
163 | |||
165 | * Profiler support. You can run single statements (similar to |
|
164 | * Profiler support. You can run single statements (similar to | |
166 | :samp:`profile.run()`) or complete programs under the profiler's control. |
|
165 | :samp:`profile.run()`) or complete programs under the profiler's control. | |
@@ -176,10 +175,11 b' Main features of the interactive shell' | |||||
176 | Interactive parallel computing |
|
175 | Interactive parallel computing | |
177 | ============================== |
|
176 | ============================== | |
178 |
|
177 | |||
179 |
Increasingly, parallel computer hardware, such as multicore CPUs, clusters and |
|
178 | Increasingly, parallel computer hardware, such as multicore CPUs, clusters and | |
180 | architecture within IPython that allows such hardware to be used quickly and easily |
|
179 | supercomputers, is becoming ubiquitous. Over the last 3 years, we have | |
181 | from Python. Moreover, this architecture is designed to support interactive and |
|
180 | developed an architecture within IPython that allows such hardware to be used | |
182 | collaborative parallel computing. |
|
181 | quickly and easily from Python. Moreover, this architecture is designed to | |
|
182 | support interactive and collaborative parallel computing. | |||
183 |
|
183 | |||
184 | The main features of this system are: |
|
184 | The main features of this system are: | |
185 |
|
185 | |||
@@ -204,16 +204,16 b' The main features of this system are:' | |||||
204 |
|
204 | |||
205 | * Capabilities based security model with full encryption of network connections. |
|
205 | * Capabilities based security model with full encryption of network connections. | |
206 |
|
206 | |||
207 |
* Share live parallel jobs with other users securely. We call this |
|
207 | * Share live parallel jobs with other users securely. We call this | |
208 | parallel computing. |
|
208 | collaborative parallel computing. | |
209 |
|
209 | |||
210 | * Dynamically load balanced task farming system. |
|
210 | * Dynamically load balanced task farming system. | |
211 |
|
211 | |||
212 | * Robust error handling. Python exceptions raised in parallel execution are |
|
212 | * Robust error handling. Python exceptions raised in parallel execution are | |
213 | gathered and presented to the top-level code. |
|
213 | gathered and presented to the top-level code. | |
214 |
|
214 | |||
215 |
For more information, see our :ref:`overview <parallel_index>` of using IPython |
|
215 | For more information, see our :ref:`overview <parallel_index>` of using IPython | |
216 | parallel computing. |
|
216 | for parallel computing. | |
217 |
|
217 | |||
218 | Portability and Python requirements |
|
218 | Portability and Python requirements | |
219 | ----------------------------------- |
|
219 | ----------------------------------- | |
@@ -225,8 +225,7 b' work with some minor changes.' | |||||
225 | IPython is known to work on the following operating systems: |
|
225 | IPython is known to work on the following operating systems: | |
226 |
|
226 | |||
227 | * Linux |
|
227 | * Linux | |
228 | * AIX |
|
228 | * Most other Unix-like OSs (AIX, Solaris, BSD, etc.) | |
229 | * Most other Unix-like OSs (Solaris, BSD, etc.) |
|
|||
230 | * Mac OS X |
|
229 | * Mac OS X | |
231 | * Windows (CygWin, XP, Vista, etc.) |
|
230 | * Windows (CygWin, XP, Vista, etc.) | |
232 |
|
231 |
@@ -13,4 +13,4 b' Using IPython for parallel computing' | |||||
13 | parallel_task.txt |
|
13 | parallel_task.txt | |
14 | parallel_mpi.txt |
|
14 | parallel_mpi.txt | |
15 | parallel_security.txt |
|
15 | parallel_security.txt | |
16 |
|
16 | visionhpc.txt |
@@ -53,6 +53,8 b' The :command:`ipcluster` command provides a simple way of starting a controller ' | |||||
53 | 2. When engines are started using the :command:`mpirun` command that comes |
|
53 | 2. When engines are started using the :command:`mpirun` command that comes | |
54 | with most MPI [MPI]_ implementations |
|
54 | with most MPI [MPI]_ implementations | |
55 | 3. When engines are started using the PBS [PBS]_ batch system. |
|
55 | 3. When engines are started using the PBS [PBS]_ batch system. | |
|
56 | 4. When the controller is started on localhost and the engines are started on | |||
|
57 | remote nodes using :command:`ssh`. | |||
56 |
|
58 | |||
57 | .. note:: |
|
59 | .. note:: | |
58 |
|
60 | |||
@@ -66,7 +68,8 b' The :command:`ipcluster` command provides a simple way of starting a controller ' | |||||
66 | :file:`~/.ipython/security` directory live on a shared filesystem that is |
|
68 | :file:`~/.ipython/security` directory live on a shared filesystem that is | |
67 | seen by both the controller and engines. If you don't have a shared file |
|
69 | seen by both the controller and engines. If you don't have a shared file | |
68 | system you will need to use :command:`ipcontroller` and |
|
70 | system you will need to use :command:`ipcontroller` and | |
69 | :command:`ipengine` directly. |
|
71 | :command:`ipengine` directly. This constraint can be relaxed if you are | |
|
72 | using the :command:`ssh` method to start the cluster. | |||
70 |
|
73 | |||
71 | Underneath the hood, :command:`ipcluster` just uses :command:`ipcontroller` |
|
74 | Underneath the hood, :command:`ipcluster` just uses :command:`ipcontroller` | |
72 | and :command:`ipengine` to perform the steps described above. |
|
75 | and :command:`ipengine` to perform the steps described above. | |
@@ -159,6 +162,75 b' Additional command line options for this mode can be found by doing::' | |||||
159 |
|
162 | |||
160 | $ ipcluster pbs -h |
|
163 | $ ipcluster pbs -h | |
161 |
|
164 | |||
|
165 | Using :command:`ipcluster` in SSH mode | |||
|
166 | -------------------------------------- | |||
|
167 | ||||
|
168 | The SSH mode uses :command:`ssh` to execute :command:`ipengine` on remote | |||
|
169 | nodes and the :command:`ipcontroller` on localhost. | |||
|
170 | ||||
|
171 | When using using this mode it highly recommended that you have set up SSH keys and are using ssh-agent [SSH]_ for password-less logins. | |||
|
172 | ||||
|
173 | To use this mode you need a python file describing the cluster, here is an example of such a "clusterfile": | |||
|
174 | ||||
|
175 | .. sourcecode:: python | |||
|
176 | ||||
|
177 | send_furl = True | |||
|
178 | engines = { 'host1.example.com' : 2, | |||
|
179 | 'host2.example.com' : 5, | |||
|
180 | 'host3.example.com' : 1, | |||
|
181 | 'host4.example.com' : 8 } | |||
|
182 | ||||
|
183 | Since this is a regular python file usual python syntax applies. Things to note: | |||
|
184 | ||||
|
185 | * The `engines` dict, where the keys is the host we want to run engines on and | |||
|
186 | the value is the number of engines to run on that host. | |||
|
187 | * send_furl can either be `True` or `False`, if `True` it will copy over the | |||
|
188 | furl needed for :command:`ipengine` to each host. | |||
|
189 | ||||
|
190 | The ``--clusterfile`` command line option lets you specify the file to use for | |||
|
191 | the cluster definition. Once you have your cluster file and you can | |||
|
192 | :command:`ssh` into the remote hosts with out an password you are ready to | |||
|
193 | start your cluster like so: | |||
|
194 | ||||
|
195 | .. sourcecode:: bash | |||
|
196 | ||||
|
197 | $ ipcluster ssh --clusterfile /path/to/my/clusterfile.py | |||
|
198 | ||||
|
199 | ||||
|
200 | Two helper shell scripts are used to start and stop :command:`ipengine` on remote hosts: | |||
|
201 | ||||
|
202 | * sshx.sh | |||
|
203 | * engine_killer.sh | |||
|
204 | ||||
|
205 | Defaults for both of these are contained in the source code for :command:`ipcluster`. The default scripts are written to a local file in a tmep directory and then copied to a temp directory on the remote host and executed from there. On most Unix, Linux and OS X systems this is /tmp. | |||
|
206 | ||||
|
207 | The default sshx.sh is the following: | |||
|
208 | ||||
|
209 | .. sourcecode:: bash | |||
|
210 | ||||
|
211 | #!/bin/sh | |||
|
212 | "$@" &> /dev/null & | |||
|
213 | echo $! | |||
|
214 | ||||
|
215 | If you want to use a custom sshx.sh script you need to use the ``--sshx`` | |||
|
216 | option and specify the file to use. Using a custom sshx.sh file could be | |||
|
217 | helpful when you need to setup the environment on the remote host before | |||
|
218 | executing :command:`ipengine`. | |||
|
219 | ||||
|
220 | For a detailed options list: | |||
|
221 | ||||
|
222 | .. sourcecode:: bash | |||
|
223 | ||||
|
224 | $ ipcluster ssh -h | |||
|
225 | ||||
|
226 | Current limitations of the SSH mode of :command:`ipcluster` are: | |||
|
227 | ||||
|
228 | * Untested on Windows. Would require a working :command:`ssh` on Windows. | |||
|
229 | Also, we are using shell scripts to setup and execute commands on remote | |||
|
230 | hosts. | |||
|
231 | * :command:`ipcontroller` is started on localhost, with no option to start it | |||
|
232 | on a remote node. | |||
|
233 | ||||
162 | Using the :command:`ipcontroller` and :command:`ipengine` commands |
|
234 | Using the :command:`ipcontroller` and :command:`ipengine` commands | |
163 | ================================================================== |
|
235 | ================================================================== | |
164 |
|
236 | |||
@@ -249,3 +321,4 b' the log files to us will often help us to debug any problems.' | |||||
249 |
|
321 | |||
250 |
|
322 | |||
251 | .. [PBS] Portable Batch System. http://www.openpbs.org/ |
|
323 | .. [PBS] Portable Batch System. http://www.openpbs.org/ | |
|
324 | .. [SSH] SSH-Agent http://en.wikipedia.org/wiki/Ssh-agent |
@@ -39,11 +39,20 b' except ImportError:' | |||||
39 | from md5 import md5 |
|
39 | from md5 import md5 | |
40 |
|
40 | |||
41 | from docutils.nodes import Body, Element |
|
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 |
|
42 | from docutils.parsers.rst import directives | |
45 | from sphinx.roles import xfileref_role |
|
43 | from sphinx.roles import xfileref_role | |
46 |
|
44 | |||
|
45 | def my_import(name): | |||
|
46 | """Module importer - taken from the python documentation. | |||
|
47 | ||||
|
48 | This function allows importing names with dots in them.""" | |||
|
49 | ||||
|
50 | mod = __import__(name) | |||
|
51 | components = name.split('.') | |||
|
52 | for comp in components[1:]: | |||
|
53 | mod = getattr(mod, comp) | |||
|
54 | return mod | |||
|
55 | ||||
47 | class DotException(Exception): |
|
56 | class DotException(Exception): | |
48 | pass |
|
57 | pass | |
49 |
|
58 | |||
@@ -84,11 +93,15 b' class InheritanceGraph(object):' | |||||
84 | path = (path and path.rstrip('.')) |
|
93 | path = (path and path.rstrip('.')) | |
85 | if not path: |
|
94 | if not path: | |
86 | path = base |
|
95 | path = base | |
87 | if not path: |
|
|||
88 | raise ValueError( |
|
|||
89 | "Invalid class or module '%s' specified for inheritance diagram" % name) |
|
|||
90 | try: |
|
96 | try: | |
91 | module = __import__(path, None, None, []) |
|
97 | module = __import__(path, None, None, []) | |
|
98 | # We must do an import of the fully qualified name. Otherwise if a | |||
|
99 | # subpackage 'a.b' is requested where 'import a' does NOT provide | |||
|
100 | # 'a.b' automatically, then 'a.b' will not be found below. This | |||
|
101 | # second call will force the equivalent of 'import a.b' to happen | |||
|
102 | # after the top-level import above. | |||
|
103 | my_import(fullname) | |||
|
104 | ||||
92 | except ImportError: |
|
105 | except ImportError: | |
93 | raise ValueError( |
|
106 | raise ValueError( | |
94 | "Could not import class or module '%s' specified for inheritance diagram" % name) |
|
107 | "Could not import class or module '%s' specified for inheritance diagram" % name) | |
@@ -277,12 +290,16 b' class inheritance_diagram(Body, Element):' | |||||
277 | """ |
|
290 | """ | |
278 | pass |
|
291 | pass | |
279 |
|
292 | |||
280 |
def inheritance_diagram_directive |
|
293 | def inheritance_diagram_directive(name, arguments, options, content, lineno, | |
|
294 | content_offset, block_text, state, | |||
|
295 | state_machine): | |||
281 | """ |
|
296 | """ | |
282 | Run when the inheritance_diagram directive is first encountered. |
|
297 | Run when the inheritance_diagram directive is first encountered. | |
283 | """ |
|
298 | """ | |
284 | node = inheritance_diagram() |
|
299 | node = inheritance_diagram() | |
285 |
|
300 | |||
|
301 | class_names = arguments | |||
|
302 | ||||
286 | # Create a graph starting with the list of classes |
|
303 | # Create a graph starting with the list of classes | |
287 | graph = InheritanceGraph(class_names) |
|
304 | graph = InheritanceGraph(class_names) | |
288 |
|
305 | |||
@@ -315,15 +332,12 b' def html_output_graph(self, node):' | |||||
315 |
|
332 | |||
316 | graph_hash = get_graph_hash(node) |
|
333 | graph_hash = get_graph_hash(node) | |
317 | name = "inheritance%s" % graph_hash |
|
334 | name = "inheritance%s" % graph_hash | |
318 | png_path = os.path.join('_static', name + ".png") |
|
335 | path = '_images' | |
319 |
|
336 | dest_path = os.path.join(setup.app.builder.outdir, path) | ||
320 | path = '_static' |
|
337 | if not os.path.exists(dest_path): | |
321 | source = self.document.attributes['source'] |
|
338 | os.makedirs(dest_path) | |
322 | count = source.split('/doc/')[-1].count('/') |
|
339 | png_path = os.path.join(dest_path, name + ".png") | |
323 | for i in range(count): |
|
340 | path = setup.app.builder.imgpath | |
324 | if os.path.exists(path): break |
|
|||
325 | path = '../'+path |
|
|||
326 | path = '../'+path #specifically added for matplotlib |
|
|||
327 |
|
341 | |||
328 | # Create a mapping from fully-qualified class names to URLs. |
|
342 | # Create a mapping from fully-qualified class names to URLs. | |
329 | urls = {} |
|
343 | urls = {} | |
@@ -349,11 +363,14 b' def latex_output_graph(self, node):' | |||||
349 |
|
363 | |||
350 | graph_hash = get_graph_hash(node) |
|
364 | graph_hash = get_graph_hash(node) | |
351 | name = "inheritance%s" % graph_hash |
|
365 | name = "inheritance%s" % graph_hash | |
352 | pdf_path = os.path.join('_static', name + ".pdf") |
|
366 | dest_path = os.path.abspath(os.path.join(setup.app.builder.outdir, '_images')) | |
|
367 | if not os.path.exists(dest_path): | |||
|
368 | os.makedirs(dest_path) | |||
|
369 | pdf_path = os.path.abspath(os.path.join(dest_path, name + ".pdf")) | |||
353 |
|
370 | |||
354 | graph.run_dot(['-Tpdf', '-o%s' % pdf_path], |
|
371 | graph.run_dot(['-Tpdf', '-o%s' % pdf_path], | |
355 | name, parts, graph_options={'size': '"6.0,6.0"'}) |
|
372 | name, parts, graph_options={'size': '"6.0,6.0"'}) | |
356 |
return '\\includegraphics{ |
|
373 | return '\n\\includegraphics{%s}\n\n' % pdf_path | |
357 |
|
374 | |||
358 | def visit_inheritance_diagram(inner_func): |
|
375 | def visit_inheritance_diagram(inner_func): | |
359 | """ |
|
376 | """ | |
@@ -377,47 +394,14 b' def visit_inheritance_diagram(inner_func):' | |||||
377 | def do_nothing(self, node): |
|
394 | def do_nothing(self, node): | |
378 | pass |
|
395 | pass | |
379 |
|
396 | |||
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): |
|
397 | def setup(app): | |
415 | app.add_node(inheritance_diagram) |
|
398 | setup.app = app | |
416 |
|
399 | setup.confdir = app.confdir | ||
417 | HTMLTranslator.visit_inheritance_diagram = \ |
|
400 | ||
418 | visit_inheritance_diagram(html_output_graph) |
|
401 | app.add_node( | |
419 | HTMLTranslator.depart_inheritance_diagram = do_nothing |
|
402 | inheritance_diagram, | |
420 |
|
403 | latex=(visit_inheritance_diagram(latex_output_graph), do_nothing), | ||
421 | LaTeXTranslator.visit_inheritance_diagram = \ |
|
404 | html=(visit_inheritance_diagram(html_output_graph), do_nothing)) | |
422 | visit_inheritance_diagram(latex_output_graph) |
|
405 | app.add_directive( | |
423 | LaTeXTranslator.depart_inheritance_diagram = do_nothing |
|
406 | 'inheritance-diagram', inheritance_diagram_directive, | |
|
407 | False, (1, 100, 0), parts = directives.nonnegative_int) |
@@ -1,18 +1,32 b'' | |||||
|
1 | """reST directive for syntax-highlighting ipython interactive sessions. | |||
|
2 | """ | |||
|
3 | ||||
|
4 | #----------------------------------------------------------------------------- | |||
|
5 | # Needed modules | |||
|
6 | ||||
|
7 | # Standard library | |||
|
8 | import re | |||
|
9 | ||||
|
10 | # Third party | |||
1 | from pygments.lexer import Lexer, do_insertions |
|
11 | from pygments.lexer import Lexer, do_insertions | |
2 |
from pygments.lexers.agile import PythonConsoleLexer, PythonLexer, |
|
12 | from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer, | |
3 | PythonTracebackLexer |
|
13 | PythonTracebackLexer) | |
4 | from pygments.token import Comment, Generic |
|
14 | from pygments.token import Comment, Generic | |
|
15 | ||||
5 | from sphinx import highlighting |
|
16 | from sphinx import highlighting | |
6 | import re |
|
|||
7 |
|
17 | |||
|
18 | ||||
|
19 | #----------------------------------------------------------------------------- | |||
|
20 | # Global constants | |||
8 | line_re = re.compile('.*?\n') |
|
21 | line_re = re.compile('.*?\n') | |
9 |
|
22 | |||
|
23 | #----------------------------------------------------------------------------- | |||
|
24 | # Code begins - classes and functions | |||
|
25 | ||||
10 | class IPythonConsoleLexer(Lexer): |
|
26 | class IPythonConsoleLexer(Lexer): | |
11 | """ |
|
27 | """ | |
12 | For IPython console output or doctests, such as: |
|
28 | For IPython console output or doctests, such as: | |
13 |
|
29 | |||
14 | Tracebacks are not currently supported. |
|
|||
15 |
|
||||
16 | .. sourcecode:: ipython |
|
30 | .. sourcecode:: ipython | |
17 |
|
31 | |||
18 | In [1]: a = 'foo' |
|
32 | In [1]: a = 'foo' | |
@@ -24,7 +38,14 b' class IPythonConsoleLexer(Lexer):' | |||||
24 | foo |
|
38 | foo | |
25 |
|
39 | |||
26 | In [4]: 1 / 0 |
|
40 | In [4]: 1 / 0 | |
|
41 | ||||
|
42 | Notes: | |||
|
43 | ||||
|
44 | - Tracebacks are not currently supported. | |||
|
45 | ||||
|
46 | - It assumes the default IPython prompts, not customized ones. | |||
27 | """ |
|
47 | """ | |
|
48 | ||||
28 | name = 'IPython console session' |
|
49 | name = 'IPython console session' | |
29 | aliases = ['ipython'] |
|
50 | aliases = ['ipython'] | |
30 | mimetypes = ['text/x-ipython-console'] |
|
51 | mimetypes = ['text/x-ipython-console'] | |
@@ -72,4 +93,6 b' class IPythonConsoleLexer(Lexer):' | |||||
72 | pylexer.get_tokens_unprocessed(curcode)): |
|
93 | pylexer.get_tokens_unprocessed(curcode)): | |
73 | yield item |
|
94 | yield item | |
74 |
|
95 | |||
|
96 | #----------------------------------------------------------------------------- | |||
|
97 | # Register the extension as a valid pygments lexer | |||
75 | highlighting.lexers['ipython'] = IPythonConsoleLexer() |
|
98 | highlighting.lexers['ipython'] = IPythonConsoleLexer() |
1 | NO CONTENT: modified file chmod 100644 => 100755 |
|
NO CONTENT: modified file chmod 100644 => 100755 |
General Comments 0
You need to be logged in to leave comments.
Login now