##// END OF EJS Templates
Merge pull request #11853 from minho42/Fixed-typos...
Matthias Bussonnier -
r25170:56ea43f4 merge
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,1024 +1,1024 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Display formatters.
2 """Display formatters.
3
3
4 Inheritance diagram:
4 Inheritance diagram:
5
5
6 .. inheritance-diagram:: IPython.core.formatters
6 .. inheritance-diagram:: IPython.core.formatters
7 :parts: 3
7 :parts: 3
8 """
8 """
9
9
10 # Copyright (c) IPython Development Team.
10 # Copyright (c) IPython Development Team.
11 # Distributed under the terms of the Modified BSD License.
11 # Distributed under the terms of the Modified BSD License.
12
12
13 import abc
13 import abc
14 import json
14 import json
15 import sys
15 import sys
16 import traceback
16 import traceback
17 import warnings
17 import warnings
18 from io import StringIO
18 from io import StringIO
19
19
20 from decorator import decorator
20 from decorator import decorator
21
21
22 from traitlets.config.configurable import Configurable
22 from traitlets.config.configurable import Configurable
23 from IPython.core.getipython import get_ipython
23 from IPython.core.getipython import get_ipython
24 from IPython.utils.sentinel import Sentinel
24 from IPython.utils.sentinel import Sentinel
25 from IPython.utils.dir2 import get_real_method
25 from IPython.utils.dir2 import get_real_method
26 from IPython.lib import pretty
26 from IPython.lib import pretty
27 from traitlets import (
27 from traitlets import (
28 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
28 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
29 ForwardDeclaredInstance,
29 ForwardDeclaredInstance,
30 default, observe,
30 default, observe,
31 )
31 )
32
32
33
33
34 class DisplayFormatter(Configurable):
34 class DisplayFormatter(Configurable):
35
35
36 active_types = List(Unicode(),
36 active_types = List(Unicode(),
37 help="""List of currently active mime-types to display.
37 help="""List of currently active mime-types to display.
38 You can use this to set a white-list for formats to display.
38 You can use this to set a white-list for formats to display.
39
39
40 Most users will not need to change this value.
40 Most users will not need to change this value.
41 """).tag(config=True)
41 """).tag(config=True)
42
42
43 @default('active_types')
43 @default('active_types')
44 def _active_types_default(self):
44 def _active_types_default(self):
45 return self.format_types
45 return self.format_types
46
46
47 @observe('active_types')
47 @observe('active_types')
48 def _active_types_changed(self, change):
48 def _active_types_changed(self, change):
49 for key, formatter in self.formatters.items():
49 for key, formatter in self.formatters.items():
50 if key in change['new']:
50 if key in change['new']:
51 formatter.enabled = True
51 formatter.enabled = True
52 else:
52 else:
53 formatter.enabled = False
53 formatter.enabled = False
54
54
55 ipython_display_formatter = ForwardDeclaredInstance('FormatterABC')
55 ipython_display_formatter = ForwardDeclaredInstance('FormatterABC')
56 @default('ipython_display_formatter')
56 @default('ipython_display_formatter')
57 def _default_formatter(self):
57 def _default_formatter(self):
58 return IPythonDisplayFormatter(parent=self)
58 return IPythonDisplayFormatter(parent=self)
59
59
60 mimebundle_formatter = ForwardDeclaredInstance('FormatterABC')
60 mimebundle_formatter = ForwardDeclaredInstance('FormatterABC')
61 @default('mimebundle_formatter')
61 @default('mimebundle_formatter')
62 def _default_mime_formatter(self):
62 def _default_mime_formatter(self):
63 return MimeBundleFormatter(parent=self)
63 return MimeBundleFormatter(parent=self)
64
64
65 # A dict of formatter whose keys are format types (MIME types) and whose
65 # A dict of formatter whose keys are format types (MIME types) and whose
66 # values are subclasses of BaseFormatter.
66 # values are subclasses of BaseFormatter.
67 formatters = Dict()
67 formatters = Dict()
68 @default('formatters')
68 @default('formatters')
69 def _formatters_default(self):
69 def _formatters_default(self):
70 """Activate the default formatters."""
70 """Activate the default formatters."""
71 formatter_classes = [
71 formatter_classes = [
72 PlainTextFormatter,
72 PlainTextFormatter,
73 HTMLFormatter,
73 HTMLFormatter,
74 MarkdownFormatter,
74 MarkdownFormatter,
75 SVGFormatter,
75 SVGFormatter,
76 PNGFormatter,
76 PNGFormatter,
77 PDFFormatter,
77 PDFFormatter,
78 JPEGFormatter,
78 JPEGFormatter,
79 LatexFormatter,
79 LatexFormatter,
80 JSONFormatter,
80 JSONFormatter,
81 JavascriptFormatter
81 JavascriptFormatter
82 ]
82 ]
83 d = {}
83 d = {}
84 for cls in formatter_classes:
84 for cls in formatter_classes:
85 f = cls(parent=self)
85 f = cls(parent=self)
86 d[f.format_type] = f
86 d[f.format_type] = f
87 return d
87 return d
88
88
89 def format(self, obj, include=None, exclude=None):
89 def format(self, obj, include=None, exclude=None):
90 """Return a format data dict for an object.
90 """Return a format data dict for an object.
91
91
92 By default all format types will be computed.
92 By default all format types will be computed.
93
93
94 The following MIME types are usually implemented:
94 The following MIME types are usually implemented:
95
95
96 * text/plain
96 * text/plain
97 * text/html
97 * text/html
98 * text/markdown
98 * text/markdown
99 * text/latex
99 * text/latex
100 * application/json
100 * application/json
101 * application/javascript
101 * application/javascript
102 * application/pdf
102 * application/pdf
103 * image/png
103 * image/png
104 * image/jpeg
104 * image/jpeg
105 * image/svg+xml
105 * image/svg+xml
106
106
107 Parameters
107 Parameters
108 ----------
108 ----------
109 obj : object
109 obj : object
110 The Python object whose format data will be computed.
110 The Python object whose format data will be computed.
111 include : list, tuple or set; optional
111 include : list, tuple or set; optional
112 A list of format type strings (MIME types) to include in the
112 A list of format type strings (MIME types) to include in the
113 format data dict. If this is set *only* the format types included
113 format data dict. If this is set *only* the format types included
114 in this list will be computed.
114 in this list will be computed.
115 exclude : list, tuple or set; optional
115 exclude : list, tuple or set; optional
116 A list of format type string (MIME types) to exclude in the format
116 A list of format type string (MIME types) to exclude in the format
117 data dict. If this is set all format types will be computed,
117 data dict. If this is set all format types will be computed,
118 except for those included in this argument.
118 except for those included in this argument.
119 Mimetypes present in exclude will take precedence over the ones in include
119 Mimetypes present in exclude will take precedence over the ones in include
120
120
121 Returns
121 Returns
122 -------
122 -------
123 (format_dict, metadata_dict) : tuple of two dicts
123 (format_dict, metadata_dict) : tuple of two dicts
124
124
125 format_dict is a dictionary of key/value pairs, one of each format that was
125 format_dict is a dictionary of key/value pairs, one of each format that was
126 generated for the object. The keys are the format types, which
126 generated for the object. The keys are the format types, which
127 will usually be MIME type strings and the values and JSON'able
127 will usually be MIME type strings and the values and JSON'able
128 data structure containing the raw data for the representation in
128 data structure containing the raw data for the representation in
129 that format.
129 that format.
130
130
131 metadata_dict is a dictionary of metadata about each mime-type output.
131 metadata_dict is a dictionary of metadata about each mime-type output.
132 Its keys will be a strict subset of the keys in format_dict.
132 Its keys will be a strict subset of the keys in format_dict.
133
133
134 Notes
134 Notes
135 -----
135 -----
136
136
137 If an object implement `_repr_mimebundle_` as well as various
137 If an object implement `_repr_mimebundle_` as well as various
138 `_repr_*_`, the data returned by `_repr_mimebundle_` will take
138 `_repr_*_`, the data returned by `_repr_mimebundle_` will take
139 precedence and the corresponding `_repr_*_` for this mimetype will
139 precedence and the corresponding `_repr_*_` for this mimetype will
140 not be called.
140 not be called.
141
141
142 """
142 """
143 format_dict = {}
143 format_dict = {}
144 md_dict = {}
144 md_dict = {}
145
145
146 if self.ipython_display_formatter(obj):
146 if self.ipython_display_formatter(obj):
147 # object handled itself, don't proceed
147 # object handled itself, don't proceed
148 return {}, {}
148 return {}, {}
149
149
150 format_dict, md_dict = self.mimebundle_formatter(obj, include=include, exclude=exclude)
150 format_dict, md_dict = self.mimebundle_formatter(obj, include=include, exclude=exclude)
151
151
152 if format_dict or md_dict:
152 if format_dict or md_dict:
153 if include:
153 if include:
154 format_dict = {k:v for k,v in format_dict.items() if k in include}
154 format_dict = {k:v for k,v in format_dict.items() if k in include}
155 md_dict = {k:v for k,v in md_dict.items() if k in include}
155 md_dict = {k:v for k,v in md_dict.items() if k in include}
156 if exclude:
156 if exclude:
157 format_dict = {k:v for k,v in format_dict.items() if k not in exclude}
157 format_dict = {k:v for k,v in format_dict.items() if k not in exclude}
158 md_dict = {k:v for k,v in md_dict.items() if k not in exclude}
158 md_dict = {k:v for k,v in md_dict.items() if k not in exclude}
159
159
160 for format_type, formatter in self.formatters.items():
160 for format_type, formatter in self.formatters.items():
161 if format_type in format_dict:
161 if format_type in format_dict:
162 # already got it from mimebundle, maybe don't render again.
162 # already got it from mimebundle, maybe don't render again.
163 # exception: manually registered per-mime renderer
163 # exception: manually registered per-mime renderer
164 # check priority:
164 # check priority:
165 # 1. user-registered per-mime formatter
165 # 1. user-registered per-mime formatter
166 # 2. mime-bundle (user-registered or repr method)
166 # 2. mime-bundle (user-registered or repr method)
167 # 3. default per-mime formatter (e.g. repr method)
167 # 3. default per-mime formatter (e.g. repr method)
168 try:
168 try:
169 formatter.lookup(obj)
169 formatter.lookup(obj)
170 except KeyError:
170 except KeyError:
171 # no special formatter, use mime-bundle-provided value
171 # no special formatter, use mime-bundle-provided value
172 continue
172 continue
173 if include and format_type not in include:
173 if include and format_type not in include:
174 continue
174 continue
175 if exclude and format_type in exclude:
175 if exclude and format_type in exclude:
176 continue
176 continue
177
177
178 md = None
178 md = None
179 try:
179 try:
180 data = formatter(obj)
180 data = formatter(obj)
181 except:
181 except:
182 # FIXME: log the exception
182 # FIXME: log the exception
183 raise
183 raise
184
184
185 # formatters can return raw data or (data, metadata)
185 # formatters can return raw data or (data, metadata)
186 if isinstance(data, tuple) and len(data) == 2:
186 if isinstance(data, tuple) and len(data) == 2:
187 data, md = data
187 data, md = data
188
188
189 if data is not None:
189 if data is not None:
190 format_dict[format_type] = data
190 format_dict[format_type] = data
191 if md is not None:
191 if md is not None:
192 md_dict[format_type] = md
192 md_dict[format_type] = md
193 return format_dict, md_dict
193 return format_dict, md_dict
194
194
195 @property
195 @property
196 def format_types(self):
196 def format_types(self):
197 """Return the format types (MIME types) of the active formatters."""
197 """Return the format types (MIME types) of the active formatters."""
198 return list(self.formatters.keys())
198 return list(self.formatters.keys())
199
199
200
200
201 #-----------------------------------------------------------------------------
201 #-----------------------------------------------------------------------------
202 # Formatters for specific format types (text, html, svg, etc.)
202 # Formatters for specific format types (text, html, svg, etc.)
203 #-----------------------------------------------------------------------------
203 #-----------------------------------------------------------------------------
204
204
205
205
206 def _safe_repr(obj):
206 def _safe_repr(obj):
207 """Try to return a repr of an object
207 """Try to return a repr of an object
208
208
209 always returns a string, at least.
209 always returns a string, at least.
210 """
210 """
211 try:
211 try:
212 return repr(obj)
212 return repr(obj)
213 except Exception as e:
213 except Exception as e:
214 return "un-repr-able object (%r)" % e
214 return "un-repr-able object (%r)" % e
215
215
216
216
217 class FormatterWarning(UserWarning):
217 class FormatterWarning(UserWarning):
218 """Warning class for errors in formatters"""
218 """Warning class for errors in formatters"""
219
219
220 @decorator
220 @decorator
221 def catch_format_error(method, self, *args, **kwargs):
221 def catch_format_error(method, self, *args, **kwargs):
222 """show traceback on failed format call"""
222 """show traceback on failed format call"""
223 try:
223 try:
224 r = method(self, *args, **kwargs)
224 r = method(self, *args, **kwargs)
225 except NotImplementedError:
225 except NotImplementedError:
226 # don't warn on NotImplementedErrors
226 # don't warn on NotImplementedErrors
227 return self._check_return(None, args[0])
227 return self._check_return(None, args[0])
228 except Exception:
228 except Exception:
229 exc_info = sys.exc_info()
229 exc_info = sys.exc_info()
230 ip = get_ipython()
230 ip = get_ipython()
231 if ip is not None:
231 if ip is not None:
232 ip.showtraceback(exc_info)
232 ip.showtraceback(exc_info)
233 else:
233 else:
234 traceback.print_exception(*exc_info)
234 traceback.print_exception(*exc_info)
235 return self._check_return(None, args[0])
235 return self._check_return(None, args[0])
236 return self._check_return(r, args[0])
236 return self._check_return(r, args[0])
237
237
238
238
239 class FormatterABC(metaclass=abc.ABCMeta):
239 class FormatterABC(metaclass=abc.ABCMeta):
240 """ Abstract base class for Formatters.
240 """ Abstract base class for Formatters.
241
241
242 A formatter is a callable class that is responsible for computing the
242 A formatter is a callable class that is responsible for computing the
243 raw format data for a particular format type (MIME type). For example,
243 raw format data for a particular format type (MIME type). For example,
244 an HTML formatter would have a format type of `text/html` and would return
244 an HTML formatter would have a format type of `text/html` and would return
245 the HTML representation of the object when called.
245 the HTML representation of the object when called.
246 """
246 """
247
247
248 # The format type of the data returned, usually a MIME type.
248 # The format type of the data returned, usually a MIME type.
249 format_type = 'text/plain'
249 format_type = 'text/plain'
250
250
251 # Is the formatter enabled...
251 # Is the formatter enabled...
252 enabled = True
252 enabled = True
253
253
254 @abc.abstractmethod
254 @abc.abstractmethod
255 def __call__(self, obj):
255 def __call__(self, obj):
256 """Return a JSON'able representation of the object.
256 """Return a JSON'able representation of the object.
257
257
258 If the object cannot be formatted by this formatter,
258 If the object cannot be formatted by this formatter,
259 warn and return None.
259 warn and return None.
260 """
260 """
261 return repr(obj)
261 return repr(obj)
262
262
263
263
264 def _mod_name_key(typ):
264 def _mod_name_key(typ):
265 """Return a (__module__, __name__) tuple for a type.
265 """Return a (__module__, __name__) tuple for a type.
266
266
267 Used as key in Formatter.deferred_printers.
267 Used as key in Formatter.deferred_printers.
268 """
268 """
269 module = getattr(typ, '__module__', None)
269 module = getattr(typ, '__module__', None)
270 name = getattr(typ, '__name__', None)
270 name = getattr(typ, '__name__', None)
271 return (module, name)
271 return (module, name)
272
272
273
273
274 def _get_type(obj):
274 def _get_type(obj):
275 """Return the type of an instance (old and new-style)"""
275 """Return the type of an instance (old and new-style)"""
276 return getattr(obj, '__class__', None) or type(obj)
276 return getattr(obj, '__class__', None) or type(obj)
277
277
278
278
279 _raise_key_error = Sentinel('_raise_key_error', __name__,
279 _raise_key_error = Sentinel('_raise_key_error', __name__,
280 """
280 """
281 Special value to raise a KeyError
281 Special value to raise a KeyError
282
282
283 Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop`
283 Raise KeyError in `BaseFormatter.pop` if passed as the default value to `pop`
284 """)
284 """)
285
285
286
286
287 class BaseFormatter(Configurable):
287 class BaseFormatter(Configurable):
288 """A base formatter class that is configurable.
288 """A base formatter class that is configurable.
289
289
290 This formatter should usually be used as the base class of all formatters.
290 This formatter should usually be used as the base class of all formatters.
291 It is a traited :class:`Configurable` class and includes an extensible
291 It is a traited :class:`Configurable` class and includes an extensible
292 API for users to determine how their objects are formatted. The following
292 API for users to determine how their objects are formatted. The following
293 logic is used to find a function to format an given object.
293 logic is used to find a function to format an given object.
294
294
295 1. The object is introspected to see if it has a method with the name
295 1. The object is introspected to see if it has a method with the name
296 :attr:`print_method`. If is does, that object is passed to that method
296 :attr:`print_method`. If is does, that object is passed to that method
297 for formatting.
297 for formatting.
298 2. If no print method is found, three internal dictionaries are consulted
298 2. If no print method is found, three internal dictionaries are consulted
299 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
299 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
300 and :attr:`deferred_printers`.
300 and :attr:`deferred_printers`.
301
301
302 Users should use these dictionaries to register functions that will be
302 Users should use these dictionaries to register functions that will be
303 used to compute the format data for their objects (if those objects don't
303 used to compute the format data for their objects (if those objects don't
304 have the special print methods). The easiest way of using these
304 have the special print methods). The easiest way of using these
305 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
305 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
306 methods.
306 methods.
307
307
308 If no function/callable is found to compute the format data, ``None`` is
308 If no function/callable is found to compute the format data, ``None`` is
309 returned and this format type is not used.
309 returned and this format type is not used.
310 """
310 """
311
311
312 format_type = Unicode('text/plain')
312 format_type = Unicode('text/plain')
313 _return_type = str
313 _return_type = str
314
314
315 enabled = Bool(True).tag(config=True)
315 enabled = Bool(True).tag(config=True)
316
316
317 print_method = ObjectName('__repr__')
317 print_method = ObjectName('__repr__')
318
318
319 # The singleton printers.
319 # The singleton printers.
320 # Maps the IDs of the builtin singleton objects to the format functions.
320 # Maps the IDs of the builtin singleton objects to the format functions.
321 singleton_printers = Dict().tag(config=True)
321 singleton_printers = Dict().tag(config=True)
322
322
323 # The type-specific printers.
323 # The type-specific printers.
324 # Map type objects to the format functions.
324 # Map type objects to the format functions.
325 type_printers = Dict().tag(config=True)
325 type_printers = Dict().tag(config=True)
326
326
327 # The deferred-import type-specific printers.
327 # The deferred-import type-specific printers.
328 # Map (modulename, classname) pairs to the format functions.
328 # Map (modulename, classname) pairs to the format functions.
329 deferred_printers = Dict().tag(config=True)
329 deferred_printers = Dict().tag(config=True)
330
330
331 @catch_format_error
331 @catch_format_error
332 def __call__(self, obj):
332 def __call__(self, obj):
333 """Compute the format for an object."""
333 """Compute the format for an object."""
334 if self.enabled:
334 if self.enabled:
335 # lookup registered printer
335 # lookup registered printer
336 try:
336 try:
337 printer = self.lookup(obj)
337 printer = self.lookup(obj)
338 except KeyError:
338 except KeyError:
339 pass
339 pass
340 else:
340 else:
341 return printer(obj)
341 return printer(obj)
342 # Finally look for special method names
342 # Finally look for special method names
343 method = get_real_method(obj, self.print_method)
343 method = get_real_method(obj, self.print_method)
344 if method is not None:
344 if method is not None:
345 return method()
345 return method()
346 return None
346 return None
347 else:
347 else:
348 return None
348 return None
349
349
350 def __contains__(self, typ):
350 def __contains__(self, typ):
351 """map in to lookup_by_type"""
351 """map in to lookup_by_type"""
352 try:
352 try:
353 self.lookup_by_type(typ)
353 self.lookup_by_type(typ)
354 except KeyError:
354 except KeyError:
355 return False
355 return False
356 else:
356 else:
357 return True
357 return True
358
358
359 def _check_return(self, r, obj):
359 def _check_return(self, r, obj):
360 """Check that a return value is appropriate
360 """Check that a return value is appropriate
361
361
362 Return the value if so, None otherwise, warning if invalid.
362 Return the value if so, None otherwise, warning if invalid.
363 """
363 """
364 if r is None or isinstance(r, self._return_type) or \
364 if r is None or isinstance(r, self._return_type) or \
365 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
365 (isinstance(r, tuple) and r and isinstance(r[0], self._return_type)):
366 return r
366 return r
367 else:
367 else:
368 warnings.warn(
368 warnings.warn(
369 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
369 "%s formatter returned invalid type %s (expected %s) for object: %s" % \
370 (self.format_type, type(r), self._return_type, _safe_repr(obj)),
370 (self.format_type, type(r), self._return_type, _safe_repr(obj)),
371 FormatterWarning
371 FormatterWarning
372 )
372 )
373
373
374 def lookup(self, obj):
374 def lookup(self, obj):
375 """Look up the formatter for a given instance.
375 """Look up the formatter for a given instance.
376
376
377 Parameters
377 Parameters
378 ----------
378 ----------
379 obj : object instance
379 obj : object instance
380
380
381 Returns
381 Returns
382 -------
382 -------
383 f : callable
383 f : callable
384 The registered formatting callable for the type.
384 The registered formatting callable for the type.
385
385
386 Raises
386 Raises
387 ------
387 ------
388 KeyError if the type has not been registered.
388 KeyError if the type has not been registered.
389 """
389 """
390 # look for singleton first
390 # look for singleton first
391 obj_id = id(obj)
391 obj_id = id(obj)
392 if obj_id in self.singleton_printers:
392 if obj_id in self.singleton_printers:
393 return self.singleton_printers[obj_id]
393 return self.singleton_printers[obj_id]
394 # then lookup by type
394 # then lookup by type
395 return self.lookup_by_type(_get_type(obj))
395 return self.lookup_by_type(_get_type(obj))
396
396
397 def lookup_by_type(self, typ):
397 def lookup_by_type(self, typ):
398 """Look up the registered formatter for a type.
398 """Look up the registered formatter for a type.
399
399
400 Parameters
400 Parameters
401 ----------
401 ----------
402 typ : type or '__module__.__name__' string for a type
402 typ : type or '__module__.__name__' string for a type
403
403
404 Returns
404 Returns
405 -------
405 -------
406 f : callable
406 f : callable
407 The registered formatting callable for the type.
407 The registered formatting callable for the type.
408
408
409 Raises
409 Raises
410 ------
410 ------
411 KeyError if the type has not been registered.
411 KeyError if the type has not been registered.
412 """
412 """
413 if isinstance(typ, str):
413 if isinstance(typ, str):
414 typ_key = tuple(typ.rsplit('.',1))
414 typ_key = tuple(typ.rsplit('.',1))
415 if typ_key not in self.deferred_printers:
415 if typ_key not in self.deferred_printers:
416 # We may have it cached in the type map. We will have to
416 # We may have it cached in the type map. We will have to
417 # iterate over all of the types to check.
417 # iterate over all of the types to check.
418 for cls in self.type_printers:
418 for cls in self.type_printers:
419 if _mod_name_key(cls) == typ_key:
419 if _mod_name_key(cls) == typ_key:
420 return self.type_printers[cls]
420 return self.type_printers[cls]
421 else:
421 else:
422 return self.deferred_printers[typ_key]
422 return self.deferred_printers[typ_key]
423 else:
423 else:
424 for cls in pretty._get_mro(typ):
424 for cls in pretty._get_mro(typ):
425 if cls in self.type_printers or self._in_deferred_types(cls):
425 if cls in self.type_printers or self._in_deferred_types(cls):
426 return self.type_printers[cls]
426 return self.type_printers[cls]
427
427
428 # If we have reached here, the lookup failed.
428 # If we have reached here, the lookup failed.
429 raise KeyError("No registered printer for {0!r}".format(typ))
429 raise KeyError("No registered printer for {0!r}".format(typ))
430
430
431 def for_type(self, typ, func=None):
431 def for_type(self, typ, func=None):
432 """Add a format function for a given type.
432 """Add a format function for a given type.
433
433
434 Parameters
434 Parameters
435 -----------
435 -----------
436 typ : type or '__module__.__name__' string for a type
436 typ : type or '__module__.__name__' string for a type
437 The class of the object that will be formatted using `func`.
437 The class of the object that will be formatted using `func`.
438 func : callable
438 func : callable
439 A callable for computing the format data.
439 A callable for computing the format data.
440 `func` will be called with the object to be formatted,
440 `func` will be called with the object to be formatted,
441 and will return the raw data in this formatter's format.
441 and will return the raw data in this formatter's format.
442 Subclasses may use a different call signature for the
442 Subclasses may use a different call signature for the
443 `func` argument.
443 `func` argument.
444
444
445 If `func` is None or not specified, there will be no change,
445 If `func` is None or not specified, there will be no change,
446 only returning the current value.
446 only returning the current value.
447
447
448 Returns
448 Returns
449 -------
449 -------
450 oldfunc : callable
450 oldfunc : callable
451 The currently registered callable.
451 The currently registered callable.
452 If you are registering a new formatter,
452 If you are registering a new formatter,
453 this will be the previous value (to enable restoring later).
453 this will be the previous value (to enable restoring later).
454 """
454 """
455 # if string given, interpret as 'pkg.module.class_name'
455 # if string given, interpret as 'pkg.module.class_name'
456 if isinstance(typ, str):
456 if isinstance(typ, str):
457 type_module, type_name = typ.rsplit('.', 1)
457 type_module, type_name = typ.rsplit('.', 1)
458 return self.for_type_by_name(type_module, type_name, func)
458 return self.for_type_by_name(type_module, type_name, func)
459
459
460 try:
460 try:
461 oldfunc = self.lookup_by_type(typ)
461 oldfunc = self.lookup_by_type(typ)
462 except KeyError:
462 except KeyError:
463 oldfunc = None
463 oldfunc = None
464
464
465 if func is not None:
465 if func is not None:
466 self.type_printers[typ] = func
466 self.type_printers[typ] = func
467
467
468 return oldfunc
468 return oldfunc
469
469
470 def for_type_by_name(self, type_module, type_name, func=None):
470 def for_type_by_name(self, type_module, type_name, func=None):
471 """Add a format function for a type specified by the full dotted
471 """Add a format function for a type specified by the full dotted
472 module and name of the type, rather than the type of the object.
472 module and name of the type, rather than the type of the object.
473
473
474 Parameters
474 Parameters
475 ----------
475 ----------
476 type_module : str
476 type_module : str
477 The full dotted name of the module the type is defined in, like
477 The full dotted name of the module the type is defined in, like
478 ``numpy``.
478 ``numpy``.
479 type_name : str
479 type_name : str
480 The name of the type (the class name), like ``dtype``
480 The name of the type (the class name), like ``dtype``
481 func : callable
481 func : callable
482 A callable for computing the format data.
482 A callable for computing the format data.
483 `func` will be called with the object to be formatted,
483 `func` will be called with the object to be formatted,
484 and will return the raw data in this formatter's format.
484 and will return the raw data in this formatter's format.
485 Subclasses may use a different call signature for the
485 Subclasses may use a different call signature for the
486 `func` argument.
486 `func` argument.
487
487
488 If `func` is None or unspecified, there will be no change,
488 If `func` is None or unspecified, there will be no change,
489 only returning the current value.
489 only returning the current value.
490
490
491 Returns
491 Returns
492 -------
492 -------
493 oldfunc : callable
493 oldfunc : callable
494 The currently registered callable.
494 The currently registered callable.
495 If you are registering a new formatter,
495 If you are registering a new formatter,
496 this will be the previous value (to enable restoring later).
496 this will be the previous value (to enable restoring later).
497 """
497 """
498 key = (type_module, type_name)
498 key = (type_module, type_name)
499
499
500 try:
500 try:
501 oldfunc = self.lookup_by_type("%s.%s" % key)
501 oldfunc = self.lookup_by_type("%s.%s" % key)
502 except KeyError:
502 except KeyError:
503 oldfunc = None
503 oldfunc = None
504
504
505 if func is not None:
505 if func is not None:
506 self.deferred_printers[key] = func
506 self.deferred_printers[key] = func
507 return oldfunc
507 return oldfunc
508
508
509 def pop(self, typ, default=_raise_key_error):
509 def pop(self, typ, default=_raise_key_error):
510 """Pop a formatter for the given type.
510 """Pop a formatter for the given type.
511
511
512 Parameters
512 Parameters
513 ----------
513 ----------
514 typ : type or '__module__.__name__' string for a type
514 typ : type or '__module__.__name__' string for a type
515 default : object
515 default : object
516 value to be returned if no formatter is registered for typ.
516 value to be returned if no formatter is registered for typ.
517
517
518 Returns
518 Returns
519 -------
519 -------
520 obj : object
520 obj : object
521 The last registered object for the type.
521 The last registered object for the type.
522
522
523 Raises
523 Raises
524 ------
524 ------
525 KeyError if the type is not registered and default is not specified.
525 KeyError if the type is not registered and default is not specified.
526 """
526 """
527
527
528 if isinstance(typ, str):
528 if isinstance(typ, str):
529 typ_key = tuple(typ.rsplit('.',1))
529 typ_key = tuple(typ.rsplit('.',1))
530 if typ_key not in self.deferred_printers:
530 if typ_key not in self.deferred_printers:
531 # We may have it cached in the type map. We will have to
531 # We may have it cached in the type map. We will have to
532 # iterate over all of the types to check.
532 # iterate over all of the types to check.
533 for cls in self.type_printers:
533 for cls in self.type_printers:
534 if _mod_name_key(cls) == typ_key:
534 if _mod_name_key(cls) == typ_key:
535 old = self.type_printers.pop(cls)
535 old = self.type_printers.pop(cls)
536 break
536 break
537 else:
537 else:
538 old = default
538 old = default
539 else:
539 else:
540 old = self.deferred_printers.pop(typ_key)
540 old = self.deferred_printers.pop(typ_key)
541 else:
541 else:
542 if typ in self.type_printers:
542 if typ in self.type_printers:
543 old = self.type_printers.pop(typ)
543 old = self.type_printers.pop(typ)
544 else:
544 else:
545 old = self.deferred_printers.pop(_mod_name_key(typ), default)
545 old = self.deferred_printers.pop(_mod_name_key(typ), default)
546 if old is _raise_key_error:
546 if old is _raise_key_error:
547 raise KeyError("No registered value for {0!r}".format(typ))
547 raise KeyError("No registered value for {0!r}".format(typ))
548 return old
548 return old
549
549
550 def _in_deferred_types(self, cls):
550 def _in_deferred_types(self, cls):
551 """
551 """
552 Check if the given class is specified in the deferred type registry.
552 Check if the given class is specified in the deferred type registry.
553
553
554 Successful matches will be moved to the regular type registry for future use.
554 Successful matches will be moved to the regular type registry for future use.
555 """
555 """
556 mod = getattr(cls, '__module__', None)
556 mod = getattr(cls, '__module__', None)
557 name = getattr(cls, '__name__', None)
557 name = getattr(cls, '__name__', None)
558 key = (mod, name)
558 key = (mod, name)
559 if key in self.deferred_printers:
559 if key in self.deferred_printers:
560 # Move the printer over to the regular registry.
560 # Move the printer over to the regular registry.
561 printer = self.deferred_printers.pop(key)
561 printer = self.deferred_printers.pop(key)
562 self.type_printers[cls] = printer
562 self.type_printers[cls] = printer
563 return True
563 return True
564 return False
564 return False
565
565
566
566
567 class PlainTextFormatter(BaseFormatter):
567 class PlainTextFormatter(BaseFormatter):
568 """The default pretty-printer.
568 """The default pretty-printer.
569
569
570 This uses :mod:`IPython.lib.pretty` to compute the format data of
570 This uses :mod:`IPython.lib.pretty` to compute the format data of
571 the object. If the object cannot be pretty printed, :func:`repr` is used.
571 the object. If the object cannot be pretty printed, :func:`repr` is used.
572 See the documentation of :mod:`IPython.lib.pretty` for details on
572 See the documentation of :mod:`IPython.lib.pretty` for details on
573 how to write pretty printers. Here is a simple example::
573 how to write pretty printers. Here is a simple example::
574
574
575 def dtype_pprinter(obj, p, cycle):
575 def dtype_pprinter(obj, p, cycle):
576 if cycle:
576 if cycle:
577 return p.text('dtype(...)')
577 return p.text('dtype(...)')
578 if hasattr(obj, 'fields'):
578 if hasattr(obj, 'fields'):
579 if obj.fields is None:
579 if obj.fields is None:
580 p.text(repr(obj))
580 p.text(repr(obj))
581 else:
581 else:
582 p.begin_group(7, 'dtype([')
582 p.begin_group(7, 'dtype([')
583 for i, field in enumerate(obj.descr):
583 for i, field in enumerate(obj.descr):
584 if i > 0:
584 if i > 0:
585 p.text(',')
585 p.text(',')
586 p.breakable()
586 p.breakable()
587 p.pretty(field)
587 p.pretty(field)
588 p.end_group(7, '])')
588 p.end_group(7, '])')
589 """
589 """
590
590
591 # The format type of data returned.
591 # The format type of data returned.
592 format_type = Unicode('text/plain')
592 format_type = Unicode('text/plain')
593
593
594 # This subclass ignores this attribute as it always need to return
594 # This subclass ignores this attribute as it always need to return
595 # something.
595 # something.
596 enabled = Bool(True).tag(config=False)
596 enabled = Bool(True).tag(config=False)
597
597
598 max_seq_length = Integer(pretty.MAX_SEQ_LENGTH,
598 max_seq_length = Integer(pretty.MAX_SEQ_LENGTH,
599 help="""Truncate large collections (lists, dicts, tuples, sets) to this size.
599 help="""Truncate large collections (lists, dicts, tuples, sets) to this size.
600
600
601 Set to 0 to disable truncation.
601 Set to 0 to disable truncation.
602 """
602 """
603 ).tag(config=True)
603 ).tag(config=True)
604
604
605 # Look for a _repr_pretty_ methods to use for pretty printing.
605 # Look for a _repr_pretty_ methods to use for pretty printing.
606 print_method = ObjectName('_repr_pretty_')
606 print_method = ObjectName('_repr_pretty_')
607
607
608 # Whether to pretty-print or not.
608 # Whether to pretty-print or not.
609 pprint = Bool(True).tag(config=True)
609 pprint = Bool(True).tag(config=True)
610
610
611 # Whether to be verbose or not.
611 # Whether to be verbose or not.
612 verbose = Bool(False).tag(config=True)
612 verbose = Bool(False).tag(config=True)
613
613
614 # The maximum width.
614 # The maximum width.
615 max_width = Integer(79).tag(config=True)
615 max_width = Integer(79).tag(config=True)
616
616
617 # The newline character.
617 # The newline character.
618 newline = Unicode('\n').tag(config=True)
618 newline = Unicode('\n').tag(config=True)
619
619
620 # format-string for pprinting floats
620 # format-string for pprinting floats
621 float_format = Unicode('%r')
621 float_format = Unicode('%r')
622 # setter for float precision, either int or direct format-string
622 # setter for float precision, either int or direct format-string
623 float_precision = CUnicode('').tag(config=True)
623 float_precision = CUnicode('').tag(config=True)
624
624
625 @observe('float_precision')
625 @observe('float_precision')
626 def _float_precision_changed(self, change):
626 def _float_precision_changed(self, change):
627 """float_precision changed, set float_format accordingly.
627 """float_precision changed, set float_format accordingly.
628
628
629 float_precision can be set by int or str.
629 float_precision can be set by int or str.
630 This will set float_format, after interpreting input.
630 This will set float_format, after interpreting input.
631 If numpy has been imported, numpy print precision will also be set.
631 If numpy has been imported, numpy print precision will also be set.
632
632
633 integer `n` sets format to '%.nf', otherwise, format set directly.
633 integer `n` sets format to '%.nf', otherwise, format set directly.
634
634
635 An empty string returns to defaults (repr for float, 8 for numpy).
635 An empty string returns to defaults (repr for float, 8 for numpy).
636
636
637 This parameter can be set via the '%precision' magic.
637 This parameter can be set via the '%precision' magic.
638 """
638 """
639
639
640 new = change['new']
640 new = change['new']
641 if '%' in new:
641 if '%' in new:
642 # got explicit format string
642 # got explicit format string
643 fmt = new
643 fmt = new
644 try:
644 try:
645 fmt%3.14159
645 fmt%3.14159
646 except Exception:
646 except Exception:
647 raise ValueError("Precision must be int or format string, not %r"%new)
647 raise ValueError("Precision must be int or format string, not %r"%new)
648 elif new:
648 elif new:
649 # otherwise, should be an int
649 # otherwise, should be an int
650 try:
650 try:
651 i = int(new)
651 i = int(new)
652 assert i >= 0
652 assert i >= 0
653 except ValueError:
653 except ValueError:
654 raise ValueError("Precision must be int or format string, not %r"%new)
654 raise ValueError("Precision must be int or format string, not %r"%new)
655 except AssertionError:
655 except AssertionError:
656 raise ValueError("int precision must be non-negative, not %r"%i)
656 raise ValueError("int precision must be non-negative, not %r"%i)
657
657
658 fmt = '%%.%if'%i
658 fmt = '%%.%if'%i
659 if 'numpy' in sys.modules:
659 if 'numpy' in sys.modules:
660 # set numpy precision if it has been imported
660 # set numpy precision if it has been imported
661 import numpy
661 import numpy
662 numpy.set_printoptions(precision=i)
662 numpy.set_printoptions(precision=i)
663 else:
663 else:
664 # default back to repr
664 # default back to repr
665 fmt = '%r'
665 fmt = '%r'
666 if 'numpy' in sys.modules:
666 if 'numpy' in sys.modules:
667 import numpy
667 import numpy
668 # numpy default is 8
668 # numpy default is 8
669 numpy.set_printoptions(precision=8)
669 numpy.set_printoptions(precision=8)
670 self.float_format = fmt
670 self.float_format = fmt
671
671
672 # Use the default pretty printers from IPython.lib.pretty.
672 # Use the default pretty printers from IPython.lib.pretty.
673 @default('singleton_printers')
673 @default('singleton_printers')
674 def _singleton_printers_default(self):
674 def _singleton_printers_default(self):
675 return pretty._singleton_pprinters.copy()
675 return pretty._singleton_pprinters.copy()
676
676
677 @default('type_printers')
677 @default('type_printers')
678 def _type_printers_default(self):
678 def _type_printers_default(self):
679 d = pretty._type_pprinters.copy()
679 d = pretty._type_pprinters.copy()
680 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
680 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
681 return d
681 return d
682
682
683 @default('deferred_printers')
683 @default('deferred_printers')
684 def _deferred_printers_default(self):
684 def _deferred_printers_default(self):
685 return pretty._deferred_type_pprinters.copy()
685 return pretty._deferred_type_pprinters.copy()
686
686
687 #### FormatterABC interface ####
687 #### FormatterABC interface ####
688
688
689 @catch_format_error
689 @catch_format_error
690 def __call__(self, obj):
690 def __call__(self, obj):
691 """Compute the pretty representation of the object."""
691 """Compute the pretty representation of the object."""
692 if not self.pprint:
692 if not self.pprint:
693 return repr(obj)
693 return repr(obj)
694 else:
694 else:
695 stream = StringIO()
695 stream = StringIO()
696 printer = pretty.RepresentationPrinter(stream, self.verbose,
696 printer = pretty.RepresentationPrinter(stream, self.verbose,
697 self.max_width, self.newline,
697 self.max_width, self.newline,
698 max_seq_length=self.max_seq_length,
698 max_seq_length=self.max_seq_length,
699 singleton_pprinters=self.singleton_printers,
699 singleton_pprinters=self.singleton_printers,
700 type_pprinters=self.type_printers,
700 type_pprinters=self.type_printers,
701 deferred_pprinters=self.deferred_printers)
701 deferred_pprinters=self.deferred_printers)
702 printer.pretty(obj)
702 printer.pretty(obj)
703 printer.flush()
703 printer.flush()
704 return stream.getvalue()
704 return stream.getvalue()
705
705
706
706
707 class HTMLFormatter(BaseFormatter):
707 class HTMLFormatter(BaseFormatter):
708 """An HTML formatter.
708 """An HTML formatter.
709
709
710 To define the callables that compute the HTML representation of your
710 To define the callables that compute the HTML representation of your
711 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
711 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
712 or :meth:`for_type_by_name` methods to register functions that handle
712 or :meth:`for_type_by_name` methods to register functions that handle
713 this.
713 this.
714
714
715 The return value of this formatter should be a valid HTML snippet that
715 The return value of this formatter should be a valid HTML snippet that
716 could be injected into an existing DOM. It should *not* include the
716 could be injected into an existing DOM. It should *not* include the
717 ```<html>`` or ```<body>`` tags.
717 ```<html>`` or ```<body>`` tags.
718 """
718 """
719 format_type = Unicode('text/html')
719 format_type = Unicode('text/html')
720
720
721 print_method = ObjectName('_repr_html_')
721 print_method = ObjectName('_repr_html_')
722
722
723
723
724 class MarkdownFormatter(BaseFormatter):
724 class MarkdownFormatter(BaseFormatter):
725 """A Markdown formatter.
725 """A Markdown formatter.
726
726
727 To define the callables that compute the Markdown representation of your
727 To define the callables that compute the Markdown representation of your
728 objects, define a :meth:`_repr_markdown_` method or use the :meth:`for_type`
728 objects, define a :meth:`_repr_markdown_` method or use the :meth:`for_type`
729 or :meth:`for_type_by_name` methods to register functions that handle
729 or :meth:`for_type_by_name` methods to register functions that handle
730 this.
730 this.
731
731
732 The return value of this formatter should be a valid Markdown.
732 The return value of this formatter should be a valid Markdown.
733 """
733 """
734 format_type = Unicode('text/markdown')
734 format_type = Unicode('text/markdown')
735
735
736 print_method = ObjectName('_repr_markdown_')
736 print_method = ObjectName('_repr_markdown_')
737
737
738 class SVGFormatter(BaseFormatter):
738 class SVGFormatter(BaseFormatter):
739 """An SVG formatter.
739 """An SVG formatter.
740
740
741 To define the callables that compute the SVG representation of your
741 To define the callables that compute the SVG representation of your
742 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
742 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
743 or :meth:`for_type_by_name` methods to register functions that handle
743 or :meth:`for_type_by_name` methods to register functions that handle
744 this.
744 this.
745
745
746 The return value of this formatter should be valid SVG enclosed in
746 The return value of this formatter should be valid SVG enclosed in
747 ```<svg>``` tags, that could be injected into an existing DOM. It should
747 ```<svg>``` tags, that could be injected into an existing DOM. It should
748 *not* include the ```<html>`` or ```<body>`` tags.
748 *not* include the ```<html>`` or ```<body>`` tags.
749 """
749 """
750 format_type = Unicode('image/svg+xml')
750 format_type = Unicode('image/svg+xml')
751
751
752 print_method = ObjectName('_repr_svg_')
752 print_method = ObjectName('_repr_svg_')
753
753
754
754
755 class PNGFormatter(BaseFormatter):
755 class PNGFormatter(BaseFormatter):
756 """A PNG formatter.
756 """A PNG formatter.
757
757
758 To define the callables that compute the PNG representation of your
758 To define the callables that compute the PNG representation of your
759 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
759 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
760 or :meth:`for_type_by_name` methods to register functions that handle
760 or :meth:`for_type_by_name` methods to register functions that handle
761 this.
761 this.
762
762
763 The return value of this formatter should be raw PNG data, *not*
763 The return value of this formatter should be raw PNG data, *not*
764 base64 encoded.
764 base64 encoded.
765 """
765 """
766 format_type = Unicode('image/png')
766 format_type = Unicode('image/png')
767
767
768 print_method = ObjectName('_repr_png_')
768 print_method = ObjectName('_repr_png_')
769
769
770 _return_type = (bytes, str)
770 _return_type = (bytes, str)
771
771
772
772
773 class JPEGFormatter(BaseFormatter):
773 class JPEGFormatter(BaseFormatter):
774 """A JPEG formatter.
774 """A JPEG formatter.
775
775
776 To define the callables that compute the JPEG representation of your
776 To define the callables that compute the JPEG representation of your
777 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
777 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
778 or :meth:`for_type_by_name` methods to register functions that handle
778 or :meth:`for_type_by_name` methods to register functions that handle
779 this.
779 this.
780
780
781 The return value of this formatter should be raw JPEG data, *not*
781 The return value of this formatter should be raw JPEG data, *not*
782 base64 encoded.
782 base64 encoded.
783 """
783 """
784 format_type = Unicode('image/jpeg')
784 format_type = Unicode('image/jpeg')
785
785
786 print_method = ObjectName('_repr_jpeg_')
786 print_method = ObjectName('_repr_jpeg_')
787
787
788 _return_type = (bytes, str)
788 _return_type = (bytes, str)
789
789
790
790
791 class LatexFormatter(BaseFormatter):
791 class LatexFormatter(BaseFormatter):
792 """A LaTeX formatter.
792 """A LaTeX formatter.
793
793
794 To define the callables that compute the LaTeX representation of your
794 To define the callables that compute the LaTeX representation of your
795 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
795 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
796 or :meth:`for_type_by_name` methods to register functions that handle
796 or :meth:`for_type_by_name` methods to register functions that handle
797 this.
797 this.
798
798
799 The return value of this formatter should be a valid LaTeX equation,
799 The return value of this formatter should be a valid LaTeX equation,
800 enclosed in either ```$```, ```$$``` or another LaTeX equation
800 enclosed in either ```$```, ```$$``` or another LaTeX equation
801 environment.
801 environment.
802 """
802 """
803 format_type = Unicode('text/latex')
803 format_type = Unicode('text/latex')
804
804
805 print_method = ObjectName('_repr_latex_')
805 print_method = ObjectName('_repr_latex_')
806
806
807
807
808 class JSONFormatter(BaseFormatter):
808 class JSONFormatter(BaseFormatter):
809 """A JSON string formatter.
809 """A JSON string formatter.
810
810
811 To define the callables that compute the JSONable representation of
811 To define the callables that compute the JSONable representation of
812 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
812 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
813 or :meth:`for_type_by_name` methods to register functions that handle
813 or :meth:`for_type_by_name` methods to register functions that handle
814 this.
814 this.
815
815
816 The return value of this formatter should be a JSONable list or dict.
816 The return value of this formatter should be a JSONable list or dict.
817 JSON scalars (None, number, string) are not allowed, only dict or list containers.
817 JSON scalars (None, number, string) are not allowed, only dict or list containers.
818 """
818 """
819 format_type = Unicode('application/json')
819 format_type = Unicode('application/json')
820 _return_type = (list, dict)
820 _return_type = (list, dict)
821
821
822 print_method = ObjectName('_repr_json_')
822 print_method = ObjectName('_repr_json_')
823
823
824 def _check_return(self, r, obj):
824 def _check_return(self, r, obj):
825 """Check that a return value is appropriate
825 """Check that a return value is appropriate
826
826
827 Return the value if so, None otherwise, warning if invalid.
827 Return the value if so, None otherwise, warning if invalid.
828 """
828 """
829 if r is None:
829 if r is None:
830 return
830 return
831 md = None
831 md = None
832 if isinstance(r, tuple):
832 if isinstance(r, tuple):
833 # unpack data, metadata tuple for type checking on first element
833 # unpack data, metadata tuple for type checking on first element
834 r, md = r
834 r, md = r
835
835
836 # handle deprecated JSON-as-string form from IPython < 3
836 # handle deprecated JSON-as-string form from IPython < 3
837 if isinstance(r, str):
837 if isinstance(r, str):
838 warnings.warn("JSON expects JSONable list/dict containers, not JSON strings",
838 warnings.warn("JSON expects JSONable list/dict containers, not JSON strings",
839 FormatterWarning)
839 FormatterWarning)
840 r = json.loads(r)
840 r = json.loads(r)
841
841
842 if md is not None:
842 if md is not None:
843 # put the tuple back together
843 # put the tuple back together
844 r = (r, md)
844 r = (r, md)
845 return super(JSONFormatter, self)._check_return(r, obj)
845 return super(JSONFormatter, self)._check_return(r, obj)
846
846
847
847
848 class JavascriptFormatter(BaseFormatter):
848 class JavascriptFormatter(BaseFormatter):
849 """A Javascript formatter.
849 """A Javascript formatter.
850
850
851 To define the callables that compute the Javascript representation of
851 To define the callables that compute the Javascript representation of
852 your objects, define a :meth:`_repr_javascript_` method or use the
852 your objects, define a :meth:`_repr_javascript_` method or use the
853 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
853 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
854 that handle this.
854 that handle this.
855
855
856 The return value of this formatter should be valid Javascript code and
856 The return value of this formatter should be valid Javascript code and
857 should *not* be enclosed in ```<script>``` tags.
857 should *not* be enclosed in ```<script>``` tags.
858 """
858 """
859 format_type = Unicode('application/javascript')
859 format_type = Unicode('application/javascript')
860
860
861 print_method = ObjectName('_repr_javascript_')
861 print_method = ObjectName('_repr_javascript_')
862
862
863
863
864 class PDFFormatter(BaseFormatter):
864 class PDFFormatter(BaseFormatter):
865 """A PDF formatter.
865 """A PDF formatter.
866
866
867 To define the callables that compute the PDF representation of your
867 To define the callables that compute the PDF representation of your
868 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
868 objects, define a :meth:`_repr_pdf_` method or use the :meth:`for_type`
869 or :meth:`for_type_by_name` methods to register functions that handle
869 or :meth:`for_type_by_name` methods to register functions that handle
870 this.
870 this.
871
871
872 The return value of this formatter should be raw PDF data, *not*
872 The return value of this formatter should be raw PDF data, *not*
873 base64 encoded.
873 base64 encoded.
874 """
874 """
875 format_type = Unicode('application/pdf')
875 format_type = Unicode('application/pdf')
876
876
877 print_method = ObjectName('_repr_pdf_')
877 print_method = ObjectName('_repr_pdf_')
878
878
879 _return_type = (bytes, str)
879 _return_type = (bytes, str)
880
880
881 class IPythonDisplayFormatter(BaseFormatter):
881 class IPythonDisplayFormatter(BaseFormatter):
882 """An escape-hatch Formatter for objects that know how to display themselves.
882 """An escape-hatch Formatter for objects that know how to display themselves.
883
883
884 To define the callables that compute the representation of your
884 To define the callables that compute the representation of your
885 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
885 objects, define a :meth:`_ipython_display_` method or use the :meth:`for_type`
886 or :meth:`for_type_by_name` methods to register functions that handle
886 or :meth:`for_type_by_name` methods to register functions that handle
887 this. Unlike mime-type displays, this method should not return anything,
887 this. Unlike mime-type displays, this method should not return anything,
888 instead calling any appropriate display methods itself.
888 instead calling any appropriate display methods itself.
889
889
890 This display formatter has highest priority.
890 This display formatter has highest priority.
891 If it fires, no other display formatter will be called.
891 If it fires, no other display formatter will be called.
892
892
893 Prior to IPython 6.1, `_ipython_display_` was the only way to display custom mime-types
893 Prior to IPython 6.1, `_ipython_display_` was the only way to display custom mime-types
894 without registering a new Formatter.
894 without registering a new Formatter.
895
895
896 IPython 6.1 introduces `_repr_mimebundle_` for displaying custom mime-types,
896 IPython 6.1 introduces `_repr_mimebundle_` for displaying custom mime-types,
897 so `_ipython_display_` should only be used for objects that require unusual
897 so `_ipython_display_` should only be used for objects that require unusual
898 display patterns, such as multiple display calls.
898 display patterns, such as multiple display calls.
899 """
899 """
900 print_method = ObjectName('_ipython_display_')
900 print_method = ObjectName('_ipython_display_')
901 _return_type = (type(None), bool)
901 _return_type = (type(None), bool)
902
902
903 @catch_format_error
903 @catch_format_error
904 def __call__(self, obj):
904 def __call__(self, obj):
905 """Compute the format for an object."""
905 """Compute the format for an object."""
906 if self.enabled:
906 if self.enabled:
907 # lookup registered printer
907 # lookup registered printer
908 try:
908 try:
909 printer = self.lookup(obj)
909 printer = self.lookup(obj)
910 except KeyError:
910 except KeyError:
911 pass
911 pass
912 else:
912 else:
913 printer(obj)
913 printer(obj)
914 return True
914 return True
915 # Finally look for special method names
915 # Finally look for special method names
916 method = get_real_method(obj, self.print_method)
916 method = get_real_method(obj, self.print_method)
917 if method is not None:
917 if method is not None:
918 method()
918 method()
919 return True
919 return True
920
920
921
921
922 class MimeBundleFormatter(BaseFormatter):
922 class MimeBundleFormatter(BaseFormatter):
923 """A Formatter for arbitrary mime-types.
923 """A Formatter for arbitrary mime-types.
924
924
925 Unlike other `_repr_<mimetype>_` methods,
925 Unlike other `_repr_<mimetype>_` methods,
926 `_repr_mimebundle_` should return mime-bundle data,
926 `_repr_mimebundle_` should return mime-bundle data,
927 either the mime-keyed `data` dictionary or the tuple `(data, metadata)`.
927 either the mime-keyed `data` dictionary or the tuple `(data, metadata)`.
928 Any mime-type is valid.
928 Any mime-type is valid.
929
929
930 To define the callables that compute the mime-bundle representation of your
930 To define the callables that compute the mime-bundle representation of your
931 objects, define a :meth:`_repr_mimebundle_` method or use the :meth:`for_type`
931 objects, define a :meth:`_repr_mimebundle_` method or use the :meth:`for_type`
932 or :meth:`for_type_by_name` methods to register functions that handle
932 or :meth:`for_type_by_name` methods to register functions that handle
933 this.
933 this.
934
934
935 .. versionadded:: 6.1
935 .. versionadded:: 6.1
936 """
936 """
937 print_method = ObjectName('_repr_mimebundle_')
937 print_method = ObjectName('_repr_mimebundle_')
938 _return_type = dict
938 _return_type = dict
939
939
940 def _check_return(self, r, obj):
940 def _check_return(self, r, obj):
941 r = super(MimeBundleFormatter, self)._check_return(r, obj)
941 r = super(MimeBundleFormatter, self)._check_return(r, obj)
942 # always return (data, metadata):
942 # always return (data, metadata):
943 if r is None:
943 if r is None:
944 return {}, {}
944 return {}, {}
945 if not isinstance(r, tuple):
945 if not isinstance(r, tuple):
946 return r, {}
946 return r, {}
947 return r
947 return r
948
948
949 @catch_format_error
949 @catch_format_error
950 def __call__(self, obj, include=None, exclude=None):
950 def __call__(self, obj, include=None, exclude=None):
951 """Compute the format for an object.
951 """Compute the format for an object.
952
952
953 Identical to parent's method but we pass extra parameters to the method.
953 Identical to parent's method but we pass extra parameters to the method.
954
954
955 Unlike other _repr_*_ `_repr_mimebundle_` should allow extra kwargs, in
955 Unlike other _repr_*_ `_repr_mimebundle_` should allow extra kwargs, in
956 particular `include` and `exclude`.
956 particular `include` and `exclude`.
957 """
957 """
958 if self.enabled:
958 if self.enabled:
959 # lookup registered printer
959 # lookup registered printer
960 try:
960 try:
961 printer = self.lookup(obj)
961 printer = self.lookup(obj)
962 except KeyError:
962 except KeyError:
963 pass
963 pass
964 else:
964 else:
965 return printer(obj)
965 return printer(obj)
966 # Finally look for special method names
966 # Finally look for special method names
967 method = get_real_method(obj, self.print_method)
967 method = get_real_method(obj, self.print_method)
968
968
969 if method is not None:
969 if method is not None:
970 return method(include=include, exclude=exclude)
970 return method(include=include, exclude=exclude)
971 return None
971 return None
972 else:
972 else:
973 return None
973 return None
974
974
975
975
976 FormatterABC.register(BaseFormatter)
976 FormatterABC.register(BaseFormatter)
977 FormatterABC.register(PlainTextFormatter)
977 FormatterABC.register(PlainTextFormatter)
978 FormatterABC.register(HTMLFormatter)
978 FormatterABC.register(HTMLFormatter)
979 FormatterABC.register(MarkdownFormatter)
979 FormatterABC.register(MarkdownFormatter)
980 FormatterABC.register(SVGFormatter)
980 FormatterABC.register(SVGFormatter)
981 FormatterABC.register(PNGFormatter)
981 FormatterABC.register(PNGFormatter)
982 FormatterABC.register(PDFFormatter)
982 FormatterABC.register(PDFFormatter)
983 FormatterABC.register(JPEGFormatter)
983 FormatterABC.register(JPEGFormatter)
984 FormatterABC.register(LatexFormatter)
984 FormatterABC.register(LatexFormatter)
985 FormatterABC.register(JSONFormatter)
985 FormatterABC.register(JSONFormatter)
986 FormatterABC.register(JavascriptFormatter)
986 FormatterABC.register(JavascriptFormatter)
987 FormatterABC.register(IPythonDisplayFormatter)
987 FormatterABC.register(IPythonDisplayFormatter)
988 FormatterABC.register(MimeBundleFormatter)
988 FormatterABC.register(MimeBundleFormatter)
989
989
990
990
991 def format_display_data(obj, include=None, exclude=None):
991 def format_display_data(obj, include=None, exclude=None):
992 """Return a format data dict for an object.
992 """Return a format data dict for an object.
993
993
994 By default all format types will be computed.
994 By default all format types will be computed.
995
995
996 Parameters
996 Parameters
997 ----------
997 ----------
998 obj : object
998 obj : object
999 The Python object whose format data will be computed.
999 The Python object whose format data will be computed.
1000
1000
1001 Returns
1001 Returns
1002 -------
1002 -------
1003 format_dict : dict
1003 format_dict : dict
1004 A dictionary of key/value pairs, one or each format that was
1004 A dictionary of key/value pairs, one or each format that was
1005 generated for the object. The keys are the format types, which
1005 generated for the object. The keys are the format types, which
1006 will usually be MIME type strings and the values and JSON'able
1006 will usually be MIME type strings and the values and JSON'able
1007 data structure containing the raw data for the representation in
1007 data structure containing the raw data for the representation in
1008 that format.
1008 that format.
1009 include : list or tuple, optional
1009 include : list or tuple, optional
1010 A list of format type strings (MIME types) to include in the
1010 A list of format type strings (MIME types) to include in the
1011 format data dict. If this is set *only* the format types included
1011 format data dict. If this is set *only* the format types included
1012 in this list will be computed.
1012 in this list will be computed.
1013 exclude : list or tuple, optional
1013 exclude : list or tuple, optional
1014 A list of format type string (MIME types) to exclue in the format
1014 A list of format type string (MIME types) to exclude in the format
1015 data dict. If this is set all format types will be computed,
1015 data dict. If this is set all format types will be computed,
1016 except for those included in this argument.
1016 except for those included in this argument.
1017 """
1017 """
1018 from IPython.core.interactiveshell import InteractiveShell
1018 from IPython.core.interactiveshell import InteractiveShell
1019
1019
1020 return InteractiveShell.instance().display_formatter.format(
1020 return InteractiveShell.instance().display_formatter.format(
1021 obj,
1021 obj,
1022 include,
1022 include,
1023 exclude
1023 exclude
1024 )
1024 )
@@ -1,3708 +1,3708 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Main IPython class."""
2 """Main IPython class."""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2008-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13
13
14 import abc
14 import abc
15 import ast
15 import ast
16 import asyncio
16 import asyncio
17 import atexit
17 import atexit
18 import builtins as builtin_mod
18 import builtins as builtin_mod
19 import functools
19 import functools
20 import inspect
20 import inspect
21 import os
21 import os
22 import re
22 import re
23 import runpy
23 import runpy
24 import sys
24 import sys
25 import tempfile
25 import tempfile
26 import traceback
26 import traceback
27 import types
27 import types
28 import subprocess
28 import subprocess
29 import warnings
29 import warnings
30 from io import open as io_open
30 from io import open as io_open
31
31
32 from pickleshare import PickleShareDB
32 from pickleshare import PickleShareDB
33
33
34 from traitlets.config.configurable import SingletonConfigurable
34 from traitlets.config.configurable import SingletonConfigurable
35 from traitlets.utils.importstring import import_item
35 from traitlets.utils.importstring import import_item
36 from IPython.core import oinspect
36 from IPython.core import oinspect
37 from IPython.core import magic
37 from IPython.core import magic
38 from IPython.core import page
38 from IPython.core import page
39 from IPython.core import prefilter
39 from IPython.core import prefilter
40 from IPython.core import ultratb
40 from IPython.core import ultratb
41 from IPython.core.alias import Alias, AliasManager
41 from IPython.core.alias import Alias, AliasManager
42 from IPython.core.autocall import ExitAutocall
42 from IPython.core.autocall import ExitAutocall
43 from IPython.core.builtin_trap import BuiltinTrap
43 from IPython.core.builtin_trap import BuiltinTrap
44 from IPython.core.events import EventManager, available_events
44 from IPython.core.events import EventManager, available_events
45 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
45 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
46 from IPython.core.debugger import Pdb
46 from IPython.core.debugger import Pdb
47 from IPython.core.display_trap import DisplayTrap
47 from IPython.core.display_trap import DisplayTrap
48 from IPython.core.displayhook import DisplayHook
48 from IPython.core.displayhook import DisplayHook
49 from IPython.core.displaypub import DisplayPublisher
49 from IPython.core.displaypub import DisplayPublisher
50 from IPython.core.error import InputRejected, UsageError
50 from IPython.core.error import InputRejected, UsageError
51 from IPython.core.extensions import ExtensionManager
51 from IPython.core.extensions import ExtensionManager
52 from IPython.core.formatters import DisplayFormatter
52 from IPython.core.formatters import DisplayFormatter
53 from IPython.core.history import HistoryManager
53 from IPython.core.history import HistoryManager
54 from IPython.core.inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
54 from IPython.core.inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
55 from IPython.core.logger import Logger
55 from IPython.core.logger import Logger
56 from IPython.core.macro import Macro
56 from IPython.core.macro import Macro
57 from IPython.core.payload import PayloadManager
57 from IPython.core.payload import PayloadManager
58 from IPython.core.prefilter import PrefilterManager
58 from IPython.core.prefilter import PrefilterManager
59 from IPython.core.profiledir import ProfileDir
59 from IPython.core.profiledir import ProfileDir
60 from IPython.core.usage import default_banner
60 from IPython.core.usage import default_banner
61 from IPython.display import display
61 from IPython.display import display
62 from IPython.testing.skipdoctest import skip_doctest
62 from IPython.testing.skipdoctest import skip_doctest
63 from IPython.utils import PyColorize
63 from IPython.utils import PyColorize
64 from IPython.utils import io
64 from IPython.utils import io
65 from IPython.utils import py3compat
65 from IPython.utils import py3compat
66 from IPython.utils import openpy
66 from IPython.utils import openpy
67 from IPython.utils.decorators import undoc
67 from IPython.utils.decorators import undoc
68 from IPython.utils.io import ask_yes_no
68 from IPython.utils.io import ask_yes_no
69 from IPython.utils.ipstruct import Struct
69 from IPython.utils.ipstruct import Struct
70 from IPython.paths import get_ipython_dir
70 from IPython.paths import get_ipython_dir
71 from IPython.utils.path import get_home_dir, get_py_filename, ensure_dir_exists
71 from IPython.utils.path import get_home_dir, get_py_filename, ensure_dir_exists
72 from IPython.utils.process import system, getoutput
72 from IPython.utils.process import system, getoutput
73 from IPython.utils.strdispatch import StrDispatch
73 from IPython.utils.strdispatch import StrDispatch
74 from IPython.utils.syspathcontext import prepended_to_syspath
74 from IPython.utils.syspathcontext import prepended_to_syspath
75 from IPython.utils.text import format_screen, LSString, SList, DollarFormatter
75 from IPython.utils.text import format_screen, LSString, SList, DollarFormatter
76 from IPython.utils.tempdir import TemporaryDirectory
76 from IPython.utils.tempdir import TemporaryDirectory
77 from traitlets import (
77 from traitlets import (
78 Integer, Bool, CaselessStrEnum, Enum, List, Dict, Unicode, Instance, Type,
78 Integer, Bool, CaselessStrEnum, Enum, List, Dict, Unicode, Instance, Type,
79 observe, default, validate, Any
79 observe, default, validate, Any
80 )
80 )
81 from warnings import warn
81 from warnings import warn
82 from logging import error
82 from logging import error
83 import IPython.core.hooks
83 import IPython.core.hooks
84
84
85 from typing import List as ListType, Tuple
85 from typing import List as ListType, Tuple
86 from ast import AST
86 from ast import AST
87
87
88 # NoOpContext is deprecated, but ipykernel imports it from here.
88 # NoOpContext is deprecated, but ipykernel imports it from here.
89 # See https://github.com/ipython/ipykernel/issues/157
89 # See https://github.com/ipython/ipykernel/issues/157
90 from IPython.utils.contexts import NoOpContext
90 from IPython.utils.contexts import NoOpContext
91
91
92 try:
92 try:
93 import docrepr.sphinxify as sphx
93 import docrepr.sphinxify as sphx
94
94
95 def sphinxify(doc):
95 def sphinxify(doc):
96 with TemporaryDirectory() as dirname:
96 with TemporaryDirectory() as dirname:
97 return {
97 return {
98 'text/html': sphx.sphinxify(doc, dirname),
98 'text/html': sphx.sphinxify(doc, dirname),
99 'text/plain': doc
99 'text/plain': doc
100 }
100 }
101 except ImportError:
101 except ImportError:
102 sphinxify = None
102 sphinxify = None
103
103
104
104
105 class ProvisionalWarning(DeprecationWarning):
105 class ProvisionalWarning(DeprecationWarning):
106 """
106 """
107 Warning class for unstable features
107 Warning class for unstable features
108 """
108 """
109 pass
109 pass
110
110
111 if sys.version_info > (3,8):
111 if sys.version_info > (3,8):
112 from ast import Module
112 from ast import Module
113 else :
113 else :
114 # mock the new API, ignore second argument
114 # mock the new API, ignore second argument
115 # see https://github.com/ipython/ipython/issues/11590
115 # see https://github.com/ipython/ipython/issues/11590
116 from ast import Module as OriginalModule
116 from ast import Module as OriginalModule
117 Module = lambda nodelist, type_ignores: OriginalModule(nodelist)
117 Module = lambda nodelist, type_ignores: OriginalModule(nodelist)
118
118
119 if sys.version_info > (3,6):
119 if sys.version_info > (3,6):
120 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
120 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
121 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
121 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
122 else:
122 else:
123 _assign_nodes = (ast.AugAssign, ast.Assign )
123 _assign_nodes = (ast.AugAssign, ast.Assign )
124 _single_targets_nodes = (ast.AugAssign, )
124 _single_targets_nodes = (ast.AugAssign, )
125
125
126 #-----------------------------------------------------------------------------
126 #-----------------------------------------------------------------------------
127 # Await Helpers
127 # Await Helpers
128 #-----------------------------------------------------------------------------
128 #-----------------------------------------------------------------------------
129
129
130 def removed_co_newlocals(function:types.FunctionType) -> types.FunctionType:
130 def removed_co_newlocals(function:types.FunctionType) -> types.FunctionType:
131 """Return a function that do not create a new local scope.
131 """Return a function that do not create a new local scope.
132
132
133 Given a function, create a clone of this function where the co_newlocal flag
133 Given a function, create a clone of this function where the co_newlocal flag
134 has been removed, making this function code actually run in the sourounding
134 has been removed, making this function code actually run in the sourounding
135 scope.
135 scope.
136
136
137 We need this in order to run asynchronous code in user level namespace.
137 We need this in order to run asynchronous code in user level namespace.
138 """
138 """
139 from types import CodeType, FunctionType
139 from types import CodeType, FunctionType
140 CO_NEWLOCALS = 0x0002
140 CO_NEWLOCALS = 0x0002
141 code = function.__code__
141 code = function.__code__
142 new_co_flags = code.co_flags & ~CO_NEWLOCALS
142 new_co_flags = code.co_flags & ~CO_NEWLOCALS
143 if sys.version_info > (3, 8, 0, 'alpha', 3):
143 if sys.version_info > (3, 8, 0, 'alpha', 3):
144 new_code = code.replace(co_flags=new_co_flags)
144 new_code = code.replace(co_flags=new_co_flags)
145 else:
145 else:
146 new_code = CodeType(
146 new_code = CodeType(
147 code.co_argcount,
147 code.co_argcount,
148 code.co_kwonlyargcount,
148 code.co_kwonlyargcount,
149 code.co_nlocals,
149 code.co_nlocals,
150 code.co_stacksize,
150 code.co_stacksize,
151 new_co_flags,
151 new_co_flags,
152 code.co_code,
152 code.co_code,
153 code.co_consts,
153 code.co_consts,
154 code.co_names,
154 code.co_names,
155 code.co_varnames,
155 code.co_varnames,
156 code.co_filename,
156 code.co_filename,
157 code.co_name,
157 code.co_name,
158 code.co_firstlineno,
158 code.co_firstlineno,
159 code.co_lnotab,
159 code.co_lnotab,
160 code.co_freevars,
160 code.co_freevars,
161 code.co_cellvars
161 code.co_cellvars
162 )
162 )
163 return FunctionType(new_code, globals(), function.__name__, function.__defaults__)
163 return FunctionType(new_code, globals(), function.__name__, function.__defaults__)
164
164
165
165
166 # we still need to run things using the asyncio eventloop, but there is no
166 # we still need to run things using the asyncio eventloop, but there is no
167 # async integration
167 # async integration
168 from .async_helpers import (_asyncio_runner, _asyncify, _pseudo_sync_runner)
168 from .async_helpers import (_asyncio_runner, _asyncify, _pseudo_sync_runner)
169 if sys.version_info > (3, 5):
169 if sys.version_info > (3, 5):
170 from .async_helpers import _curio_runner, _trio_runner, _should_be_async
170 from .async_helpers import _curio_runner, _trio_runner, _should_be_async
171 else :
171 else :
172 _curio_runner = _trio_runner = None
172 _curio_runner = _trio_runner = None
173
173
174 def _should_be_async(cell:str)->bool:
174 def _should_be_async(cell:str)->bool:
175 return False
175 return False
176
176
177
177
178 def _ast_asyncify(cell:str, wrapper_name:str) -> ast.Module:
178 def _ast_asyncify(cell:str, wrapper_name:str) -> ast.Module:
179 """
179 """
180 Parse a cell with top-level await and modify the AST to be able to run it later.
180 Parse a cell with top-level await and modify the AST to be able to run it later.
181
181
182 Parameter
182 Parameter
183 ---------
183 ---------
184
184
185 cell: str
185 cell: str
186 The code cell to asyncronify
186 The code cell to asyncronify
187 wrapper_name: str
187 wrapper_name: str
188 The name of the function to be used to wrap the passed `cell`. It is
188 The name of the function to be used to wrap the passed `cell`. It is
189 advised to **not** use a python identifier in order to not pollute the
189 advised to **not** use a python identifier in order to not pollute the
190 global namespace in which the function will be ran.
190 global namespace in which the function will be ran.
191
191
192 Return
192 Return
193 ------
193 ------
194
194
195 A module object AST containing **one** function named `wrapper_name`.
195 A module object AST containing **one** function named `wrapper_name`.
196
196
197 The given code is wrapped in a async-def function, parsed into an AST, and
197 The given code is wrapped in a async-def function, parsed into an AST, and
198 the resulting function definition AST is modified to return the last
198 the resulting function definition AST is modified to return the last
199 expression.
199 expression.
200
200
201 The last expression or await node is moved into a return statement at the
201 The last expression or await node is moved into a return statement at the
202 end of the function, and removed from its original location. If the last
202 end of the function, and removed from its original location. If the last
203 node is not Expr or Await nothing is done.
203 node is not Expr or Await nothing is done.
204
204
205 The function `__code__` will need to be later modified (by
205 The function `__code__` will need to be later modified (by
206 ``removed_co_newlocals``) in a subsequent step to not create new `locals()`
206 ``removed_co_newlocals``) in a subsequent step to not create new `locals()`
207 meaning that the local and global scope are the same, ie as if the body of
207 meaning that the local and global scope are the same, ie as if the body of
208 the function was at module level.
208 the function was at module level.
209
209
210 Lastly a call to `locals()` is made just before the last expression of the
210 Lastly a call to `locals()` is made just before the last expression of the
211 function, or just after the last assignment or statement to make sure the
211 function, or just after the last assignment or statement to make sure the
212 global dict is updated as python function work with a local fast cache which
212 global dict is updated as python function work with a local fast cache which
213 is updated only on `local()` calls.
213 is updated only on `local()` calls.
214 """
214 """
215
215
216 from ast import Expr, Await, Return
216 from ast import Expr, Await, Return
217 if sys.version_info >= (3,8):
217 if sys.version_info >= (3,8):
218 return ast.parse(cell)
218 return ast.parse(cell)
219 tree = ast.parse(_asyncify(cell))
219 tree = ast.parse(_asyncify(cell))
220
220
221 function_def = tree.body[0]
221 function_def = tree.body[0]
222 function_def.name = wrapper_name
222 function_def.name = wrapper_name
223 try_block = function_def.body[0]
223 try_block = function_def.body[0]
224 lastexpr = try_block.body[-1]
224 lastexpr = try_block.body[-1]
225 if isinstance(lastexpr, (Expr, Await)):
225 if isinstance(lastexpr, (Expr, Await)):
226 try_block.body[-1] = Return(lastexpr.value)
226 try_block.body[-1] = Return(lastexpr.value)
227 ast.fix_missing_locations(tree)
227 ast.fix_missing_locations(tree)
228 return tree
228 return tree
229 #-----------------------------------------------------------------------------
229 #-----------------------------------------------------------------------------
230 # Globals
230 # Globals
231 #-----------------------------------------------------------------------------
231 #-----------------------------------------------------------------------------
232
232
233 # compiled regexps for autoindent management
233 # compiled regexps for autoindent management
234 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
234 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
235
235
236 #-----------------------------------------------------------------------------
236 #-----------------------------------------------------------------------------
237 # Utilities
237 # Utilities
238 #-----------------------------------------------------------------------------
238 #-----------------------------------------------------------------------------
239
239
240 @undoc
240 @undoc
241 def softspace(file, newvalue):
241 def softspace(file, newvalue):
242 """Copied from code.py, to remove the dependency"""
242 """Copied from code.py, to remove the dependency"""
243
243
244 oldvalue = 0
244 oldvalue = 0
245 try:
245 try:
246 oldvalue = file.softspace
246 oldvalue = file.softspace
247 except AttributeError:
247 except AttributeError:
248 pass
248 pass
249 try:
249 try:
250 file.softspace = newvalue
250 file.softspace = newvalue
251 except (AttributeError, TypeError):
251 except (AttributeError, TypeError):
252 # "attribute-less object" or "read-only attributes"
252 # "attribute-less object" or "read-only attributes"
253 pass
253 pass
254 return oldvalue
254 return oldvalue
255
255
256 @undoc
256 @undoc
257 def no_op(*a, **kw):
257 def no_op(*a, **kw):
258 pass
258 pass
259
259
260
260
261 class SpaceInInput(Exception): pass
261 class SpaceInInput(Exception): pass
262
262
263
263
264 def get_default_colors():
264 def get_default_colors():
265 "DEPRECATED"
265 "DEPRECATED"
266 warn('get_default_color is deprecated since IPython 5.0, and returns `Neutral` on all platforms.',
266 warn('get_default_color is deprecated since IPython 5.0, and returns `Neutral` on all platforms.',
267 DeprecationWarning, stacklevel=2)
267 DeprecationWarning, stacklevel=2)
268 return 'Neutral'
268 return 'Neutral'
269
269
270
270
271 class SeparateUnicode(Unicode):
271 class SeparateUnicode(Unicode):
272 r"""A Unicode subclass to validate separate_in, separate_out, etc.
272 r"""A Unicode subclass to validate separate_in, separate_out, etc.
273
273
274 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
274 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
275 """
275 """
276
276
277 def validate(self, obj, value):
277 def validate(self, obj, value):
278 if value == '0': value = ''
278 if value == '0': value = ''
279 value = value.replace('\\n','\n')
279 value = value.replace('\\n','\n')
280 return super(SeparateUnicode, self).validate(obj, value)
280 return super(SeparateUnicode, self).validate(obj, value)
281
281
282
282
283 @undoc
283 @undoc
284 class DummyMod(object):
284 class DummyMod(object):
285 """A dummy module used for IPython's interactive module when
285 """A dummy module used for IPython's interactive module when
286 a namespace must be assigned to the module's __dict__."""
286 a namespace must be assigned to the module's __dict__."""
287 __spec__ = None
287 __spec__ = None
288
288
289
289
290 class ExecutionInfo(object):
290 class ExecutionInfo(object):
291 """The arguments used for a call to :meth:`InteractiveShell.run_cell`
291 """The arguments used for a call to :meth:`InteractiveShell.run_cell`
292
292
293 Stores information about what is going to happen.
293 Stores information about what is going to happen.
294 """
294 """
295 raw_cell = None
295 raw_cell = None
296 store_history = False
296 store_history = False
297 silent = False
297 silent = False
298 shell_futures = True
298 shell_futures = True
299
299
300 def __init__(self, raw_cell, store_history, silent, shell_futures):
300 def __init__(self, raw_cell, store_history, silent, shell_futures):
301 self.raw_cell = raw_cell
301 self.raw_cell = raw_cell
302 self.store_history = store_history
302 self.store_history = store_history
303 self.silent = silent
303 self.silent = silent
304 self.shell_futures = shell_futures
304 self.shell_futures = shell_futures
305
305
306 def __repr__(self):
306 def __repr__(self):
307 name = self.__class__.__qualname__
307 name = self.__class__.__qualname__
308 raw_cell = ((self.raw_cell[:50] + '..')
308 raw_cell = ((self.raw_cell[:50] + '..')
309 if len(self.raw_cell) > 50 else self.raw_cell)
309 if len(self.raw_cell) > 50 else self.raw_cell)
310 return '<%s object at %x, raw_cell="%s" store_history=%s silent=%s shell_futures=%s>' %\
310 return '<%s object at %x, raw_cell="%s" store_history=%s silent=%s shell_futures=%s>' %\
311 (name, id(self), raw_cell, self.store_history, self.silent, self.shell_futures)
311 (name, id(self), raw_cell, self.store_history, self.silent, self.shell_futures)
312
312
313
313
314 class ExecutionResult(object):
314 class ExecutionResult(object):
315 """The result of a call to :meth:`InteractiveShell.run_cell`
315 """The result of a call to :meth:`InteractiveShell.run_cell`
316
316
317 Stores information about what took place.
317 Stores information about what took place.
318 """
318 """
319 execution_count = None
319 execution_count = None
320 error_before_exec = None
320 error_before_exec = None
321 error_in_exec = None
321 error_in_exec = None
322 info = None
322 info = None
323 result = None
323 result = None
324
324
325 def __init__(self, info):
325 def __init__(self, info):
326 self.info = info
326 self.info = info
327
327
328 @property
328 @property
329 def success(self):
329 def success(self):
330 return (self.error_before_exec is None) and (self.error_in_exec is None)
330 return (self.error_before_exec is None) and (self.error_in_exec is None)
331
331
332 def raise_error(self):
332 def raise_error(self):
333 """Reraises error if `success` is `False`, otherwise does nothing"""
333 """Reraises error if `success` is `False`, otherwise does nothing"""
334 if self.error_before_exec is not None:
334 if self.error_before_exec is not None:
335 raise self.error_before_exec
335 raise self.error_before_exec
336 if self.error_in_exec is not None:
336 if self.error_in_exec is not None:
337 raise self.error_in_exec
337 raise self.error_in_exec
338
338
339 def __repr__(self):
339 def __repr__(self):
340 name = self.__class__.__qualname__
340 name = self.__class__.__qualname__
341 return '<%s object at %x, execution_count=%s error_before_exec=%s error_in_exec=%s info=%s result=%s>' %\
341 return '<%s object at %x, execution_count=%s error_before_exec=%s error_in_exec=%s info=%s result=%s>' %\
342 (name, id(self), self.execution_count, self.error_before_exec, self.error_in_exec, repr(self.info), repr(self.result))
342 (name, id(self), self.execution_count, self.error_before_exec, self.error_in_exec, repr(self.info), repr(self.result))
343
343
344
344
345 class InteractiveShell(SingletonConfigurable):
345 class InteractiveShell(SingletonConfigurable):
346 """An enhanced, interactive shell for Python."""
346 """An enhanced, interactive shell for Python."""
347
347
348 _instance = None
348 _instance = None
349
349
350 ast_transformers = List([], help=
350 ast_transformers = List([], help=
351 """
351 """
352 A list of ast.NodeTransformer subclass instances, which will be applied
352 A list of ast.NodeTransformer subclass instances, which will be applied
353 to user input before code is run.
353 to user input before code is run.
354 """
354 """
355 ).tag(config=True)
355 ).tag(config=True)
356
356
357 autocall = Enum((0,1,2), default_value=0, help=
357 autocall = Enum((0,1,2), default_value=0, help=
358 """
358 """
359 Make IPython automatically call any callable object even if you didn't
359 Make IPython automatically call any callable object even if you didn't
360 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
360 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
361 automatically. The value can be '0' to disable the feature, '1' for
361 automatically. The value can be '0' to disable the feature, '1' for
362 'smart' autocall, where it is not applied if there are no more
362 'smart' autocall, where it is not applied if there are no more
363 arguments on the line, and '2' for 'full' autocall, where all callable
363 arguments on the line, and '2' for 'full' autocall, where all callable
364 objects are automatically called (even if no arguments are present).
364 objects are automatically called (even if no arguments are present).
365 """
365 """
366 ).tag(config=True)
366 ).tag(config=True)
367
367
368 autoindent = Bool(True, help=
368 autoindent = Bool(True, help=
369 """
369 """
370 Autoindent IPython code entered interactively.
370 Autoindent IPython code entered interactively.
371 """
371 """
372 ).tag(config=True)
372 ).tag(config=True)
373
373
374 autoawait = Bool(True, help=
374 autoawait = Bool(True, help=
375 """
375 """
376 Automatically run await statement in the top level repl.
376 Automatically run await statement in the top level repl.
377 """
377 """
378 ).tag(config=True)
378 ).tag(config=True)
379
379
380 loop_runner_map ={
380 loop_runner_map ={
381 'asyncio':(_asyncio_runner, True),
381 'asyncio':(_asyncio_runner, True),
382 'curio':(_curio_runner, True),
382 'curio':(_curio_runner, True),
383 'trio':(_trio_runner, True),
383 'trio':(_trio_runner, True),
384 'sync': (_pseudo_sync_runner, False)
384 'sync': (_pseudo_sync_runner, False)
385 }
385 }
386
386
387 loop_runner = Any(default_value="IPython.core.interactiveshell._asyncio_runner",
387 loop_runner = Any(default_value="IPython.core.interactiveshell._asyncio_runner",
388 allow_none=True,
388 allow_none=True,
389 help="""Select the loop runner that will be used to execute top-level asynchronous code"""
389 help="""Select the loop runner that will be used to execute top-level asynchronous code"""
390 ).tag(config=True)
390 ).tag(config=True)
391
391
392 @default('loop_runner')
392 @default('loop_runner')
393 def _default_loop_runner(self):
393 def _default_loop_runner(self):
394 return import_item("IPython.core.interactiveshell._asyncio_runner")
394 return import_item("IPython.core.interactiveshell._asyncio_runner")
395
395
396 @validate('loop_runner')
396 @validate('loop_runner')
397 def _import_runner(self, proposal):
397 def _import_runner(self, proposal):
398 if isinstance(proposal.value, str):
398 if isinstance(proposal.value, str):
399 if proposal.value in self.loop_runner_map:
399 if proposal.value in self.loop_runner_map:
400 runner, autoawait = self.loop_runner_map[proposal.value]
400 runner, autoawait = self.loop_runner_map[proposal.value]
401 self.autoawait = autoawait
401 self.autoawait = autoawait
402 return runner
402 return runner
403 runner = import_item(proposal.value)
403 runner = import_item(proposal.value)
404 if not callable(runner):
404 if not callable(runner):
405 raise ValueError('loop_runner must be callable')
405 raise ValueError('loop_runner must be callable')
406 return runner
406 return runner
407 if not callable(proposal.value):
407 if not callable(proposal.value):
408 raise ValueError('loop_runner must be callable')
408 raise ValueError('loop_runner must be callable')
409 return proposal.value
409 return proposal.value
410
410
411 automagic = Bool(True, help=
411 automagic = Bool(True, help=
412 """
412 """
413 Enable magic commands to be called without the leading %.
413 Enable magic commands to be called without the leading %.
414 """
414 """
415 ).tag(config=True)
415 ).tag(config=True)
416
416
417 banner1 = Unicode(default_banner,
417 banner1 = Unicode(default_banner,
418 help="""The part of the banner to be printed before the profile"""
418 help="""The part of the banner to be printed before the profile"""
419 ).tag(config=True)
419 ).tag(config=True)
420 banner2 = Unicode('',
420 banner2 = Unicode('',
421 help="""The part of the banner to be printed after the profile"""
421 help="""The part of the banner to be printed after the profile"""
422 ).tag(config=True)
422 ).tag(config=True)
423
423
424 cache_size = Integer(1000, help=
424 cache_size = Integer(1000, help=
425 """
425 """
426 Set the size of the output cache. The default is 1000, you can
426 Set the size of the output cache. The default is 1000, you can
427 change it permanently in your config file. Setting it to 0 completely
427 change it permanently in your config file. Setting it to 0 completely
428 disables the caching system, and the minimum value accepted is 3 (if
428 disables the caching system, and the minimum value accepted is 3 (if
429 you provide a value less than 3, it is reset to 0 and a warning is
429 you provide a value less than 3, it is reset to 0 and a warning is
430 issued). This limit is defined because otherwise you'll spend more
430 issued). This limit is defined because otherwise you'll spend more
431 time re-flushing a too small cache than working
431 time re-flushing a too small cache than working
432 """
432 """
433 ).tag(config=True)
433 ).tag(config=True)
434 color_info = Bool(True, help=
434 color_info = Bool(True, help=
435 """
435 """
436 Use colors for displaying information about objects. Because this
436 Use colors for displaying information about objects. Because this
437 information is passed through a pager (like 'less'), and some pagers
437 information is passed through a pager (like 'less'), and some pagers
438 get confused with color codes, this capability can be turned off.
438 get confused with color codes, this capability can be turned off.
439 """
439 """
440 ).tag(config=True)
440 ).tag(config=True)
441 colors = CaselessStrEnum(('Neutral', 'NoColor','LightBG','Linux'),
441 colors = CaselessStrEnum(('Neutral', 'NoColor','LightBG','Linux'),
442 default_value='Neutral',
442 default_value='Neutral',
443 help="Set the color scheme (NoColor, Neutral, Linux, or LightBG)."
443 help="Set the color scheme (NoColor, Neutral, Linux, or LightBG)."
444 ).tag(config=True)
444 ).tag(config=True)
445 debug = Bool(False).tag(config=True)
445 debug = Bool(False).tag(config=True)
446 disable_failing_post_execute = Bool(False,
446 disable_failing_post_execute = Bool(False,
447 help="Don't call post-execute functions that have failed in the past."
447 help="Don't call post-execute functions that have failed in the past."
448 ).tag(config=True)
448 ).tag(config=True)
449 display_formatter = Instance(DisplayFormatter, allow_none=True)
449 display_formatter = Instance(DisplayFormatter, allow_none=True)
450 displayhook_class = Type(DisplayHook)
450 displayhook_class = Type(DisplayHook)
451 display_pub_class = Type(DisplayPublisher)
451 display_pub_class = Type(DisplayPublisher)
452
452
453 sphinxify_docstring = Bool(False, help=
453 sphinxify_docstring = Bool(False, help=
454 """
454 """
455 Enables rich html representation of docstrings. (This requires the
455 Enables rich html representation of docstrings. (This requires the
456 docrepr module).
456 docrepr module).
457 """).tag(config=True)
457 """).tag(config=True)
458
458
459 @observe("sphinxify_docstring")
459 @observe("sphinxify_docstring")
460 def _sphinxify_docstring_changed(self, change):
460 def _sphinxify_docstring_changed(self, change):
461 if change['new']:
461 if change['new']:
462 warn("`sphinxify_docstring` is provisional since IPython 5.0 and might change in future versions." , ProvisionalWarning)
462 warn("`sphinxify_docstring` is provisional since IPython 5.0 and might change in future versions." , ProvisionalWarning)
463
463
464 enable_html_pager = Bool(False, help=
464 enable_html_pager = Bool(False, help=
465 """
465 """
466 (Provisional API) enables html representation in mime bundles sent
466 (Provisional API) enables html representation in mime bundles sent
467 to pagers.
467 to pagers.
468 """).tag(config=True)
468 """).tag(config=True)
469
469
470 @observe("enable_html_pager")
470 @observe("enable_html_pager")
471 def _enable_html_pager_changed(self, change):
471 def _enable_html_pager_changed(self, change):
472 if change['new']:
472 if change['new']:
473 warn("`enable_html_pager` is provisional since IPython 5.0 and might change in future versions.", ProvisionalWarning)
473 warn("`enable_html_pager` is provisional since IPython 5.0 and might change in future versions.", ProvisionalWarning)
474
474
475 data_pub_class = None
475 data_pub_class = None
476
476
477 exit_now = Bool(False)
477 exit_now = Bool(False)
478 exiter = Instance(ExitAutocall)
478 exiter = Instance(ExitAutocall)
479 @default('exiter')
479 @default('exiter')
480 def _exiter_default(self):
480 def _exiter_default(self):
481 return ExitAutocall(self)
481 return ExitAutocall(self)
482 # Monotonically increasing execution counter
482 # Monotonically increasing execution counter
483 execution_count = Integer(1)
483 execution_count = Integer(1)
484 filename = Unicode("<ipython console>")
484 filename = Unicode("<ipython console>")
485 ipython_dir= Unicode('').tag(config=True) # Set to get_ipython_dir() in __init__
485 ipython_dir= Unicode('').tag(config=True) # Set to get_ipython_dir() in __init__
486
486
487 # Used to transform cells before running them, and check whether code is complete
487 # Used to transform cells before running them, and check whether code is complete
488 input_transformer_manager = Instance('IPython.core.inputtransformer2.TransformerManager',
488 input_transformer_manager = Instance('IPython.core.inputtransformer2.TransformerManager',
489 ())
489 ())
490
490
491 @property
491 @property
492 def input_transformers_cleanup(self):
492 def input_transformers_cleanup(self):
493 return self.input_transformer_manager.cleanup_transforms
493 return self.input_transformer_manager.cleanup_transforms
494
494
495 input_transformers_post = List([],
495 input_transformers_post = List([],
496 help="A list of string input transformers, to be applied after IPython's "
496 help="A list of string input transformers, to be applied after IPython's "
497 "own input transformations."
497 "own input transformations."
498 )
498 )
499
499
500 @property
500 @property
501 def input_splitter(self):
501 def input_splitter(self):
502 """Make this available for backward compatibility (pre-7.0 release) with existing code.
502 """Make this available for backward compatibility (pre-7.0 release) with existing code.
503
503
504 For example, ipykernel ipykernel currently uses
504 For example, ipykernel ipykernel currently uses
505 `shell.input_splitter.check_complete`
505 `shell.input_splitter.check_complete`
506 """
506 """
507 from warnings import warn
507 from warnings import warn
508 warn("`input_splitter` is deprecated since IPython 7.0, prefer `input_transformer_manager`.",
508 warn("`input_splitter` is deprecated since IPython 7.0, prefer `input_transformer_manager`.",
509 DeprecationWarning, stacklevel=2
509 DeprecationWarning, stacklevel=2
510 )
510 )
511 return self.input_transformer_manager
511 return self.input_transformer_manager
512
512
513 logstart = Bool(False, help=
513 logstart = Bool(False, help=
514 """
514 """
515 Start logging to the default log file in overwrite mode.
515 Start logging to the default log file in overwrite mode.
516 Use `logappend` to specify a log file to **append** logs to.
516 Use `logappend` to specify a log file to **append** logs to.
517 """
517 """
518 ).tag(config=True)
518 ).tag(config=True)
519 logfile = Unicode('', help=
519 logfile = Unicode('', help=
520 """
520 """
521 The name of the logfile to use.
521 The name of the logfile to use.
522 """
522 """
523 ).tag(config=True)
523 ).tag(config=True)
524 logappend = Unicode('', help=
524 logappend = Unicode('', help=
525 """
525 """
526 Start logging to the given file in append mode.
526 Start logging to the given file in append mode.
527 Use `logfile` to specify a log file to **overwrite** logs to.
527 Use `logfile` to specify a log file to **overwrite** logs to.
528 """
528 """
529 ).tag(config=True)
529 ).tag(config=True)
530 object_info_string_level = Enum((0,1,2), default_value=0,
530 object_info_string_level = Enum((0,1,2), default_value=0,
531 ).tag(config=True)
531 ).tag(config=True)
532 pdb = Bool(False, help=
532 pdb = Bool(False, help=
533 """
533 """
534 Automatically call the pdb debugger after every exception.
534 Automatically call the pdb debugger after every exception.
535 """
535 """
536 ).tag(config=True)
536 ).tag(config=True)
537 display_page = Bool(False,
537 display_page = Bool(False,
538 help="""If True, anything that would be passed to the pager
538 help="""If True, anything that would be passed to the pager
539 will be displayed as regular output instead."""
539 will be displayed as regular output instead."""
540 ).tag(config=True)
540 ).tag(config=True)
541
541
542 # deprecated prompt traits:
542 # deprecated prompt traits:
543
543
544 prompt_in1 = Unicode('In [\\#]: ',
544 prompt_in1 = Unicode('In [\\#]: ',
545 help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly."
545 help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly."
546 ).tag(config=True)
546 ).tag(config=True)
547 prompt_in2 = Unicode(' .\\D.: ',
547 prompt_in2 = Unicode(' .\\D.: ',
548 help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly."
548 help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly."
549 ).tag(config=True)
549 ).tag(config=True)
550 prompt_out = Unicode('Out[\\#]: ',
550 prompt_out = Unicode('Out[\\#]: ',
551 help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly."
551 help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly."
552 ).tag(config=True)
552 ).tag(config=True)
553 prompts_pad_left = Bool(True,
553 prompts_pad_left = Bool(True,
554 help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly."
554 help="Deprecated since IPython 4.0 and ignored since 5.0, set TerminalInteractiveShell.prompts object directly."
555 ).tag(config=True)
555 ).tag(config=True)
556
556
557 @observe('prompt_in1', 'prompt_in2', 'prompt_out', 'prompt_pad_left')
557 @observe('prompt_in1', 'prompt_in2', 'prompt_out', 'prompt_pad_left')
558 def _prompt_trait_changed(self, change):
558 def _prompt_trait_changed(self, change):
559 name = change['name']
559 name = change['name']
560 warn("InteractiveShell.{name} is deprecated since IPython 4.0"
560 warn("InteractiveShell.{name} is deprecated since IPython 4.0"
561 " and ignored since 5.0, set TerminalInteractiveShell.prompts"
561 " and ignored since 5.0, set TerminalInteractiveShell.prompts"
562 " object directly.".format(name=name))
562 " object directly.".format(name=name))
563
563
564 # protect against weird cases where self.config may not exist:
564 # protect against weird cases where self.config may not exist:
565
565
566 show_rewritten_input = Bool(True,
566 show_rewritten_input = Bool(True,
567 help="Show rewritten input, e.g. for autocall."
567 help="Show rewritten input, e.g. for autocall."
568 ).tag(config=True)
568 ).tag(config=True)
569
569
570 quiet = Bool(False).tag(config=True)
570 quiet = Bool(False).tag(config=True)
571
571
572 history_length = Integer(10000,
572 history_length = Integer(10000,
573 help='Total length of command history'
573 help='Total length of command history'
574 ).tag(config=True)
574 ).tag(config=True)
575
575
576 history_load_length = Integer(1000, help=
576 history_load_length = Integer(1000, help=
577 """
577 """
578 The number of saved history entries to be loaded
578 The number of saved history entries to be loaded
579 into the history buffer at startup.
579 into the history buffer at startup.
580 """
580 """
581 ).tag(config=True)
581 ).tag(config=True)
582
582
583 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'],
583 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'],
584 default_value='last_expr',
584 default_value='last_expr',
585 help="""
585 help="""
586 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying
586 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying
587 which nodes should be run interactively (displaying output from expressions).
587 which nodes should be run interactively (displaying output from expressions).
588 """
588 """
589 ).tag(config=True)
589 ).tag(config=True)
590
590
591 # TODO: this part of prompt management should be moved to the frontends.
591 # TODO: this part of prompt management should be moved to the frontends.
592 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
592 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
593 separate_in = SeparateUnicode('\n').tag(config=True)
593 separate_in = SeparateUnicode('\n').tag(config=True)
594 separate_out = SeparateUnicode('').tag(config=True)
594 separate_out = SeparateUnicode('').tag(config=True)
595 separate_out2 = SeparateUnicode('').tag(config=True)
595 separate_out2 = SeparateUnicode('').tag(config=True)
596 wildcards_case_sensitive = Bool(True).tag(config=True)
596 wildcards_case_sensitive = Bool(True).tag(config=True)
597 xmode = CaselessStrEnum(('Context', 'Plain', 'Verbose', 'Minimal'),
597 xmode = CaselessStrEnum(('Context', 'Plain', 'Verbose', 'Minimal'),
598 default_value='Context',
598 default_value='Context',
599 help="Switch modes for the IPython exception handlers."
599 help="Switch modes for the IPython exception handlers."
600 ).tag(config=True)
600 ).tag(config=True)
601
601
602 # Subcomponents of InteractiveShell
602 # Subcomponents of InteractiveShell
603 alias_manager = Instance('IPython.core.alias.AliasManager', allow_none=True)
603 alias_manager = Instance('IPython.core.alias.AliasManager', allow_none=True)
604 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
604 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
605 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap', allow_none=True)
605 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap', allow_none=True)
606 display_trap = Instance('IPython.core.display_trap.DisplayTrap', allow_none=True)
606 display_trap = Instance('IPython.core.display_trap.DisplayTrap', allow_none=True)
607 extension_manager = Instance('IPython.core.extensions.ExtensionManager', allow_none=True)
607 extension_manager = Instance('IPython.core.extensions.ExtensionManager', allow_none=True)
608 payload_manager = Instance('IPython.core.payload.PayloadManager', allow_none=True)
608 payload_manager = Instance('IPython.core.payload.PayloadManager', allow_none=True)
609 history_manager = Instance('IPython.core.history.HistoryAccessorBase', allow_none=True)
609 history_manager = Instance('IPython.core.history.HistoryAccessorBase', allow_none=True)
610 magics_manager = Instance('IPython.core.magic.MagicsManager', allow_none=True)
610 magics_manager = Instance('IPython.core.magic.MagicsManager', allow_none=True)
611
611
612 profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True)
612 profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True)
613 @property
613 @property
614 def profile(self):
614 def profile(self):
615 if self.profile_dir is not None:
615 if self.profile_dir is not None:
616 name = os.path.basename(self.profile_dir.location)
616 name = os.path.basename(self.profile_dir.location)
617 return name.replace('profile_','')
617 return name.replace('profile_','')
618
618
619
619
620 # Private interface
620 # Private interface
621 _post_execute = Dict()
621 _post_execute = Dict()
622
622
623 # Tracks any GUI loop loaded for pylab
623 # Tracks any GUI loop loaded for pylab
624 pylab_gui_select = None
624 pylab_gui_select = None
625
625
626 last_execution_succeeded = Bool(True, help='Did last executed command succeeded')
626 last_execution_succeeded = Bool(True, help='Did last executed command succeeded')
627
627
628 last_execution_result = Instance('IPython.core.interactiveshell.ExecutionResult', help='Result of executing the last command', allow_none=True)
628 last_execution_result = Instance('IPython.core.interactiveshell.ExecutionResult', help='Result of executing the last command', allow_none=True)
629
629
630 def __init__(self, ipython_dir=None, profile_dir=None,
630 def __init__(self, ipython_dir=None, profile_dir=None,
631 user_module=None, user_ns=None,
631 user_module=None, user_ns=None,
632 custom_exceptions=((), None), **kwargs):
632 custom_exceptions=((), None), **kwargs):
633
633
634 # This is where traits with a config_key argument are updated
634 # This is where traits with a config_key argument are updated
635 # from the values on config.
635 # from the values on config.
636 super(InteractiveShell, self).__init__(**kwargs)
636 super(InteractiveShell, self).__init__(**kwargs)
637 if 'PromptManager' in self.config:
637 if 'PromptManager' in self.config:
638 warn('As of IPython 5.0 `PromptManager` config will have no effect'
638 warn('As of IPython 5.0 `PromptManager` config will have no effect'
639 ' and has been replaced by TerminalInteractiveShell.prompts_class')
639 ' and has been replaced by TerminalInteractiveShell.prompts_class')
640 self.configurables = [self]
640 self.configurables = [self]
641
641
642 # These are relatively independent and stateless
642 # These are relatively independent and stateless
643 self.init_ipython_dir(ipython_dir)
643 self.init_ipython_dir(ipython_dir)
644 self.init_profile_dir(profile_dir)
644 self.init_profile_dir(profile_dir)
645 self.init_instance_attrs()
645 self.init_instance_attrs()
646 self.init_environment()
646 self.init_environment()
647
647
648 # Check if we're in a virtualenv, and set up sys.path.
648 # Check if we're in a virtualenv, and set up sys.path.
649 self.init_virtualenv()
649 self.init_virtualenv()
650
650
651 # Create namespaces (user_ns, user_global_ns, etc.)
651 # Create namespaces (user_ns, user_global_ns, etc.)
652 self.init_create_namespaces(user_module, user_ns)
652 self.init_create_namespaces(user_module, user_ns)
653 # This has to be done after init_create_namespaces because it uses
653 # This has to be done after init_create_namespaces because it uses
654 # something in self.user_ns, but before init_sys_modules, which
654 # something in self.user_ns, but before init_sys_modules, which
655 # is the first thing to modify sys.
655 # is the first thing to modify sys.
656 # TODO: When we override sys.stdout and sys.stderr before this class
656 # TODO: When we override sys.stdout and sys.stderr before this class
657 # is created, we are saving the overridden ones here. Not sure if this
657 # is created, we are saving the overridden ones here. Not sure if this
658 # is what we want to do.
658 # is what we want to do.
659 self.save_sys_module_state()
659 self.save_sys_module_state()
660 self.init_sys_modules()
660 self.init_sys_modules()
661
661
662 # While we're trying to have each part of the code directly access what
662 # While we're trying to have each part of the code directly access what
663 # it needs without keeping redundant references to objects, we have too
663 # it needs without keeping redundant references to objects, we have too
664 # much legacy code that expects ip.db to exist.
664 # much legacy code that expects ip.db to exist.
665 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
665 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
666
666
667 self.init_history()
667 self.init_history()
668 self.init_encoding()
668 self.init_encoding()
669 self.init_prefilter()
669 self.init_prefilter()
670
670
671 self.init_syntax_highlighting()
671 self.init_syntax_highlighting()
672 self.init_hooks()
672 self.init_hooks()
673 self.init_events()
673 self.init_events()
674 self.init_pushd_popd_magic()
674 self.init_pushd_popd_magic()
675 self.init_user_ns()
675 self.init_user_ns()
676 self.init_logger()
676 self.init_logger()
677 self.init_builtins()
677 self.init_builtins()
678
678
679 # The following was in post_config_initialization
679 # The following was in post_config_initialization
680 self.init_inspector()
680 self.init_inspector()
681 self.raw_input_original = input
681 self.raw_input_original = input
682 self.init_completer()
682 self.init_completer()
683 # TODO: init_io() needs to happen before init_traceback handlers
683 # TODO: init_io() needs to happen before init_traceback handlers
684 # because the traceback handlers hardcode the stdout/stderr streams.
684 # because the traceback handlers hardcode the stdout/stderr streams.
685 # This logic in in debugger.Pdb and should eventually be changed.
685 # This logic in in debugger.Pdb and should eventually be changed.
686 self.init_io()
686 self.init_io()
687 self.init_traceback_handlers(custom_exceptions)
687 self.init_traceback_handlers(custom_exceptions)
688 self.init_prompts()
688 self.init_prompts()
689 self.init_display_formatter()
689 self.init_display_formatter()
690 self.init_display_pub()
690 self.init_display_pub()
691 self.init_data_pub()
691 self.init_data_pub()
692 self.init_displayhook()
692 self.init_displayhook()
693 self.init_magics()
693 self.init_magics()
694 self.init_alias()
694 self.init_alias()
695 self.init_logstart()
695 self.init_logstart()
696 self.init_pdb()
696 self.init_pdb()
697 self.init_extension_manager()
697 self.init_extension_manager()
698 self.init_payload()
698 self.init_payload()
699 self.init_deprecation_warnings()
699 self.init_deprecation_warnings()
700 self.hooks.late_startup_hook()
700 self.hooks.late_startup_hook()
701 self.events.trigger('shell_initialized', self)
701 self.events.trigger('shell_initialized', self)
702 atexit.register(self.atexit_operations)
702 atexit.register(self.atexit_operations)
703
703
704 def get_ipython(self):
704 def get_ipython(self):
705 """Return the currently running IPython instance."""
705 """Return the currently running IPython instance."""
706 return self
706 return self
707
707
708 #-------------------------------------------------------------------------
708 #-------------------------------------------------------------------------
709 # Trait changed handlers
709 # Trait changed handlers
710 #-------------------------------------------------------------------------
710 #-------------------------------------------------------------------------
711 @observe('ipython_dir')
711 @observe('ipython_dir')
712 def _ipython_dir_changed(self, change):
712 def _ipython_dir_changed(self, change):
713 ensure_dir_exists(change['new'])
713 ensure_dir_exists(change['new'])
714
714
715 def set_autoindent(self,value=None):
715 def set_autoindent(self,value=None):
716 """Set the autoindent flag.
716 """Set the autoindent flag.
717
717
718 If called with no arguments, it acts as a toggle."""
718 If called with no arguments, it acts as a toggle."""
719 if value is None:
719 if value is None:
720 self.autoindent = not self.autoindent
720 self.autoindent = not self.autoindent
721 else:
721 else:
722 self.autoindent = value
722 self.autoindent = value
723
723
724 #-------------------------------------------------------------------------
724 #-------------------------------------------------------------------------
725 # init_* methods called by __init__
725 # init_* methods called by __init__
726 #-------------------------------------------------------------------------
726 #-------------------------------------------------------------------------
727
727
728 def init_ipython_dir(self, ipython_dir):
728 def init_ipython_dir(self, ipython_dir):
729 if ipython_dir is not None:
729 if ipython_dir is not None:
730 self.ipython_dir = ipython_dir
730 self.ipython_dir = ipython_dir
731 return
731 return
732
732
733 self.ipython_dir = get_ipython_dir()
733 self.ipython_dir = get_ipython_dir()
734
734
735 def init_profile_dir(self, profile_dir):
735 def init_profile_dir(self, profile_dir):
736 if profile_dir is not None:
736 if profile_dir is not None:
737 self.profile_dir = profile_dir
737 self.profile_dir = profile_dir
738 return
738 return
739 self.profile_dir =\
739 self.profile_dir =\
740 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
740 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
741
741
742 def init_instance_attrs(self):
742 def init_instance_attrs(self):
743 self.more = False
743 self.more = False
744
744
745 # command compiler
745 # command compiler
746 self.compile = CachingCompiler()
746 self.compile = CachingCompiler()
747
747
748 # Make an empty namespace, which extension writers can rely on both
748 # Make an empty namespace, which extension writers can rely on both
749 # existing and NEVER being used by ipython itself. This gives them a
749 # existing and NEVER being used by ipython itself. This gives them a
750 # convenient location for storing additional information and state
750 # convenient location for storing additional information and state
751 # their extensions may require, without fear of collisions with other
751 # their extensions may require, without fear of collisions with other
752 # ipython names that may develop later.
752 # ipython names that may develop later.
753 self.meta = Struct()
753 self.meta = Struct()
754
754
755 # Temporary files used for various purposes. Deleted at exit.
755 # Temporary files used for various purposes. Deleted at exit.
756 self.tempfiles = []
756 self.tempfiles = []
757 self.tempdirs = []
757 self.tempdirs = []
758
758
759 # keep track of where we started running (mainly for crash post-mortem)
759 # keep track of where we started running (mainly for crash post-mortem)
760 # This is not being used anywhere currently.
760 # This is not being used anywhere currently.
761 self.starting_dir = os.getcwd()
761 self.starting_dir = os.getcwd()
762
762
763 # Indentation management
763 # Indentation management
764 self.indent_current_nsp = 0
764 self.indent_current_nsp = 0
765
765
766 # Dict to track post-execution functions that have been registered
766 # Dict to track post-execution functions that have been registered
767 self._post_execute = {}
767 self._post_execute = {}
768
768
769 def init_environment(self):
769 def init_environment(self):
770 """Any changes we need to make to the user's environment."""
770 """Any changes we need to make to the user's environment."""
771 pass
771 pass
772
772
773 def init_encoding(self):
773 def init_encoding(self):
774 # Get system encoding at startup time. Certain terminals (like Emacs
774 # Get system encoding at startup time. Certain terminals (like Emacs
775 # under Win32 have it set to None, and we need to have a known valid
775 # under Win32 have it set to None, and we need to have a known valid
776 # encoding to use in the raw_input() method
776 # encoding to use in the raw_input() method
777 try:
777 try:
778 self.stdin_encoding = sys.stdin.encoding or 'ascii'
778 self.stdin_encoding = sys.stdin.encoding or 'ascii'
779 except AttributeError:
779 except AttributeError:
780 self.stdin_encoding = 'ascii'
780 self.stdin_encoding = 'ascii'
781
781
782
782
783 @observe('colors')
783 @observe('colors')
784 def init_syntax_highlighting(self, changes=None):
784 def init_syntax_highlighting(self, changes=None):
785 # Python source parser/formatter for syntax highlighting
785 # Python source parser/formatter for syntax highlighting
786 pyformat = PyColorize.Parser(style=self.colors, parent=self).format
786 pyformat = PyColorize.Parser(style=self.colors, parent=self).format
787 self.pycolorize = lambda src: pyformat(src,'str')
787 self.pycolorize = lambda src: pyformat(src,'str')
788
788
789 def refresh_style(self):
789 def refresh_style(self):
790 # No-op here, used in subclass
790 # No-op here, used in subclass
791 pass
791 pass
792
792
793 def init_pushd_popd_magic(self):
793 def init_pushd_popd_magic(self):
794 # for pushd/popd management
794 # for pushd/popd management
795 self.home_dir = get_home_dir()
795 self.home_dir = get_home_dir()
796
796
797 self.dir_stack = []
797 self.dir_stack = []
798
798
799 def init_logger(self):
799 def init_logger(self):
800 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
800 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
801 logmode='rotate')
801 logmode='rotate')
802
802
803 def init_logstart(self):
803 def init_logstart(self):
804 """Initialize logging in case it was requested at the command line.
804 """Initialize logging in case it was requested at the command line.
805 """
805 """
806 if self.logappend:
806 if self.logappend:
807 self.magic('logstart %s append' % self.logappend)
807 self.magic('logstart %s append' % self.logappend)
808 elif self.logfile:
808 elif self.logfile:
809 self.magic('logstart %s' % self.logfile)
809 self.magic('logstart %s' % self.logfile)
810 elif self.logstart:
810 elif self.logstart:
811 self.magic('logstart')
811 self.magic('logstart')
812
812
813 def init_deprecation_warnings(self):
813 def init_deprecation_warnings(self):
814 """
814 """
815 register default filter for deprecation warning.
815 register default filter for deprecation warning.
816
816
817 This will allow deprecation warning of function used interactively to show
817 This will allow deprecation warning of function used interactively to show
818 warning to users, and still hide deprecation warning from libraries import.
818 warning to users, and still hide deprecation warning from libraries import.
819 """
819 """
820 if sys.version_info < (3,7):
820 if sys.version_info < (3,7):
821 warnings.filterwarnings("default", category=DeprecationWarning, module=self.user_ns.get("__name__"))
821 warnings.filterwarnings("default", category=DeprecationWarning, module=self.user_ns.get("__name__"))
822
822
823
823
824 def init_builtins(self):
824 def init_builtins(self):
825 # A single, static flag that we set to True. Its presence indicates
825 # A single, static flag that we set to True. Its presence indicates
826 # that an IPython shell has been created, and we make no attempts at
826 # that an IPython shell has been created, and we make no attempts at
827 # removing on exit or representing the existence of more than one
827 # removing on exit or representing the existence of more than one
828 # IPython at a time.
828 # IPython at a time.
829 builtin_mod.__dict__['__IPYTHON__'] = True
829 builtin_mod.__dict__['__IPYTHON__'] = True
830 builtin_mod.__dict__['display'] = display
830 builtin_mod.__dict__['display'] = display
831
831
832 self.builtin_trap = BuiltinTrap(shell=self)
832 self.builtin_trap = BuiltinTrap(shell=self)
833
833
834 @observe('colors')
834 @observe('colors')
835 def init_inspector(self, changes=None):
835 def init_inspector(self, changes=None):
836 # Object inspector
836 # Object inspector
837 self.inspector = oinspect.Inspector(oinspect.InspectColors,
837 self.inspector = oinspect.Inspector(oinspect.InspectColors,
838 PyColorize.ANSICodeColors,
838 PyColorize.ANSICodeColors,
839 self.colors,
839 self.colors,
840 self.object_info_string_level)
840 self.object_info_string_level)
841
841
842 def init_io(self):
842 def init_io(self):
843 # This will just use sys.stdout and sys.stderr. If you want to
843 # This will just use sys.stdout and sys.stderr. If you want to
844 # override sys.stdout and sys.stderr themselves, you need to do that
844 # override sys.stdout and sys.stderr themselves, you need to do that
845 # *before* instantiating this class, because io holds onto
845 # *before* instantiating this class, because io holds onto
846 # references to the underlying streams.
846 # references to the underlying streams.
847 # io.std* are deprecated, but don't show our own deprecation warnings
847 # io.std* are deprecated, but don't show our own deprecation warnings
848 # during initialization of the deprecated API.
848 # during initialization of the deprecated API.
849 with warnings.catch_warnings():
849 with warnings.catch_warnings():
850 warnings.simplefilter('ignore', DeprecationWarning)
850 warnings.simplefilter('ignore', DeprecationWarning)
851 io.stdout = io.IOStream(sys.stdout)
851 io.stdout = io.IOStream(sys.stdout)
852 io.stderr = io.IOStream(sys.stderr)
852 io.stderr = io.IOStream(sys.stderr)
853
853
854 def init_prompts(self):
854 def init_prompts(self):
855 # Set system prompts, so that scripts can decide if they are running
855 # Set system prompts, so that scripts can decide if they are running
856 # interactively.
856 # interactively.
857 sys.ps1 = 'In : '
857 sys.ps1 = 'In : '
858 sys.ps2 = '...: '
858 sys.ps2 = '...: '
859 sys.ps3 = 'Out: '
859 sys.ps3 = 'Out: '
860
860
861 def init_display_formatter(self):
861 def init_display_formatter(self):
862 self.display_formatter = DisplayFormatter(parent=self)
862 self.display_formatter = DisplayFormatter(parent=self)
863 self.configurables.append(self.display_formatter)
863 self.configurables.append(self.display_formatter)
864
864
865 def init_display_pub(self):
865 def init_display_pub(self):
866 self.display_pub = self.display_pub_class(parent=self)
866 self.display_pub = self.display_pub_class(parent=self)
867 self.configurables.append(self.display_pub)
867 self.configurables.append(self.display_pub)
868
868
869 def init_data_pub(self):
869 def init_data_pub(self):
870 if not self.data_pub_class:
870 if not self.data_pub_class:
871 self.data_pub = None
871 self.data_pub = None
872 return
872 return
873 self.data_pub = self.data_pub_class(parent=self)
873 self.data_pub = self.data_pub_class(parent=self)
874 self.configurables.append(self.data_pub)
874 self.configurables.append(self.data_pub)
875
875
876 def init_displayhook(self):
876 def init_displayhook(self):
877 # Initialize displayhook, set in/out prompts and printing system
877 # Initialize displayhook, set in/out prompts and printing system
878 self.displayhook = self.displayhook_class(
878 self.displayhook = self.displayhook_class(
879 parent=self,
879 parent=self,
880 shell=self,
880 shell=self,
881 cache_size=self.cache_size,
881 cache_size=self.cache_size,
882 )
882 )
883 self.configurables.append(self.displayhook)
883 self.configurables.append(self.displayhook)
884 # This is a context manager that installs/revmoes the displayhook at
884 # This is a context manager that installs/revmoes the displayhook at
885 # the appropriate time.
885 # the appropriate time.
886 self.display_trap = DisplayTrap(hook=self.displayhook)
886 self.display_trap = DisplayTrap(hook=self.displayhook)
887
887
888 def init_virtualenv(self):
888 def init_virtualenv(self):
889 """Add a virtualenv to sys.path so the user can import modules from it.
889 """Add a virtualenv to sys.path so the user can import modules from it.
890 This isn't perfect: it doesn't use the Python interpreter with which the
890 This isn't perfect: it doesn't use the Python interpreter with which the
891 virtualenv was built, and it ignores the --no-site-packages option. A
891 virtualenv was built, and it ignores the --no-site-packages option. A
892 warning will appear suggesting the user installs IPython in the
892 warning will appear suggesting the user installs IPython in the
893 virtualenv, but for many cases, it probably works well enough.
893 virtualenv, but for many cases, it probably works well enough.
894
894
895 Adapted from code snippets online.
895 Adapted from code snippets online.
896
896
897 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
897 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
898 """
898 """
899 if 'VIRTUAL_ENV' not in os.environ:
899 if 'VIRTUAL_ENV' not in os.environ:
900 # Not in a virtualenv
900 # Not in a virtualenv
901 return
901 return
902
902
903 p = os.path.normcase(sys.executable)
903 p = os.path.normcase(sys.executable)
904 p_venv = os.path.normcase(os.environ['VIRTUAL_ENV'])
904 p_venv = os.path.normcase(os.environ['VIRTUAL_ENV'])
905
905
906 # executable path should end like /bin/python or \\scripts\\python.exe
906 # executable path should end like /bin/python or \\scripts\\python.exe
907 p_exe_up2 = os.path.dirname(os.path.dirname(p))
907 p_exe_up2 = os.path.dirname(os.path.dirname(p))
908 if p_exe_up2 and os.path.exists(p_venv) and os.path.samefile(p_exe_up2, p_venv):
908 if p_exe_up2 and os.path.exists(p_venv) and os.path.samefile(p_exe_up2, p_venv):
909 # Our exe is inside the virtualenv, don't need to do anything.
909 # Our exe is inside the virtualenv, don't need to do anything.
910 return
910 return
911
911
912 # fallback venv detection:
912 # fallback venv detection:
913 # stdlib venv may symlink sys.executable, so we can't use realpath.
913 # stdlib venv may symlink sys.executable, so we can't use realpath.
914 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
914 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
915 # So we just check every item in the symlink tree (generally <= 3)
915 # So we just check every item in the symlink tree (generally <= 3)
916 paths = [p]
916 paths = [p]
917 while os.path.islink(p):
917 while os.path.islink(p):
918 p = os.path.normcase(os.path.join(os.path.dirname(p), os.readlink(p)))
918 p = os.path.normcase(os.path.join(os.path.dirname(p), os.readlink(p)))
919 paths.append(p)
919 paths.append(p)
920
920
921 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
921 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
922 if p_venv.startswith('\\cygdrive'):
922 if p_venv.startswith('\\cygdrive'):
923 p_venv = p_venv[11:]
923 p_venv = p_venv[11:]
924 elif len(p_venv) >= 2 and p_venv[1] == ':':
924 elif len(p_venv) >= 2 and p_venv[1] == ':':
925 p_venv = p_venv[2:]
925 p_venv = p_venv[2:]
926
926
927 if any(p_venv in p for p in paths):
927 if any(p_venv in p for p in paths):
928 # Running properly in the virtualenv, don't need to do anything
928 # Running properly in the virtualenv, don't need to do anything
929 return
929 return
930
930
931 warn("Attempting to work in a virtualenv. If you encounter problems, please "
931 warn("Attempting to work in a virtualenv. If you encounter problems, please "
932 "install IPython inside the virtualenv.")
932 "install IPython inside the virtualenv.")
933 if sys.platform == "win32":
933 if sys.platform == "win32":
934 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
934 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
935 else:
935 else:
936 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
936 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
937 'python%d.%d' % sys.version_info[:2], 'site-packages')
937 'python%d.%d' % sys.version_info[:2], 'site-packages')
938
938
939 import site
939 import site
940 sys.path.insert(0, virtual_env)
940 sys.path.insert(0, virtual_env)
941 site.addsitedir(virtual_env)
941 site.addsitedir(virtual_env)
942
942
943 #-------------------------------------------------------------------------
943 #-------------------------------------------------------------------------
944 # Things related to injections into the sys module
944 # Things related to injections into the sys module
945 #-------------------------------------------------------------------------
945 #-------------------------------------------------------------------------
946
946
947 def save_sys_module_state(self):
947 def save_sys_module_state(self):
948 """Save the state of hooks in the sys module.
948 """Save the state of hooks in the sys module.
949
949
950 This has to be called after self.user_module is created.
950 This has to be called after self.user_module is created.
951 """
951 """
952 self._orig_sys_module_state = {'stdin': sys.stdin,
952 self._orig_sys_module_state = {'stdin': sys.stdin,
953 'stdout': sys.stdout,
953 'stdout': sys.stdout,
954 'stderr': sys.stderr,
954 'stderr': sys.stderr,
955 'excepthook': sys.excepthook}
955 'excepthook': sys.excepthook}
956 self._orig_sys_modules_main_name = self.user_module.__name__
956 self._orig_sys_modules_main_name = self.user_module.__name__
957 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
957 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
958
958
959 def restore_sys_module_state(self):
959 def restore_sys_module_state(self):
960 """Restore the state of the sys module."""
960 """Restore the state of the sys module."""
961 try:
961 try:
962 for k, v in self._orig_sys_module_state.items():
962 for k, v in self._orig_sys_module_state.items():
963 setattr(sys, k, v)
963 setattr(sys, k, v)
964 except AttributeError:
964 except AttributeError:
965 pass
965 pass
966 # Reset what what done in self.init_sys_modules
966 # Reset what what done in self.init_sys_modules
967 if self._orig_sys_modules_main_mod is not None:
967 if self._orig_sys_modules_main_mod is not None:
968 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
968 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
969
969
970 #-------------------------------------------------------------------------
970 #-------------------------------------------------------------------------
971 # Things related to the banner
971 # Things related to the banner
972 #-------------------------------------------------------------------------
972 #-------------------------------------------------------------------------
973
973
974 @property
974 @property
975 def banner(self):
975 def banner(self):
976 banner = self.banner1
976 banner = self.banner1
977 if self.profile and self.profile != 'default':
977 if self.profile and self.profile != 'default':
978 banner += '\nIPython profile: %s\n' % self.profile
978 banner += '\nIPython profile: %s\n' % self.profile
979 if self.banner2:
979 if self.banner2:
980 banner += '\n' + self.banner2
980 banner += '\n' + self.banner2
981 return banner
981 return banner
982
982
983 def show_banner(self, banner=None):
983 def show_banner(self, banner=None):
984 if banner is None:
984 if banner is None:
985 banner = self.banner
985 banner = self.banner
986 sys.stdout.write(banner)
986 sys.stdout.write(banner)
987
987
988 #-------------------------------------------------------------------------
988 #-------------------------------------------------------------------------
989 # Things related to hooks
989 # Things related to hooks
990 #-------------------------------------------------------------------------
990 #-------------------------------------------------------------------------
991
991
992 def init_hooks(self):
992 def init_hooks(self):
993 # hooks holds pointers used for user-side customizations
993 # hooks holds pointers used for user-side customizations
994 self.hooks = Struct()
994 self.hooks = Struct()
995
995
996 self.strdispatchers = {}
996 self.strdispatchers = {}
997
997
998 # Set all default hooks, defined in the IPython.hooks module.
998 # Set all default hooks, defined in the IPython.hooks module.
999 hooks = IPython.core.hooks
999 hooks = IPython.core.hooks
1000 for hook_name in hooks.__all__:
1000 for hook_name in hooks.__all__:
1001 # default hooks have priority 100, i.e. low; user hooks should have
1001 # default hooks have priority 100, i.e. low; user hooks should have
1002 # 0-100 priority
1002 # 0-100 priority
1003 self.set_hook(hook_name,getattr(hooks,hook_name), 100, _warn_deprecated=False)
1003 self.set_hook(hook_name,getattr(hooks,hook_name), 100, _warn_deprecated=False)
1004
1004
1005 if self.display_page:
1005 if self.display_page:
1006 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
1006 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
1007
1007
1008 def set_hook(self,name,hook, priority=50, str_key=None, re_key=None,
1008 def set_hook(self,name,hook, priority=50, str_key=None, re_key=None,
1009 _warn_deprecated=True):
1009 _warn_deprecated=True):
1010 """set_hook(name,hook) -> sets an internal IPython hook.
1010 """set_hook(name,hook) -> sets an internal IPython hook.
1011
1011
1012 IPython exposes some of its internal API as user-modifiable hooks. By
1012 IPython exposes some of its internal API as user-modifiable hooks. By
1013 adding your function to one of these hooks, you can modify IPython's
1013 adding your function to one of these hooks, you can modify IPython's
1014 behavior to call at runtime your own routines."""
1014 behavior to call at runtime your own routines."""
1015
1015
1016 # At some point in the future, this should validate the hook before it
1016 # At some point in the future, this should validate the hook before it
1017 # accepts it. Probably at least check that the hook takes the number
1017 # accepts it. Probably at least check that the hook takes the number
1018 # of args it's supposed to.
1018 # of args it's supposed to.
1019
1019
1020 f = types.MethodType(hook,self)
1020 f = types.MethodType(hook,self)
1021
1021
1022 # check if the hook is for strdispatcher first
1022 # check if the hook is for strdispatcher first
1023 if str_key is not None:
1023 if str_key is not None:
1024 sdp = self.strdispatchers.get(name, StrDispatch())
1024 sdp = self.strdispatchers.get(name, StrDispatch())
1025 sdp.add_s(str_key, f, priority )
1025 sdp.add_s(str_key, f, priority )
1026 self.strdispatchers[name] = sdp
1026 self.strdispatchers[name] = sdp
1027 return
1027 return
1028 if re_key is not None:
1028 if re_key is not None:
1029 sdp = self.strdispatchers.get(name, StrDispatch())
1029 sdp = self.strdispatchers.get(name, StrDispatch())
1030 sdp.add_re(re.compile(re_key), f, priority )
1030 sdp.add_re(re.compile(re_key), f, priority )
1031 self.strdispatchers[name] = sdp
1031 self.strdispatchers[name] = sdp
1032 return
1032 return
1033
1033
1034 dp = getattr(self.hooks, name, None)
1034 dp = getattr(self.hooks, name, None)
1035 if name not in IPython.core.hooks.__all__:
1035 if name not in IPython.core.hooks.__all__:
1036 print("Warning! Hook '%s' is not one of %s" % \
1036 print("Warning! Hook '%s' is not one of %s" % \
1037 (name, IPython.core.hooks.__all__ ))
1037 (name, IPython.core.hooks.__all__ ))
1038
1038
1039 if _warn_deprecated and (name in IPython.core.hooks.deprecated):
1039 if _warn_deprecated and (name in IPython.core.hooks.deprecated):
1040 alternative = IPython.core.hooks.deprecated[name]
1040 alternative = IPython.core.hooks.deprecated[name]
1041 warn("Hook {} is deprecated. Use {} instead.".format(name, alternative), stacklevel=2)
1041 warn("Hook {} is deprecated. Use {} instead.".format(name, alternative), stacklevel=2)
1042
1042
1043 if not dp:
1043 if not dp:
1044 dp = IPython.core.hooks.CommandChainDispatcher()
1044 dp = IPython.core.hooks.CommandChainDispatcher()
1045
1045
1046 try:
1046 try:
1047 dp.add(f,priority)
1047 dp.add(f,priority)
1048 except AttributeError:
1048 except AttributeError:
1049 # it was not commandchain, plain old func - replace
1049 # it was not commandchain, plain old func - replace
1050 dp = f
1050 dp = f
1051
1051
1052 setattr(self.hooks,name, dp)
1052 setattr(self.hooks,name, dp)
1053
1053
1054 #-------------------------------------------------------------------------
1054 #-------------------------------------------------------------------------
1055 # Things related to events
1055 # Things related to events
1056 #-------------------------------------------------------------------------
1056 #-------------------------------------------------------------------------
1057
1057
1058 def init_events(self):
1058 def init_events(self):
1059 self.events = EventManager(self, available_events)
1059 self.events = EventManager(self, available_events)
1060
1060
1061 self.events.register("pre_execute", self._clear_warning_registry)
1061 self.events.register("pre_execute", self._clear_warning_registry)
1062
1062
1063 def register_post_execute(self, func):
1063 def register_post_execute(self, func):
1064 """DEPRECATED: Use ip.events.register('post_run_cell', func)
1064 """DEPRECATED: Use ip.events.register('post_run_cell', func)
1065
1065
1066 Register a function for calling after code execution.
1066 Register a function for calling after code execution.
1067 """
1067 """
1068 warn("ip.register_post_execute is deprecated, use "
1068 warn("ip.register_post_execute is deprecated, use "
1069 "ip.events.register('post_run_cell', func) instead.", stacklevel=2)
1069 "ip.events.register('post_run_cell', func) instead.", stacklevel=2)
1070 self.events.register('post_run_cell', func)
1070 self.events.register('post_run_cell', func)
1071
1071
1072 def _clear_warning_registry(self):
1072 def _clear_warning_registry(self):
1073 # clear the warning registry, so that different code blocks with
1073 # clear the warning registry, so that different code blocks with
1074 # overlapping line number ranges don't cause spurious suppression of
1074 # overlapping line number ranges don't cause spurious suppression of
1075 # warnings (see gh-6611 for details)
1075 # warnings (see gh-6611 for details)
1076 if "__warningregistry__" in self.user_global_ns:
1076 if "__warningregistry__" in self.user_global_ns:
1077 del self.user_global_ns["__warningregistry__"]
1077 del self.user_global_ns["__warningregistry__"]
1078
1078
1079 #-------------------------------------------------------------------------
1079 #-------------------------------------------------------------------------
1080 # Things related to the "main" module
1080 # Things related to the "main" module
1081 #-------------------------------------------------------------------------
1081 #-------------------------------------------------------------------------
1082
1082
1083 def new_main_mod(self, filename, modname):
1083 def new_main_mod(self, filename, modname):
1084 """Return a new 'main' module object for user code execution.
1084 """Return a new 'main' module object for user code execution.
1085
1085
1086 ``filename`` should be the path of the script which will be run in the
1086 ``filename`` should be the path of the script which will be run in the
1087 module. Requests with the same filename will get the same module, with
1087 module. Requests with the same filename will get the same module, with
1088 its namespace cleared.
1088 its namespace cleared.
1089
1089
1090 ``modname`` should be the module name - normally either '__main__' or
1090 ``modname`` should be the module name - normally either '__main__' or
1091 the basename of the file without the extension.
1091 the basename of the file without the extension.
1092
1092
1093 When scripts are executed via %run, we must keep a reference to their
1093 When scripts are executed via %run, we must keep a reference to their
1094 __main__ module around so that Python doesn't
1094 __main__ module around so that Python doesn't
1095 clear it, rendering references to module globals useless.
1095 clear it, rendering references to module globals useless.
1096
1096
1097 This method keeps said reference in a private dict, keyed by the
1097 This method keeps said reference in a private dict, keyed by the
1098 absolute path of the script. This way, for multiple executions of the
1098 absolute path of the script. This way, for multiple executions of the
1099 same script we only keep one copy of the namespace (the last one),
1099 same script we only keep one copy of the namespace (the last one),
1100 thus preventing memory leaks from old references while allowing the
1100 thus preventing memory leaks from old references while allowing the
1101 objects from the last execution to be accessible.
1101 objects from the last execution to be accessible.
1102 """
1102 """
1103 filename = os.path.abspath(filename)
1103 filename = os.path.abspath(filename)
1104 try:
1104 try:
1105 main_mod = self._main_mod_cache[filename]
1105 main_mod = self._main_mod_cache[filename]
1106 except KeyError:
1106 except KeyError:
1107 main_mod = self._main_mod_cache[filename] = types.ModuleType(
1107 main_mod = self._main_mod_cache[filename] = types.ModuleType(
1108 modname,
1108 modname,
1109 doc="Module created for script run in IPython")
1109 doc="Module created for script run in IPython")
1110 else:
1110 else:
1111 main_mod.__dict__.clear()
1111 main_mod.__dict__.clear()
1112 main_mod.__name__ = modname
1112 main_mod.__name__ = modname
1113
1113
1114 main_mod.__file__ = filename
1114 main_mod.__file__ = filename
1115 # It seems pydoc (and perhaps others) needs any module instance to
1115 # It seems pydoc (and perhaps others) needs any module instance to
1116 # implement a __nonzero__ method
1116 # implement a __nonzero__ method
1117 main_mod.__nonzero__ = lambda : True
1117 main_mod.__nonzero__ = lambda : True
1118
1118
1119 return main_mod
1119 return main_mod
1120
1120
1121 def clear_main_mod_cache(self):
1121 def clear_main_mod_cache(self):
1122 """Clear the cache of main modules.
1122 """Clear the cache of main modules.
1123
1123
1124 Mainly for use by utilities like %reset.
1124 Mainly for use by utilities like %reset.
1125
1125
1126 Examples
1126 Examples
1127 --------
1127 --------
1128
1128
1129 In [15]: import IPython
1129 In [15]: import IPython
1130
1130
1131 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
1131 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
1132
1132
1133 In [17]: len(_ip._main_mod_cache) > 0
1133 In [17]: len(_ip._main_mod_cache) > 0
1134 Out[17]: True
1134 Out[17]: True
1135
1135
1136 In [18]: _ip.clear_main_mod_cache()
1136 In [18]: _ip.clear_main_mod_cache()
1137
1137
1138 In [19]: len(_ip._main_mod_cache) == 0
1138 In [19]: len(_ip._main_mod_cache) == 0
1139 Out[19]: True
1139 Out[19]: True
1140 """
1140 """
1141 self._main_mod_cache.clear()
1141 self._main_mod_cache.clear()
1142
1142
1143 #-------------------------------------------------------------------------
1143 #-------------------------------------------------------------------------
1144 # Things related to debugging
1144 # Things related to debugging
1145 #-------------------------------------------------------------------------
1145 #-------------------------------------------------------------------------
1146
1146
1147 def init_pdb(self):
1147 def init_pdb(self):
1148 # Set calling of pdb on exceptions
1148 # Set calling of pdb on exceptions
1149 # self.call_pdb is a property
1149 # self.call_pdb is a property
1150 self.call_pdb = self.pdb
1150 self.call_pdb = self.pdb
1151
1151
1152 def _get_call_pdb(self):
1152 def _get_call_pdb(self):
1153 return self._call_pdb
1153 return self._call_pdb
1154
1154
1155 def _set_call_pdb(self,val):
1155 def _set_call_pdb(self,val):
1156
1156
1157 if val not in (0,1,False,True):
1157 if val not in (0,1,False,True):
1158 raise ValueError('new call_pdb value must be boolean')
1158 raise ValueError('new call_pdb value must be boolean')
1159
1159
1160 # store value in instance
1160 # store value in instance
1161 self._call_pdb = val
1161 self._call_pdb = val
1162
1162
1163 # notify the actual exception handlers
1163 # notify the actual exception handlers
1164 self.InteractiveTB.call_pdb = val
1164 self.InteractiveTB.call_pdb = val
1165
1165
1166 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1166 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1167 'Control auto-activation of pdb at exceptions')
1167 'Control auto-activation of pdb at exceptions')
1168
1168
1169 def debugger(self,force=False):
1169 def debugger(self,force=False):
1170 """Call the pdb debugger.
1170 """Call the pdb debugger.
1171
1171
1172 Keywords:
1172 Keywords:
1173
1173
1174 - force(False): by default, this routine checks the instance call_pdb
1174 - force(False): by default, this routine checks the instance call_pdb
1175 flag and does not actually invoke the debugger if the flag is false.
1175 flag and does not actually invoke the debugger if the flag is false.
1176 The 'force' option forces the debugger to activate even if the flag
1176 The 'force' option forces the debugger to activate even if the flag
1177 is false.
1177 is false.
1178 """
1178 """
1179
1179
1180 if not (force or self.call_pdb):
1180 if not (force or self.call_pdb):
1181 return
1181 return
1182
1182
1183 if not hasattr(sys,'last_traceback'):
1183 if not hasattr(sys,'last_traceback'):
1184 error('No traceback has been produced, nothing to debug.')
1184 error('No traceback has been produced, nothing to debug.')
1185 return
1185 return
1186
1186
1187 self.InteractiveTB.debugger(force=True)
1187 self.InteractiveTB.debugger(force=True)
1188
1188
1189 #-------------------------------------------------------------------------
1189 #-------------------------------------------------------------------------
1190 # Things related to IPython's various namespaces
1190 # Things related to IPython's various namespaces
1191 #-------------------------------------------------------------------------
1191 #-------------------------------------------------------------------------
1192 default_user_namespaces = True
1192 default_user_namespaces = True
1193
1193
1194 def init_create_namespaces(self, user_module=None, user_ns=None):
1194 def init_create_namespaces(self, user_module=None, user_ns=None):
1195 # Create the namespace where the user will operate. user_ns is
1195 # Create the namespace where the user will operate. user_ns is
1196 # normally the only one used, and it is passed to the exec calls as
1196 # normally the only one used, and it is passed to the exec calls as
1197 # the locals argument. But we do carry a user_global_ns namespace
1197 # the locals argument. But we do carry a user_global_ns namespace
1198 # given as the exec 'globals' argument, This is useful in embedding
1198 # given as the exec 'globals' argument, This is useful in embedding
1199 # situations where the ipython shell opens in a context where the
1199 # situations where the ipython shell opens in a context where the
1200 # distinction between locals and globals is meaningful. For
1200 # distinction between locals and globals is meaningful. For
1201 # non-embedded contexts, it is just the same object as the user_ns dict.
1201 # non-embedded contexts, it is just the same object as the user_ns dict.
1202
1202
1203 # FIXME. For some strange reason, __builtins__ is showing up at user
1203 # FIXME. For some strange reason, __builtins__ is showing up at user
1204 # level as a dict instead of a module. This is a manual fix, but I
1204 # level as a dict instead of a module. This is a manual fix, but I
1205 # should really track down where the problem is coming from. Alex
1205 # should really track down where the problem is coming from. Alex
1206 # Schmolck reported this problem first.
1206 # Schmolck reported this problem first.
1207
1207
1208 # A useful post by Alex Martelli on this topic:
1208 # A useful post by Alex Martelli on this topic:
1209 # Re: inconsistent value from __builtins__
1209 # Re: inconsistent value from __builtins__
1210 # Von: Alex Martelli <aleaxit@yahoo.com>
1210 # Von: Alex Martelli <aleaxit@yahoo.com>
1211 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1211 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1212 # Gruppen: comp.lang.python
1212 # Gruppen: comp.lang.python
1213
1213
1214 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1214 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1215 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1215 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1216 # > <type 'dict'>
1216 # > <type 'dict'>
1217 # > >>> print type(__builtins__)
1217 # > >>> print type(__builtins__)
1218 # > <type 'module'>
1218 # > <type 'module'>
1219 # > Is this difference in return value intentional?
1219 # > Is this difference in return value intentional?
1220
1220
1221 # Well, it's documented that '__builtins__' can be either a dictionary
1221 # Well, it's documented that '__builtins__' can be either a dictionary
1222 # or a module, and it's been that way for a long time. Whether it's
1222 # or a module, and it's been that way for a long time. Whether it's
1223 # intentional (or sensible), I don't know. In any case, the idea is
1223 # intentional (or sensible), I don't know. In any case, the idea is
1224 # that if you need to access the built-in namespace directly, you
1224 # that if you need to access the built-in namespace directly, you
1225 # should start with "import __builtin__" (note, no 's') which will
1225 # should start with "import __builtin__" (note, no 's') which will
1226 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1226 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1227
1227
1228 # These routines return a properly built module and dict as needed by
1228 # These routines return a properly built module and dict as needed by
1229 # the rest of the code, and can also be used by extension writers to
1229 # the rest of the code, and can also be used by extension writers to
1230 # generate properly initialized namespaces.
1230 # generate properly initialized namespaces.
1231 if (user_ns is not None) or (user_module is not None):
1231 if (user_ns is not None) or (user_module is not None):
1232 self.default_user_namespaces = False
1232 self.default_user_namespaces = False
1233 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1233 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1234
1234
1235 # A record of hidden variables we have added to the user namespace, so
1235 # A record of hidden variables we have added to the user namespace, so
1236 # we can list later only variables defined in actual interactive use.
1236 # we can list later only variables defined in actual interactive use.
1237 self.user_ns_hidden = {}
1237 self.user_ns_hidden = {}
1238
1238
1239 # Now that FakeModule produces a real module, we've run into a nasty
1239 # Now that FakeModule produces a real module, we've run into a nasty
1240 # problem: after script execution (via %run), the module where the user
1240 # problem: after script execution (via %run), the module where the user
1241 # code ran is deleted. Now that this object is a true module (needed
1241 # code ran is deleted. Now that this object is a true module (needed
1242 # so doctest and other tools work correctly), the Python module
1242 # so doctest and other tools work correctly), the Python module
1243 # teardown mechanism runs over it, and sets to None every variable
1243 # teardown mechanism runs over it, and sets to None every variable
1244 # present in that module. Top-level references to objects from the
1244 # present in that module. Top-level references to objects from the
1245 # script survive, because the user_ns is updated with them. However,
1245 # script survive, because the user_ns is updated with them. However,
1246 # calling functions defined in the script that use other things from
1246 # calling functions defined in the script that use other things from
1247 # the script will fail, because the function's closure had references
1247 # the script will fail, because the function's closure had references
1248 # to the original objects, which are now all None. So we must protect
1248 # to the original objects, which are now all None. So we must protect
1249 # these modules from deletion by keeping a cache.
1249 # these modules from deletion by keeping a cache.
1250 #
1250 #
1251 # To avoid keeping stale modules around (we only need the one from the
1251 # To avoid keeping stale modules around (we only need the one from the
1252 # last run), we use a dict keyed with the full path to the script, so
1252 # last run), we use a dict keyed with the full path to the script, so
1253 # only the last version of the module is held in the cache. Note,
1253 # only the last version of the module is held in the cache. Note,
1254 # however, that we must cache the module *namespace contents* (their
1254 # however, that we must cache the module *namespace contents* (their
1255 # __dict__). Because if we try to cache the actual modules, old ones
1255 # __dict__). Because if we try to cache the actual modules, old ones
1256 # (uncached) could be destroyed while still holding references (such as
1256 # (uncached) could be destroyed while still holding references (such as
1257 # those held by GUI objects that tend to be long-lived)>
1257 # those held by GUI objects that tend to be long-lived)>
1258 #
1258 #
1259 # The %reset command will flush this cache. See the cache_main_mod()
1259 # The %reset command will flush this cache. See the cache_main_mod()
1260 # and clear_main_mod_cache() methods for details on use.
1260 # and clear_main_mod_cache() methods for details on use.
1261
1261
1262 # This is the cache used for 'main' namespaces
1262 # This is the cache used for 'main' namespaces
1263 self._main_mod_cache = {}
1263 self._main_mod_cache = {}
1264
1264
1265 # A table holding all the namespaces IPython deals with, so that
1265 # A table holding all the namespaces IPython deals with, so that
1266 # introspection facilities can search easily.
1266 # introspection facilities can search easily.
1267 self.ns_table = {'user_global':self.user_module.__dict__,
1267 self.ns_table = {'user_global':self.user_module.__dict__,
1268 'user_local':self.user_ns,
1268 'user_local':self.user_ns,
1269 'builtin':builtin_mod.__dict__
1269 'builtin':builtin_mod.__dict__
1270 }
1270 }
1271
1271
1272 @property
1272 @property
1273 def user_global_ns(self):
1273 def user_global_ns(self):
1274 return self.user_module.__dict__
1274 return self.user_module.__dict__
1275
1275
1276 def prepare_user_module(self, user_module=None, user_ns=None):
1276 def prepare_user_module(self, user_module=None, user_ns=None):
1277 """Prepare the module and namespace in which user code will be run.
1277 """Prepare the module and namespace in which user code will be run.
1278
1278
1279 When IPython is started normally, both parameters are None: a new module
1279 When IPython is started normally, both parameters are None: a new module
1280 is created automatically, and its __dict__ used as the namespace.
1280 is created automatically, and its __dict__ used as the namespace.
1281
1281
1282 If only user_module is provided, its __dict__ is used as the namespace.
1282 If only user_module is provided, its __dict__ is used as the namespace.
1283 If only user_ns is provided, a dummy module is created, and user_ns
1283 If only user_ns is provided, a dummy module is created, and user_ns
1284 becomes the global namespace. If both are provided (as they may be
1284 becomes the global namespace. If both are provided (as they may be
1285 when embedding), user_ns is the local namespace, and user_module
1285 when embedding), user_ns is the local namespace, and user_module
1286 provides the global namespace.
1286 provides the global namespace.
1287
1287
1288 Parameters
1288 Parameters
1289 ----------
1289 ----------
1290 user_module : module, optional
1290 user_module : module, optional
1291 The current user module in which IPython is being run. If None,
1291 The current user module in which IPython is being run. If None,
1292 a clean module will be created.
1292 a clean module will be created.
1293 user_ns : dict, optional
1293 user_ns : dict, optional
1294 A namespace in which to run interactive commands.
1294 A namespace in which to run interactive commands.
1295
1295
1296 Returns
1296 Returns
1297 -------
1297 -------
1298 A tuple of user_module and user_ns, each properly initialised.
1298 A tuple of user_module and user_ns, each properly initialised.
1299 """
1299 """
1300 if user_module is None and user_ns is not None:
1300 if user_module is None and user_ns is not None:
1301 user_ns.setdefault("__name__", "__main__")
1301 user_ns.setdefault("__name__", "__main__")
1302 user_module = DummyMod()
1302 user_module = DummyMod()
1303 user_module.__dict__ = user_ns
1303 user_module.__dict__ = user_ns
1304
1304
1305 if user_module is None:
1305 if user_module is None:
1306 user_module = types.ModuleType("__main__",
1306 user_module = types.ModuleType("__main__",
1307 doc="Automatically created module for IPython interactive environment")
1307 doc="Automatically created module for IPython interactive environment")
1308
1308
1309 # We must ensure that __builtin__ (without the final 's') is always
1309 # We must ensure that __builtin__ (without the final 's') is always
1310 # available and pointing to the __builtin__ *module*. For more details:
1310 # available and pointing to the __builtin__ *module*. For more details:
1311 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1311 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1312 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1312 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1313 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1313 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1314
1314
1315 if user_ns is None:
1315 if user_ns is None:
1316 user_ns = user_module.__dict__
1316 user_ns = user_module.__dict__
1317
1317
1318 return user_module, user_ns
1318 return user_module, user_ns
1319
1319
1320 def init_sys_modules(self):
1320 def init_sys_modules(self):
1321 # We need to insert into sys.modules something that looks like a
1321 # We need to insert into sys.modules something that looks like a
1322 # module but which accesses the IPython namespace, for shelve and
1322 # module but which accesses the IPython namespace, for shelve and
1323 # pickle to work interactively. Normally they rely on getting
1323 # pickle to work interactively. Normally they rely on getting
1324 # everything out of __main__, but for embedding purposes each IPython
1324 # everything out of __main__, but for embedding purposes each IPython
1325 # instance has its own private namespace, so we can't go shoving
1325 # instance has its own private namespace, so we can't go shoving
1326 # everything into __main__.
1326 # everything into __main__.
1327
1327
1328 # note, however, that we should only do this for non-embedded
1328 # note, however, that we should only do this for non-embedded
1329 # ipythons, which really mimic the __main__.__dict__ with their own
1329 # ipythons, which really mimic the __main__.__dict__ with their own
1330 # namespace. Embedded instances, on the other hand, should not do
1330 # namespace. Embedded instances, on the other hand, should not do
1331 # this because they need to manage the user local/global namespaces
1331 # this because they need to manage the user local/global namespaces
1332 # only, but they live within a 'normal' __main__ (meaning, they
1332 # only, but they live within a 'normal' __main__ (meaning, they
1333 # shouldn't overtake the execution environment of the script they're
1333 # shouldn't overtake the execution environment of the script they're
1334 # embedded in).
1334 # embedded in).
1335
1335
1336 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1336 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1337 main_name = self.user_module.__name__
1337 main_name = self.user_module.__name__
1338 sys.modules[main_name] = self.user_module
1338 sys.modules[main_name] = self.user_module
1339
1339
1340 def init_user_ns(self):
1340 def init_user_ns(self):
1341 """Initialize all user-visible namespaces to their minimum defaults.
1341 """Initialize all user-visible namespaces to their minimum defaults.
1342
1342
1343 Certain history lists are also initialized here, as they effectively
1343 Certain history lists are also initialized here, as they effectively
1344 act as user namespaces.
1344 act as user namespaces.
1345
1345
1346 Notes
1346 Notes
1347 -----
1347 -----
1348 All data structures here are only filled in, they are NOT reset by this
1348 All data structures here are only filled in, they are NOT reset by this
1349 method. If they were not empty before, data will simply be added to
1349 method. If they were not empty before, data will simply be added to
1350 them.
1350 them.
1351 """
1351 """
1352 # This function works in two parts: first we put a few things in
1352 # This function works in two parts: first we put a few things in
1353 # user_ns, and we sync that contents into user_ns_hidden so that these
1353 # user_ns, and we sync that contents into user_ns_hidden so that these
1354 # initial variables aren't shown by %who. After the sync, we add the
1354 # initial variables aren't shown by %who. After the sync, we add the
1355 # rest of what we *do* want the user to see with %who even on a new
1355 # rest of what we *do* want the user to see with %who even on a new
1356 # session (probably nothing, so they really only see their own stuff)
1356 # session (probably nothing, so they really only see their own stuff)
1357
1357
1358 # The user dict must *always* have a __builtin__ reference to the
1358 # The user dict must *always* have a __builtin__ reference to the
1359 # Python standard __builtin__ namespace, which must be imported.
1359 # Python standard __builtin__ namespace, which must be imported.
1360 # This is so that certain operations in prompt evaluation can be
1360 # This is so that certain operations in prompt evaluation can be
1361 # reliably executed with builtins. Note that we can NOT use
1361 # reliably executed with builtins. Note that we can NOT use
1362 # __builtins__ (note the 's'), because that can either be a dict or a
1362 # __builtins__ (note the 's'), because that can either be a dict or a
1363 # module, and can even mutate at runtime, depending on the context
1363 # module, and can even mutate at runtime, depending on the context
1364 # (Python makes no guarantees on it). In contrast, __builtin__ is
1364 # (Python makes no guarantees on it). In contrast, __builtin__ is
1365 # always a module object, though it must be explicitly imported.
1365 # always a module object, though it must be explicitly imported.
1366
1366
1367 # For more details:
1367 # For more details:
1368 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1368 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1369 ns = {}
1369 ns = {}
1370
1370
1371 # make global variables for user access to the histories
1371 # make global variables for user access to the histories
1372 ns['_ih'] = self.history_manager.input_hist_parsed
1372 ns['_ih'] = self.history_manager.input_hist_parsed
1373 ns['_oh'] = self.history_manager.output_hist
1373 ns['_oh'] = self.history_manager.output_hist
1374 ns['_dh'] = self.history_manager.dir_hist
1374 ns['_dh'] = self.history_manager.dir_hist
1375
1375
1376 # user aliases to input and output histories. These shouldn't show up
1376 # user aliases to input and output histories. These shouldn't show up
1377 # in %who, as they can have very large reprs.
1377 # in %who, as they can have very large reprs.
1378 ns['In'] = self.history_manager.input_hist_parsed
1378 ns['In'] = self.history_manager.input_hist_parsed
1379 ns['Out'] = self.history_manager.output_hist
1379 ns['Out'] = self.history_manager.output_hist
1380
1380
1381 # Store myself as the public api!!!
1381 # Store myself as the public api!!!
1382 ns['get_ipython'] = self.get_ipython
1382 ns['get_ipython'] = self.get_ipython
1383
1383
1384 ns['exit'] = self.exiter
1384 ns['exit'] = self.exiter
1385 ns['quit'] = self.exiter
1385 ns['quit'] = self.exiter
1386
1386
1387 # Sync what we've added so far to user_ns_hidden so these aren't seen
1387 # Sync what we've added so far to user_ns_hidden so these aren't seen
1388 # by %who
1388 # by %who
1389 self.user_ns_hidden.update(ns)
1389 self.user_ns_hidden.update(ns)
1390
1390
1391 # Anything put into ns now would show up in %who. Think twice before
1391 # Anything put into ns now would show up in %who. Think twice before
1392 # putting anything here, as we really want %who to show the user their
1392 # putting anything here, as we really want %who to show the user their
1393 # stuff, not our variables.
1393 # stuff, not our variables.
1394
1394
1395 # Finally, update the real user's namespace
1395 # Finally, update the real user's namespace
1396 self.user_ns.update(ns)
1396 self.user_ns.update(ns)
1397
1397
1398 @property
1398 @property
1399 def all_ns_refs(self):
1399 def all_ns_refs(self):
1400 """Get a list of references to all the namespace dictionaries in which
1400 """Get a list of references to all the namespace dictionaries in which
1401 IPython might store a user-created object.
1401 IPython might store a user-created object.
1402
1402
1403 Note that this does not include the displayhook, which also caches
1403 Note that this does not include the displayhook, which also caches
1404 objects from the output."""
1404 objects from the output."""
1405 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1405 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1406 [m.__dict__ for m in self._main_mod_cache.values()]
1406 [m.__dict__ for m in self._main_mod_cache.values()]
1407
1407
1408 def reset(self, new_session=True):
1408 def reset(self, new_session=True):
1409 """Clear all internal namespaces, and attempt to release references to
1409 """Clear all internal namespaces, and attempt to release references to
1410 user objects.
1410 user objects.
1411
1411
1412 If new_session is True, a new history session will be opened.
1412 If new_session is True, a new history session will be opened.
1413 """
1413 """
1414 # Clear histories
1414 # Clear histories
1415 self.history_manager.reset(new_session)
1415 self.history_manager.reset(new_session)
1416 # Reset counter used to index all histories
1416 # Reset counter used to index all histories
1417 if new_session:
1417 if new_session:
1418 self.execution_count = 1
1418 self.execution_count = 1
1419
1419
1420 # Reset last execution result
1420 # Reset last execution result
1421 self.last_execution_succeeded = True
1421 self.last_execution_succeeded = True
1422 self.last_execution_result = None
1422 self.last_execution_result = None
1423
1423
1424 # Flush cached output items
1424 # Flush cached output items
1425 if self.displayhook.do_full_cache:
1425 if self.displayhook.do_full_cache:
1426 self.displayhook.flush()
1426 self.displayhook.flush()
1427
1427
1428 # The main execution namespaces must be cleared very carefully,
1428 # The main execution namespaces must be cleared very carefully,
1429 # skipping the deletion of the builtin-related keys, because doing so
1429 # skipping the deletion of the builtin-related keys, because doing so
1430 # would cause errors in many object's __del__ methods.
1430 # would cause errors in many object's __del__ methods.
1431 if self.user_ns is not self.user_global_ns:
1431 if self.user_ns is not self.user_global_ns:
1432 self.user_ns.clear()
1432 self.user_ns.clear()
1433 ns = self.user_global_ns
1433 ns = self.user_global_ns
1434 drop_keys = set(ns.keys())
1434 drop_keys = set(ns.keys())
1435 drop_keys.discard('__builtin__')
1435 drop_keys.discard('__builtin__')
1436 drop_keys.discard('__builtins__')
1436 drop_keys.discard('__builtins__')
1437 drop_keys.discard('__name__')
1437 drop_keys.discard('__name__')
1438 for k in drop_keys:
1438 for k in drop_keys:
1439 del ns[k]
1439 del ns[k]
1440
1440
1441 self.user_ns_hidden.clear()
1441 self.user_ns_hidden.clear()
1442
1442
1443 # Restore the user namespaces to minimal usability
1443 # Restore the user namespaces to minimal usability
1444 self.init_user_ns()
1444 self.init_user_ns()
1445
1445
1446 # Restore the default and user aliases
1446 # Restore the default and user aliases
1447 self.alias_manager.clear_aliases()
1447 self.alias_manager.clear_aliases()
1448 self.alias_manager.init_aliases()
1448 self.alias_manager.init_aliases()
1449
1449
1450 # Now define aliases that only make sense on the terminal, because they
1450 # Now define aliases that only make sense on the terminal, because they
1451 # need direct access to the console in a way that we can't emulate in
1451 # need direct access to the console in a way that we can't emulate in
1452 # GUI or web frontend
1452 # GUI or web frontend
1453 if os.name == 'posix':
1453 if os.name == 'posix':
1454 for cmd in ('clear', 'more', 'less', 'man'):
1454 for cmd in ('clear', 'more', 'less', 'man'):
1455 if cmd not in self.magics_manager.magics['line']:
1455 if cmd not in self.magics_manager.magics['line']:
1456 self.alias_manager.soft_define_alias(cmd, cmd)
1456 self.alias_manager.soft_define_alias(cmd, cmd)
1457
1457
1458 # Flush the private list of module references kept for script
1458 # Flush the private list of module references kept for script
1459 # execution protection
1459 # execution protection
1460 self.clear_main_mod_cache()
1460 self.clear_main_mod_cache()
1461
1461
1462 def del_var(self, varname, by_name=False):
1462 def del_var(self, varname, by_name=False):
1463 """Delete a variable from the various namespaces, so that, as
1463 """Delete a variable from the various namespaces, so that, as
1464 far as possible, we're not keeping any hidden references to it.
1464 far as possible, we're not keeping any hidden references to it.
1465
1465
1466 Parameters
1466 Parameters
1467 ----------
1467 ----------
1468 varname : str
1468 varname : str
1469 The name of the variable to delete.
1469 The name of the variable to delete.
1470 by_name : bool
1470 by_name : bool
1471 If True, delete variables with the given name in each
1471 If True, delete variables with the given name in each
1472 namespace. If False (default), find the variable in the user
1472 namespace. If False (default), find the variable in the user
1473 namespace, and delete references to it.
1473 namespace, and delete references to it.
1474 """
1474 """
1475 if varname in ('__builtin__', '__builtins__'):
1475 if varname in ('__builtin__', '__builtins__'):
1476 raise ValueError("Refusing to delete %s" % varname)
1476 raise ValueError("Refusing to delete %s" % varname)
1477
1477
1478 ns_refs = self.all_ns_refs
1478 ns_refs = self.all_ns_refs
1479
1479
1480 if by_name: # Delete by name
1480 if by_name: # Delete by name
1481 for ns in ns_refs:
1481 for ns in ns_refs:
1482 try:
1482 try:
1483 del ns[varname]
1483 del ns[varname]
1484 except KeyError:
1484 except KeyError:
1485 pass
1485 pass
1486 else: # Delete by object
1486 else: # Delete by object
1487 try:
1487 try:
1488 obj = self.user_ns[varname]
1488 obj = self.user_ns[varname]
1489 except KeyError:
1489 except KeyError:
1490 raise NameError("name '%s' is not defined" % varname)
1490 raise NameError("name '%s' is not defined" % varname)
1491 # Also check in output history
1491 # Also check in output history
1492 ns_refs.append(self.history_manager.output_hist)
1492 ns_refs.append(self.history_manager.output_hist)
1493 for ns in ns_refs:
1493 for ns in ns_refs:
1494 to_delete = [n for n, o in ns.items() if o is obj]
1494 to_delete = [n for n, o in ns.items() if o is obj]
1495 for name in to_delete:
1495 for name in to_delete:
1496 del ns[name]
1496 del ns[name]
1497
1497
1498 # Ensure it is removed from the last execution result
1498 # Ensure it is removed from the last execution result
1499 if self.last_execution_result.result is obj:
1499 if self.last_execution_result.result is obj:
1500 self.last_execution_result = None
1500 self.last_execution_result = None
1501
1501
1502 # displayhook keeps extra references, but not in a dictionary
1502 # displayhook keeps extra references, but not in a dictionary
1503 for name in ('_', '__', '___'):
1503 for name in ('_', '__', '___'):
1504 if getattr(self.displayhook, name) is obj:
1504 if getattr(self.displayhook, name) is obj:
1505 setattr(self.displayhook, name, None)
1505 setattr(self.displayhook, name, None)
1506
1506
1507 def reset_selective(self, regex=None):
1507 def reset_selective(self, regex=None):
1508 """Clear selective variables from internal namespaces based on a
1508 """Clear selective variables from internal namespaces based on a
1509 specified regular expression.
1509 specified regular expression.
1510
1510
1511 Parameters
1511 Parameters
1512 ----------
1512 ----------
1513 regex : string or compiled pattern, optional
1513 regex : string or compiled pattern, optional
1514 A regular expression pattern that will be used in searching
1514 A regular expression pattern that will be used in searching
1515 variable names in the users namespaces.
1515 variable names in the users namespaces.
1516 """
1516 """
1517 if regex is not None:
1517 if regex is not None:
1518 try:
1518 try:
1519 m = re.compile(regex)
1519 m = re.compile(regex)
1520 except TypeError:
1520 except TypeError:
1521 raise TypeError('regex must be a string or compiled pattern')
1521 raise TypeError('regex must be a string or compiled pattern')
1522 # Search for keys in each namespace that match the given regex
1522 # Search for keys in each namespace that match the given regex
1523 # If a match is found, delete the key/value pair.
1523 # If a match is found, delete the key/value pair.
1524 for ns in self.all_ns_refs:
1524 for ns in self.all_ns_refs:
1525 for var in ns:
1525 for var in ns:
1526 if m.search(var):
1526 if m.search(var):
1527 del ns[var]
1527 del ns[var]
1528
1528
1529 def push(self, variables, interactive=True):
1529 def push(self, variables, interactive=True):
1530 """Inject a group of variables into the IPython user namespace.
1530 """Inject a group of variables into the IPython user namespace.
1531
1531
1532 Parameters
1532 Parameters
1533 ----------
1533 ----------
1534 variables : dict, str or list/tuple of str
1534 variables : dict, str or list/tuple of str
1535 The variables to inject into the user's namespace. If a dict, a
1535 The variables to inject into the user's namespace. If a dict, a
1536 simple update is done. If a str, the string is assumed to have
1536 simple update is done. If a str, the string is assumed to have
1537 variable names separated by spaces. A list/tuple of str can also
1537 variable names separated by spaces. A list/tuple of str can also
1538 be used to give the variable names. If just the variable names are
1538 be used to give the variable names. If just the variable names are
1539 give (list/tuple/str) then the variable values looked up in the
1539 give (list/tuple/str) then the variable values looked up in the
1540 callers frame.
1540 callers frame.
1541 interactive : bool
1541 interactive : bool
1542 If True (default), the variables will be listed with the ``who``
1542 If True (default), the variables will be listed with the ``who``
1543 magic.
1543 magic.
1544 """
1544 """
1545 vdict = None
1545 vdict = None
1546
1546
1547 # We need a dict of name/value pairs to do namespace updates.
1547 # We need a dict of name/value pairs to do namespace updates.
1548 if isinstance(variables, dict):
1548 if isinstance(variables, dict):
1549 vdict = variables
1549 vdict = variables
1550 elif isinstance(variables, (str, list, tuple)):
1550 elif isinstance(variables, (str, list, tuple)):
1551 if isinstance(variables, str):
1551 if isinstance(variables, str):
1552 vlist = variables.split()
1552 vlist = variables.split()
1553 else:
1553 else:
1554 vlist = variables
1554 vlist = variables
1555 vdict = {}
1555 vdict = {}
1556 cf = sys._getframe(1)
1556 cf = sys._getframe(1)
1557 for name in vlist:
1557 for name in vlist:
1558 try:
1558 try:
1559 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1559 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1560 except:
1560 except:
1561 print('Could not get variable %s from %s' %
1561 print('Could not get variable %s from %s' %
1562 (name,cf.f_code.co_name))
1562 (name,cf.f_code.co_name))
1563 else:
1563 else:
1564 raise ValueError('variables must be a dict/str/list/tuple')
1564 raise ValueError('variables must be a dict/str/list/tuple')
1565
1565
1566 # Propagate variables to user namespace
1566 # Propagate variables to user namespace
1567 self.user_ns.update(vdict)
1567 self.user_ns.update(vdict)
1568
1568
1569 # And configure interactive visibility
1569 # And configure interactive visibility
1570 user_ns_hidden = self.user_ns_hidden
1570 user_ns_hidden = self.user_ns_hidden
1571 if interactive:
1571 if interactive:
1572 for name in vdict:
1572 for name in vdict:
1573 user_ns_hidden.pop(name, None)
1573 user_ns_hidden.pop(name, None)
1574 else:
1574 else:
1575 user_ns_hidden.update(vdict)
1575 user_ns_hidden.update(vdict)
1576
1576
1577 def drop_by_id(self, variables):
1577 def drop_by_id(self, variables):
1578 """Remove a dict of variables from the user namespace, if they are the
1578 """Remove a dict of variables from the user namespace, if they are the
1579 same as the values in the dictionary.
1579 same as the values in the dictionary.
1580
1580
1581 This is intended for use by extensions: variables that they've added can
1581 This is intended for use by extensions: variables that they've added can
1582 be taken back out if they are unloaded, without removing any that the
1582 be taken back out if they are unloaded, without removing any that the
1583 user has overwritten.
1583 user has overwritten.
1584
1584
1585 Parameters
1585 Parameters
1586 ----------
1586 ----------
1587 variables : dict
1587 variables : dict
1588 A dictionary mapping object names (as strings) to the objects.
1588 A dictionary mapping object names (as strings) to the objects.
1589 """
1589 """
1590 for name, obj in variables.items():
1590 for name, obj in variables.items():
1591 if name in self.user_ns and self.user_ns[name] is obj:
1591 if name in self.user_ns and self.user_ns[name] is obj:
1592 del self.user_ns[name]
1592 del self.user_ns[name]
1593 self.user_ns_hidden.pop(name, None)
1593 self.user_ns_hidden.pop(name, None)
1594
1594
1595 #-------------------------------------------------------------------------
1595 #-------------------------------------------------------------------------
1596 # Things related to object introspection
1596 # Things related to object introspection
1597 #-------------------------------------------------------------------------
1597 #-------------------------------------------------------------------------
1598
1598
1599 def _ofind(self, oname, namespaces=None):
1599 def _ofind(self, oname, namespaces=None):
1600 """Find an object in the available namespaces.
1600 """Find an object in the available namespaces.
1601
1601
1602 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1602 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1603
1603
1604 Has special code to detect magic functions.
1604 Has special code to detect magic functions.
1605 """
1605 """
1606 oname = oname.strip()
1606 oname = oname.strip()
1607 if not oname.startswith(ESC_MAGIC) and \
1607 if not oname.startswith(ESC_MAGIC) and \
1608 not oname.startswith(ESC_MAGIC2) and \
1608 not oname.startswith(ESC_MAGIC2) and \
1609 not all(a.isidentifier() for a in oname.split(".")):
1609 not all(a.isidentifier() for a in oname.split(".")):
1610 return {'found': False}
1610 return {'found': False}
1611
1611
1612 if namespaces is None:
1612 if namespaces is None:
1613 # Namespaces to search in:
1613 # Namespaces to search in:
1614 # Put them in a list. The order is important so that we
1614 # Put them in a list. The order is important so that we
1615 # find things in the same order that Python finds them.
1615 # find things in the same order that Python finds them.
1616 namespaces = [ ('Interactive', self.user_ns),
1616 namespaces = [ ('Interactive', self.user_ns),
1617 ('Interactive (global)', self.user_global_ns),
1617 ('Interactive (global)', self.user_global_ns),
1618 ('Python builtin', builtin_mod.__dict__),
1618 ('Python builtin', builtin_mod.__dict__),
1619 ]
1619 ]
1620
1620
1621 ismagic = False
1621 ismagic = False
1622 isalias = False
1622 isalias = False
1623 found = False
1623 found = False
1624 ospace = None
1624 ospace = None
1625 parent = None
1625 parent = None
1626 obj = None
1626 obj = None
1627
1627
1628
1628
1629 # Look for the given name by splitting it in parts. If the head is
1629 # Look for the given name by splitting it in parts. If the head is
1630 # found, then we look for all the remaining parts as members, and only
1630 # found, then we look for all the remaining parts as members, and only
1631 # declare success if we can find them all.
1631 # declare success if we can find them all.
1632 oname_parts = oname.split('.')
1632 oname_parts = oname.split('.')
1633 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1633 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1634 for nsname,ns in namespaces:
1634 for nsname,ns in namespaces:
1635 try:
1635 try:
1636 obj = ns[oname_head]
1636 obj = ns[oname_head]
1637 except KeyError:
1637 except KeyError:
1638 continue
1638 continue
1639 else:
1639 else:
1640 for idx, part in enumerate(oname_rest):
1640 for idx, part in enumerate(oname_rest):
1641 try:
1641 try:
1642 parent = obj
1642 parent = obj
1643 # The last part is looked up in a special way to avoid
1643 # The last part is looked up in a special way to avoid
1644 # descriptor invocation as it may raise or have side
1644 # descriptor invocation as it may raise or have side
1645 # effects.
1645 # effects.
1646 if idx == len(oname_rest) - 1:
1646 if idx == len(oname_rest) - 1:
1647 obj = self._getattr_property(obj, part)
1647 obj = self._getattr_property(obj, part)
1648 else:
1648 else:
1649 obj = getattr(obj, part)
1649 obj = getattr(obj, part)
1650 except:
1650 except:
1651 # Blanket except b/c some badly implemented objects
1651 # Blanket except b/c some badly implemented objects
1652 # allow __getattr__ to raise exceptions other than
1652 # allow __getattr__ to raise exceptions other than
1653 # AttributeError, which then crashes IPython.
1653 # AttributeError, which then crashes IPython.
1654 break
1654 break
1655 else:
1655 else:
1656 # If we finish the for loop (no break), we got all members
1656 # If we finish the for loop (no break), we got all members
1657 found = True
1657 found = True
1658 ospace = nsname
1658 ospace = nsname
1659 break # namespace loop
1659 break # namespace loop
1660
1660
1661 # Try to see if it's magic
1661 # Try to see if it's magic
1662 if not found:
1662 if not found:
1663 obj = None
1663 obj = None
1664 if oname.startswith(ESC_MAGIC2):
1664 if oname.startswith(ESC_MAGIC2):
1665 oname = oname.lstrip(ESC_MAGIC2)
1665 oname = oname.lstrip(ESC_MAGIC2)
1666 obj = self.find_cell_magic(oname)
1666 obj = self.find_cell_magic(oname)
1667 elif oname.startswith(ESC_MAGIC):
1667 elif oname.startswith(ESC_MAGIC):
1668 oname = oname.lstrip(ESC_MAGIC)
1668 oname = oname.lstrip(ESC_MAGIC)
1669 obj = self.find_line_magic(oname)
1669 obj = self.find_line_magic(oname)
1670 else:
1670 else:
1671 # search without prefix, so run? will find %run?
1671 # search without prefix, so run? will find %run?
1672 obj = self.find_line_magic(oname)
1672 obj = self.find_line_magic(oname)
1673 if obj is None:
1673 if obj is None:
1674 obj = self.find_cell_magic(oname)
1674 obj = self.find_cell_magic(oname)
1675 if obj is not None:
1675 if obj is not None:
1676 found = True
1676 found = True
1677 ospace = 'IPython internal'
1677 ospace = 'IPython internal'
1678 ismagic = True
1678 ismagic = True
1679 isalias = isinstance(obj, Alias)
1679 isalias = isinstance(obj, Alias)
1680
1680
1681 # Last try: special-case some literals like '', [], {}, etc:
1681 # Last try: special-case some literals like '', [], {}, etc:
1682 if not found and oname_head in ["''",'""','[]','{}','()']:
1682 if not found and oname_head in ["''",'""','[]','{}','()']:
1683 obj = eval(oname_head)
1683 obj = eval(oname_head)
1684 found = True
1684 found = True
1685 ospace = 'Interactive'
1685 ospace = 'Interactive'
1686
1686
1687 return {
1687 return {
1688 'obj':obj,
1688 'obj':obj,
1689 'found':found,
1689 'found':found,
1690 'parent':parent,
1690 'parent':parent,
1691 'ismagic':ismagic,
1691 'ismagic':ismagic,
1692 'isalias':isalias,
1692 'isalias':isalias,
1693 'namespace':ospace
1693 'namespace':ospace
1694 }
1694 }
1695
1695
1696 @staticmethod
1696 @staticmethod
1697 def _getattr_property(obj, attrname):
1697 def _getattr_property(obj, attrname):
1698 """Property-aware getattr to use in object finding.
1698 """Property-aware getattr to use in object finding.
1699
1699
1700 If attrname represents a property, return it unevaluated (in case it has
1700 If attrname represents a property, return it unevaluated (in case it has
1701 side effects or raises an error.
1701 side effects or raises an error.
1702
1702
1703 """
1703 """
1704 if not isinstance(obj, type):
1704 if not isinstance(obj, type):
1705 try:
1705 try:
1706 # `getattr(type(obj), attrname)` is not guaranteed to return
1706 # `getattr(type(obj), attrname)` is not guaranteed to return
1707 # `obj`, but does so for property:
1707 # `obj`, but does so for property:
1708 #
1708 #
1709 # property.__get__(self, None, cls) -> self
1709 # property.__get__(self, None, cls) -> self
1710 #
1710 #
1711 # The universal alternative is to traverse the mro manually
1711 # The universal alternative is to traverse the mro manually
1712 # searching for attrname in class dicts.
1712 # searching for attrname in class dicts.
1713 attr = getattr(type(obj), attrname)
1713 attr = getattr(type(obj), attrname)
1714 except AttributeError:
1714 except AttributeError:
1715 pass
1715 pass
1716 else:
1716 else:
1717 # This relies on the fact that data descriptors (with both
1717 # This relies on the fact that data descriptors (with both
1718 # __get__ & __set__ magic methods) take precedence over
1718 # __get__ & __set__ magic methods) take precedence over
1719 # instance-level attributes:
1719 # instance-level attributes:
1720 #
1720 #
1721 # class A(object):
1721 # class A(object):
1722 # @property
1722 # @property
1723 # def foobar(self): return 123
1723 # def foobar(self): return 123
1724 # a = A()
1724 # a = A()
1725 # a.__dict__['foobar'] = 345
1725 # a.__dict__['foobar'] = 345
1726 # a.foobar # == 123
1726 # a.foobar # == 123
1727 #
1727 #
1728 # So, a property may be returned right away.
1728 # So, a property may be returned right away.
1729 if isinstance(attr, property):
1729 if isinstance(attr, property):
1730 return attr
1730 return attr
1731
1731
1732 # Nothing helped, fall back.
1732 # Nothing helped, fall back.
1733 return getattr(obj, attrname)
1733 return getattr(obj, attrname)
1734
1734
1735 def _object_find(self, oname, namespaces=None):
1735 def _object_find(self, oname, namespaces=None):
1736 """Find an object and return a struct with info about it."""
1736 """Find an object and return a struct with info about it."""
1737 return Struct(self._ofind(oname, namespaces))
1737 return Struct(self._ofind(oname, namespaces))
1738
1738
1739 def _inspect(self, meth, oname, namespaces=None, **kw):
1739 def _inspect(self, meth, oname, namespaces=None, **kw):
1740 """Generic interface to the inspector system.
1740 """Generic interface to the inspector system.
1741
1741
1742 This function is meant to be called by pdef, pdoc & friends.
1742 This function is meant to be called by pdef, pdoc & friends.
1743 """
1743 """
1744 info = self._object_find(oname, namespaces)
1744 info = self._object_find(oname, namespaces)
1745 docformat = sphinxify if self.sphinxify_docstring else None
1745 docformat = sphinxify if self.sphinxify_docstring else None
1746 if info.found:
1746 if info.found:
1747 pmethod = getattr(self.inspector, meth)
1747 pmethod = getattr(self.inspector, meth)
1748 # TODO: only apply format_screen to the plain/text repr of the mime
1748 # TODO: only apply format_screen to the plain/text repr of the mime
1749 # bundle.
1749 # bundle.
1750 formatter = format_screen if info.ismagic else docformat
1750 formatter = format_screen if info.ismagic else docformat
1751 if meth == 'pdoc':
1751 if meth == 'pdoc':
1752 pmethod(info.obj, oname, formatter)
1752 pmethod(info.obj, oname, formatter)
1753 elif meth == 'pinfo':
1753 elif meth == 'pinfo':
1754 pmethod(info.obj, oname, formatter, info,
1754 pmethod(info.obj, oname, formatter, info,
1755 enable_html_pager=self.enable_html_pager, **kw)
1755 enable_html_pager=self.enable_html_pager, **kw)
1756 else:
1756 else:
1757 pmethod(info.obj, oname)
1757 pmethod(info.obj, oname)
1758 else:
1758 else:
1759 print('Object `%s` not found.' % oname)
1759 print('Object `%s` not found.' % oname)
1760 return 'not found' # so callers can take other action
1760 return 'not found' # so callers can take other action
1761
1761
1762 def object_inspect(self, oname, detail_level=0):
1762 def object_inspect(self, oname, detail_level=0):
1763 """Get object info about oname"""
1763 """Get object info about oname"""
1764 with self.builtin_trap:
1764 with self.builtin_trap:
1765 info = self._object_find(oname)
1765 info = self._object_find(oname)
1766 if info.found:
1766 if info.found:
1767 return self.inspector.info(info.obj, oname, info=info,
1767 return self.inspector.info(info.obj, oname, info=info,
1768 detail_level=detail_level
1768 detail_level=detail_level
1769 )
1769 )
1770 else:
1770 else:
1771 return oinspect.object_info(name=oname, found=False)
1771 return oinspect.object_info(name=oname, found=False)
1772
1772
1773 def object_inspect_text(self, oname, detail_level=0):
1773 def object_inspect_text(self, oname, detail_level=0):
1774 """Get object info as formatted text"""
1774 """Get object info as formatted text"""
1775 return self.object_inspect_mime(oname, detail_level)['text/plain']
1775 return self.object_inspect_mime(oname, detail_level)['text/plain']
1776
1776
1777 def object_inspect_mime(self, oname, detail_level=0):
1777 def object_inspect_mime(self, oname, detail_level=0):
1778 """Get object info as a mimebundle of formatted representations.
1778 """Get object info as a mimebundle of formatted representations.
1779
1779
1780 A mimebundle is a dictionary, keyed by mime-type.
1780 A mimebundle is a dictionary, keyed by mime-type.
1781 It must always have the key `'text/plain'`.
1781 It must always have the key `'text/plain'`.
1782 """
1782 """
1783 with self.builtin_trap:
1783 with self.builtin_trap:
1784 info = self._object_find(oname)
1784 info = self._object_find(oname)
1785 if info.found:
1785 if info.found:
1786 return self.inspector._get_info(info.obj, oname, info=info,
1786 return self.inspector._get_info(info.obj, oname, info=info,
1787 detail_level=detail_level
1787 detail_level=detail_level
1788 )
1788 )
1789 else:
1789 else:
1790 raise KeyError(oname)
1790 raise KeyError(oname)
1791
1791
1792 #-------------------------------------------------------------------------
1792 #-------------------------------------------------------------------------
1793 # Things related to history management
1793 # Things related to history management
1794 #-------------------------------------------------------------------------
1794 #-------------------------------------------------------------------------
1795
1795
1796 def init_history(self):
1796 def init_history(self):
1797 """Sets up the command history, and starts regular autosaves."""
1797 """Sets up the command history, and starts regular autosaves."""
1798 self.history_manager = HistoryManager(shell=self, parent=self)
1798 self.history_manager = HistoryManager(shell=self, parent=self)
1799 self.configurables.append(self.history_manager)
1799 self.configurables.append(self.history_manager)
1800
1800
1801 #-------------------------------------------------------------------------
1801 #-------------------------------------------------------------------------
1802 # Things related to exception handling and tracebacks (not debugging)
1802 # Things related to exception handling and tracebacks (not debugging)
1803 #-------------------------------------------------------------------------
1803 #-------------------------------------------------------------------------
1804
1804
1805 debugger_cls = Pdb
1805 debugger_cls = Pdb
1806
1806
1807 def init_traceback_handlers(self, custom_exceptions):
1807 def init_traceback_handlers(self, custom_exceptions):
1808 # Syntax error handler.
1808 # Syntax error handler.
1809 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor', parent=self)
1809 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor', parent=self)
1810
1810
1811 # The interactive one is initialized with an offset, meaning we always
1811 # The interactive one is initialized with an offset, meaning we always
1812 # want to remove the topmost item in the traceback, which is our own
1812 # want to remove the topmost item in the traceback, which is our own
1813 # internal code. Valid modes: ['Plain','Context','Verbose','Minimal']
1813 # internal code. Valid modes: ['Plain','Context','Verbose','Minimal']
1814 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1814 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1815 color_scheme='NoColor',
1815 color_scheme='NoColor',
1816 tb_offset = 1,
1816 tb_offset = 1,
1817 check_cache=check_linecache_ipython,
1817 check_cache=check_linecache_ipython,
1818 debugger_cls=self.debugger_cls, parent=self)
1818 debugger_cls=self.debugger_cls, parent=self)
1819
1819
1820 # The instance will store a pointer to the system-wide exception hook,
1820 # The instance will store a pointer to the system-wide exception hook,
1821 # so that runtime code (such as magics) can access it. This is because
1821 # so that runtime code (such as magics) can access it. This is because
1822 # during the read-eval loop, it may get temporarily overwritten.
1822 # during the read-eval loop, it may get temporarily overwritten.
1823 self.sys_excepthook = sys.excepthook
1823 self.sys_excepthook = sys.excepthook
1824
1824
1825 # and add any custom exception handlers the user may have specified
1825 # and add any custom exception handlers the user may have specified
1826 self.set_custom_exc(*custom_exceptions)
1826 self.set_custom_exc(*custom_exceptions)
1827
1827
1828 # Set the exception mode
1828 # Set the exception mode
1829 self.InteractiveTB.set_mode(mode=self.xmode)
1829 self.InteractiveTB.set_mode(mode=self.xmode)
1830
1830
1831 def set_custom_exc(self, exc_tuple, handler):
1831 def set_custom_exc(self, exc_tuple, handler):
1832 """set_custom_exc(exc_tuple, handler)
1832 """set_custom_exc(exc_tuple, handler)
1833
1833
1834 Set a custom exception handler, which will be called if any of the
1834 Set a custom exception handler, which will be called if any of the
1835 exceptions in exc_tuple occur in the mainloop (specifically, in the
1835 exceptions in exc_tuple occur in the mainloop (specifically, in the
1836 run_code() method).
1836 run_code() method).
1837
1837
1838 Parameters
1838 Parameters
1839 ----------
1839 ----------
1840
1840
1841 exc_tuple : tuple of exception classes
1841 exc_tuple : tuple of exception classes
1842 A *tuple* of exception classes, for which to call the defined
1842 A *tuple* of exception classes, for which to call the defined
1843 handler. It is very important that you use a tuple, and NOT A
1843 handler. It is very important that you use a tuple, and NOT A
1844 LIST here, because of the way Python's except statement works. If
1844 LIST here, because of the way Python's except statement works. If
1845 you only want to trap a single exception, use a singleton tuple::
1845 you only want to trap a single exception, use a singleton tuple::
1846
1846
1847 exc_tuple == (MyCustomException,)
1847 exc_tuple == (MyCustomException,)
1848
1848
1849 handler : callable
1849 handler : callable
1850 handler must have the following signature::
1850 handler must have the following signature::
1851
1851
1852 def my_handler(self, etype, value, tb, tb_offset=None):
1852 def my_handler(self, etype, value, tb, tb_offset=None):
1853 ...
1853 ...
1854 return structured_traceback
1854 return structured_traceback
1855
1855
1856 Your handler must return a structured traceback (a list of strings),
1856 Your handler must return a structured traceback (a list of strings),
1857 or None.
1857 or None.
1858
1858
1859 This will be made into an instance method (via types.MethodType)
1859 This will be made into an instance method (via types.MethodType)
1860 of IPython itself, and it will be called if any of the exceptions
1860 of IPython itself, and it will be called if any of the exceptions
1861 listed in the exc_tuple are caught. If the handler is None, an
1861 listed in the exc_tuple are caught. If the handler is None, an
1862 internal basic one is used, which just prints basic info.
1862 internal basic one is used, which just prints basic info.
1863
1863
1864 To protect IPython from crashes, if your handler ever raises an
1864 To protect IPython from crashes, if your handler ever raises an
1865 exception or returns an invalid result, it will be immediately
1865 exception or returns an invalid result, it will be immediately
1866 disabled.
1866 disabled.
1867
1867
1868 WARNING: by putting in your own exception handler into IPython's main
1868 WARNING: by putting in your own exception handler into IPython's main
1869 execution loop, you run a very good chance of nasty crashes. This
1869 execution loop, you run a very good chance of nasty crashes. This
1870 facility should only be used if you really know what you are doing."""
1870 facility should only be used if you really know what you are doing."""
1871 if not isinstance(exc_tuple, tuple):
1871 if not isinstance(exc_tuple, tuple):
1872 raise TypeError("The custom exceptions must be given as a tuple.")
1872 raise TypeError("The custom exceptions must be given as a tuple.")
1873
1873
1874 def dummy_handler(self, etype, value, tb, tb_offset=None):
1874 def dummy_handler(self, etype, value, tb, tb_offset=None):
1875 print('*** Simple custom exception handler ***')
1875 print('*** Simple custom exception handler ***')
1876 print('Exception type :', etype)
1876 print('Exception type :', etype)
1877 print('Exception value:', value)
1877 print('Exception value:', value)
1878 print('Traceback :', tb)
1878 print('Traceback :', tb)
1879
1879
1880 def validate_stb(stb):
1880 def validate_stb(stb):
1881 """validate structured traceback return type
1881 """validate structured traceback return type
1882
1882
1883 return type of CustomTB *should* be a list of strings, but allow
1883 return type of CustomTB *should* be a list of strings, but allow
1884 single strings or None, which are harmless.
1884 single strings or None, which are harmless.
1885
1885
1886 This function will *always* return a list of strings,
1886 This function will *always* return a list of strings,
1887 and will raise a TypeError if stb is inappropriate.
1887 and will raise a TypeError if stb is inappropriate.
1888 """
1888 """
1889 msg = "CustomTB must return list of strings, not %r" % stb
1889 msg = "CustomTB must return list of strings, not %r" % stb
1890 if stb is None:
1890 if stb is None:
1891 return []
1891 return []
1892 elif isinstance(stb, str):
1892 elif isinstance(stb, str):
1893 return [stb]
1893 return [stb]
1894 elif not isinstance(stb, list):
1894 elif not isinstance(stb, list):
1895 raise TypeError(msg)
1895 raise TypeError(msg)
1896 # it's a list
1896 # it's a list
1897 for line in stb:
1897 for line in stb:
1898 # check every element
1898 # check every element
1899 if not isinstance(line, str):
1899 if not isinstance(line, str):
1900 raise TypeError(msg)
1900 raise TypeError(msg)
1901 return stb
1901 return stb
1902
1902
1903 if handler is None:
1903 if handler is None:
1904 wrapped = dummy_handler
1904 wrapped = dummy_handler
1905 else:
1905 else:
1906 def wrapped(self,etype,value,tb,tb_offset=None):
1906 def wrapped(self,etype,value,tb,tb_offset=None):
1907 """wrap CustomTB handler, to protect IPython from user code
1907 """wrap CustomTB handler, to protect IPython from user code
1908
1908
1909 This makes it harder (but not impossible) for custom exception
1909 This makes it harder (but not impossible) for custom exception
1910 handlers to crash IPython.
1910 handlers to crash IPython.
1911 """
1911 """
1912 try:
1912 try:
1913 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1913 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1914 return validate_stb(stb)
1914 return validate_stb(stb)
1915 except:
1915 except:
1916 # clear custom handler immediately
1916 # clear custom handler immediately
1917 self.set_custom_exc((), None)
1917 self.set_custom_exc((), None)
1918 print("Custom TB Handler failed, unregistering", file=sys.stderr)
1918 print("Custom TB Handler failed, unregistering", file=sys.stderr)
1919 # show the exception in handler first
1919 # show the exception in handler first
1920 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1920 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1921 print(self.InteractiveTB.stb2text(stb))
1921 print(self.InteractiveTB.stb2text(stb))
1922 print("The original exception:")
1922 print("The original exception:")
1923 stb = self.InteractiveTB.structured_traceback(
1923 stb = self.InteractiveTB.structured_traceback(
1924 (etype,value,tb), tb_offset=tb_offset
1924 (etype,value,tb), tb_offset=tb_offset
1925 )
1925 )
1926 return stb
1926 return stb
1927
1927
1928 self.CustomTB = types.MethodType(wrapped,self)
1928 self.CustomTB = types.MethodType(wrapped,self)
1929 self.custom_exceptions = exc_tuple
1929 self.custom_exceptions = exc_tuple
1930
1930
1931 def excepthook(self, etype, value, tb):
1931 def excepthook(self, etype, value, tb):
1932 """One more defense for GUI apps that call sys.excepthook.
1932 """One more defense for GUI apps that call sys.excepthook.
1933
1933
1934 GUI frameworks like wxPython trap exceptions and call
1934 GUI frameworks like wxPython trap exceptions and call
1935 sys.excepthook themselves. I guess this is a feature that
1935 sys.excepthook themselves. I guess this is a feature that
1936 enables them to keep running after exceptions that would
1936 enables them to keep running after exceptions that would
1937 otherwise kill their mainloop. This is a bother for IPython
1937 otherwise kill their mainloop. This is a bother for IPython
1938 which excepts to catch all of the program exceptions with a try:
1938 which excepts to catch all of the program exceptions with a try:
1939 except: statement.
1939 except: statement.
1940
1940
1941 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1941 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1942 any app directly invokes sys.excepthook, it will look to the user like
1942 any app directly invokes sys.excepthook, it will look to the user like
1943 IPython crashed. In order to work around this, we can disable the
1943 IPython crashed. In order to work around this, we can disable the
1944 CrashHandler and replace it with this excepthook instead, which prints a
1944 CrashHandler and replace it with this excepthook instead, which prints a
1945 regular traceback using our InteractiveTB. In this fashion, apps which
1945 regular traceback using our InteractiveTB. In this fashion, apps which
1946 call sys.excepthook will generate a regular-looking exception from
1946 call sys.excepthook will generate a regular-looking exception from
1947 IPython, and the CrashHandler will only be triggered by real IPython
1947 IPython, and the CrashHandler will only be triggered by real IPython
1948 crashes.
1948 crashes.
1949
1949
1950 This hook should be used sparingly, only in places which are not likely
1950 This hook should be used sparingly, only in places which are not likely
1951 to be true IPython errors.
1951 to be true IPython errors.
1952 """
1952 """
1953 self.showtraceback((etype, value, tb), tb_offset=0)
1953 self.showtraceback((etype, value, tb), tb_offset=0)
1954
1954
1955 def _get_exc_info(self, exc_tuple=None):
1955 def _get_exc_info(self, exc_tuple=None):
1956 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1956 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1957
1957
1958 Ensures sys.last_type,value,traceback hold the exc_info we found,
1958 Ensures sys.last_type,value,traceback hold the exc_info we found,
1959 from whichever source.
1959 from whichever source.
1960
1960
1961 raises ValueError if none of these contain any information
1961 raises ValueError if none of these contain any information
1962 """
1962 """
1963 if exc_tuple is None:
1963 if exc_tuple is None:
1964 etype, value, tb = sys.exc_info()
1964 etype, value, tb = sys.exc_info()
1965 else:
1965 else:
1966 etype, value, tb = exc_tuple
1966 etype, value, tb = exc_tuple
1967
1967
1968 if etype is None:
1968 if etype is None:
1969 if hasattr(sys, 'last_type'):
1969 if hasattr(sys, 'last_type'):
1970 etype, value, tb = sys.last_type, sys.last_value, \
1970 etype, value, tb = sys.last_type, sys.last_value, \
1971 sys.last_traceback
1971 sys.last_traceback
1972
1972
1973 if etype is None:
1973 if etype is None:
1974 raise ValueError("No exception to find")
1974 raise ValueError("No exception to find")
1975
1975
1976 # Now store the exception info in sys.last_type etc.
1976 # Now store the exception info in sys.last_type etc.
1977 # WARNING: these variables are somewhat deprecated and not
1977 # WARNING: these variables are somewhat deprecated and not
1978 # necessarily safe to use in a threaded environment, but tools
1978 # necessarily safe to use in a threaded environment, but tools
1979 # like pdb depend on their existence, so let's set them. If we
1979 # like pdb depend on their existence, so let's set them. If we
1980 # find problems in the field, we'll need to revisit their use.
1980 # find problems in the field, we'll need to revisit their use.
1981 sys.last_type = etype
1981 sys.last_type = etype
1982 sys.last_value = value
1982 sys.last_value = value
1983 sys.last_traceback = tb
1983 sys.last_traceback = tb
1984
1984
1985 return etype, value, tb
1985 return etype, value, tb
1986
1986
1987 def show_usage_error(self, exc):
1987 def show_usage_error(self, exc):
1988 """Show a short message for UsageErrors
1988 """Show a short message for UsageErrors
1989
1989
1990 These are special exceptions that shouldn't show a traceback.
1990 These are special exceptions that shouldn't show a traceback.
1991 """
1991 """
1992 print("UsageError: %s" % exc, file=sys.stderr)
1992 print("UsageError: %s" % exc, file=sys.stderr)
1993
1993
1994 def get_exception_only(self, exc_tuple=None):
1994 def get_exception_only(self, exc_tuple=None):
1995 """
1995 """
1996 Return as a string (ending with a newline) the exception that
1996 Return as a string (ending with a newline) the exception that
1997 just occurred, without any traceback.
1997 just occurred, without any traceback.
1998 """
1998 """
1999 etype, value, tb = self._get_exc_info(exc_tuple)
1999 etype, value, tb = self._get_exc_info(exc_tuple)
2000 msg = traceback.format_exception_only(etype, value)
2000 msg = traceback.format_exception_only(etype, value)
2001 return ''.join(msg)
2001 return ''.join(msg)
2002
2002
2003 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
2003 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
2004 exception_only=False, running_compiled_code=False):
2004 exception_only=False, running_compiled_code=False):
2005 """Display the exception that just occurred.
2005 """Display the exception that just occurred.
2006
2006
2007 If nothing is known about the exception, this is the method which
2007 If nothing is known about the exception, this is the method which
2008 should be used throughout the code for presenting user tracebacks,
2008 should be used throughout the code for presenting user tracebacks,
2009 rather than directly invoking the InteractiveTB object.
2009 rather than directly invoking the InteractiveTB object.
2010
2010
2011 A specific showsyntaxerror() also exists, but this method can take
2011 A specific showsyntaxerror() also exists, but this method can take
2012 care of calling it if needed, so unless you are explicitly catching a
2012 care of calling it if needed, so unless you are explicitly catching a
2013 SyntaxError exception, don't try to analyze the stack manually and
2013 SyntaxError exception, don't try to analyze the stack manually and
2014 simply call this method."""
2014 simply call this method."""
2015
2015
2016 try:
2016 try:
2017 try:
2017 try:
2018 etype, value, tb = self._get_exc_info(exc_tuple)
2018 etype, value, tb = self._get_exc_info(exc_tuple)
2019 except ValueError:
2019 except ValueError:
2020 print('No traceback available to show.', file=sys.stderr)
2020 print('No traceback available to show.', file=sys.stderr)
2021 return
2021 return
2022
2022
2023 if issubclass(etype, SyntaxError):
2023 if issubclass(etype, SyntaxError):
2024 # Though this won't be called by syntax errors in the input
2024 # Though this won't be called by syntax errors in the input
2025 # line, there may be SyntaxError cases with imported code.
2025 # line, there may be SyntaxError cases with imported code.
2026 self.showsyntaxerror(filename, running_compiled_code)
2026 self.showsyntaxerror(filename, running_compiled_code)
2027 elif etype is UsageError:
2027 elif etype is UsageError:
2028 self.show_usage_error(value)
2028 self.show_usage_error(value)
2029 else:
2029 else:
2030 if exception_only:
2030 if exception_only:
2031 stb = ['An exception has occurred, use %tb to see '
2031 stb = ['An exception has occurred, use %tb to see '
2032 'the full traceback.\n']
2032 'the full traceback.\n']
2033 stb.extend(self.InteractiveTB.get_exception_only(etype,
2033 stb.extend(self.InteractiveTB.get_exception_only(etype,
2034 value))
2034 value))
2035 else:
2035 else:
2036 try:
2036 try:
2037 # Exception classes can customise their traceback - we
2037 # Exception classes can customise their traceback - we
2038 # use this in IPython.parallel for exceptions occurring
2038 # use this in IPython.parallel for exceptions occurring
2039 # in the engines. This should return a list of strings.
2039 # in the engines. This should return a list of strings.
2040 stb = value._render_traceback_()
2040 stb = value._render_traceback_()
2041 except Exception:
2041 except Exception:
2042 stb = self.InteractiveTB.structured_traceback(etype,
2042 stb = self.InteractiveTB.structured_traceback(etype,
2043 value, tb, tb_offset=tb_offset)
2043 value, tb, tb_offset=tb_offset)
2044
2044
2045 self._showtraceback(etype, value, stb)
2045 self._showtraceback(etype, value, stb)
2046 if self.call_pdb:
2046 if self.call_pdb:
2047 # drop into debugger
2047 # drop into debugger
2048 self.debugger(force=True)
2048 self.debugger(force=True)
2049 return
2049 return
2050
2050
2051 # Actually show the traceback
2051 # Actually show the traceback
2052 self._showtraceback(etype, value, stb)
2052 self._showtraceback(etype, value, stb)
2053
2053
2054 except KeyboardInterrupt:
2054 except KeyboardInterrupt:
2055 print('\n' + self.get_exception_only(), file=sys.stderr)
2055 print('\n' + self.get_exception_only(), file=sys.stderr)
2056
2056
2057 def _showtraceback(self, etype, evalue, stb):
2057 def _showtraceback(self, etype, evalue, stb):
2058 """Actually show a traceback.
2058 """Actually show a traceback.
2059
2059
2060 Subclasses may override this method to put the traceback on a different
2060 Subclasses may override this method to put the traceback on a different
2061 place, like a side channel.
2061 place, like a side channel.
2062 """
2062 """
2063 print(self.InteractiveTB.stb2text(stb))
2063 print(self.InteractiveTB.stb2text(stb))
2064
2064
2065 def showsyntaxerror(self, filename=None, running_compiled_code=False):
2065 def showsyntaxerror(self, filename=None, running_compiled_code=False):
2066 """Display the syntax error that just occurred.
2066 """Display the syntax error that just occurred.
2067
2067
2068 This doesn't display a stack trace because there isn't one.
2068 This doesn't display a stack trace because there isn't one.
2069
2069
2070 If a filename is given, it is stuffed in the exception instead
2070 If a filename is given, it is stuffed in the exception instead
2071 of what was there before (because Python's parser always uses
2071 of what was there before (because Python's parser always uses
2072 "<string>" when reading from a string).
2072 "<string>" when reading from a string).
2073
2073
2074 If the syntax error occurred when running a compiled code (i.e. running_compile_code=True),
2074 If the syntax error occurred when running a compiled code (i.e. running_compile_code=True),
2075 longer stack trace will be displayed.
2075 longer stack trace will be displayed.
2076 """
2076 """
2077 etype, value, last_traceback = self._get_exc_info()
2077 etype, value, last_traceback = self._get_exc_info()
2078
2078
2079 if filename and issubclass(etype, SyntaxError):
2079 if filename and issubclass(etype, SyntaxError):
2080 try:
2080 try:
2081 value.filename = filename
2081 value.filename = filename
2082 except:
2082 except:
2083 # Not the format we expect; leave it alone
2083 # Not the format we expect; leave it alone
2084 pass
2084 pass
2085
2085
2086 # If the error occurred when executing compiled code, we should provide full stacktrace.
2086 # If the error occurred when executing compiled code, we should provide full stacktrace.
2087 elist = traceback.extract_tb(last_traceback) if running_compiled_code else []
2087 elist = traceback.extract_tb(last_traceback) if running_compiled_code else []
2088 stb = self.SyntaxTB.structured_traceback(etype, value, elist)
2088 stb = self.SyntaxTB.structured_traceback(etype, value, elist)
2089 self._showtraceback(etype, value, stb)
2089 self._showtraceback(etype, value, stb)
2090
2090
2091 # This is overridden in TerminalInteractiveShell to show a message about
2091 # This is overridden in TerminalInteractiveShell to show a message about
2092 # the %paste magic.
2092 # the %paste magic.
2093 def showindentationerror(self):
2093 def showindentationerror(self):
2094 """Called by _run_cell when there's an IndentationError in code entered
2094 """Called by _run_cell when there's an IndentationError in code entered
2095 at the prompt.
2095 at the prompt.
2096
2096
2097 This is overridden in TerminalInteractiveShell to show a message about
2097 This is overridden in TerminalInteractiveShell to show a message about
2098 the %paste magic."""
2098 the %paste magic."""
2099 self.showsyntaxerror()
2099 self.showsyntaxerror()
2100
2100
2101 #-------------------------------------------------------------------------
2101 #-------------------------------------------------------------------------
2102 # Things related to readline
2102 # Things related to readline
2103 #-------------------------------------------------------------------------
2103 #-------------------------------------------------------------------------
2104
2104
2105 def init_readline(self):
2105 def init_readline(self):
2106 """DEPRECATED
2106 """DEPRECATED
2107
2107
2108 Moved to terminal subclass, here only to simplify the init logic."""
2108 Moved to terminal subclass, here only to simplify the init logic."""
2109 # Set a number of methods that depend on readline to be no-op
2109 # Set a number of methods that depend on readline to be no-op
2110 warnings.warn('`init_readline` is no-op since IPython 5.0 and is Deprecated',
2110 warnings.warn('`init_readline` is no-op since IPython 5.0 and is Deprecated',
2111 DeprecationWarning, stacklevel=2)
2111 DeprecationWarning, stacklevel=2)
2112 self.set_custom_completer = no_op
2112 self.set_custom_completer = no_op
2113
2113
2114 @skip_doctest
2114 @skip_doctest
2115 def set_next_input(self, s, replace=False):
2115 def set_next_input(self, s, replace=False):
2116 """ Sets the 'default' input string for the next command line.
2116 """ Sets the 'default' input string for the next command line.
2117
2117
2118 Example::
2118 Example::
2119
2119
2120 In [1]: _ip.set_next_input("Hello Word")
2120 In [1]: _ip.set_next_input("Hello Word")
2121 In [2]: Hello Word_ # cursor is here
2121 In [2]: Hello Word_ # cursor is here
2122 """
2122 """
2123 self.rl_next_input = s
2123 self.rl_next_input = s
2124
2124
2125 def _indent_current_str(self):
2125 def _indent_current_str(self):
2126 """return the current level of indentation as a string"""
2126 """return the current level of indentation as a string"""
2127 return self.input_splitter.get_indent_spaces() * ' '
2127 return self.input_splitter.get_indent_spaces() * ' '
2128
2128
2129 #-------------------------------------------------------------------------
2129 #-------------------------------------------------------------------------
2130 # Things related to text completion
2130 # Things related to text completion
2131 #-------------------------------------------------------------------------
2131 #-------------------------------------------------------------------------
2132
2132
2133 def init_completer(self):
2133 def init_completer(self):
2134 """Initialize the completion machinery.
2134 """Initialize the completion machinery.
2135
2135
2136 This creates completion machinery that can be used by client code,
2136 This creates completion machinery that can be used by client code,
2137 either interactively in-process (typically triggered by the readline
2137 either interactively in-process (typically triggered by the readline
2138 library), programmatically (such as in test suites) or out-of-process
2138 library), programmatically (such as in test suites) or out-of-process
2139 (typically over the network by remote frontends).
2139 (typically over the network by remote frontends).
2140 """
2140 """
2141 from IPython.core.completer import IPCompleter
2141 from IPython.core.completer import IPCompleter
2142 from IPython.core.completerlib import (module_completer,
2142 from IPython.core.completerlib import (module_completer,
2143 magic_run_completer, cd_completer, reset_completer)
2143 magic_run_completer, cd_completer, reset_completer)
2144
2144
2145 self.Completer = IPCompleter(shell=self,
2145 self.Completer = IPCompleter(shell=self,
2146 namespace=self.user_ns,
2146 namespace=self.user_ns,
2147 global_namespace=self.user_global_ns,
2147 global_namespace=self.user_global_ns,
2148 parent=self,
2148 parent=self,
2149 )
2149 )
2150 self.configurables.append(self.Completer)
2150 self.configurables.append(self.Completer)
2151
2151
2152 # Add custom completers to the basic ones built into IPCompleter
2152 # Add custom completers to the basic ones built into IPCompleter
2153 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2153 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2154 self.strdispatchers['complete_command'] = sdisp
2154 self.strdispatchers['complete_command'] = sdisp
2155 self.Completer.custom_completers = sdisp
2155 self.Completer.custom_completers = sdisp
2156
2156
2157 self.set_hook('complete_command', module_completer, str_key = 'import')
2157 self.set_hook('complete_command', module_completer, str_key = 'import')
2158 self.set_hook('complete_command', module_completer, str_key = 'from')
2158 self.set_hook('complete_command', module_completer, str_key = 'from')
2159 self.set_hook('complete_command', module_completer, str_key = '%aimport')
2159 self.set_hook('complete_command', module_completer, str_key = '%aimport')
2160 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2160 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2161 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2161 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2162 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2162 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2163
2163
2164 @skip_doctest
2164 @skip_doctest
2165 def complete(self, text, line=None, cursor_pos=None):
2165 def complete(self, text, line=None, cursor_pos=None):
2166 """Return the completed text and a list of completions.
2166 """Return the completed text and a list of completions.
2167
2167
2168 Parameters
2168 Parameters
2169 ----------
2169 ----------
2170
2170
2171 text : string
2171 text : string
2172 A string of text to be completed on. It can be given as empty and
2172 A string of text to be completed on. It can be given as empty and
2173 instead a line/position pair are given. In this case, the
2173 instead a line/position pair are given. In this case, the
2174 completer itself will split the line like readline does.
2174 completer itself will split the line like readline does.
2175
2175
2176 line : string, optional
2176 line : string, optional
2177 The complete line that text is part of.
2177 The complete line that text is part of.
2178
2178
2179 cursor_pos : int, optional
2179 cursor_pos : int, optional
2180 The position of the cursor on the input line.
2180 The position of the cursor on the input line.
2181
2181
2182 Returns
2182 Returns
2183 -------
2183 -------
2184 text : string
2184 text : string
2185 The actual text that was completed.
2185 The actual text that was completed.
2186
2186
2187 matches : list
2187 matches : list
2188 A sorted list with all possible completions.
2188 A sorted list with all possible completions.
2189
2189
2190 The optional arguments allow the completion to take more context into
2190 The optional arguments allow the completion to take more context into
2191 account, and are part of the low-level completion API.
2191 account, and are part of the low-level completion API.
2192
2192
2193 This is a wrapper around the completion mechanism, similar to what
2193 This is a wrapper around the completion mechanism, similar to what
2194 readline does at the command line when the TAB key is hit. By
2194 readline does at the command line when the TAB key is hit. By
2195 exposing it as a method, it can be used by other non-readline
2195 exposing it as a method, it can be used by other non-readline
2196 environments (such as GUIs) for text completion.
2196 environments (such as GUIs) for text completion.
2197
2197
2198 Simple usage example:
2198 Simple usage example:
2199
2199
2200 In [1]: x = 'hello'
2200 In [1]: x = 'hello'
2201
2201
2202 In [2]: _ip.complete('x.l')
2202 In [2]: _ip.complete('x.l')
2203 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2203 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2204 """
2204 """
2205
2205
2206 # Inject names into __builtin__ so we can complete on the added names.
2206 # Inject names into __builtin__ so we can complete on the added names.
2207 with self.builtin_trap:
2207 with self.builtin_trap:
2208 return self.Completer.complete(text, line, cursor_pos)
2208 return self.Completer.complete(text, line, cursor_pos)
2209
2209
2210 def set_custom_completer(self, completer, pos=0):
2210 def set_custom_completer(self, completer, pos=0):
2211 """Adds a new custom completer function.
2211 """Adds a new custom completer function.
2212
2212
2213 The position argument (defaults to 0) is the index in the completers
2213 The position argument (defaults to 0) is the index in the completers
2214 list where you want the completer to be inserted."""
2214 list where you want the completer to be inserted."""
2215
2215
2216 newcomp = types.MethodType(completer,self.Completer)
2216 newcomp = types.MethodType(completer,self.Completer)
2217 self.Completer.matchers.insert(pos,newcomp)
2217 self.Completer.matchers.insert(pos,newcomp)
2218
2218
2219 def set_completer_frame(self, frame=None):
2219 def set_completer_frame(self, frame=None):
2220 """Set the frame of the completer."""
2220 """Set the frame of the completer."""
2221 if frame:
2221 if frame:
2222 self.Completer.namespace = frame.f_locals
2222 self.Completer.namespace = frame.f_locals
2223 self.Completer.global_namespace = frame.f_globals
2223 self.Completer.global_namespace = frame.f_globals
2224 else:
2224 else:
2225 self.Completer.namespace = self.user_ns
2225 self.Completer.namespace = self.user_ns
2226 self.Completer.global_namespace = self.user_global_ns
2226 self.Completer.global_namespace = self.user_global_ns
2227
2227
2228 #-------------------------------------------------------------------------
2228 #-------------------------------------------------------------------------
2229 # Things related to magics
2229 # Things related to magics
2230 #-------------------------------------------------------------------------
2230 #-------------------------------------------------------------------------
2231
2231
2232 def init_magics(self):
2232 def init_magics(self):
2233 from IPython.core import magics as m
2233 from IPython.core import magics as m
2234 self.magics_manager = magic.MagicsManager(shell=self,
2234 self.magics_manager = magic.MagicsManager(shell=self,
2235 parent=self,
2235 parent=self,
2236 user_magics=m.UserMagics(self))
2236 user_magics=m.UserMagics(self))
2237 self.configurables.append(self.magics_manager)
2237 self.configurables.append(self.magics_manager)
2238
2238
2239 # Expose as public API from the magics manager
2239 # Expose as public API from the magics manager
2240 self.register_magics = self.magics_manager.register
2240 self.register_magics = self.magics_manager.register
2241
2241
2242 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2242 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2243 m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics,
2243 m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics,
2244 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2244 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2245 m.NamespaceMagics, m.OSMagics, m.PackagingMagics,
2245 m.NamespaceMagics, m.OSMagics, m.PackagingMagics,
2246 m.PylabMagics, m.ScriptMagics,
2246 m.PylabMagics, m.ScriptMagics,
2247 )
2247 )
2248 if sys.version_info >(3,5):
2248 if sys.version_info >(3,5):
2249 self.register_magics(m.AsyncMagics)
2249 self.register_magics(m.AsyncMagics)
2250
2250
2251 # Register Magic Aliases
2251 # Register Magic Aliases
2252 mman = self.magics_manager
2252 mman = self.magics_manager
2253 # FIXME: magic aliases should be defined by the Magics classes
2253 # FIXME: magic aliases should be defined by the Magics classes
2254 # or in MagicsManager, not here
2254 # or in MagicsManager, not here
2255 mman.register_alias('ed', 'edit')
2255 mman.register_alias('ed', 'edit')
2256 mman.register_alias('hist', 'history')
2256 mman.register_alias('hist', 'history')
2257 mman.register_alias('rep', 'recall')
2257 mman.register_alias('rep', 'recall')
2258 mman.register_alias('SVG', 'svg', 'cell')
2258 mman.register_alias('SVG', 'svg', 'cell')
2259 mman.register_alias('HTML', 'html', 'cell')
2259 mman.register_alias('HTML', 'html', 'cell')
2260 mman.register_alias('file', 'writefile', 'cell')
2260 mman.register_alias('file', 'writefile', 'cell')
2261
2261
2262 # FIXME: Move the color initialization to the DisplayHook, which
2262 # FIXME: Move the color initialization to the DisplayHook, which
2263 # should be split into a prompt manager and displayhook. We probably
2263 # should be split into a prompt manager and displayhook. We probably
2264 # even need a centralize colors management object.
2264 # even need a centralize colors management object.
2265 self.run_line_magic('colors', self.colors)
2265 self.run_line_magic('colors', self.colors)
2266
2266
2267 # Defined here so that it's included in the documentation
2267 # Defined here so that it's included in the documentation
2268 @functools.wraps(magic.MagicsManager.register_function)
2268 @functools.wraps(magic.MagicsManager.register_function)
2269 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2269 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2270 self.magics_manager.register_function(func,
2270 self.magics_manager.register_function(func,
2271 magic_kind=magic_kind, magic_name=magic_name)
2271 magic_kind=magic_kind, magic_name=magic_name)
2272
2272
2273 def run_line_magic(self, magic_name, line, _stack_depth=1):
2273 def run_line_magic(self, magic_name, line, _stack_depth=1):
2274 """Execute the given line magic.
2274 """Execute the given line magic.
2275
2275
2276 Parameters
2276 Parameters
2277 ----------
2277 ----------
2278 magic_name : str
2278 magic_name : str
2279 Name of the desired magic function, without '%' prefix.
2279 Name of the desired magic function, without '%' prefix.
2280
2280
2281 line : str
2281 line : str
2282 The rest of the input line as a single string.
2282 The rest of the input line as a single string.
2283
2283
2284 _stack_depth : int
2284 _stack_depth : int
2285 If run_line_magic() is called from magic() then _stack_depth=2.
2285 If run_line_magic() is called from magic() then _stack_depth=2.
2286 This is added to ensure backward compatibility for use of 'get_ipython().magic()'
2286 This is added to ensure backward compatibility for use of 'get_ipython().magic()'
2287 """
2287 """
2288 fn = self.find_line_magic(magic_name)
2288 fn = self.find_line_magic(magic_name)
2289 if fn is None:
2289 if fn is None:
2290 cm = self.find_cell_magic(magic_name)
2290 cm = self.find_cell_magic(magic_name)
2291 etpl = "Line magic function `%%%s` not found%s."
2291 etpl = "Line magic function `%%%s` not found%s."
2292 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2292 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2293 'did you mean that instead?)' % magic_name )
2293 'did you mean that instead?)' % magic_name )
2294 raise UsageError(etpl % (magic_name, extra))
2294 raise UsageError(etpl % (magic_name, extra))
2295 else:
2295 else:
2296 # Note: this is the distance in the stack to the user's frame.
2296 # Note: this is the distance in the stack to the user's frame.
2297 # This will need to be updated if the internal calling logic gets
2297 # This will need to be updated if the internal calling logic gets
2298 # refactored, or else we'll be expanding the wrong variables.
2298 # refactored, or else we'll be expanding the wrong variables.
2299
2299
2300 # Determine stack_depth depending on where run_line_magic() has been called
2300 # Determine stack_depth depending on where run_line_magic() has been called
2301 stack_depth = _stack_depth
2301 stack_depth = _stack_depth
2302 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2302 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2303 # magic has opted out of var_expand
2303 # magic has opted out of var_expand
2304 magic_arg_s = line
2304 magic_arg_s = line
2305 else:
2305 else:
2306 magic_arg_s = self.var_expand(line, stack_depth)
2306 magic_arg_s = self.var_expand(line, stack_depth)
2307 # Put magic args in a list so we can call with f(*a) syntax
2307 # Put magic args in a list so we can call with f(*a) syntax
2308 args = [magic_arg_s]
2308 args = [magic_arg_s]
2309 kwargs = {}
2309 kwargs = {}
2310 # Grab local namespace if we need it:
2310 # Grab local namespace if we need it:
2311 if getattr(fn, "needs_local_scope", False):
2311 if getattr(fn, "needs_local_scope", False):
2312 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2312 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2313 with self.builtin_trap:
2313 with self.builtin_trap:
2314 result = fn(*args, **kwargs)
2314 result = fn(*args, **kwargs)
2315 return result
2315 return result
2316
2316
2317 def run_cell_magic(self, magic_name, line, cell):
2317 def run_cell_magic(self, magic_name, line, cell):
2318 """Execute the given cell magic.
2318 """Execute the given cell magic.
2319
2319
2320 Parameters
2320 Parameters
2321 ----------
2321 ----------
2322 magic_name : str
2322 magic_name : str
2323 Name of the desired magic function, without '%' prefix.
2323 Name of the desired magic function, without '%' prefix.
2324
2324
2325 line : str
2325 line : str
2326 The rest of the first input line as a single string.
2326 The rest of the first input line as a single string.
2327
2327
2328 cell : str
2328 cell : str
2329 The body of the cell as a (possibly multiline) string.
2329 The body of the cell as a (possibly multiline) string.
2330 """
2330 """
2331 fn = self.find_cell_magic(magic_name)
2331 fn = self.find_cell_magic(magic_name)
2332 if fn is None:
2332 if fn is None:
2333 lm = self.find_line_magic(magic_name)
2333 lm = self.find_line_magic(magic_name)
2334 etpl = "Cell magic `%%{0}` not found{1}."
2334 etpl = "Cell magic `%%{0}` not found{1}."
2335 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2335 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2336 'did you mean that instead?)'.format(magic_name))
2336 'did you mean that instead?)'.format(magic_name))
2337 raise UsageError(etpl.format(magic_name, extra))
2337 raise UsageError(etpl.format(magic_name, extra))
2338 elif cell == '':
2338 elif cell == '':
2339 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2339 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2340 if self.find_line_magic(magic_name) is not None:
2340 if self.find_line_magic(magic_name) is not None:
2341 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2341 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2342 raise UsageError(message)
2342 raise UsageError(message)
2343 else:
2343 else:
2344 # Note: this is the distance in the stack to the user's frame.
2344 # Note: this is the distance in the stack to the user's frame.
2345 # This will need to be updated if the internal calling logic gets
2345 # This will need to be updated if the internal calling logic gets
2346 # refactored, or else we'll be expanding the wrong variables.
2346 # refactored, or else we'll be expanding the wrong variables.
2347 stack_depth = 2
2347 stack_depth = 2
2348 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2348 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2349 # magic has opted out of var_expand
2349 # magic has opted out of var_expand
2350 magic_arg_s = line
2350 magic_arg_s = line
2351 else:
2351 else:
2352 magic_arg_s = self.var_expand(line, stack_depth)
2352 magic_arg_s = self.var_expand(line, stack_depth)
2353 kwargs = {}
2353 kwargs = {}
2354 if getattr(fn, "needs_local_scope", False):
2354 if getattr(fn, "needs_local_scope", False):
2355 kwargs['local_ns'] = self.user_ns
2355 kwargs['local_ns'] = self.user_ns
2356
2356
2357 with self.builtin_trap:
2357 with self.builtin_trap:
2358 args = (magic_arg_s, cell)
2358 args = (magic_arg_s, cell)
2359 result = fn(*args, **kwargs)
2359 result = fn(*args, **kwargs)
2360 return result
2360 return result
2361
2361
2362 def find_line_magic(self, magic_name):
2362 def find_line_magic(self, magic_name):
2363 """Find and return a line magic by name.
2363 """Find and return a line magic by name.
2364
2364
2365 Returns None if the magic isn't found."""
2365 Returns None if the magic isn't found."""
2366 return self.magics_manager.magics['line'].get(magic_name)
2366 return self.magics_manager.magics['line'].get(magic_name)
2367
2367
2368 def find_cell_magic(self, magic_name):
2368 def find_cell_magic(self, magic_name):
2369 """Find and return a cell magic by name.
2369 """Find and return a cell magic by name.
2370
2370
2371 Returns None if the magic isn't found."""
2371 Returns None if the magic isn't found."""
2372 return self.magics_manager.magics['cell'].get(magic_name)
2372 return self.magics_manager.magics['cell'].get(magic_name)
2373
2373
2374 def find_magic(self, magic_name, magic_kind='line'):
2374 def find_magic(self, magic_name, magic_kind='line'):
2375 """Find and return a magic of the given type by name.
2375 """Find and return a magic of the given type by name.
2376
2376
2377 Returns None if the magic isn't found."""
2377 Returns None if the magic isn't found."""
2378 return self.magics_manager.magics[magic_kind].get(magic_name)
2378 return self.magics_manager.magics[magic_kind].get(magic_name)
2379
2379
2380 def magic(self, arg_s):
2380 def magic(self, arg_s):
2381 """DEPRECATED. Use run_line_magic() instead.
2381 """DEPRECATED. Use run_line_magic() instead.
2382
2382
2383 Call a magic function by name.
2383 Call a magic function by name.
2384
2384
2385 Input: a string containing the name of the magic function to call and
2385 Input: a string containing the name of the magic function to call and
2386 any additional arguments to be passed to the magic.
2386 any additional arguments to be passed to the magic.
2387
2387
2388 magic('name -opt foo bar') is equivalent to typing at the ipython
2388 magic('name -opt foo bar') is equivalent to typing at the ipython
2389 prompt:
2389 prompt:
2390
2390
2391 In[1]: %name -opt foo bar
2391 In[1]: %name -opt foo bar
2392
2392
2393 To call a magic without arguments, simply use magic('name').
2393 To call a magic without arguments, simply use magic('name').
2394
2394
2395 This provides a proper Python function to call IPython's magics in any
2395 This provides a proper Python function to call IPython's magics in any
2396 valid Python code you can type at the interpreter, including loops and
2396 valid Python code you can type at the interpreter, including loops and
2397 compound statements.
2397 compound statements.
2398 """
2398 """
2399 # TODO: should we issue a loud deprecation warning here?
2399 # TODO: should we issue a loud deprecation warning here?
2400 magic_name, _, magic_arg_s = arg_s.partition(' ')
2400 magic_name, _, magic_arg_s = arg_s.partition(' ')
2401 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2401 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2402 return self.run_line_magic(magic_name, magic_arg_s, _stack_depth=2)
2402 return self.run_line_magic(magic_name, magic_arg_s, _stack_depth=2)
2403
2403
2404 #-------------------------------------------------------------------------
2404 #-------------------------------------------------------------------------
2405 # Things related to macros
2405 # Things related to macros
2406 #-------------------------------------------------------------------------
2406 #-------------------------------------------------------------------------
2407
2407
2408 def define_macro(self, name, themacro):
2408 def define_macro(self, name, themacro):
2409 """Define a new macro
2409 """Define a new macro
2410
2410
2411 Parameters
2411 Parameters
2412 ----------
2412 ----------
2413 name : str
2413 name : str
2414 The name of the macro.
2414 The name of the macro.
2415 themacro : str or Macro
2415 themacro : str or Macro
2416 The action to do upon invoking the macro. If a string, a new
2416 The action to do upon invoking the macro. If a string, a new
2417 Macro object is created by passing the string to it.
2417 Macro object is created by passing the string to it.
2418 """
2418 """
2419
2419
2420 from IPython.core import macro
2420 from IPython.core import macro
2421
2421
2422 if isinstance(themacro, str):
2422 if isinstance(themacro, str):
2423 themacro = macro.Macro(themacro)
2423 themacro = macro.Macro(themacro)
2424 if not isinstance(themacro, macro.Macro):
2424 if not isinstance(themacro, macro.Macro):
2425 raise ValueError('A macro must be a string or a Macro instance.')
2425 raise ValueError('A macro must be a string or a Macro instance.')
2426 self.user_ns[name] = themacro
2426 self.user_ns[name] = themacro
2427
2427
2428 #-------------------------------------------------------------------------
2428 #-------------------------------------------------------------------------
2429 # Things related to the running of system commands
2429 # Things related to the running of system commands
2430 #-------------------------------------------------------------------------
2430 #-------------------------------------------------------------------------
2431
2431
2432 def system_piped(self, cmd):
2432 def system_piped(self, cmd):
2433 """Call the given cmd in a subprocess, piping stdout/err
2433 """Call the given cmd in a subprocess, piping stdout/err
2434
2434
2435 Parameters
2435 Parameters
2436 ----------
2436 ----------
2437 cmd : str
2437 cmd : str
2438 Command to execute (can not end in '&', as background processes are
2438 Command to execute (can not end in '&', as background processes are
2439 not supported. Should not be a command that expects input
2439 not supported. Should not be a command that expects input
2440 other than simple text.
2440 other than simple text.
2441 """
2441 """
2442 if cmd.rstrip().endswith('&'):
2442 if cmd.rstrip().endswith('&'):
2443 # this is *far* from a rigorous test
2443 # this is *far* from a rigorous test
2444 # We do not support backgrounding processes because we either use
2444 # We do not support backgrounding processes because we either use
2445 # pexpect or pipes to read from. Users can always just call
2445 # pexpect or pipes to read from. Users can always just call
2446 # os.system() or use ip.system=ip.system_raw
2446 # os.system() or use ip.system=ip.system_raw
2447 # if they really want a background process.
2447 # if they really want a background process.
2448 raise OSError("Background processes not supported.")
2448 raise OSError("Background processes not supported.")
2449
2449
2450 # we explicitly do NOT return the subprocess status code, because
2450 # we explicitly do NOT return the subprocess status code, because
2451 # a non-None value would trigger :func:`sys.displayhook` calls.
2451 # a non-None value would trigger :func:`sys.displayhook` calls.
2452 # Instead, we store the exit_code in user_ns.
2452 # Instead, we store the exit_code in user_ns.
2453 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2453 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2454
2454
2455 def system_raw(self, cmd):
2455 def system_raw(self, cmd):
2456 """Call the given cmd in a subprocess using os.system on Windows or
2456 """Call the given cmd in a subprocess using os.system on Windows or
2457 subprocess.call using the system shell on other platforms.
2457 subprocess.call using the system shell on other platforms.
2458
2458
2459 Parameters
2459 Parameters
2460 ----------
2460 ----------
2461 cmd : str
2461 cmd : str
2462 Command to execute.
2462 Command to execute.
2463 """
2463 """
2464 cmd = self.var_expand(cmd, depth=1)
2464 cmd = self.var_expand(cmd, depth=1)
2465 # protect os.system from UNC paths on Windows, which it can't handle:
2465 # protect os.system from UNC paths on Windows, which it can't handle:
2466 if sys.platform == 'win32':
2466 if sys.platform == 'win32':
2467 from IPython.utils._process_win32 import AvoidUNCPath
2467 from IPython.utils._process_win32 import AvoidUNCPath
2468 with AvoidUNCPath() as path:
2468 with AvoidUNCPath() as path:
2469 if path is not None:
2469 if path is not None:
2470 cmd = '"pushd %s &&"%s' % (path, cmd)
2470 cmd = '"pushd %s &&"%s' % (path, cmd)
2471 try:
2471 try:
2472 ec = os.system(cmd)
2472 ec = os.system(cmd)
2473 except KeyboardInterrupt:
2473 except KeyboardInterrupt:
2474 print('\n' + self.get_exception_only(), file=sys.stderr)
2474 print('\n' + self.get_exception_only(), file=sys.stderr)
2475 ec = -2
2475 ec = -2
2476 else:
2476 else:
2477 # For posix the result of the subprocess.call() below is an exit
2477 # For posix the result of the subprocess.call() below is an exit
2478 # code, which by convention is zero for success, positive for
2478 # code, which by convention is zero for success, positive for
2479 # program failure. Exit codes above 128 are reserved for signals,
2479 # program failure. Exit codes above 128 are reserved for signals,
2480 # and the formula for converting a signal to an exit code is usually
2480 # and the formula for converting a signal to an exit code is usually
2481 # signal_number+128. To more easily differentiate between exit
2481 # signal_number+128. To more easily differentiate between exit
2482 # codes and signals, ipython uses negative numbers. For instance
2482 # codes and signals, ipython uses negative numbers. For instance
2483 # since control-c is signal 2 but exit code 130, ipython's
2483 # since control-c is signal 2 but exit code 130, ipython's
2484 # _exit_code variable will read -2. Note that some shells like
2484 # _exit_code variable will read -2. Note that some shells like
2485 # csh and fish don't follow sh/bash conventions for exit codes.
2485 # csh and fish don't follow sh/bash conventions for exit codes.
2486 executable = os.environ.get('SHELL', None)
2486 executable = os.environ.get('SHELL', None)
2487 try:
2487 try:
2488 # Use env shell instead of default /bin/sh
2488 # Use env shell instead of default /bin/sh
2489 ec = subprocess.call(cmd, shell=True, executable=executable)
2489 ec = subprocess.call(cmd, shell=True, executable=executable)
2490 except KeyboardInterrupt:
2490 except KeyboardInterrupt:
2491 # intercept control-C; a long traceback is not useful here
2491 # intercept control-C; a long traceback is not useful here
2492 print('\n' + self.get_exception_only(), file=sys.stderr)
2492 print('\n' + self.get_exception_only(), file=sys.stderr)
2493 ec = 130
2493 ec = 130
2494 if ec > 128:
2494 if ec > 128:
2495 ec = -(ec - 128)
2495 ec = -(ec - 128)
2496
2496
2497 # We explicitly do NOT return the subprocess status code, because
2497 # We explicitly do NOT return the subprocess status code, because
2498 # a non-None value would trigger :func:`sys.displayhook` calls.
2498 # a non-None value would trigger :func:`sys.displayhook` calls.
2499 # Instead, we store the exit_code in user_ns. Note the semantics
2499 # Instead, we store the exit_code in user_ns. Note the semantics
2500 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2500 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2501 # but raising SystemExit(_exit_code) will give status 254!
2501 # but raising SystemExit(_exit_code) will give status 254!
2502 self.user_ns['_exit_code'] = ec
2502 self.user_ns['_exit_code'] = ec
2503
2503
2504 # use piped system by default, because it is better behaved
2504 # use piped system by default, because it is better behaved
2505 system = system_piped
2505 system = system_piped
2506
2506
2507 def getoutput(self, cmd, split=True, depth=0):
2507 def getoutput(self, cmd, split=True, depth=0):
2508 """Get output (possibly including stderr) from a subprocess.
2508 """Get output (possibly including stderr) from a subprocess.
2509
2509
2510 Parameters
2510 Parameters
2511 ----------
2511 ----------
2512 cmd : str
2512 cmd : str
2513 Command to execute (can not end in '&', as background processes are
2513 Command to execute (can not end in '&', as background processes are
2514 not supported.
2514 not supported.
2515 split : bool, optional
2515 split : bool, optional
2516 If True, split the output into an IPython SList. Otherwise, an
2516 If True, split the output into an IPython SList. Otherwise, an
2517 IPython LSString is returned. These are objects similar to normal
2517 IPython LSString is returned. These are objects similar to normal
2518 lists and strings, with a few convenience attributes for easier
2518 lists and strings, with a few convenience attributes for easier
2519 manipulation of line-based output. You can use '?' on them for
2519 manipulation of line-based output. You can use '?' on them for
2520 details.
2520 details.
2521 depth : int, optional
2521 depth : int, optional
2522 How many frames above the caller are the local variables which should
2522 How many frames above the caller are the local variables which should
2523 be expanded in the command string? The default (0) assumes that the
2523 be expanded in the command string? The default (0) assumes that the
2524 expansion variables are in the stack frame calling this function.
2524 expansion variables are in the stack frame calling this function.
2525 """
2525 """
2526 if cmd.rstrip().endswith('&'):
2526 if cmd.rstrip().endswith('&'):
2527 # this is *far* from a rigorous test
2527 # this is *far* from a rigorous test
2528 raise OSError("Background processes not supported.")
2528 raise OSError("Background processes not supported.")
2529 out = getoutput(self.var_expand(cmd, depth=depth+1))
2529 out = getoutput(self.var_expand(cmd, depth=depth+1))
2530 if split:
2530 if split:
2531 out = SList(out.splitlines())
2531 out = SList(out.splitlines())
2532 else:
2532 else:
2533 out = LSString(out)
2533 out = LSString(out)
2534 return out
2534 return out
2535
2535
2536 #-------------------------------------------------------------------------
2536 #-------------------------------------------------------------------------
2537 # Things related to aliases
2537 # Things related to aliases
2538 #-------------------------------------------------------------------------
2538 #-------------------------------------------------------------------------
2539
2539
2540 def init_alias(self):
2540 def init_alias(self):
2541 self.alias_manager = AliasManager(shell=self, parent=self)
2541 self.alias_manager = AliasManager(shell=self, parent=self)
2542 self.configurables.append(self.alias_manager)
2542 self.configurables.append(self.alias_manager)
2543
2543
2544 #-------------------------------------------------------------------------
2544 #-------------------------------------------------------------------------
2545 # Things related to extensions
2545 # Things related to extensions
2546 #-------------------------------------------------------------------------
2546 #-------------------------------------------------------------------------
2547
2547
2548 def init_extension_manager(self):
2548 def init_extension_manager(self):
2549 self.extension_manager = ExtensionManager(shell=self, parent=self)
2549 self.extension_manager = ExtensionManager(shell=self, parent=self)
2550 self.configurables.append(self.extension_manager)
2550 self.configurables.append(self.extension_manager)
2551
2551
2552 #-------------------------------------------------------------------------
2552 #-------------------------------------------------------------------------
2553 # Things related to payloads
2553 # Things related to payloads
2554 #-------------------------------------------------------------------------
2554 #-------------------------------------------------------------------------
2555
2555
2556 def init_payload(self):
2556 def init_payload(self):
2557 self.payload_manager = PayloadManager(parent=self)
2557 self.payload_manager = PayloadManager(parent=self)
2558 self.configurables.append(self.payload_manager)
2558 self.configurables.append(self.payload_manager)
2559
2559
2560 #-------------------------------------------------------------------------
2560 #-------------------------------------------------------------------------
2561 # Things related to the prefilter
2561 # Things related to the prefilter
2562 #-------------------------------------------------------------------------
2562 #-------------------------------------------------------------------------
2563
2563
2564 def init_prefilter(self):
2564 def init_prefilter(self):
2565 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2565 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2566 self.configurables.append(self.prefilter_manager)
2566 self.configurables.append(self.prefilter_manager)
2567 # Ultimately this will be refactored in the new interpreter code, but
2567 # Ultimately this will be refactored in the new interpreter code, but
2568 # for now, we should expose the main prefilter method (there's legacy
2568 # for now, we should expose the main prefilter method (there's legacy
2569 # code out there that may rely on this).
2569 # code out there that may rely on this).
2570 self.prefilter = self.prefilter_manager.prefilter_lines
2570 self.prefilter = self.prefilter_manager.prefilter_lines
2571
2571
2572 def auto_rewrite_input(self, cmd):
2572 def auto_rewrite_input(self, cmd):
2573 """Print to the screen the rewritten form of the user's command.
2573 """Print to the screen the rewritten form of the user's command.
2574
2574
2575 This shows visual feedback by rewriting input lines that cause
2575 This shows visual feedback by rewriting input lines that cause
2576 automatic calling to kick in, like::
2576 automatic calling to kick in, like::
2577
2577
2578 /f x
2578 /f x
2579
2579
2580 into::
2580 into::
2581
2581
2582 ------> f(x)
2582 ------> f(x)
2583
2583
2584 after the user's input prompt. This helps the user understand that the
2584 after the user's input prompt. This helps the user understand that the
2585 input line was transformed automatically by IPython.
2585 input line was transformed automatically by IPython.
2586 """
2586 """
2587 if not self.show_rewritten_input:
2587 if not self.show_rewritten_input:
2588 return
2588 return
2589
2589
2590 # This is overridden in TerminalInteractiveShell to use fancy prompts
2590 # This is overridden in TerminalInteractiveShell to use fancy prompts
2591 print("------> " + cmd)
2591 print("------> " + cmd)
2592
2592
2593 #-------------------------------------------------------------------------
2593 #-------------------------------------------------------------------------
2594 # Things related to extracting values/expressions from kernel and user_ns
2594 # Things related to extracting values/expressions from kernel and user_ns
2595 #-------------------------------------------------------------------------
2595 #-------------------------------------------------------------------------
2596
2596
2597 def _user_obj_error(self):
2597 def _user_obj_error(self):
2598 """return simple exception dict
2598 """return simple exception dict
2599
2599
2600 for use in user_expressions
2600 for use in user_expressions
2601 """
2601 """
2602
2602
2603 etype, evalue, tb = self._get_exc_info()
2603 etype, evalue, tb = self._get_exc_info()
2604 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2604 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2605
2605
2606 exc_info = {
2606 exc_info = {
2607 u'status' : 'error',
2607 u'status' : 'error',
2608 u'traceback' : stb,
2608 u'traceback' : stb,
2609 u'ename' : etype.__name__,
2609 u'ename' : etype.__name__,
2610 u'evalue' : py3compat.safe_unicode(evalue),
2610 u'evalue' : py3compat.safe_unicode(evalue),
2611 }
2611 }
2612
2612
2613 return exc_info
2613 return exc_info
2614
2614
2615 def _format_user_obj(self, obj):
2615 def _format_user_obj(self, obj):
2616 """format a user object to display dict
2616 """format a user object to display dict
2617
2617
2618 for use in user_expressions
2618 for use in user_expressions
2619 """
2619 """
2620
2620
2621 data, md = self.display_formatter.format(obj)
2621 data, md = self.display_formatter.format(obj)
2622 value = {
2622 value = {
2623 'status' : 'ok',
2623 'status' : 'ok',
2624 'data' : data,
2624 'data' : data,
2625 'metadata' : md,
2625 'metadata' : md,
2626 }
2626 }
2627 return value
2627 return value
2628
2628
2629 def user_expressions(self, expressions):
2629 def user_expressions(self, expressions):
2630 """Evaluate a dict of expressions in the user's namespace.
2630 """Evaluate a dict of expressions in the user's namespace.
2631
2631
2632 Parameters
2632 Parameters
2633 ----------
2633 ----------
2634 expressions : dict
2634 expressions : dict
2635 A dict with string keys and string values. The expression values
2635 A dict with string keys and string values. The expression values
2636 should be valid Python expressions, each of which will be evaluated
2636 should be valid Python expressions, each of which will be evaluated
2637 in the user namespace.
2637 in the user namespace.
2638
2638
2639 Returns
2639 Returns
2640 -------
2640 -------
2641 A dict, keyed like the input expressions dict, with the rich mime-typed
2641 A dict, keyed like the input expressions dict, with the rich mime-typed
2642 display_data of each value.
2642 display_data of each value.
2643 """
2643 """
2644 out = {}
2644 out = {}
2645 user_ns = self.user_ns
2645 user_ns = self.user_ns
2646 global_ns = self.user_global_ns
2646 global_ns = self.user_global_ns
2647
2647
2648 for key, expr in expressions.items():
2648 for key, expr in expressions.items():
2649 try:
2649 try:
2650 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2650 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2651 except:
2651 except:
2652 value = self._user_obj_error()
2652 value = self._user_obj_error()
2653 out[key] = value
2653 out[key] = value
2654 return out
2654 return out
2655
2655
2656 #-------------------------------------------------------------------------
2656 #-------------------------------------------------------------------------
2657 # Things related to the running of code
2657 # Things related to the running of code
2658 #-------------------------------------------------------------------------
2658 #-------------------------------------------------------------------------
2659
2659
2660 def ex(self, cmd):
2660 def ex(self, cmd):
2661 """Execute a normal python statement in user namespace."""
2661 """Execute a normal python statement in user namespace."""
2662 with self.builtin_trap:
2662 with self.builtin_trap:
2663 exec(cmd, self.user_global_ns, self.user_ns)
2663 exec(cmd, self.user_global_ns, self.user_ns)
2664
2664
2665 def ev(self, expr):
2665 def ev(self, expr):
2666 """Evaluate python expression expr in user namespace.
2666 """Evaluate python expression expr in user namespace.
2667
2667
2668 Returns the result of evaluation
2668 Returns the result of evaluation
2669 """
2669 """
2670 with self.builtin_trap:
2670 with self.builtin_trap:
2671 return eval(expr, self.user_global_ns, self.user_ns)
2671 return eval(expr, self.user_global_ns, self.user_ns)
2672
2672
2673 def safe_execfile(self, fname, *where, exit_ignore=False, raise_exceptions=False, shell_futures=False):
2673 def safe_execfile(self, fname, *where, exit_ignore=False, raise_exceptions=False, shell_futures=False):
2674 """A safe version of the builtin execfile().
2674 """A safe version of the builtin execfile().
2675
2675
2676 This version will never throw an exception, but instead print
2676 This version will never throw an exception, but instead print
2677 helpful error messages to the screen. This only works on pure
2677 helpful error messages to the screen. This only works on pure
2678 Python files with the .py extension.
2678 Python files with the .py extension.
2679
2679
2680 Parameters
2680 Parameters
2681 ----------
2681 ----------
2682 fname : string
2682 fname : string
2683 The name of the file to be executed.
2683 The name of the file to be executed.
2684 where : tuple
2684 where : tuple
2685 One or two namespaces, passed to execfile() as (globals,locals).
2685 One or two namespaces, passed to execfile() as (globals,locals).
2686 If only one is given, it is passed as both.
2686 If only one is given, it is passed as both.
2687 exit_ignore : bool (False)
2687 exit_ignore : bool (False)
2688 If True, then silence SystemExit for non-zero status (it is always
2688 If True, then silence SystemExit for non-zero status (it is always
2689 silenced for zero status, as it is so common).
2689 silenced for zero status, as it is so common).
2690 raise_exceptions : bool (False)
2690 raise_exceptions : bool (False)
2691 If True raise exceptions everywhere. Meant for testing.
2691 If True raise exceptions everywhere. Meant for testing.
2692 shell_futures : bool (False)
2692 shell_futures : bool (False)
2693 If True, the code will share future statements with the interactive
2693 If True, the code will share future statements with the interactive
2694 shell. It will both be affected by previous __future__ imports, and
2694 shell. It will both be affected by previous __future__ imports, and
2695 any __future__ imports in the code will affect the shell. If False,
2695 any __future__ imports in the code will affect the shell. If False,
2696 __future__ imports are not shared in either direction.
2696 __future__ imports are not shared in either direction.
2697
2697
2698 """
2698 """
2699 fname = os.path.abspath(os.path.expanduser(fname))
2699 fname = os.path.abspath(os.path.expanduser(fname))
2700
2700
2701 # Make sure we can open the file
2701 # Make sure we can open the file
2702 try:
2702 try:
2703 with open(fname):
2703 with open(fname):
2704 pass
2704 pass
2705 except:
2705 except:
2706 warn('Could not open file <%s> for safe execution.' % fname)
2706 warn('Could not open file <%s> for safe execution.' % fname)
2707 return
2707 return
2708
2708
2709 # Find things also in current directory. This is needed to mimic the
2709 # Find things also in current directory. This is needed to mimic the
2710 # behavior of running a script from the system command line, where
2710 # behavior of running a script from the system command line, where
2711 # Python inserts the script's directory into sys.path
2711 # Python inserts the script's directory into sys.path
2712 dname = os.path.dirname(fname)
2712 dname = os.path.dirname(fname)
2713
2713
2714 with prepended_to_syspath(dname), self.builtin_trap:
2714 with prepended_to_syspath(dname), self.builtin_trap:
2715 try:
2715 try:
2716 glob, loc = (where + (None, ))[:2]
2716 glob, loc = (where + (None, ))[:2]
2717 py3compat.execfile(
2717 py3compat.execfile(
2718 fname, glob, loc,
2718 fname, glob, loc,
2719 self.compile if shell_futures else None)
2719 self.compile if shell_futures else None)
2720 except SystemExit as status:
2720 except SystemExit as status:
2721 # If the call was made with 0 or None exit status (sys.exit(0)
2721 # If the call was made with 0 or None exit status (sys.exit(0)
2722 # or sys.exit() ), don't bother showing a traceback, as both of
2722 # or sys.exit() ), don't bother showing a traceback, as both of
2723 # these are considered normal by the OS:
2723 # these are considered normal by the OS:
2724 # > python -c'import sys;sys.exit(0)'; echo $?
2724 # > python -c'import sys;sys.exit(0)'; echo $?
2725 # 0
2725 # 0
2726 # > python -c'import sys;sys.exit()'; echo $?
2726 # > python -c'import sys;sys.exit()'; echo $?
2727 # 0
2727 # 0
2728 # For other exit status, we show the exception unless
2728 # For other exit status, we show the exception unless
2729 # explicitly silenced, but only in short form.
2729 # explicitly silenced, but only in short form.
2730 if status.code:
2730 if status.code:
2731 if raise_exceptions:
2731 if raise_exceptions:
2732 raise
2732 raise
2733 if not exit_ignore:
2733 if not exit_ignore:
2734 self.showtraceback(exception_only=True)
2734 self.showtraceback(exception_only=True)
2735 except:
2735 except:
2736 if raise_exceptions:
2736 if raise_exceptions:
2737 raise
2737 raise
2738 # tb offset is 2 because we wrap execfile
2738 # tb offset is 2 because we wrap execfile
2739 self.showtraceback(tb_offset=2)
2739 self.showtraceback(tb_offset=2)
2740
2740
2741 def safe_execfile_ipy(self, fname, shell_futures=False, raise_exceptions=False):
2741 def safe_execfile_ipy(self, fname, shell_futures=False, raise_exceptions=False):
2742 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2742 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2743
2743
2744 Parameters
2744 Parameters
2745 ----------
2745 ----------
2746 fname : str
2746 fname : str
2747 The name of the file to execute. The filename must have a
2747 The name of the file to execute. The filename must have a
2748 .ipy or .ipynb extension.
2748 .ipy or .ipynb extension.
2749 shell_futures : bool (False)
2749 shell_futures : bool (False)
2750 If True, the code will share future statements with the interactive
2750 If True, the code will share future statements with the interactive
2751 shell. It will both be affected by previous __future__ imports, and
2751 shell. It will both be affected by previous __future__ imports, and
2752 any __future__ imports in the code will affect the shell. If False,
2752 any __future__ imports in the code will affect the shell. If False,
2753 __future__ imports are not shared in either direction.
2753 __future__ imports are not shared in either direction.
2754 raise_exceptions : bool (False)
2754 raise_exceptions : bool (False)
2755 If True raise exceptions everywhere. Meant for testing.
2755 If True raise exceptions everywhere. Meant for testing.
2756 """
2756 """
2757 fname = os.path.abspath(os.path.expanduser(fname))
2757 fname = os.path.abspath(os.path.expanduser(fname))
2758
2758
2759 # Make sure we can open the file
2759 # Make sure we can open the file
2760 try:
2760 try:
2761 with open(fname):
2761 with open(fname):
2762 pass
2762 pass
2763 except:
2763 except:
2764 warn('Could not open file <%s> for safe execution.' % fname)
2764 warn('Could not open file <%s> for safe execution.' % fname)
2765 return
2765 return
2766
2766
2767 # Find things also in current directory. This is needed to mimic the
2767 # Find things also in current directory. This is needed to mimic the
2768 # behavior of running a script from the system command line, where
2768 # behavior of running a script from the system command line, where
2769 # Python inserts the script's directory into sys.path
2769 # Python inserts the script's directory into sys.path
2770 dname = os.path.dirname(fname)
2770 dname = os.path.dirname(fname)
2771
2771
2772 def get_cells():
2772 def get_cells():
2773 """generator for sequence of code blocks to run"""
2773 """generator for sequence of code blocks to run"""
2774 if fname.endswith('.ipynb'):
2774 if fname.endswith('.ipynb'):
2775 from nbformat import read
2775 from nbformat import read
2776 nb = read(fname, as_version=4)
2776 nb = read(fname, as_version=4)
2777 if not nb.cells:
2777 if not nb.cells:
2778 return
2778 return
2779 for cell in nb.cells:
2779 for cell in nb.cells:
2780 if cell.cell_type == 'code':
2780 if cell.cell_type == 'code':
2781 yield cell.source
2781 yield cell.source
2782 else:
2782 else:
2783 with open(fname) as f:
2783 with open(fname) as f:
2784 yield f.read()
2784 yield f.read()
2785
2785
2786 with prepended_to_syspath(dname):
2786 with prepended_to_syspath(dname):
2787 try:
2787 try:
2788 for cell in get_cells():
2788 for cell in get_cells():
2789 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2789 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2790 if raise_exceptions:
2790 if raise_exceptions:
2791 result.raise_error()
2791 result.raise_error()
2792 elif not result.success:
2792 elif not result.success:
2793 break
2793 break
2794 except:
2794 except:
2795 if raise_exceptions:
2795 if raise_exceptions:
2796 raise
2796 raise
2797 self.showtraceback()
2797 self.showtraceback()
2798 warn('Unknown failure executing file: <%s>' % fname)
2798 warn('Unknown failure executing file: <%s>' % fname)
2799
2799
2800 def safe_run_module(self, mod_name, where):
2800 def safe_run_module(self, mod_name, where):
2801 """A safe version of runpy.run_module().
2801 """A safe version of runpy.run_module().
2802
2802
2803 This version will never throw an exception, but instead print
2803 This version will never throw an exception, but instead print
2804 helpful error messages to the screen.
2804 helpful error messages to the screen.
2805
2805
2806 `SystemExit` exceptions with status code 0 or None are ignored.
2806 `SystemExit` exceptions with status code 0 or None are ignored.
2807
2807
2808 Parameters
2808 Parameters
2809 ----------
2809 ----------
2810 mod_name : string
2810 mod_name : string
2811 The name of the module to be executed.
2811 The name of the module to be executed.
2812 where : dict
2812 where : dict
2813 The globals namespace.
2813 The globals namespace.
2814 """
2814 """
2815 try:
2815 try:
2816 try:
2816 try:
2817 where.update(
2817 where.update(
2818 runpy.run_module(str(mod_name), run_name="__main__",
2818 runpy.run_module(str(mod_name), run_name="__main__",
2819 alter_sys=True)
2819 alter_sys=True)
2820 )
2820 )
2821 except SystemExit as status:
2821 except SystemExit as status:
2822 if status.code:
2822 if status.code:
2823 raise
2823 raise
2824 except:
2824 except:
2825 self.showtraceback()
2825 self.showtraceback()
2826 warn('Unknown failure executing module: <%s>' % mod_name)
2826 warn('Unknown failure executing module: <%s>' % mod_name)
2827
2827
2828 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2828 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2829 """Run a complete IPython cell.
2829 """Run a complete IPython cell.
2830
2830
2831 Parameters
2831 Parameters
2832 ----------
2832 ----------
2833 raw_cell : str
2833 raw_cell : str
2834 The code (including IPython code such as %magic functions) to run.
2834 The code (including IPython code such as %magic functions) to run.
2835 store_history : bool
2835 store_history : bool
2836 If True, the raw and translated cell will be stored in IPython's
2836 If True, the raw and translated cell will be stored in IPython's
2837 history. For user code calling back into IPython's machinery, this
2837 history. For user code calling back into IPython's machinery, this
2838 should be set to False.
2838 should be set to False.
2839 silent : bool
2839 silent : bool
2840 If True, avoid side-effects, such as implicit displayhooks and
2840 If True, avoid side-effects, such as implicit displayhooks and
2841 and logging. silent=True forces store_history=False.
2841 and logging. silent=True forces store_history=False.
2842 shell_futures : bool
2842 shell_futures : bool
2843 If True, the code will share future statements with the interactive
2843 If True, the code will share future statements with the interactive
2844 shell. It will both be affected by previous __future__ imports, and
2844 shell. It will both be affected by previous __future__ imports, and
2845 any __future__ imports in the code will affect the shell. If False,
2845 any __future__ imports in the code will affect the shell. If False,
2846 __future__ imports are not shared in either direction.
2846 __future__ imports are not shared in either direction.
2847
2847
2848 Returns
2848 Returns
2849 -------
2849 -------
2850 result : :class:`ExecutionResult`
2850 result : :class:`ExecutionResult`
2851 """
2851 """
2852 result = None
2852 result = None
2853 try:
2853 try:
2854 result = self._run_cell(
2854 result = self._run_cell(
2855 raw_cell, store_history, silent, shell_futures)
2855 raw_cell, store_history, silent, shell_futures)
2856 finally:
2856 finally:
2857 self.events.trigger('post_execute')
2857 self.events.trigger('post_execute')
2858 if not silent:
2858 if not silent:
2859 self.events.trigger('post_run_cell', result)
2859 self.events.trigger('post_run_cell', result)
2860 return result
2860 return result
2861
2861
2862 def _run_cell(self, raw_cell:str, store_history:bool, silent:bool, shell_futures:bool):
2862 def _run_cell(self, raw_cell:str, store_history:bool, silent:bool, shell_futures:bool):
2863 """Internal method to run a complete IPython cell."""
2863 """Internal method to run a complete IPython cell."""
2864 coro = self.run_cell_async(
2864 coro = self.run_cell_async(
2865 raw_cell,
2865 raw_cell,
2866 store_history=store_history,
2866 store_history=store_history,
2867 silent=silent,
2867 silent=silent,
2868 shell_futures=shell_futures,
2868 shell_futures=shell_futures,
2869 )
2869 )
2870
2870
2871 # run_cell_async is async, but may not actually need an eventloop.
2871 # run_cell_async is async, but may not actually need an eventloop.
2872 # when this is the case, we want to run it using the pseudo_sync_runner
2872 # when this is the case, we want to run it using the pseudo_sync_runner
2873 # so that code can invoke eventloops (for example via the %run , and
2873 # so that code can invoke eventloops (for example via the %run , and
2874 # `%paste` magic.
2874 # `%paste` magic.
2875 if self.should_run_async(raw_cell):
2875 if self.should_run_async(raw_cell):
2876 runner = self.loop_runner
2876 runner = self.loop_runner
2877 else:
2877 else:
2878 runner = _pseudo_sync_runner
2878 runner = _pseudo_sync_runner
2879
2879
2880 try:
2880 try:
2881 return runner(coro)
2881 return runner(coro)
2882 except BaseException as e:
2882 except BaseException as e:
2883 info = ExecutionInfo(raw_cell, store_history, silent, shell_futures)
2883 info = ExecutionInfo(raw_cell, store_history, silent, shell_futures)
2884 result = ExecutionResult(info)
2884 result = ExecutionResult(info)
2885 result.error_in_exec = e
2885 result.error_in_exec = e
2886 self.showtraceback(running_compiled_code=True)
2886 self.showtraceback(running_compiled_code=True)
2887 return result
2887 return result
2888 return
2888 return
2889
2889
2890 def should_run_async(self, raw_cell: str) -> bool:
2890 def should_run_async(self, raw_cell: str) -> bool:
2891 """Return whether a cell should be run asynchronously via a coroutine runner
2891 """Return whether a cell should be run asynchronously via a coroutine runner
2892
2892
2893 Parameters
2893 Parameters
2894 ----------
2894 ----------
2895 raw_cell: str
2895 raw_cell: str
2896 The code to be executed
2896 The code to be executed
2897
2897
2898 Returns
2898 Returns
2899 -------
2899 -------
2900 result: bool
2900 result: bool
2901 Whether the code needs to be run with a coroutine runner or not
2901 Whether the code needs to be run with a coroutine runner or not
2902
2902
2903 .. versionadded: 7.0
2903 .. versionadded: 7.0
2904 """
2904 """
2905 if not self.autoawait:
2905 if not self.autoawait:
2906 return False
2906 return False
2907 try:
2907 try:
2908 cell = self.transform_cell(raw_cell)
2908 cell = self.transform_cell(raw_cell)
2909 except Exception:
2909 except Exception:
2910 # any exception during transform will be raised
2910 # any exception during transform will be raised
2911 # prior to execution
2911 # prior to execution
2912 return False
2912 return False
2913 return _should_be_async(cell)
2913 return _should_be_async(cell)
2914
2914
2915 async def run_cell_async(self, raw_cell: str, store_history=False, silent=False, shell_futures=True) -> ExecutionResult:
2915 async def run_cell_async(self, raw_cell: str, store_history=False, silent=False, shell_futures=True) -> ExecutionResult:
2916 """Run a complete IPython cell asynchronously.
2916 """Run a complete IPython cell asynchronously.
2917
2917
2918 Parameters
2918 Parameters
2919 ----------
2919 ----------
2920 raw_cell : str
2920 raw_cell : str
2921 The code (including IPython code such as %magic functions) to run.
2921 The code (including IPython code such as %magic functions) to run.
2922 store_history : bool
2922 store_history : bool
2923 If True, the raw and translated cell will be stored in IPython's
2923 If True, the raw and translated cell will be stored in IPython's
2924 history. For user code calling back into IPython's machinery, this
2924 history. For user code calling back into IPython's machinery, this
2925 should be set to False.
2925 should be set to False.
2926 silent : bool
2926 silent : bool
2927 If True, avoid side-effects, such as implicit displayhooks and
2927 If True, avoid side-effects, such as implicit displayhooks and
2928 and logging. silent=True forces store_history=False.
2928 and logging. silent=True forces store_history=False.
2929 shell_futures : bool
2929 shell_futures : bool
2930 If True, the code will share future statements with the interactive
2930 If True, the code will share future statements with the interactive
2931 shell. It will both be affected by previous __future__ imports, and
2931 shell. It will both be affected by previous __future__ imports, and
2932 any __future__ imports in the code will affect the shell. If False,
2932 any __future__ imports in the code will affect the shell. If False,
2933 __future__ imports are not shared in either direction.
2933 __future__ imports are not shared in either direction.
2934
2934
2935 Returns
2935 Returns
2936 -------
2936 -------
2937 result : :class:`ExecutionResult`
2937 result : :class:`ExecutionResult`
2938
2938
2939 .. versionadded: 7.0
2939 .. versionadded: 7.0
2940 """
2940 """
2941 info = ExecutionInfo(
2941 info = ExecutionInfo(
2942 raw_cell, store_history, silent, shell_futures)
2942 raw_cell, store_history, silent, shell_futures)
2943 result = ExecutionResult(info)
2943 result = ExecutionResult(info)
2944
2944
2945 if (not raw_cell) or raw_cell.isspace():
2945 if (not raw_cell) or raw_cell.isspace():
2946 self.last_execution_succeeded = True
2946 self.last_execution_succeeded = True
2947 self.last_execution_result = result
2947 self.last_execution_result = result
2948 return result
2948 return result
2949
2949
2950 if silent:
2950 if silent:
2951 store_history = False
2951 store_history = False
2952
2952
2953 if store_history:
2953 if store_history:
2954 result.execution_count = self.execution_count
2954 result.execution_count = self.execution_count
2955
2955
2956 def error_before_exec(value):
2956 def error_before_exec(value):
2957 if store_history:
2957 if store_history:
2958 self.execution_count += 1
2958 self.execution_count += 1
2959 result.error_before_exec = value
2959 result.error_before_exec = value
2960 self.last_execution_succeeded = False
2960 self.last_execution_succeeded = False
2961 self.last_execution_result = result
2961 self.last_execution_result = result
2962 return result
2962 return result
2963
2963
2964 self.events.trigger('pre_execute')
2964 self.events.trigger('pre_execute')
2965 if not silent:
2965 if not silent:
2966 self.events.trigger('pre_run_cell', info)
2966 self.events.trigger('pre_run_cell', info)
2967
2967
2968 # If any of our input transformation (input_transformer_manager or
2968 # If any of our input transformation (input_transformer_manager or
2969 # prefilter_manager) raises an exception, we store it in this variable
2969 # prefilter_manager) raises an exception, we store it in this variable
2970 # so that we can display the error after logging the input and storing
2970 # so that we can display the error after logging the input and storing
2971 # it in the history.
2971 # it in the history.
2972 try:
2972 try:
2973 cell = self.transform_cell(raw_cell)
2973 cell = self.transform_cell(raw_cell)
2974 except Exception:
2974 except Exception:
2975 preprocessing_exc_tuple = sys.exc_info()
2975 preprocessing_exc_tuple = sys.exc_info()
2976 cell = raw_cell # cell has to exist so it can be stored/logged
2976 cell = raw_cell # cell has to exist so it can be stored/logged
2977 else:
2977 else:
2978 preprocessing_exc_tuple = None
2978 preprocessing_exc_tuple = None
2979
2979
2980 # Store raw and processed history
2980 # Store raw and processed history
2981 if store_history:
2981 if store_history:
2982 self.history_manager.store_inputs(self.execution_count,
2982 self.history_manager.store_inputs(self.execution_count,
2983 cell, raw_cell)
2983 cell, raw_cell)
2984 if not silent:
2984 if not silent:
2985 self.logger.log(cell, raw_cell)
2985 self.logger.log(cell, raw_cell)
2986
2986
2987 # Display the exception if input processing failed.
2987 # Display the exception if input processing failed.
2988 if preprocessing_exc_tuple is not None:
2988 if preprocessing_exc_tuple is not None:
2989 self.showtraceback(preprocessing_exc_tuple)
2989 self.showtraceback(preprocessing_exc_tuple)
2990 if store_history:
2990 if store_history:
2991 self.execution_count += 1
2991 self.execution_count += 1
2992 return error_before_exec(preprocessing_exc_tuple[1])
2992 return error_before_exec(preprocessing_exc_tuple[1])
2993
2993
2994 # Our own compiler remembers the __future__ environment. If we want to
2994 # Our own compiler remembers the __future__ environment. If we want to
2995 # run code with a separate __future__ environment, use the default
2995 # run code with a separate __future__ environment, use the default
2996 # compiler
2996 # compiler
2997 compiler = self.compile if shell_futures else CachingCompiler()
2997 compiler = self.compile if shell_futures else CachingCompiler()
2998
2998
2999 _run_async = False
2999 _run_async = False
3000
3000
3001 with self.builtin_trap:
3001 with self.builtin_trap:
3002 cell_name = self.compile.cache(cell, self.execution_count)
3002 cell_name = self.compile.cache(cell, self.execution_count)
3003
3003
3004 with self.display_trap:
3004 with self.display_trap:
3005 # Compile to bytecode
3005 # Compile to bytecode
3006 try:
3006 try:
3007 if sys.version_info < (3,8) and self.autoawait:
3007 if sys.version_info < (3,8) and self.autoawait:
3008 if _should_be_async(cell):
3008 if _should_be_async(cell):
3009 # the code AST below will not be user code: we wrap it
3009 # the code AST below will not be user code: we wrap it
3010 # in an `async def`. This will likely make some AST
3010 # in an `async def`. This will likely make some AST
3011 # transformer below miss some transform opportunity and
3011 # transformer below miss some transform opportunity and
3012 # introduce a small coupling to run_code (in which we
3012 # introduce a small coupling to run_code (in which we
3013 # bake some assumptions of what _ast_asyncify returns.
3013 # bake some assumptions of what _ast_asyncify returns.
3014 # they are ways around (like grafting part of the ast
3014 # they are ways around (like grafting part of the ast
3015 # later:
3015 # later:
3016 # - Here, return code_ast.body[0].body[1:-1], as well
3016 # - Here, return code_ast.body[0].body[1:-1], as well
3017 # as last expression in return statement which is
3017 # as last expression in return statement which is
3018 # the user code part.
3018 # the user code part.
3019 # - Let it go through the AST transformers, and graft
3019 # - Let it go through the AST transformers, and graft
3020 # - it back after the AST transform
3020 # - it back after the AST transform
3021 # But that seem unreasonable, at least while we
3021 # But that seem unreasonable, at least while we
3022 # do not need it.
3022 # do not need it.
3023 code_ast = _ast_asyncify(cell, 'async-def-wrapper')
3023 code_ast = _ast_asyncify(cell, 'async-def-wrapper')
3024 _run_async = True
3024 _run_async = True
3025 else:
3025 else:
3026 code_ast = compiler.ast_parse(cell, filename=cell_name)
3026 code_ast = compiler.ast_parse(cell, filename=cell_name)
3027 else:
3027 else:
3028 code_ast = compiler.ast_parse(cell, filename=cell_name)
3028 code_ast = compiler.ast_parse(cell, filename=cell_name)
3029 except self.custom_exceptions as e:
3029 except self.custom_exceptions as e:
3030 etype, value, tb = sys.exc_info()
3030 etype, value, tb = sys.exc_info()
3031 self.CustomTB(etype, value, tb)
3031 self.CustomTB(etype, value, tb)
3032 return error_before_exec(e)
3032 return error_before_exec(e)
3033 except IndentationError as e:
3033 except IndentationError as e:
3034 self.showindentationerror()
3034 self.showindentationerror()
3035 return error_before_exec(e)
3035 return error_before_exec(e)
3036 except (OverflowError, SyntaxError, ValueError, TypeError,
3036 except (OverflowError, SyntaxError, ValueError, TypeError,
3037 MemoryError) as e:
3037 MemoryError) as e:
3038 self.showsyntaxerror()
3038 self.showsyntaxerror()
3039 return error_before_exec(e)
3039 return error_before_exec(e)
3040
3040
3041 # Apply AST transformations
3041 # Apply AST transformations
3042 try:
3042 try:
3043 code_ast = self.transform_ast(code_ast)
3043 code_ast = self.transform_ast(code_ast)
3044 except InputRejected as e:
3044 except InputRejected as e:
3045 self.showtraceback()
3045 self.showtraceback()
3046 return error_before_exec(e)
3046 return error_before_exec(e)
3047
3047
3048 # Give the displayhook a reference to our ExecutionResult so it
3048 # Give the displayhook a reference to our ExecutionResult so it
3049 # can fill in the output value.
3049 # can fill in the output value.
3050 self.displayhook.exec_result = result
3050 self.displayhook.exec_result = result
3051
3051
3052 # Execute the user code
3052 # Execute the user code
3053 interactivity = "none" if silent else self.ast_node_interactivity
3053 interactivity = "none" if silent else self.ast_node_interactivity
3054 if _run_async:
3054 if _run_async:
3055 interactivity = 'async'
3055 interactivity = 'async'
3056
3056
3057 has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
3057 has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
3058 interactivity=interactivity, compiler=compiler, result=result)
3058 interactivity=interactivity, compiler=compiler, result=result)
3059
3059
3060 self.last_execution_succeeded = not has_raised
3060 self.last_execution_succeeded = not has_raised
3061 self.last_execution_result = result
3061 self.last_execution_result = result
3062
3062
3063 # Reset this so later displayed values do not modify the
3063 # Reset this so later displayed values do not modify the
3064 # ExecutionResult
3064 # ExecutionResult
3065 self.displayhook.exec_result = None
3065 self.displayhook.exec_result = None
3066
3066
3067 if store_history:
3067 if store_history:
3068 # Write output to the database. Does nothing unless
3068 # Write output to the database. Does nothing unless
3069 # history output logging is enabled.
3069 # history output logging is enabled.
3070 self.history_manager.store_output(self.execution_count)
3070 self.history_manager.store_output(self.execution_count)
3071 # Each cell is a *single* input, regardless of how many lines it has
3071 # Each cell is a *single* input, regardless of how many lines it has
3072 self.execution_count += 1
3072 self.execution_count += 1
3073
3073
3074 return result
3074 return result
3075
3075
3076 def transform_cell(self, raw_cell):
3076 def transform_cell(self, raw_cell):
3077 """Transform an input cell before parsing it.
3077 """Transform an input cell before parsing it.
3078
3078
3079 Static transformations, implemented in IPython.core.inputtransformer2,
3079 Static transformations, implemented in IPython.core.inputtransformer2,
3080 deal with things like ``%magic`` and ``!system`` commands.
3080 deal with things like ``%magic`` and ``!system`` commands.
3081 These run on all input.
3081 These run on all input.
3082 Dynamic transformations, for things like unescaped magics and the exit
3082 Dynamic transformations, for things like unescaped magics and the exit
3083 autocall, depend on the state of the interpreter.
3083 autocall, depend on the state of the interpreter.
3084 These only apply to single line inputs.
3084 These only apply to single line inputs.
3085
3085
3086 These string-based transformations are followed by AST transformations;
3086 These string-based transformations are followed by AST transformations;
3087 see :meth:`transform_ast`.
3087 see :meth:`transform_ast`.
3088 """
3088 """
3089 # Static input transformations
3089 # Static input transformations
3090 cell = self.input_transformer_manager.transform_cell(raw_cell)
3090 cell = self.input_transformer_manager.transform_cell(raw_cell)
3091
3091
3092 if len(cell.splitlines()) == 1:
3092 if len(cell.splitlines()) == 1:
3093 # Dynamic transformations - only applied for single line commands
3093 # Dynamic transformations - only applied for single line commands
3094 with self.builtin_trap:
3094 with self.builtin_trap:
3095 # use prefilter_lines to handle trailing newlines
3095 # use prefilter_lines to handle trailing newlines
3096 # restore trailing newline for ast.parse
3096 # restore trailing newline for ast.parse
3097 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
3097 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
3098
3098
3099 lines = cell.splitlines(keepends=True)
3099 lines = cell.splitlines(keepends=True)
3100 for transform in self.input_transformers_post:
3100 for transform in self.input_transformers_post:
3101 lines = transform(lines)
3101 lines = transform(lines)
3102 cell = ''.join(lines)
3102 cell = ''.join(lines)
3103
3103
3104 return cell
3104 return cell
3105
3105
3106 def transform_ast(self, node):
3106 def transform_ast(self, node):
3107 """Apply the AST transformations from self.ast_transformers
3107 """Apply the AST transformations from self.ast_transformers
3108
3108
3109 Parameters
3109 Parameters
3110 ----------
3110 ----------
3111 node : ast.Node
3111 node : ast.Node
3112 The root node to be transformed. Typically called with the ast.Module
3112 The root node to be transformed. Typically called with the ast.Module
3113 produced by parsing user input.
3113 produced by parsing user input.
3114
3114
3115 Returns
3115 Returns
3116 -------
3116 -------
3117 An ast.Node corresponding to the node it was called with. Note that it
3117 An ast.Node corresponding to the node it was called with. Note that it
3118 may also modify the passed object, so don't rely on references to the
3118 may also modify the passed object, so don't rely on references to the
3119 original AST.
3119 original AST.
3120 """
3120 """
3121 for transformer in self.ast_transformers:
3121 for transformer in self.ast_transformers:
3122 try:
3122 try:
3123 node = transformer.visit(node)
3123 node = transformer.visit(node)
3124 except InputRejected:
3124 except InputRejected:
3125 # User-supplied AST transformers can reject an input by raising
3125 # User-supplied AST transformers can reject an input by raising
3126 # an InputRejected. Short-circuit in this case so that we
3126 # an InputRejected. Short-circuit in this case so that we
3127 # don't unregister the transform.
3127 # don't unregister the transform.
3128 raise
3128 raise
3129 except Exception:
3129 except Exception:
3130 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
3130 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
3131 self.ast_transformers.remove(transformer)
3131 self.ast_transformers.remove(transformer)
3132
3132
3133 if self.ast_transformers:
3133 if self.ast_transformers:
3134 ast.fix_missing_locations(node)
3134 ast.fix_missing_locations(node)
3135 return node
3135 return node
3136
3136
3137 async def run_ast_nodes(self, nodelist:ListType[AST], cell_name:str, interactivity='last_expr',
3137 async def run_ast_nodes(self, nodelist:ListType[AST], cell_name:str, interactivity='last_expr',
3138 compiler=compile, result=None):
3138 compiler=compile, result=None):
3139 """Run a sequence of AST nodes. The execution mode depends on the
3139 """Run a sequence of AST nodes. The execution mode depends on the
3140 interactivity parameter.
3140 interactivity parameter.
3141
3141
3142 Parameters
3142 Parameters
3143 ----------
3143 ----------
3144 nodelist : list
3144 nodelist : list
3145 A sequence of AST nodes to run.
3145 A sequence of AST nodes to run.
3146 cell_name : str
3146 cell_name : str
3147 Will be passed to the compiler as the filename of the cell. Typically
3147 Will be passed to the compiler as the filename of the cell. Typically
3148 the value returned by ip.compile.cache(cell).
3148 the value returned by ip.compile.cache(cell).
3149 interactivity : str
3149 interactivity : str
3150 'all', 'last', 'last_expr' , 'last_expr_or_assign' or 'none',
3150 'all', 'last', 'last_expr' , 'last_expr_or_assign' or 'none',
3151 specifying which nodes should be run interactively (displaying output
3151 specifying which nodes should be run interactively (displaying output
3152 from expressions). 'last_expr' will run the last node interactively
3152 from expressions). 'last_expr' will run the last node interactively
3153 only if it is an expression (i.e. expressions in loops or other blocks
3153 only if it is an expression (i.e. expressions in loops or other blocks
3154 are not displayed) 'last_expr_or_assign' will run the last expression
3154 are not displayed) 'last_expr_or_assign' will run the last expression
3155 or the last assignment. Other values for this parameter will raise a
3155 or the last assignment. Other values for this parameter will raise a
3156 ValueError.
3156 ValueError.
3157
3157
3158 Experimental value: 'async' Will try to run top level interactive
3158 Experimental value: 'async' Will try to run top level interactive
3159 async/await code in default runner, this will not respect the
3159 async/await code in default runner, this will not respect the
3160 interactivty setting and will only run the last node if it is an
3160 interactivity setting and will only run the last node if it is an
3161 expression.
3161 expression.
3162
3162
3163 compiler : callable
3163 compiler : callable
3164 A function with the same interface as the built-in compile(), to turn
3164 A function with the same interface as the built-in compile(), to turn
3165 the AST nodes into code objects. Default is the built-in compile().
3165 the AST nodes into code objects. Default is the built-in compile().
3166 result : ExecutionResult, optional
3166 result : ExecutionResult, optional
3167 An object to store exceptions that occur during execution.
3167 An object to store exceptions that occur during execution.
3168
3168
3169 Returns
3169 Returns
3170 -------
3170 -------
3171 True if an exception occurred while running code, False if it finished
3171 True if an exception occurred while running code, False if it finished
3172 running.
3172 running.
3173 """
3173 """
3174 if not nodelist:
3174 if not nodelist:
3175 return
3175 return
3176
3176
3177 if interactivity == 'last_expr_or_assign':
3177 if interactivity == 'last_expr_or_assign':
3178 if isinstance(nodelist[-1], _assign_nodes):
3178 if isinstance(nodelist[-1], _assign_nodes):
3179 asg = nodelist[-1]
3179 asg = nodelist[-1]
3180 if isinstance(asg, ast.Assign) and len(asg.targets) == 1:
3180 if isinstance(asg, ast.Assign) and len(asg.targets) == 1:
3181 target = asg.targets[0]
3181 target = asg.targets[0]
3182 elif isinstance(asg, _single_targets_nodes):
3182 elif isinstance(asg, _single_targets_nodes):
3183 target = asg.target
3183 target = asg.target
3184 else:
3184 else:
3185 target = None
3185 target = None
3186 if isinstance(target, ast.Name):
3186 if isinstance(target, ast.Name):
3187 nnode = ast.Expr(ast.Name(target.id, ast.Load()))
3187 nnode = ast.Expr(ast.Name(target.id, ast.Load()))
3188 ast.fix_missing_locations(nnode)
3188 ast.fix_missing_locations(nnode)
3189 nodelist.append(nnode)
3189 nodelist.append(nnode)
3190 interactivity = 'last_expr'
3190 interactivity = 'last_expr'
3191
3191
3192 _async = False
3192 _async = False
3193 if interactivity == 'last_expr':
3193 if interactivity == 'last_expr':
3194 if isinstance(nodelist[-1], ast.Expr):
3194 if isinstance(nodelist[-1], ast.Expr):
3195 interactivity = "last"
3195 interactivity = "last"
3196 else:
3196 else:
3197 interactivity = "none"
3197 interactivity = "none"
3198
3198
3199 if interactivity == 'none':
3199 if interactivity == 'none':
3200 to_run_exec, to_run_interactive = nodelist, []
3200 to_run_exec, to_run_interactive = nodelist, []
3201 elif interactivity == 'last':
3201 elif interactivity == 'last':
3202 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
3202 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
3203 elif interactivity == 'all':
3203 elif interactivity == 'all':
3204 to_run_exec, to_run_interactive = [], nodelist
3204 to_run_exec, to_run_interactive = [], nodelist
3205 elif interactivity == 'async':
3205 elif interactivity == 'async':
3206 to_run_exec, to_run_interactive = [], nodelist
3206 to_run_exec, to_run_interactive = [], nodelist
3207 _async = True
3207 _async = True
3208 else:
3208 else:
3209 raise ValueError("Interactivity was %r" % interactivity)
3209 raise ValueError("Interactivity was %r" % interactivity)
3210
3210
3211 try:
3211 try:
3212 if _async and sys.version_info > (3,8):
3212 if _async and sys.version_info > (3,8):
3213 raise ValueError("This branch should never happen on Python 3.8 and above, "
3213 raise ValueError("This branch should never happen on Python 3.8 and above, "
3214 "please try to upgrade IPython and open a bug report with your case.")
3214 "please try to upgrade IPython and open a bug report with your case.")
3215 if _async:
3215 if _async:
3216 # If interactivity is async the semantics of run_code are
3216 # If interactivity is async the semantics of run_code are
3217 # completely different Skip usual machinery.
3217 # completely different Skip usual machinery.
3218 mod = Module(nodelist, [])
3218 mod = Module(nodelist, [])
3219 async_wrapper_code = compiler(mod, cell_name, 'exec')
3219 async_wrapper_code = compiler(mod, cell_name, 'exec')
3220 exec(async_wrapper_code, self.user_global_ns, self.user_ns)
3220 exec(async_wrapper_code, self.user_global_ns, self.user_ns)
3221 async_code = removed_co_newlocals(self.user_ns.pop('async-def-wrapper')).__code__
3221 async_code = removed_co_newlocals(self.user_ns.pop('async-def-wrapper')).__code__
3222 if (await self.run_code(async_code, result, async_=True)):
3222 if (await self.run_code(async_code, result, async_=True)):
3223 return True
3223 return True
3224 else:
3224 else:
3225 if sys.version_info > (3, 8):
3225 if sys.version_info > (3, 8):
3226 def compare(code):
3226 def compare(code):
3227 is_async = (inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE)
3227 is_async = (inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE)
3228 return is_async
3228 return is_async
3229 else:
3229 else:
3230 def compare(code):
3230 def compare(code):
3231 return _async
3231 return _async
3232
3232
3233 # refactor that to just change the mod constructor.
3233 # refactor that to just change the mod constructor.
3234 to_run = []
3234 to_run = []
3235 for node in to_run_exec:
3235 for node in to_run_exec:
3236 to_run.append((node, 'exec'))
3236 to_run.append((node, 'exec'))
3237
3237
3238 for node in to_run_interactive:
3238 for node in to_run_interactive:
3239 to_run.append((node, 'single'))
3239 to_run.append((node, 'single'))
3240
3240
3241 for node,mode in to_run:
3241 for node,mode in to_run:
3242 if mode == 'exec':
3242 if mode == 'exec':
3243 mod = Module([node], [])
3243 mod = Module([node], [])
3244 elif mode == 'single':
3244 elif mode == 'single':
3245 mod = ast.Interactive([node])
3245 mod = ast.Interactive([node])
3246 with compiler.extra_flags(getattr(ast, 'PyCF_ALLOW_TOP_LEVEL_AWAIT', 0x0) if self.autoawait else 0x0):
3246 with compiler.extra_flags(getattr(ast, 'PyCF_ALLOW_TOP_LEVEL_AWAIT', 0x0) if self.autoawait else 0x0):
3247 code = compiler(mod, cell_name, mode)
3247 code = compiler(mod, cell_name, mode)
3248 asy = compare(code)
3248 asy = compare(code)
3249 if (await self.run_code(code, result, async_=asy)):
3249 if (await self.run_code(code, result, async_=asy)):
3250 return True
3250 return True
3251
3251
3252 # Flush softspace
3252 # Flush softspace
3253 if softspace(sys.stdout, 0):
3253 if softspace(sys.stdout, 0):
3254 print()
3254 print()
3255
3255
3256 except:
3256 except:
3257 # It's possible to have exceptions raised here, typically by
3257 # It's possible to have exceptions raised here, typically by
3258 # compilation of odd code (such as a naked 'return' outside a
3258 # compilation of odd code (such as a naked 'return' outside a
3259 # function) that did parse but isn't valid. Typically the exception
3259 # function) that did parse but isn't valid. Typically the exception
3260 # is a SyntaxError, but it's safest just to catch anything and show
3260 # is a SyntaxError, but it's safest just to catch anything and show
3261 # the user a traceback.
3261 # the user a traceback.
3262
3262
3263 # We do only one try/except outside the loop to minimize the impact
3263 # We do only one try/except outside the loop to minimize the impact
3264 # on runtime, and also because if any node in the node list is
3264 # on runtime, and also because if any node in the node list is
3265 # broken, we should stop execution completely.
3265 # broken, we should stop execution completely.
3266 if result:
3266 if result:
3267 result.error_before_exec = sys.exc_info()[1]
3267 result.error_before_exec = sys.exc_info()[1]
3268 self.showtraceback()
3268 self.showtraceback()
3269 return True
3269 return True
3270
3270
3271 return False
3271 return False
3272
3272
3273 def _async_exec(self, code_obj: types.CodeType, user_ns: dict):
3273 def _async_exec(self, code_obj: types.CodeType, user_ns: dict):
3274 """
3274 """
3275 Evaluate an asynchronous code object using a code runner
3275 Evaluate an asynchronous code object using a code runner
3276
3276
3277 Fake asynchronous execution of code_object in a namespace via a proxy namespace.
3277 Fake asynchronous execution of code_object in a namespace via a proxy namespace.
3278
3278
3279 Returns coroutine object, which can be executed via async loop runner
3279 Returns coroutine object, which can be executed via async loop runner
3280
3280
3281 WARNING: The semantics of `async_exec` are quite different from `exec`,
3281 WARNING: The semantics of `async_exec` are quite different from `exec`,
3282 in particular you can only pass a single namespace. It also return a
3282 in particular you can only pass a single namespace. It also return a
3283 handle to the value of the last things returned by code_object.
3283 handle to the value of the last things returned by code_object.
3284 """
3284 """
3285
3285
3286 return eval(code_obj, user_ns)
3286 return eval(code_obj, user_ns)
3287
3287
3288 async def run_code(self, code_obj, result=None, *, async_=False):
3288 async def run_code(self, code_obj, result=None, *, async_=False):
3289 """Execute a code object.
3289 """Execute a code object.
3290
3290
3291 When an exception occurs, self.showtraceback() is called to display a
3291 When an exception occurs, self.showtraceback() is called to display a
3292 traceback.
3292 traceback.
3293
3293
3294 Parameters
3294 Parameters
3295 ----------
3295 ----------
3296 code_obj : code object
3296 code_obj : code object
3297 A compiled code object, to be executed
3297 A compiled code object, to be executed
3298 result : ExecutionResult, optional
3298 result : ExecutionResult, optional
3299 An object to store exceptions that occur during execution.
3299 An object to store exceptions that occur during execution.
3300 async_ : Bool (Experimental)
3300 async_ : Bool (Experimental)
3301 Attempt to run top-level asynchronous code in a default loop.
3301 Attempt to run top-level asynchronous code in a default loop.
3302
3302
3303 Returns
3303 Returns
3304 -------
3304 -------
3305 False : successful execution.
3305 False : successful execution.
3306 True : an error occurred.
3306 True : an error occurred.
3307 """
3307 """
3308 # Set our own excepthook in case the user code tries to call it
3308 # Set our own excepthook in case the user code tries to call it
3309 # directly, so that the IPython crash handler doesn't get triggered
3309 # directly, so that the IPython crash handler doesn't get triggered
3310 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3310 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3311
3311
3312 # we save the original sys.excepthook in the instance, in case config
3312 # we save the original sys.excepthook in the instance, in case config
3313 # code (such as magics) needs access to it.
3313 # code (such as magics) needs access to it.
3314 self.sys_excepthook = old_excepthook
3314 self.sys_excepthook = old_excepthook
3315 outflag = True # happens in more places, so it's easier as default
3315 outflag = True # happens in more places, so it's easier as default
3316 try:
3316 try:
3317 try:
3317 try:
3318 self.hooks.pre_run_code_hook()
3318 self.hooks.pre_run_code_hook()
3319 if async_ and sys.version_info < (3,8):
3319 if async_ and sys.version_info < (3,8):
3320 last_expr = (await self._async_exec(code_obj, self.user_ns))
3320 last_expr = (await self._async_exec(code_obj, self.user_ns))
3321 code = compile('last_expr', 'fake', "single")
3321 code = compile('last_expr', 'fake', "single")
3322 exec(code, {'last_expr': last_expr})
3322 exec(code, {'last_expr': last_expr})
3323 elif async_ :
3323 elif async_ :
3324 await eval(code_obj, self.user_global_ns, self.user_ns)
3324 await eval(code_obj, self.user_global_ns, self.user_ns)
3325 else:
3325 else:
3326 exec(code_obj, self.user_global_ns, self.user_ns)
3326 exec(code_obj, self.user_global_ns, self.user_ns)
3327 finally:
3327 finally:
3328 # Reset our crash handler in place
3328 # Reset our crash handler in place
3329 sys.excepthook = old_excepthook
3329 sys.excepthook = old_excepthook
3330 except SystemExit as e:
3330 except SystemExit as e:
3331 if result is not None:
3331 if result is not None:
3332 result.error_in_exec = e
3332 result.error_in_exec = e
3333 self.showtraceback(exception_only=True)
3333 self.showtraceback(exception_only=True)
3334 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
3334 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
3335 except self.custom_exceptions:
3335 except self.custom_exceptions:
3336 etype, value, tb = sys.exc_info()
3336 etype, value, tb = sys.exc_info()
3337 if result is not None:
3337 if result is not None:
3338 result.error_in_exec = value
3338 result.error_in_exec = value
3339 self.CustomTB(etype, value, tb)
3339 self.CustomTB(etype, value, tb)
3340 except:
3340 except:
3341 if result is not None:
3341 if result is not None:
3342 result.error_in_exec = sys.exc_info()[1]
3342 result.error_in_exec = sys.exc_info()[1]
3343 self.showtraceback(running_compiled_code=True)
3343 self.showtraceback(running_compiled_code=True)
3344 else:
3344 else:
3345 outflag = False
3345 outflag = False
3346 return outflag
3346 return outflag
3347
3347
3348 # For backwards compatibility
3348 # For backwards compatibility
3349 runcode = run_code
3349 runcode = run_code
3350
3350
3351 def check_complete(self, code: str) -> Tuple[str, str]:
3351 def check_complete(self, code: str) -> Tuple[str, str]:
3352 """Return whether a block of code is ready to execute, or should be continued
3352 """Return whether a block of code is ready to execute, or should be continued
3353
3353
3354 Parameters
3354 Parameters
3355 ----------
3355 ----------
3356 source : string
3356 source : string
3357 Python input code, which can be multiline.
3357 Python input code, which can be multiline.
3358
3358
3359 Returns
3359 Returns
3360 -------
3360 -------
3361 status : str
3361 status : str
3362 One of 'complete', 'incomplete', or 'invalid' if source is not a
3362 One of 'complete', 'incomplete', or 'invalid' if source is not a
3363 prefix of valid code.
3363 prefix of valid code.
3364 indent : str
3364 indent : str
3365 When status is 'incomplete', this is some whitespace to insert on
3365 When status is 'incomplete', this is some whitespace to insert on
3366 the next line of the prompt.
3366 the next line of the prompt.
3367 """
3367 """
3368 status, nspaces = self.input_transformer_manager.check_complete(code)
3368 status, nspaces = self.input_transformer_manager.check_complete(code)
3369 return status, ' ' * (nspaces or 0)
3369 return status, ' ' * (nspaces or 0)
3370
3370
3371 #-------------------------------------------------------------------------
3371 #-------------------------------------------------------------------------
3372 # Things related to GUI support and pylab
3372 # Things related to GUI support and pylab
3373 #-------------------------------------------------------------------------
3373 #-------------------------------------------------------------------------
3374
3374
3375 active_eventloop = None
3375 active_eventloop = None
3376
3376
3377 def enable_gui(self, gui=None):
3377 def enable_gui(self, gui=None):
3378 raise NotImplementedError('Implement enable_gui in a subclass')
3378 raise NotImplementedError('Implement enable_gui in a subclass')
3379
3379
3380 def enable_matplotlib(self, gui=None):
3380 def enable_matplotlib(self, gui=None):
3381 """Enable interactive matplotlib and inline figure support.
3381 """Enable interactive matplotlib and inline figure support.
3382
3382
3383 This takes the following steps:
3383 This takes the following steps:
3384
3384
3385 1. select the appropriate eventloop and matplotlib backend
3385 1. select the appropriate eventloop and matplotlib backend
3386 2. set up matplotlib for interactive use with that backend
3386 2. set up matplotlib for interactive use with that backend
3387 3. configure formatters for inline figure display
3387 3. configure formatters for inline figure display
3388 4. enable the selected gui eventloop
3388 4. enable the selected gui eventloop
3389
3389
3390 Parameters
3390 Parameters
3391 ----------
3391 ----------
3392 gui : optional, string
3392 gui : optional, string
3393 If given, dictates the choice of matplotlib GUI backend to use
3393 If given, dictates the choice of matplotlib GUI backend to use
3394 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3394 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3395 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3395 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3396 matplotlib (as dictated by the matplotlib build-time options plus the
3396 matplotlib (as dictated by the matplotlib build-time options plus the
3397 user's matplotlibrc configuration file). Note that not all backends
3397 user's matplotlibrc configuration file). Note that not all backends
3398 make sense in all contexts, for example a terminal ipython can't
3398 make sense in all contexts, for example a terminal ipython can't
3399 display figures inline.
3399 display figures inline.
3400 """
3400 """
3401 from IPython.core import pylabtools as pt
3401 from IPython.core import pylabtools as pt
3402 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3402 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3403
3403
3404 if gui != 'inline':
3404 if gui != 'inline':
3405 # If we have our first gui selection, store it
3405 # If we have our first gui selection, store it
3406 if self.pylab_gui_select is None:
3406 if self.pylab_gui_select is None:
3407 self.pylab_gui_select = gui
3407 self.pylab_gui_select = gui
3408 # Otherwise if they are different
3408 # Otherwise if they are different
3409 elif gui != self.pylab_gui_select:
3409 elif gui != self.pylab_gui_select:
3410 print('Warning: Cannot change to a different GUI toolkit: %s.'
3410 print('Warning: Cannot change to a different GUI toolkit: %s.'
3411 ' Using %s instead.' % (gui, self.pylab_gui_select))
3411 ' Using %s instead.' % (gui, self.pylab_gui_select))
3412 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3412 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3413
3413
3414 pt.activate_matplotlib(backend)
3414 pt.activate_matplotlib(backend)
3415 pt.configure_inline_support(self, backend)
3415 pt.configure_inline_support(self, backend)
3416
3416
3417 # Now we must activate the gui pylab wants to use, and fix %run to take
3417 # Now we must activate the gui pylab wants to use, and fix %run to take
3418 # plot updates into account
3418 # plot updates into account
3419 self.enable_gui(gui)
3419 self.enable_gui(gui)
3420 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3420 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3421 pt.mpl_runner(self.safe_execfile)
3421 pt.mpl_runner(self.safe_execfile)
3422
3422
3423 return gui, backend
3423 return gui, backend
3424
3424
3425 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3425 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3426 """Activate pylab support at runtime.
3426 """Activate pylab support at runtime.
3427
3427
3428 This turns on support for matplotlib, preloads into the interactive
3428 This turns on support for matplotlib, preloads into the interactive
3429 namespace all of numpy and pylab, and configures IPython to correctly
3429 namespace all of numpy and pylab, and configures IPython to correctly
3430 interact with the GUI event loop. The GUI backend to be used can be
3430 interact with the GUI event loop. The GUI backend to be used can be
3431 optionally selected with the optional ``gui`` argument.
3431 optionally selected with the optional ``gui`` argument.
3432
3432
3433 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3433 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3434
3434
3435 Parameters
3435 Parameters
3436 ----------
3436 ----------
3437 gui : optional, string
3437 gui : optional, string
3438 If given, dictates the choice of matplotlib GUI backend to use
3438 If given, dictates the choice of matplotlib GUI backend to use
3439 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3439 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3440 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3440 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3441 matplotlib (as dictated by the matplotlib build-time options plus the
3441 matplotlib (as dictated by the matplotlib build-time options plus the
3442 user's matplotlibrc configuration file). Note that not all backends
3442 user's matplotlibrc configuration file). Note that not all backends
3443 make sense in all contexts, for example a terminal ipython can't
3443 make sense in all contexts, for example a terminal ipython can't
3444 display figures inline.
3444 display figures inline.
3445 import_all : optional, bool, default: True
3445 import_all : optional, bool, default: True
3446 Whether to do `from numpy import *` and `from pylab import *`
3446 Whether to do `from numpy import *` and `from pylab import *`
3447 in addition to module imports.
3447 in addition to module imports.
3448 welcome_message : deprecated
3448 welcome_message : deprecated
3449 This argument is ignored, no welcome message will be displayed.
3449 This argument is ignored, no welcome message will be displayed.
3450 """
3450 """
3451 from IPython.core.pylabtools import import_pylab
3451 from IPython.core.pylabtools import import_pylab
3452
3452
3453 gui, backend = self.enable_matplotlib(gui)
3453 gui, backend = self.enable_matplotlib(gui)
3454
3454
3455 # We want to prevent the loading of pylab to pollute the user's
3455 # We want to prevent the loading of pylab to pollute the user's
3456 # namespace as shown by the %who* magics, so we execute the activation
3456 # namespace as shown by the %who* magics, so we execute the activation
3457 # code in an empty namespace, and we update *both* user_ns and
3457 # code in an empty namespace, and we update *both* user_ns and
3458 # user_ns_hidden with this information.
3458 # user_ns_hidden with this information.
3459 ns = {}
3459 ns = {}
3460 import_pylab(ns, import_all)
3460 import_pylab(ns, import_all)
3461 # warn about clobbered names
3461 # warn about clobbered names
3462 ignored = {"__builtins__"}
3462 ignored = {"__builtins__"}
3463 both = set(ns).intersection(self.user_ns).difference(ignored)
3463 both = set(ns).intersection(self.user_ns).difference(ignored)
3464 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3464 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3465 self.user_ns.update(ns)
3465 self.user_ns.update(ns)
3466 self.user_ns_hidden.update(ns)
3466 self.user_ns_hidden.update(ns)
3467 return gui, backend, clobbered
3467 return gui, backend, clobbered
3468
3468
3469 #-------------------------------------------------------------------------
3469 #-------------------------------------------------------------------------
3470 # Utilities
3470 # Utilities
3471 #-------------------------------------------------------------------------
3471 #-------------------------------------------------------------------------
3472
3472
3473 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3473 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3474 """Expand python variables in a string.
3474 """Expand python variables in a string.
3475
3475
3476 The depth argument indicates how many frames above the caller should
3476 The depth argument indicates how many frames above the caller should
3477 be walked to look for the local namespace where to expand variables.
3477 be walked to look for the local namespace where to expand variables.
3478
3478
3479 The global namespace for expansion is always the user's interactive
3479 The global namespace for expansion is always the user's interactive
3480 namespace.
3480 namespace.
3481 """
3481 """
3482 ns = self.user_ns.copy()
3482 ns = self.user_ns.copy()
3483 try:
3483 try:
3484 frame = sys._getframe(depth+1)
3484 frame = sys._getframe(depth+1)
3485 except ValueError:
3485 except ValueError:
3486 # This is thrown if there aren't that many frames on the stack,
3486 # This is thrown if there aren't that many frames on the stack,
3487 # e.g. if a script called run_line_magic() directly.
3487 # e.g. if a script called run_line_magic() directly.
3488 pass
3488 pass
3489 else:
3489 else:
3490 ns.update(frame.f_locals)
3490 ns.update(frame.f_locals)
3491
3491
3492 try:
3492 try:
3493 # We have to use .vformat() here, because 'self' is a valid and common
3493 # We have to use .vformat() here, because 'self' is a valid and common
3494 # name, and expanding **ns for .format() would make it collide with
3494 # name, and expanding **ns for .format() would make it collide with
3495 # the 'self' argument of the method.
3495 # the 'self' argument of the method.
3496 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3496 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3497 except Exception:
3497 except Exception:
3498 # if formatter couldn't format, just let it go untransformed
3498 # if formatter couldn't format, just let it go untransformed
3499 pass
3499 pass
3500 return cmd
3500 return cmd
3501
3501
3502 def mktempfile(self, data=None, prefix='ipython_edit_'):
3502 def mktempfile(self, data=None, prefix='ipython_edit_'):
3503 """Make a new tempfile and return its filename.
3503 """Make a new tempfile and return its filename.
3504
3504
3505 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3505 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3506 but it registers the created filename internally so ipython cleans it up
3506 but it registers the created filename internally so ipython cleans it up
3507 at exit time.
3507 at exit time.
3508
3508
3509 Optional inputs:
3509 Optional inputs:
3510
3510
3511 - data(None): if data is given, it gets written out to the temp file
3511 - data(None): if data is given, it gets written out to the temp file
3512 immediately, and the file is closed again."""
3512 immediately, and the file is closed again."""
3513
3513
3514 dirname = tempfile.mkdtemp(prefix=prefix)
3514 dirname = tempfile.mkdtemp(prefix=prefix)
3515 self.tempdirs.append(dirname)
3515 self.tempdirs.append(dirname)
3516
3516
3517 handle, filename = tempfile.mkstemp('.py', prefix, dir=dirname)
3517 handle, filename = tempfile.mkstemp('.py', prefix, dir=dirname)
3518 os.close(handle) # On Windows, there can only be one open handle on a file
3518 os.close(handle) # On Windows, there can only be one open handle on a file
3519 self.tempfiles.append(filename)
3519 self.tempfiles.append(filename)
3520
3520
3521 if data:
3521 if data:
3522 with open(filename, 'w') as tmp_file:
3522 with open(filename, 'w') as tmp_file:
3523 tmp_file.write(data)
3523 tmp_file.write(data)
3524 return filename
3524 return filename
3525
3525
3526 @undoc
3526 @undoc
3527 def write(self,data):
3527 def write(self,data):
3528 """DEPRECATED: Write a string to the default output"""
3528 """DEPRECATED: Write a string to the default output"""
3529 warn('InteractiveShell.write() is deprecated, use sys.stdout instead',
3529 warn('InteractiveShell.write() is deprecated, use sys.stdout instead',
3530 DeprecationWarning, stacklevel=2)
3530 DeprecationWarning, stacklevel=2)
3531 sys.stdout.write(data)
3531 sys.stdout.write(data)
3532
3532
3533 @undoc
3533 @undoc
3534 def write_err(self,data):
3534 def write_err(self,data):
3535 """DEPRECATED: Write a string to the default error output"""
3535 """DEPRECATED: Write a string to the default error output"""
3536 warn('InteractiveShell.write_err() is deprecated, use sys.stderr instead',
3536 warn('InteractiveShell.write_err() is deprecated, use sys.stderr instead',
3537 DeprecationWarning, stacklevel=2)
3537 DeprecationWarning, stacklevel=2)
3538 sys.stderr.write(data)
3538 sys.stderr.write(data)
3539
3539
3540 def ask_yes_no(self, prompt, default=None, interrupt=None):
3540 def ask_yes_no(self, prompt, default=None, interrupt=None):
3541 if self.quiet:
3541 if self.quiet:
3542 return True
3542 return True
3543 return ask_yes_no(prompt,default,interrupt)
3543 return ask_yes_no(prompt,default,interrupt)
3544
3544
3545 def show_usage(self):
3545 def show_usage(self):
3546 """Show a usage message"""
3546 """Show a usage message"""
3547 page.page(IPython.core.usage.interactive_usage)
3547 page.page(IPython.core.usage.interactive_usage)
3548
3548
3549 def extract_input_lines(self, range_str, raw=False):
3549 def extract_input_lines(self, range_str, raw=False):
3550 """Return as a string a set of input history slices.
3550 """Return as a string a set of input history slices.
3551
3551
3552 Parameters
3552 Parameters
3553 ----------
3553 ----------
3554 range_str : string
3554 range_str : string
3555 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3555 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3556 since this function is for use by magic functions which get their
3556 since this function is for use by magic functions which get their
3557 arguments as strings. The number before the / is the session
3557 arguments as strings. The number before the / is the session
3558 number: ~n goes n back from the current session.
3558 number: ~n goes n back from the current session.
3559
3559
3560 raw : bool, optional
3560 raw : bool, optional
3561 By default, the processed input is used. If this is true, the raw
3561 By default, the processed input is used. If this is true, the raw
3562 input history is used instead.
3562 input history is used instead.
3563
3563
3564 Notes
3564 Notes
3565 -----
3565 -----
3566
3566
3567 Slices can be described with two notations:
3567 Slices can be described with two notations:
3568
3568
3569 * ``N:M`` -> standard python form, means including items N...(M-1).
3569 * ``N:M`` -> standard python form, means including items N...(M-1).
3570 * ``N-M`` -> include items N..M (closed endpoint).
3570 * ``N-M`` -> include items N..M (closed endpoint).
3571 """
3571 """
3572 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3572 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3573 return "\n".join(x for _, _, x in lines)
3573 return "\n".join(x for _, _, x in lines)
3574
3574
3575 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3575 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3576 """Get a code string from history, file, url, or a string or macro.
3576 """Get a code string from history, file, url, or a string or macro.
3577
3577
3578 This is mainly used by magic functions.
3578 This is mainly used by magic functions.
3579
3579
3580 Parameters
3580 Parameters
3581 ----------
3581 ----------
3582
3582
3583 target : str
3583 target : str
3584
3584
3585 A string specifying code to retrieve. This will be tried respectively
3585 A string specifying code to retrieve. This will be tried respectively
3586 as: ranges of input history (see %history for syntax), url,
3586 as: ranges of input history (see %history for syntax), url,
3587 corresponding .py file, filename, or an expression evaluating to a
3587 corresponding .py file, filename, or an expression evaluating to a
3588 string or Macro in the user namespace.
3588 string or Macro in the user namespace.
3589
3589
3590 raw : bool
3590 raw : bool
3591 If true (default), retrieve raw history. Has no effect on the other
3591 If true (default), retrieve raw history. Has no effect on the other
3592 retrieval mechanisms.
3592 retrieval mechanisms.
3593
3593
3594 py_only : bool (default False)
3594 py_only : bool (default False)
3595 Only try to fetch python code, do not try alternative methods to decode file
3595 Only try to fetch python code, do not try alternative methods to decode file
3596 if unicode fails.
3596 if unicode fails.
3597
3597
3598 Returns
3598 Returns
3599 -------
3599 -------
3600 A string of code.
3600 A string of code.
3601
3601
3602 ValueError is raised if nothing is found, and TypeError if it evaluates
3602 ValueError is raised if nothing is found, and TypeError if it evaluates
3603 to an object of another type. In each case, .args[0] is a printable
3603 to an object of another type. In each case, .args[0] is a printable
3604 message.
3604 message.
3605 """
3605 """
3606 code = self.extract_input_lines(target, raw=raw) # Grab history
3606 code = self.extract_input_lines(target, raw=raw) # Grab history
3607 if code:
3607 if code:
3608 return code
3608 return code
3609 try:
3609 try:
3610 if target.startswith(('http://', 'https://')):
3610 if target.startswith(('http://', 'https://')):
3611 return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
3611 return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
3612 except UnicodeDecodeError:
3612 except UnicodeDecodeError:
3613 if not py_only :
3613 if not py_only :
3614 # Deferred import
3614 # Deferred import
3615 from urllib.request import urlopen
3615 from urllib.request import urlopen
3616 response = urlopen(target)
3616 response = urlopen(target)
3617 return response.read().decode('latin1')
3617 return response.read().decode('latin1')
3618 raise ValueError(("'%s' seem to be unreadable.") % target)
3618 raise ValueError(("'%s' seem to be unreadable.") % target)
3619
3619
3620 potential_target = [target]
3620 potential_target = [target]
3621 try :
3621 try :
3622 potential_target.insert(0,get_py_filename(target))
3622 potential_target.insert(0,get_py_filename(target))
3623 except IOError:
3623 except IOError:
3624 pass
3624 pass
3625
3625
3626 for tgt in potential_target :
3626 for tgt in potential_target :
3627 if os.path.isfile(tgt): # Read file
3627 if os.path.isfile(tgt): # Read file
3628 try :
3628 try :
3629 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3629 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3630 except UnicodeDecodeError :
3630 except UnicodeDecodeError :
3631 if not py_only :
3631 if not py_only :
3632 with io_open(tgt,'r', encoding='latin1') as f :
3632 with io_open(tgt,'r', encoding='latin1') as f :
3633 return f.read()
3633 return f.read()
3634 raise ValueError(("'%s' seem to be unreadable.") % target)
3634 raise ValueError(("'%s' seem to be unreadable.") % target)
3635 elif os.path.isdir(os.path.expanduser(tgt)):
3635 elif os.path.isdir(os.path.expanduser(tgt)):
3636 raise ValueError("'%s' is a directory, not a regular file." % target)
3636 raise ValueError("'%s' is a directory, not a regular file." % target)
3637
3637
3638 if search_ns:
3638 if search_ns:
3639 # Inspect namespace to load object source
3639 # Inspect namespace to load object source
3640 object_info = self.object_inspect(target, detail_level=1)
3640 object_info = self.object_inspect(target, detail_level=1)
3641 if object_info['found'] and object_info['source']:
3641 if object_info['found'] and object_info['source']:
3642 return object_info['source']
3642 return object_info['source']
3643
3643
3644 try: # User namespace
3644 try: # User namespace
3645 codeobj = eval(target, self.user_ns)
3645 codeobj = eval(target, self.user_ns)
3646 except Exception:
3646 except Exception:
3647 raise ValueError(("'%s' was not found in history, as a file, url, "
3647 raise ValueError(("'%s' was not found in history, as a file, url, "
3648 "nor in the user namespace.") % target)
3648 "nor in the user namespace.") % target)
3649
3649
3650 if isinstance(codeobj, str):
3650 if isinstance(codeobj, str):
3651 return codeobj
3651 return codeobj
3652 elif isinstance(codeobj, Macro):
3652 elif isinstance(codeobj, Macro):
3653 return codeobj.value
3653 return codeobj.value
3654
3654
3655 raise TypeError("%s is neither a string nor a macro." % target,
3655 raise TypeError("%s is neither a string nor a macro." % target,
3656 codeobj)
3656 codeobj)
3657
3657
3658 #-------------------------------------------------------------------------
3658 #-------------------------------------------------------------------------
3659 # Things related to IPython exiting
3659 # Things related to IPython exiting
3660 #-------------------------------------------------------------------------
3660 #-------------------------------------------------------------------------
3661 def atexit_operations(self):
3661 def atexit_operations(self):
3662 """This will be executed at the time of exit.
3662 """This will be executed at the time of exit.
3663
3663
3664 Cleanup operations and saving of persistent data that is done
3664 Cleanup operations and saving of persistent data that is done
3665 unconditionally by IPython should be performed here.
3665 unconditionally by IPython should be performed here.
3666
3666
3667 For things that may depend on startup flags or platform specifics (such
3667 For things that may depend on startup flags or platform specifics (such
3668 as having readline or not), register a separate atexit function in the
3668 as having readline or not), register a separate atexit function in the
3669 code that has the appropriate information, rather than trying to
3669 code that has the appropriate information, rather than trying to
3670 clutter
3670 clutter
3671 """
3671 """
3672 # Close the history session (this stores the end time and line count)
3672 # Close the history session (this stores the end time and line count)
3673 # this must be *before* the tempfile cleanup, in case of temporary
3673 # this must be *before* the tempfile cleanup, in case of temporary
3674 # history db
3674 # history db
3675 self.history_manager.end_session()
3675 self.history_manager.end_session()
3676
3676
3677 # Cleanup all tempfiles and folders left around
3677 # Cleanup all tempfiles and folders left around
3678 for tfile in self.tempfiles:
3678 for tfile in self.tempfiles:
3679 try:
3679 try:
3680 os.unlink(tfile)
3680 os.unlink(tfile)
3681 except OSError:
3681 except OSError:
3682 pass
3682 pass
3683
3683
3684 for tdir in self.tempdirs:
3684 for tdir in self.tempdirs:
3685 try:
3685 try:
3686 os.rmdir(tdir)
3686 os.rmdir(tdir)
3687 except OSError:
3687 except OSError:
3688 pass
3688 pass
3689
3689
3690 # Clear all user namespaces to release all references cleanly.
3690 # Clear all user namespaces to release all references cleanly.
3691 self.reset(new_session=False)
3691 self.reset(new_session=False)
3692
3692
3693 # Run user hooks
3693 # Run user hooks
3694 self.hooks.shutdown_hook()
3694 self.hooks.shutdown_hook()
3695
3695
3696 def cleanup(self):
3696 def cleanup(self):
3697 self.restore_sys_module_state()
3697 self.restore_sys_module_state()
3698
3698
3699
3699
3700 # Overridden in terminal subclass to change prompts
3700 # Overridden in terminal subclass to change prompts
3701 def switch_doctest_mode(self, mode):
3701 def switch_doctest_mode(self, mode):
3702 pass
3702 pass
3703
3703
3704
3704
3705 class InteractiveShellABC(metaclass=abc.ABCMeta):
3705 class InteractiveShellABC(metaclass=abc.ABCMeta):
3706 """An abstract base class for InteractiveShell."""
3706 """An abstract base class for InteractiveShell."""
3707
3707
3708 InteractiveShellABC.register(InteractiveShell)
3708 InteractiveShellABC.register(InteractiveShell)
@@ -1,1501 +1,1501 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Implementation of execution-related magic functions."""
2 """Implementation of execution-related magic functions."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7
7
8 import ast
8 import ast
9 import bdb
9 import bdb
10 import builtins as builtin_mod
10 import builtins as builtin_mod
11 import gc
11 import gc
12 import itertools
12 import itertools
13 import os
13 import os
14 import shlex
14 import shlex
15 import sys
15 import sys
16 import time
16 import time
17 import timeit
17 import timeit
18 import math
18 import math
19 import re
19 import re
20 from pdb import Restart
20 from pdb import Restart
21
21
22 # cProfile was added in Python2.5
22 # cProfile was added in Python2.5
23 try:
23 try:
24 import cProfile as profile
24 import cProfile as profile
25 import pstats
25 import pstats
26 except ImportError:
26 except ImportError:
27 # profile isn't bundled by default in Debian for license reasons
27 # profile isn't bundled by default in Debian for license reasons
28 try:
28 try:
29 import profile, pstats
29 import profile, pstats
30 except ImportError:
30 except ImportError:
31 profile = pstats = None
31 profile = pstats = None
32
32
33 from IPython.core import oinspect
33 from IPython.core import oinspect
34 from IPython.core import magic_arguments
34 from IPython.core import magic_arguments
35 from IPython.core import page
35 from IPython.core import page
36 from IPython.core.error import UsageError
36 from IPython.core.error import UsageError
37 from IPython.core.macro import Macro
37 from IPython.core.macro import Macro
38 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
38 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
39 line_cell_magic, on_off, needs_local_scope,
39 line_cell_magic, on_off, needs_local_scope,
40 no_var_expand)
40 no_var_expand)
41 from IPython.testing.skipdoctest import skip_doctest
41 from IPython.testing.skipdoctest import skip_doctest
42 from IPython.utils.contexts import preserve_keys
42 from IPython.utils.contexts import preserve_keys
43 from IPython.utils.capture import capture_output
43 from IPython.utils.capture import capture_output
44 from IPython.utils.ipstruct import Struct
44 from IPython.utils.ipstruct import Struct
45 from IPython.utils.module_paths import find_mod
45 from IPython.utils.module_paths import find_mod
46 from IPython.utils.path import get_py_filename, shellglob
46 from IPython.utils.path import get_py_filename, shellglob
47 from IPython.utils.timing import clock, clock2
47 from IPython.utils.timing import clock, clock2
48 from warnings import warn
48 from warnings import warn
49 from logging import error
49 from logging import error
50 from io import StringIO
50 from io import StringIO
51
51
52 if sys.version_info > (3,8):
52 if sys.version_info > (3,8):
53 from ast import Module
53 from ast import Module
54 else :
54 else :
55 # mock the new API, ignore second argument
55 # mock the new API, ignore second argument
56 # see https://github.com/ipython/ipython/issues/11590
56 # see https://github.com/ipython/ipython/issues/11590
57 from ast import Module as OriginalModule
57 from ast import Module as OriginalModule
58 Module = lambda nodelist, type_ignores: OriginalModule(nodelist)
58 Module = lambda nodelist, type_ignores: OriginalModule(nodelist)
59
59
60
60
61 #-----------------------------------------------------------------------------
61 #-----------------------------------------------------------------------------
62 # Magic implementation classes
62 # Magic implementation classes
63 #-----------------------------------------------------------------------------
63 #-----------------------------------------------------------------------------
64
64
65
65
66 class TimeitResult(object):
66 class TimeitResult(object):
67 """
67 """
68 Object returned by the timeit magic with info about the run.
68 Object returned by the timeit magic with info about the run.
69
69
70 Contains the following attributes :
70 Contains the following attributes :
71
71
72 loops: (int) number of loops done per measurement
72 loops: (int) number of loops done per measurement
73 repeat: (int) number of times the measurement has been repeated
73 repeat: (int) number of times the measurement has been repeated
74 best: (float) best execution time / number
74 best: (float) best execution time / number
75 all_runs: (list of float) execution time of each run (in s)
75 all_runs: (list of float) execution time of each run (in s)
76 compile_time: (float) time of statement compilation (s)
76 compile_time: (float) time of statement compilation (s)
77
77
78 """
78 """
79 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
79 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
80 self.loops = loops
80 self.loops = loops
81 self.repeat = repeat
81 self.repeat = repeat
82 self.best = best
82 self.best = best
83 self.worst = worst
83 self.worst = worst
84 self.all_runs = all_runs
84 self.all_runs = all_runs
85 self.compile_time = compile_time
85 self.compile_time = compile_time
86 self._precision = precision
86 self._precision = precision
87 self.timings = [ dt / self.loops for dt in all_runs]
87 self.timings = [ dt / self.loops for dt in all_runs]
88
88
89 @property
89 @property
90 def average(self):
90 def average(self):
91 return math.fsum(self.timings) / len(self.timings)
91 return math.fsum(self.timings) / len(self.timings)
92
92
93 @property
93 @property
94 def stdev(self):
94 def stdev(self):
95 mean = self.average
95 mean = self.average
96 return (math.fsum([(x - mean) ** 2 for x in self.timings]) / len(self.timings)) ** 0.5
96 return (math.fsum([(x - mean) ** 2 for x in self.timings]) / len(self.timings)) ** 0.5
97
97
98 def __str__(self):
98 def __str__(self):
99 pm = '+-'
99 pm = '+-'
100 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
100 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
101 try:
101 try:
102 u'\xb1'.encode(sys.stdout.encoding)
102 u'\xb1'.encode(sys.stdout.encoding)
103 pm = u'\xb1'
103 pm = u'\xb1'
104 except:
104 except:
105 pass
105 pass
106 return (
106 return (
107 u"{mean} {pm} {std} per loop (mean {pm} std. dev. of {runs} run{run_plural}, {loops} loop{loop_plural} each)"
107 u"{mean} {pm} {std} per loop (mean {pm} std. dev. of {runs} run{run_plural}, {loops} loop{loop_plural} each)"
108 .format(
108 .format(
109 pm = pm,
109 pm = pm,
110 runs = self.repeat,
110 runs = self.repeat,
111 loops = self.loops,
111 loops = self.loops,
112 loop_plural = "" if self.loops == 1 else "s",
112 loop_plural = "" if self.loops == 1 else "s",
113 run_plural = "" if self.repeat == 1 else "s",
113 run_plural = "" if self.repeat == 1 else "s",
114 mean = _format_time(self.average, self._precision),
114 mean = _format_time(self.average, self._precision),
115 std = _format_time(self.stdev, self._precision))
115 std = _format_time(self.stdev, self._precision))
116 )
116 )
117
117
118 def _repr_pretty_(self, p , cycle):
118 def _repr_pretty_(self, p , cycle):
119 unic = self.__str__()
119 unic = self.__str__()
120 p.text(u'<TimeitResult : '+unic+u'>')
120 p.text(u'<TimeitResult : '+unic+u'>')
121
121
122
122
123 class TimeitTemplateFiller(ast.NodeTransformer):
123 class TimeitTemplateFiller(ast.NodeTransformer):
124 """Fill in the AST template for timing execution.
124 """Fill in the AST template for timing execution.
125
125
126 This is quite closely tied to the template definition, which is in
126 This is quite closely tied to the template definition, which is in
127 :meth:`ExecutionMagics.timeit`.
127 :meth:`ExecutionMagics.timeit`.
128 """
128 """
129 def __init__(self, ast_setup, ast_stmt):
129 def __init__(self, ast_setup, ast_stmt):
130 self.ast_setup = ast_setup
130 self.ast_setup = ast_setup
131 self.ast_stmt = ast_stmt
131 self.ast_stmt = ast_stmt
132
132
133 def visit_FunctionDef(self, node):
133 def visit_FunctionDef(self, node):
134 "Fill in the setup statement"
134 "Fill in the setup statement"
135 self.generic_visit(node)
135 self.generic_visit(node)
136 if node.name == "inner":
136 if node.name == "inner":
137 node.body[:1] = self.ast_setup.body
137 node.body[:1] = self.ast_setup.body
138
138
139 return node
139 return node
140
140
141 def visit_For(self, node):
141 def visit_For(self, node):
142 "Fill in the statement to be timed"
142 "Fill in the statement to be timed"
143 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
143 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
144 node.body = self.ast_stmt.body
144 node.body = self.ast_stmt.body
145 return node
145 return node
146
146
147
147
148 class Timer(timeit.Timer):
148 class Timer(timeit.Timer):
149 """Timer class that explicitly uses self.inner
149 """Timer class that explicitly uses self.inner
150
150
151 which is an undocumented implementation detail of CPython,
151 which is an undocumented implementation detail of CPython,
152 not shared by PyPy.
152 not shared by PyPy.
153 """
153 """
154 # Timer.timeit copied from CPython 3.4.2
154 # Timer.timeit copied from CPython 3.4.2
155 def timeit(self, number=timeit.default_number):
155 def timeit(self, number=timeit.default_number):
156 """Time 'number' executions of the main statement.
156 """Time 'number' executions of the main statement.
157
157
158 To be precise, this executes the setup statement once, and
158 To be precise, this executes the setup statement once, and
159 then returns the time it takes to execute the main statement
159 then returns the time it takes to execute the main statement
160 a number of times, as a float measured in seconds. The
160 a number of times, as a float measured in seconds. The
161 argument is the number of times through the loop, defaulting
161 argument is the number of times through the loop, defaulting
162 to one million. The main statement, the setup statement and
162 to one million. The main statement, the setup statement and
163 the timer function to be used are passed to the constructor.
163 the timer function to be used are passed to the constructor.
164 """
164 """
165 it = itertools.repeat(None, number)
165 it = itertools.repeat(None, number)
166 gcold = gc.isenabled()
166 gcold = gc.isenabled()
167 gc.disable()
167 gc.disable()
168 try:
168 try:
169 timing = self.inner(it, self.timer)
169 timing = self.inner(it, self.timer)
170 finally:
170 finally:
171 if gcold:
171 if gcold:
172 gc.enable()
172 gc.enable()
173 return timing
173 return timing
174
174
175
175
176 @magics_class
176 @magics_class
177 class ExecutionMagics(Magics):
177 class ExecutionMagics(Magics):
178 """Magics related to code execution, debugging, profiling, etc.
178 """Magics related to code execution, debugging, profiling, etc.
179
179
180 """
180 """
181
181
182 def __init__(self, shell):
182 def __init__(self, shell):
183 super(ExecutionMagics, self).__init__(shell)
183 super(ExecutionMagics, self).__init__(shell)
184 if profile is None:
184 if profile is None:
185 self.prun = self.profile_missing_notice
185 self.prun = self.profile_missing_notice
186 # Default execution function used to actually run user code.
186 # Default execution function used to actually run user code.
187 self.default_runner = None
187 self.default_runner = None
188
188
189 def profile_missing_notice(self, *args, **kwargs):
189 def profile_missing_notice(self, *args, **kwargs):
190 error("""\
190 error("""\
191 The profile module could not be found. It has been removed from the standard
191 The profile module could not be found. It has been removed from the standard
192 python packages because of its non-free license. To use profiling, install the
192 python packages because of its non-free license. To use profiling, install the
193 python-profiler package from non-free.""")
193 python-profiler package from non-free.""")
194
194
195 @skip_doctest
195 @skip_doctest
196 @no_var_expand
196 @no_var_expand
197 @line_cell_magic
197 @line_cell_magic
198 def prun(self, parameter_s='', cell=None):
198 def prun(self, parameter_s='', cell=None):
199
199
200 """Run a statement through the python code profiler.
200 """Run a statement through the python code profiler.
201
201
202 Usage, in line mode:
202 Usage, in line mode:
203 %prun [options] statement
203 %prun [options] statement
204
204
205 Usage, in cell mode:
205 Usage, in cell mode:
206 %%prun [options] [statement]
206 %%prun [options] [statement]
207 code...
207 code...
208 code...
208 code...
209
209
210 In cell mode, the additional code lines are appended to the (possibly
210 In cell mode, the additional code lines are appended to the (possibly
211 empty) statement in the first line. Cell mode allows you to easily
211 empty) statement in the first line. Cell mode allows you to easily
212 profile multiline blocks without having to put them in a separate
212 profile multiline blocks without having to put them in a separate
213 function.
213 function.
214
214
215 The given statement (which doesn't require quote marks) is run via the
215 The given statement (which doesn't require quote marks) is run via the
216 python profiler in a manner similar to the profile.run() function.
216 python profiler in a manner similar to the profile.run() function.
217 Namespaces are internally managed to work correctly; profile.run
217 Namespaces are internally managed to work correctly; profile.run
218 cannot be used in IPython because it makes certain assumptions about
218 cannot be used in IPython because it makes certain assumptions about
219 namespaces which do not hold under IPython.
219 namespaces which do not hold under IPython.
220
220
221 Options:
221 Options:
222
222
223 -l <limit>
223 -l <limit>
224 you can place restrictions on what or how much of the
224 you can place restrictions on what or how much of the
225 profile gets printed. The limit value can be:
225 profile gets printed. The limit value can be:
226
226
227 * A string: only information for function names containing this string
227 * A string: only information for function names containing this string
228 is printed.
228 is printed.
229
229
230 * An integer: only these many lines are printed.
230 * An integer: only these many lines are printed.
231
231
232 * A float (between 0 and 1): this fraction of the report is printed
232 * A float (between 0 and 1): this fraction of the report is printed
233 (for example, use a limit of 0.4 to see the topmost 40% only).
233 (for example, use a limit of 0.4 to see the topmost 40% only).
234
234
235 You can combine several limits with repeated use of the option. For
235 You can combine several limits with repeated use of the option. For
236 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
236 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
237 information about class constructors.
237 information about class constructors.
238
238
239 -r
239 -r
240 return the pstats.Stats object generated by the profiling. This
240 return the pstats.Stats object generated by the profiling. This
241 object has all the information about the profile in it, and you can
241 object has all the information about the profile in it, and you can
242 later use it for further analysis or in other functions.
242 later use it for further analysis or in other functions.
243
243
244 -s <key>
244 -s <key>
245 sort profile by given key. You can provide more than one key
245 sort profile by given key. You can provide more than one key
246 by using the option several times: '-s key1 -s key2 -s key3...'. The
246 by using the option several times: '-s key1 -s key2 -s key3...'. The
247 default sorting key is 'time'.
247 default sorting key is 'time'.
248
248
249 The following is copied verbatim from the profile documentation
249 The following is copied verbatim from the profile documentation
250 referenced below:
250 referenced below:
251
251
252 When more than one key is provided, additional keys are used as
252 When more than one key is provided, additional keys are used as
253 secondary criteria when the there is equality in all keys selected
253 secondary criteria when the there is equality in all keys selected
254 before them.
254 before them.
255
255
256 Abbreviations can be used for any key names, as long as the
256 Abbreviations can be used for any key names, as long as the
257 abbreviation is unambiguous. The following are the keys currently
257 abbreviation is unambiguous. The following are the keys currently
258 defined:
258 defined:
259
259
260 ============ =====================
260 ============ =====================
261 Valid Arg Meaning
261 Valid Arg Meaning
262 ============ =====================
262 ============ =====================
263 "calls" call count
263 "calls" call count
264 "cumulative" cumulative time
264 "cumulative" cumulative time
265 "file" file name
265 "file" file name
266 "module" file name
266 "module" file name
267 "pcalls" primitive call count
267 "pcalls" primitive call count
268 "line" line number
268 "line" line number
269 "name" function name
269 "name" function name
270 "nfl" name/file/line
270 "nfl" name/file/line
271 "stdname" standard name
271 "stdname" standard name
272 "time" internal time
272 "time" internal time
273 ============ =====================
273 ============ =====================
274
274
275 Note that all sorts on statistics are in descending order (placing
275 Note that all sorts on statistics are in descending order (placing
276 most time consuming items first), where as name, file, and line number
276 most time consuming items first), where as name, file, and line number
277 searches are in ascending order (i.e., alphabetical). The subtle
277 searches are in ascending order (i.e., alphabetical). The subtle
278 distinction between "nfl" and "stdname" is that the standard name is a
278 distinction between "nfl" and "stdname" is that the standard name is a
279 sort of the name as printed, which means that the embedded line
279 sort of the name as printed, which means that the embedded line
280 numbers get compared in an odd way. For example, lines 3, 20, and 40
280 numbers get compared in an odd way. For example, lines 3, 20, and 40
281 would (if the file names were the same) appear in the string order
281 would (if the file names were the same) appear in the string order
282 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
282 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
283 line numbers. In fact, sort_stats("nfl") is the same as
283 line numbers. In fact, sort_stats("nfl") is the same as
284 sort_stats("name", "file", "line").
284 sort_stats("name", "file", "line").
285
285
286 -T <filename>
286 -T <filename>
287 save profile results as shown on screen to a text
287 save profile results as shown on screen to a text
288 file. The profile is still shown on screen.
288 file. The profile is still shown on screen.
289
289
290 -D <filename>
290 -D <filename>
291 save (via dump_stats) profile statistics to given
291 save (via dump_stats) profile statistics to given
292 filename. This data is in a format understood by the pstats module, and
292 filename. This data is in a format understood by the pstats module, and
293 is generated by a call to the dump_stats() method of profile
293 is generated by a call to the dump_stats() method of profile
294 objects. The profile is still shown on screen.
294 objects. The profile is still shown on screen.
295
295
296 -q
296 -q
297 suppress output to the pager. Best used with -T and/or -D above.
297 suppress output to the pager. Best used with -T and/or -D above.
298
298
299 If you want to run complete programs under the profiler's control, use
299 If you want to run complete programs under the profiler's control, use
300 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
300 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
301 contains profiler specific options as described here.
301 contains profiler specific options as described here.
302
302
303 You can read the complete documentation for the profile module with::
303 You can read the complete documentation for the profile module with::
304
304
305 In [1]: import profile; profile.help()
305 In [1]: import profile; profile.help()
306
306
307 .. versionchanged:: 7.3
307 .. versionchanged:: 7.3
308 User variables are no longer expanded,
308 User variables are no longer expanded,
309 the magic line is always left unmodified.
309 the magic line is always left unmodified.
310
310
311 """
311 """
312 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
312 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
313 list_all=True, posix=False)
313 list_all=True, posix=False)
314 if cell is not None:
314 if cell is not None:
315 arg_str += '\n' + cell
315 arg_str += '\n' + cell
316 arg_str = self.shell.transform_cell(arg_str)
316 arg_str = self.shell.transform_cell(arg_str)
317 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
317 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
318
318
319 def _run_with_profiler(self, code, opts, namespace):
319 def _run_with_profiler(self, code, opts, namespace):
320 """
320 """
321 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
321 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
322
322
323 Parameters
323 Parameters
324 ----------
324 ----------
325 code : str
325 code : str
326 Code to be executed.
326 Code to be executed.
327 opts : Struct
327 opts : Struct
328 Options parsed by `self.parse_options`.
328 Options parsed by `self.parse_options`.
329 namespace : dict
329 namespace : dict
330 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
330 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
331
331
332 """
332 """
333
333
334 # Fill default values for unspecified options:
334 # Fill default values for unspecified options:
335 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
335 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
336
336
337 prof = profile.Profile()
337 prof = profile.Profile()
338 try:
338 try:
339 prof = prof.runctx(code, namespace, namespace)
339 prof = prof.runctx(code, namespace, namespace)
340 sys_exit = ''
340 sys_exit = ''
341 except SystemExit:
341 except SystemExit:
342 sys_exit = """*** SystemExit exception caught in code being profiled."""
342 sys_exit = """*** SystemExit exception caught in code being profiled."""
343
343
344 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
344 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
345
345
346 lims = opts.l
346 lims = opts.l
347 if lims:
347 if lims:
348 lims = [] # rebuild lims with ints/floats/strings
348 lims = [] # rebuild lims with ints/floats/strings
349 for lim in opts.l:
349 for lim in opts.l:
350 try:
350 try:
351 lims.append(int(lim))
351 lims.append(int(lim))
352 except ValueError:
352 except ValueError:
353 try:
353 try:
354 lims.append(float(lim))
354 lims.append(float(lim))
355 except ValueError:
355 except ValueError:
356 lims.append(lim)
356 lims.append(lim)
357
357
358 # Trap output.
358 # Trap output.
359 stdout_trap = StringIO()
359 stdout_trap = StringIO()
360 stats_stream = stats.stream
360 stats_stream = stats.stream
361 try:
361 try:
362 stats.stream = stdout_trap
362 stats.stream = stdout_trap
363 stats.print_stats(*lims)
363 stats.print_stats(*lims)
364 finally:
364 finally:
365 stats.stream = stats_stream
365 stats.stream = stats_stream
366
366
367 output = stdout_trap.getvalue()
367 output = stdout_trap.getvalue()
368 output = output.rstrip()
368 output = output.rstrip()
369
369
370 if 'q' not in opts:
370 if 'q' not in opts:
371 page.page(output)
371 page.page(output)
372 print(sys_exit, end=' ')
372 print(sys_exit, end=' ')
373
373
374 dump_file = opts.D[0]
374 dump_file = opts.D[0]
375 text_file = opts.T[0]
375 text_file = opts.T[0]
376 if dump_file:
376 if dump_file:
377 prof.dump_stats(dump_file)
377 prof.dump_stats(dump_file)
378 print('\n*** Profile stats marshalled to file',\
378 print('\n*** Profile stats marshalled to file',\
379 repr(dump_file)+'.',sys_exit)
379 repr(dump_file)+'.',sys_exit)
380 if text_file:
380 if text_file:
381 with open(text_file, 'w') as pfile:
381 with open(text_file, 'w') as pfile:
382 pfile.write(output)
382 pfile.write(output)
383 print('\n*** Profile printout saved to text file',\
383 print('\n*** Profile printout saved to text file',\
384 repr(text_file)+'.',sys_exit)
384 repr(text_file)+'.',sys_exit)
385
385
386 if 'r' in opts:
386 if 'r' in opts:
387 return stats
387 return stats
388 else:
388 else:
389 return None
389 return None
390
390
391 @line_magic
391 @line_magic
392 def pdb(self, parameter_s=''):
392 def pdb(self, parameter_s=''):
393 """Control the automatic calling of the pdb interactive debugger.
393 """Control the automatic calling of the pdb interactive debugger.
394
394
395 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
395 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
396 argument it works as a toggle.
396 argument it works as a toggle.
397
397
398 When an exception is triggered, IPython can optionally call the
398 When an exception is triggered, IPython can optionally call the
399 interactive pdb debugger after the traceback printout. %pdb toggles
399 interactive pdb debugger after the traceback printout. %pdb toggles
400 this feature on and off.
400 this feature on and off.
401
401
402 The initial state of this feature is set in your configuration
402 The initial state of this feature is set in your configuration
403 file (the option is ``InteractiveShell.pdb``).
403 file (the option is ``InteractiveShell.pdb``).
404
404
405 If you want to just activate the debugger AFTER an exception has fired,
405 If you want to just activate the debugger AFTER an exception has fired,
406 without having to type '%pdb on' and rerunning your code, you can use
406 without having to type '%pdb on' and rerunning your code, you can use
407 the %debug magic."""
407 the %debug magic."""
408
408
409 par = parameter_s.strip().lower()
409 par = parameter_s.strip().lower()
410
410
411 if par:
411 if par:
412 try:
412 try:
413 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
413 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
414 except KeyError:
414 except KeyError:
415 print ('Incorrect argument. Use on/1, off/0, '
415 print ('Incorrect argument. Use on/1, off/0, '
416 'or nothing for a toggle.')
416 'or nothing for a toggle.')
417 return
417 return
418 else:
418 else:
419 # toggle
419 # toggle
420 new_pdb = not self.shell.call_pdb
420 new_pdb = not self.shell.call_pdb
421
421
422 # set on the shell
422 # set on the shell
423 self.shell.call_pdb = new_pdb
423 self.shell.call_pdb = new_pdb
424 print('Automatic pdb calling has been turned',on_off(new_pdb))
424 print('Automatic pdb calling has been turned',on_off(new_pdb))
425
425
426 @skip_doctest
426 @skip_doctest
427 @magic_arguments.magic_arguments()
427 @magic_arguments.magic_arguments()
428 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
428 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
429 help="""
429 help="""
430 Set break point at LINE in FILE.
430 Set break point at LINE in FILE.
431 """
431 """
432 )
432 )
433 @magic_arguments.argument('statement', nargs='*',
433 @magic_arguments.argument('statement', nargs='*',
434 help="""
434 help="""
435 Code to run in debugger.
435 Code to run in debugger.
436 You can omit this in cell magic mode.
436 You can omit this in cell magic mode.
437 """
437 """
438 )
438 )
439 @no_var_expand
439 @no_var_expand
440 @line_cell_magic
440 @line_cell_magic
441 def debug(self, line='', cell=None):
441 def debug(self, line='', cell=None):
442 """Activate the interactive debugger.
442 """Activate the interactive debugger.
443
443
444 This magic command support two ways of activating debugger.
444 This magic command support two ways of activating debugger.
445 One is to activate debugger before executing code. This way, you
445 One is to activate debugger before executing code. This way, you
446 can set a break point, to step through the code from the point.
446 can set a break point, to step through the code from the point.
447 You can use this mode by giving statements to execute and optionally
447 You can use this mode by giving statements to execute and optionally
448 a breakpoint.
448 a breakpoint.
449
449
450 The other one is to activate debugger in post-mortem mode. You can
450 The other one is to activate debugger in post-mortem mode. You can
451 activate this mode simply running %debug without any argument.
451 activate this mode simply running %debug without any argument.
452 If an exception has just occurred, this lets you inspect its stack
452 If an exception has just occurred, this lets you inspect its stack
453 frames interactively. Note that this will always work only on the last
453 frames interactively. Note that this will always work only on the last
454 traceback that occurred, so you must call this quickly after an
454 traceback that occurred, so you must call this quickly after an
455 exception that you wish to inspect has fired, because if another one
455 exception that you wish to inspect has fired, because if another one
456 occurs, it clobbers the previous one.
456 occurs, it clobbers the previous one.
457
457
458 If you want IPython to automatically do this on every exception, see
458 If you want IPython to automatically do this on every exception, see
459 the %pdb magic for more details.
459 the %pdb magic for more details.
460
460
461 .. versionchanged:: 7.3
461 .. versionchanged:: 7.3
462 When running code, user variables are no longer expanded,
462 When running code, user variables are no longer expanded,
463 the magic line is always left unmodified.
463 the magic line is always left unmodified.
464
464
465 """
465 """
466 args = magic_arguments.parse_argstring(self.debug, line)
466 args = magic_arguments.parse_argstring(self.debug, line)
467
467
468 if not (args.breakpoint or args.statement or cell):
468 if not (args.breakpoint or args.statement or cell):
469 self._debug_post_mortem()
469 self._debug_post_mortem()
470 else:
470 else:
471 code = "\n".join(args.statement)
471 code = "\n".join(args.statement)
472 if cell:
472 if cell:
473 code += "\n" + cell
473 code += "\n" + cell
474 self._debug_exec(code, args.breakpoint)
474 self._debug_exec(code, args.breakpoint)
475
475
476 def _debug_post_mortem(self):
476 def _debug_post_mortem(self):
477 self.shell.debugger(force=True)
477 self.shell.debugger(force=True)
478
478
479 def _debug_exec(self, code, breakpoint):
479 def _debug_exec(self, code, breakpoint):
480 if breakpoint:
480 if breakpoint:
481 (filename, bp_line) = breakpoint.rsplit(':', 1)
481 (filename, bp_line) = breakpoint.rsplit(':', 1)
482 bp_line = int(bp_line)
482 bp_line = int(bp_line)
483 else:
483 else:
484 (filename, bp_line) = (None, None)
484 (filename, bp_line) = (None, None)
485 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
485 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
486
486
487 @line_magic
487 @line_magic
488 def tb(self, s):
488 def tb(self, s):
489 """Print the last traceback.
489 """Print the last traceback.
490
490
491 Optionally, specify an exception reporting mode, tuning the
491 Optionally, specify an exception reporting mode, tuning the
492 verbosity of the traceback. By default the currently-active exception
492 verbosity of the traceback. By default the currently-active exception
493 mode is used. See %xmode for changing exception reporting modes.
493 mode is used. See %xmode for changing exception reporting modes.
494
494
495 Valid modes: Plain, Context, Verbose, and Minimal.
495 Valid modes: Plain, Context, Verbose, and Minimal.
496 """
496 """
497 interactive_tb = self.shell.InteractiveTB
497 interactive_tb = self.shell.InteractiveTB
498 if s:
498 if s:
499 # Switch exception reporting mode for this one call.
499 # Switch exception reporting mode for this one call.
500 # Ensure it is switched back.
500 # Ensure it is switched back.
501 def xmode_switch_err(name):
501 def xmode_switch_err(name):
502 warn('Error changing %s exception modes.\n%s' %
502 warn('Error changing %s exception modes.\n%s' %
503 (name,sys.exc_info()[1]))
503 (name,sys.exc_info()[1]))
504
504
505 new_mode = s.strip().capitalize()
505 new_mode = s.strip().capitalize()
506 original_mode = interactive_tb.mode
506 original_mode = interactive_tb.mode
507 try:
507 try:
508 try:
508 try:
509 interactive_tb.set_mode(mode=new_mode)
509 interactive_tb.set_mode(mode=new_mode)
510 except Exception:
510 except Exception:
511 xmode_switch_err('user')
511 xmode_switch_err('user')
512 else:
512 else:
513 self.shell.showtraceback()
513 self.shell.showtraceback()
514 finally:
514 finally:
515 interactive_tb.set_mode(mode=original_mode)
515 interactive_tb.set_mode(mode=original_mode)
516 else:
516 else:
517 self.shell.showtraceback()
517 self.shell.showtraceback()
518
518
519 @skip_doctest
519 @skip_doctest
520 @line_magic
520 @line_magic
521 def run(self, parameter_s='', runner=None,
521 def run(self, parameter_s='', runner=None,
522 file_finder=get_py_filename):
522 file_finder=get_py_filename):
523 """Run the named file inside IPython as a program.
523 """Run the named file inside IPython as a program.
524
524
525 Usage::
525 Usage::
526
526
527 %run [-n -i -e -G]
527 %run [-n -i -e -G]
528 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
528 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
529 ( -m mod | file ) [args]
529 ( -m mod | file ) [args]
530
530
531 Parameters after the filename are passed as command-line arguments to
531 Parameters after the filename are passed as command-line arguments to
532 the program (put in sys.argv). Then, control returns to IPython's
532 the program (put in sys.argv). Then, control returns to IPython's
533 prompt.
533 prompt.
534
534
535 This is similar to running at a system prompt ``python file args``,
535 This is similar to running at a system prompt ``python file args``,
536 but with the advantage of giving you IPython's tracebacks, and of
536 but with the advantage of giving you IPython's tracebacks, and of
537 loading all variables into your interactive namespace for further use
537 loading all variables into your interactive namespace for further use
538 (unless -p is used, see below).
538 (unless -p is used, see below).
539
539
540 The file is executed in a namespace initially consisting only of
540 The file is executed in a namespace initially consisting only of
541 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
541 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
542 sees its environment as if it were being run as a stand-alone program
542 sees its environment as if it were being run as a stand-alone program
543 (except for sharing global objects such as previously imported
543 (except for sharing global objects such as previously imported
544 modules). But after execution, the IPython interactive namespace gets
544 modules). But after execution, the IPython interactive namespace gets
545 updated with all variables defined in the program (except for __name__
545 updated with all variables defined in the program (except for __name__
546 and sys.argv). This allows for very convenient loading of code for
546 and sys.argv). This allows for very convenient loading of code for
547 interactive work, while giving each program a 'clean sheet' to run in.
547 interactive work, while giving each program a 'clean sheet' to run in.
548
548
549 Arguments are expanded using shell-like glob match. Patterns
549 Arguments are expanded using shell-like glob match. Patterns
550 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
550 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
551 tilde '~' will be expanded into user's home directory. Unlike
551 tilde '~' will be expanded into user's home directory. Unlike
552 real shells, quotation does not suppress expansions. Use
552 real shells, quotation does not suppress expansions. Use
553 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
553 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
554 To completely disable these expansions, you can use -G flag.
554 To completely disable these expansions, you can use -G flag.
555
555
556 On Windows systems, the use of single quotes `'` when specifying
556 On Windows systems, the use of single quotes `'` when specifying
557 a file is not supported. Use double quotes `"`.
557 a file is not supported. Use double quotes `"`.
558
558
559 Options:
559 Options:
560
560
561 -n
561 -n
562 __name__ is NOT set to '__main__', but to the running file's name
562 __name__ is NOT set to '__main__', but to the running file's name
563 without extension (as python does under import). This allows running
563 without extension (as python does under import). This allows running
564 scripts and reloading the definitions in them without calling code
564 scripts and reloading the definitions in them without calling code
565 protected by an ``if __name__ == "__main__"`` clause.
565 protected by an ``if __name__ == "__main__"`` clause.
566
566
567 -i
567 -i
568 run the file in IPython's namespace instead of an empty one. This
568 run the file in IPython's namespace instead of an empty one. This
569 is useful if you are experimenting with code written in a text editor
569 is useful if you are experimenting with code written in a text editor
570 which depends on variables defined interactively.
570 which depends on variables defined interactively.
571
571
572 -e
572 -e
573 ignore sys.exit() calls or SystemExit exceptions in the script
573 ignore sys.exit() calls or SystemExit exceptions in the script
574 being run. This is particularly useful if IPython is being used to
574 being run. This is particularly useful if IPython is being used to
575 run unittests, which always exit with a sys.exit() call. In such
575 run unittests, which always exit with a sys.exit() call. In such
576 cases you are interested in the output of the test results, not in
576 cases you are interested in the output of the test results, not in
577 seeing a traceback of the unittest module.
577 seeing a traceback of the unittest module.
578
578
579 -t
579 -t
580 print timing information at the end of the run. IPython will give
580 print timing information at the end of the run. IPython will give
581 you an estimated CPU time consumption for your script, which under
581 you an estimated CPU time consumption for your script, which under
582 Unix uses the resource module to avoid the wraparound problems of
582 Unix uses the resource module to avoid the wraparound problems of
583 time.clock(). Under Unix, an estimate of time spent on system tasks
583 time.clock(). Under Unix, an estimate of time spent on system tasks
584 is also given (for Windows platforms this is reported as 0.0).
584 is also given (for Windows platforms this is reported as 0.0).
585
585
586 If -t is given, an additional ``-N<N>`` option can be given, where <N>
586 If -t is given, an additional ``-N<N>`` option can be given, where <N>
587 must be an integer indicating how many times you want the script to
587 must be an integer indicating how many times you want the script to
588 run. The final timing report will include total and per run results.
588 run. The final timing report will include total and per run results.
589
589
590 For example (testing the script uniq_stable.py)::
590 For example (testing the script uniq_stable.py)::
591
591
592 In [1]: run -t uniq_stable
592 In [1]: run -t uniq_stable
593
593
594 IPython CPU timings (estimated):
594 IPython CPU timings (estimated):
595 User : 0.19597 s.
595 User : 0.19597 s.
596 System: 0.0 s.
596 System: 0.0 s.
597
597
598 In [2]: run -t -N5 uniq_stable
598 In [2]: run -t -N5 uniq_stable
599
599
600 IPython CPU timings (estimated):
600 IPython CPU timings (estimated):
601 Total runs performed: 5
601 Total runs performed: 5
602 Times : Total Per run
602 Times : Total Per run
603 User : 0.910862 s, 0.1821724 s.
603 User : 0.910862 s, 0.1821724 s.
604 System: 0.0 s, 0.0 s.
604 System: 0.0 s, 0.0 s.
605
605
606 -d
606 -d
607 run your program under the control of pdb, the Python debugger.
607 run your program under the control of pdb, the Python debugger.
608 This allows you to execute your program step by step, watch variables,
608 This allows you to execute your program step by step, watch variables,
609 etc. Internally, what IPython does is similar to calling::
609 etc. Internally, what IPython does is similar to calling::
610
610
611 pdb.run('execfile("YOURFILENAME")')
611 pdb.run('execfile("YOURFILENAME")')
612
612
613 with a breakpoint set on line 1 of your file. You can change the line
613 with a breakpoint set on line 1 of your file. You can change the line
614 number for this automatic breakpoint to be <N> by using the -bN option
614 number for this automatic breakpoint to be <N> by using the -bN option
615 (where N must be an integer). For example::
615 (where N must be an integer). For example::
616
616
617 %run -d -b40 myscript
617 %run -d -b40 myscript
618
618
619 will set the first breakpoint at line 40 in myscript.py. Note that
619 will set the first breakpoint at line 40 in myscript.py. Note that
620 the first breakpoint must be set on a line which actually does
620 the first breakpoint must be set on a line which actually does
621 something (not a comment or docstring) for it to stop execution.
621 something (not a comment or docstring) for it to stop execution.
622
622
623 Or you can specify a breakpoint in a different file::
623 Or you can specify a breakpoint in a different file::
624
624
625 %run -d -b myotherfile.py:20 myscript
625 %run -d -b myotherfile.py:20 myscript
626
626
627 When the pdb debugger starts, you will see a (Pdb) prompt. You must
627 When the pdb debugger starts, you will see a (Pdb) prompt. You must
628 first enter 'c' (without quotes) to start execution up to the first
628 first enter 'c' (without quotes) to start execution up to the first
629 breakpoint.
629 breakpoint.
630
630
631 Entering 'help' gives information about the use of the debugger. You
631 Entering 'help' gives information about the use of the debugger. You
632 can easily see pdb's full documentation with "import pdb;pdb.help()"
632 can easily see pdb's full documentation with "import pdb;pdb.help()"
633 at a prompt.
633 at a prompt.
634
634
635 -p
635 -p
636 run program under the control of the Python profiler module (which
636 run program under the control of the Python profiler module (which
637 prints a detailed report of execution times, function calls, etc).
637 prints a detailed report of execution times, function calls, etc).
638
638
639 You can pass other options after -p which affect the behavior of the
639 You can pass other options after -p which affect the behavior of the
640 profiler itself. See the docs for %prun for details.
640 profiler itself. See the docs for %prun for details.
641
641
642 In this mode, the program's variables do NOT propagate back to the
642 In this mode, the program's variables do NOT propagate back to the
643 IPython interactive namespace (because they remain in the namespace
643 IPython interactive namespace (because they remain in the namespace
644 where the profiler executes them).
644 where the profiler executes them).
645
645
646 Internally this triggers a call to %prun, see its documentation for
646 Internally this triggers a call to %prun, see its documentation for
647 details on the options available specifically for profiling.
647 details on the options available specifically for profiling.
648
648
649 There is one special usage for which the text above doesn't apply:
649 There is one special usage for which the text above doesn't apply:
650 if the filename ends with .ipy[nb], the file is run as ipython script,
650 if the filename ends with .ipy[nb], the file is run as ipython script,
651 just as if the commands were written on IPython prompt.
651 just as if the commands were written on IPython prompt.
652
652
653 -m
653 -m
654 specify module name to load instead of script path. Similar to
654 specify module name to load instead of script path. Similar to
655 the -m option for the python interpreter. Use this option last if you
655 the -m option for the python interpreter. Use this option last if you
656 want to combine with other %run options. Unlike the python interpreter
656 want to combine with other %run options. Unlike the python interpreter
657 only source modules are allowed no .pyc or .pyo files.
657 only source modules are allowed no .pyc or .pyo files.
658 For example::
658 For example::
659
659
660 %run -m example
660 %run -m example
661
661
662 will run the example module.
662 will run the example module.
663
663
664 -G
664 -G
665 disable shell-like glob expansion of arguments.
665 disable shell-like glob expansion of arguments.
666
666
667 """
667 """
668
668
669 # Logic to handle issue #3664
669 # Logic to handle issue #3664
670 # Add '--' after '-m <module_name>' to ignore additional args passed to a module.
670 # Add '--' after '-m <module_name>' to ignore additional args passed to a module.
671 if '-m' in parameter_s and '--' not in parameter_s:
671 if '-m' in parameter_s and '--' not in parameter_s:
672 argv = shlex.split(parameter_s, posix=(os.name == 'posix'))
672 argv = shlex.split(parameter_s, posix=(os.name == 'posix'))
673 for idx, arg in enumerate(argv):
673 for idx, arg in enumerate(argv):
674 if arg and arg.startswith('-') and arg != '-':
674 if arg and arg.startswith('-') and arg != '-':
675 if arg == '-m':
675 if arg == '-m':
676 argv.insert(idx + 2, '--')
676 argv.insert(idx + 2, '--')
677 break
677 break
678 else:
678 else:
679 # Positional arg, break
679 # Positional arg, break
680 break
680 break
681 parameter_s = ' '.join(shlex.quote(arg) for arg in argv)
681 parameter_s = ' '.join(shlex.quote(arg) for arg in argv)
682
682
683 # get arguments and set sys.argv for program to be run.
683 # get arguments and set sys.argv for program to be run.
684 opts, arg_lst = self.parse_options(parameter_s,
684 opts, arg_lst = self.parse_options(parameter_s,
685 'nidtN:b:pD:l:rs:T:em:G',
685 'nidtN:b:pD:l:rs:T:em:G',
686 mode='list', list_all=1)
686 mode='list', list_all=1)
687 if "m" in opts:
687 if "m" in opts:
688 modulename = opts["m"][0]
688 modulename = opts["m"][0]
689 modpath = find_mod(modulename)
689 modpath = find_mod(modulename)
690 if modpath is None:
690 if modpath is None:
691 warn('%r is not a valid modulename on sys.path'%modulename)
691 warn('%r is not a valid modulename on sys.path'%modulename)
692 return
692 return
693 arg_lst = [modpath] + arg_lst
693 arg_lst = [modpath] + arg_lst
694 try:
694 try:
695 fpath = None # initialize to make sure fpath is in scope later
695 fpath = None # initialize to make sure fpath is in scope later
696 fpath = arg_lst[0]
696 fpath = arg_lst[0]
697 filename = file_finder(fpath)
697 filename = file_finder(fpath)
698 except IndexError:
698 except IndexError:
699 warn('you must provide at least a filename.')
699 warn('you must provide at least a filename.')
700 print('\n%run:\n', oinspect.getdoc(self.run))
700 print('\n%run:\n', oinspect.getdoc(self.run))
701 return
701 return
702 except IOError as e:
702 except IOError as e:
703 try:
703 try:
704 msg = str(e)
704 msg = str(e)
705 except UnicodeError:
705 except UnicodeError:
706 msg = e.message
706 msg = e.message
707 if os.name == 'nt' and re.match(r"^'.*'$",fpath):
707 if os.name == 'nt' and re.match(r"^'.*'$",fpath):
708 warn('For Windows, use double quotes to wrap a filename: %run "mypath\\myfile.py"')
708 warn('For Windows, use double quotes to wrap a filename: %run "mypath\\myfile.py"')
709 error(msg)
709 error(msg)
710 return
710 return
711
711
712 if filename.lower().endswith(('.ipy', '.ipynb')):
712 if filename.lower().endswith(('.ipy', '.ipynb')):
713 with preserve_keys(self.shell.user_ns, '__file__'):
713 with preserve_keys(self.shell.user_ns, '__file__'):
714 self.shell.user_ns['__file__'] = filename
714 self.shell.user_ns['__file__'] = filename
715 self.shell.safe_execfile_ipy(filename)
715 self.shell.safe_execfile_ipy(filename)
716 return
716 return
717
717
718 # Control the response to exit() calls made by the script being run
718 # Control the response to exit() calls made by the script being run
719 exit_ignore = 'e' in opts
719 exit_ignore = 'e' in opts
720
720
721 # Make sure that the running script gets a proper sys.argv as if it
721 # Make sure that the running script gets a proper sys.argv as if it
722 # were run from a system shell.
722 # were run from a system shell.
723 save_argv = sys.argv # save it for later restoring
723 save_argv = sys.argv # save it for later restoring
724
724
725 if 'G' in opts:
725 if 'G' in opts:
726 args = arg_lst[1:]
726 args = arg_lst[1:]
727 else:
727 else:
728 # tilde and glob expansion
728 # tilde and glob expansion
729 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
729 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
730
730
731 sys.argv = [filename] + args # put in the proper filename
731 sys.argv = [filename] + args # put in the proper filename
732
732
733 if 'n' in opts:
733 if 'n' in opts:
734 name = os.path.splitext(os.path.basename(filename))[0]
734 name = os.path.splitext(os.path.basename(filename))[0]
735 else:
735 else:
736 name = '__main__'
736 name = '__main__'
737
737
738 if 'i' in opts:
738 if 'i' in opts:
739 # Run in user's interactive namespace
739 # Run in user's interactive namespace
740 prog_ns = self.shell.user_ns
740 prog_ns = self.shell.user_ns
741 __name__save = self.shell.user_ns['__name__']
741 __name__save = self.shell.user_ns['__name__']
742 prog_ns['__name__'] = name
742 prog_ns['__name__'] = name
743 main_mod = self.shell.user_module
743 main_mod = self.shell.user_module
744
744
745 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
745 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
746 # set the __file__ global in the script's namespace
746 # set the __file__ global in the script's namespace
747 # TK: Is this necessary in interactive mode?
747 # TK: Is this necessary in interactive mode?
748 prog_ns['__file__'] = filename
748 prog_ns['__file__'] = filename
749 else:
749 else:
750 # Run in a fresh, empty namespace
750 # Run in a fresh, empty namespace
751
751
752 # The shell MUST hold a reference to prog_ns so after %run
752 # The shell MUST hold a reference to prog_ns so after %run
753 # exits, the python deletion mechanism doesn't zero it out
753 # exits, the python deletion mechanism doesn't zero it out
754 # (leaving dangling references). See interactiveshell for details
754 # (leaving dangling references). See interactiveshell for details
755 main_mod = self.shell.new_main_mod(filename, name)
755 main_mod = self.shell.new_main_mod(filename, name)
756 prog_ns = main_mod.__dict__
756 prog_ns = main_mod.__dict__
757
757
758 # pickle fix. See interactiveshell for an explanation. But we need to
758 # pickle fix. See interactiveshell for an explanation. But we need to
759 # make sure that, if we overwrite __main__, we replace it at the end
759 # make sure that, if we overwrite __main__, we replace it at the end
760 main_mod_name = prog_ns['__name__']
760 main_mod_name = prog_ns['__name__']
761
761
762 if main_mod_name == '__main__':
762 if main_mod_name == '__main__':
763 restore_main = sys.modules['__main__']
763 restore_main = sys.modules['__main__']
764 else:
764 else:
765 restore_main = False
765 restore_main = False
766
766
767 # This needs to be undone at the end to prevent holding references to
767 # This needs to be undone at the end to prevent holding references to
768 # every single object ever created.
768 # every single object ever created.
769 sys.modules[main_mod_name] = main_mod
769 sys.modules[main_mod_name] = main_mod
770
770
771 if 'p' in opts or 'd' in opts:
771 if 'p' in opts or 'd' in opts:
772 if 'm' in opts:
772 if 'm' in opts:
773 code = 'run_module(modulename, prog_ns)'
773 code = 'run_module(modulename, prog_ns)'
774 code_ns = {
774 code_ns = {
775 'run_module': self.shell.safe_run_module,
775 'run_module': self.shell.safe_run_module,
776 'prog_ns': prog_ns,
776 'prog_ns': prog_ns,
777 'modulename': modulename,
777 'modulename': modulename,
778 }
778 }
779 else:
779 else:
780 if 'd' in opts:
780 if 'd' in opts:
781 # allow exceptions to raise in debug mode
781 # allow exceptions to raise in debug mode
782 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
782 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
783 else:
783 else:
784 code = 'execfile(filename, prog_ns)'
784 code = 'execfile(filename, prog_ns)'
785 code_ns = {
785 code_ns = {
786 'execfile': self.shell.safe_execfile,
786 'execfile': self.shell.safe_execfile,
787 'prog_ns': prog_ns,
787 'prog_ns': prog_ns,
788 'filename': get_py_filename(filename),
788 'filename': get_py_filename(filename),
789 }
789 }
790
790
791 try:
791 try:
792 stats = None
792 stats = None
793 if 'p' in opts:
793 if 'p' in opts:
794 stats = self._run_with_profiler(code, opts, code_ns)
794 stats = self._run_with_profiler(code, opts, code_ns)
795 else:
795 else:
796 if 'd' in opts:
796 if 'd' in opts:
797 bp_file, bp_line = parse_breakpoint(
797 bp_file, bp_line = parse_breakpoint(
798 opts.get('b', ['1'])[0], filename)
798 opts.get('b', ['1'])[0], filename)
799 self._run_with_debugger(
799 self._run_with_debugger(
800 code, code_ns, filename, bp_line, bp_file)
800 code, code_ns, filename, bp_line, bp_file)
801 else:
801 else:
802 if 'm' in opts:
802 if 'm' in opts:
803 def run():
803 def run():
804 self.shell.safe_run_module(modulename, prog_ns)
804 self.shell.safe_run_module(modulename, prog_ns)
805 else:
805 else:
806 if runner is None:
806 if runner is None:
807 runner = self.default_runner
807 runner = self.default_runner
808 if runner is None:
808 if runner is None:
809 runner = self.shell.safe_execfile
809 runner = self.shell.safe_execfile
810
810
811 def run():
811 def run():
812 runner(filename, prog_ns, prog_ns,
812 runner(filename, prog_ns, prog_ns,
813 exit_ignore=exit_ignore)
813 exit_ignore=exit_ignore)
814
814
815 if 't' in opts:
815 if 't' in opts:
816 # timed execution
816 # timed execution
817 try:
817 try:
818 nruns = int(opts['N'][0])
818 nruns = int(opts['N'][0])
819 if nruns < 1:
819 if nruns < 1:
820 error('Number of runs must be >=1')
820 error('Number of runs must be >=1')
821 return
821 return
822 except (KeyError):
822 except (KeyError):
823 nruns = 1
823 nruns = 1
824 self._run_with_timing(run, nruns)
824 self._run_with_timing(run, nruns)
825 else:
825 else:
826 # regular execution
826 # regular execution
827 run()
827 run()
828
828
829 if 'i' in opts:
829 if 'i' in opts:
830 self.shell.user_ns['__name__'] = __name__save
830 self.shell.user_ns['__name__'] = __name__save
831 else:
831 else:
832 # update IPython interactive namespace
832 # update IPython interactive namespace
833
833
834 # Some forms of read errors on the file may mean the
834 # Some forms of read errors on the file may mean the
835 # __name__ key was never set; using pop we don't have to
835 # __name__ key was never set; using pop we don't have to
836 # worry about a possible KeyError.
836 # worry about a possible KeyError.
837 prog_ns.pop('__name__', None)
837 prog_ns.pop('__name__', None)
838
838
839 with preserve_keys(self.shell.user_ns, '__file__'):
839 with preserve_keys(self.shell.user_ns, '__file__'):
840 self.shell.user_ns.update(prog_ns)
840 self.shell.user_ns.update(prog_ns)
841 finally:
841 finally:
842 # It's a bit of a mystery why, but __builtins__ can change from
842 # It's a bit of a mystery why, but __builtins__ can change from
843 # being a module to becoming a dict missing some key data after
843 # being a module to becoming a dict missing some key data after
844 # %run. As best I can see, this is NOT something IPython is doing
844 # %run. As best I can see, this is NOT something IPython is doing
845 # at all, and similar problems have been reported before:
845 # at all, and similar problems have been reported before:
846 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
846 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
847 # Since this seems to be done by the interpreter itself, the best
847 # Since this seems to be done by the interpreter itself, the best
848 # we can do is to at least restore __builtins__ for the user on
848 # we can do is to at least restore __builtins__ for the user on
849 # exit.
849 # exit.
850 self.shell.user_ns['__builtins__'] = builtin_mod
850 self.shell.user_ns['__builtins__'] = builtin_mod
851
851
852 # Ensure key global structures are restored
852 # Ensure key global structures are restored
853 sys.argv = save_argv
853 sys.argv = save_argv
854 if restore_main:
854 if restore_main:
855 sys.modules['__main__'] = restore_main
855 sys.modules['__main__'] = restore_main
856 else:
856 else:
857 # Remove from sys.modules the reference to main_mod we'd
857 # Remove from sys.modules the reference to main_mod we'd
858 # added. Otherwise it will trap references to objects
858 # added. Otherwise it will trap references to objects
859 # contained therein.
859 # contained therein.
860 del sys.modules[main_mod_name]
860 del sys.modules[main_mod_name]
861
861
862 return stats
862 return stats
863
863
864 def _run_with_debugger(self, code, code_ns, filename=None,
864 def _run_with_debugger(self, code, code_ns, filename=None,
865 bp_line=None, bp_file=None):
865 bp_line=None, bp_file=None):
866 """
866 """
867 Run `code` in debugger with a break point.
867 Run `code` in debugger with a break point.
868
868
869 Parameters
869 Parameters
870 ----------
870 ----------
871 code : str
871 code : str
872 Code to execute.
872 Code to execute.
873 code_ns : dict
873 code_ns : dict
874 A namespace in which `code` is executed.
874 A namespace in which `code` is executed.
875 filename : str
875 filename : str
876 `code` is ran as if it is in `filename`.
876 `code` is ran as if it is in `filename`.
877 bp_line : int, optional
877 bp_line : int, optional
878 Line number of the break point.
878 Line number of the break point.
879 bp_file : str, optional
879 bp_file : str, optional
880 Path to the file in which break point is specified.
880 Path to the file in which break point is specified.
881 `filename` is used if not given.
881 `filename` is used if not given.
882
882
883 Raises
883 Raises
884 ------
884 ------
885 UsageError
885 UsageError
886 If the break point given by `bp_line` is not valid.
886 If the break point given by `bp_line` is not valid.
887
887
888 """
888 """
889 deb = self.shell.InteractiveTB.pdb
889 deb = self.shell.InteractiveTB.pdb
890 if not deb:
890 if not deb:
891 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
891 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
892 deb = self.shell.InteractiveTB.pdb
892 deb = self.shell.InteractiveTB.pdb
893
893
894 # deb.checkline() fails if deb.curframe exists but is None; it can
894 # deb.checkline() fails if deb.curframe exists but is None; it can
895 # handle it not existing. https://github.com/ipython/ipython/issues/10028
895 # handle it not existing. https://github.com/ipython/ipython/issues/10028
896 if hasattr(deb, 'curframe'):
896 if hasattr(deb, 'curframe'):
897 del deb.curframe
897 del deb.curframe
898
898
899 # reset Breakpoint state, which is moronically kept
899 # reset Breakpoint state, which is moronically kept
900 # in a class
900 # in a class
901 bdb.Breakpoint.next = 1
901 bdb.Breakpoint.next = 1
902 bdb.Breakpoint.bplist = {}
902 bdb.Breakpoint.bplist = {}
903 bdb.Breakpoint.bpbynumber = [None]
903 bdb.Breakpoint.bpbynumber = [None]
904 deb.clear_all_breaks()
904 deb.clear_all_breaks()
905 if bp_line is not None:
905 if bp_line is not None:
906 # Set an initial breakpoint to stop execution
906 # Set an initial breakpoint to stop execution
907 maxtries = 10
907 maxtries = 10
908 bp_file = bp_file or filename
908 bp_file = bp_file or filename
909 checkline = deb.checkline(bp_file, bp_line)
909 checkline = deb.checkline(bp_file, bp_line)
910 if not checkline:
910 if not checkline:
911 for bp in range(bp_line + 1, bp_line + maxtries + 1):
911 for bp in range(bp_line + 1, bp_line + maxtries + 1):
912 if deb.checkline(bp_file, bp):
912 if deb.checkline(bp_file, bp):
913 break
913 break
914 else:
914 else:
915 msg = ("\nI failed to find a valid line to set "
915 msg = ("\nI failed to find a valid line to set "
916 "a breakpoint\n"
916 "a breakpoint\n"
917 "after trying up to line: %s.\n"
917 "after trying up to line: %s.\n"
918 "Please set a valid breakpoint manually "
918 "Please set a valid breakpoint manually "
919 "with the -b option." % bp)
919 "with the -b option." % bp)
920 raise UsageError(msg)
920 raise UsageError(msg)
921 # if we find a good linenumber, set the breakpoint
921 # if we find a good linenumber, set the breakpoint
922 deb.do_break('%s:%s' % (bp_file, bp_line))
922 deb.do_break('%s:%s' % (bp_file, bp_line))
923
923
924 if filename:
924 if filename:
925 # Mimic Pdb._runscript(...)
925 # Mimic Pdb._runscript(...)
926 deb._wait_for_mainpyfile = True
926 deb._wait_for_mainpyfile = True
927 deb.mainpyfile = deb.canonic(filename)
927 deb.mainpyfile = deb.canonic(filename)
928
928
929 # Start file run
929 # Start file run
930 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
930 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
931 try:
931 try:
932 if filename:
932 if filename:
933 # save filename so it can be used by methods on the deb object
933 # save filename so it can be used by methods on the deb object
934 deb._exec_filename = filename
934 deb._exec_filename = filename
935 while True:
935 while True:
936 try:
936 try:
937 trace = sys.gettrace()
937 trace = sys.gettrace()
938 deb.run(code, code_ns)
938 deb.run(code, code_ns)
939 except Restart:
939 except Restart:
940 print("Restarting")
940 print("Restarting")
941 if filename:
941 if filename:
942 deb._wait_for_mainpyfile = True
942 deb._wait_for_mainpyfile = True
943 deb.mainpyfile = deb.canonic(filename)
943 deb.mainpyfile = deb.canonic(filename)
944 continue
944 continue
945 else:
945 else:
946 break
946 break
947 finally:
947 finally:
948 sys.settrace(trace)
948 sys.settrace(trace)
949
949
950
950
951 except:
951 except:
952 etype, value, tb = sys.exc_info()
952 etype, value, tb = sys.exc_info()
953 # Skip three frames in the traceback: the %run one,
953 # Skip three frames in the traceback: the %run one,
954 # one inside bdb.py, and the command-line typed by the
954 # one inside bdb.py, and the command-line typed by the
955 # user (run by exec in pdb itself).
955 # user (run by exec in pdb itself).
956 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
956 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
957
957
958 @staticmethod
958 @staticmethod
959 def _run_with_timing(run, nruns):
959 def _run_with_timing(run, nruns):
960 """
960 """
961 Run function `run` and print timing information.
961 Run function `run` and print timing information.
962
962
963 Parameters
963 Parameters
964 ----------
964 ----------
965 run : callable
965 run : callable
966 Any callable object which takes no argument.
966 Any callable object which takes no argument.
967 nruns : int
967 nruns : int
968 Number of times to execute `run`.
968 Number of times to execute `run`.
969
969
970 """
970 """
971 twall0 = time.perf_counter()
971 twall0 = time.perf_counter()
972 if nruns == 1:
972 if nruns == 1:
973 t0 = clock2()
973 t0 = clock2()
974 run()
974 run()
975 t1 = clock2()
975 t1 = clock2()
976 t_usr = t1[0] - t0[0]
976 t_usr = t1[0] - t0[0]
977 t_sys = t1[1] - t0[1]
977 t_sys = t1[1] - t0[1]
978 print("\nIPython CPU timings (estimated):")
978 print("\nIPython CPU timings (estimated):")
979 print(" User : %10.2f s." % t_usr)
979 print(" User : %10.2f s." % t_usr)
980 print(" System : %10.2f s." % t_sys)
980 print(" System : %10.2f s." % t_sys)
981 else:
981 else:
982 runs = range(nruns)
982 runs = range(nruns)
983 t0 = clock2()
983 t0 = clock2()
984 for nr in runs:
984 for nr in runs:
985 run()
985 run()
986 t1 = clock2()
986 t1 = clock2()
987 t_usr = t1[0] - t0[0]
987 t_usr = t1[0] - t0[0]
988 t_sys = t1[1] - t0[1]
988 t_sys = t1[1] - t0[1]
989 print("\nIPython CPU timings (estimated):")
989 print("\nIPython CPU timings (estimated):")
990 print("Total runs performed:", nruns)
990 print("Total runs performed:", nruns)
991 print(" Times : %10s %10s" % ('Total', 'Per run'))
991 print(" Times : %10s %10s" % ('Total', 'Per run'))
992 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
992 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
993 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
993 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
994 twall1 = time.perf_counter()
994 twall1 = time.perf_counter()
995 print("Wall time: %10.2f s." % (twall1 - twall0))
995 print("Wall time: %10.2f s." % (twall1 - twall0))
996
996
997 @skip_doctest
997 @skip_doctest
998 @no_var_expand
998 @no_var_expand
999 @line_cell_magic
999 @line_cell_magic
1000 @needs_local_scope
1000 @needs_local_scope
1001 def timeit(self, line='', cell=None, local_ns=None):
1001 def timeit(self, line='', cell=None, local_ns=None):
1002 """Time execution of a Python statement or expression
1002 """Time execution of a Python statement or expression
1003
1003
1004 Usage, in line mode:
1004 Usage, in line mode:
1005 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
1005 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
1006 or in cell mode:
1006 or in cell mode:
1007 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
1007 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
1008 code
1008 code
1009 code...
1009 code...
1010
1010
1011 Time execution of a Python statement or expression using the timeit
1011 Time execution of a Python statement or expression using the timeit
1012 module. This function can be used both as a line and cell magic:
1012 module. This function can be used both as a line and cell magic:
1013
1013
1014 - In line mode you can time a single-line statement (though multiple
1014 - In line mode you can time a single-line statement (though multiple
1015 ones can be chained with using semicolons).
1015 ones can be chained with using semicolons).
1016
1016
1017 - In cell mode, the statement in the first line is used as setup code
1017 - In cell mode, the statement in the first line is used as setup code
1018 (executed but not timed) and the body of the cell is timed. The cell
1018 (executed but not timed) and the body of the cell is timed. The cell
1019 body has access to any variables created in the setup code.
1019 body has access to any variables created in the setup code.
1020
1020
1021 Options:
1021 Options:
1022 -n<N>: execute the given statement <N> times in a loop. If <N> is not
1022 -n<N>: execute the given statement <N> times in a loop. If <N> is not
1023 provided, <N> is determined so as to get sufficient accuracy.
1023 provided, <N> is determined so as to get sufficient accuracy.
1024
1024
1025 -r<R>: number of repeats <R>, each consisting of <N> loops, and take the
1025 -r<R>: number of repeats <R>, each consisting of <N> loops, and take the
1026 best result.
1026 best result.
1027 Default: 7
1027 Default: 7
1028
1028
1029 -t: use time.time to measure the time, which is the default on Unix.
1029 -t: use time.time to measure the time, which is the default on Unix.
1030 This function measures wall time.
1030 This function measures wall time.
1031
1031
1032 -c: use time.clock to measure the time, which is the default on
1032 -c: use time.clock to measure the time, which is the default on
1033 Windows and measures wall time. On Unix, resource.getrusage is used
1033 Windows and measures wall time. On Unix, resource.getrusage is used
1034 instead and returns the CPU user time.
1034 instead and returns the CPU user time.
1035
1035
1036 -p<P>: use a precision of <P> digits to display the timing result.
1036 -p<P>: use a precision of <P> digits to display the timing result.
1037 Default: 3
1037 Default: 3
1038
1038
1039 -q: Quiet, do not print result.
1039 -q: Quiet, do not print result.
1040
1040
1041 -o: return a TimeitResult that can be stored in a variable to inspect
1041 -o: return a TimeitResult that can be stored in a variable to inspect
1042 the result in more details.
1042 the result in more details.
1043
1043
1044 .. versionchanged:: 7.3
1044 .. versionchanged:: 7.3
1045 User variables are no longer expanded,
1045 User variables are no longer expanded,
1046 the magic line is always left unmodified.
1046 the magic line is always left unmodified.
1047
1047
1048 Examples
1048 Examples
1049 --------
1049 --------
1050 ::
1050 ::
1051
1051
1052 In [1]: %timeit pass
1052 In [1]: %timeit pass
1053 8.26 ns ± 0.12 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
1053 8.26 ns ± 0.12 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
1054
1054
1055 In [2]: u = None
1055 In [2]: u = None
1056
1056
1057 In [3]: %timeit u is None
1057 In [3]: %timeit u is None
1058 29.9 ns ± 0.643 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
1058 29.9 ns ± 0.643 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
1059
1059
1060 In [4]: %timeit -r 4 u == None
1060 In [4]: %timeit -r 4 u == None
1061
1061
1062 In [5]: import time
1062 In [5]: import time
1063
1063
1064 In [6]: %timeit -n1 time.sleep(2)
1064 In [6]: %timeit -n1 time.sleep(2)
1065
1065
1066
1066
1067 The times reported by %timeit will be slightly higher than those
1067 The times reported by %timeit will be slightly higher than those
1068 reported by the timeit.py script when variables are accessed. This is
1068 reported by the timeit.py script when variables are accessed. This is
1069 due to the fact that %timeit executes the statement in the namespace
1069 due to the fact that %timeit executes the statement in the namespace
1070 of the shell, compared with timeit.py, which uses a single setup
1070 of the shell, compared with timeit.py, which uses a single setup
1071 statement to import function or create variables. Generally, the bias
1071 statement to import function or create variables. Generally, the bias
1072 does not matter as long as results from timeit.py are not mixed with
1072 does not matter as long as results from timeit.py are not mixed with
1073 those from %timeit."""
1073 those from %timeit."""
1074
1074
1075 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
1075 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
1076 posix=False, strict=False)
1076 posix=False, strict=False)
1077 if stmt == "" and cell is None:
1077 if stmt == "" and cell is None:
1078 return
1078 return
1079
1079
1080 timefunc = timeit.default_timer
1080 timefunc = timeit.default_timer
1081 number = int(getattr(opts, "n", 0))
1081 number = int(getattr(opts, "n", 0))
1082 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
1082 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
1083 repeat = int(getattr(opts, "r", default_repeat))
1083 repeat = int(getattr(opts, "r", default_repeat))
1084 precision = int(getattr(opts, "p", 3))
1084 precision = int(getattr(opts, "p", 3))
1085 quiet = 'q' in opts
1085 quiet = 'q' in opts
1086 return_result = 'o' in opts
1086 return_result = 'o' in opts
1087 if hasattr(opts, "t"):
1087 if hasattr(opts, "t"):
1088 timefunc = time.time
1088 timefunc = time.time
1089 if hasattr(opts, "c"):
1089 if hasattr(opts, "c"):
1090 timefunc = clock
1090 timefunc = clock
1091
1091
1092 timer = Timer(timer=timefunc)
1092 timer = Timer(timer=timefunc)
1093 # this code has tight coupling to the inner workings of timeit.Timer,
1093 # this code has tight coupling to the inner workings of timeit.Timer,
1094 # but is there a better way to achieve that the code stmt has access
1094 # but is there a better way to achieve that the code stmt has access
1095 # to the shell namespace?
1095 # to the shell namespace?
1096 transform = self.shell.transform_cell
1096 transform = self.shell.transform_cell
1097
1097
1098 if cell is None:
1098 if cell is None:
1099 # called as line magic
1099 # called as line magic
1100 ast_setup = self.shell.compile.ast_parse("pass")
1100 ast_setup = self.shell.compile.ast_parse("pass")
1101 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1101 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1102 else:
1102 else:
1103 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1103 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1104 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1104 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1105
1105
1106 ast_setup = self.shell.transform_ast(ast_setup)
1106 ast_setup = self.shell.transform_ast(ast_setup)
1107 ast_stmt = self.shell.transform_ast(ast_stmt)
1107 ast_stmt = self.shell.transform_ast(ast_stmt)
1108
1108
1109 # Check that these compile to valid Python code *outside* the timer func
1109 # Check that these compile to valid Python code *outside* the timer func
1110 # Invalid code may become valid when put inside the function & loop,
1110 # Invalid code may become valid when put inside the function & loop,
1111 # which messes up error messages.
1111 # which messes up error messages.
1112 # https://github.com/ipython/ipython/issues/10636
1112 # https://github.com/ipython/ipython/issues/10636
1113 self.shell.compile(ast_setup, "<magic-timeit-setup>", "exec")
1113 self.shell.compile(ast_setup, "<magic-timeit-setup>", "exec")
1114 self.shell.compile(ast_stmt, "<magic-timeit-stmt>", "exec")
1114 self.shell.compile(ast_stmt, "<magic-timeit-stmt>", "exec")
1115
1115
1116 # This codestring is taken from timeit.template - we fill it in as an
1116 # This codestring is taken from timeit.template - we fill it in as an
1117 # AST, so that we can apply our AST transformations to the user code
1117 # AST, so that we can apply our AST transformations to the user code
1118 # without affecting the timing code.
1118 # without affecting the timing code.
1119 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1119 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1120 ' setup\n'
1120 ' setup\n'
1121 ' _t0 = _timer()\n'
1121 ' _t0 = _timer()\n'
1122 ' for _i in _it:\n'
1122 ' for _i in _it:\n'
1123 ' stmt\n'
1123 ' stmt\n'
1124 ' _t1 = _timer()\n'
1124 ' _t1 = _timer()\n'
1125 ' return _t1 - _t0\n')
1125 ' return _t1 - _t0\n')
1126
1126
1127 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1127 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1128 timeit_ast = ast.fix_missing_locations(timeit_ast)
1128 timeit_ast = ast.fix_missing_locations(timeit_ast)
1129
1129
1130 # Track compilation time so it can be reported if too long
1130 # Track compilation time so it can be reported if too long
1131 # Minimum time above which compilation time will be reported
1131 # Minimum time above which compilation time will be reported
1132 tc_min = 0.1
1132 tc_min = 0.1
1133
1133
1134 t0 = clock()
1134 t0 = clock()
1135 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1135 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1136 tc = clock()-t0
1136 tc = clock()-t0
1137
1137
1138 ns = {}
1138 ns = {}
1139 glob = self.shell.user_ns
1139 glob = self.shell.user_ns
1140 # handles global vars with same name as local vars. We store them in conflict_globs.
1140 # handles global vars with same name as local vars. We store them in conflict_globs.
1141 conflict_globs = {}
1141 conflict_globs = {}
1142 if local_ns and cell is None:
1142 if local_ns and cell is None:
1143 for var_name, var_val in glob.items():
1143 for var_name, var_val in glob.items():
1144 if var_name in local_ns:
1144 if var_name in local_ns:
1145 conflict_globs[var_name] = var_val
1145 conflict_globs[var_name] = var_val
1146 glob.update(local_ns)
1146 glob.update(local_ns)
1147
1147
1148 exec(code, glob, ns)
1148 exec(code, glob, ns)
1149 timer.inner = ns["inner"]
1149 timer.inner = ns["inner"]
1150
1150
1151 # This is used to check if there is a huge difference between the
1151 # This is used to check if there is a huge difference between the
1152 # best and worst timings.
1152 # best and worst timings.
1153 # Issue: https://github.com/ipython/ipython/issues/6471
1153 # Issue: https://github.com/ipython/ipython/issues/6471
1154 if number == 0:
1154 if number == 0:
1155 # determine number so that 0.2 <= total time < 2.0
1155 # determine number so that 0.2 <= total time < 2.0
1156 for index in range(0, 10):
1156 for index in range(0, 10):
1157 number = 10 ** index
1157 number = 10 ** index
1158 time_number = timer.timeit(number)
1158 time_number = timer.timeit(number)
1159 if time_number >= 0.2:
1159 if time_number >= 0.2:
1160 break
1160 break
1161
1161
1162 all_runs = timer.repeat(repeat, number)
1162 all_runs = timer.repeat(repeat, number)
1163 best = min(all_runs) / number
1163 best = min(all_runs) / number
1164 worst = max(all_runs) / number
1164 worst = max(all_runs) / number
1165 timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1165 timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1166
1166
1167 # Restore global vars from conflict_globs
1167 # Restore global vars from conflict_globs
1168 if conflict_globs:
1168 if conflict_globs:
1169 glob.update(conflict_globs)
1169 glob.update(conflict_globs)
1170
1170
1171 if not quiet :
1171 if not quiet :
1172 # Check best timing is greater than zero to avoid a
1172 # Check best timing is greater than zero to avoid a
1173 # ZeroDivisionError.
1173 # ZeroDivisionError.
1174 # In cases where the slowest timing is lesser than a micosecond
1174 # In cases where the slowest timing is lesser than a microsecond
1175 # we assume that it does not really matter if the fastest
1175 # we assume that it does not really matter if the fastest
1176 # timing is 4 times faster than the slowest timing or not.
1176 # timing is 4 times faster than the slowest timing or not.
1177 if worst > 4 * best and best > 0 and worst > 1e-6:
1177 if worst > 4 * best and best > 0 and worst > 1e-6:
1178 print("The slowest run took %0.2f times longer than the "
1178 print("The slowest run took %0.2f times longer than the "
1179 "fastest. This could mean that an intermediate result "
1179 "fastest. This could mean that an intermediate result "
1180 "is being cached." % (worst / best))
1180 "is being cached." % (worst / best))
1181
1181
1182 print( timeit_result )
1182 print( timeit_result )
1183
1183
1184 if tc > tc_min:
1184 if tc > tc_min:
1185 print("Compiler time: %.2f s" % tc)
1185 print("Compiler time: %.2f s" % tc)
1186 if return_result:
1186 if return_result:
1187 return timeit_result
1187 return timeit_result
1188
1188
1189 @skip_doctest
1189 @skip_doctest
1190 @no_var_expand
1190 @no_var_expand
1191 @needs_local_scope
1191 @needs_local_scope
1192 @line_cell_magic
1192 @line_cell_magic
1193 def time(self,line='', cell=None, local_ns=None):
1193 def time(self,line='', cell=None, local_ns=None):
1194 """Time execution of a Python statement or expression.
1194 """Time execution of a Python statement or expression.
1195
1195
1196 The CPU and wall clock times are printed, and the value of the
1196 The CPU and wall clock times are printed, and the value of the
1197 expression (if any) is returned. Note that under Win32, system time
1197 expression (if any) is returned. Note that under Win32, system time
1198 is always reported as 0, since it can not be measured.
1198 is always reported as 0, since it can not be measured.
1199
1199
1200 This function can be used both as a line and cell magic:
1200 This function can be used both as a line and cell magic:
1201
1201
1202 - In line mode you can time a single-line statement (though multiple
1202 - In line mode you can time a single-line statement (though multiple
1203 ones can be chained with using semicolons).
1203 ones can be chained with using semicolons).
1204
1204
1205 - In cell mode, you can time the cell body (a directly
1205 - In cell mode, you can time the cell body (a directly
1206 following statement raises an error).
1206 following statement raises an error).
1207
1207
1208 This function provides very basic timing functionality. Use the timeit
1208 This function provides very basic timing functionality. Use the timeit
1209 magic for more control over the measurement.
1209 magic for more control over the measurement.
1210
1210
1211 .. versionchanged:: 7.3
1211 .. versionchanged:: 7.3
1212 User variables are no longer expanded,
1212 User variables are no longer expanded,
1213 the magic line is always left unmodified.
1213 the magic line is always left unmodified.
1214
1214
1215 Examples
1215 Examples
1216 --------
1216 --------
1217 ::
1217 ::
1218
1218
1219 In [1]: %time 2**128
1219 In [1]: %time 2**128
1220 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1220 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1221 Wall time: 0.00
1221 Wall time: 0.00
1222 Out[1]: 340282366920938463463374607431768211456L
1222 Out[1]: 340282366920938463463374607431768211456L
1223
1223
1224 In [2]: n = 1000000
1224 In [2]: n = 1000000
1225
1225
1226 In [3]: %time sum(range(n))
1226 In [3]: %time sum(range(n))
1227 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1227 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1228 Wall time: 1.37
1228 Wall time: 1.37
1229 Out[3]: 499999500000L
1229 Out[3]: 499999500000L
1230
1230
1231 In [4]: %time print 'hello world'
1231 In [4]: %time print 'hello world'
1232 hello world
1232 hello world
1233 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1233 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1234 Wall time: 0.00
1234 Wall time: 0.00
1235
1235
1236 Note that the time needed by Python to compile the given expression
1236 Note that the time needed by Python to compile the given expression
1237 will be reported if it is more than 0.1s. In this example, the
1237 will be reported if it is more than 0.1s. In this example, the
1238 actual exponentiation is done by Python at compilation time, so while
1238 actual exponentiation is done by Python at compilation time, so while
1239 the expression can take a noticeable amount of time to compute, that
1239 the expression can take a noticeable amount of time to compute, that
1240 time is purely due to the compilation:
1240 time is purely due to the compilation:
1241
1241
1242 In [5]: %time 3**9999;
1242 In [5]: %time 3**9999;
1243 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1243 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1244 Wall time: 0.00 s
1244 Wall time: 0.00 s
1245
1245
1246 In [6]: %time 3**999999;
1246 In [6]: %time 3**999999;
1247 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1247 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1248 Wall time: 0.00 s
1248 Wall time: 0.00 s
1249 Compiler : 0.78 s
1249 Compiler : 0.78 s
1250 """
1250 """
1251
1251
1252 # fail immediately if the given expression can't be compiled
1252 # fail immediately if the given expression can't be compiled
1253
1253
1254 if line and cell:
1254 if line and cell:
1255 raise UsageError("Can't use statement directly after '%%time'!")
1255 raise UsageError("Can't use statement directly after '%%time'!")
1256
1256
1257 if cell:
1257 if cell:
1258 expr = self.shell.transform_cell(cell)
1258 expr = self.shell.transform_cell(cell)
1259 else:
1259 else:
1260 expr = self.shell.transform_cell(line)
1260 expr = self.shell.transform_cell(line)
1261
1261
1262 # Minimum time above which parse time will be reported
1262 # Minimum time above which parse time will be reported
1263 tp_min = 0.1
1263 tp_min = 0.1
1264
1264
1265 t0 = clock()
1265 t0 = clock()
1266 expr_ast = self.shell.compile.ast_parse(expr)
1266 expr_ast = self.shell.compile.ast_parse(expr)
1267 tp = clock()-t0
1267 tp = clock()-t0
1268
1268
1269 # Apply AST transformations
1269 # Apply AST transformations
1270 expr_ast = self.shell.transform_ast(expr_ast)
1270 expr_ast = self.shell.transform_ast(expr_ast)
1271
1271
1272 # Minimum time above which compilation time will be reported
1272 # Minimum time above which compilation time will be reported
1273 tc_min = 0.1
1273 tc_min = 0.1
1274
1274
1275 expr_val=None
1275 expr_val=None
1276 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1276 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1277 mode = 'eval'
1277 mode = 'eval'
1278 source = '<timed eval>'
1278 source = '<timed eval>'
1279 expr_ast = ast.Expression(expr_ast.body[0].value)
1279 expr_ast = ast.Expression(expr_ast.body[0].value)
1280 else:
1280 else:
1281 mode = 'exec'
1281 mode = 'exec'
1282 source = '<timed exec>'
1282 source = '<timed exec>'
1283 # multi-line %%time case
1283 # multi-line %%time case
1284 if len(expr_ast.body) > 1 and isinstance(expr_ast.body[-1], ast.Expr):
1284 if len(expr_ast.body) > 1 and isinstance(expr_ast.body[-1], ast.Expr):
1285 expr_val= expr_ast.body[-1]
1285 expr_val= expr_ast.body[-1]
1286 expr_ast = expr_ast.body[:-1]
1286 expr_ast = expr_ast.body[:-1]
1287 expr_ast = Module(expr_ast, [])
1287 expr_ast = Module(expr_ast, [])
1288 expr_val = ast.Expression(expr_val.value)
1288 expr_val = ast.Expression(expr_val.value)
1289
1289
1290 t0 = clock()
1290 t0 = clock()
1291 code = self.shell.compile(expr_ast, source, mode)
1291 code = self.shell.compile(expr_ast, source, mode)
1292 tc = clock()-t0
1292 tc = clock()-t0
1293
1293
1294 # skew measurement as little as possible
1294 # skew measurement as little as possible
1295 glob = self.shell.user_ns
1295 glob = self.shell.user_ns
1296 wtime = time.time
1296 wtime = time.time
1297 # time execution
1297 # time execution
1298 wall_st = wtime()
1298 wall_st = wtime()
1299 if mode=='eval':
1299 if mode=='eval':
1300 st = clock2()
1300 st = clock2()
1301 try:
1301 try:
1302 out = eval(code, glob, local_ns)
1302 out = eval(code, glob, local_ns)
1303 except:
1303 except:
1304 self.shell.showtraceback()
1304 self.shell.showtraceback()
1305 return
1305 return
1306 end = clock2()
1306 end = clock2()
1307 else:
1307 else:
1308 st = clock2()
1308 st = clock2()
1309 try:
1309 try:
1310 exec(code, glob, local_ns)
1310 exec(code, glob, local_ns)
1311 out=None
1311 out=None
1312 # multi-line %%time case
1312 # multi-line %%time case
1313 if expr_val is not None:
1313 if expr_val is not None:
1314 code_2 = self.shell.compile(expr_val, source, 'eval')
1314 code_2 = self.shell.compile(expr_val, source, 'eval')
1315 out = eval(code_2, glob, local_ns)
1315 out = eval(code_2, glob, local_ns)
1316 except:
1316 except:
1317 self.shell.showtraceback()
1317 self.shell.showtraceback()
1318 return
1318 return
1319 end = clock2()
1319 end = clock2()
1320
1320
1321 wall_end = wtime()
1321 wall_end = wtime()
1322 # Compute actual times and report
1322 # Compute actual times and report
1323 wall_time = wall_end-wall_st
1323 wall_time = wall_end-wall_st
1324 cpu_user = end[0]-st[0]
1324 cpu_user = end[0]-st[0]
1325 cpu_sys = end[1]-st[1]
1325 cpu_sys = end[1]-st[1]
1326 cpu_tot = cpu_user+cpu_sys
1326 cpu_tot = cpu_user+cpu_sys
1327 # On windows cpu_sys is always zero, so no new information to the next print
1327 # On windows cpu_sys is always zero, so no new information to the next print
1328 if sys.platform != 'win32':
1328 if sys.platform != 'win32':
1329 print("CPU times: user %s, sys: %s, total: %s" % \
1329 print("CPU times: user %s, sys: %s, total: %s" % \
1330 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1330 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1331 print("Wall time: %s" % _format_time(wall_time))
1331 print("Wall time: %s" % _format_time(wall_time))
1332 if tc > tc_min:
1332 if tc > tc_min:
1333 print("Compiler : %s" % _format_time(tc))
1333 print("Compiler : %s" % _format_time(tc))
1334 if tp > tp_min:
1334 if tp > tp_min:
1335 print("Parser : %s" % _format_time(tp))
1335 print("Parser : %s" % _format_time(tp))
1336 return out
1336 return out
1337
1337
1338 @skip_doctest
1338 @skip_doctest
1339 @line_magic
1339 @line_magic
1340 def macro(self, parameter_s=''):
1340 def macro(self, parameter_s=''):
1341 """Define a macro for future re-execution. It accepts ranges of history,
1341 """Define a macro for future re-execution. It accepts ranges of history,
1342 filenames or string objects.
1342 filenames or string objects.
1343
1343
1344 Usage:\\
1344 Usage:\\
1345 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1345 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1346
1346
1347 Options:
1347 Options:
1348
1348
1349 -r: use 'raw' input. By default, the 'processed' history is used,
1349 -r: use 'raw' input. By default, the 'processed' history is used,
1350 so that magics are loaded in their transformed version to valid
1350 so that magics are loaded in their transformed version to valid
1351 Python. If this option is given, the raw input as typed at the
1351 Python. If this option is given, the raw input as typed at the
1352 command line is used instead.
1352 command line is used instead.
1353
1353
1354 -q: quiet macro definition. By default, a tag line is printed
1354 -q: quiet macro definition. By default, a tag line is printed
1355 to indicate the macro has been created, and then the contents of
1355 to indicate the macro has been created, and then the contents of
1356 the macro are printed. If this option is given, then no printout
1356 the macro are printed. If this option is given, then no printout
1357 is produced once the macro is created.
1357 is produced once the macro is created.
1358
1358
1359 This will define a global variable called `name` which is a string
1359 This will define a global variable called `name` which is a string
1360 made of joining the slices and lines you specify (n1,n2,... numbers
1360 made of joining the slices and lines you specify (n1,n2,... numbers
1361 above) from your input history into a single string. This variable
1361 above) from your input history into a single string. This variable
1362 acts like an automatic function which re-executes those lines as if
1362 acts like an automatic function which re-executes those lines as if
1363 you had typed them. You just type 'name' at the prompt and the code
1363 you had typed them. You just type 'name' at the prompt and the code
1364 executes.
1364 executes.
1365
1365
1366 The syntax for indicating input ranges is described in %history.
1366 The syntax for indicating input ranges is described in %history.
1367
1367
1368 Note: as a 'hidden' feature, you can also use traditional python slice
1368 Note: as a 'hidden' feature, you can also use traditional python slice
1369 notation, where N:M means numbers N through M-1.
1369 notation, where N:M means numbers N through M-1.
1370
1370
1371 For example, if your history contains (print using %hist -n )::
1371 For example, if your history contains (print using %hist -n )::
1372
1372
1373 44: x=1
1373 44: x=1
1374 45: y=3
1374 45: y=3
1375 46: z=x+y
1375 46: z=x+y
1376 47: print x
1376 47: print x
1377 48: a=5
1377 48: a=5
1378 49: print 'x',x,'y',y
1378 49: print 'x',x,'y',y
1379
1379
1380 you can create a macro with lines 44 through 47 (included) and line 49
1380 you can create a macro with lines 44 through 47 (included) and line 49
1381 called my_macro with::
1381 called my_macro with::
1382
1382
1383 In [55]: %macro my_macro 44-47 49
1383 In [55]: %macro my_macro 44-47 49
1384
1384
1385 Now, typing `my_macro` (without quotes) will re-execute all this code
1385 Now, typing `my_macro` (without quotes) will re-execute all this code
1386 in one pass.
1386 in one pass.
1387
1387
1388 You don't need to give the line-numbers in order, and any given line
1388 You don't need to give the line-numbers in order, and any given line
1389 number can appear multiple times. You can assemble macros with any
1389 number can appear multiple times. You can assemble macros with any
1390 lines from your input history in any order.
1390 lines from your input history in any order.
1391
1391
1392 The macro is a simple object which holds its value in an attribute,
1392 The macro is a simple object which holds its value in an attribute,
1393 but IPython's display system checks for macros and executes them as
1393 but IPython's display system checks for macros and executes them as
1394 code instead of printing them when you type their name.
1394 code instead of printing them when you type their name.
1395
1395
1396 You can view a macro's contents by explicitly printing it with::
1396 You can view a macro's contents by explicitly printing it with::
1397
1397
1398 print macro_name
1398 print macro_name
1399
1399
1400 """
1400 """
1401 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1401 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1402 if not args: # List existing macros
1402 if not args: # List existing macros
1403 return sorted(k for k,v in self.shell.user_ns.items() if isinstance(v, Macro))
1403 return sorted(k for k,v in self.shell.user_ns.items() if isinstance(v, Macro))
1404 if len(args) == 1:
1404 if len(args) == 1:
1405 raise UsageError(
1405 raise UsageError(
1406 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1406 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1407 name, codefrom = args[0], " ".join(args[1:])
1407 name, codefrom = args[0], " ".join(args[1:])
1408
1408
1409 #print 'rng',ranges # dbg
1409 #print 'rng',ranges # dbg
1410 try:
1410 try:
1411 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1411 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1412 except (ValueError, TypeError) as e:
1412 except (ValueError, TypeError) as e:
1413 print(e.args[0])
1413 print(e.args[0])
1414 return
1414 return
1415 macro = Macro(lines)
1415 macro = Macro(lines)
1416 self.shell.define_macro(name, macro)
1416 self.shell.define_macro(name, macro)
1417 if not ( 'q' in opts) :
1417 if not ( 'q' in opts) :
1418 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1418 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1419 print('=== Macro contents: ===')
1419 print('=== Macro contents: ===')
1420 print(macro, end=' ')
1420 print(macro, end=' ')
1421
1421
1422 @magic_arguments.magic_arguments()
1422 @magic_arguments.magic_arguments()
1423 @magic_arguments.argument('output', type=str, default='', nargs='?',
1423 @magic_arguments.argument('output', type=str, default='', nargs='?',
1424 help="""The name of the variable in which to store output.
1424 help="""The name of the variable in which to store output.
1425 This is a utils.io.CapturedIO object with stdout/err attributes
1425 This is a utils.io.CapturedIO object with stdout/err attributes
1426 for the text of the captured output.
1426 for the text of the captured output.
1427
1427
1428 CapturedOutput also has a show() method for displaying the output,
1428 CapturedOutput also has a show() method for displaying the output,
1429 and __call__ as well, so you can use that to quickly display the
1429 and __call__ as well, so you can use that to quickly display the
1430 output.
1430 output.
1431
1431
1432 If unspecified, captured output is discarded.
1432 If unspecified, captured output is discarded.
1433 """
1433 """
1434 )
1434 )
1435 @magic_arguments.argument('--no-stderr', action="store_true",
1435 @magic_arguments.argument('--no-stderr', action="store_true",
1436 help="""Don't capture stderr."""
1436 help="""Don't capture stderr."""
1437 )
1437 )
1438 @magic_arguments.argument('--no-stdout', action="store_true",
1438 @magic_arguments.argument('--no-stdout', action="store_true",
1439 help="""Don't capture stdout."""
1439 help="""Don't capture stdout."""
1440 )
1440 )
1441 @magic_arguments.argument('--no-display', action="store_true",
1441 @magic_arguments.argument('--no-display', action="store_true",
1442 help="""Don't capture IPython's rich display."""
1442 help="""Don't capture IPython's rich display."""
1443 )
1443 )
1444 @cell_magic
1444 @cell_magic
1445 def capture(self, line, cell):
1445 def capture(self, line, cell):
1446 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1446 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1447 args = magic_arguments.parse_argstring(self.capture, line)
1447 args = magic_arguments.parse_argstring(self.capture, line)
1448 out = not args.no_stdout
1448 out = not args.no_stdout
1449 err = not args.no_stderr
1449 err = not args.no_stderr
1450 disp = not args.no_display
1450 disp = not args.no_display
1451 with capture_output(out, err, disp) as io:
1451 with capture_output(out, err, disp) as io:
1452 self.shell.run_cell(cell)
1452 self.shell.run_cell(cell)
1453 if args.output:
1453 if args.output:
1454 self.shell.user_ns[args.output] = io
1454 self.shell.user_ns[args.output] = io
1455
1455
1456 def parse_breakpoint(text, current_file):
1456 def parse_breakpoint(text, current_file):
1457 '''Returns (file, line) for file:line and (current_file, line) for line'''
1457 '''Returns (file, line) for file:line and (current_file, line) for line'''
1458 colon = text.find(':')
1458 colon = text.find(':')
1459 if colon == -1:
1459 if colon == -1:
1460 return current_file, int(text)
1460 return current_file, int(text)
1461 else:
1461 else:
1462 return text[:colon], int(text[colon+1:])
1462 return text[:colon], int(text[colon+1:])
1463
1463
1464 def _format_time(timespan, precision=3):
1464 def _format_time(timespan, precision=3):
1465 """Formats the timespan in a human readable form"""
1465 """Formats the timespan in a human readable form"""
1466
1466
1467 if timespan >= 60.0:
1467 if timespan >= 60.0:
1468 # we have more than a minute, format that in a human readable form
1468 # we have more than a minute, format that in a human readable form
1469 # Idea from http://snipplr.com/view/5713/
1469 # Idea from http://snipplr.com/view/5713/
1470 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1470 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1471 time = []
1471 time = []
1472 leftover = timespan
1472 leftover = timespan
1473 for suffix, length in parts:
1473 for suffix, length in parts:
1474 value = int(leftover / length)
1474 value = int(leftover / length)
1475 if value > 0:
1475 if value > 0:
1476 leftover = leftover % length
1476 leftover = leftover % length
1477 time.append(u'%s%s' % (str(value), suffix))
1477 time.append(u'%s%s' % (str(value), suffix))
1478 if leftover < 1:
1478 if leftover < 1:
1479 break
1479 break
1480 return " ".join(time)
1480 return " ".join(time)
1481
1481
1482
1482
1483 # Unfortunately the unicode 'micro' symbol can cause problems in
1483 # Unfortunately the unicode 'micro' symbol can cause problems in
1484 # certain terminals.
1484 # certain terminals.
1485 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1485 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1486 # Try to prevent crashes by being more secure than it needs to
1486 # Try to prevent crashes by being more secure than it needs to
1487 # E.g. eclipse is able to print a µ, but has no sys.stdout.encoding set.
1487 # E.g. eclipse is able to print a µ, but has no sys.stdout.encoding set.
1488 units = [u"s", u"ms",u'us',"ns"] # the save value
1488 units = [u"s", u"ms",u'us',"ns"] # the save value
1489 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1489 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1490 try:
1490 try:
1491 u'\xb5'.encode(sys.stdout.encoding)
1491 u'\xb5'.encode(sys.stdout.encoding)
1492 units = [u"s", u"ms",u'\xb5s',"ns"]
1492 units = [u"s", u"ms",u'\xb5s',"ns"]
1493 except:
1493 except:
1494 pass
1494 pass
1495 scaling = [1, 1e3, 1e6, 1e9]
1495 scaling = [1, 1e3, 1e6, 1e9]
1496
1496
1497 if timespan > 0.0:
1497 if timespan > 0.0:
1498 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1498 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1499 else:
1499 else:
1500 order = 3
1500 order = 3
1501 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
1501 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
@@ -1,843 +1,843 b''
1 """Implementation of magic functions for interaction with the OS.
1 """Implementation of magic functions for interaction with the OS.
2
2
3 Note: this module is named 'osm' instead of 'os' to avoid a collision with the
3 Note: this module is named 'osm' instead of 'os' to avoid a collision with the
4 builtin.
4 builtin.
5 """
5 """
6 # Copyright (c) IPython Development Team.
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8
8
9 import io
9 import io
10 import os
10 import os
11 import re
11 import re
12 import sys
12 import sys
13 from pprint import pformat
13 from pprint import pformat
14
14
15 from IPython.core import magic_arguments
15 from IPython.core import magic_arguments
16 from IPython.core import oinspect
16 from IPython.core import oinspect
17 from IPython.core import page
17 from IPython.core import page
18 from IPython.core.alias import AliasError, Alias
18 from IPython.core.alias import AliasError, Alias
19 from IPython.core.error import UsageError
19 from IPython.core.error import UsageError
20 from IPython.core.magic import (
20 from IPython.core.magic import (
21 Magics, compress_dhist, magics_class, line_magic, cell_magic, line_cell_magic
21 Magics, compress_dhist, magics_class, line_magic, cell_magic, line_cell_magic
22 )
22 )
23 from IPython.testing.skipdoctest import skip_doctest
23 from IPython.testing.skipdoctest import skip_doctest
24 from IPython.utils.openpy import source_to_unicode
24 from IPython.utils.openpy import source_to_unicode
25 from IPython.utils.process import abbrev_cwd
25 from IPython.utils.process import abbrev_cwd
26 from IPython.utils.terminal import set_term_title
26 from IPython.utils.terminal import set_term_title
27 from traitlets import Bool
27 from traitlets import Bool
28
28
29
29
30 @magics_class
30 @magics_class
31 class OSMagics(Magics):
31 class OSMagics(Magics):
32 """Magics to interact with the underlying OS (shell-type functionality).
32 """Magics to interact with the underlying OS (shell-type functionality).
33 """
33 """
34
34
35 cd_force_quiet = Bool(False,
35 cd_force_quiet = Bool(False,
36 help="Force %cd magic to be quiet even if -q is not passed."
36 help="Force %cd magic to be quiet even if -q is not passed."
37 ).tag(config=True)
37 ).tag(config=True)
38
38
39 def __init__(self, shell=None, **kwargs):
39 def __init__(self, shell=None, **kwargs):
40
40
41 # Now define isexec in a cross platform manner.
41 # Now define isexec in a cross platform manner.
42 self.is_posix = False
42 self.is_posix = False
43 self.execre = None
43 self.execre = None
44 if os.name == 'posix':
44 if os.name == 'posix':
45 self.is_posix = True
45 self.is_posix = True
46 else:
46 else:
47 try:
47 try:
48 winext = os.environ['pathext'].replace(';','|').replace('.','')
48 winext = os.environ['pathext'].replace(';','|').replace('.','')
49 except KeyError:
49 except KeyError:
50 winext = 'exe|com|bat|py'
50 winext = 'exe|com|bat|py'
51
51
52 self.execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
52 self.execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
53
53
54 # call up the chain
54 # call up the chain
55 super().__init__(shell=shell, **kwargs)
55 super().__init__(shell=shell, **kwargs)
56
56
57
57
58 @skip_doctest
58 @skip_doctest
59 def _isexec_POSIX(self, file):
59 def _isexec_POSIX(self, file):
60 """
60 """
61 Test for executible on a POSIX system
61 Test for executable on a POSIX system
62 """
62 """
63 if os.access(file.path, os.X_OK):
63 if os.access(file.path, os.X_OK):
64 # will fail on maxOS if access is not X_OK
64 # will fail on maxOS if access is not X_OK
65 return file.is_file()
65 return file.is_file()
66 return False
66 return False
67
67
68
68
69
69
70 @skip_doctest
70 @skip_doctest
71 def _isexec_WIN(self, file):
71 def _isexec_WIN(self, file):
72 """
72 """
73 Test for executible file on non POSIX system
73 Test for executable file on non POSIX system
74 """
74 """
75 return file.is_file() and self.execre.match(file.name) is not None
75 return file.is_file() and self.execre.match(file.name) is not None
76
76
77 @skip_doctest
77 @skip_doctest
78 def isexec(self, file):
78 def isexec(self, file):
79 """
79 """
80 Test for executible file on non POSIX system
80 Test for executable file on non POSIX system
81 """
81 """
82 if self.is_posix:
82 if self.is_posix:
83 return self._isexec_POSIX(file)
83 return self._isexec_POSIX(file)
84 else:
84 else:
85 return self._isexec_WIN(file)
85 return self._isexec_WIN(file)
86
86
87
87
88 @skip_doctest
88 @skip_doctest
89 @line_magic
89 @line_magic
90 def alias(self, parameter_s=''):
90 def alias(self, parameter_s=''):
91 """Define an alias for a system command.
91 """Define an alias for a system command.
92
92
93 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
93 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
94
94
95 Then, typing 'alias_name params' will execute the system command 'cmd
95 Then, typing 'alias_name params' will execute the system command 'cmd
96 params' (from your underlying operating system).
96 params' (from your underlying operating system).
97
97
98 Aliases have lower precedence than magic functions and Python normal
98 Aliases have lower precedence than magic functions and Python normal
99 variables, so if 'foo' is both a Python variable and an alias, the
99 variables, so if 'foo' is both a Python variable and an alias, the
100 alias can not be executed until 'del foo' removes the Python variable.
100 alias can not be executed until 'del foo' removes the Python variable.
101
101
102 You can use the %l specifier in an alias definition to represent the
102 You can use the %l specifier in an alias definition to represent the
103 whole line when the alias is called. For example::
103 whole line when the alias is called. For example::
104
104
105 In [2]: alias bracket echo "Input in brackets: <%l>"
105 In [2]: alias bracket echo "Input in brackets: <%l>"
106 In [3]: bracket hello world
106 In [3]: bracket hello world
107 Input in brackets: <hello world>
107 Input in brackets: <hello world>
108
108
109 You can also define aliases with parameters using %s specifiers (one
109 You can also define aliases with parameters using %s specifiers (one
110 per parameter)::
110 per parameter)::
111
111
112 In [1]: alias parts echo first %s second %s
112 In [1]: alias parts echo first %s second %s
113 In [2]: %parts A B
113 In [2]: %parts A B
114 first A second B
114 first A second B
115 In [3]: %parts A
115 In [3]: %parts A
116 Incorrect number of arguments: 2 expected.
116 Incorrect number of arguments: 2 expected.
117 parts is an alias to: 'echo first %s second %s'
117 parts is an alias to: 'echo first %s second %s'
118
118
119 Note that %l and %s are mutually exclusive. You can only use one or
119 Note that %l and %s are mutually exclusive. You can only use one or
120 the other in your aliases.
120 the other in your aliases.
121
121
122 Aliases expand Python variables just like system calls using ! or !!
122 Aliases expand Python variables just like system calls using ! or !!
123 do: all expressions prefixed with '$' get expanded. For details of
123 do: all expressions prefixed with '$' get expanded. For details of
124 the semantic rules, see PEP-215:
124 the semantic rules, see PEP-215:
125 http://www.python.org/peps/pep-0215.html. This is the library used by
125 http://www.python.org/peps/pep-0215.html. This is the library used by
126 IPython for variable expansion. If you want to access a true shell
126 IPython for variable expansion. If you want to access a true shell
127 variable, an extra $ is necessary to prevent its expansion by
127 variable, an extra $ is necessary to prevent its expansion by
128 IPython::
128 IPython::
129
129
130 In [6]: alias show echo
130 In [6]: alias show echo
131 In [7]: PATH='A Python string'
131 In [7]: PATH='A Python string'
132 In [8]: show $PATH
132 In [8]: show $PATH
133 A Python string
133 A Python string
134 In [9]: show $$PATH
134 In [9]: show $$PATH
135 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
135 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
136
136
137 You can use the alias facility to access all of $PATH. See the %rehashx
137 You can use the alias facility to access all of $PATH. See the %rehashx
138 function, which automatically creates aliases for the contents of your
138 function, which automatically creates aliases for the contents of your
139 $PATH.
139 $PATH.
140
140
141 If called with no parameters, %alias prints the current alias table
141 If called with no parameters, %alias prints the current alias table
142 for your system. For posix systems, the default aliases are 'cat',
142 for your system. For posix systems, the default aliases are 'cat',
143 'cp', 'mv', 'rm', 'rmdir', and 'mkdir', and other platform-specific
143 'cp', 'mv', 'rm', 'rmdir', and 'mkdir', and other platform-specific
144 aliases are added. For windows-based systems, the default aliases are
144 aliases are added. For windows-based systems, the default aliases are
145 'copy', 'ddir', 'echo', 'ls', 'ldir', 'mkdir', 'ren', and 'rmdir'.
145 'copy', 'ddir', 'echo', 'ls', 'ldir', 'mkdir', 'ren', and 'rmdir'.
146
146
147 You can see the definition of alias by adding a question mark in the
147 You can see the definition of alias by adding a question mark in the
148 end::
148 end::
149
149
150 In [1]: cat?
150 In [1]: cat?
151 Repr: <alias cat for 'cat'>"""
151 Repr: <alias cat for 'cat'>"""
152
152
153 par = parameter_s.strip()
153 par = parameter_s.strip()
154 if not par:
154 if not par:
155 aliases = sorted(self.shell.alias_manager.aliases)
155 aliases = sorted(self.shell.alias_manager.aliases)
156 # stored = self.shell.db.get('stored_aliases', {} )
156 # stored = self.shell.db.get('stored_aliases', {} )
157 # for k, v in stored:
157 # for k, v in stored:
158 # atab.append(k, v[0])
158 # atab.append(k, v[0])
159
159
160 print("Total number of aliases:", len(aliases))
160 print("Total number of aliases:", len(aliases))
161 sys.stdout.flush()
161 sys.stdout.flush()
162 return aliases
162 return aliases
163
163
164 # Now try to define a new one
164 # Now try to define a new one
165 try:
165 try:
166 alias,cmd = par.split(None, 1)
166 alias,cmd = par.split(None, 1)
167 except TypeError:
167 except TypeError:
168 print(oinspect.getdoc(self.alias))
168 print(oinspect.getdoc(self.alias))
169 return
169 return
170
170
171 try:
171 try:
172 self.shell.alias_manager.define_alias(alias, cmd)
172 self.shell.alias_manager.define_alias(alias, cmd)
173 except AliasError as e:
173 except AliasError as e:
174 print(e)
174 print(e)
175 # end magic_alias
175 # end magic_alias
176
176
177 @line_magic
177 @line_magic
178 def unalias(self, parameter_s=''):
178 def unalias(self, parameter_s=''):
179 """Remove an alias"""
179 """Remove an alias"""
180
180
181 aname = parameter_s.strip()
181 aname = parameter_s.strip()
182 try:
182 try:
183 self.shell.alias_manager.undefine_alias(aname)
183 self.shell.alias_manager.undefine_alias(aname)
184 except ValueError as e:
184 except ValueError as e:
185 print(e)
185 print(e)
186 return
186 return
187
187
188 stored = self.shell.db.get('stored_aliases', {} )
188 stored = self.shell.db.get('stored_aliases', {} )
189 if aname in stored:
189 if aname in stored:
190 print("Removing %stored alias",aname)
190 print("Removing %stored alias",aname)
191 del stored[aname]
191 del stored[aname]
192 self.shell.db['stored_aliases'] = stored
192 self.shell.db['stored_aliases'] = stored
193
193
194 @line_magic
194 @line_magic
195 def rehashx(self, parameter_s=''):
195 def rehashx(self, parameter_s=''):
196 """Update the alias table with all executable files in $PATH.
196 """Update the alias table with all executable files in $PATH.
197
197
198 rehashx explicitly checks that every entry in $PATH is a file
198 rehashx explicitly checks that every entry in $PATH is a file
199 with execute access (os.X_OK).
199 with execute access (os.X_OK).
200
200
201 Under Windows, it checks executability as a match against a
201 Under Windows, it checks executability as a match against a
202 '|'-separated string of extensions, stored in the IPython config
202 '|'-separated string of extensions, stored in the IPython config
203 variable win_exec_ext. This defaults to 'exe|com|bat'.
203 variable win_exec_ext. This defaults to 'exe|com|bat'.
204
204
205 This function also resets the root module cache of module completer,
205 This function also resets the root module cache of module completer,
206 used on slow filesystems.
206 used on slow filesystems.
207 """
207 """
208 from IPython.core.alias import InvalidAliasError
208 from IPython.core.alias import InvalidAliasError
209
209
210 # for the benefit of module completer in ipy_completers.py
210 # for the benefit of module completer in ipy_completers.py
211 del self.shell.db['rootmodules_cache']
211 del self.shell.db['rootmodules_cache']
212
212
213 path = [os.path.abspath(os.path.expanduser(p)) for p in
213 path = [os.path.abspath(os.path.expanduser(p)) for p in
214 os.environ.get('PATH','').split(os.pathsep)]
214 os.environ.get('PATH','').split(os.pathsep)]
215
215
216 syscmdlist = []
216 syscmdlist = []
217 savedir = os.getcwd()
217 savedir = os.getcwd()
218
218
219 # Now walk the paths looking for executables to alias.
219 # Now walk the paths looking for executables to alias.
220 try:
220 try:
221 # write the whole loop for posix/Windows so we don't have an if in
221 # write the whole loop for posix/Windows so we don't have an if in
222 # the innermost part
222 # the innermost part
223 if self.is_posix:
223 if self.is_posix:
224 for pdir in path:
224 for pdir in path:
225 try:
225 try:
226 os.chdir(pdir)
226 os.chdir(pdir)
227 except OSError:
227 except OSError:
228 continue
228 continue
229
229
230 # for python 3.6+ rewrite to: with os.scandir(pdir) as dirlist:
230 # for python 3.6+ rewrite to: with os.scandir(pdir) as dirlist:
231 dirlist = os.scandir(path=pdir)
231 dirlist = os.scandir(path=pdir)
232 for ff in dirlist:
232 for ff in dirlist:
233 if self.isexec(ff):
233 if self.isexec(ff):
234 fname = ff.name
234 fname = ff.name
235 try:
235 try:
236 # Removes dots from the name since ipython
236 # Removes dots from the name since ipython
237 # will assume names with dots to be python.
237 # will assume names with dots to be python.
238 if not self.shell.alias_manager.is_alias(fname):
238 if not self.shell.alias_manager.is_alias(fname):
239 self.shell.alias_manager.define_alias(
239 self.shell.alias_manager.define_alias(
240 fname.replace('.',''), fname)
240 fname.replace('.',''), fname)
241 except InvalidAliasError:
241 except InvalidAliasError:
242 pass
242 pass
243 else:
243 else:
244 syscmdlist.append(fname)
244 syscmdlist.append(fname)
245 else:
245 else:
246 no_alias = Alias.blacklist
246 no_alias = Alias.blacklist
247 for pdir in path:
247 for pdir in path:
248 try:
248 try:
249 os.chdir(pdir)
249 os.chdir(pdir)
250 except OSError:
250 except OSError:
251 continue
251 continue
252
252
253 # for python 3.6+ rewrite to: with os.scandir(pdir) as dirlist:
253 # for python 3.6+ rewrite to: with os.scandir(pdir) as dirlist:
254 dirlist = os.scandir(pdir)
254 dirlist = os.scandir(pdir)
255 for ff in dirlist:
255 for ff in dirlist:
256 fname = ff.name
256 fname = ff.name
257 base, ext = os.path.splitext(fname)
257 base, ext = os.path.splitext(fname)
258 if self.isexec(ff) and base.lower() not in no_alias:
258 if self.isexec(ff) and base.lower() not in no_alias:
259 if ext.lower() == '.exe':
259 if ext.lower() == '.exe':
260 fname = base
260 fname = base
261 try:
261 try:
262 # Removes dots from the name since ipython
262 # Removes dots from the name since ipython
263 # will assume names with dots to be python.
263 # will assume names with dots to be python.
264 self.shell.alias_manager.define_alias(
264 self.shell.alias_manager.define_alias(
265 base.lower().replace('.',''), fname)
265 base.lower().replace('.',''), fname)
266 except InvalidAliasError:
266 except InvalidAliasError:
267 pass
267 pass
268 syscmdlist.append(fname)
268 syscmdlist.append(fname)
269
269
270 self.shell.db['syscmdlist'] = syscmdlist
270 self.shell.db['syscmdlist'] = syscmdlist
271 finally:
271 finally:
272 os.chdir(savedir)
272 os.chdir(savedir)
273
273
274 @skip_doctest
274 @skip_doctest
275 @line_magic
275 @line_magic
276 def pwd(self, parameter_s=''):
276 def pwd(self, parameter_s=''):
277 """Return the current working directory path.
277 """Return the current working directory path.
278
278
279 Examples
279 Examples
280 --------
280 --------
281 ::
281 ::
282
282
283 In [9]: pwd
283 In [9]: pwd
284 Out[9]: '/home/tsuser/sprint/ipython'
284 Out[9]: '/home/tsuser/sprint/ipython'
285 """
285 """
286 try:
286 try:
287 return os.getcwd()
287 return os.getcwd()
288 except FileNotFoundError:
288 except FileNotFoundError:
289 raise UsageError("CWD no longer exists - please use %cd to change directory.")
289 raise UsageError("CWD no longer exists - please use %cd to change directory.")
290
290
291 @skip_doctest
291 @skip_doctest
292 @line_magic
292 @line_magic
293 def cd(self, parameter_s=''):
293 def cd(self, parameter_s=''):
294 """Change the current working directory.
294 """Change the current working directory.
295
295
296 This command automatically maintains an internal list of directories
296 This command automatically maintains an internal list of directories
297 you visit during your IPython session, in the variable _dh. The
297 you visit during your IPython session, in the variable _dh. The
298 command %dhist shows this history nicely formatted. You can also
298 command %dhist shows this history nicely formatted. You can also
299 do 'cd -<tab>' to see directory history conveniently.
299 do 'cd -<tab>' to see directory history conveniently.
300
300
301 Usage:
301 Usage:
302
302
303 cd 'dir': changes to directory 'dir'.
303 cd 'dir': changes to directory 'dir'.
304
304
305 cd -: changes to the last visited directory.
305 cd -: changes to the last visited directory.
306
306
307 cd -<n>: changes to the n-th directory in the directory history.
307 cd -<n>: changes to the n-th directory in the directory history.
308
308
309 cd --foo: change to directory that matches 'foo' in history
309 cd --foo: change to directory that matches 'foo' in history
310
310
311 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
311 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
312 (note: cd <bookmark_name> is enough if there is no
312 (note: cd <bookmark_name> is enough if there is no
313 directory <bookmark_name>, but a bookmark with the name exists.)
313 directory <bookmark_name>, but a bookmark with the name exists.)
314 'cd -b <tab>' allows you to tab-complete bookmark names.
314 'cd -b <tab>' allows you to tab-complete bookmark names.
315
315
316 Options:
316 Options:
317
317
318 -q: quiet. Do not print the working directory after the cd command is
318 -q: quiet. Do not print the working directory after the cd command is
319 executed. By default IPython's cd command does print this directory,
319 executed. By default IPython's cd command does print this directory,
320 since the default prompts do not display path information.
320 since the default prompts do not display path information.
321
321
322 Note that !cd doesn't work for this purpose because the shell where
322 Note that !cd doesn't work for this purpose because the shell where
323 !command runs is immediately discarded after executing 'command'.
323 !command runs is immediately discarded after executing 'command'.
324
324
325 Examples
325 Examples
326 --------
326 --------
327 ::
327 ::
328
328
329 In [10]: cd parent/child
329 In [10]: cd parent/child
330 /home/tsuser/parent/child
330 /home/tsuser/parent/child
331 """
331 """
332
332
333 try:
333 try:
334 oldcwd = os.getcwd()
334 oldcwd = os.getcwd()
335 except FileNotFoundError:
335 except FileNotFoundError:
336 # Happens if the CWD has been deleted.
336 # Happens if the CWD has been deleted.
337 oldcwd = None
337 oldcwd = None
338
338
339 numcd = re.match(r'(-)(\d+)$',parameter_s)
339 numcd = re.match(r'(-)(\d+)$',parameter_s)
340 # jump in directory history by number
340 # jump in directory history by number
341 if numcd:
341 if numcd:
342 nn = int(numcd.group(2))
342 nn = int(numcd.group(2))
343 try:
343 try:
344 ps = self.shell.user_ns['_dh'][nn]
344 ps = self.shell.user_ns['_dh'][nn]
345 except IndexError:
345 except IndexError:
346 print('The requested directory does not exist in history.')
346 print('The requested directory does not exist in history.')
347 return
347 return
348 else:
348 else:
349 opts = {}
349 opts = {}
350 elif parameter_s.startswith('--'):
350 elif parameter_s.startswith('--'):
351 ps = None
351 ps = None
352 fallback = None
352 fallback = None
353 pat = parameter_s[2:]
353 pat = parameter_s[2:]
354 dh = self.shell.user_ns['_dh']
354 dh = self.shell.user_ns['_dh']
355 # first search only by basename (last component)
355 # first search only by basename (last component)
356 for ent in reversed(dh):
356 for ent in reversed(dh):
357 if pat in os.path.basename(ent) and os.path.isdir(ent):
357 if pat in os.path.basename(ent) and os.path.isdir(ent):
358 ps = ent
358 ps = ent
359 break
359 break
360
360
361 if fallback is None and pat in ent and os.path.isdir(ent):
361 if fallback is None and pat in ent and os.path.isdir(ent):
362 fallback = ent
362 fallback = ent
363
363
364 # if we have no last part match, pick the first full path match
364 # if we have no last part match, pick the first full path match
365 if ps is None:
365 if ps is None:
366 ps = fallback
366 ps = fallback
367
367
368 if ps is None:
368 if ps is None:
369 print("No matching entry in directory history")
369 print("No matching entry in directory history")
370 return
370 return
371 else:
371 else:
372 opts = {}
372 opts = {}
373
373
374
374
375 else:
375 else:
376 opts, ps = self.parse_options(parameter_s, 'qb', mode='string')
376 opts, ps = self.parse_options(parameter_s, 'qb', mode='string')
377 # jump to previous
377 # jump to previous
378 if ps == '-':
378 if ps == '-':
379 try:
379 try:
380 ps = self.shell.user_ns['_dh'][-2]
380 ps = self.shell.user_ns['_dh'][-2]
381 except IndexError:
381 except IndexError:
382 raise UsageError('%cd -: No previous directory to change to.')
382 raise UsageError('%cd -: No previous directory to change to.')
383 # jump to bookmark if needed
383 # jump to bookmark if needed
384 else:
384 else:
385 if not os.path.isdir(ps) or 'b' in opts:
385 if not os.path.isdir(ps) or 'b' in opts:
386 bkms = self.shell.db.get('bookmarks', {})
386 bkms = self.shell.db.get('bookmarks', {})
387
387
388 if ps in bkms:
388 if ps in bkms:
389 target = bkms[ps]
389 target = bkms[ps]
390 print('(bookmark:%s) -> %s' % (ps, target))
390 print('(bookmark:%s) -> %s' % (ps, target))
391 ps = target
391 ps = target
392 else:
392 else:
393 if 'b' in opts:
393 if 'b' in opts:
394 raise UsageError("Bookmark '%s' not found. "
394 raise UsageError("Bookmark '%s' not found. "
395 "Use '%%bookmark -l' to see your bookmarks." % ps)
395 "Use '%%bookmark -l' to see your bookmarks." % ps)
396
396
397 # at this point ps should point to the target dir
397 # at this point ps should point to the target dir
398 if ps:
398 if ps:
399 try:
399 try:
400 os.chdir(os.path.expanduser(ps))
400 os.chdir(os.path.expanduser(ps))
401 if hasattr(self.shell, 'term_title') and self.shell.term_title:
401 if hasattr(self.shell, 'term_title') and self.shell.term_title:
402 set_term_title(self.shell.term_title_format.format(cwd=abbrev_cwd()))
402 set_term_title(self.shell.term_title_format.format(cwd=abbrev_cwd()))
403 except OSError:
403 except OSError:
404 print(sys.exc_info()[1])
404 print(sys.exc_info()[1])
405 else:
405 else:
406 cwd = os.getcwd()
406 cwd = os.getcwd()
407 dhist = self.shell.user_ns['_dh']
407 dhist = self.shell.user_ns['_dh']
408 if oldcwd != cwd:
408 if oldcwd != cwd:
409 dhist.append(cwd)
409 dhist.append(cwd)
410 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
410 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
411
411
412 else:
412 else:
413 os.chdir(self.shell.home_dir)
413 os.chdir(self.shell.home_dir)
414 if hasattr(self.shell, 'term_title') and self.shell.term_title:
414 if hasattr(self.shell, 'term_title') and self.shell.term_title:
415 set_term_title(self.shell.term_title_format.format(cwd="~"))
415 set_term_title(self.shell.term_title_format.format(cwd="~"))
416 cwd = os.getcwd()
416 cwd = os.getcwd()
417 dhist = self.shell.user_ns['_dh']
417 dhist = self.shell.user_ns['_dh']
418
418
419 if oldcwd != cwd:
419 if oldcwd != cwd:
420 dhist.append(cwd)
420 dhist.append(cwd)
421 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
421 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
422 if not 'q' in opts and not self.cd_force_quiet and self.shell.user_ns['_dh']:
422 if not 'q' in opts and not self.cd_force_quiet and self.shell.user_ns['_dh']:
423 print(self.shell.user_ns['_dh'][-1])
423 print(self.shell.user_ns['_dh'][-1])
424
424
425 @line_magic
425 @line_magic
426 def env(self, parameter_s=''):
426 def env(self, parameter_s=''):
427 """Get, set, or list environment variables.
427 """Get, set, or list environment variables.
428
428
429 Usage:\\
429 Usage:\\
430
430
431 %env: lists all environment variables/values
431 %env: lists all environment variables/values
432 %env var: get value for var
432 %env var: get value for var
433 %env var val: set value for var
433 %env var val: set value for var
434 %env var=val: set value for var
434 %env var=val: set value for var
435 %env var=$val: set value for var, using python expansion if possible
435 %env var=$val: set value for var, using python expansion if possible
436 """
436 """
437 if parameter_s.strip():
437 if parameter_s.strip():
438 split = '=' if '=' in parameter_s else ' '
438 split = '=' if '=' in parameter_s else ' '
439 bits = parameter_s.split(split)
439 bits = parameter_s.split(split)
440 if len(bits) == 1:
440 if len(bits) == 1:
441 key = parameter_s.strip()
441 key = parameter_s.strip()
442 if key in os.environ:
442 if key in os.environ:
443 return os.environ[key]
443 return os.environ[key]
444 else:
444 else:
445 err = "Environment does not have key: {0}".format(key)
445 err = "Environment does not have key: {0}".format(key)
446 raise UsageError(err)
446 raise UsageError(err)
447 if len(bits) > 1:
447 if len(bits) > 1:
448 return self.set_env(parameter_s)
448 return self.set_env(parameter_s)
449 return dict(os.environ)
449 return dict(os.environ)
450
450
451 @line_magic
451 @line_magic
452 def set_env(self, parameter_s):
452 def set_env(self, parameter_s):
453 """Set environment variables. Assumptions are that either "val" is a
453 """Set environment variables. Assumptions are that either "val" is a
454 name in the user namespace, or val is something that evaluates to a
454 name in the user namespace, or val is something that evaluates to a
455 string.
455 string.
456
456
457 Usage:\\
457 Usage:\\
458 %set_env var val: set value for var
458 %set_env var val: set value for var
459 %set_env var=val: set value for var
459 %set_env var=val: set value for var
460 %set_env var=$val: set value for var, using python expansion if possible
460 %set_env var=$val: set value for var, using python expansion if possible
461 """
461 """
462 split = '=' if '=' in parameter_s else ' '
462 split = '=' if '=' in parameter_s else ' '
463 bits = parameter_s.split(split, 1)
463 bits = parameter_s.split(split, 1)
464 if not parameter_s.strip() or len(bits)<2:
464 if not parameter_s.strip() or len(bits)<2:
465 raise UsageError("usage is 'set_env var=val'")
465 raise UsageError("usage is 'set_env var=val'")
466 var = bits[0].strip()
466 var = bits[0].strip()
467 val = bits[1].strip()
467 val = bits[1].strip()
468 if re.match(r'.*\s.*', var):
468 if re.match(r'.*\s.*', var):
469 # an environment variable with whitespace is almost certainly
469 # an environment variable with whitespace is almost certainly
470 # not what the user intended. what's more likely is the wrong
470 # not what the user intended. what's more likely is the wrong
471 # split was chosen, ie for "set_env cmd_args A=B", we chose
471 # split was chosen, ie for "set_env cmd_args A=B", we chose
472 # '=' for the split and should have chosen ' '. to get around
472 # '=' for the split and should have chosen ' '. to get around
473 # this, users should just assign directly to os.environ or use
473 # this, users should just assign directly to os.environ or use
474 # standard magic {var} expansion.
474 # standard magic {var} expansion.
475 err = "refusing to set env var with whitespace: '{0}'"
475 err = "refusing to set env var with whitespace: '{0}'"
476 err = err.format(val)
476 err = err.format(val)
477 raise UsageError(err)
477 raise UsageError(err)
478 os.environ[var] = val
478 os.environ[var] = val
479 print('env: {0}={1}'.format(var,val))
479 print('env: {0}={1}'.format(var,val))
480
480
481 @line_magic
481 @line_magic
482 def pushd(self, parameter_s=''):
482 def pushd(self, parameter_s=''):
483 """Place the current dir on stack and change directory.
483 """Place the current dir on stack and change directory.
484
484
485 Usage:\\
485 Usage:\\
486 %pushd ['dirname']
486 %pushd ['dirname']
487 """
487 """
488
488
489 dir_s = self.shell.dir_stack
489 dir_s = self.shell.dir_stack
490 tgt = os.path.expanduser(parameter_s)
490 tgt = os.path.expanduser(parameter_s)
491 cwd = os.getcwd().replace(self.shell.home_dir,'~')
491 cwd = os.getcwd().replace(self.shell.home_dir,'~')
492 if tgt:
492 if tgt:
493 self.cd(parameter_s)
493 self.cd(parameter_s)
494 dir_s.insert(0,cwd)
494 dir_s.insert(0,cwd)
495 return self.shell.magic('dirs')
495 return self.shell.magic('dirs')
496
496
497 @line_magic
497 @line_magic
498 def popd(self, parameter_s=''):
498 def popd(self, parameter_s=''):
499 """Change to directory popped off the top of the stack.
499 """Change to directory popped off the top of the stack.
500 """
500 """
501 if not self.shell.dir_stack:
501 if not self.shell.dir_stack:
502 raise UsageError("%popd on empty stack")
502 raise UsageError("%popd on empty stack")
503 top = self.shell.dir_stack.pop(0)
503 top = self.shell.dir_stack.pop(0)
504 self.cd(top)
504 self.cd(top)
505 print("popd ->",top)
505 print("popd ->",top)
506
506
507 @line_magic
507 @line_magic
508 def dirs(self, parameter_s=''):
508 def dirs(self, parameter_s=''):
509 """Return the current directory stack."""
509 """Return the current directory stack."""
510
510
511 return self.shell.dir_stack
511 return self.shell.dir_stack
512
512
513 @line_magic
513 @line_magic
514 def dhist(self, parameter_s=''):
514 def dhist(self, parameter_s=''):
515 """Print your history of visited directories.
515 """Print your history of visited directories.
516
516
517 %dhist -> print full history\\
517 %dhist -> print full history\\
518 %dhist n -> print last n entries only\\
518 %dhist n -> print last n entries only\\
519 %dhist n1 n2 -> print entries between n1 and n2 (n2 not included)\\
519 %dhist n1 n2 -> print entries between n1 and n2 (n2 not included)\\
520
520
521 This history is automatically maintained by the %cd command, and
521 This history is automatically maintained by the %cd command, and
522 always available as the global list variable _dh. You can use %cd -<n>
522 always available as the global list variable _dh. You can use %cd -<n>
523 to go to directory number <n>.
523 to go to directory number <n>.
524
524
525 Note that most of time, you should view directory history by entering
525 Note that most of time, you should view directory history by entering
526 cd -<TAB>.
526 cd -<TAB>.
527
527
528 """
528 """
529
529
530 dh = self.shell.user_ns['_dh']
530 dh = self.shell.user_ns['_dh']
531 if parameter_s:
531 if parameter_s:
532 try:
532 try:
533 args = map(int,parameter_s.split())
533 args = map(int,parameter_s.split())
534 except:
534 except:
535 self.arg_err(self.dhist)
535 self.arg_err(self.dhist)
536 return
536 return
537 if len(args) == 1:
537 if len(args) == 1:
538 ini,fin = max(len(dh)-(args[0]),0),len(dh)
538 ini,fin = max(len(dh)-(args[0]),0),len(dh)
539 elif len(args) == 2:
539 elif len(args) == 2:
540 ini,fin = args
540 ini,fin = args
541 fin = min(fin, len(dh))
541 fin = min(fin, len(dh))
542 else:
542 else:
543 self.arg_err(self.dhist)
543 self.arg_err(self.dhist)
544 return
544 return
545 else:
545 else:
546 ini,fin = 0,len(dh)
546 ini,fin = 0,len(dh)
547 print('Directory history (kept in _dh)')
547 print('Directory history (kept in _dh)')
548 for i in range(ini, fin):
548 for i in range(ini, fin):
549 print("%d: %s" % (i, dh[i]))
549 print("%d: %s" % (i, dh[i]))
550
550
551 @skip_doctest
551 @skip_doctest
552 @line_magic
552 @line_magic
553 def sc(self, parameter_s=''):
553 def sc(self, parameter_s=''):
554 """Shell capture - run shell command and capture output (DEPRECATED use !).
554 """Shell capture - run shell command and capture output (DEPRECATED use !).
555
555
556 DEPRECATED. Suboptimal, retained for backwards compatibility.
556 DEPRECATED. Suboptimal, retained for backwards compatibility.
557
557
558 You should use the form 'var = !command' instead. Example:
558 You should use the form 'var = !command' instead. Example:
559
559
560 "%sc -l myfiles = ls ~" should now be written as
560 "%sc -l myfiles = ls ~" should now be written as
561
561
562 "myfiles = !ls ~"
562 "myfiles = !ls ~"
563
563
564 myfiles.s, myfiles.l and myfiles.n still apply as documented
564 myfiles.s, myfiles.l and myfiles.n still apply as documented
565 below.
565 below.
566
566
567 --
567 --
568 %sc [options] varname=command
568 %sc [options] varname=command
569
569
570 IPython will run the given command using commands.getoutput(), and
570 IPython will run the given command using commands.getoutput(), and
571 will then update the user's interactive namespace with a variable
571 will then update the user's interactive namespace with a variable
572 called varname, containing the value of the call. Your command can
572 called varname, containing the value of the call. Your command can
573 contain shell wildcards, pipes, etc.
573 contain shell wildcards, pipes, etc.
574
574
575 The '=' sign in the syntax is mandatory, and the variable name you
575 The '=' sign in the syntax is mandatory, and the variable name you
576 supply must follow Python's standard conventions for valid names.
576 supply must follow Python's standard conventions for valid names.
577
577
578 (A special format without variable name exists for internal use)
578 (A special format without variable name exists for internal use)
579
579
580 Options:
580 Options:
581
581
582 -l: list output. Split the output on newlines into a list before
582 -l: list output. Split the output on newlines into a list before
583 assigning it to the given variable. By default the output is stored
583 assigning it to the given variable. By default the output is stored
584 as a single string.
584 as a single string.
585
585
586 -v: verbose. Print the contents of the variable.
586 -v: verbose. Print the contents of the variable.
587
587
588 In most cases you should not need to split as a list, because the
588 In most cases you should not need to split as a list, because the
589 returned value is a special type of string which can automatically
589 returned value is a special type of string which can automatically
590 provide its contents either as a list (split on newlines) or as a
590 provide its contents either as a list (split on newlines) or as a
591 space-separated string. These are convenient, respectively, either
591 space-separated string. These are convenient, respectively, either
592 for sequential processing or to be passed to a shell command.
592 for sequential processing or to be passed to a shell command.
593
593
594 For example::
594 For example::
595
595
596 # Capture into variable a
596 # Capture into variable a
597 In [1]: sc a=ls *py
597 In [1]: sc a=ls *py
598
598
599 # a is a string with embedded newlines
599 # a is a string with embedded newlines
600 In [2]: a
600 In [2]: a
601 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
601 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
602
602
603 # which can be seen as a list:
603 # which can be seen as a list:
604 In [3]: a.l
604 In [3]: a.l
605 Out[3]: ['setup.py', 'win32_manual_post_install.py']
605 Out[3]: ['setup.py', 'win32_manual_post_install.py']
606
606
607 # or as a whitespace-separated string:
607 # or as a whitespace-separated string:
608 In [4]: a.s
608 In [4]: a.s
609 Out[4]: 'setup.py win32_manual_post_install.py'
609 Out[4]: 'setup.py win32_manual_post_install.py'
610
610
611 # a.s is useful to pass as a single command line:
611 # a.s is useful to pass as a single command line:
612 In [5]: !wc -l $a.s
612 In [5]: !wc -l $a.s
613 146 setup.py
613 146 setup.py
614 130 win32_manual_post_install.py
614 130 win32_manual_post_install.py
615 276 total
615 276 total
616
616
617 # while the list form is useful to loop over:
617 # while the list form is useful to loop over:
618 In [6]: for f in a.l:
618 In [6]: for f in a.l:
619 ...: !wc -l $f
619 ...: !wc -l $f
620 ...:
620 ...:
621 146 setup.py
621 146 setup.py
622 130 win32_manual_post_install.py
622 130 win32_manual_post_install.py
623
623
624 Similarly, the lists returned by the -l option are also special, in
624 Similarly, the lists returned by the -l option are also special, in
625 the sense that you can equally invoke the .s attribute on them to
625 the sense that you can equally invoke the .s attribute on them to
626 automatically get a whitespace-separated string from their contents::
626 automatically get a whitespace-separated string from their contents::
627
627
628 In [7]: sc -l b=ls *py
628 In [7]: sc -l b=ls *py
629
629
630 In [8]: b
630 In [8]: b
631 Out[8]: ['setup.py', 'win32_manual_post_install.py']
631 Out[8]: ['setup.py', 'win32_manual_post_install.py']
632
632
633 In [9]: b.s
633 In [9]: b.s
634 Out[9]: 'setup.py win32_manual_post_install.py'
634 Out[9]: 'setup.py win32_manual_post_install.py'
635
635
636 In summary, both the lists and strings used for output capture have
636 In summary, both the lists and strings used for output capture have
637 the following special attributes::
637 the following special attributes::
638
638
639 .l (or .list) : value as list.
639 .l (or .list) : value as list.
640 .n (or .nlstr): value as newline-separated string.
640 .n (or .nlstr): value as newline-separated string.
641 .s (or .spstr): value as space-separated string.
641 .s (or .spstr): value as space-separated string.
642 """
642 """
643
643
644 opts,args = self.parse_options(parameter_s, 'lv')
644 opts,args = self.parse_options(parameter_s, 'lv')
645 # Try to get a variable name and command to run
645 # Try to get a variable name and command to run
646 try:
646 try:
647 # the variable name must be obtained from the parse_options
647 # the variable name must be obtained from the parse_options
648 # output, which uses shlex.split to strip options out.
648 # output, which uses shlex.split to strip options out.
649 var,_ = args.split('=', 1)
649 var,_ = args.split('=', 1)
650 var = var.strip()
650 var = var.strip()
651 # But the command has to be extracted from the original input
651 # But the command has to be extracted from the original input
652 # parameter_s, not on what parse_options returns, to avoid the
652 # parameter_s, not on what parse_options returns, to avoid the
653 # quote stripping which shlex.split performs on it.
653 # quote stripping which shlex.split performs on it.
654 _,cmd = parameter_s.split('=', 1)
654 _,cmd = parameter_s.split('=', 1)
655 except ValueError:
655 except ValueError:
656 var,cmd = '',''
656 var,cmd = '',''
657 # If all looks ok, proceed
657 # If all looks ok, proceed
658 split = 'l' in opts
658 split = 'l' in opts
659 out = self.shell.getoutput(cmd, split=split)
659 out = self.shell.getoutput(cmd, split=split)
660 if 'v' in opts:
660 if 'v' in opts:
661 print('%s ==\n%s' % (var, pformat(out)))
661 print('%s ==\n%s' % (var, pformat(out)))
662 if var:
662 if var:
663 self.shell.user_ns.update({var:out})
663 self.shell.user_ns.update({var:out})
664 else:
664 else:
665 return out
665 return out
666
666
667 @line_cell_magic
667 @line_cell_magic
668 def sx(self, line='', cell=None):
668 def sx(self, line='', cell=None):
669 """Shell execute - run shell command and capture output (!! is short-hand).
669 """Shell execute - run shell command and capture output (!! is short-hand).
670
670
671 %sx command
671 %sx command
672
672
673 IPython will run the given command using commands.getoutput(), and
673 IPython will run the given command using commands.getoutput(), and
674 return the result formatted as a list (split on '\\n'). Since the
674 return the result formatted as a list (split on '\\n'). Since the
675 output is _returned_, it will be stored in ipython's regular output
675 output is _returned_, it will be stored in ipython's regular output
676 cache Out[N] and in the '_N' automatic variables.
676 cache Out[N] and in the '_N' automatic variables.
677
677
678 Notes:
678 Notes:
679
679
680 1) If an input line begins with '!!', then %sx is automatically
680 1) If an input line begins with '!!', then %sx is automatically
681 invoked. That is, while::
681 invoked. That is, while::
682
682
683 !ls
683 !ls
684
684
685 causes ipython to simply issue system('ls'), typing::
685 causes ipython to simply issue system('ls'), typing::
686
686
687 !!ls
687 !!ls
688
688
689 is a shorthand equivalent to::
689 is a shorthand equivalent to::
690
690
691 %sx ls
691 %sx ls
692
692
693 2) %sx differs from %sc in that %sx automatically splits into a list,
693 2) %sx differs from %sc in that %sx automatically splits into a list,
694 like '%sc -l'. The reason for this is to make it as easy as possible
694 like '%sc -l'. The reason for this is to make it as easy as possible
695 to process line-oriented shell output via further python commands.
695 to process line-oriented shell output via further python commands.
696 %sc is meant to provide much finer control, but requires more
696 %sc is meant to provide much finer control, but requires more
697 typing.
697 typing.
698
698
699 3) Just like %sc -l, this is a list with special attributes:
699 3) Just like %sc -l, this is a list with special attributes:
700 ::
700 ::
701
701
702 .l (or .list) : value as list.
702 .l (or .list) : value as list.
703 .n (or .nlstr): value as newline-separated string.
703 .n (or .nlstr): value as newline-separated string.
704 .s (or .spstr): value as whitespace-separated string.
704 .s (or .spstr): value as whitespace-separated string.
705
705
706 This is very useful when trying to use such lists as arguments to
706 This is very useful when trying to use such lists as arguments to
707 system commands."""
707 system commands."""
708
708
709 if cell is None:
709 if cell is None:
710 # line magic
710 # line magic
711 return self.shell.getoutput(line)
711 return self.shell.getoutput(line)
712 else:
712 else:
713 opts,args = self.parse_options(line, '', 'out=')
713 opts,args = self.parse_options(line, '', 'out=')
714 output = self.shell.getoutput(cell)
714 output = self.shell.getoutput(cell)
715 out_name = opts.get('out', opts.get('o'))
715 out_name = opts.get('out', opts.get('o'))
716 if out_name:
716 if out_name:
717 self.shell.user_ns[out_name] = output
717 self.shell.user_ns[out_name] = output
718 else:
718 else:
719 return output
719 return output
720
720
721 system = line_cell_magic('system')(sx)
721 system = line_cell_magic('system')(sx)
722 bang = cell_magic('!')(sx)
722 bang = cell_magic('!')(sx)
723
723
724 @line_magic
724 @line_magic
725 def bookmark(self, parameter_s=''):
725 def bookmark(self, parameter_s=''):
726 """Manage IPython's bookmark system.
726 """Manage IPython's bookmark system.
727
727
728 %bookmark <name> - set bookmark to current dir
728 %bookmark <name> - set bookmark to current dir
729 %bookmark <name> <dir> - set bookmark to <dir>
729 %bookmark <name> <dir> - set bookmark to <dir>
730 %bookmark -l - list all bookmarks
730 %bookmark -l - list all bookmarks
731 %bookmark -d <name> - remove bookmark
731 %bookmark -d <name> - remove bookmark
732 %bookmark -r - remove all bookmarks
732 %bookmark -r - remove all bookmarks
733
733
734 You can later on access a bookmarked folder with::
734 You can later on access a bookmarked folder with::
735
735
736 %cd -b <name>
736 %cd -b <name>
737
737
738 or simply '%cd <name>' if there is no directory called <name> AND
738 or simply '%cd <name>' if there is no directory called <name> AND
739 there is such a bookmark defined.
739 there is such a bookmark defined.
740
740
741 Your bookmarks persist through IPython sessions, but they are
741 Your bookmarks persist through IPython sessions, but they are
742 associated with each profile."""
742 associated with each profile."""
743
743
744 opts,args = self.parse_options(parameter_s,'drl',mode='list')
744 opts,args = self.parse_options(parameter_s,'drl',mode='list')
745 if len(args) > 2:
745 if len(args) > 2:
746 raise UsageError("%bookmark: too many arguments")
746 raise UsageError("%bookmark: too many arguments")
747
747
748 bkms = self.shell.db.get('bookmarks',{})
748 bkms = self.shell.db.get('bookmarks',{})
749
749
750 if 'd' in opts:
750 if 'd' in opts:
751 try:
751 try:
752 todel = args[0]
752 todel = args[0]
753 except IndexError:
753 except IndexError:
754 raise UsageError(
754 raise UsageError(
755 "%bookmark -d: must provide a bookmark to delete")
755 "%bookmark -d: must provide a bookmark to delete")
756 else:
756 else:
757 try:
757 try:
758 del bkms[todel]
758 del bkms[todel]
759 except KeyError:
759 except KeyError:
760 raise UsageError(
760 raise UsageError(
761 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
761 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
762
762
763 elif 'r' in opts:
763 elif 'r' in opts:
764 bkms = {}
764 bkms = {}
765 elif 'l' in opts:
765 elif 'l' in opts:
766 bks = sorted(bkms)
766 bks = sorted(bkms)
767 if bks:
767 if bks:
768 size = max(map(len, bks))
768 size = max(map(len, bks))
769 else:
769 else:
770 size = 0
770 size = 0
771 fmt = '%-'+str(size)+'s -> %s'
771 fmt = '%-'+str(size)+'s -> %s'
772 print('Current bookmarks:')
772 print('Current bookmarks:')
773 for bk in bks:
773 for bk in bks:
774 print(fmt % (bk, bkms[bk]))
774 print(fmt % (bk, bkms[bk]))
775 else:
775 else:
776 if not args:
776 if not args:
777 raise UsageError("%bookmark: You must specify the bookmark name")
777 raise UsageError("%bookmark: You must specify the bookmark name")
778 elif len(args)==1:
778 elif len(args)==1:
779 bkms[args[0]] = os.getcwd()
779 bkms[args[0]] = os.getcwd()
780 elif len(args)==2:
780 elif len(args)==2:
781 bkms[args[0]] = args[1]
781 bkms[args[0]] = args[1]
782 self.shell.db['bookmarks'] = bkms
782 self.shell.db['bookmarks'] = bkms
783
783
784 @line_magic
784 @line_magic
785 def pycat(self, parameter_s=''):
785 def pycat(self, parameter_s=''):
786 """Show a syntax-highlighted file through a pager.
786 """Show a syntax-highlighted file through a pager.
787
787
788 This magic is similar to the cat utility, but it will assume the file
788 This magic is similar to the cat utility, but it will assume the file
789 to be Python source and will show it with syntax highlighting.
789 to be Python source and will show it with syntax highlighting.
790
790
791 This magic command can either take a local filename, an url,
791 This magic command can either take a local filename, an url,
792 an history range (see %history) or a macro as argument ::
792 an history range (see %history) or a macro as argument ::
793
793
794 %pycat myscript.py
794 %pycat myscript.py
795 %pycat 7-27
795 %pycat 7-27
796 %pycat myMacro
796 %pycat myMacro
797 %pycat http://www.example.com/myscript.py
797 %pycat http://www.example.com/myscript.py
798 """
798 """
799 if not parameter_s:
799 if not parameter_s:
800 raise UsageError('Missing filename, URL, input history range, '
800 raise UsageError('Missing filename, URL, input history range, '
801 'or macro.')
801 'or macro.')
802
802
803 try :
803 try :
804 cont = self.shell.find_user_code(parameter_s, skip_encoding_cookie=False)
804 cont = self.shell.find_user_code(parameter_s, skip_encoding_cookie=False)
805 except (ValueError, IOError):
805 except (ValueError, IOError):
806 print("Error: no such file, variable, URL, history range or macro")
806 print("Error: no such file, variable, URL, history range or macro")
807 return
807 return
808
808
809 page.page(self.shell.pycolorize(source_to_unicode(cont)))
809 page.page(self.shell.pycolorize(source_to_unicode(cont)))
810
810
811 @magic_arguments.magic_arguments()
811 @magic_arguments.magic_arguments()
812 @magic_arguments.argument(
812 @magic_arguments.argument(
813 '-a', '--append', action='store_true', default=False,
813 '-a', '--append', action='store_true', default=False,
814 help='Append contents of the cell to an existing file. '
814 help='Append contents of the cell to an existing file. '
815 'The file will be created if it does not exist.'
815 'The file will be created if it does not exist.'
816 )
816 )
817 @magic_arguments.argument(
817 @magic_arguments.argument(
818 'filename', type=str,
818 'filename', type=str,
819 help='file to write'
819 help='file to write'
820 )
820 )
821 @cell_magic
821 @cell_magic
822 def writefile(self, line, cell):
822 def writefile(self, line, cell):
823 """Write the contents of the cell to a file.
823 """Write the contents of the cell to a file.
824
824
825 The file will be overwritten unless the -a (--append) flag is specified.
825 The file will be overwritten unless the -a (--append) flag is specified.
826 """
826 """
827 args = magic_arguments.parse_argstring(self.writefile, line)
827 args = magic_arguments.parse_argstring(self.writefile, line)
828 if re.match(r'^(\'.*\')|(".*")$', args.filename):
828 if re.match(r'^(\'.*\')|(".*")$', args.filename):
829 filename = os.path.expanduser(args.filename[1:-1])
829 filename = os.path.expanduser(args.filename[1:-1])
830 else:
830 else:
831 filename = os.path.expanduser(args.filename)
831 filename = os.path.expanduser(args.filename)
832
832
833 if os.path.exists(filename):
833 if os.path.exists(filename):
834 if args.append:
834 if args.append:
835 print("Appending to %s" % filename)
835 print("Appending to %s" % filename)
836 else:
836 else:
837 print("Overwriting %s" % filename)
837 print("Overwriting %s" % filename)
838 else:
838 else:
839 print("Writing %s" % filename)
839 print("Writing %s" % filename)
840
840
841 mode = 'a' if args.append else 'w'
841 mode = 'a' if args.append else 'w'
842 with io.open(filename, mode, encoding='utf-8') as f:
842 with io.open(filename, mode, encoding='utf-8') as f:
843 f.write(cell)
843 f.write(cell)
@@ -1,178 +1,178 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for completerlib.
2 """Tests for completerlib.
3
3
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Imports
7 # Imports
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9
9
10 import os
10 import os
11 import shutil
11 import shutil
12 import sys
12 import sys
13 import tempfile
13 import tempfile
14 import unittest
14 import unittest
15 from os.path import join
15 from os.path import join
16
16
17 import nose.tools as nt
17 import nose.tools as nt
18
18
19 from IPython.core.completerlib import magic_run_completer, module_completion, try_import
19 from IPython.core.completerlib import magic_run_completer, module_completion, try_import
20 from IPython.utils.tempdir import TemporaryDirectory
20 from IPython.utils.tempdir import TemporaryDirectory
21 from IPython.testing.decorators import onlyif_unicode_paths
21 from IPython.testing.decorators import onlyif_unicode_paths
22
22
23
23
24 class MockEvent(object):
24 class MockEvent(object):
25 def __init__(self, line):
25 def __init__(self, line):
26 self.line = line
26 self.line = line
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Test functions begin
29 # Test functions begin
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31 class Test_magic_run_completer(unittest.TestCase):
31 class Test_magic_run_completer(unittest.TestCase):
32 files = [u"aao.py", u"a.py", u"b.py", u"aao.txt"]
32 files = [u"aao.py", u"a.py", u"b.py", u"aao.txt"]
33 dirs = [u"adir/", "bdir/"]
33 dirs = [u"adir/", "bdir/"]
34
34
35 def setUp(self):
35 def setUp(self):
36 self.BASETESTDIR = tempfile.mkdtemp()
36 self.BASETESTDIR = tempfile.mkdtemp()
37 for fil in self.files:
37 for fil in self.files:
38 with open(join(self.BASETESTDIR, fil), "w") as sfile:
38 with open(join(self.BASETESTDIR, fil), "w") as sfile:
39 sfile.write("pass\n")
39 sfile.write("pass\n")
40 for d in self.dirs:
40 for d in self.dirs:
41 os.mkdir(join(self.BASETESTDIR, d))
41 os.mkdir(join(self.BASETESTDIR, d))
42
42
43 self.oldpath = os.getcwd()
43 self.oldpath = os.getcwd()
44 os.chdir(self.BASETESTDIR)
44 os.chdir(self.BASETESTDIR)
45
45
46 def tearDown(self):
46 def tearDown(self):
47 os.chdir(self.oldpath)
47 os.chdir(self.oldpath)
48 shutil.rmtree(self.BASETESTDIR)
48 shutil.rmtree(self.BASETESTDIR)
49
49
50 def test_1(self):
50 def test_1(self):
51 """Test magic_run_completer, should match two alterntives
51 """Test magic_run_completer, should match two alternatives
52 """
52 """
53 event = MockEvent(u"%run a")
53 event = MockEvent(u"%run a")
54 mockself = None
54 mockself = None
55 match = set(magic_run_completer(mockself, event))
55 match = set(magic_run_completer(mockself, event))
56 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
56 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
57
57
58 def test_2(self):
58 def test_2(self):
59 """Test magic_run_completer, should match one alterntive
59 """Test magic_run_completer, should match one alternative
60 """
60 """
61 event = MockEvent(u"%run aa")
61 event = MockEvent(u"%run aa")
62 mockself = None
62 mockself = None
63 match = set(magic_run_completer(mockself, event))
63 match = set(magic_run_completer(mockself, event))
64 self.assertEqual(match, {u"aao.py"})
64 self.assertEqual(match, {u"aao.py"})
65
65
66 def test_3(self):
66 def test_3(self):
67 """Test magic_run_completer with unterminated " """
67 """Test magic_run_completer with unterminated " """
68 event = MockEvent(u'%run "a')
68 event = MockEvent(u'%run "a')
69 mockself = None
69 mockself = None
70 match = set(magic_run_completer(mockself, event))
70 match = set(magic_run_completer(mockself, event))
71 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
71 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
72
72
73 def test_completion_more_args(self):
73 def test_completion_more_args(self):
74 event = MockEvent(u'%run a.py ')
74 event = MockEvent(u'%run a.py ')
75 match = set(magic_run_completer(None, event))
75 match = set(magic_run_completer(None, event))
76 self.assertEqual(match, set(self.files + self.dirs))
76 self.assertEqual(match, set(self.files + self.dirs))
77
77
78 def test_completion_in_dir(self):
78 def test_completion_in_dir(self):
79 # Github issue #3459
79 # Github issue #3459
80 event = MockEvent(u'%run a.py {}'.format(join(self.BASETESTDIR, 'a')))
80 event = MockEvent(u'%run a.py {}'.format(join(self.BASETESTDIR, 'a')))
81 print(repr(event.line))
81 print(repr(event.line))
82 match = set(magic_run_completer(None, event))
82 match = set(magic_run_completer(None, event))
83 # We specifically use replace here rather than normpath, because
83 # We specifically use replace here rather than normpath, because
84 # at one point there were duplicates 'adir' and 'adir/', and normpath
84 # at one point there were duplicates 'adir' and 'adir/', and normpath
85 # would hide the failure for that.
85 # would hide the failure for that.
86 self.assertEqual(match, {join(self.BASETESTDIR, f).replace('\\','/')
86 self.assertEqual(match, {join(self.BASETESTDIR, f).replace('\\','/')
87 for f in (u'a.py', u'aao.py', u'aao.txt', u'adir/')})
87 for f in (u'a.py', u'aao.py', u'aao.txt', u'adir/')})
88
88
89 class Test_magic_run_completer_nonascii(unittest.TestCase):
89 class Test_magic_run_completer_nonascii(unittest.TestCase):
90 @onlyif_unicode_paths
90 @onlyif_unicode_paths
91 def setUp(self):
91 def setUp(self):
92 self.BASETESTDIR = tempfile.mkdtemp()
92 self.BASETESTDIR = tempfile.mkdtemp()
93 for fil in [u"aaø.py", u"a.py", u"b.py"]:
93 for fil in [u"aaø.py", u"a.py", u"b.py"]:
94 with open(join(self.BASETESTDIR, fil), "w") as sfile:
94 with open(join(self.BASETESTDIR, fil), "w") as sfile:
95 sfile.write("pass\n")
95 sfile.write("pass\n")
96 self.oldpath = os.getcwd()
96 self.oldpath = os.getcwd()
97 os.chdir(self.BASETESTDIR)
97 os.chdir(self.BASETESTDIR)
98
98
99 def tearDown(self):
99 def tearDown(self):
100 os.chdir(self.oldpath)
100 os.chdir(self.oldpath)
101 shutil.rmtree(self.BASETESTDIR)
101 shutil.rmtree(self.BASETESTDIR)
102
102
103 @onlyif_unicode_paths
103 @onlyif_unicode_paths
104 def test_1(self):
104 def test_1(self):
105 """Test magic_run_completer, should match two alterntives
105 """Test magic_run_completer, should match two alternatives
106 """
106 """
107 event = MockEvent(u"%run a")
107 event = MockEvent(u"%run a")
108 mockself = None
108 mockself = None
109 match = set(magic_run_completer(mockself, event))
109 match = set(magic_run_completer(mockself, event))
110 self.assertEqual(match, {u"a.py", u"aaø.py"})
110 self.assertEqual(match, {u"a.py", u"aaø.py"})
111
111
112 @onlyif_unicode_paths
112 @onlyif_unicode_paths
113 def test_2(self):
113 def test_2(self):
114 """Test magic_run_completer, should match one alterntive
114 """Test magic_run_completer, should match one alternative
115 """
115 """
116 event = MockEvent(u"%run aa")
116 event = MockEvent(u"%run aa")
117 mockself = None
117 mockself = None
118 match = set(magic_run_completer(mockself, event))
118 match = set(magic_run_completer(mockself, event))
119 self.assertEqual(match, {u"aaø.py"})
119 self.assertEqual(match, {u"aaø.py"})
120
120
121 @onlyif_unicode_paths
121 @onlyif_unicode_paths
122 def test_3(self):
122 def test_3(self):
123 """Test magic_run_completer with unterminated " """
123 """Test magic_run_completer with unterminated " """
124 event = MockEvent(u'%run "a')
124 event = MockEvent(u'%run "a')
125 mockself = None
125 mockself = None
126 match = set(magic_run_completer(mockself, event))
126 match = set(magic_run_completer(mockself, event))
127 self.assertEqual(match, {u"a.py", u"aaø.py"})
127 self.assertEqual(match, {u"a.py", u"aaø.py"})
128
128
129 # module_completer:
129 # module_completer:
130
130
131 def test_import_invalid_module():
131 def test_import_invalid_module():
132 """Testing of issue https://github.com/ipython/ipython/issues/1107"""
132 """Testing of issue https://github.com/ipython/ipython/issues/1107"""
133 invalid_module_names = {'foo-bar', 'foo:bar', '10foo'}
133 invalid_module_names = {'foo-bar', 'foo:bar', '10foo'}
134 valid_module_names = {'foobar'}
134 valid_module_names = {'foobar'}
135 with TemporaryDirectory() as tmpdir:
135 with TemporaryDirectory() as tmpdir:
136 sys.path.insert( 0, tmpdir )
136 sys.path.insert( 0, tmpdir )
137 for name in invalid_module_names | valid_module_names:
137 for name in invalid_module_names | valid_module_names:
138 filename = os.path.join(tmpdir, name + '.py')
138 filename = os.path.join(tmpdir, name + '.py')
139 open(filename, 'w').close()
139 open(filename, 'w').close()
140
140
141 s = set( module_completion('import foo') )
141 s = set( module_completion('import foo') )
142 intersection = s.intersection(invalid_module_names)
142 intersection = s.intersection(invalid_module_names)
143 nt.assert_equal(intersection, set())
143 nt.assert_equal(intersection, set())
144
144
145 assert valid_module_names.issubset(s), valid_module_names.intersection(s)
145 assert valid_module_names.issubset(s), valid_module_names.intersection(s)
146
146
147
147
148 def test_bad_module_all():
148 def test_bad_module_all():
149 """Test module with invalid __all__
149 """Test module with invalid __all__
150
150
151 https://github.com/ipython/ipython/issues/9678
151 https://github.com/ipython/ipython/issues/9678
152 """
152 """
153 testsdir = os.path.dirname(__file__)
153 testsdir = os.path.dirname(__file__)
154 sys.path.insert(0, testsdir)
154 sys.path.insert(0, testsdir)
155 try:
155 try:
156 results = module_completion('from bad_all import ')
156 results = module_completion('from bad_all import ')
157 nt.assert_in('puppies', results)
157 nt.assert_in('puppies', results)
158 for r in results:
158 for r in results:
159 nt.assert_is_instance(r, str)
159 nt.assert_is_instance(r, str)
160 finally:
160 finally:
161 sys.path.remove(testsdir)
161 sys.path.remove(testsdir)
162
162
163
163
164 def test_module_without_init():
164 def test_module_without_init():
165 """
165 """
166 Test module without __init__.py.
166 Test module without __init__.py.
167
167
168 https://github.com/ipython/ipython/issues/11226
168 https://github.com/ipython/ipython/issues/11226
169 """
169 """
170 fake_module_name = "foo"
170 fake_module_name = "foo"
171 with TemporaryDirectory() as tmpdir:
171 with TemporaryDirectory() as tmpdir:
172 sys.path.insert(0, tmpdir)
172 sys.path.insert(0, tmpdir)
173 try:
173 try:
174 os.makedirs(os.path.join(tmpdir, fake_module_name))
174 os.makedirs(os.path.join(tmpdir, fake_module_name))
175 s = try_import(mod=fake_module_name)
175 s = try_import(mod=fake_module_name)
176 assert s == []
176 assert s == []
177 finally:
177 finally:
178 sys.path.remove(tmpdir)
178 sys.path.remove(tmpdir)
@@ -1,112 +1,112 b''
1 import sys
1 import sys
2 from IPython.testing.tools import AssertPrints, AssertNotPrints
2 from IPython.testing.tools import AssertPrints, AssertNotPrints
3 from IPython.core.displayhook import CapturingDisplayHook
3 from IPython.core.displayhook import CapturingDisplayHook
4 from IPython.utils.capture import CapturedIO
4 from IPython.utils.capture import CapturedIO
5
5
6 def test_output_displayed():
6 def test_output_displayed():
7 """Checking to make sure that output is displayed"""
7 """Checking to make sure that output is displayed"""
8
8
9 with AssertPrints('2'):
9 with AssertPrints('2'):
10 ip.run_cell('1+1', store_history=True)
10 ip.run_cell('1+1', store_history=True)
11
11
12 with AssertPrints('2'):
12 with AssertPrints('2'):
13 ip.run_cell('1+1 # comment with a semicolon;', store_history=True)
13 ip.run_cell('1+1 # comment with a semicolon;', store_history=True)
14
14
15 with AssertPrints('2'):
15 with AssertPrints('2'):
16 ip.run_cell('1+1\n#commented_out_function();', store_history=True)
16 ip.run_cell('1+1\n#commented_out_function();', store_history=True)
17
17
18
18
19 def test_output_quiet():
19 def test_output_quiet():
20 """Checking to make sure that output is quiet"""
20 """Checking to make sure that output is quiet"""
21
21
22 with AssertNotPrints('2'):
22 with AssertNotPrints('2'):
23 ip.run_cell('1+1;', store_history=True)
23 ip.run_cell('1+1;', store_history=True)
24
24
25 with AssertNotPrints('2'):
25 with AssertNotPrints('2'):
26 ip.run_cell('1+1; # comment with a semicolon', store_history=True)
26 ip.run_cell('1+1; # comment with a semicolon', store_history=True)
27
27
28 with AssertNotPrints('2'):
28 with AssertNotPrints('2'):
29 ip.run_cell('1+1;\n#commented_out_function()', store_history=True)
29 ip.run_cell('1+1;\n#commented_out_function()', store_history=True)
30
30
31 def test_underscore_no_overrite_user():
31 def test_underscore_no_overrite_user():
32 ip.run_cell('_ = 42', store_history=True)
32 ip.run_cell('_ = 42', store_history=True)
33 ip.run_cell('1+1', store_history=True)
33 ip.run_cell('1+1', store_history=True)
34
34
35 with AssertPrints('42'):
35 with AssertPrints('42'):
36 ip.run_cell('print(_)', store_history=True)
36 ip.run_cell('print(_)', store_history=True)
37
37
38 ip.run_cell('del _', store_history=True)
38 ip.run_cell('del _', store_history=True)
39 ip.run_cell('6+6', store_history=True)
39 ip.run_cell('6+6', store_history=True)
40 with AssertPrints('12'):
40 with AssertPrints('12'):
41 ip.run_cell('_', store_history=True)
41 ip.run_cell('_', store_history=True)
42
42
43
43
44 def test_underscore_no_overrite_builtins():
44 def test_underscore_no_overrite_builtins():
45 ip.run_cell("import gettext ; gettext.install('foo')", store_history=True)
45 ip.run_cell("import gettext ; gettext.install('foo')", store_history=True)
46 ip.run_cell('3+3', store_history=True)
46 ip.run_cell('3+3', store_history=True)
47
47
48 with AssertPrints('gettext'):
48 with AssertPrints('gettext'):
49 ip.run_cell('print(_)', store_history=True)
49 ip.run_cell('print(_)', store_history=True)
50
50
51 ip.run_cell('_ = "userset"', store_history=True)
51 ip.run_cell('_ = "userset"', store_history=True)
52
52
53 with AssertPrints('userset'):
53 with AssertPrints('userset'):
54 ip.run_cell('print(_)', store_history=True)
54 ip.run_cell('print(_)', store_history=True)
55 ip.run_cell('import builtins; del builtins._')
55 ip.run_cell('import builtins; del builtins._')
56
56
57
57
58 def test_interactivehooks_ast_modes():
58 def test_interactivehooks_ast_modes():
59 """
59 """
60 Test that ast nodes can be triggered with different modes
60 Test that ast nodes can be triggered with different modes
61 """
61 """
62 saved_mode = ip.ast_node_interactivity
62 saved_mode = ip.ast_node_interactivity
63 ip.ast_node_interactivity = 'last_expr_or_assign'
63 ip.ast_node_interactivity = 'last_expr_or_assign'
64
64
65 try:
65 try:
66 with AssertPrints('2'):
66 with AssertPrints('2'):
67 ip.run_cell('a = 1+1', store_history=True)
67 ip.run_cell('a = 1+1', store_history=True)
68
68
69 with AssertPrints('9'):
69 with AssertPrints('9'):
70 ip.run_cell('b = 1+8 # comment with a semicolon;', store_history=False)
70 ip.run_cell('b = 1+8 # comment with a semicolon;', store_history=False)
71
71
72 with AssertPrints('7'):
72 with AssertPrints('7'):
73 ip.run_cell('c = 1+6\n#commented_out_function();', store_history=True)
73 ip.run_cell('c = 1+6\n#commented_out_function();', store_history=True)
74
74
75 ip.run_cell('d = 11', store_history=True)
75 ip.run_cell('d = 11', store_history=True)
76 with AssertPrints('12'):
76 with AssertPrints('12'):
77 ip.run_cell('d += 1', store_history=True)
77 ip.run_cell('d += 1', store_history=True)
78
78
79 with AssertNotPrints('42'):
79 with AssertNotPrints('42'):
80 ip.run_cell('(u,v) = (41+1, 43-1)')
80 ip.run_cell('(u,v) = (41+1, 43-1)')
81
81
82 finally:
82 finally:
83 ip.ast_node_interactivity = saved_mode
83 ip.ast_node_interactivity = saved_mode
84
84
85 def test_interactivehooks_ast_modes_semi_supress():
85 def test_interactivehooks_ast_modes_semi_suppress():
86 """
86 """
87 Test that ast nodes can be triggered with different modes and suppressed
87 Test that ast nodes can be triggered with different modes and suppressed
88 by semicolon
88 by semicolon
89 """
89 """
90 saved_mode = ip.ast_node_interactivity
90 saved_mode = ip.ast_node_interactivity
91 ip.ast_node_interactivity = 'last_expr_or_assign'
91 ip.ast_node_interactivity = 'last_expr_or_assign'
92
92
93 try:
93 try:
94 with AssertNotPrints('2'):
94 with AssertNotPrints('2'):
95 ip.run_cell('x = 1+1;', store_history=True)
95 ip.run_cell('x = 1+1;', store_history=True)
96
96
97 with AssertNotPrints('7'):
97 with AssertNotPrints('7'):
98 ip.run_cell('y = 1+6; # comment with a semicolon', store_history=True)
98 ip.run_cell('y = 1+6; # comment with a semicolon', store_history=True)
99
99
100 with AssertNotPrints('9'):
100 with AssertNotPrints('9'):
101 ip.run_cell('z = 1+8;\n#commented_out_function()', store_history=True)
101 ip.run_cell('z = 1+8;\n#commented_out_function()', store_history=True)
102
102
103 finally:
103 finally:
104 ip.ast_node_interactivity = saved_mode
104 ip.ast_node_interactivity = saved_mode
105
105
106 def test_capture_display_hook_format():
106 def test_capture_display_hook_format():
107 """Tests that the capture display hook conforms to the CapturedIO output format"""
107 """Tests that the capture display hook conforms to the CapturedIO output format"""
108 hook = CapturingDisplayHook(ip)
108 hook = CapturingDisplayHook(ip)
109 hook({"foo": "bar"})
109 hook({"foo": "bar"})
110 captured = CapturedIO(sys.stdout, sys.stderr, hook.outputs)
110 captured = CapturedIO(sys.stdout, sys.stderr, hook.outputs)
111 # Should not raise with RichOutput transformation error
111 # Should not raise with RichOutput transformation error
112 captured.outputs
112 captured.outputs
@@ -1,1000 +1,1000 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for the key interactiveshell module.
2 """Tests for the key interactiveshell module.
3
3
4 Historically the main classes in interactiveshell have been under-tested. This
4 Historically the main classes in interactiveshell have been under-tested. This
5 module should grow as many single-method tests as possible to trap many of the
5 module should grow as many single-method tests as possible to trap many of the
6 recurring bugs we seem to encounter with high-level interaction.
6 recurring bugs we seem to encounter with high-level interaction.
7 """
7 """
8
8
9 # Copyright (c) IPython Development Team.
9 # Copyright (c) IPython Development Team.
10 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
11
11
12 import asyncio
12 import asyncio
13 import ast
13 import ast
14 import os
14 import os
15 import signal
15 import signal
16 import shutil
16 import shutil
17 import sys
17 import sys
18 import tempfile
18 import tempfile
19 import unittest
19 import unittest
20 from unittest import mock
20 from unittest import mock
21
21
22 from os.path import join
22 from os.path import join
23
23
24 import nose.tools as nt
24 import nose.tools as nt
25
25
26 from IPython.core.error import InputRejected
26 from IPython.core.error import InputRejected
27 from IPython.core.inputtransformer import InputTransformer
27 from IPython.core.inputtransformer import InputTransformer
28 from IPython.core import interactiveshell
28 from IPython.core import interactiveshell
29 from IPython.testing.decorators import (
29 from IPython.testing.decorators import (
30 skipif, skip_win32, onlyif_unicode_paths, onlyif_cmds_exist,
30 skipif, skip_win32, onlyif_unicode_paths, onlyif_cmds_exist,
31 )
31 )
32 from IPython.testing import tools as tt
32 from IPython.testing import tools as tt
33 from IPython.utils.process import find_cmd
33 from IPython.utils.process import find_cmd
34
34
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 # Globals
36 # Globals
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38 # This is used by every single test, no point repeating it ad nauseam
38 # This is used by every single test, no point repeating it ad nauseam
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Tests
41 # Tests
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43
43
44 class DerivedInterrupt(KeyboardInterrupt):
44 class DerivedInterrupt(KeyboardInterrupt):
45 pass
45 pass
46
46
47 class InteractiveShellTestCase(unittest.TestCase):
47 class InteractiveShellTestCase(unittest.TestCase):
48 def test_naked_string_cells(self):
48 def test_naked_string_cells(self):
49 """Test that cells with only naked strings are fully executed"""
49 """Test that cells with only naked strings are fully executed"""
50 # First, single-line inputs
50 # First, single-line inputs
51 ip.run_cell('"a"\n')
51 ip.run_cell('"a"\n')
52 self.assertEqual(ip.user_ns['_'], 'a')
52 self.assertEqual(ip.user_ns['_'], 'a')
53 # And also multi-line cells
53 # And also multi-line cells
54 ip.run_cell('"""a\nb"""\n')
54 ip.run_cell('"""a\nb"""\n')
55 self.assertEqual(ip.user_ns['_'], 'a\nb')
55 self.assertEqual(ip.user_ns['_'], 'a\nb')
56
56
57 def test_run_empty_cell(self):
57 def test_run_empty_cell(self):
58 """Just make sure we don't get a horrible error with a blank
58 """Just make sure we don't get a horrible error with a blank
59 cell of input. Yes, I did overlook that."""
59 cell of input. Yes, I did overlook that."""
60 old_xc = ip.execution_count
60 old_xc = ip.execution_count
61 res = ip.run_cell('')
61 res = ip.run_cell('')
62 self.assertEqual(ip.execution_count, old_xc)
62 self.assertEqual(ip.execution_count, old_xc)
63 self.assertEqual(res.execution_count, None)
63 self.assertEqual(res.execution_count, None)
64
64
65 def test_run_cell_multiline(self):
65 def test_run_cell_multiline(self):
66 """Multi-block, multi-line cells must execute correctly.
66 """Multi-block, multi-line cells must execute correctly.
67 """
67 """
68 src = '\n'.join(["x=1",
68 src = '\n'.join(["x=1",
69 "y=2",
69 "y=2",
70 "if 1:",
70 "if 1:",
71 " x += 1",
71 " x += 1",
72 " y += 1",])
72 " y += 1",])
73 res = ip.run_cell(src)
73 res = ip.run_cell(src)
74 self.assertEqual(ip.user_ns['x'], 2)
74 self.assertEqual(ip.user_ns['x'], 2)
75 self.assertEqual(ip.user_ns['y'], 3)
75 self.assertEqual(ip.user_ns['y'], 3)
76 self.assertEqual(res.success, True)
76 self.assertEqual(res.success, True)
77 self.assertEqual(res.result, None)
77 self.assertEqual(res.result, None)
78
78
79 def test_multiline_string_cells(self):
79 def test_multiline_string_cells(self):
80 "Code sprinkled with multiline strings should execute (GH-306)"
80 "Code sprinkled with multiline strings should execute (GH-306)"
81 ip.run_cell('tmp=0')
81 ip.run_cell('tmp=0')
82 self.assertEqual(ip.user_ns['tmp'], 0)
82 self.assertEqual(ip.user_ns['tmp'], 0)
83 res = ip.run_cell('tmp=1;"""a\nb"""\n')
83 res = ip.run_cell('tmp=1;"""a\nb"""\n')
84 self.assertEqual(ip.user_ns['tmp'], 1)
84 self.assertEqual(ip.user_ns['tmp'], 1)
85 self.assertEqual(res.success, True)
85 self.assertEqual(res.success, True)
86 self.assertEqual(res.result, "a\nb")
86 self.assertEqual(res.result, "a\nb")
87
87
88 def test_dont_cache_with_semicolon(self):
88 def test_dont_cache_with_semicolon(self):
89 "Ending a line with semicolon should not cache the returned object (GH-307)"
89 "Ending a line with semicolon should not cache the returned object (GH-307)"
90 oldlen = len(ip.user_ns['Out'])
90 oldlen = len(ip.user_ns['Out'])
91 for cell in ['1;', '1;1;']:
91 for cell in ['1;', '1;1;']:
92 res = ip.run_cell(cell, store_history=True)
92 res = ip.run_cell(cell, store_history=True)
93 newlen = len(ip.user_ns['Out'])
93 newlen = len(ip.user_ns['Out'])
94 self.assertEqual(oldlen, newlen)
94 self.assertEqual(oldlen, newlen)
95 self.assertIsNone(res.result)
95 self.assertIsNone(res.result)
96 i = 0
96 i = 0
97 #also test the default caching behavior
97 #also test the default caching behavior
98 for cell in ['1', '1;1']:
98 for cell in ['1', '1;1']:
99 ip.run_cell(cell, store_history=True)
99 ip.run_cell(cell, store_history=True)
100 newlen = len(ip.user_ns['Out'])
100 newlen = len(ip.user_ns['Out'])
101 i += 1
101 i += 1
102 self.assertEqual(oldlen+i, newlen)
102 self.assertEqual(oldlen+i, newlen)
103
103
104 def test_syntax_error(self):
104 def test_syntax_error(self):
105 res = ip.run_cell("raise = 3")
105 res = ip.run_cell("raise = 3")
106 self.assertIsInstance(res.error_before_exec, SyntaxError)
106 self.assertIsInstance(res.error_before_exec, SyntaxError)
107
107
108 def test_In_variable(self):
108 def test_In_variable(self):
109 "Verify that In variable grows with user input (GH-284)"
109 "Verify that In variable grows with user input (GH-284)"
110 oldlen = len(ip.user_ns['In'])
110 oldlen = len(ip.user_ns['In'])
111 ip.run_cell('1;', store_history=True)
111 ip.run_cell('1;', store_history=True)
112 newlen = len(ip.user_ns['In'])
112 newlen = len(ip.user_ns['In'])
113 self.assertEqual(oldlen+1, newlen)
113 self.assertEqual(oldlen+1, newlen)
114 self.assertEqual(ip.user_ns['In'][-1],'1;')
114 self.assertEqual(ip.user_ns['In'][-1],'1;')
115
115
116 def test_magic_names_in_string(self):
116 def test_magic_names_in_string(self):
117 ip.run_cell('a = """\n%exit\n"""')
117 ip.run_cell('a = """\n%exit\n"""')
118 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
118 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
119
119
120 def test_trailing_newline(self):
120 def test_trailing_newline(self):
121 """test that running !(command) does not raise a SyntaxError"""
121 """test that running !(command) does not raise a SyntaxError"""
122 ip.run_cell('!(true)\n', False)
122 ip.run_cell('!(true)\n', False)
123 ip.run_cell('!(true)\n\n\n', False)
123 ip.run_cell('!(true)\n\n\n', False)
124
124
125 def test_gh_597(self):
125 def test_gh_597(self):
126 """Pretty-printing lists of objects with non-ascii reprs may cause
126 """Pretty-printing lists of objects with non-ascii reprs may cause
127 problems."""
127 problems."""
128 class Spam(object):
128 class Spam(object):
129 def __repr__(self):
129 def __repr__(self):
130 return "\xe9"*50
130 return "\xe9"*50
131 import IPython.core.formatters
131 import IPython.core.formatters
132 f = IPython.core.formatters.PlainTextFormatter()
132 f = IPython.core.formatters.PlainTextFormatter()
133 f([Spam(),Spam()])
133 f([Spam(),Spam()])
134
134
135
135
136 def test_future_flags(self):
136 def test_future_flags(self):
137 """Check that future flags are used for parsing code (gh-777)"""
137 """Check that future flags are used for parsing code (gh-777)"""
138 ip.run_cell('from __future__ import barry_as_FLUFL')
138 ip.run_cell('from __future__ import barry_as_FLUFL')
139 try:
139 try:
140 ip.run_cell('prfunc_return_val = 1 <> 2')
140 ip.run_cell('prfunc_return_val = 1 <> 2')
141 assert 'prfunc_return_val' in ip.user_ns
141 assert 'prfunc_return_val' in ip.user_ns
142 finally:
142 finally:
143 # Reset compiler flags so we don't mess up other tests.
143 # Reset compiler flags so we don't mess up other tests.
144 ip.compile.reset_compiler_flags()
144 ip.compile.reset_compiler_flags()
145
145
146 def test_can_pickle(self):
146 def test_can_pickle(self):
147 "Can we pickle objects defined interactively (GH-29)"
147 "Can we pickle objects defined interactively (GH-29)"
148 ip = get_ipython()
148 ip = get_ipython()
149 ip.reset()
149 ip.reset()
150 ip.run_cell(("class Mylist(list):\n"
150 ip.run_cell(("class Mylist(list):\n"
151 " def __init__(self,x=[]):\n"
151 " def __init__(self,x=[]):\n"
152 " list.__init__(self,x)"))
152 " list.__init__(self,x)"))
153 ip.run_cell("w=Mylist([1,2,3])")
153 ip.run_cell("w=Mylist([1,2,3])")
154
154
155 from pickle import dumps
155 from pickle import dumps
156
156
157 # We need to swap in our main module - this is only necessary
157 # We need to swap in our main module - this is only necessary
158 # inside the test framework, because IPython puts the interactive module
158 # inside the test framework, because IPython puts the interactive module
159 # in place (but the test framework undoes this).
159 # in place (but the test framework undoes this).
160 _main = sys.modules['__main__']
160 _main = sys.modules['__main__']
161 sys.modules['__main__'] = ip.user_module
161 sys.modules['__main__'] = ip.user_module
162 try:
162 try:
163 res = dumps(ip.user_ns["w"])
163 res = dumps(ip.user_ns["w"])
164 finally:
164 finally:
165 sys.modules['__main__'] = _main
165 sys.modules['__main__'] = _main
166 self.assertTrue(isinstance(res, bytes))
166 self.assertTrue(isinstance(res, bytes))
167
167
168 def test_global_ns(self):
168 def test_global_ns(self):
169 "Code in functions must be able to access variables outside them."
169 "Code in functions must be able to access variables outside them."
170 ip = get_ipython()
170 ip = get_ipython()
171 ip.run_cell("a = 10")
171 ip.run_cell("a = 10")
172 ip.run_cell(("def f(x):\n"
172 ip.run_cell(("def f(x):\n"
173 " return x + a"))
173 " return x + a"))
174 ip.run_cell("b = f(12)")
174 ip.run_cell("b = f(12)")
175 self.assertEqual(ip.user_ns["b"], 22)
175 self.assertEqual(ip.user_ns["b"], 22)
176
176
177 def test_bad_custom_tb(self):
177 def test_bad_custom_tb(self):
178 """Check that InteractiveShell is protected from bad custom exception handlers"""
178 """Check that InteractiveShell is protected from bad custom exception handlers"""
179 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
179 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
180 self.assertEqual(ip.custom_exceptions, (IOError,))
180 self.assertEqual(ip.custom_exceptions, (IOError,))
181 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
181 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
182 ip.run_cell(u'raise IOError("foo")')
182 ip.run_cell(u'raise IOError("foo")')
183 self.assertEqual(ip.custom_exceptions, ())
183 self.assertEqual(ip.custom_exceptions, ())
184
184
185 def test_bad_custom_tb_return(self):
185 def test_bad_custom_tb_return(self):
186 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
186 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
187 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
187 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
188 self.assertEqual(ip.custom_exceptions, (NameError,))
188 self.assertEqual(ip.custom_exceptions, (NameError,))
189 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
189 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
190 ip.run_cell(u'a=abracadabra')
190 ip.run_cell(u'a=abracadabra')
191 self.assertEqual(ip.custom_exceptions, ())
191 self.assertEqual(ip.custom_exceptions, ())
192
192
193 def test_drop_by_id(self):
193 def test_drop_by_id(self):
194 myvars = {"a":object(), "b":object(), "c": object()}
194 myvars = {"a":object(), "b":object(), "c": object()}
195 ip.push(myvars, interactive=False)
195 ip.push(myvars, interactive=False)
196 for name in myvars:
196 for name in myvars:
197 assert name in ip.user_ns, name
197 assert name in ip.user_ns, name
198 assert name in ip.user_ns_hidden, name
198 assert name in ip.user_ns_hidden, name
199 ip.user_ns['b'] = 12
199 ip.user_ns['b'] = 12
200 ip.drop_by_id(myvars)
200 ip.drop_by_id(myvars)
201 for name in ["a", "c"]:
201 for name in ["a", "c"]:
202 assert name not in ip.user_ns, name
202 assert name not in ip.user_ns, name
203 assert name not in ip.user_ns_hidden, name
203 assert name not in ip.user_ns_hidden, name
204 assert ip.user_ns['b'] == 12
204 assert ip.user_ns['b'] == 12
205 ip.reset()
205 ip.reset()
206
206
207 def test_var_expand(self):
207 def test_var_expand(self):
208 ip.user_ns['f'] = u'Ca\xf1o'
208 ip.user_ns['f'] = u'Ca\xf1o'
209 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
209 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
210 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
210 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
211 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
211 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
212 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
212 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
213
213
214 self.assertEqual(ip.var_expand(u"grep x | awk '{print $1}'"), u"grep x | awk '{print $1}'")
214 self.assertEqual(ip.var_expand(u"grep x | awk '{print $1}'"), u"grep x | awk '{print $1}'")
215
215
216 ip.user_ns['f'] = b'Ca\xc3\xb1o'
216 ip.user_ns['f'] = b'Ca\xc3\xb1o'
217 # This should not raise any exception:
217 # This should not raise any exception:
218 ip.var_expand(u'echo $f')
218 ip.var_expand(u'echo $f')
219
219
220 def test_var_expand_local(self):
220 def test_var_expand_local(self):
221 """Test local variable expansion in !system and %magic calls"""
221 """Test local variable expansion in !system and %magic calls"""
222 # !system
222 # !system
223 ip.run_cell('def test():\n'
223 ip.run_cell('def test():\n'
224 ' lvar = "ttt"\n'
224 ' lvar = "ttt"\n'
225 ' ret = !echo {lvar}\n'
225 ' ret = !echo {lvar}\n'
226 ' return ret[0]\n')
226 ' return ret[0]\n')
227 res = ip.user_ns['test']()
227 res = ip.user_ns['test']()
228 nt.assert_in('ttt', res)
228 nt.assert_in('ttt', res)
229
229
230 # %magic
230 # %magic
231 ip.run_cell('def makemacro():\n'
231 ip.run_cell('def makemacro():\n'
232 ' macroname = "macro_var_expand_locals"\n'
232 ' macroname = "macro_var_expand_locals"\n'
233 ' %macro {macroname} codestr\n')
233 ' %macro {macroname} codestr\n')
234 ip.user_ns['codestr'] = "str(12)"
234 ip.user_ns['codestr'] = "str(12)"
235 ip.run_cell('makemacro()')
235 ip.run_cell('makemacro()')
236 nt.assert_in('macro_var_expand_locals', ip.user_ns)
236 nt.assert_in('macro_var_expand_locals', ip.user_ns)
237
237
238 def test_var_expand_self(self):
238 def test_var_expand_self(self):
239 """Test variable expansion with the name 'self', which was failing.
239 """Test variable expansion with the name 'self', which was failing.
240
240
241 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
241 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
242 """
242 """
243 ip.run_cell('class cTest:\n'
243 ip.run_cell('class cTest:\n'
244 ' classvar="see me"\n'
244 ' classvar="see me"\n'
245 ' def test(self):\n'
245 ' def test(self):\n'
246 ' res = !echo Variable: {self.classvar}\n'
246 ' res = !echo Variable: {self.classvar}\n'
247 ' return res[0]\n')
247 ' return res[0]\n')
248 nt.assert_in('see me', ip.user_ns['cTest']().test())
248 nt.assert_in('see me', ip.user_ns['cTest']().test())
249
249
250 def test_bad_var_expand(self):
250 def test_bad_var_expand(self):
251 """var_expand on invalid formats shouldn't raise"""
251 """var_expand on invalid formats shouldn't raise"""
252 # SyntaxError
252 # SyntaxError
253 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
253 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
254 # NameError
254 # NameError
255 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
255 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
256 # ZeroDivisionError
256 # ZeroDivisionError
257 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
257 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
258
258
259 def test_silent_postexec(self):
259 def test_silent_postexec(self):
260 """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks"""
260 """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks"""
261 pre_explicit = mock.Mock()
261 pre_explicit = mock.Mock()
262 pre_always = mock.Mock()
262 pre_always = mock.Mock()
263 post_explicit = mock.Mock()
263 post_explicit = mock.Mock()
264 post_always = mock.Mock()
264 post_always = mock.Mock()
265 all_mocks = [pre_explicit, pre_always, post_explicit, post_always]
265 all_mocks = [pre_explicit, pre_always, post_explicit, post_always]
266
266
267 ip.events.register('pre_run_cell', pre_explicit)
267 ip.events.register('pre_run_cell', pre_explicit)
268 ip.events.register('pre_execute', pre_always)
268 ip.events.register('pre_execute', pre_always)
269 ip.events.register('post_run_cell', post_explicit)
269 ip.events.register('post_run_cell', post_explicit)
270 ip.events.register('post_execute', post_always)
270 ip.events.register('post_execute', post_always)
271
271
272 try:
272 try:
273 ip.run_cell("1", silent=True)
273 ip.run_cell("1", silent=True)
274 assert pre_always.called
274 assert pre_always.called
275 assert not pre_explicit.called
275 assert not pre_explicit.called
276 assert post_always.called
276 assert post_always.called
277 assert not post_explicit.called
277 assert not post_explicit.called
278 # double-check that non-silent exec did what we expected
278 # double-check that non-silent exec did what we expected
279 # silent to avoid
279 # silent to avoid
280 ip.run_cell("1")
280 ip.run_cell("1")
281 assert pre_explicit.called
281 assert pre_explicit.called
282 assert post_explicit.called
282 assert post_explicit.called
283 info, = pre_explicit.call_args[0]
283 info, = pre_explicit.call_args[0]
284 result, = post_explicit.call_args[0]
284 result, = post_explicit.call_args[0]
285 self.assertEqual(info, result.info)
285 self.assertEqual(info, result.info)
286 # check that post hooks are always called
286 # check that post hooks are always called
287 [m.reset_mock() for m in all_mocks]
287 [m.reset_mock() for m in all_mocks]
288 ip.run_cell("syntax error")
288 ip.run_cell("syntax error")
289 assert pre_always.called
289 assert pre_always.called
290 assert pre_explicit.called
290 assert pre_explicit.called
291 assert post_always.called
291 assert post_always.called
292 assert post_explicit.called
292 assert post_explicit.called
293 info, = pre_explicit.call_args[0]
293 info, = pre_explicit.call_args[0]
294 result, = post_explicit.call_args[0]
294 result, = post_explicit.call_args[0]
295 self.assertEqual(info, result.info)
295 self.assertEqual(info, result.info)
296 finally:
296 finally:
297 # remove post-exec
297 # remove post-exec
298 ip.events.unregister('pre_run_cell', pre_explicit)
298 ip.events.unregister('pre_run_cell', pre_explicit)
299 ip.events.unregister('pre_execute', pre_always)
299 ip.events.unregister('pre_execute', pre_always)
300 ip.events.unregister('post_run_cell', post_explicit)
300 ip.events.unregister('post_run_cell', post_explicit)
301 ip.events.unregister('post_execute', post_always)
301 ip.events.unregister('post_execute', post_always)
302
302
303 def test_silent_noadvance(self):
303 def test_silent_noadvance(self):
304 """run_cell(silent=True) doesn't advance execution_count"""
304 """run_cell(silent=True) doesn't advance execution_count"""
305 ec = ip.execution_count
305 ec = ip.execution_count
306 # silent should force store_history=False
306 # silent should force store_history=False
307 ip.run_cell("1", store_history=True, silent=True)
307 ip.run_cell("1", store_history=True, silent=True)
308
308
309 self.assertEqual(ec, ip.execution_count)
309 self.assertEqual(ec, ip.execution_count)
310 # double-check that non-silent exec did what we expected
310 # double-check that non-silent exec did what we expected
311 # silent to avoid
311 # silent to avoid
312 ip.run_cell("1", store_history=True)
312 ip.run_cell("1", store_history=True)
313 self.assertEqual(ec+1, ip.execution_count)
313 self.assertEqual(ec+1, ip.execution_count)
314
314
315 def test_silent_nodisplayhook(self):
315 def test_silent_nodisplayhook(self):
316 """run_cell(silent=True) doesn't trigger displayhook"""
316 """run_cell(silent=True) doesn't trigger displayhook"""
317 d = dict(called=False)
317 d = dict(called=False)
318
318
319 trap = ip.display_trap
319 trap = ip.display_trap
320 save_hook = trap.hook
320 save_hook = trap.hook
321
321
322 def failing_hook(*args, **kwargs):
322 def failing_hook(*args, **kwargs):
323 d['called'] = True
323 d['called'] = True
324
324
325 try:
325 try:
326 trap.hook = failing_hook
326 trap.hook = failing_hook
327 res = ip.run_cell("1", silent=True)
327 res = ip.run_cell("1", silent=True)
328 self.assertFalse(d['called'])
328 self.assertFalse(d['called'])
329 self.assertIsNone(res.result)
329 self.assertIsNone(res.result)
330 # double-check that non-silent exec did what we expected
330 # double-check that non-silent exec did what we expected
331 # silent to avoid
331 # silent to avoid
332 ip.run_cell("1")
332 ip.run_cell("1")
333 self.assertTrue(d['called'])
333 self.assertTrue(d['called'])
334 finally:
334 finally:
335 trap.hook = save_hook
335 trap.hook = save_hook
336
336
337 def test_ofind_line_magic(self):
337 def test_ofind_line_magic(self):
338 from IPython.core.magic import register_line_magic
338 from IPython.core.magic import register_line_magic
339
339
340 @register_line_magic
340 @register_line_magic
341 def lmagic(line):
341 def lmagic(line):
342 "A line magic"
342 "A line magic"
343
343
344 # Get info on line magic
344 # Get info on line magic
345 lfind = ip._ofind('lmagic')
345 lfind = ip._ofind('lmagic')
346 info = dict(found=True, isalias=False, ismagic=True,
346 info = dict(found=True, isalias=False, ismagic=True,
347 namespace = 'IPython internal', obj= lmagic.__wrapped__,
347 namespace = 'IPython internal', obj= lmagic.__wrapped__,
348 parent = None)
348 parent = None)
349 nt.assert_equal(lfind, info)
349 nt.assert_equal(lfind, info)
350
350
351 def test_ofind_cell_magic(self):
351 def test_ofind_cell_magic(self):
352 from IPython.core.magic import register_cell_magic
352 from IPython.core.magic import register_cell_magic
353
353
354 @register_cell_magic
354 @register_cell_magic
355 def cmagic(line, cell):
355 def cmagic(line, cell):
356 "A cell magic"
356 "A cell magic"
357
357
358 # Get info on cell magic
358 # Get info on cell magic
359 find = ip._ofind('cmagic')
359 find = ip._ofind('cmagic')
360 info = dict(found=True, isalias=False, ismagic=True,
360 info = dict(found=True, isalias=False, ismagic=True,
361 namespace = 'IPython internal', obj= cmagic.__wrapped__,
361 namespace = 'IPython internal', obj= cmagic.__wrapped__,
362 parent = None)
362 parent = None)
363 nt.assert_equal(find, info)
363 nt.assert_equal(find, info)
364
364
365 def test_ofind_property_with_error(self):
365 def test_ofind_property_with_error(self):
366 class A(object):
366 class A(object):
367 @property
367 @property
368 def foo(self):
368 def foo(self):
369 raise NotImplementedError()
369 raise NotImplementedError()
370 a = A()
370 a = A()
371
371
372 found = ip._ofind('a.foo', [('locals', locals())])
372 found = ip._ofind('a.foo', [('locals', locals())])
373 info = dict(found=True, isalias=False, ismagic=False,
373 info = dict(found=True, isalias=False, ismagic=False,
374 namespace='locals', obj=A.foo, parent=a)
374 namespace='locals', obj=A.foo, parent=a)
375 nt.assert_equal(found, info)
375 nt.assert_equal(found, info)
376
376
377 def test_ofind_multiple_attribute_lookups(self):
377 def test_ofind_multiple_attribute_lookups(self):
378 class A(object):
378 class A(object):
379 @property
379 @property
380 def foo(self):
380 def foo(self):
381 raise NotImplementedError()
381 raise NotImplementedError()
382
382
383 a = A()
383 a = A()
384 a.a = A()
384 a.a = A()
385 a.a.a = A()
385 a.a.a = A()
386
386
387 found = ip._ofind('a.a.a.foo', [('locals', locals())])
387 found = ip._ofind('a.a.a.foo', [('locals', locals())])
388 info = dict(found=True, isalias=False, ismagic=False,
388 info = dict(found=True, isalias=False, ismagic=False,
389 namespace='locals', obj=A.foo, parent=a.a.a)
389 namespace='locals', obj=A.foo, parent=a.a.a)
390 nt.assert_equal(found, info)
390 nt.assert_equal(found, info)
391
391
392 def test_ofind_slotted_attributes(self):
392 def test_ofind_slotted_attributes(self):
393 class A(object):
393 class A(object):
394 __slots__ = ['foo']
394 __slots__ = ['foo']
395 def __init__(self):
395 def __init__(self):
396 self.foo = 'bar'
396 self.foo = 'bar'
397
397
398 a = A()
398 a = A()
399 found = ip._ofind('a.foo', [('locals', locals())])
399 found = ip._ofind('a.foo', [('locals', locals())])
400 info = dict(found=True, isalias=False, ismagic=False,
400 info = dict(found=True, isalias=False, ismagic=False,
401 namespace='locals', obj=a.foo, parent=a)
401 namespace='locals', obj=a.foo, parent=a)
402 nt.assert_equal(found, info)
402 nt.assert_equal(found, info)
403
403
404 found = ip._ofind('a.bar', [('locals', locals())])
404 found = ip._ofind('a.bar', [('locals', locals())])
405 info = dict(found=False, isalias=False, ismagic=False,
405 info = dict(found=False, isalias=False, ismagic=False,
406 namespace=None, obj=None, parent=a)
406 namespace=None, obj=None, parent=a)
407 nt.assert_equal(found, info)
407 nt.assert_equal(found, info)
408
408
409 def test_ofind_prefers_property_to_instance_level_attribute(self):
409 def test_ofind_prefers_property_to_instance_level_attribute(self):
410 class A(object):
410 class A(object):
411 @property
411 @property
412 def foo(self):
412 def foo(self):
413 return 'bar'
413 return 'bar'
414 a = A()
414 a = A()
415 a.__dict__['foo'] = 'baz'
415 a.__dict__['foo'] = 'baz'
416 nt.assert_equal(a.foo, 'bar')
416 nt.assert_equal(a.foo, 'bar')
417 found = ip._ofind('a.foo', [('locals', locals())])
417 found = ip._ofind('a.foo', [('locals', locals())])
418 nt.assert_is(found['obj'], A.foo)
418 nt.assert_is(found['obj'], A.foo)
419
419
420 def test_custom_syntaxerror_exception(self):
420 def test_custom_syntaxerror_exception(self):
421 called = []
421 called = []
422 def my_handler(shell, etype, value, tb, tb_offset=None):
422 def my_handler(shell, etype, value, tb, tb_offset=None):
423 called.append(etype)
423 called.append(etype)
424 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
424 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
425
425
426 ip.set_custom_exc((SyntaxError,), my_handler)
426 ip.set_custom_exc((SyntaxError,), my_handler)
427 try:
427 try:
428 ip.run_cell("1f")
428 ip.run_cell("1f")
429 # Check that this was called, and only once.
429 # Check that this was called, and only once.
430 self.assertEqual(called, [SyntaxError])
430 self.assertEqual(called, [SyntaxError])
431 finally:
431 finally:
432 # Reset the custom exception hook
432 # Reset the custom exception hook
433 ip.set_custom_exc((), None)
433 ip.set_custom_exc((), None)
434
434
435 def test_custom_exception(self):
435 def test_custom_exception(self):
436 called = []
436 called = []
437 def my_handler(shell, etype, value, tb, tb_offset=None):
437 def my_handler(shell, etype, value, tb, tb_offset=None):
438 called.append(etype)
438 called.append(etype)
439 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
439 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
440
440
441 ip.set_custom_exc((ValueError,), my_handler)
441 ip.set_custom_exc((ValueError,), my_handler)
442 try:
442 try:
443 res = ip.run_cell("raise ValueError('test')")
443 res = ip.run_cell("raise ValueError('test')")
444 # Check that this was called, and only once.
444 # Check that this was called, and only once.
445 self.assertEqual(called, [ValueError])
445 self.assertEqual(called, [ValueError])
446 # Check that the error is on the result object
446 # Check that the error is on the result object
447 self.assertIsInstance(res.error_in_exec, ValueError)
447 self.assertIsInstance(res.error_in_exec, ValueError)
448 finally:
448 finally:
449 # Reset the custom exception hook
449 # Reset the custom exception hook
450 ip.set_custom_exc((), None)
450 ip.set_custom_exc((), None)
451
451
452 def test_mktempfile(self):
452 def test_mktempfile(self):
453 filename = ip.mktempfile()
453 filename = ip.mktempfile()
454 # Check that we can open the file again on Windows
454 # Check that we can open the file again on Windows
455 with open(filename, 'w') as f:
455 with open(filename, 'w') as f:
456 f.write('abc')
456 f.write('abc')
457
457
458 filename = ip.mktempfile(data='blah')
458 filename = ip.mktempfile(data='blah')
459 with open(filename, 'r') as f:
459 with open(filename, 'r') as f:
460 self.assertEqual(f.read(), 'blah')
460 self.assertEqual(f.read(), 'blah')
461
461
462 def test_new_main_mod(self):
462 def test_new_main_mod(self):
463 # Smoketest to check that this accepts a unicode module name
463 # Smoketest to check that this accepts a unicode module name
464 name = u'jiefmw'
464 name = u'jiefmw'
465 mod = ip.new_main_mod(u'%s.py' % name, name)
465 mod = ip.new_main_mod(u'%s.py' % name, name)
466 self.assertEqual(mod.__name__, name)
466 self.assertEqual(mod.__name__, name)
467
467
468 def test_get_exception_only(self):
468 def test_get_exception_only(self):
469 try:
469 try:
470 raise KeyboardInterrupt
470 raise KeyboardInterrupt
471 except KeyboardInterrupt:
471 except KeyboardInterrupt:
472 msg = ip.get_exception_only()
472 msg = ip.get_exception_only()
473 self.assertEqual(msg, 'KeyboardInterrupt\n')
473 self.assertEqual(msg, 'KeyboardInterrupt\n')
474
474
475 try:
475 try:
476 raise DerivedInterrupt("foo")
476 raise DerivedInterrupt("foo")
477 except KeyboardInterrupt:
477 except KeyboardInterrupt:
478 msg = ip.get_exception_only()
478 msg = ip.get_exception_only()
479 self.assertEqual(msg, 'IPython.core.tests.test_interactiveshell.DerivedInterrupt: foo\n')
479 self.assertEqual(msg, 'IPython.core.tests.test_interactiveshell.DerivedInterrupt: foo\n')
480
480
481 def test_inspect_text(self):
481 def test_inspect_text(self):
482 ip.run_cell('a = 5')
482 ip.run_cell('a = 5')
483 text = ip.object_inspect_text('a')
483 text = ip.object_inspect_text('a')
484 self.assertIsInstance(text, str)
484 self.assertIsInstance(text, str)
485
485
486 def test_last_execution_result(self):
486 def test_last_execution_result(self):
487 """ Check that last execution result gets set correctly (GH-10702) """
487 """ Check that last execution result gets set correctly (GH-10702) """
488 result = ip.run_cell('a = 5; a')
488 result = ip.run_cell('a = 5; a')
489 self.assertTrue(ip.last_execution_succeeded)
489 self.assertTrue(ip.last_execution_succeeded)
490 self.assertEqual(ip.last_execution_result.result, 5)
490 self.assertEqual(ip.last_execution_result.result, 5)
491
491
492 result = ip.run_cell('a = x_invalid_id_x')
492 result = ip.run_cell('a = x_invalid_id_x')
493 self.assertFalse(ip.last_execution_succeeded)
493 self.assertFalse(ip.last_execution_succeeded)
494 self.assertFalse(ip.last_execution_result.success)
494 self.assertFalse(ip.last_execution_result.success)
495 self.assertIsInstance(ip.last_execution_result.error_in_exec, NameError)
495 self.assertIsInstance(ip.last_execution_result.error_in_exec, NameError)
496
496
497 def test_reset_aliasing(self):
497 def test_reset_aliasing(self):
498 """ Check that standard posix aliases work after %reset. """
498 """ Check that standard posix aliases work after %reset. """
499 if os.name != 'posix':
499 if os.name != 'posix':
500 return
500 return
501
501
502 ip.reset()
502 ip.reset()
503 for cmd in ('clear', 'more', 'less', 'man'):
503 for cmd in ('clear', 'more', 'less', 'man'):
504 res = ip.run_cell('%' + cmd)
504 res = ip.run_cell('%' + cmd)
505 self.assertEqual(res.success, True)
505 self.assertEqual(res.success, True)
506
506
507
507
508 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
508 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
509
509
510 @onlyif_unicode_paths
510 @onlyif_unicode_paths
511 def setUp(self):
511 def setUp(self):
512 self.BASETESTDIR = tempfile.mkdtemp()
512 self.BASETESTDIR = tempfile.mkdtemp()
513 self.TESTDIR = join(self.BASETESTDIR, u"åäö")
513 self.TESTDIR = join(self.BASETESTDIR, u"åäö")
514 os.mkdir(self.TESTDIR)
514 os.mkdir(self.TESTDIR)
515 with open(join(self.TESTDIR, u"åäötestscript.py"), "w") as sfile:
515 with open(join(self.TESTDIR, u"åäötestscript.py"), "w") as sfile:
516 sfile.write("pass\n")
516 sfile.write("pass\n")
517 self.oldpath = os.getcwd()
517 self.oldpath = os.getcwd()
518 os.chdir(self.TESTDIR)
518 os.chdir(self.TESTDIR)
519 self.fname = u"åäötestscript.py"
519 self.fname = u"åäötestscript.py"
520
520
521 def tearDown(self):
521 def tearDown(self):
522 os.chdir(self.oldpath)
522 os.chdir(self.oldpath)
523 shutil.rmtree(self.BASETESTDIR)
523 shutil.rmtree(self.BASETESTDIR)
524
524
525 @onlyif_unicode_paths
525 @onlyif_unicode_paths
526 def test_1(self):
526 def test_1(self):
527 """Test safe_execfile with non-ascii path
527 """Test safe_execfile with non-ascii path
528 """
528 """
529 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
529 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
530
530
531 class ExitCodeChecks(tt.TempFileMixin):
531 class ExitCodeChecks(tt.TempFileMixin):
532
532
533 def setUp(self):
533 def setUp(self):
534 self.system = ip.system_raw
534 self.system = ip.system_raw
535
535
536 def test_exit_code_ok(self):
536 def test_exit_code_ok(self):
537 self.system('exit 0')
537 self.system('exit 0')
538 self.assertEqual(ip.user_ns['_exit_code'], 0)
538 self.assertEqual(ip.user_ns['_exit_code'], 0)
539
539
540 def test_exit_code_error(self):
540 def test_exit_code_error(self):
541 self.system('exit 1')
541 self.system('exit 1')
542 self.assertEqual(ip.user_ns['_exit_code'], 1)
542 self.assertEqual(ip.user_ns['_exit_code'], 1)
543
543
544 @skipif(not hasattr(signal, 'SIGALRM'))
544 @skipif(not hasattr(signal, 'SIGALRM'))
545 def test_exit_code_signal(self):
545 def test_exit_code_signal(self):
546 self.mktmp("import signal, time\n"
546 self.mktmp("import signal, time\n"
547 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
547 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
548 "time.sleep(1)\n")
548 "time.sleep(1)\n")
549 self.system("%s %s" % (sys.executable, self.fname))
549 self.system("%s %s" % (sys.executable, self.fname))
550 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
550 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
551
551
552 @onlyif_cmds_exist("csh")
552 @onlyif_cmds_exist("csh")
553 def test_exit_code_signal_csh(self):
553 def test_exit_code_signal_csh(self):
554 SHELL = os.environ.get('SHELL', None)
554 SHELL = os.environ.get('SHELL', None)
555 os.environ['SHELL'] = find_cmd("csh")
555 os.environ['SHELL'] = find_cmd("csh")
556 try:
556 try:
557 self.test_exit_code_signal()
557 self.test_exit_code_signal()
558 finally:
558 finally:
559 if SHELL is not None:
559 if SHELL is not None:
560 os.environ['SHELL'] = SHELL
560 os.environ['SHELL'] = SHELL
561 else:
561 else:
562 del os.environ['SHELL']
562 del os.environ['SHELL']
563
563
564
564
565 class TestSystemRaw(ExitCodeChecks):
565 class TestSystemRaw(ExitCodeChecks):
566
566
567 def setUp(self):
567 def setUp(self):
568 super().setUp()
568 super().setUp()
569 self.sytem = ip.system_raw
569 self.system = ip.system_raw
570
570
571 @onlyif_unicode_paths
571 @onlyif_unicode_paths
572 def test_1(self):
572 def test_1(self):
573 """Test system_raw with non-ascii cmd
573 """Test system_raw with non-ascii cmd
574 """
574 """
575 cmd = u'''python -c "'åäö'" '''
575 cmd = u'''python -c "'åäö'" '''
576 ip.system_raw(cmd)
576 ip.system_raw(cmd)
577
577
578 @mock.patch('subprocess.call', side_effect=KeyboardInterrupt)
578 @mock.patch('subprocess.call', side_effect=KeyboardInterrupt)
579 @mock.patch('os.system', side_effect=KeyboardInterrupt)
579 @mock.patch('os.system', side_effect=KeyboardInterrupt)
580 def test_control_c(self, *mocks):
580 def test_control_c(self, *mocks):
581 try:
581 try:
582 self.system("sleep 1 # wont happen")
582 self.system("sleep 1 # wont happen")
583 except KeyboardInterrupt:
583 except KeyboardInterrupt:
584 self.fail("system call should intercept "
584 self.fail("system call should intercept "
585 "keyboard interrupt from subprocess.call")
585 "keyboard interrupt from subprocess.call")
586 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGINT)
586 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGINT)
587
587
588 # TODO: Exit codes are currently ignored on Windows.
588 # TODO: Exit codes are currently ignored on Windows.
589 class TestSystemPipedExitCode(ExitCodeChecks):
589 class TestSystemPipedExitCode(ExitCodeChecks):
590
590
591 def setUp(self):
591 def setUp(self):
592 super().setUp()
592 super().setUp()
593 self.sytem = ip.system_piped
593 self.system = ip.system_piped
594
594
595 @skip_win32
595 @skip_win32
596 def test_exit_code_ok(self):
596 def test_exit_code_ok(self):
597 ExitCodeChecks.test_exit_code_ok(self)
597 ExitCodeChecks.test_exit_code_ok(self)
598
598
599 @skip_win32
599 @skip_win32
600 def test_exit_code_error(self):
600 def test_exit_code_error(self):
601 ExitCodeChecks.test_exit_code_error(self)
601 ExitCodeChecks.test_exit_code_error(self)
602
602
603 @skip_win32
603 @skip_win32
604 def test_exit_code_signal(self):
604 def test_exit_code_signal(self):
605 ExitCodeChecks.test_exit_code_signal(self)
605 ExitCodeChecks.test_exit_code_signal(self)
606
606
607 class TestModules(tt.TempFileMixin):
607 class TestModules(tt.TempFileMixin):
608 def test_extraneous_loads(self):
608 def test_extraneous_loads(self):
609 """Test we're not loading modules on startup that we shouldn't.
609 """Test we're not loading modules on startup that we shouldn't.
610 """
610 """
611 self.mktmp("import sys\n"
611 self.mktmp("import sys\n"
612 "print('numpy' in sys.modules)\n"
612 "print('numpy' in sys.modules)\n"
613 "print('ipyparallel' in sys.modules)\n"
613 "print('ipyparallel' in sys.modules)\n"
614 "print('ipykernel' in sys.modules)\n"
614 "print('ipykernel' in sys.modules)\n"
615 )
615 )
616 out = "False\nFalse\nFalse\n"
616 out = "False\nFalse\nFalse\n"
617 tt.ipexec_validate(self.fname, out)
617 tt.ipexec_validate(self.fname, out)
618
618
619 class Negator(ast.NodeTransformer):
619 class Negator(ast.NodeTransformer):
620 """Negates all number literals in an AST."""
620 """Negates all number literals in an AST."""
621
621
622 # for python 3.7 and earlier
622 # for python 3.7 and earlier
623 def visit_Num(self, node):
623 def visit_Num(self, node):
624 node.n = -node.n
624 node.n = -node.n
625 return node
625 return node
626
626
627 # for python 3.8+
627 # for python 3.8+
628 def visit_Constant(self, node):
628 def visit_Constant(self, node):
629 if isinstance(node.value, int):
629 if isinstance(node.value, int):
630 return self.visit_Num(node)
630 return self.visit_Num(node)
631 return node
631 return node
632
632
633 class TestAstTransform(unittest.TestCase):
633 class TestAstTransform(unittest.TestCase):
634 def setUp(self):
634 def setUp(self):
635 self.negator = Negator()
635 self.negator = Negator()
636 ip.ast_transformers.append(self.negator)
636 ip.ast_transformers.append(self.negator)
637
637
638 def tearDown(self):
638 def tearDown(self):
639 ip.ast_transformers.remove(self.negator)
639 ip.ast_transformers.remove(self.negator)
640
640
641 def test_run_cell(self):
641 def test_run_cell(self):
642 with tt.AssertPrints('-34'):
642 with tt.AssertPrints('-34'):
643 ip.run_cell('print (12 + 22)')
643 ip.run_cell('print (12 + 22)')
644
644
645 # A named reference to a number shouldn't be transformed.
645 # A named reference to a number shouldn't be transformed.
646 ip.user_ns['n'] = 55
646 ip.user_ns['n'] = 55
647 with tt.AssertNotPrints('-55'):
647 with tt.AssertNotPrints('-55'):
648 ip.run_cell('print (n)')
648 ip.run_cell('print (n)')
649
649
650 def test_timeit(self):
650 def test_timeit(self):
651 called = set()
651 called = set()
652 def f(x):
652 def f(x):
653 called.add(x)
653 called.add(x)
654 ip.push({'f':f})
654 ip.push({'f':f})
655
655
656 with tt.AssertPrints("std. dev. of"):
656 with tt.AssertPrints("std. dev. of"):
657 ip.run_line_magic("timeit", "-n1 f(1)")
657 ip.run_line_magic("timeit", "-n1 f(1)")
658 self.assertEqual(called, {-1})
658 self.assertEqual(called, {-1})
659 called.clear()
659 called.clear()
660
660
661 with tt.AssertPrints("std. dev. of"):
661 with tt.AssertPrints("std. dev. of"):
662 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
662 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
663 self.assertEqual(called, {-2, -3})
663 self.assertEqual(called, {-2, -3})
664
664
665 def test_time(self):
665 def test_time(self):
666 called = []
666 called = []
667 def f(x):
667 def f(x):
668 called.append(x)
668 called.append(x)
669 ip.push({'f':f})
669 ip.push({'f':f})
670
670
671 # Test with an expression
671 # Test with an expression
672 with tt.AssertPrints("Wall time: "):
672 with tt.AssertPrints("Wall time: "):
673 ip.run_line_magic("time", "f(5+9)")
673 ip.run_line_magic("time", "f(5+9)")
674 self.assertEqual(called, [-14])
674 self.assertEqual(called, [-14])
675 called[:] = []
675 called[:] = []
676
676
677 # Test with a statement (different code path)
677 # Test with a statement (different code path)
678 with tt.AssertPrints("Wall time: "):
678 with tt.AssertPrints("Wall time: "):
679 ip.run_line_magic("time", "a = f(-3 + -2)")
679 ip.run_line_magic("time", "a = f(-3 + -2)")
680 self.assertEqual(called, [5])
680 self.assertEqual(called, [5])
681
681
682 def test_macro(self):
682 def test_macro(self):
683 ip.push({'a':10})
683 ip.push({'a':10})
684 # The AST transformation makes this do a+=-1
684 # The AST transformation makes this do a+=-1
685 ip.define_macro("amacro", "a+=1\nprint(a)")
685 ip.define_macro("amacro", "a+=1\nprint(a)")
686
686
687 with tt.AssertPrints("9"):
687 with tt.AssertPrints("9"):
688 ip.run_cell("amacro")
688 ip.run_cell("amacro")
689 with tt.AssertPrints("8"):
689 with tt.AssertPrints("8"):
690 ip.run_cell("amacro")
690 ip.run_cell("amacro")
691
691
692 class IntegerWrapper(ast.NodeTransformer):
692 class IntegerWrapper(ast.NodeTransformer):
693 """Wraps all integers in a call to Integer()"""
693 """Wraps all integers in a call to Integer()"""
694
694
695 # for Python 3.7 and earlier
695 # for Python 3.7 and earlier
696
696
697 # for Python 3.7 and earlier
697 # for Python 3.7 and earlier
698 def visit_Num(self, node):
698 def visit_Num(self, node):
699 if isinstance(node.n, int):
699 if isinstance(node.n, int):
700 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
700 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
701 args=[node], keywords=[])
701 args=[node], keywords=[])
702 return node
702 return node
703
703
704 # For Python 3.8+
704 # For Python 3.8+
705 def visit_Constant(self, node):
705 def visit_Constant(self, node):
706 if isinstance(node.value, int):
706 if isinstance(node.value, int):
707 return self.visit_Num(node)
707 return self.visit_Num(node)
708 return node
708 return node
709
709
710
710
711 class TestAstTransform2(unittest.TestCase):
711 class TestAstTransform2(unittest.TestCase):
712 def setUp(self):
712 def setUp(self):
713 self.intwrapper = IntegerWrapper()
713 self.intwrapper = IntegerWrapper()
714 ip.ast_transformers.append(self.intwrapper)
714 ip.ast_transformers.append(self.intwrapper)
715
715
716 self.calls = []
716 self.calls = []
717 def Integer(*args):
717 def Integer(*args):
718 self.calls.append(args)
718 self.calls.append(args)
719 return args
719 return args
720 ip.push({"Integer": Integer})
720 ip.push({"Integer": Integer})
721
721
722 def tearDown(self):
722 def tearDown(self):
723 ip.ast_transformers.remove(self.intwrapper)
723 ip.ast_transformers.remove(self.intwrapper)
724 del ip.user_ns['Integer']
724 del ip.user_ns['Integer']
725
725
726 def test_run_cell(self):
726 def test_run_cell(self):
727 ip.run_cell("n = 2")
727 ip.run_cell("n = 2")
728 self.assertEqual(self.calls, [(2,)])
728 self.assertEqual(self.calls, [(2,)])
729
729
730 # This shouldn't throw an error
730 # This shouldn't throw an error
731 ip.run_cell("o = 2.0")
731 ip.run_cell("o = 2.0")
732 self.assertEqual(ip.user_ns['o'], 2.0)
732 self.assertEqual(ip.user_ns['o'], 2.0)
733
733
734 def test_timeit(self):
734 def test_timeit(self):
735 called = set()
735 called = set()
736 def f(x):
736 def f(x):
737 called.add(x)
737 called.add(x)
738 ip.push({'f':f})
738 ip.push({'f':f})
739
739
740 with tt.AssertPrints("std. dev. of"):
740 with tt.AssertPrints("std. dev. of"):
741 ip.run_line_magic("timeit", "-n1 f(1)")
741 ip.run_line_magic("timeit", "-n1 f(1)")
742 self.assertEqual(called, {(1,)})
742 self.assertEqual(called, {(1,)})
743 called.clear()
743 called.clear()
744
744
745 with tt.AssertPrints("std. dev. of"):
745 with tt.AssertPrints("std. dev. of"):
746 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
746 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
747 self.assertEqual(called, {(2,), (3,)})
747 self.assertEqual(called, {(2,), (3,)})
748
748
749 class ErrorTransformer(ast.NodeTransformer):
749 class ErrorTransformer(ast.NodeTransformer):
750 """Throws an error when it sees a number."""
750 """Throws an error when it sees a number."""
751
751
752 # for Python 3.7 and earlier
752 # for Python 3.7 and earlier
753 def visit_Num(self, node):
753 def visit_Num(self, node):
754 raise ValueError("test")
754 raise ValueError("test")
755
755
756 # for Python 3.8+
756 # for Python 3.8+
757 def visit_Constant(self, node):
757 def visit_Constant(self, node):
758 if isinstance(node.value, int):
758 if isinstance(node.value, int):
759 return self.visit_Num(node)
759 return self.visit_Num(node)
760 return node
760 return node
761
761
762
762
763 class TestAstTransformError(unittest.TestCase):
763 class TestAstTransformError(unittest.TestCase):
764 def test_unregistering(self):
764 def test_unregistering(self):
765 err_transformer = ErrorTransformer()
765 err_transformer = ErrorTransformer()
766 ip.ast_transformers.append(err_transformer)
766 ip.ast_transformers.append(err_transformer)
767
767
768 with self.assertWarnsRegex(UserWarning, "It will be unregistered"):
768 with self.assertWarnsRegex(UserWarning, "It will be unregistered"):
769 ip.run_cell("1 + 2")
769 ip.run_cell("1 + 2")
770
770
771 # This should have been removed.
771 # This should have been removed.
772 nt.assert_not_in(err_transformer, ip.ast_transformers)
772 nt.assert_not_in(err_transformer, ip.ast_transformers)
773
773
774
774
775 class StringRejector(ast.NodeTransformer):
775 class StringRejector(ast.NodeTransformer):
776 """Throws an InputRejected when it sees a string literal.
776 """Throws an InputRejected when it sees a string literal.
777
777
778 Used to verify that NodeTransformers can signal that a piece of code should
778 Used to verify that NodeTransformers can signal that a piece of code should
779 not be executed by throwing an InputRejected.
779 not be executed by throwing an InputRejected.
780 """
780 """
781
781
782 #for python 3.7 and earlier
782 #for python 3.7 and earlier
783 def visit_Str(self, node):
783 def visit_Str(self, node):
784 raise InputRejected("test")
784 raise InputRejected("test")
785
785
786 # 3.8 only
786 # 3.8 only
787 def visit_Constant(self, node):
787 def visit_Constant(self, node):
788 if isinstance(node.value, str):
788 if isinstance(node.value, str):
789 raise InputRejected("test")
789 raise InputRejected("test")
790 return node
790 return node
791
791
792
792
793 class TestAstTransformInputRejection(unittest.TestCase):
793 class TestAstTransformInputRejection(unittest.TestCase):
794
794
795 def setUp(self):
795 def setUp(self):
796 self.transformer = StringRejector()
796 self.transformer = StringRejector()
797 ip.ast_transformers.append(self.transformer)
797 ip.ast_transformers.append(self.transformer)
798
798
799 def tearDown(self):
799 def tearDown(self):
800 ip.ast_transformers.remove(self.transformer)
800 ip.ast_transformers.remove(self.transformer)
801
801
802 def test_input_rejection(self):
802 def test_input_rejection(self):
803 """Check that NodeTransformers can reject input."""
803 """Check that NodeTransformers can reject input."""
804
804
805 expect_exception_tb = tt.AssertPrints("InputRejected: test")
805 expect_exception_tb = tt.AssertPrints("InputRejected: test")
806 expect_no_cell_output = tt.AssertNotPrints("'unsafe'", suppress=False)
806 expect_no_cell_output = tt.AssertNotPrints("'unsafe'", suppress=False)
807
807
808 # Run the same check twice to verify that the transformer is not
808 # Run the same check twice to verify that the transformer is not
809 # disabled after raising.
809 # disabled after raising.
810 with expect_exception_tb, expect_no_cell_output:
810 with expect_exception_tb, expect_no_cell_output:
811 ip.run_cell("'unsafe'")
811 ip.run_cell("'unsafe'")
812
812
813 with expect_exception_tb, expect_no_cell_output:
813 with expect_exception_tb, expect_no_cell_output:
814 res = ip.run_cell("'unsafe'")
814 res = ip.run_cell("'unsafe'")
815
815
816 self.assertIsInstance(res.error_before_exec, InputRejected)
816 self.assertIsInstance(res.error_before_exec, InputRejected)
817
817
818 def test__IPYTHON__():
818 def test__IPYTHON__():
819 # This shouldn't raise a NameError, that's all
819 # This shouldn't raise a NameError, that's all
820 __IPYTHON__
820 __IPYTHON__
821
821
822
822
823 class DummyRepr(object):
823 class DummyRepr(object):
824 def __repr__(self):
824 def __repr__(self):
825 return "DummyRepr"
825 return "DummyRepr"
826
826
827 def _repr_html_(self):
827 def _repr_html_(self):
828 return "<b>dummy</b>"
828 return "<b>dummy</b>"
829
829
830 def _repr_javascript_(self):
830 def _repr_javascript_(self):
831 return "console.log('hi');", {'key': 'value'}
831 return "console.log('hi');", {'key': 'value'}
832
832
833
833
834 def test_user_variables():
834 def test_user_variables():
835 # enable all formatters
835 # enable all formatters
836 ip.display_formatter.active_types = ip.display_formatter.format_types
836 ip.display_formatter.active_types = ip.display_formatter.format_types
837
837
838 ip.user_ns['dummy'] = d = DummyRepr()
838 ip.user_ns['dummy'] = d = DummyRepr()
839 keys = {'dummy', 'doesnotexist'}
839 keys = {'dummy', 'doesnotexist'}
840 r = ip.user_expressions({ key:key for key in keys})
840 r = ip.user_expressions({ key:key for key in keys})
841
841
842 nt.assert_equal(keys, set(r.keys()))
842 nt.assert_equal(keys, set(r.keys()))
843 dummy = r['dummy']
843 dummy = r['dummy']
844 nt.assert_equal({'status', 'data', 'metadata'}, set(dummy.keys()))
844 nt.assert_equal({'status', 'data', 'metadata'}, set(dummy.keys()))
845 nt.assert_equal(dummy['status'], 'ok')
845 nt.assert_equal(dummy['status'], 'ok')
846 data = dummy['data']
846 data = dummy['data']
847 metadata = dummy['metadata']
847 metadata = dummy['metadata']
848 nt.assert_equal(data.get('text/html'), d._repr_html_())
848 nt.assert_equal(data.get('text/html'), d._repr_html_())
849 js, jsmd = d._repr_javascript_()
849 js, jsmd = d._repr_javascript_()
850 nt.assert_equal(data.get('application/javascript'), js)
850 nt.assert_equal(data.get('application/javascript'), js)
851 nt.assert_equal(metadata.get('application/javascript'), jsmd)
851 nt.assert_equal(metadata.get('application/javascript'), jsmd)
852
852
853 dne = r['doesnotexist']
853 dne = r['doesnotexist']
854 nt.assert_equal(dne['status'], 'error')
854 nt.assert_equal(dne['status'], 'error')
855 nt.assert_equal(dne['ename'], 'NameError')
855 nt.assert_equal(dne['ename'], 'NameError')
856
856
857 # back to text only
857 # back to text only
858 ip.display_formatter.active_types = ['text/plain']
858 ip.display_formatter.active_types = ['text/plain']
859
859
860 def test_user_expression():
860 def test_user_expression():
861 # enable all formatters
861 # enable all formatters
862 ip.display_formatter.active_types = ip.display_formatter.format_types
862 ip.display_formatter.active_types = ip.display_formatter.format_types
863 query = {
863 query = {
864 'a' : '1 + 2',
864 'a' : '1 + 2',
865 'b' : '1/0',
865 'b' : '1/0',
866 }
866 }
867 r = ip.user_expressions(query)
867 r = ip.user_expressions(query)
868 import pprint
868 import pprint
869 pprint.pprint(r)
869 pprint.pprint(r)
870 nt.assert_equal(set(r.keys()), set(query.keys()))
870 nt.assert_equal(set(r.keys()), set(query.keys()))
871 a = r['a']
871 a = r['a']
872 nt.assert_equal({'status', 'data', 'metadata'}, set(a.keys()))
872 nt.assert_equal({'status', 'data', 'metadata'}, set(a.keys()))
873 nt.assert_equal(a['status'], 'ok')
873 nt.assert_equal(a['status'], 'ok')
874 data = a['data']
874 data = a['data']
875 metadata = a['metadata']
875 metadata = a['metadata']
876 nt.assert_equal(data.get('text/plain'), '3')
876 nt.assert_equal(data.get('text/plain'), '3')
877
877
878 b = r['b']
878 b = r['b']
879 nt.assert_equal(b['status'], 'error')
879 nt.assert_equal(b['status'], 'error')
880 nt.assert_equal(b['ename'], 'ZeroDivisionError')
880 nt.assert_equal(b['ename'], 'ZeroDivisionError')
881
881
882 # back to text only
882 # back to text only
883 ip.display_formatter.active_types = ['text/plain']
883 ip.display_formatter.active_types = ['text/plain']
884
884
885
885
886 class TestSyntaxErrorTransformer(unittest.TestCase):
886 class TestSyntaxErrorTransformer(unittest.TestCase):
887 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
887 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
888
888
889 @staticmethod
889 @staticmethod
890 def transformer(lines):
890 def transformer(lines):
891 for line in lines:
891 for line in lines:
892 pos = line.find('syntaxerror')
892 pos = line.find('syntaxerror')
893 if pos >= 0:
893 if pos >= 0:
894 e = SyntaxError('input contains "syntaxerror"')
894 e = SyntaxError('input contains "syntaxerror"')
895 e.text = line
895 e.text = line
896 e.offset = pos + 1
896 e.offset = pos + 1
897 raise e
897 raise e
898 return lines
898 return lines
899
899
900 def setUp(self):
900 def setUp(self):
901 ip.input_transformers_post.append(self.transformer)
901 ip.input_transformers_post.append(self.transformer)
902
902
903 def tearDown(self):
903 def tearDown(self):
904 ip.input_transformers_post.remove(self.transformer)
904 ip.input_transformers_post.remove(self.transformer)
905
905
906 def test_syntaxerror_input_transformer(self):
906 def test_syntaxerror_input_transformer(self):
907 with tt.AssertPrints('1234'):
907 with tt.AssertPrints('1234'):
908 ip.run_cell('1234')
908 ip.run_cell('1234')
909 with tt.AssertPrints('SyntaxError: invalid syntax'):
909 with tt.AssertPrints('SyntaxError: invalid syntax'):
910 ip.run_cell('1 2 3') # plain python syntax error
910 ip.run_cell('1 2 3') # plain python syntax error
911 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
911 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
912 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
912 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
913 with tt.AssertPrints('3456'):
913 with tt.AssertPrints('3456'):
914 ip.run_cell('3456')
914 ip.run_cell('3456')
915
915
916
916
917 class TestWarningSupression(unittest.TestCase):
917 class TestWarningSuppression(unittest.TestCase):
918 def test_warning_suppression(self):
918 def test_warning_suppression(self):
919 ip.run_cell("import warnings")
919 ip.run_cell("import warnings")
920 try:
920 try:
921 with self.assertWarnsRegex(UserWarning, "asdf"):
921 with self.assertWarnsRegex(UserWarning, "asdf"):
922 ip.run_cell("warnings.warn('asdf')")
922 ip.run_cell("warnings.warn('asdf')")
923 # Here's the real test -- if we run that again, we should get the
923 # Here's the real test -- if we run that again, we should get the
924 # warning again. Traditionally, each warning was only issued once per
924 # warning again. Traditionally, each warning was only issued once per
925 # IPython session (approximately), even if the user typed in new and
925 # IPython session (approximately), even if the user typed in new and
926 # different code that should have also triggered the warning, leading
926 # different code that should have also triggered the warning, leading
927 # to much confusion.
927 # to much confusion.
928 with self.assertWarnsRegex(UserWarning, "asdf"):
928 with self.assertWarnsRegex(UserWarning, "asdf"):
929 ip.run_cell("warnings.warn('asdf')")
929 ip.run_cell("warnings.warn('asdf')")
930 finally:
930 finally:
931 ip.run_cell("del warnings")
931 ip.run_cell("del warnings")
932
932
933
933
934 def test_deprecation_warning(self):
934 def test_deprecation_warning(self):
935 ip.run_cell("""
935 ip.run_cell("""
936 import warnings
936 import warnings
937 def wrn():
937 def wrn():
938 warnings.warn(
938 warnings.warn(
939 "I AM A WARNING",
939 "I AM A WARNING",
940 DeprecationWarning
940 DeprecationWarning
941 )
941 )
942 """)
942 """)
943 try:
943 try:
944 with self.assertWarnsRegex(DeprecationWarning, "I AM A WARNING"):
944 with self.assertWarnsRegex(DeprecationWarning, "I AM A WARNING"):
945 ip.run_cell("wrn()")
945 ip.run_cell("wrn()")
946 finally:
946 finally:
947 ip.run_cell("del warnings")
947 ip.run_cell("del warnings")
948 ip.run_cell("del wrn")
948 ip.run_cell("del wrn")
949
949
950
950
951 class TestImportNoDeprecate(tt.TempFileMixin):
951 class TestImportNoDeprecate(tt.TempFileMixin):
952
952
953 def setUp(self):
953 def setUp(self):
954 """Make a valid python temp file."""
954 """Make a valid python temp file."""
955 self.mktmp("""
955 self.mktmp("""
956 import warnings
956 import warnings
957 def wrn():
957 def wrn():
958 warnings.warn(
958 warnings.warn(
959 "I AM A WARNING",
959 "I AM A WARNING",
960 DeprecationWarning
960 DeprecationWarning
961 )
961 )
962 """)
962 """)
963 super().setUp()
963 super().setUp()
964
964
965 def test_no_dep(self):
965 def test_no_dep(self):
966 """
966 """
967 No deprecation warning should be raised from imported functions
967 No deprecation warning should be raised from imported functions
968 """
968 """
969 ip.run_cell("from {} import wrn".format(self.fname))
969 ip.run_cell("from {} import wrn".format(self.fname))
970
970
971 with tt.AssertNotPrints("I AM A WARNING"):
971 with tt.AssertNotPrints("I AM A WARNING"):
972 ip.run_cell("wrn()")
972 ip.run_cell("wrn()")
973 ip.run_cell("del wrn")
973 ip.run_cell("del wrn")
974
974
975
975
976 def test_custom_exc_count():
976 def test_custom_exc_count():
977 hook = mock.Mock(return_value=None)
977 hook = mock.Mock(return_value=None)
978 ip.set_custom_exc((SyntaxError,), hook)
978 ip.set_custom_exc((SyntaxError,), hook)
979 before = ip.execution_count
979 before = ip.execution_count
980 ip.run_cell("def foo()", store_history=True)
980 ip.run_cell("def foo()", store_history=True)
981 # restore default excepthook
981 # restore default excepthook
982 ip.set_custom_exc((), None)
982 ip.set_custom_exc((), None)
983 nt.assert_equal(hook.call_count, 1)
983 nt.assert_equal(hook.call_count, 1)
984 nt.assert_equal(ip.execution_count, before + 1)
984 nt.assert_equal(ip.execution_count, before + 1)
985
985
986
986
987 def test_run_cell_async():
987 def test_run_cell_async():
988 loop = asyncio.get_event_loop()
988 loop = asyncio.get_event_loop()
989 ip.run_cell("import asyncio")
989 ip.run_cell("import asyncio")
990 coro = ip.run_cell_async("await asyncio.sleep(0.01)\n5")
990 coro = ip.run_cell_async("await asyncio.sleep(0.01)\n5")
991 assert asyncio.iscoroutine(coro)
991 assert asyncio.iscoroutine(coro)
992 result = loop.run_until_complete(coro)
992 result = loop.run_until_complete(coro)
993 assert isinstance(result, interactiveshell.ExecutionResult)
993 assert isinstance(result, interactiveshell.ExecutionResult)
994 assert result.result == 5
994 assert result.result == 5
995
995
996
996
997 def test_should_run_async():
997 def test_should_run_async():
998 assert not ip.should_run_async("a = 5")
998 assert not ip.should_run_async("a = 5")
999 assert ip.should_run_async("await x")
999 assert ip.should_run_async("await x")
1000 assert ip.should_run_async("import asyncio; await asyncio.sleep(1)")
1000 assert ip.should_run_async("import asyncio; await asyncio.sleep(1)")
@@ -1,329 +1,329 b''
1 """
1 """
2 This module contains factory functions that attempt
2 This module contains factory functions that attempt
3 to return Qt submodules from the various python Qt bindings.
3 to return Qt submodules from the various python Qt bindings.
4
4
5 It also protects against double-importing Qt with different
5 It also protects against double-importing Qt with different
6 bindings, which is unstable and likely to crash
6 bindings, which is unstable and likely to crash
7
7
8 This is used primarily by qt and qt_for_kernel, and shouldn't
8 This is used primarily by qt and qt_for_kernel, and shouldn't
9 be accessed directly from the outside
9 be accessed directly from the outside
10 """
10 """
11 import sys
11 import sys
12 import types
12 import types
13 from functools import partial
13 from functools import partial
14 from importlib import import_module
14 from importlib import import_module
15
15
16 from IPython.utils.version import check_version
16 from IPython.utils.version import check_version
17
17
18 # Available APIs.
18 # Available APIs.
19 QT_API_PYQT = 'pyqt' # Force version 2
19 QT_API_PYQT = 'pyqt' # Force version 2
20 QT_API_PYQT5 = 'pyqt5'
20 QT_API_PYQT5 = 'pyqt5'
21 QT_API_PYQTv1 = 'pyqtv1' # Force version 2
21 QT_API_PYQTv1 = 'pyqtv1' # Force version 2
22 QT_API_PYQT_DEFAULT = 'pyqtdefault' # use system default for version 1 vs. 2
22 QT_API_PYQT_DEFAULT = 'pyqtdefault' # use system default for version 1 vs. 2
23 QT_API_PYSIDE = 'pyside'
23 QT_API_PYSIDE = 'pyside'
24 QT_API_PYSIDE2 = 'pyside2'
24 QT_API_PYSIDE2 = 'pyside2'
25
25
26 api_to_module = {QT_API_PYSIDE2: 'PySide2',
26 api_to_module = {QT_API_PYSIDE2: 'PySide2',
27 QT_API_PYSIDE: 'PySide',
27 QT_API_PYSIDE: 'PySide',
28 QT_API_PYQT: 'PyQt4',
28 QT_API_PYQT: 'PyQt4',
29 QT_API_PYQTv1: 'PyQt4',
29 QT_API_PYQTv1: 'PyQt4',
30 QT_API_PYQT5: 'PyQt5',
30 QT_API_PYQT5: 'PyQt5',
31 QT_API_PYQT_DEFAULT: 'PyQt4',
31 QT_API_PYQT_DEFAULT: 'PyQt4',
32 }
32 }
33
33
34
34
35 class ImportDenier(object):
35 class ImportDenier(object):
36 """Import Hook that will guard against bad Qt imports
36 """Import Hook that will guard against bad Qt imports
37 once IPython commits to a specific binding
37 once IPython commits to a specific binding
38 """
38 """
39
39
40 def __init__(self):
40 def __init__(self):
41 self.__forbidden = set()
41 self.__forbidden = set()
42
42
43 def forbid(self, module_name):
43 def forbid(self, module_name):
44 sys.modules.pop(module_name, None)
44 sys.modules.pop(module_name, None)
45 self.__forbidden.add(module_name)
45 self.__forbidden.add(module_name)
46
46
47 def find_module(self, fullname, path=None):
47 def find_module(self, fullname, path=None):
48 if path:
48 if path:
49 return
49 return
50 if fullname in self.__forbidden:
50 if fullname in self.__forbidden:
51 return self
51 return self
52
52
53 def load_module(self, fullname):
53 def load_module(self, fullname):
54 raise ImportError("""
54 raise ImportError("""
55 Importing %s disabled by IPython, which has
55 Importing %s disabled by IPython, which has
56 already imported an Incompatible QT Binding: %s
56 already imported an Incompatible QT Binding: %s
57 """ % (fullname, loaded_api()))
57 """ % (fullname, loaded_api()))
58
58
59 ID = ImportDenier()
59 ID = ImportDenier()
60 sys.meta_path.insert(0, ID)
60 sys.meta_path.insert(0, ID)
61
61
62
62
63 def commit_api(api):
63 def commit_api(api):
64 """Commit to a particular API, and trigger ImportErrors on subsequent
64 """Commit to a particular API, and trigger ImportErrors on subsequent
65 dangerous imports"""
65 dangerous imports"""
66
66
67 if api == QT_API_PYSIDE2:
67 if api == QT_API_PYSIDE2:
68 ID.forbid('PySide')
68 ID.forbid('PySide')
69 ID.forbid('PyQt4')
69 ID.forbid('PyQt4')
70 ID.forbid('PyQt5')
70 ID.forbid('PyQt5')
71 elif api == QT_API_PYSIDE:
71 elif api == QT_API_PYSIDE:
72 ID.forbid('PySide2')
72 ID.forbid('PySide2')
73 ID.forbid('PyQt4')
73 ID.forbid('PyQt4')
74 ID.forbid('PyQt5')
74 ID.forbid('PyQt5')
75 elif api == QT_API_PYQT5:
75 elif api == QT_API_PYQT5:
76 ID.forbid('PySide2')
76 ID.forbid('PySide2')
77 ID.forbid('PySide')
77 ID.forbid('PySide')
78 ID.forbid('PyQt4')
78 ID.forbid('PyQt4')
79 else: # There are three other possibilities, all representing PyQt4
79 else: # There are three other possibilities, all representing PyQt4
80 ID.forbid('PyQt5')
80 ID.forbid('PyQt5')
81 ID.forbid('PySide2')
81 ID.forbid('PySide2')
82 ID.forbid('PySide')
82 ID.forbid('PySide')
83
83
84
84
85 def loaded_api():
85 def loaded_api():
86 """Return which API is loaded, if any
86 """Return which API is loaded, if any
87
87
88 If this returns anything besides None,
88 If this returns anything besides None,
89 importing any other Qt binding is unsafe.
89 importing any other Qt binding is unsafe.
90
90
91 Returns
91 Returns
92 -------
92 -------
93 None, 'pyside2', 'pyside', 'pyqt', 'pyqt5', or 'pyqtv1'
93 None, 'pyside2', 'pyside', 'pyqt', 'pyqt5', or 'pyqtv1'
94 """
94 """
95 if 'PyQt4.QtCore' in sys.modules:
95 if 'PyQt4.QtCore' in sys.modules:
96 if qtapi_version() == 2:
96 if qtapi_version() == 2:
97 return QT_API_PYQT
97 return QT_API_PYQT
98 else:
98 else:
99 return QT_API_PYQTv1
99 return QT_API_PYQTv1
100 elif 'PySide.QtCore' in sys.modules:
100 elif 'PySide.QtCore' in sys.modules:
101 return QT_API_PYSIDE
101 return QT_API_PYSIDE
102 elif 'PySide2.QtCore' in sys.modules:
102 elif 'PySide2.QtCore' in sys.modules:
103 return QT_API_PYSIDE2
103 return QT_API_PYSIDE2
104 elif 'PyQt5.QtCore' in sys.modules:
104 elif 'PyQt5.QtCore' in sys.modules:
105 return QT_API_PYQT5
105 return QT_API_PYQT5
106 return None
106 return None
107
107
108
108
109 def has_binding(api):
109 def has_binding(api):
110 """Safely check for PyQt4/5, PySide or PySide2, without importing submodules
110 """Safely check for PyQt4/5, PySide or PySide2, without importing submodules
111
111
112 Parameters
112 Parameters
113 ----------
113 ----------
114 api : str [ 'pyqtv1' | 'pyqt' | 'pyqt5' | 'pyside' | 'pyside2' | 'pyqtdefault']
114 api : str [ 'pyqtv1' | 'pyqt' | 'pyqt5' | 'pyside' | 'pyside2' | 'pyqtdefault']
115 Which module to check for
115 Which module to check for
116
116
117 Returns
117 Returns
118 -------
118 -------
119 True if the relevant module appears to be importable
119 True if the relevant module appears to be importable
120 """
120 """
121 module_name = api_to_module[api]
121 module_name = api_to_module[api]
122 from importlib.util import find_spec
122 from importlib.util import find_spec
123
123
124 required = ['QtCore', 'QtGui', 'QtSvg']
124 required = ['QtCore', 'QtGui', 'QtSvg']
125 if api in (QT_API_PYQT5, QT_API_PYSIDE2):
125 if api in (QT_API_PYQT5, QT_API_PYSIDE2):
126 # QT5 requires QtWidgets too
126 # QT5 requires QtWidgets too
127 required.append('QtWidgets')
127 required.append('QtWidgets')
128
128
129 for submod in required:
129 for submod in required:
130 try:
130 try:
131 spec = find_spec('%s.%s' % (module_name, submod))
131 spec = find_spec('%s.%s' % (module_name, submod))
132 except ImportError:
132 except ImportError:
133 # Package (e.g. PyQt5) not found
133 # Package (e.g. PyQt5) not found
134 return False
134 return False
135 else:
135 else:
136 if spec is None:
136 if spec is None:
137 # Submodule (e.g. PyQt5.QtCore) not found
137 # Submodule (e.g. PyQt5.QtCore) not found
138 return False
138 return False
139
139
140 if api == QT_API_PYSIDE:
140 if api == QT_API_PYSIDE:
141 # We can also safely check PySide version
141 # We can also safely check PySide version
142 import PySide
142 import PySide
143 return check_version(PySide.__version__, '1.0.3')
143 return check_version(PySide.__version__, '1.0.3')
144
144
145 return True
145 return True
146
146
147
147
148 def qtapi_version():
148 def qtapi_version():
149 """Return which QString API has been set, if any
149 """Return which QString API has been set, if any
150
150
151 Returns
151 Returns
152 -------
152 -------
153 The QString API version (1 or 2), or None if not set
153 The QString API version (1 or 2), or None if not set
154 """
154 """
155 try:
155 try:
156 import sip
156 import sip
157 except ImportError:
157 except ImportError:
158 return
158 return
159 try:
159 try:
160 return sip.getapi('QString')
160 return sip.getapi('QString')
161 except ValueError:
161 except ValueError:
162 return
162 return
163
163
164
164
165 def can_import(api):
165 def can_import(api):
166 """Safely query whether an API is importable, without importing it"""
166 """Safely query whether an API is importable, without importing it"""
167 if not has_binding(api):
167 if not has_binding(api):
168 return False
168 return False
169
169
170 current = loaded_api()
170 current = loaded_api()
171 if api == QT_API_PYQT_DEFAULT:
171 if api == QT_API_PYQT_DEFAULT:
172 return current in [QT_API_PYQT, QT_API_PYQTv1, None]
172 return current in [QT_API_PYQT, QT_API_PYQTv1, None]
173 else:
173 else:
174 return current in [api, None]
174 return current in [api, None]
175
175
176
176
177 def import_pyqt4(version=2):
177 def import_pyqt4(version=2):
178 """
178 """
179 Import PyQt4
179 Import PyQt4
180
180
181 Parameters
181 Parameters
182 ----------
182 ----------
183 version : 1, 2, or None
183 version : 1, 2, or None
184 Which QString/QVariant API to use. Set to None to use the system
184 Which QString/QVariant API to use. Set to None to use the system
185 default
185 default
186
186
187 ImportErrors rasied within this function are non-recoverable
187 ImportErrors rasied within this function are non-recoverable
188 """
188 """
189 # The new-style string API (version=2) automatically
189 # The new-style string API (version=2) automatically
190 # converts QStrings to Unicode Python strings. Also, automatically unpacks
190 # converts QStrings to Unicode Python strings. Also, automatically unpacks
191 # QVariants to their underlying objects.
191 # QVariants to their underlying objects.
192 import sip
192 import sip
193
193
194 if version is not None:
194 if version is not None:
195 sip.setapi('QString', version)
195 sip.setapi('QString', version)
196 sip.setapi('QVariant', version)
196 sip.setapi('QVariant', version)
197
197
198 from PyQt4 import QtGui, QtCore, QtSvg
198 from PyQt4 import QtGui, QtCore, QtSvg
199
199
200 if not check_version(QtCore.PYQT_VERSION_STR, '4.7'):
200 if not check_version(QtCore.PYQT_VERSION_STR, '4.7'):
201 raise ImportError("IPython requires PyQt4 >= 4.7, found %s" %
201 raise ImportError("IPython requires PyQt4 >= 4.7, found %s" %
202 QtCore.PYQT_VERSION_STR)
202 QtCore.PYQT_VERSION_STR)
203
203
204 # Alias PyQt-specific functions for PySide compatibility.
204 # Alias PyQt-specific functions for PySide compatibility.
205 QtCore.Signal = QtCore.pyqtSignal
205 QtCore.Signal = QtCore.pyqtSignal
206 QtCore.Slot = QtCore.pyqtSlot
206 QtCore.Slot = QtCore.pyqtSlot
207
207
208 # query for the API version (in case version == None)
208 # query for the API version (in case version == None)
209 version = sip.getapi('QString')
209 version = sip.getapi('QString')
210 api = QT_API_PYQTv1 if version == 1 else QT_API_PYQT
210 api = QT_API_PYQTv1 if version == 1 else QT_API_PYQT
211 return QtCore, QtGui, QtSvg, api
211 return QtCore, QtGui, QtSvg, api
212
212
213
213
214 def import_pyqt5():
214 def import_pyqt5():
215 """
215 """
216 Import PyQt5
216 Import PyQt5
217
217
218 ImportErrors rasied within this function are non-recoverable
218 ImportErrors rasied within this function are non-recoverable
219 """
219 """
220
220
221 from PyQt5 import QtCore, QtSvg, QtWidgets, QtGui
221 from PyQt5 import QtCore, QtSvg, QtWidgets, QtGui
222
222
223 # Alias PyQt-specific functions for PySide compatibility.
223 # Alias PyQt-specific functions for PySide compatibility.
224 QtCore.Signal = QtCore.pyqtSignal
224 QtCore.Signal = QtCore.pyqtSignal
225 QtCore.Slot = QtCore.pyqtSlot
225 QtCore.Slot = QtCore.pyqtSlot
226
226
227 # Join QtGui and QtWidgets for Qt4 compatibility.
227 # Join QtGui and QtWidgets for Qt4 compatibility.
228 QtGuiCompat = types.ModuleType('QtGuiCompat')
228 QtGuiCompat = types.ModuleType('QtGuiCompat')
229 QtGuiCompat.__dict__.update(QtGui.__dict__)
229 QtGuiCompat.__dict__.update(QtGui.__dict__)
230 QtGuiCompat.__dict__.update(QtWidgets.__dict__)
230 QtGuiCompat.__dict__.update(QtWidgets.__dict__)
231
231
232 api = QT_API_PYQT5
232 api = QT_API_PYQT5
233 return QtCore, QtGuiCompat, QtSvg, api
233 return QtCore, QtGuiCompat, QtSvg, api
234
234
235
235
236 def import_pyside():
236 def import_pyside():
237 """
237 """
238 Import PySide
238 Import PySide
239
239
240 ImportErrors raised within this function are non-recoverable
240 ImportErrors raised within this function are non-recoverable
241 """
241 """
242 from PySide import QtGui, QtCore, QtSvg
242 from PySide import QtGui, QtCore, QtSvg
243 return QtCore, QtGui, QtSvg, QT_API_PYSIDE
243 return QtCore, QtGui, QtSvg, QT_API_PYSIDE
244
244
245 def import_pyside2():
245 def import_pyside2():
246 """
246 """
247 Import PySide2
247 Import PySide2
248
248
249 ImportErrors raised within this function are non-recoverable
249 ImportErrors raised within this function are non-recoverable
250 """
250 """
251 from PySide2 import QtGui, QtCore, QtSvg, QtWidgets, QtPrintSupport
251 from PySide2 import QtGui, QtCore, QtSvg, QtWidgets, QtPrintSupport
252
252
253 # Join QtGui and QtWidgets for Qt4 compatibility.
253 # Join QtGui and QtWidgets for Qt4 compatibility.
254 QtGuiCompat = types.ModuleType('QtGuiCompat')
254 QtGuiCompat = types.ModuleType('QtGuiCompat')
255 QtGuiCompat.__dict__.update(QtGui.__dict__)
255 QtGuiCompat.__dict__.update(QtGui.__dict__)
256 QtGuiCompat.__dict__.update(QtWidgets.__dict__)
256 QtGuiCompat.__dict__.update(QtWidgets.__dict__)
257 QtGuiCompat.__dict__.update(QtPrintSupport.__dict__)
257 QtGuiCompat.__dict__.update(QtPrintSupport.__dict__)
258
258
259 return QtCore, QtGuiCompat, QtSvg, QT_API_PYSIDE2
259 return QtCore, QtGuiCompat, QtSvg, QT_API_PYSIDE2
260
260
261
261
262 def load_qt(api_options):
262 def load_qt(api_options):
263 """
263 """
264 Attempt to import Qt, given a preference list
264 Attempt to import Qt, given a preference list
265 of permissible bindings
265 of permissible bindings
266
266
267 It is safe to call this function multiple times.
267 It is safe to call this function multiple times.
268
268
269 Parameters
269 Parameters
270 ----------
270 ----------
271 api_options: List of strings
271 api_options: List of strings
272 The order of APIs to try. Valid items are 'pyside', 'pyside2',
272 The order of APIs to try. Valid items are 'pyside', 'pyside2',
273 'pyqt', 'pyqt5', 'pyqtv1' and 'pyqtdefault'
273 'pyqt', 'pyqt5', 'pyqtv1' and 'pyqtdefault'
274
274
275 Returns
275 Returns
276 -------
276 -------
277
277
278 A tuple of QtCore, QtGui, QtSvg, QT_API
278 A tuple of QtCore, QtGui, QtSvg, QT_API
279 The first three are the Qt modules. The last is the
279 The first three are the Qt modules. The last is the
280 string indicating which module was loaded.
280 string indicating which module was loaded.
281
281
282 Raises
282 Raises
283 ------
283 ------
284 ImportError, if it isn't possible to import any requested
284 ImportError, if it isn't possible to import any requested
285 bindings (either becaues they aren't installed, or because
285 bindings (either because they aren't installed, or because
286 an incompatible library has already been installed)
286 an incompatible library has already been installed)
287 """
287 """
288 loaders = {
288 loaders = {
289 QT_API_PYSIDE2: import_pyside2,
289 QT_API_PYSIDE2: import_pyside2,
290 QT_API_PYSIDE: import_pyside,
290 QT_API_PYSIDE: import_pyside,
291 QT_API_PYQT: import_pyqt4,
291 QT_API_PYQT: import_pyqt4,
292 QT_API_PYQT5: import_pyqt5,
292 QT_API_PYQT5: import_pyqt5,
293 QT_API_PYQTv1: partial(import_pyqt4, version=1),
293 QT_API_PYQTv1: partial(import_pyqt4, version=1),
294 QT_API_PYQT_DEFAULT: partial(import_pyqt4, version=None)
294 QT_API_PYQT_DEFAULT: partial(import_pyqt4, version=None)
295 }
295 }
296
296
297 for api in api_options:
297 for api in api_options:
298
298
299 if api not in loaders:
299 if api not in loaders:
300 raise RuntimeError(
300 raise RuntimeError(
301 "Invalid Qt API %r, valid values are: %s" %
301 "Invalid Qt API %r, valid values are: %s" %
302 (api, ", ".join(["%r" % k for k in loaders.keys()])))
302 (api, ", ".join(["%r" % k for k in loaders.keys()])))
303
303
304 if not can_import(api):
304 if not can_import(api):
305 continue
305 continue
306
306
307 #cannot safely recover from an ImportError during this
307 #cannot safely recover from an ImportError during this
308 result = loaders[api]()
308 result = loaders[api]()
309 api = result[-1] # changed if api = QT_API_PYQT_DEFAULT
309 api = result[-1] # changed if api = QT_API_PYQT_DEFAULT
310 commit_api(api)
310 commit_api(api)
311 return result
311 return result
312 else:
312 else:
313 raise ImportError("""
313 raise ImportError("""
314 Could not load requested Qt binding. Please ensure that
314 Could not load requested Qt binding. Please ensure that
315 PyQt4 >= 4.7, PyQt5, PySide >= 1.0.3 or PySide2 is available,
315 PyQt4 >= 4.7, PyQt5, PySide >= 1.0.3 or PySide2 is available,
316 and only one is imported per session.
316 and only one is imported per session.
317
317
318 Currently-imported Qt library: %r
318 Currently-imported Qt library: %r
319 PyQt4 available (requires QtCore, QtGui, QtSvg): %s
319 PyQt4 available (requires QtCore, QtGui, QtSvg): %s
320 PyQt5 available (requires QtCore, QtGui, QtSvg, QtWidgets): %s
320 PyQt5 available (requires QtCore, QtGui, QtSvg, QtWidgets): %s
321 PySide >= 1.0.3 installed: %s
321 PySide >= 1.0.3 installed: %s
322 PySide2 installed: %s
322 PySide2 installed: %s
323 Tried to load: %r
323 Tried to load: %r
324 """ % (loaded_api(),
324 """ % (loaded_api(),
325 has_binding(QT_API_PYQT),
325 has_binding(QT_API_PYQT),
326 has_binding(QT_API_PYQT5),
326 has_binding(QT_API_PYQT5),
327 has_binding(QT_API_PYSIDE),
327 has_binding(QT_API_PYSIDE),
328 has_binding(QT_API_PYSIDE2),
328 has_binding(QT_API_PYSIDE2),
329 api_options))
329 api_options))
@@ -1,347 +1,347 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Provides a reload() function that acts recursively.
3 Provides a reload() function that acts recursively.
4
4
5 Python's normal :func:`python:reload` function only reloads the module that it's
5 Python's normal :func:`python:reload` function only reloads the module that it's
6 passed. The :func:`reload` function in this module also reloads everything
6 passed. The :func:`reload` function in this module also reloads everything
7 imported from that module, which is useful when you're changing files deep
7 imported from that module, which is useful when you're changing files deep
8 inside a package.
8 inside a package.
9
9
10 To use this as your default reload function, type this for Python 2::
10 To use this as your default reload function, type this for Python 2::
11
11
12 import __builtin__
12 import __builtin__
13 from IPython.lib import deepreload
13 from IPython.lib import deepreload
14 __builtin__.reload = deepreload.reload
14 __builtin__.reload = deepreload.reload
15
15
16 Or this for Python 3::
16 Or this for Python 3::
17
17
18 import builtins
18 import builtins
19 from IPython.lib import deepreload
19 from IPython.lib import deepreload
20 builtins.reload = deepreload.reload
20 builtins.reload = deepreload.reload
21
21
22 A reference to the original :func:`python:reload` is stored in this module as
22 A reference to the original :func:`python:reload` is stored in this module as
23 :data:`original_reload`, so you can restore it later.
23 :data:`original_reload`, so you can restore it later.
24
24
25 This code is almost entirely based on knee.py, which is a Python
25 This code is almost entirely based on knee.py, which is a Python
26 re-implementation of hierarchical module import.
26 re-implementation of hierarchical module import.
27 """
27 """
28 #*****************************************************************************
28 #*****************************************************************************
29 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
29 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
30 #
30 #
31 # Distributed under the terms of the BSD License. The full license is in
31 # Distributed under the terms of the BSD License. The full license is in
32 # the file COPYING, distributed as part of this software.
32 # the file COPYING, distributed as part of this software.
33 #*****************************************************************************
33 #*****************************************************************************
34
34
35 import builtins as builtin_mod
35 import builtins as builtin_mod
36 from contextlib import contextmanager
36 from contextlib import contextmanager
37 import imp
37 import imp
38 import sys
38 import sys
39
39
40 from types import ModuleType
40 from types import ModuleType
41 from warnings import warn
41 from warnings import warn
42 import types
42 import types
43
43
44 original_import = builtin_mod.__import__
44 original_import = builtin_mod.__import__
45
45
46 @contextmanager
46 @contextmanager
47 def replace_import_hook(new_import):
47 def replace_import_hook(new_import):
48 saved_import = builtin_mod.__import__
48 saved_import = builtin_mod.__import__
49 builtin_mod.__import__ = new_import
49 builtin_mod.__import__ = new_import
50 try:
50 try:
51 yield
51 yield
52 finally:
52 finally:
53 builtin_mod.__import__ = saved_import
53 builtin_mod.__import__ = saved_import
54
54
55 def get_parent(globals, level):
55 def get_parent(globals, level):
56 """
56 """
57 parent, name = get_parent(globals, level)
57 parent, name = get_parent(globals, level)
58
58
59 Return the package that an import is being performed in. If globals comes
59 Return the package that an import is being performed in. If globals comes
60 from the module foo.bar.bat (not itself a package), this returns the
60 from the module foo.bar.bat (not itself a package), this returns the
61 sys.modules entry for foo.bar. If globals is from a package's __init__.py,
61 sys.modules entry for foo.bar. If globals is from a package's __init__.py,
62 the package's entry in sys.modules is returned.
62 the package's entry in sys.modules is returned.
63
63
64 If globals doesn't come from a package or a module in a package, or a
64 If globals doesn't come from a package or a module in a package, or a
65 corresponding entry is not found in sys.modules, None is returned.
65 corresponding entry is not found in sys.modules, None is returned.
66 """
66 """
67 orig_level = level
67 orig_level = level
68
68
69 if not level or not isinstance(globals, dict):
69 if not level or not isinstance(globals, dict):
70 return None, ''
70 return None, ''
71
71
72 pkgname = globals.get('__package__', None)
72 pkgname = globals.get('__package__', None)
73
73
74 if pkgname is not None:
74 if pkgname is not None:
75 # __package__ is set, so use it
75 # __package__ is set, so use it
76 if not hasattr(pkgname, 'rindex'):
76 if not hasattr(pkgname, 'rindex'):
77 raise ValueError('__package__ set to non-string')
77 raise ValueError('__package__ set to non-string')
78 if len(pkgname) == 0:
78 if len(pkgname) == 0:
79 if level > 0:
79 if level > 0:
80 raise ValueError('Attempted relative import in non-package')
80 raise ValueError('Attempted relative import in non-package')
81 return None, ''
81 return None, ''
82 name = pkgname
82 name = pkgname
83 else:
83 else:
84 # __package__ not set, so figure it out and set it
84 # __package__ not set, so figure it out and set it
85 if '__name__' not in globals:
85 if '__name__' not in globals:
86 return None, ''
86 return None, ''
87 modname = globals['__name__']
87 modname = globals['__name__']
88
88
89 if '__path__' in globals:
89 if '__path__' in globals:
90 # __path__ is set, so modname is already the package name
90 # __path__ is set, so modname is already the package name
91 globals['__package__'] = name = modname
91 globals['__package__'] = name = modname
92 else:
92 else:
93 # Normal module, so work out the package name if any
93 # Normal module, so work out the package name if any
94 lastdot = modname.rfind('.')
94 lastdot = modname.rfind('.')
95 if lastdot < 0 < level:
95 if lastdot < 0 < level:
96 raise ValueError("Attempted relative import in non-package")
96 raise ValueError("Attempted relative import in non-package")
97 if lastdot < 0:
97 if lastdot < 0:
98 globals['__package__'] = None
98 globals['__package__'] = None
99 return None, ''
99 return None, ''
100 globals['__package__'] = name = modname[:lastdot]
100 globals['__package__'] = name = modname[:lastdot]
101
101
102 dot = len(name)
102 dot = len(name)
103 for x in range(level, 1, -1):
103 for x in range(level, 1, -1):
104 try:
104 try:
105 dot = name.rindex('.', 0, dot)
105 dot = name.rindex('.', 0, dot)
106 except ValueError:
106 except ValueError:
107 raise ValueError("attempted relative import beyond top-level "
107 raise ValueError("attempted relative import beyond top-level "
108 "package")
108 "package")
109 name = name[:dot]
109 name = name[:dot]
110
110
111 try:
111 try:
112 parent = sys.modules[name]
112 parent = sys.modules[name]
113 except:
113 except:
114 if orig_level < 1:
114 if orig_level < 1:
115 warn("Parent module '%.200s' not found while handling absolute "
115 warn("Parent module '%.200s' not found while handling absolute "
116 "import" % name)
116 "import" % name)
117 parent = None
117 parent = None
118 else:
118 else:
119 raise SystemError("Parent module '%.200s' not loaded, cannot "
119 raise SystemError("Parent module '%.200s' not loaded, cannot "
120 "perform relative import" % name)
120 "perform relative import" % name)
121
121
122 # We expect, but can't guarantee, if parent != None, that:
122 # We expect, but can't guarantee, if parent != None, that:
123 # - parent.__name__ == name
123 # - parent.__name__ == name
124 # - parent.__dict__ is globals
124 # - parent.__dict__ is globals
125 # If this is violated... Who cares?
125 # If this is violated... Who cares?
126 return parent, name
126 return parent, name
127
127
128 def load_next(mod, altmod, name, buf):
128 def load_next(mod, altmod, name, buf):
129 """
129 """
130 mod, name, buf = load_next(mod, altmod, name, buf)
130 mod, name, buf = load_next(mod, altmod, name, buf)
131
131
132 altmod is either None or same as mod
132 altmod is either None or same as mod
133 """
133 """
134
134
135 if len(name) == 0:
135 if len(name) == 0:
136 # completely empty module name should only happen in
136 # completely empty module name should only happen in
137 # 'from . import' (or '__import__("")')
137 # 'from . import' (or '__import__("")')
138 return mod, None, buf
138 return mod, None, buf
139
139
140 dot = name.find('.')
140 dot = name.find('.')
141 if dot == 0:
141 if dot == 0:
142 raise ValueError('Empty module name')
142 raise ValueError('Empty module name')
143
143
144 if dot < 0:
144 if dot < 0:
145 subname = name
145 subname = name
146 next = None
146 next = None
147 else:
147 else:
148 subname = name[:dot]
148 subname = name[:dot]
149 next = name[dot+1:]
149 next = name[dot+1:]
150
150
151 if buf != '':
151 if buf != '':
152 buf += '.'
152 buf += '.'
153 buf += subname
153 buf += subname
154
154
155 result = import_submodule(mod, subname, buf)
155 result = import_submodule(mod, subname, buf)
156 if result is None and mod != altmod:
156 if result is None and mod != altmod:
157 result = import_submodule(altmod, subname, subname)
157 result = import_submodule(altmod, subname, subname)
158 if result is not None:
158 if result is not None:
159 buf = subname
159 buf = subname
160
160
161 if result is None:
161 if result is None:
162 raise ImportError("No module named %.200s" % name)
162 raise ImportError("No module named %.200s" % name)
163
163
164 return result, next, buf
164 return result, next, buf
165
165
166
166
167 # Need to keep track of what we've already reloaded to prevent cyclic evil
167 # Need to keep track of what we've already reloaded to prevent cyclic evil
168 found_now = {}
168 found_now = {}
169
169
170 def import_submodule(mod, subname, fullname):
170 def import_submodule(mod, subname, fullname):
171 """m = import_submodule(mod, subname, fullname)"""
171 """m = import_submodule(mod, subname, fullname)"""
172 # Require:
172 # Require:
173 # if mod == None: subname == fullname
173 # if mod == None: subname == fullname
174 # else: mod.__name__ + "." + subname == fullname
174 # else: mod.__name__ + "." + subname == fullname
175
175
176 global found_now
176 global found_now
177 if fullname in found_now and fullname in sys.modules:
177 if fullname in found_now and fullname in sys.modules:
178 m = sys.modules[fullname]
178 m = sys.modules[fullname]
179 else:
179 else:
180 print('Reloading', fullname)
180 print('Reloading', fullname)
181 found_now[fullname] = 1
181 found_now[fullname] = 1
182 oldm = sys.modules.get(fullname, None)
182 oldm = sys.modules.get(fullname, None)
183
183
184 if mod is None:
184 if mod is None:
185 path = None
185 path = None
186 elif hasattr(mod, '__path__'):
186 elif hasattr(mod, '__path__'):
187 path = mod.__path__
187 path = mod.__path__
188 else:
188 else:
189 return None
189 return None
190
190
191 try:
191 try:
192 # This appears to be necessary on Python 3, because imp.find_module()
192 # This appears to be necessary on Python 3, because imp.find_module()
193 # tries to import standard libraries (like io) itself, and we don't
193 # tries to import standard libraries (like io) itself, and we don't
194 # want them to be processed by our deep_import_hook.
194 # want them to be processed by our deep_import_hook.
195 with replace_import_hook(original_import):
195 with replace_import_hook(original_import):
196 fp, filename, stuff = imp.find_module(subname, path)
196 fp, filename, stuff = imp.find_module(subname, path)
197 except ImportError:
197 except ImportError:
198 return None
198 return None
199
199
200 try:
200 try:
201 m = imp.load_module(fullname, fp, filename, stuff)
201 m = imp.load_module(fullname, fp, filename, stuff)
202 except:
202 except:
203 # load_module probably removed name from modules because of
203 # load_module probably removed name from modules because of
204 # the error. Put back the original module object.
204 # the error. Put back the original module object.
205 if oldm:
205 if oldm:
206 sys.modules[fullname] = oldm
206 sys.modules[fullname] = oldm
207 raise
207 raise
208 finally:
208 finally:
209 if fp: fp.close()
209 if fp: fp.close()
210
210
211 add_submodule(mod, m, fullname, subname)
211 add_submodule(mod, m, fullname, subname)
212
212
213 return m
213 return m
214
214
215 def add_submodule(mod, submod, fullname, subname):
215 def add_submodule(mod, submod, fullname, subname):
216 """mod.{subname} = submod"""
216 """mod.{subname} = submod"""
217 if mod is None:
217 if mod is None:
218 return #Nothing to do here.
218 return #Nothing to do here.
219
219
220 if submod is None:
220 if submod is None:
221 submod = sys.modules[fullname]
221 submod = sys.modules[fullname]
222
222
223 setattr(mod, subname, submod)
223 setattr(mod, subname, submod)
224
224
225 return
225 return
226
226
227 def ensure_fromlist(mod, fromlist, buf, recursive):
227 def ensure_fromlist(mod, fromlist, buf, recursive):
228 """Handle 'from module import a, b, c' imports."""
228 """Handle 'from module import a, b, c' imports."""
229 if not hasattr(mod, '__path__'):
229 if not hasattr(mod, '__path__'):
230 return
230 return
231 for item in fromlist:
231 for item in fromlist:
232 if not hasattr(item, 'rindex'):
232 if not hasattr(item, 'rindex'):
233 raise TypeError("Item in ``from list'' not a string")
233 raise TypeError("Item in ``from list'' not a string")
234 if item == '*':
234 if item == '*':
235 if recursive:
235 if recursive:
236 continue # avoid endless recursion
236 continue # avoid endless recursion
237 try:
237 try:
238 all = mod.__all__
238 all = mod.__all__
239 except AttributeError:
239 except AttributeError:
240 pass
240 pass
241 else:
241 else:
242 ret = ensure_fromlist(mod, all, buf, 1)
242 ret = ensure_fromlist(mod, all, buf, 1)
243 if not ret:
243 if not ret:
244 return 0
244 return 0
245 elif not hasattr(mod, item):
245 elif not hasattr(mod, item):
246 import_submodule(mod, item, buf + '.' + item)
246 import_submodule(mod, item, buf + '.' + item)
247
247
248 def deep_import_hook(name, globals=None, locals=None, fromlist=None, level=-1):
248 def deep_import_hook(name, globals=None, locals=None, fromlist=None, level=-1):
249 """Replacement for __import__()"""
249 """Replacement for __import__()"""
250 parent, buf = get_parent(globals, level)
250 parent, buf = get_parent(globals, level)
251
251
252 head, name, buf = load_next(parent, None if level < 0 else parent, name, buf)
252 head, name, buf = load_next(parent, None if level < 0 else parent, name, buf)
253
253
254 tail = head
254 tail = head
255 while name:
255 while name:
256 tail, name, buf = load_next(tail, tail, name, buf)
256 tail, name, buf = load_next(tail, tail, name, buf)
257
257
258 # If tail is None, both get_parent and load_next found
258 # If tail is None, both get_parent and load_next found
259 # an empty module name: someone called __import__("") or
259 # an empty module name: someone called __import__("") or
260 # doctored faulty bytecode
260 # doctored faulty bytecode
261 if tail is None:
261 if tail is None:
262 raise ValueError('Empty module name')
262 raise ValueError('Empty module name')
263
263
264 if not fromlist:
264 if not fromlist:
265 return head
265 return head
266
266
267 ensure_fromlist(tail, fromlist, buf, 0)
267 ensure_fromlist(tail, fromlist, buf, 0)
268 return tail
268 return tail
269
269
270 modules_reloading = {}
270 modules_reloading = {}
271
271
272 def deep_reload_hook(m):
272 def deep_reload_hook(m):
273 """Replacement for reload()."""
273 """Replacement for reload()."""
274 # Hardcode this one as it would raise a NotImplemeentedError from the
274 # Hardcode this one as it would raise a NotImplementedError from the
275 # bowels of Python and screw up the import machinery after.
275 # bowels of Python and screw up the import machinery after.
276 # unlike other imports the `exclude` list already in place is not enough.
276 # unlike other imports the `exclude` list already in place is not enough.
277
277
278 if m is types:
278 if m is types:
279 return m
279 return m
280 if not isinstance(m, ModuleType):
280 if not isinstance(m, ModuleType):
281 raise TypeError("reload() argument must be module")
281 raise TypeError("reload() argument must be module")
282
282
283 name = m.__name__
283 name = m.__name__
284
284
285 if name not in sys.modules:
285 if name not in sys.modules:
286 raise ImportError("reload(): module %.200s not in sys.modules" % name)
286 raise ImportError("reload(): module %.200s not in sys.modules" % name)
287
287
288 global modules_reloading
288 global modules_reloading
289 try:
289 try:
290 return modules_reloading[name]
290 return modules_reloading[name]
291 except:
291 except:
292 modules_reloading[name] = m
292 modules_reloading[name] = m
293
293
294 dot = name.rfind('.')
294 dot = name.rfind('.')
295 if dot < 0:
295 if dot < 0:
296 subname = name
296 subname = name
297 path = None
297 path = None
298 else:
298 else:
299 try:
299 try:
300 parent = sys.modules[name[:dot]]
300 parent = sys.modules[name[:dot]]
301 except KeyError:
301 except KeyError:
302 modules_reloading.clear()
302 modules_reloading.clear()
303 raise ImportError("reload(): parent %.200s not in sys.modules" % name[:dot])
303 raise ImportError("reload(): parent %.200s not in sys.modules" % name[:dot])
304 subname = name[dot+1:]
304 subname = name[dot+1:]
305 path = getattr(parent, "__path__", None)
305 path = getattr(parent, "__path__", None)
306
306
307 try:
307 try:
308 # This appears to be necessary on Python 3, because imp.find_module()
308 # This appears to be necessary on Python 3, because imp.find_module()
309 # tries to import standard libraries (like io) itself, and we don't
309 # tries to import standard libraries (like io) itself, and we don't
310 # want them to be processed by our deep_import_hook.
310 # want them to be processed by our deep_import_hook.
311 with replace_import_hook(original_import):
311 with replace_import_hook(original_import):
312 fp, filename, stuff = imp.find_module(subname, path)
312 fp, filename, stuff = imp.find_module(subname, path)
313 finally:
313 finally:
314 modules_reloading.clear()
314 modules_reloading.clear()
315
315
316 try:
316 try:
317 newm = imp.load_module(name, fp, filename, stuff)
317 newm = imp.load_module(name, fp, filename, stuff)
318 except:
318 except:
319 # load_module probably removed name from modules because of
319 # load_module probably removed name from modules because of
320 # the error. Put back the original module object.
320 # the error. Put back the original module object.
321 sys.modules[name] = m
321 sys.modules[name] = m
322 raise
322 raise
323 finally:
323 finally:
324 if fp: fp.close()
324 if fp: fp.close()
325
325
326 modules_reloading.clear()
326 modules_reloading.clear()
327 return newm
327 return newm
328
328
329 # Save the original hooks
329 # Save the original hooks
330 original_reload = imp.reload
330 original_reload = imp.reload
331
331
332 # Replacement for reload()
332 # Replacement for reload()
333 def reload(module, exclude=('sys', 'os.path', 'builtins', '__main__',
333 def reload(module, exclude=('sys', 'os.path', 'builtins', '__main__',
334 'numpy', 'numpy._globals')):
334 'numpy', 'numpy._globals')):
335 """Recursively reload all modules used in the given module. Optionally
335 """Recursively reload all modules used in the given module. Optionally
336 takes a list of modules to exclude from reloading. The default exclude
336 takes a list of modules to exclude from reloading. The default exclude
337 list contains sys, __main__, and __builtin__, to prevent, e.g., resetting
337 list contains sys, __main__, and __builtin__, to prevent, e.g., resetting
338 display, exception, and io hooks.
338 display, exception, and io hooks.
339 """
339 """
340 global found_now
340 global found_now
341 for i in exclude:
341 for i in exclude:
342 found_now[i] = 1
342 found_now[i] = 1
343 try:
343 try:
344 with replace_import_hook(deep_import_hook):
344 with replace_import_hook(deep_import_hook):
345 return deep_reload_hook(module)
345 return deep_reload_hook(module)
346 finally:
346 finally:
347 found_now = {}
347 found_now = {}
@@ -1,648 +1,648 b''
1 """Various display related classes.
1 """Various display related classes.
2
2
3 Authors : MinRK, gregcaporaso, dannystaple
3 Authors : MinRK, gregcaporaso, dannystaple
4 """
4 """
5 from html import escape as html_escape
5 from html import escape as html_escape
6 from os.path import exists, isfile, splitext, abspath, join, isdir
6 from os.path import exists, isfile, splitext, abspath, join, isdir
7 from os import walk, sep, fsdecode
7 from os import walk, sep, fsdecode
8
8
9 from IPython.core.display import DisplayObject, TextDisplayObject
9 from IPython.core.display import DisplayObject, TextDisplayObject
10
10
11 __all__ = ['Audio', 'IFrame', 'YouTubeVideo', 'VimeoVideo', 'ScribdDocument',
11 __all__ = ['Audio', 'IFrame', 'YouTubeVideo', 'VimeoVideo', 'ScribdDocument',
12 'FileLink', 'FileLinks', 'Code']
12 'FileLink', 'FileLinks', 'Code']
13
13
14
14
15 class Audio(DisplayObject):
15 class Audio(DisplayObject):
16 """Create an audio object.
16 """Create an audio object.
17
17
18 When this object is returned by an input cell or passed to the
18 When this object is returned by an input cell or passed to the
19 display function, it will result in Audio controls being displayed
19 display function, it will result in Audio controls being displayed
20 in the frontend (only works in the notebook).
20 in the frontend (only works in the notebook).
21
21
22 Parameters
22 Parameters
23 ----------
23 ----------
24 data : numpy array, list, unicode, str or bytes
24 data : numpy array, list, unicode, str or bytes
25 Can be one of
25 Can be one of
26
26
27 * Numpy 1d array containing the desired waveform (mono)
27 * Numpy 1d array containing the desired waveform (mono)
28 * Numpy 2d array containing waveforms for each channel.
28 * Numpy 2d array containing waveforms for each channel.
29 Shape=(NCHAN, NSAMPLES). For the standard channel order, see
29 Shape=(NCHAN, NSAMPLES). For the standard channel order, see
30 http://msdn.microsoft.com/en-us/library/windows/hardware/dn653308(v=vs.85).aspx
30 http://msdn.microsoft.com/en-us/library/windows/hardware/dn653308(v=vs.85).aspx
31 * List of float or integer representing the waveform (mono)
31 * List of float or integer representing the waveform (mono)
32 * String containing the filename
32 * String containing the filename
33 * Bytestring containing raw PCM data or
33 * Bytestring containing raw PCM data or
34 * URL pointing to a file on the web.
34 * URL pointing to a file on the web.
35
35
36 If the array option is used, the waveform will be normalized.
36 If the array option is used, the waveform will be normalized.
37
37
38 If a filename or url is used, the format support will be browser
38 If a filename or url is used, the format support will be browser
39 dependent.
39 dependent.
40 url : unicode
40 url : unicode
41 A URL to download the data from.
41 A URL to download the data from.
42 filename : unicode
42 filename : unicode
43 Path to a local file to load the data from.
43 Path to a local file to load the data from.
44 embed : boolean
44 embed : boolean
45 Should the audio data be embedded using a data URI (True) or should
45 Should the audio data be embedded using a data URI (True) or should
46 the original source be referenced. Set this to True if you want the
46 the original source be referenced. Set this to True if you want the
47 audio to playable later with no internet connection in the notebook.
47 audio to playable later with no internet connection in the notebook.
48
48
49 Default is `True`, unless the keyword argument `url` is set, then
49 Default is `True`, unless the keyword argument `url` is set, then
50 default value is `False`.
50 default value is `False`.
51 rate : integer
51 rate : integer
52 The sampling rate of the raw data.
52 The sampling rate of the raw data.
53 Only required when data parameter is being used as an array
53 Only required when data parameter is being used as an array
54 autoplay : bool
54 autoplay : bool
55 Set to True if the audio should immediately start playing.
55 Set to True if the audio should immediately start playing.
56 Default is `False`.
56 Default is `False`.
57 normalize : bool
57 normalize : bool
58 Whether audio should be normalized (rescaled) to the maximum possible
58 Whether audio should be normalized (rescaled) to the maximum possible
59 range. Default is `True`. When set to `False`, `data` must be between
59 range. Default is `True`. When set to `False`, `data` must be between
60 -1 and 1 (inclusive), otherwise an error is raised.
60 -1 and 1 (inclusive), otherwise an error is raised.
61 Applies only when `data` is a list or array of samples; other types of
61 Applies only when `data` is a list or array of samples; other types of
62 audio are never normalized.
62 audio are never normalized.
63
63
64 Examples
64 Examples
65 --------
65 --------
66 ::
66 ::
67
67
68 # Generate a sound
68 # Generate a sound
69 import numpy as np
69 import numpy as np
70 framerate = 44100
70 framerate = 44100
71 t = np.linspace(0,5,framerate*5)
71 t = np.linspace(0,5,framerate*5)
72 data = np.sin(2*np.pi*220*t) + np.sin(2*np.pi*224*t)
72 data = np.sin(2*np.pi*220*t) + np.sin(2*np.pi*224*t)
73 Audio(data,rate=framerate)
73 Audio(data,rate=framerate)
74
74
75 # Can also do stereo or more channels
75 # Can also do stereo or more channels
76 dataleft = np.sin(2*np.pi*220*t)
76 dataleft = np.sin(2*np.pi*220*t)
77 dataright = np.sin(2*np.pi*224*t)
77 dataright = np.sin(2*np.pi*224*t)
78 Audio([dataleft, dataright],rate=framerate)
78 Audio([dataleft, dataright],rate=framerate)
79
79
80 Audio("http://www.nch.com.au/acm/8k16bitpcm.wav") # From URL
80 Audio("http://www.nch.com.au/acm/8k16bitpcm.wav") # From URL
81 Audio(url="http://www.w3schools.com/html/horse.ogg")
81 Audio(url="http://www.w3schools.com/html/horse.ogg")
82
82
83 Audio('/path/to/sound.wav') # From file
83 Audio('/path/to/sound.wav') # From file
84 Audio(filename='/path/to/sound.ogg')
84 Audio(filename='/path/to/sound.ogg')
85
85
86 Audio(b'RAW_WAV_DATA..) # From bytes
86 Audio(b'RAW_WAV_DATA..) # From bytes
87 Audio(data=b'RAW_WAV_DATA..)
87 Audio(data=b'RAW_WAV_DATA..)
88
88
89 See Also
89 See Also
90 --------
90 --------
91
91
92 See also the ``Audio`` widgets form the ``ipywidget`` package for more flexibility and options.
92 See also the ``Audio`` widgets form the ``ipywidget`` package for more flexibility and options.
93
93
94 """
94 """
95 _read_flags = 'rb'
95 _read_flags = 'rb'
96
96
97 def __init__(self, data=None, filename=None, url=None, embed=None, rate=None, autoplay=False, normalize=True, *,
97 def __init__(self, data=None, filename=None, url=None, embed=None, rate=None, autoplay=False, normalize=True, *,
98 element_id=None):
98 element_id=None):
99 if filename is None and url is None and data is None:
99 if filename is None and url is None and data is None:
100 raise ValueError("No audio data found. Expecting filename, url, or data.")
100 raise ValueError("No audio data found. Expecting filename, url, or data.")
101 if embed is False and url is None:
101 if embed is False and url is None:
102 raise ValueError("No url found. Expecting url when embed=False")
102 raise ValueError("No url found. Expecting url when embed=False")
103
103
104 if url is not None and embed is not True:
104 if url is not None and embed is not True:
105 self.embed = False
105 self.embed = False
106 else:
106 else:
107 self.embed = True
107 self.embed = True
108 self.autoplay = autoplay
108 self.autoplay = autoplay
109 self.element_id = element_id
109 self.element_id = element_id
110 super(Audio, self).__init__(data=data, url=url, filename=filename)
110 super(Audio, self).__init__(data=data, url=url, filename=filename)
111
111
112 if self.data is not None and not isinstance(self.data, bytes):
112 if self.data is not None and not isinstance(self.data, bytes):
113 if rate is None:
113 if rate is None:
114 raise ValueError("rate must be specified when data is a numpy array or list of audio samples.")
114 raise ValueError("rate must be specified when data is a numpy array or list of audio samples.")
115 self.data = Audio._make_wav(data, rate, normalize)
115 self.data = Audio._make_wav(data, rate, normalize)
116
116
117 def reload(self):
117 def reload(self):
118 """Reload the raw data from file or URL."""
118 """Reload the raw data from file or URL."""
119 import mimetypes
119 import mimetypes
120 if self.embed:
120 if self.embed:
121 super(Audio, self).reload()
121 super(Audio, self).reload()
122
122
123 if self.filename is not None:
123 if self.filename is not None:
124 self.mimetype = mimetypes.guess_type(self.filename)[0]
124 self.mimetype = mimetypes.guess_type(self.filename)[0]
125 elif self.url is not None:
125 elif self.url is not None:
126 self.mimetype = mimetypes.guess_type(self.url)[0]
126 self.mimetype = mimetypes.guess_type(self.url)[0]
127 else:
127 else:
128 self.mimetype = "audio/wav"
128 self.mimetype = "audio/wav"
129
129
130 @staticmethod
130 @staticmethod
131 def _make_wav(data, rate, normalize):
131 def _make_wav(data, rate, normalize):
132 """ Transform a numpy array to a PCM bytestring """
132 """ Transform a numpy array to a PCM bytestring """
133 import struct
133 import struct
134 from io import BytesIO
134 from io import BytesIO
135 import wave
135 import wave
136
136
137 try:
137 try:
138 scaled, nchan = Audio._validate_and_normalize_with_numpy(data, normalize)
138 scaled, nchan = Audio._validate_and_normalize_with_numpy(data, normalize)
139 except ImportError:
139 except ImportError:
140 scaled, nchan = Audio._validate_and_normalize_without_numpy(data, normalize)
140 scaled, nchan = Audio._validate_and_normalize_without_numpy(data, normalize)
141
141
142 fp = BytesIO()
142 fp = BytesIO()
143 waveobj = wave.open(fp,mode='wb')
143 waveobj = wave.open(fp,mode='wb')
144 waveobj.setnchannels(nchan)
144 waveobj.setnchannels(nchan)
145 waveobj.setframerate(rate)
145 waveobj.setframerate(rate)
146 waveobj.setsampwidth(2)
146 waveobj.setsampwidth(2)
147 waveobj.setcomptype('NONE','NONE')
147 waveobj.setcomptype('NONE','NONE')
148 waveobj.writeframes(b''.join([struct.pack('<h',x) for x in scaled]))
148 waveobj.writeframes(b''.join([struct.pack('<h',x) for x in scaled]))
149 val = fp.getvalue()
149 val = fp.getvalue()
150 waveobj.close()
150 waveobj.close()
151
151
152 return val
152 return val
153
153
154 @staticmethod
154 @staticmethod
155 def _validate_and_normalize_with_numpy(data, normalize):
155 def _validate_and_normalize_with_numpy(data, normalize):
156 import numpy as np
156 import numpy as np
157
157
158 data = np.array(data, dtype=float)
158 data = np.array(data, dtype=float)
159 if len(data.shape) == 1:
159 if len(data.shape) == 1:
160 nchan = 1
160 nchan = 1
161 elif len(data.shape) == 2:
161 elif len(data.shape) == 2:
162 # In wave files,channels are interleaved. E.g.,
162 # In wave files,channels are interleaved. E.g.,
163 # "L1R1L2R2..." for stereo. See
163 # "L1R1L2R2..." for stereo. See
164 # http://msdn.microsoft.com/en-us/library/windows/hardware/dn653308(v=vs.85).aspx
164 # http://msdn.microsoft.com/en-us/library/windows/hardware/dn653308(v=vs.85).aspx
165 # for channel ordering
165 # for channel ordering
166 nchan = data.shape[0]
166 nchan = data.shape[0]
167 data = data.T.ravel()
167 data = data.T.ravel()
168 else:
168 else:
169 raise ValueError('Array audio input must be a 1D or 2D array')
169 raise ValueError('Array audio input must be a 1D or 2D array')
170
170
171 max_abs_value = np.max(np.abs(data))
171 max_abs_value = np.max(np.abs(data))
172 normalization_factor = Audio._get_normalization_factor(max_abs_value, normalize)
172 normalization_factor = Audio._get_normalization_factor(max_abs_value, normalize)
173 scaled = np.int16(data / normalization_factor * 32767).tolist()
173 scaled = np.int16(data / normalization_factor * 32767).tolist()
174 return scaled, nchan
174 return scaled, nchan
175
175
176
176
177 @staticmethod
177 @staticmethod
178 def _validate_and_normalize_without_numpy(data, normalize):
178 def _validate_and_normalize_without_numpy(data, normalize):
179 try:
179 try:
180 max_abs_value = float(max([abs(x) for x in data]))
180 max_abs_value = float(max([abs(x) for x in data]))
181 except TypeError:
181 except TypeError:
182 raise TypeError('Only lists of mono audio are '
182 raise TypeError('Only lists of mono audio are '
183 'supported if numpy is not installed')
183 'supported if numpy is not installed')
184
184
185 normalization_factor = Audio._get_normalization_factor(max_abs_value, normalize)
185 normalization_factor = Audio._get_normalization_factor(max_abs_value, normalize)
186 scaled = [int(x / normalization_factor * 32767) for x in data]
186 scaled = [int(x / normalization_factor * 32767) for x in data]
187 nchan = 1
187 nchan = 1
188 return scaled, nchan
188 return scaled, nchan
189
189
190 @staticmethod
190 @staticmethod
191 def _get_normalization_factor(max_abs_value, normalize):
191 def _get_normalization_factor(max_abs_value, normalize):
192 if not normalize and max_abs_value > 1:
192 if not normalize and max_abs_value > 1:
193 raise ValueError('Audio data must be between -1 and 1 when normalize=False.')
193 raise ValueError('Audio data must be between -1 and 1 when normalize=False.')
194 return max_abs_value if normalize else 1
194 return max_abs_value if normalize else 1
195
195
196 def _data_and_metadata(self):
196 def _data_and_metadata(self):
197 """shortcut for returning metadata with url information, if defined"""
197 """shortcut for returning metadata with url information, if defined"""
198 md = {}
198 md = {}
199 if self.url:
199 if self.url:
200 md['url'] = self.url
200 md['url'] = self.url
201 if md:
201 if md:
202 return self.data, md
202 return self.data, md
203 else:
203 else:
204 return self.data
204 return self.data
205
205
206 def _repr_html_(self):
206 def _repr_html_(self):
207 src = """
207 src = """
208 <audio {element_id} controls="controls" {autoplay}>
208 <audio {element_id} controls="controls" {autoplay}>
209 <source src="{src}" type="{type}" />
209 <source src="{src}" type="{type}" />
210 Your browser does not support the audio element.
210 Your browser does not support the audio element.
211 </audio>
211 </audio>
212 """
212 """
213 return src.format(src=self.src_attr(), type=self.mimetype, autoplay=self.autoplay_attr(),
213 return src.format(src=self.src_attr(), type=self.mimetype, autoplay=self.autoplay_attr(),
214 element_id=self.element_id_attr())
214 element_id=self.element_id_attr())
215
215
216 def src_attr(self):
216 def src_attr(self):
217 import base64
217 import base64
218 if self.embed and (self.data is not None):
218 if self.embed and (self.data is not None):
219 data = base64=base64.b64encode(self.data).decode('ascii')
219 data = base64=base64.b64encode(self.data).decode('ascii')
220 return """data:{type};base64,{base64}""".format(type=self.mimetype,
220 return """data:{type};base64,{base64}""".format(type=self.mimetype,
221 base64=data)
221 base64=data)
222 elif self.url is not None:
222 elif self.url is not None:
223 return self.url
223 return self.url
224 else:
224 else:
225 return ""
225 return ""
226
226
227 def autoplay_attr(self):
227 def autoplay_attr(self):
228 if(self.autoplay):
228 if(self.autoplay):
229 return 'autoplay="autoplay"'
229 return 'autoplay="autoplay"'
230 else:
230 else:
231 return ''
231 return ''
232
232
233 def element_id_attr(self):
233 def element_id_attr(self):
234 if (self.element_id):
234 if (self.element_id):
235 return 'id="{element_id}"'.format(element_id=self.element_id)
235 return 'id="{element_id}"'.format(element_id=self.element_id)
236 else:
236 else:
237 return ''
237 return ''
238
238
239 class IFrame(object):
239 class IFrame(object):
240 """
240 """
241 Generic class to embed an iframe in an IPython notebook
241 Generic class to embed an iframe in an IPython notebook
242 """
242 """
243
243
244 iframe = """
244 iframe = """
245 <iframe
245 <iframe
246 width="{width}"
246 width="{width}"
247 height="{height}"
247 height="{height}"
248 src="{src}{params}"
248 src="{src}{params}"
249 frameborder="0"
249 frameborder="0"
250 allowfullscreen
250 allowfullscreen
251 ></iframe>
251 ></iframe>
252 """
252 """
253
253
254 def __init__(self, src, width, height, **kwargs):
254 def __init__(self, src, width, height, **kwargs):
255 self.src = src
255 self.src = src
256 self.width = width
256 self.width = width
257 self.height = height
257 self.height = height
258 self.params = kwargs
258 self.params = kwargs
259
259
260 def _repr_html_(self):
260 def _repr_html_(self):
261 """return the embed iframe"""
261 """return the embed iframe"""
262 if self.params:
262 if self.params:
263 try:
263 try:
264 from urllib.parse import urlencode # Py 3
264 from urllib.parse import urlencode # Py 3
265 except ImportError:
265 except ImportError:
266 from urllib import urlencode
266 from urllib import urlencode
267 params = "?" + urlencode(self.params)
267 params = "?" + urlencode(self.params)
268 else:
268 else:
269 params = ""
269 params = ""
270 return self.iframe.format(src=self.src,
270 return self.iframe.format(src=self.src,
271 width=self.width,
271 width=self.width,
272 height=self.height,
272 height=self.height,
273 params=params)
273 params=params)
274
274
275 class YouTubeVideo(IFrame):
275 class YouTubeVideo(IFrame):
276 """Class for embedding a YouTube Video in an IPython session, based on its video id.
276 """Class for embedding a YouTube Video in an IPython session, based on its video id.
277
277
278 e.g. to embed the video from https://www.youtube.com/watch?v=foo , you would
278 e.g. to embed the video from https://www.youtube.com/watch?v=foo , you would
279 do::
279 do::
280
280
281 vid = YouTubeVideo("foo")
281 vid = YouTubeVideo("foo")
282 display(vid)
282 display(vid)
283
283
284 To start from 30 seconds::
284 To start from 30 seconds::
285
285
286 vid = YouTubeVideo("abc", start=30)
286 vid = YouTubeVideo("abc", start=30)
287 display(vid)
287 display(vid)
288
288
289 To calculate seconds from time as hours, minutes, seconds use
289 To calculate seconds from time as hours, minutes, seconds use
290 :class:`datetime.timedelta`::
290 :class:`datetime.timedelta`::
291
291
292 start=int(timedelta(hours=1, minutes=46, seconds=40).total_seconds())
292 start=int(timedelta(hours=1, minutes=46, seconds=40).total_seconds())
293
293
294 Other parameters can be provided as documented at
294 Other parameters can be provided as documented at
295 https://developers.google.com/youtube/player_parameters#Parameters
295 https://developers.google.com/youtube/player_parameters#Parameters
296
296
297 When converting the notebook using nbconvert, a jpeg representation of the video
297 When converting the notebook using nbconvert, a jpeg representation of the video
298 will be inserted in the document.
298 will be inserted in the document.
299 """
299 """
300
300
301 def __init__(self, id, width=400, height=300, **kwargs):
301 def __init__(self, id, width=400, height=300, **kwargs):
302 self.id=id
302 self.id=id
303 src = "https://www.youtube.com/embed/{0}".format(id)
303 src = "https://www.youtube.com/embed/{0}".format(id)
304 super(YouTubeVideo, self).__init__(src, width, height, **kwargs)
304 super(YouTubeVideo, self).__init__(src, width, height, **kwargs)
305
305
306 def _repr_jpeg_(self):
306 def _repr_jpeg_(self):
307 # Deferred import
307 # Deferred import
308 from urllib.request import urlopen
308 from urllib.request import urlopen
309
309
310 try:
310 try:
311 return urlopen("https://img.youtube.com/vi/{id}/hqdefault.jpg".format(id=self.id)).read()
311 return urlopen("https://img.youtube.com/vi/{id}/hqdefault.jpg".format(id=self.id)).read()
312 except IOError:
312 except IOError:
313 return None
313 return None
314
314
315 class VimeoVideo(IFrame):
315 class VimeoVideo(IFrame):
316 """
316 """
317 Class for embedding a Vimeo video in an IPython session, based on its video id.
317 Class for embedding a Vimeo video in an IPython session, based on its video id.
318 """
318 """
319
319
320 def __init__(self, id, width=400, height=300, **kwargs):
320 def __init__(self, id, width=400, height=300, **kwargs):
321 src="https://player.vimeo.com/video/{0}".format(id)
321 src="https://player.vimeo.com/video/{0}".format(id)
322 super(VimeoVideo, self).__init__(src, width, height, **kwargs)
322 super(VimeoVideo, self).__init__(src, width, height, **kwargs)
323
323
324 class ScribdDocument(IFrame):
324 class ScribdDocument(IFrame):
325 """
325 """
326 Class for embedding a Scribd document in an IPython session
326 Class for embedding a Scribd document in an IPython session
327
327
328 Use the start_page params to specify a starting point in the document
328 Use the start_page params to specify a starting point in the document
329 Use the view_mode params to specify display type one off scroll | slideshow | book
329 Use the view_mode params to specify display type one off scroll | slideshow | book
330
330
331 e.g to Display Wes' foundational paper about PANDAS in book mode from page 3
331 e.g to Display Wes' foundational paper about PANDAS in book mode from page 3
332
332
333 ScribdDocument(71048089, width=800, height=400, start_page=3, view_mode="book")
333 ScribdDocument(71048089, width=800, height=400, start_page=3, view_mode="book")
334 """
334 """
335
335
336 def __init__(self, id, width=400, height=300, **kwargs):
336 def __init__(self, id, width=400, height=300, **kwargs):
337 src="https://www.scribd.com/embeds/{0}/content".format(id)
337 src="https://www.scribd.com/embeds/{0}/content".format(id)
338 super(ScribdDocument, self).__init__(src, width, height, **kwargs)
338 super(ScribdDocument, self).__init__(src, width, height, **kwargs)
339
339
340 class FileLink(object):
340 class FileLink(object):
341 """Class for embedding a local file link in an IPython session, based on path
341 """Class for embedding a local file link in an IPython session, based on path
342
342
343 e.g. to embed a link that was generated in the IPython notebook as my/data.txt
343 e.g. to embed a link that was generated in the IPython notebook as my/data.txt
344
344
345 you would do::
345 you would do::
346
346
347 local_file = FileLink("my/data.txt")
347 local_file = FileLink("my/data.txt")
348 display(local_file)
348 display(local_file)
349
349
350 or in the HTML notebook, just::
350 or in the HTML notebook, just::
351
351
352 FileLink("my/data.txt")
352 FileLink("my/data.txt")
353 """
353 """
354
354
355 html_link_str = "<a href='%s' target='_blank'>%s</a>"
355 html_link_str = "<a href='%s' target='_blank'>%s</a>"
356
356
357 def __init__(self,
357 def __init__(self,
358 path,
358 path,
359 url_prefix='',
359 url_prefix='',
360 result_html_prefix='',
360 result_html_prefix='',
361 result_html_suffix='<br>'):
361 result_html_suffix='<br>'):
362 """
362 """
363 Parameters
363 Parameters
364 ----------
364 ----------
365 path : str
365 path : str
366 path to the file or directory that should be formatted
366 path to the file or directory that should be formatted
367 url_prefix : str
367 url_prefix : str
368 prefix to be prepended to all files to form a working link [default:
368 prefix to be prepended to all files to form a working link [default:
369 '']
369 '']
370 result_html_prefix : str
370 result_html_prefix : str
371 text to append to beginning to link [default: '']
371 text to append to beginning to link [default: '']
372 result_html_suffix : str
372 result_html_suffix : str
373 text to append at the end of link [default: '<br>']
373 text to append at the end of link [default: '<br>']
374 """
374 """
375 if isdir(path):
375 if isdir(path):
376 raise ValueError("Cannot display a directory using FileLink. "
376 raise ValueError("Cannot display a directory using FileLink. "
377 "Use FileLinks to display '%s'." % path)
377 "Use FileLinks to display '%s'." % path)
378 self.path = fsdecode(path)
378 self.path = fsdecode(path)
379 self.url_prefix = url_prefix
379 self.url_prefix = url_prefix
380 self.result_html_prefix = result_html_prefix
380 self.result_html_prefix = result_html_prefix
381 self.result_html_suffix = result_html_suffix
381 self.result_html_suffix = result_html_suffix
382
382
383 def _format_path(self):
383 def _format_path(self):
384 fp = ''.join([self.url_prefix, html_escape(self.path)])
384 fp = ''.join([self.url_prefix, html_escape(self.path)])
385 return ''.join([self.result_html_prefix,
385 return ''.join([self.result_html_prefix,
386 self.html_link_str % \
386 self.html_link_str % \
387 (fp, html_escape(self.path, quote=False)),
387 (fp, html_escape(self.path, quote=False)),
388 self.result_html_suffix])
388 self.result_html_suffix])
389
389
390 def _repr_html_(self):
390 def _repr_html_(self):
391 """return html link to file
391 """return html link to file
392 """
392 """
393 if not exists(self.path):
393 if not exists(self.path):
394 return ("Path (<tt>%s</tt>) doesn't exist. "
394 return ("Path (<tt>%s</tt>) doesn't exist. "
395 "It may still be in the process of "
395 "It may still be in the process of "
396 "being generated, or you may have the "
396 "being generated, or you may have the "
397 "incorrect path." % self.path)
397 "incorrect path." % self.path)
398
398
399 return self._format_path()
399 return self._format_path()
400
400
401 def __repr__(self):
401 def __repr__(self):
402 """return absolute path to file
402 """return absolute path to file
403 """
403 """
404 return abspath(self.path)
404 return abspath(self.path)
405
405
406 class FileLinks(FileLink):
406 class FileLinks(FileLink):
407 """Class for embedding local file links in an IPython session, based on path
407 """Class for embedding local file links in an IPython session, based on path
408
408
409 e.g. to embed links to files that were generated in the IPython notebook
409 e.g. to embed links to files that were generated in the IPython notebook
410 under ``my/data``, you would do::
410 under ``my/data``, you would do::
411
411
412 local_files = FileLinks("my/data")
412 local_files = FileLinks("my/data")
413 display(local_files)
413 display(local_files)
414
414
415 or in the HTML notebook, just::
415 or in the HTML notebook, just::
416
416
417 FileLinks("my/data")
417 FileLinks("my/data")
418 """
418 """
419 def __init__(self,
419 def __init__(self,
420 path,
420 path,
421 url_prefix='',
421 url_prefix='',
422 included_suffixes=None,
422 included_suffixes=None,
423 result_html_prefix='',
423 result_html_prefix='',
424 result_html_suffix='<br>',
424 result_html_suffix='<br>',
425 notebook_display_formatter=None,
425 notebook_display_formatter=None,
426 terminal_display_formatter=None,
426 terminal_display_formatter=None,
427 recursive=True):
427 recursive=True):
428 """
428 """
429 See :class:`FileLink` for the ``path``, ``url_prefix``,
429 See :class:`FileLink` for the ``path``, ``url_prefix``,
430 ``result_html_prefix`` and ``result_html_suffix`` parameters.
430 ``result_html_prefix`` and ``result_html_suffix`` parameters.
431
431
432 included_suffixes : list
432 included_suffixes : list
433 Filename suffixes to include when formatting output [default: include
433 Filename suffixes to include when formatting output [default: include
434 all files]
434 all files]
435
435
436 notebook_display_formatter : function
436 notebook_display_formatter : function
437 Used to format links for display in the notebook. See discussion of
437 Used to format links for display in the notebook. See discussion of
438 formatter functions below.
438 formatter functions below.
439
439
440 terminal_display_formatter : function
440 terminal_display_formatter : function
441 Used to format links for display in the terminal. See discussion of
441 Used to format links for display in the terminal. See discussion of
442 formatter functions below.
442 formatter functions below.
443
443
444 Formatter functions must be of the form::
444 Formatter functions must be of the form::
445
445
446 f(dirname, fnames, included_suffixes)
446 f(dirname, fnames, included_suffixes)
447
447
448 dirname : str
448 dirname : str
449 The name of a directory
449 The name of a directory
450 fnames : list
450 fnames : list
451 The files in that directory
451 The files in that directory
452 included_suffixes : list
452 included_suffixes : list
453 The file suffixes that should be included in the output (passing None
453 The file suffixes that should be included in the output (passing None
454 meansto include all suffixes in the output in the built-in formatters)
454 meansto include all suffixes in the output in the built-in formatters)
455 recursive : boolean
455 recursive : boolean
456 Whether to recurse into subdirectories. Default is True.
456 Whether to recurse into subdirectories. Default is True.
457
457
458 The function should return a list of lines that will be printed in the
458 The function should return a list of lines that will be printed in the
459 notebook (if passing notebook_display_formatter) or the terminal (if
459 notebook (if passing notebook_display_formatter) or the terminal (if
460 passing terminal_display_formatter). This function is iterated over for
460 passing terminal_display_formatter). This function is iterated over for
461 each directory in self.path. Default formatters are in place, can be
461 each directory in self.path. Default formatters are in place, can be
462 passed here to support alternative formatting.
462 passed here to support alternative formatting.
463
463
464 """
464 """
465 if isfile(path):
465 if isfile(path):
466 raise ValueError("Cannot display a file using FileLinks. "
466 raise ValueError("Cannot display a file using FileLinks. "
467 "Use FileLink to display '%s'." % path)
467 "Use FileLink to display '%s'." % path)
468 self.included_suffixes = included_suffixes
468 self.included_suffixes = included_suffixes
469 # remove trailing slashes for more consistent output formatting
469 # remove trailing slashes for more consistent output formatting
470 path = path.rstrip('/')
470 path = path.rstrip('/')
471
471
472 self.path = path
472 self.path = path
473 self.url_prefix = url_prefix
473 self.url_prefix = url_prefix
474 self.result_html_prefix = result_html_prefix
474 self.result_html_prefix = result_html_prefix
475 self.result_html_suffix = result_html_suffix
475 self.result_html_suffix = result_html_suffix
476
476
477 self.notebook_display_formatter = \
477 self.notebook_display_formatter = \
478 notebook_display_formatter or self._get_notebook_display_formatter()
478 notebook_display_formatter or self._get_notebook_display_formatter()
479 self.terminal_display_formatter = \
479 self.terminal_display_formatter = \
480 terminal_display_formatter or self._get_terminal_display_formatter()
480 terminal_display_formatter or self._get_terminal_display_formatter()
481
481
482 self.recursive = recursive
482 self.recursive = recursive
483
483
484 def _get_display_formatter(self,
484 def _get_display_formatter(self,
485 dirname_output_format,
485 dirname_output_format,
486 fname_output_format,
486 fname_output_format,
487 fp_format,
487 fp_format,
488 fp_cleaner=None):
488 fp_cleaner=None):
489 """ generate built-in formatter function
489 """ generate built-in formatter function
490
490
491 this is used to define both the notebook and terminal built-in
491 this is used to define both the notebook and terminal built-in
492 formatters as they only differ by some wrapper text for each entry
492 formatters as they only differ by some wrapper text for each entry
493
493
494 dirname_output_format: string to use for formatting directory
494 dirname_output_format: string to use for formatting directory
495 names, dirname will be substituted for a single "%s" which
495 names, dirname will be substituted for a single "%s" which
496 must appear in this string
496 must appear in this string
497 fname_output_format: string to use for formatting file names,
497 fname_output_format: string to use for formatting file names,
498 if a single "%s" appears in the string, fname will be substituted
498 if a single "%s" appears in the string, fname will be substituted
499 if two "%s" appear in the string, the path to fname will be
499 if two "%s" appear in the string, the path to fname will be
500 substituted for the first and fname will be substituted for the
500 substituted for the first and fname will be substituted for the
501 second
501 second
502 fp_format: string to use for formatting filepaths, must contain
502 fp_format: string to use for formatting filepaths, must contain
503 exactly two "%s" and the dirname will be subsituted for the first
503 exactly two "%s" and the dirname will be substituted for the first
504 and fname will be substituted for the second
504 and fname will be substituted for the second
505 """
505 """
506 def f(dirname, fnames, included_suffixes=None):
506 def f(dirname, fnames, included_suffixes=None):
507 result = []
507 result = []
508 # begin by figuring out which filenames, if any,
508 # begin by figuring out which filenames, if any,
509 # are going to be displayed
509 # are going to be displayed
510 display_fnames = []
510 display_fnames = []
511 for fname in fnames:
511 for fname in fnames:
512 if (isfile(join(dirname,fname)) and
512 if (isfile(join(dirname,fname)) and
513 (included_suffixes is None or
513 (included_suffixes is None or
514 splitext(fname)[1] in included_suffixes)):
514 splitext(fname)[1] in included_suffixes)):
515 display_fnames.append(fname)
515 display_fnames.append(fname)
516
516
517 if len(display_fnames) == 0:
517 if len(display_fnames) == 0:
518 # if there are no filenames to display, don't print anything
518 # if there are no filenames to display, don't print anything
519 # (not even the directory name)
519 # (not even the directory name)
520 pass
520 pass
521 else:
521 else:
522 # otherwise print the formatted directory name followed by
522 # otherwise print the formatted directory name followed by
523 # the formatted filenames
523 # the formatted filenames
524 dirname_output_line = dirname_output_format % dirname
524 dirname_output_line = dirname_output_format % dirname
525 result.append(dirname_output_line)
525 result.append(dirname_output_line)
526 for fname in display_fnames:
526 for fname in display_fnames:
527 fp = fp_format % (dirname,fname)
527 fp = fp_format % (dirname,fname)
528 if fp_cleaner is not None:
528 if fp_cleaner is not None:
529 fp = fp_cleaner(fp)
529 fp = fp_cleaner(fp)
530 try:
530 try:
531 # output can include both a filepath and a filename...
531 # output can include both a filepath and a filename...
532 fname_output_line = fname_output_format % (fp, fname)
532 fname_output_line = fname_output_format % (fp, fname)
533 except TypeError:
533 except TypeError:
534 # ... or just a single filepath
534 # ... or just a single filepath
535 fname_output_line = fname_output_format % fname
535 fname_output_line = fname_output_format % fname
536 result.append(fname_output_line)
536 result.append(fname_output_line)
537 return result
537 return result
538 return f
538 return f
539
539
540 def _get_notebook_display_formatter(self,
540 def _get_notebook_display_formatter(self,
541 spacer="&nbsp;&nbsp;"):
541 spacer="&nbsp;&nbsp;"):
542 """ generate function to use for notebook formatting
542 """ generate function to use for notebook formatting
543 """
543 """
544 dirname_output_format = \
544 dirname_output_format = \
545 self.result_html_prefix + "%s/" + self.result_html_suffix
545 self.result_html_prefix + "%s/" + self.result_html_suffix
546 fname_output_format = \
546 fname_output_format = \
547 self.result_html_prefix + spacer + self.html_link_str + self.result_html_suffix
547 self.result_html_prefix + spacer + self.html_link_str + self.result_html_suffix
548 fp_format = self.url_prefix + '%s/%s'
548 fp_format = self.url_prefix + '%s/%s'
549 if sep == "\\":
549 if sep == "\\":
550 # Working on a platform where the path separator is "\", so
550 # Working on a platform where the path separator is "\", so
551 # must convert these to "/" for generating a URI
551 # must convert these to "/" for generating a URI
552 def fp_cleaner(fp):
552 def fp_cleaner(fp):
553 # Replace all occurrences of backslash ("\") with a forward
553 # Replace all occurrences of backslash ("\") with a forward
554 # slash ("/") - this is necessary on windows when a path is
554 # slash ("/") - this is necessary on windows when a path is
555 # provided as input, but we must link to a URI
555 # provided as input, but we must link to a URI
556 return fp.replace('\\','/')
556 return fp.replace('\\','/')
557 else:
557 else:
558 fp_cleaner = None
558 fp_cleaner = None
559
559
560 return self._get_display_formatter(dirname_output_format,
560 return self._get_display_formatter(dirname_output_format,
561 fname_output_format,
561 fname_output_format,
562 fp_format,
562 fp_format,
563 fp_cleaner)
563 fp_cleaner)
564
564
565 def _get_terminal_display_formatter(self,
565 def _get_terminal_display_formatter(self,
566 spacer=" "):
566 spacer=" "):
567 """ generate function to use for terminal formatting
567 """ generate function to use for terminal formatting
568 """
568 """
569 dirname_output_format = "%s/"
569 dirname_output_format = "%s/"
570 fname_output_format = spacer + "%s"
570 fname_output_format = spacer + "%s"
571 fp_format = '%s/%s'
571 fp_format = '%s/%s'
572
572
573 return self._get_display_formatter(dirname_output_format,
573 return self._get_display_formatter(dirname_output_format,
574 fname_output_format,
574 fname_output_format,
575 fp_format)
575 fp_format)
576
576
577 def _format_path(self):
577 def _format_path(self):
578 result_lines = []
578 result_lines = []
579 if self.recursive:
579 if self.recursive:
580 walked_dir = list(walk(self.path))
580 walked_dir = list(walk(self.path))
581 else:
581 else:
582 walked_dir = [next(walk(self.path))]
582 walked_dir = [next(walk(self.path))]
583 walked_dir.sort()
583 walked_dir.sort()
584 for dirname, subdirs, fnames in walked_dir:
584 for dirname, subdirs, fnames in walked_dir:
585 result_lines += self.notebook_display_formatter(dirname, fnames, self.included_suffixes)
585 result_lines += self.notebook_display_formatter(dirname, fnames, self.included_suffixes)
586 return '\n'.join(result_lines)
586 return '\n'.join(result_lines)
587
587
588 def __repr__(self):
588 def __repr__(self):
589 """return newline-separated absolute paths
589 """return newline-separated absolute paths
590 """
590 """
591 result_lines = []
591 result_lines = []
592 if self.recursive:
592 if self.recursive:
593 walked_dir = list(walk(self.path))
593 walked_dir = list(walk(self.path))
594 else:
594 else:
595 walked_dir = [next(walk(self.path))]
595 walked_dir = [next(walk(self.path))]
596 walked_dir.sort()
596 walked_dir.sort()
597 for dirname, subdirs, fnames in walked_dir:
597 for dirname, subdirs, fnames in walked_dir:
598 result_lines += self.terminal_display_formatter(dirname, fnames, self.included_suffixes)
598 result_lines += self.terminal_display_formatter(dirname, fnames, self.included_suffixes)
599 return '\n'.join(result_lines)
599 return '\n'.join(result_lines)
600
600
601
601
602 class Code(TextDisplayObject):
602 class Code(TextDisplayObject):
603 """Display syntax-highlighted source code.
603 """Display syntax-highlighted source code.
604
604
605 This uses Pygments to highlight the code for HTML and Latex output.
605 This uses Pygments to highlight the code for HTML and Latex output.
606
606
607 Parameters
607 Parameters
608 ----------
608 ----------
609 data : str
609 data : str
610 The code as a string
610 The code as a string
611 url : str
611 url : str
612 A URL to fetch the code from
612 A URL to fetch the code from
613 filename : str
613 filename : str
614 A local filename to load the code from
614 A local filename to load the code from
615 language : str
615 language : str
616 The short name of a Pygments lexer to use for highlighting.
616 The short name of a Pygments lexer to use for highlighting.
617 If not specified, it will guess the lexer based on the filename
617 If not specified, it will guess the lexer based on the filename
618 or the code. Available lexers: http://pygments.org/docs/lexers/
618 or the code. Available lexers: http://pygments.org/docs/lexers/
619 """
619 """
620 def __init__(self, data=None, url=None, filename=None, language=None):
620 def __init__(self, data=None, url=None, filename=None, language=None):
621 self.language = language
621 self.language = language
622 super().__init__(data=data, url=url, filename=filename)
622 super().__init__(data=data, url=url, filename=filename)
623
623
624 def _get_lexer(self):
624 def _get_lexer(self):
625 if self.language:
625 if self.language:
626 from pygments.lexers import get_lexer_by_name
626 from pygments.lexers import get_lexer_by_name
627 return get_lexer_by_name(self.language)
627 return get_lexer_by_name(self.language)
628 elif self.filename:
628 elif self.filename:
629 from pygments.lexers import get_lexer_for_filename
629 from pygments.lexers import get_lexer_for_filename
630 return get_lexer_for_filename(self.filename)
630 return get_lexer_for_filename(self.filename)
631 else:
631 else:
632 from pygments.lexers import guess_lexer
632 from pygments.lexers import guess_lexer
633 return guess_lexer(self.data)
633 return guess_lexer(self.data)
634
634
635 def __repr__(self):
635 def __repr__(self):
636 return self.data
636 return self.data
637
637
638 def _repr_html_(self):
638 def _repr_html_(self):
639 from pygments import highlight
639 from pygments import highlight
640 from pygments.formatters import HtmlFormatter
640 from pygments.formatters import HtmlFormatter
641 fmt = HtmlFormatter()
641 fmt = HtmlFormatter()
642 style = '<style>{}</style>'.format(fmt.get_style_defs('.output_html'))
642 style = '<style>{}</style>'.format(fmt.get_style_defs('.output_html'))
643 return style + highlight(self.data, self._get_lexer(), fmt)
643 return style + highlight(self.data, self._get_lexer(), fmt)
644
644
645 def _repr_latex_(self):
645 def _repr_latex_(self):
646 from pygments import highlight
646 from pygments import highlight
647 from pygments.formatters import LatexFormatter
647 from pygments.formatters import LatexFormatter
648 return highlight(self.data, self._get_lexer(), LatexFormatter())
648 return highlight(self.data, self._get_lexer(), LatexFormatter())
@@ -1,35 +1,35 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Enable pygtk to be used interacive by setting PyOS_InputHook.
3 Enable pygtk to be used interactively by setting PyOS_InputHook.
4
4
5 Authors: Brian Granger
5 Authors: Brian Granger
6 """
6 """
7
7
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2008-2011 The IPython Development Team
9 # Copyright (C) 2008-2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
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 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 import sys
19 import sys
20 import gtk, gobject
20 import gtk, gobject
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Code
23 # Code
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26
26
27 def _main_quit(*args, **kwargs):
27 def _main_quit(*args, **kwargs):
28 gtk.main_quit()
28 gtk.main_quit()
29 return False
29 return False
30
30
31 def inputhook_gtk():
31 def inputhook_gtk():
32 gobject.io_add_watch(sys.stdin, gobject.IO_IN, _main_quit)
32 gobject.io_add_watch(sys.stdin, gobject.IO_IN, _main_quit)
33 gtk.main()
33 gtk.main()
34 return 0
34 return 0
35
35
@@ -1,34 +1,34 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Enable Gtk3 to be used interacive by IPython.
3 Enable Gtk3 to be used interactively by IPython.
4
4
5 Authors: Thomi Richards
5 Authors: Thomi Richards
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2012, the IPython Development Team.
8 # Copyright (c) 2012, the IPython Development Team.
9 #
9 #
10 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
11 #
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 import sys
19 import sys
20 from gi.repository import Gtk, GLib
20 from gi.repository import Gtk, GLib
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Code
23 # Code
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 def _main_quit(*args, **kwargs):
26 def _main_quit(*args, **kwargs):
27 Gtk.main_quit()
27 Gtk.main_quit()
28 return False
28 return False
29
29
30
30
31 def inputhook_gtk3():
31 def inputhook_gtk3():
32 GLib.io_add_watch(sys.stdin, GLib.PRIORITY_DEFAULT, GLib.IO_IN, _main_quit)
32 GLib.io_add_watch(sys.stdin, GLib.PRIORITY_DEFAULT, GLib.IO_IN, _main_quit)
33 Gtk.main()
33 Gtk.main()
34 return 0
34 return 0
@@ -1,111 +1,111 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Enable pyglet to be used interacive by setting PyOS_InputHook.
3 Enable pyglet to be used interactively by setting PyOS_InputHook.
4
4
5 Authors
5 Authors
6 -------
6 -------
7
7
8 * Nicolas P. Rougier
8 * Nicolas P. Rougier
9 * Fernando Perez
9 * Fernando Perez
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2011 The IPython Development Team
13 # Copyright (C) 2008-2011 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import os
23 import os
24 import sys
24 import sys
25 import time
25 import time
26 from timeit import default_timer as clock
26 from timeit import default_timer as clock
27 import pyglet
27 import pyglet
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Platform-dependent imports and functions
30 # Platform-dependent imports and functions
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33 if os.name == 'posix':
33 if os.name == 'posix':
34 import select
34 import select
35
35
36 def stdin_ready():
36 def stdin_ready():
37 infds, outfds, erfds = select.select([sys.stdin],[],[],0)
37 infds, outfds, erfds = select.select([sys.stdin],[],[],0)
38 if infds:
38 if infds:
39 return True
39 return True
40 else:
40 else:
41 return False
41 return False
42
42
43 elif sys.platform == 'win32':
43 elif sys.platform == 'win32':
44 import msvcrt
44 import msvcrt
45
45
46 def stdin_ready():
46 def stdin_ready():
47 return msvcrt.kbhit()
47 return msvcrt.kbhit()
48
48
49
49
50 # On linux only, window.flip() has a bug that causes an AttributeError on
50 # On linux only, window.flip() has a bug that causes an AttributeError on
51 # window close. For details, see:
51 # window close. For details, see:
52 # http://groups.google.com/group/pyglet-users/browse_thread/thread/47c1aab9aa4a3d23/c22f9e819826799e?#c22f9e819826799e
52 # http://groups.google.com/group/pyglet-users/browse_thread/thread/47c1aab9aa4a3d23/c22f9e819826799e?#c22f9e819826799e
53
53
54 if sys.platform.startswith('linux'):
54 if sys.platform.startswith('linux'):
55 def flip(window):
55 def flip(window):
56 try:
56 try:
57 window.flip()
57 window.flip()
58 except AttributeError:
58 except AttributeError:
59 pass
59 pass
60 else:
60 else:
61 def flip(window):
61 def flip(window):
62 window.flip()
62 window.flip()
63
63
64 #-----------------------------------------------------------------------------
64 #-----------------------------------------------------------------------------
65 # Code
65 # Code
66 #-----------------------------------------------------------------------------
66 #-----------------------------------------------------------------------------
67
67
68 def inputhook_pyglet():
68 def inputhook_pyglet():
69 """Run the pyglet event loop by processing pending events only.
69 """Run the pyglet event loop by processing pending events only.
70
70
71 This keeps processing pending events until stdin is ready. After
71 This keeps processing pending events until stdin is ready. After
72 processing all pending events, a call to time.sleep is inserted. This is
72 processing all pending events, a call to time.sleep is inserted. This is
73 needed, otherwise, CPU usage is at 100%. This sleep time should be tuned
73 needed, otherwise, CPU usage is at 100%. This sleep time should be tuned
74 though for best performance.
74 though for best performance.
75 """
75 """
76 # We need to protect against a user pressing Control-C when IPython is
76 # We need to protect against a user pressing Control-C when IPython is
77 # idle and this is running. We trap KeyboardInterrupt and pass.
77 # idle and this is running. We trap KeyboardInterrupt and pass.
78 try:
78 try:
79 t = clock()
79 t = clock()
80 while not stdin_ready():
80 while not stdin_ready():
81 pyglet.clock.tick()
81 pyglet.clock.tick()
82 for window in pyglet.app.windows:
82 for window in pyglet.app.windows:
83 window.switch_to()
83 window.switch_to()
84 window.dispatch_events()
84 window.dispatch_events()
85 window.dispatch_event('on_draw')
85 window.dispatch_event('on_draw')
86 flip(window)
86 flip(window)
87
87
88 # We need to sleep at this point to keep the idle CPU load
88 # We need to sleep at this point to keep the idle CPU load
89 # low. However, if sleep to long, GUI response is poor. As
89 # low. However, if sleep to long, GUI response is poor. As
90 # a compromise, we watch how often GUI events are being processed
90 # a compromise, we watch how often GUI events are being processed
91 # and switch between a short and long sleep time. Here are some
91 # and switch between a short and long sleep time. Here are some
92 # stats useful in helping to tune this.
92 # stats useful in helping to tune this.
93 # time CPU load
93 # time CPU load
94 # 0.001 13%
94 # 0.001 13%
95 # 0.005 3%
95 # 0.005 3%
96 # 0.01 1.5%
96 # 0.01 1.5%
97 # 0.05 0.5%
97 # 0.05 0.5%
98 used_time = clock() - t
98 used_time = clock() - t
99 if used_time > 10.0:
99 if used_time > 10.0:
100 # print 'Sleep for 1 s' # dbg
100 # print 'Sleep for 1 s' # dbg
101 time.sleep(1.0)
101 time.sleep(1.0)
102 elif used_time > 0.1:
102 elif used_time > 0.1:
103 # Few GUI events coming in, so we can sleep longer
103 # Few GUI events coming in, so we can sleep longer
104 # print 'Sleep for 0.05 s' # dbg
104 # print 'Sleep for 0.05 s' # dbg
105 time.sleep(0.05)
105 time.sleep(0.05)
106 else:
106 else:
107 # Many GUI events coming in, so sleep only very little
107 # Many GUI events coming in, so sleep only very little
108 time.sleep(0.001)
108 time.sleep(0.001)
109 except KeyboardInterrupt:
109 except KeyboardInterrupt:
110 pass
110 pass
111 return 0
111 return 0
@@ -1,167 +1,167 b''
1 # encoding: utf-8
1 # encoding: utf-8
2
2
3 """
3 """
4 Enable wxPython to be used interacive by setting PyOS_InputHook.
4 Enable wxPython to be used interactively by setting PyOS_InputHook.
5
5
6 Authors: Robin Dunn, Brian Granger, Ondrej Certik
6 Authors: Robin Dunn, Brian Granger, Ondrej Certik
7 """
7 """
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2008-2011 The IPython Development Team
10 # Copyright (C) 2008-2011 The IPython Development Team
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Imports
17 # Imports
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 import sys
20 import sys
21 import signal
21 import signal
22 import time
22 import time
23 from timeit import default_timer as clock
23 from timeit import default_timer as clock
24 import wx
24 import wx
25
25
26 from IPython.lib.inputhook import stdin_ready
26 from IPython.lib.inputhook import stdin_ready
27
27
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Code
30 # Code
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33 def inputhook_wx1():
33 def inputhook_wx1():
34 """Run the wx event loop by processing pending events only.
34 """Run the wx event loop by processing pending events only.
35
35
36 This approach seems to work, but its performance is not great as it
36 This approach seems to work, but its performance is not great as it
37 relies on having PyOS_InputHook called regularly.
37 relies on having PyOS_InputHook called regularly.
38 """
38 """
39 try:
39 try:
40 app = wx.GetApp()
40 app = wx.GetApp()
41 if app is not None:
41 if app is not None:
42 assert wx.Thread_IsMain()
42 assert wx.Thread_IsMain()
43
43
44 # Make a temporary event loop and process system events until
44 # Make a temporary event loop and process system events until
45 # there are no more waiting, then allow idle events (which
45 # there are no more waiting, then allow idle events (which
46 # will also deal with pending or posted wx events.)
46 # will also deal with pending or posted wx events.)
47 evtloop = wx.EventLoop()
47 evtloop = wx.EventLoop()
48 ea = wx.EventLoopActivator(evtloop)
48 ea = wx.EventLoopActivator(evtloop)
49 while evtloop.Pending():
49 while evtloop.Pending():
50 evtloop.Dispatch()
50 evtloop.Dispatch()
51 app.ProcessIdle()
51 app.ProcessIdle()
52 del ea
52 del ea
53 except KeyboardInterrupt:
53 except KeyboardInterrupt:
54 pass
54 pass
55 return 0
55 return 0
56
56
57 class EventLoopTimer(wx.Timer):
57 class EventLoopTimer(wx.Timer):
58
58
59 def __init__(self, func):
59 def __init__(self, func):
60 self.func = func
60 self.func = func
61 wx.Timer.__init__(self)
61 wx.Timer.__init__(self)
62
62
63 def Notify(self):
63 def Notify(self):
64 self.func()
64 self.func()
65
65
66 class EventLoopRunner(object):
66 class EventLoopRunner(object):
67
67
68 def Run(self, time):
68 def Run(self, time):
69 self.evtloop = wx.EventLoop()
69 self.evtloop = wx.EventLoop()
70 self.timer = EventLoopTimer(self.check_stdin)
70 self.timer = EventLoopTimer(self.check_stdin)
71 self.timer.Start(time)
71 self.timer.Start(time)
72 self.evtloop.Run()
72 self.evtloop.Run()
73
73
74 def check_stdin(self):
74 def check_stdin(self):
75 if stdin_ready():
75 if stdin_ready():
76 self.timer.Stop()
76 self.timer.Stop()
77 self.evtloop.Exit()
77 self.evtloop.Exit()
78
78
79 def inputhook_wx2():
79 def inputhook_wx2():
80 """Run the wx event loop, polling for stdin.
80 """Run the wx event loop, polling for stdin.
81
81
82 This version runs the wx eventloop for an undetermined amount of time,
82 This version runs the wx eventloop for an undetermined amount of time,
83 during which it periodically checks to see if anything is ready on
83 during which it periodically checks to see if anything is ready on
84 stdin. If anything is ready on stdin, the event loop exits.
84 stdin. If anything is ready on stdin, the event loop exits.
85
85
86 The argument to elr.Run controls how often the event loop looks at stdin.
86 The argument to elr.Run controls how often the event loop looks at stdin.
87 This determines the responsiveness at the keyboard. A setting of 1000
87 This determines the responsiveness at the keyboard. A setting of 1000
88 enables a user to type at most 1 char per second. I have found that a
88 enables a user to type at most 1 char per second. I have found that a
89 setting of 10 gives good keyboard response. We can shorten it further,
89 setting of 10 gives good keyboard response. We can shorten it further,
90 but eventually performance would suffer from calling select/kbhit too
90 but eventually performance would suffer from calling select/kbhit too
91 often.
91 often.
92 """
92 """
93 try:
93 try:
94 app = wx.GetApp()
94 app = wx.GetApp()
95 if app is not None:
95 if app is not None:
96 assert wx.Thread_IsMain()
96 assert wx.Thread_IsMain()
97 elr = EventLoopRunner()
97 elr = EventLoopRunner()
98 # As this time is made shorter, keyboard response improves, but idle
98 # As this time is made shorter, keyboard response improves, but idle
99 # CPU load goes up. 10 ms seems like a good compromise.
99 # CPU load goes up. 10 ms seems like a good compromise.
100 elr.Run(time=10) # CHANGE time here to control polling interval
100 elr.Run(time=10) # CHANGE time here to control polling interval
101 except KeyboardInterrupt:
101 except KeyboardInterrupt:
102 pass
102 pass
103 return 0
103 return 0
104
104
105 def inputhook_wx3():
105 def inputhook_wx3():
106 """Run the wx event loop by processing pending events only.
106 """Run the wx event loop by processing pending events only.
107
107
108 This is like inputhook_wx1, but it keeps processing pending events
108 This is like inputhook_wx1, but it keeps processing pending events
109 until stdin is ready. After processing all pending events, a call to
109 until stdin is ready. After processing all pending events, a call to
110 time.sleep is inserted. This is needed, otherwise, CPU usage is at 100%.
110 time.sleep is inserted. This is needed, otherwise, CPU usage is at 100%.
111 This sleep time should be tuned though for best performance.
111 This sleep time should be tuned though for best performance.
112 """
112 """
113 # We need to protect against a user pressing Control-C when IPython is
113 # We need to protect against a user pressing Control-C when IPython is
114 # idle and this is running. We trap KeyboardInterrupt and pass.
114 # idle and this is running. We trap KeyboardInterrupt and pass.
115 try:
115 try:
116 app = wx.GetApp()
116 app = wx.GetApp()
117 if app is not None:
117 if app is not None:
118 assert wx.Thread_IsMain()
118 assert wx.Thread_IsMain()
119
119
120 # The import of wx on Linux sets the handler for signal.SIGINT
120 # The import of wx on Linux sets the handler for signal.SIGINT
121 # to 0. This is a bug in wx or gtk. We fix by just setting it
121 # to 0. This is a bug in wx or gtk. We fix by just setting it
122 # back to the Python default.
122 # back to the Python default.
123 if not callable(signal.getsignal(signal.SIGINT)):
123 if not callable(signal.getsignal(signal.SIGINT)):
124 signal.signal(signal.SIGINT, signal.default_int_handler)
124 signal.signal(signal.SIGINT, signal.default_int_handler)
125
125
126 evtloop = wx.EventLoop()
126 evtloop = wx.EventLoop()
127 ea = wx.EventLoopActivator(evtloop)
127 ea = wx.EventLoopActivator(evtloop)
128 t = clock()
128 t = clock()
129 while not stdin_ready():
129 while not stdin_ready():
130 while evtloop.Pending():
130 while evtloop.Pending():
131 t = clock()
131 t = clock()
132 evtloop.Dispatch()
132 evtloop.Dispatch()
133 app.ProcessIdle()
133 app.ProcessIdle()
134 # We need to sleep at this point to keep the idle CPU load
134 # We need to sleep at this point to keep the idle CPU load
135 # low. However, if sleep to long, GUI response is poor. As
135 # low. However, if sleep to long, GUI response is poor. As
136 # a compromise, we watch how often GUI events are being processed
136 # a compromise, we watch how often GUI events are being processed
137 # and switch between a short and long sleep time. Here are some
137 # and switch between a short and long sleep time. Here are some
138 # stats useful in helping to tune this.
138 # stats useful in helping to tune this.
139 # time CPU load
139 # time CPU load
140 # 0.001 13%
140 # 0.001 13%
141 # 0.005 3%
141 # 0.005 3%
142 # 0.01 1.5%
142 # 0.01 1.5%
143 # 0.05 0.5%
143 # 0.05 0.5%
144 used_time = clock() - t
144 used_time = clock() - t
145 if used_time > 10.0:
145 if used_time > 10.0:
146 # print 'Sleep for 1 s' # dbg
146 # print 'Sleep for 1 s' # dbg
147 time.sleep(1.0)
147 time.sleep(1.0)
148 elif used_time > 0.1:
148 elif used_time > 0.1:
149 # Few GUI events coming in, so we can sleep longer
149 # Few GUI events coming in, so we can sleep longer
150 # print 'Sleep for 0.05 s' # dbg
150 # print 'Sleep for 0.05 s' # dbg
151 time.sleep(0.05)
151 time.sleep(0.05)
152 else:
152 else:
153 # Many GUI events coming in, so sleep only very little
153 # Many GUI events coming in, so sleep only very little
154 time.sleep(0.001)
154 time.sleep(0.001)
155 del ea
155 del ea
156 except KeyboardInterrupt:
156 except KeyboardInterrupt:
157 pass
157 pass
158 return 0
158 return 0
159
159
160 if sys.platform == 'darwin':
160 if sys.platform == 'darwin':
161 # On OSX, evtloop.Pending() always returns True, regardless of there being
161 # On OSX, evtloop.Pending() always returns True, regardless of there being
162 # any events pending. As such we can't use implementations 1 or 3 of the
162 # any events pending. As such we can't use implementations 1 or 3 of the
163 # inputhook as those depend on a pending/dispatch loop.
163 # inputhook as those depend on a pending/dispatch loop.
164 inputhook_wx = inputhook_wx2
164 inputhook_wx = inputhook_wx2
165 else:
165 else:
166 # This is our default implementation
166 # This is our default implementation
167 inputhook_wx = inputhook_wx3
167 inputhook_wx = inputhook_wx3
@@ -1,271 +1,271 b''
1 """Tests for IPython.lib.display.
1 """Tests for IPython.lib.display.
2
2
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2012, the IPython Development Team.
5 # Copyright (c) 2012, the IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 from tempfile import NamedTemporaryFile, mkdtemp
15 from tempfile import NamedTemporaryFile, mkdtemp
16 from os.path import split, join as pjoin, dirname
16 from os.path import split, join as pjoin, dirname
17 import sys
17 import sys
18 try:
18 try:
19 import pathlib
19 import pathlib
20 except ImportError:
20 except ImportError:
21 pass
21 pass
22 from unittest import TestCase, mock
22 from unittest import TestCase, mock
23 import struct
23 import struct
24 import wave
24 import wave
25 from io import BytesIO
25 from io import BytesIO
26
26
27 # Third-party imports
27 # Third-party imports
28 import nose.tools as nt
28 import nose.tools as nt
29
29
30 try:
30 try:
31 import numpy
31 import numpy
32 except ImportError:
32 except ImportError:
33 pass
33 pass
34
34
35 # Our own imports
35 # Our own imports
36 from IPython.lib import display
36 from IPython.lib import display
37
37
38 from IPython.testing.decorators import skipif_not_numpy
38 from IPython.testing.decorators import skipif_not_numpy
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Classes and functions
41 # Classes and functions
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43
43
44 #--------------------------
44 #--------------------------
45 # FileLink tests
45 # FileLink tests
46 #--------------------------
46 #--------------------------
47
47
48 def test_instantiation_FileLink():
48 def test_instantiation_FileLink():
49 """FileLink: Test class can be instantiated"""
49 """FileLink: Test class can be instantiated"""
50 fl = display.FileLink('example.txt')
50 fl = display.FileLink('example.txt')
51 # TODO: remove if when only Python >= 3.6 is supported
51 # TODO: remove if when only Python >= 3.6 is supported
52 if sys.version_info >= (3, 6):
52 if sys.version_info >= (3, 6):
53 fl = display.FileLink(pathlib.PurePath('example.txt'))
53 fl = display.FileLink(pathlib.PurePath('example.txt'))
54
54
55 def test_warning_on_non_existant_path_FileLink():
55 def test_warning_on_non_existent_path_FileLink():
56 """FileLink: Calling _repr_html_ on non-existant files returns a warning
56 """FileLink: Calling _repr_html_ on non-existent files returns a warning
57 """
57 """
58 fl = display.FileLink('example.txt')
58 fl = display.FileLink('example.txt')
59 nt.assert_true(fl._repr_html_().startswith('Path (<tt>example.txt</tt>)'))
59 nt.assert_true(fl._repr_html_().startswith('Path (<tt>example.txt</tt>)'))
60
60
61 def test_existing_path_FileLink():
61 def test_existing_path_FileLink():
62 """FileLink: Calling _repr_html_ functions as expected on existing filepath
62 """FileLink: Calling _repr_html_ functions as expected on existing filepath
63 """
63 """
64 tf = NamedTemporaryFile()
64 tf = NamedTemporaryFile()
65 fl = display.FileLink(tf.name)
65 fl = display.FileLink(tf.name)
66 actual = fl._repr_html_()
66 actual = fl._repr_html_()
67 expected = "<a href='%s' target='_blank'>%s</a><br>" % (tf.name,tf.name)
67 expected = "<a href='%s' target='_blank'>%s</a><br>" % (tf.name,tf.name)
68 nt.assert_equal(actual,expected)
68 nt.assert_equal(actual,expected)
69
69
70 def test_existing_path_FileLink_repr():
70 def test_existing_path_FileLink_repr():
71 """FileLink: Calling repr() functions as expected on existing filepath
71 """FileLink: Calling repr() functions as expected on existing filepath
72 """
72 """
73 tf = NamedTemporaryFile()
73 tf = NamedTemporaryFile()
74 fl = display.FileLink(tf.name)
74 fl = display.FileLink(tf.name)
75 actual = repr(fl)
75 actual = repr(fl)
76 expected = tf.name
76 expected = tf.name
77 nt.assert_equal(actual,expected)
77 nt.assert_equal(actual,expected)
78
78
79 def test_error_on_directory_to_FileLink():
79 def test_error_on_directory_to_FileLink():
80 """FileLink: Raises error when passed directory
80 """FileLink: Raises error when passed directory
81 """
81 """
82 td = mkdtemp()
82 td = mkdtemp()
83 nt.assert_raises(ValueError,display.FileLink,td)
83 nt.assert_raises(ValueError,display.FileLink,td)
84
84
85 #--------------------------
85 #--------------------------
86 # FileLinks tests
86 # FileLinks tests
87 #--------------------------
87 #--------------------------
88
88
89 def test_instantiation_FileLinks():
89 def test_instantiation_FileLinks():
90 """FileLinks: Test class can be instantiated
90 """FileLinks: Test class can be instantiated
91 """
91 """
92 fls = display.FileLinks('example')
92 fls = display.FileLinks('example')
93
93
94 def test_warning_on_non_existant_path_FileLinks():
94 def test_warning_on_non_existent_path_FileLinks():
95 """FileLinks: Calling _repr_html_ on non-existant files returns a warning
95 """FileLinks: Calling _repr_html_ on non-existent files returns a warning
96 """
96 """
97 fls = display.FileLinks('example')
97 fls = display.FileLinks('example')
98 nt.assert_true(fls._repr_html_().startswith('Path (<tt>example</tt>)'))
98 nt.assert_true(fls._repr_html_().startswith('Path (<tt>example</tt>)'))
99
99
100 def test_existing_path_FileLinks():
100 def test_existing_path_FileLinks():
101 """FileLinks: Calling _repr_html_ functions as expected on existing dir
101 """FileLinks: Calling _repr_html_ functions as expected on existing dir
102 """
102 """
103 td = mkdtemp()
103 td = mkdtemp()
104 tf1 = NamedTemporaryFile(dir=td)
104 tf1 = NamedTemporaryFile(dir=td)
105 tf2 = NamedTemporaryFile(dir=td)
105 tf2 = NamedTemporaryFile(dir=td)
106 fl = display.FileLinks(td)
106 fl = display.FileLinks(td)
107 actual = fl._repr_html_()
107 actual = fl._repr_html_()
108 actual = actual.split('\n')
108 actual = actual.split('\n')
109 actual.sort()
109 actual.sort()
110 # the links should always have forward slashes, even on windows, so replace
110 # the links should always have forward slashes, even on windows, so replace
111 # backslashes with forward slashes here
111 # backslashes with forward slashes here
112 expected = ["%s/<br>" % td,
112 expected = ["%s/<br>" % td,
113 "&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>" %\
113 "&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>" %\
114 (tf2.name.replace("\\","/"),split(tf2.name)[1]),
114 (tf2.name.replace("\\","/"),split(tf2.name)[1]),
115 "&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>" %\
115 "&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>" %\
116 (tf1.name.replace("\\","/"),split(tf1.name)[1])]
116 (tf1.name.replace("\\","/"),split(tf1.name)[1])]
117 expected.sort()
117 expected.sort()
118 # We compare the sorted list of links here as that's more reliable
118 # We compare the sorted list of links here as that's more reliable
119 nt.assert_equal(actual,expected)
119 nt.assert_equal(actual,expected)
120
120
121 def test_existing_path_FileLinks_alt_formatter():
121 def test_existing_path_FileLinks_alt_formatter():
122 """FileLinks: Calling _repr_html_ functions as expected w/ an alt formatter
122 """FileLinks: Calling _repr_html_ functions as expected w/ an alt formatter
123 """
123 """
124 td = mkdtemp()
124 td = mkdtemp()
125 tf1 = NamedTemporaryFile(dir=td)
125 tf1 = NamedTemporaryFile(dir=td)
126 tf2 = NamedTemporaryFile(dir=td)
126 tf2 = NamedTemporaryFile(dir=td)
127 def fake_formatter(dirname,fnames,included_suffixes):
127 def fake_formatter(dirname,fnames,included_suffixes):
128 return ["hello","world"]
128 return ["hello","world"]
129 fl = display.FileLinks(td,notebook_display_formatter=fake_formatter)
129 fl = display.FileLinks(td,notebook_display_formatter=fake_formatter)
130 actual = fl._repr_html_()
130 actual = fl._repr_html_()
131 actual = actual.split('\n')
131 actual = actual.split('\n')
132 actual.sort()
132 actual.sort()
133 expected = ["hello","world"]
133 expected = ["hello","world"]
134 expected.sort()
134 expected.sort()
135 # We compare the sorted list of links here as that's more reliable
135 # We compare the sorted list of links here as that's more reliable
136 nt.assert_equal(actual,expected)
136 nt.assert_equal(actual,expected)
137
137
138 def test_existing_path_FileLinks_repr():
138 def test_existing_path_FileLinks_repr():
139 """FileLinks: Calling repr() functions as expected on existing directory """
139 """FileLinks: Calling repr() functions as expected on existing directory """
140 td = mkdtemp()
140 td = mkdtemp()
141 tf1 = NamedTemporaryFile(dir=td)
141 tf1 = NamedTemporaryFile(dir=td)
142 tf2 = NamedTemporaryFile(dir=td)
142 tf2 = NamedTemporaryFile(dir=td)
143 fl = display.FileLinks(td)
143 fl = display.FileLinks(td)
144 actual = repr(fl)
144 actual = repr(fl)
145 actual = actual.split('\n')
145 actual = actual.split('\n')
146 actual.sort()
146 actual.sort()
147 expected = ['%s/' % td, ' %s' % split(tf1.name)[1],' %s' % split(tf2.name)[1]]
147 expected = ['%s/' % td, ' %s' % split(tf1.name)[1],' %s' % split(tf2.name)[1]]
148 expected.sort()
148 expected.sort()
149 # We compare the sorted list of links here as that's more reliable
149 # We compare the sorted list of links here as that's more reliable
150 nt.assert_equal(actual,expected)
150 nt.assert_equal(actual,expected)
151
151
152 def test_existing_path_FileLinks_repr_alt_formatter():
152 def test_existing_path_FileLinks_repr_alt_formatter():
153 """FileLinks: Calling repr() functions as expected w/ alt formatter
153 """FileLinks: Calling repr() functions as expected w/ alt formatter
154 """
154 """
155 td = mkdtemp()
155 td = mkdtemp()
156 tf1 = NamedTemporaryFile(dir=td)
156 tf1 = NamedTemporaryFile(dir=td)
157 tf2 = NamedTemporaryFile(dir=td)
157 tf2 = NamedTemporaryFile(dir=td)
158 def fake_formatter(dirname,fnames,included_suffixes):
158 def fake_formatter(dirname,fnames,included_suffixes):
159 return ["hello","world"]
159 return ["hello","world"]
160 fl = display.FileLinks(td,terminal_display_formatter=fake_formatter)
160 fl = display.FileLinks(td,terminal_display_formatter=fake_formatter)
161 actual = repr(fl)
161 actual = repr(fl)
162 actual = actual.split('\n')
162 actual = actual.split('\n')
163 actual.sort()
163 actual.sort()
164 expected = ["hello","world"]
164 expected = ["hello","world"]
165 expected.sort()
165 expected.sort()
166 # We compare the sorted list of links here as that's more reliable
166 # We compare the sorted list of links here as that's more reliable
167 nt.assert_equal(actual,expected)
167 nt.assert_equal(actual,expected)
168
168
169 def test_error_on_file_to_FileLinks():
169 def test_error_on_file_to_FileLinks():
170 """FileLinks: Raises error when passed file
170 """FileLinks: Raises error when passed file
171 """
171 """
172 td = mkdtemp()
172 td = mkdtemp()
173 tf1 = NamedTemporaryFile(dir=td)
173 tf1 = NamedTemporaryFile(dir=td)
174 nt.assert_raises(ValueError,display.FileLinks,tf1.name)
174 nt.assert_raises(ValueError,display.FileLinks,tf1.name)
175
175
176 def test_recursive_FileLinks():
176 def test_recursive_FileLinks():
177 """FileLinks: Does not recurse when recursive=False
177 """FileLinks: Does not recurse when recursive=False
178 """
178 """
179 td = mkdtemp()
179 td = mkdtemp()
180 tf = NamedTemporaryFile(dir=td)
180 tf = NamedTemporaryFile(dir=td)
181 subtd = mkdtemp(dir=td)
181 subtd = mkdtemp(dir=td)
182 subtf = NamedTemporaryFile(dir=subtd)
182 subtf = NamedTemporaryFile(dir=subtd)
183 fl = display.FileLinks(td)
183 fl = display.FileLinks(td)
184 actual = str(fl)
184 actual = str(fl)
185 actual = actual.split('\n')
185 actual = actual.split('\n')
186 nt.assert_equal(len(actual), 4, actual)
186 nt.assert_equal(len(actual), 4, actual)
187 fl = display.FileLinks(td, recursive=False)
187 fl = display.FileLinks(td, recursive=False)
188 actual = str(fl)
188 actual = str(fl)
189 actual = actual.split('\n')
189 actual = actual.split('\n')
190 nt.assert_equal(len(actual), 2, actual)
190 nt.assert_equal(len(actual), 2, actual)
191
191
192 def test_audio_from_file():
192 def test_audio_from_file():
193 path = pjoin(dirname(__file__), 'test.wav')
193 path = pjoin(dirname(__file__), 'test.wav')
194 display.Audio(filename=path)
194 display.Audio(filename=path)
195
195
196 class TestAudioDataWithNumpy(TestCase):
196 class TestAudioDataWithNumpy(TestCase):
197
197
198 @skipif_not_numpy
198 @skipif_not_numpy
199 def test_audio_from_numpy_array(self):
199 def test_audio_from_numpy_array(self):
200 test_tone = get_test_tone()
200 test_tone = get_test_tone()
201 audio = display.Audio(test_tone, rate=44100)
201 audio = display.Audio(test_tone, rate=44100)
202 nt.assert_equal(len(read_wav(audio.data)), len(test_tone))
202 nt.assert_equal(len(read_wav(audio.data)), len(test_tone))
203
203
204 @skipif_not_numpy
204 @skipif_not_numpy
205 def test_audio_from_list(self):
205 def test_audio_from_list(self):
206 test_tone = get_test_tone()
206 test_tone = get_test_tone()
207 audio = display.Audio(list(test_tone), rate=44100)
207 audio = display.Audio(list(test_tone), rate=44100)
208 nt.assert_equal(len(read_wav(audio.data)), len(test_tone))
208 nt.assert_equal(len(read_wav(audio.data)), len(test_tone))
209
209
210 @skipif_not_numpy
210 @skipif_not_numpy
211 def test_audio_from_numpy_array_without_rate_raises(self):
211 def test_audio_from_numpy_array_without_rate_raises(self):
212 nt.assert_raises(ValueError, display.Audio, get_test_tone())
212 nt.assert_raises(ValueError, display.Audio, get_test_tone())
213
213
214 @skipif_not_numpy
214 @skipif_not_numpy
215 def test_audio_data_normalization(self):
215 def test_audio_data_normalization(self):
216 expected_max_value = numpy.iinfo(numpy.int16).max
216 expected_max_value = numpy.iinfo(numpy.int16).max
217 for scale in [1, 0.5, 2]:
217 for scale in [1, 0.5, 2]:
218 audio = display.Audio(get_test_tone(scale), rate=44100)
218 audio = display.Audio(get_test_tone(scale), rate=44100)
219 actual_max_value = numpy.max(numpy.abs(read_wav(audio.data)))
219 actual_max_value = numpy.max(numpy.abs(read_wav(audio.data)))
220 nt.assert_equal(actual_max_value, expected_max_value)
220 nt.assert_equal(actual_max_value, expected_max_value)
221
221
222 @skipif_not_numpy
222 @skipif_not_numpy
223 def test_audio_data_without_normalization(self):
223 def test_audio_data_without_normalization(self):
224 max_int16 = numpy.iinfo(numpy.int16).max
224 max_int16 = numpy.iinfo(numpy.int16).max
225 for scale in [1, 0.5, 0.2]:
225 for scale in [1, 0.5, 0.2]:
226 test_tone = get_test_tone(scale)
226 test_tone = get_test_tone(scale)
227 test_tone_max_abs = numpy.max(numpy.abs(test_tone))
227 test_tone_max_abs = numpy.max(numpy.abs(test_tone))
228 expected_max_value = int(max_int16 * test_tone_max_abs)
228 expected_max_value = int(max_int16 * test_tone_max_abs)
229 audio = display.Audio(test_tone, rate=44100, normalize=False)
229 audio = display.Audio(test_tone, rate=44100, normalize=False)
230 actual_max_value = numpy.max(numpy.abs(read_wav(audio.data)))
230 actual_max_value = numpy.max(numpy.abs(read_wav(audio.data)))
231 nt.assert_equal(actual_max_value, expected_max_value)
231 nt.assert_equal(actual_max_value, expected_max_value)
232
232
233 def test_audio_data_without_normalization_raises_for_invalid_data(self):
233 def test_audio_data_without_normalization_raises_for_invalid_data(self):
234 nt.assert_raises(
234 nt.assert_raises(
235 ValueError,
235 ValueError,
236 lambda: display.Audio([1.001], rate=44100, normalize=False))
236 lambda: display.Audio([1.001], rate=44100, normalize=False))
237 nt.assert_raises(
237 nt.assert_raises(
238 ValueError,
238 ValueError,
239 lambda: display.Audio([-1.001], rate=44100, normalize=False))
239 lambda: display.Audio([-1.001], rate=44100, normalize=False))
240
240
241 def simulate_numpy_not_installed():
241 def simulate_numpy_not_installed():
242 try:
242 try:
243 import numpy
243 import numpy
244 return mock.patch('numpy.array', mock.MagicMock(side_effect=ImportError))
244 return mock.patch('numpy.array', mock.MagicMock(side_effect=ImportError))
245 except ModuleNotFoundError:
245 except ModuleNotFoundError:
246 return lambda x:x
246 return lambda x:x
247
247
248 @simulate_numpy_not_installed()
248 @simulate_numpy_not_installed()
249 class TestAudioDataWithoutNumpy(TestAudioDataWithNumpy):
249 class TestAudioDataWithoutNumpy(TestAudioDataWithNumpy):
250 # All tests from `TestAudioDataWithNumpy` are inherited.
250 # All tests from `TestAudioDataWithNumpy` are inherited.
251
251
252 @skipif_not_numpy
252 @skipif_not_numpy
253 def test_audio_raises_for_nested_list(self):
253 def test_audio_raises_for_nested_list(self):
254 stereo_signal = [list(get_test_tone())] * 2
254 stereo_signal = [list(get_test_tone())] * 2
255 nt.assert_raises(
255 nt.assert_raises(
256 TypeError,
256 TypeError,
257 lambda: display.Audio(stereo_signal, rate=44100))
257 lambda: display.Audio(stereo_signal, rate=44100))
258
258
259 @skipif_not_numpy
259 @skipif_not_numpy
260 def get_test_tone(scale=1):
260 def get_test_tone(scale=1):
261 return numpy.sin(2 * numpy.pi * 440 * numpy.linspace(0, 1, 44100)) * scale
261 return numpy.sin(2 * numpy.pi * 440 * numpy.linspace(0, 1, 44100)) * scale
262
262
263 def read_wav(data):
263 def read_wav(data):
264 with wave.open(BytesIO(data)) as wave_file:
264 with wave.open(BytesIO(data)) as wave_file:
265 wave_data = wave_file.readframes(wave_file.getnframes())
265 wave_data = wave_file.readframes(wave_file.getnframes())
266 num_samples = wave_file.getnframes() * wave_file.getnchannels()
266 num_samples = wave_file.getnframes() * wave_file.getnchannels()
267 return struct.unpack('<%sh' % num_samples, wave_data)
267 return struct.unpack('<%sh' % num_samples, wave_data)
268
268
269 def test_code_from_file():
269 def test_code_from_file():
270 c = display.Code(filename=__file__)
270 c = display.Code(filename=__file__)
271 assert c._repr_html_().startswith('<style>')
271 assert c._repr_html_().startswith('<style>')
@@ -1,1251 +1,1251 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Sphinx directive to support embedded IPython code.
3 Sphinx directive to support embedded IPython code.
4
4
5 IPython provides an extension for `Sphinx <http://www.sphinx-doc.org/>`_ to
5 IPython provides an extension for `Sphinx <http://www.sphinx-doc.org/>`_ to
6 highlight and run code.
6 highlight and run code.
7
7
8 This directive allows pasting of entire interactive IPython sessions, prompts
8 This directive allows pasting of entire interactive IPython sessions, prompts
9 and all, and their code will actually get re-executed at doc build time, with
9 and all, and their code will actually get re-executed at doc build time, with
10 all prompts renumbered sequentially. It also allows you to input code as a pure
10 all prompts renumbered sequentially. It also allows you to input code as a pure
11 python input by giving the argument python to the directive. The output looks
11 python input by giving the argument python to the directive. The output looks
12 like an interactive ipython section.
12 like an interactive ipython section.
13
13
14 Here is an example of how the IPython directive can
14 Here is an example of how the IPython directive can
15 **run** python code, at build time.
15 **run** python code, at build time.
16
16
17 .. ipython::
17 .. ipython::
18
18
19 In [1]: 1+1
19 In [1]: 1+1
20
20
21 In [1]: import datetime
21 In [1]: import datetime
22 ...: datetime.datetime.now()
22 ...: datetime.datetime.now()
23
23
24 It supports IPython construct that plain
24 It supports IPython construct that plain
25 Python does not understand (like magics):
25 Python does not understand (like magics):
26
26
27 .. ipython::
27 .. ipython::
28
28
29 In [0]: import time
29 In [0]: import time
30
30
31 In [0]: %timeit time.sleep(0.05)
31 In [0]: %timeit time.sleep(0.05)
32
32
33 This will also support top-level async when using IPython 7.0+
33 This will also support top-level async when using IPython 7.0+
34
34
35 .. ipython::
35 .. ipython::
36
36
37 In [2]: import asyncio
37 In [2]: import asyncio
38 ...: print('before')
38 ...: print('before')
39 ...: await asyncio.sleep(1)
39 ...: await asyncio.sleep(1)
40 ...: print('after')
40 ...: print('after')
41
41
42
42
43 The namespace will persist across multiple code chucks, Let's define a variable:
43 The namespace will persist across multiple code chucks, Let's define a variable:
44
44
45 .. ipython::
45 .. ipython::
46
46
47 In [0]: who = "World"
47 In [0]: who = "World"
48
48
49 And now say hello:
49 And now say hello:
50
50
51 .. ipython::
51 .. ipython::
52
52
53 In [0]: print('Hello,', who)
53 In [0]: print('Hello,', who)
54
54
55 If the current section raises an exception, you can add the ``:okexcept:`` flag
55 If the current section raises an exception, you can add the ``:okexcept:`` flag
56 to the current block, otherwise the build will fail.
56 to the current block, otherwise the build will fail.
57
57
58 .. ipython::
58 .. ipython::
59 :okexcept:
59 :okexcept:
60
60
61 In [1]: 1/0
61 In [1]: 1/0
62
62
63 IPython Sphinx directive module
63 IPython Sphinx directive module
64 ===============================
64 ===============================
65
65
66 To enable this directive, simply list it in your Sphinx ``conf.py`` file
66 To enable this directive, simply list it in your Sphinx ``conf.py`` file
67 (making sure the directory where you placed it is visible to sphinx, as is
67 (making sure the directory where you placed it is visible to sphinx, as is
68 needed for all Sphinx directives). For example, to enable syntax highlighting
68 needed for all Sphinx directives). For example, to enable syntax highlighting
69 and the IPython directive::
69 and the IPython directive::
70
70
71 extensions = ['IPython.sphinxext.ipython_console_highlighting',
71 extensions = ['IPython.sphinxext.ipython_console_highlighting',
72 'IPython.sphinxext.ipython_directive']
72 'IPython.sphinxext.ipython_directive']
73
73
74 The IPython directive outputs code-blocks with the language 'ipython'. So
74 The IPython directive outputs code-blocks with the language 'ipython'. So
75 if you do not have the syntax highlighting extension enabled as well, then
75 if you do not have the syntax highlighting extension enabled as well, then
76 all rendered code-blocks will be uncolored. By default this directive assumes
76 all rendered code-blocks will be uncolored. By default this directive assumes
77 that your prompts are unchanged IPython ones, but this can be customized.
77 that your prompts are unchanged IPython ones, but this can be customized.
78 The configurable options that can be placed in conf.py are:
78 The configurable options that can be placed in conf.py are:
79
79
80 ipython_savefig_dir:
80 ipython_savefig_dir:
81 The directory in which to save the figures. This is relative to the
81 The directory in which to save the figures. This is relative to the
82 Sphinx source directory. The default is `html_static_path`.
82 Sphinx source directory. The default is `html_static_path`.
83 ipython_rgxin:
83 ipython_rgxin:
84 The compiled regular expression to denote the start of IPython input
84 The compiled regular expression to denote the start of IPython input
85 lines. The default is ``re.compile('In \\[(\\d+)\\]:\\s?(.*)\\s*')``. You
85 lines. The default is ``re.compile('In \\[(\\d+)\\]:\\s?(.*)\\s*')``. You
86 shouldn't need to change this.
86 shouldn't need to change this.
87 ipython_warning_is_error: [default to True]
87 ipython_warning_is_error: [default to True]
88 Fail the build if something unexpected happen, for example if a block raise
88 Fail the build if something unexpected happen, for example if a block raise
89 an exception but does not have the `:okexcept:` flag. The exact behavior of
89 an exception but does not have the `:okexcept:` flag. The exact behavior of
90 what is considered strict, may change between the sphinx directive version.
90 what is considered strict, may change between the sphinx directive version.
91 ipython_rgxout:
91 ipython_rgxout:
92 The compiled regular expression to denote the start of IPython output
92 The compiled regular expression to denote the start of IPython output
93 lines. The default is ``re.compile('Out\\[(\\d+)\\]:\\s?(.*)\\s*')``. You
93 lines. The default is ``re.compile('Out\\[(\\d+)\\]:\\s?(.*)\\s*')``. You
94 shouldn't need to change this.
94 shouldn't need to change this.
95 ipython_promptin:
95 ipython_promptin:
96 The string to represent the IPython input prompt in the generated ReST.
96 The string to represent the IPython input prompt in the generated ReST.
97 The default is ``'In [%d]:'``. This expects that the line numbers are used
97 The default is ``'In [%d]:'``. This expects that the line numbers are used
98 in the prompt.
98 in the prompt.
99 ipython_promptout:
99 ipython_promptout:
100 The string to represent the IPython prompt in the generated ReST. The
100 The string to represent the IPython prompt in the generated ReST. The
101 default is ``'Out [%d]:'``. This expects that the line numbers are used
101 default is ``'Out [%d]:'``. This expects that the line numbers are used
102 in the prompt.
102 in the prompt.
103 ipython_mplbackend:
103 ipython_mplbackend:
104 The string which specifies if the embedded Sphinx shell should import
104 The string which specifies if the embedded Sphinx shell should import
105 Matplotlib and set the backend. The value specifies a backend that is
105 Matplotlib and set the backend. The value specifies a backend that is
106 passed to `matplotlib.use()` before any lines in `ipython_execlines` are
106 passed to `matplotlib.use()` before any lines in `ipython_execlines` are
107 executed. If not specified in conf.py, then the default value of 'agg' is
107 executed. If not specified in conf.py, then the default value of 'agg' is
108 used. To use the IPython directive without matplotlib as a dependency, set
108 used. To use the IPython directive without matplotlib as a dependency, set
109 the value to `None`. It may end up that matplotlib is still imported
109 the value to `None`. It may end up that matplotlib is still imported
110 if the user specifies so in `ipython_execlines` or makes use of the
110 if the user specifies so in `ipython_execlines` or makes use of the
111 @savefig pseudo decorator.
111 @savefig pseudo decorator.
112 ipython_execlines:
112 ipython_execlines:
113 A list of strings to be exec'd in the embedded Sphinx shell. Typical
113 A list of strings to be exec'd in the embedded Sphinx shell. Typical
114 usage is to make certain packages always available. Set this to an empty
114 usage is to make certain packages always available. Set this to an empty
115 list if you wish to have no imports always available. If specified in
115 list if you wish to have no imports always available. If specified in
116 ``conf.py`` as `None`, then it has the effect of making no imports available.
116 ``conf.py`` as `None`, then it has the effect of making no imports available.
117 If omitted from conf.py altogether, then the default value of
117 If omitted from conf.py altogether, then the default value of
118 ['import numpy as np', 'import matplotlib.pyplot as plt'] is used.
118 ['import numpy as np', 'import matplotlib.pyplot as plt'] is used.
119 ipython_holdcount
119 ipython_holdcount
120 When the @suppress pseudo-decorator is used, the execution count can be
120 When the @suppress pseudo-decorator is used, the execution count can be
121 incremented or not. The default behavior is to hold the execution count,
121 incremented or not. The default behavior is to hold the execution count,
122 corresponding to a value of `True`. Set this to `False` to increment
122 corresponding to a value of `True`. Set this to `False` to increment
123 the execution count after each suppressed command.
123 the execution count after each suppressed command.
124
124
125 As an example, to use the IPython directive when `matplotlib` is not available,
125 As an example, to use the IPython directive when `matplotlib` is not available,
126 one sets the backend to `None`::
126 one sets the backend to `None`::
127
127
128 ipython_mplbackend = None
128 ipython_mplbackend = None
129
129
130 An example usage of the directive is:
130 An example usage of the directive is:
131
131
132 .. code-block:: rst
132 .. code-block:: rst
133
133
134 .. ipython::
134 .. ipython::
135
135
136 In [1]: x = 1
136 In [1]: x = 1
137
137
138 In [2]: y = x**2
138 In [2]: y = x**2
139
139
140 In [3]: print(y)
140 In [3]: print(y)
141
141
142 See http://matplotlib.org/sampledoc/ipython_directive.html for additional
142 See http://matplotlib.org/sampledoc/ipython_directive.html for additional
143 documentation.
143 documentation.
144
144
145 Pseudo-Decorators
145 Pseudo-Decorators
146 =================
146 =================
147
147
148 Note: Only one decorator is supported per input. If more than one decorator
148 Note: Only one decorator is supported per input. If more than one decorator
149 is specified, then only the last one is used.
149 is specified, then only the last one is used.
150
150
151 In addition to the Pseudo-Decorators/options described at the above link,
151 In addition to the Pseudo-Decorators/options described at the above link,
152 several enhancements have been made. The directive will emit a message to the
152 several enhancements have been made. The directive will emit a message to the
153 console at build-time if code-execution resulted in an exception or warning.
153 console at build-time if code-execution resulted in an exception or warning.
154 You can suppress these on a per-block basis by specifying the :okexcept:
154 You can suppress these on a per-block basis by specifying the :okexcept:
155 or :okwarning: options:
155 or :okwarning: options:
156
156
157 .. code-block:: rst
157 .. code-block:: rst
158
158
159 .. ipython::
159 .. ipython::
160 :okexcept:
160 :okexcept:
161 :okwarning:
161 :okwarning:
162
162
163 In [1]: 1/0
163 In [1]: 1/0
164 In [2]: # raise warning.
164 In [2]: # raise warning.
165
165
166 To Do
166 To Do
167 =====
167 =====
168
168
169 - Turn the ad-hoc test() function into a real test suite.
169 - Turn the ad-hoc test() function into a real test suite.
170 - Break up ipython-specific functionality from matplotlib stuff into better
170 - Break up ipython-specific functionality from matplotlib stuff into better
171 separated code.
171 separated code.
172
172
173 """
173 """
174
174
175 # Authors
175 # Authors
176 # =======
176 # =======
177 #
177 #
178 # - John D Hunter: original author.
178 # - John D Hunter: original author.
179 # - Fernando Perez: refactoring, documentation, cleanups, port to 0.11.
179 # - Fernando Perez: refactoring, documentation, cleanups, port to 0.11.
180 # - VáclavŠmilauer <eudoxos-AT-arcig.cz>: Prompt generalizations.
180 # - VáclavŠmilauer <eudoxos-AT-arcig.cz>: Prompt generalizations.
181 # - Skipper Seabold, refactoring, cleanups, pure python addition
181 # - Skipper Seabold, refactoring, cleanups, pure python addition
182
182
183 #-----------------------------------------------------------------------------
183 #-----------------------------------------------------------------------------
184 # Imports
184 # Imports
185 #-----------------------------------------------------------------------------
185 #-----------------------------------------------------------------------------
186
186
187 # Stdlib
187 # Stdlib
188 import atexit
188 import atexit
189 import errno
189 import errno
190 import os
190 import os
191 import pathlib
191 import pathlib
192 import re
192 import re
193 import sys
193 import sys
194 import tempfile
194 import tempfile
195 import ast
195 import ast
196 import warnings
196 import warnings
197 import shutil
197 import shutil
198 from io import StringIO
198 from io import StringIO
199
199
200 # Third-party
200 # Third-party
201 from docutils.parsers.rst import directives
201 from docutils.parsers.rst import directives
202 from docutils.parsers.rst import Directive
202 from docutils.parsers.rst import Directive
203
203
204 # Our own
204 # Our own
205 from traitlets.config import Config
205 from traitlets.config import Config
206 from IPython import InteractiveShell
206 from IPython import InteractiveShell
207 from IPython.core.profiledir import ProfileDir
207 from IPython.core.profiledir import ProfileDir
208
208
209 use_matpltolib = False
209 use_matplotlib = False
210 try:
210 try:
211 import matplotlib
211 import matplotlib
212 use_matpltolib = True
212 use_matplotlib = True
213 except Exception:
213 except Exception:
214 pass
214 pass
215
215
216 #-----------------------------------------------------------------------------
216 #-----------------------------------------------------------------------------
217 # Globals
217 # Globals
218 #-----------------------------------------------------------------------------
218 #-----------------------------------------------------------------------------
219 # for tokenizing blocks
219 # for tokenizing blocks
220 COMMENT, INPUT, OUTPUT = range(3)
220 COMMENT, INPUT, OUTPUT = range(3)
221
221
222 #-----------------------------------------------------------------------------
222 #-----------------------------------------------------------------------------
223 # Functions and class declarations
223 # Functions and class declarations
224 #-----------------------------------------------------------------------------
224 #-----------------------------------------------------------------------------
225
225
226 def block_parser(part, rgxin, rgxout, fmtin, fmtout):
226 def block_parser(part, rgxin, rgxout, fmtin, fmtout):
227 """
227 """
228 part is a string of ipython text, comprised of at most one
228 part is a string of ipython text, comprised of at most one
229 input, one output, comments, and blank lines. The block parser
229 input, one output, comments, and blank lines. The block parser
230 parses the text into a list of::
230 parses the text into a list of::
231
231
232 blocks = [ (TOKEN0, data0), (TOKEN1, data1), ...]
232 blocks = [ (TOKEN0, data0), (TOKEN1, data1), ...]
233
233
234 where TOKEN is one of [COMMENT | INPUT | OUTPUT ] and
234 where TOKEN is one of [COMMENT | INPUT | OUTPUT ] and
235 data is, depending on the type of token::
235 data is, depending on the type of token::
236
236
237 COMMENT : the comment string
237 COMMENT : the comment string
238
238
239 INPUT: the (DECORATOR, INPUT_LINE, REST) where
239 INPUT: the (DECORATOR, INPUT_LINE, REST) where
240 DECORATOR: the input decorator (or None)
240 DECORATOR: the input decorator (or None)
241 INPUT_LINE: the input as string (possibly multi-line)
241 INPUT_LINE: the input as string (possibly multi-line)
242 REST : any stdout generated by the input line (not OUTPUT)
242 REST : any stdout generated by the input line (not OUTPUT)
243
243
244 OUTPUT: the output string, possibly multi-line
244 OUTPUT: the output string, possibly multi-line
245
245
246 """
246 """
247 block = []
247 block = []
248 lines = part.split('\n')
248 lines = part.split('\n')
249 N = len(lines)
249 N = len(lines)
250 i = 0
250 i = 0
251 decorator = None
251 decorator = None
252 while 1:
252 while 1:
253
253
254 if i==N:
254 if i==N:
255 # nothing left to parse -- the last line
255 # nothing left to parse -- the last line
256 break
256 break
257
257
258 line = lines[i]
258 line = lines[i]
259 i += 1
259 i += 1
260 line_stripped = line.strip()
260 line_stripped = line.strip()
261 if line_stripped.startswith('#'):
261 if line_stripped.startswith('#'):
262 block.append((COMMENT, line))
262 block.append((COMMENT, line))
263 continue
263 continue
264
264
265 if line_stripped.startswith('@'):
265 if line_stripped.startswith('@'):
266 # Here is where we assume there is, at most, one decorator.
266 # Here is where we assume there is, at most, one decorator.
267 # Might need to rethink this.
267 # Might need to rethink this.
268 decorator = line_stripped
268 decorator = line_stripped
269 continue
269 continue
270
270
271 # does this look like an input line?
271 # does this look like an input line?
272 matchin = rgxin.match(line)
272 matchin = rgxin.match(line)
273 if matchin:
273 if matchin:
274 lineno, inputline = int(matchin.group(1)), matchin.group(2)
274 lineno, inputline = int(matchin.group(1)), matchin.group(2)
275
275
276 # the ....: continuation string
276 # the ....: continuation string
277 continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2))
277 continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2))
278 Nc = len(continuation)
278 Nc = len(continuation)
279 # input lines can continue on for more than one line, if
279 # input lines can continue on for more than one line, if
280 # we have a '\' line continuation char or a function call
280 # we have a '\' line continuation char or a function call
281 # echo line 'print'. The input line can only be
281 # echo line 'print'. The input line can only be
282 # terminated by the end of the block or an output line, so
282 # terminated by the end of the block or an output line, so
283 # we parse out the rest of the input line if it is
283 # we parse out the rest of the input line if it is
284 # multiline as well as any echo text
284 # multiline as well as any echo text
285
285
286 rest = []
286 rest = []
287 while i<N:
287 while i<N:
288
288
289 # look ahead; if the next line is blank, or a comment, or
289 # look ahead; if the next line is blank, or a comment, or
290 # an output line, we're done
290 # an output line, we're done
291
291
292 nextline = lines[i]
292 nextline = lines[i]
293 matchout = rgxout.match(nextline)
293 matchout = rgxout.match(nextline)
294 #print "nextline=%s, continuation=%s, starts=%s"%(nextline, continuation, nextline.startswith(continuation))
294 #print "nextline=%s, continuation=%s, starts=%s"%(nextline, continuation, nextline.startswith(continuation))
295 if matchout or nextline.startswith('#'):
295 if matchout or nextline.startswith('#'):
296 break
296 break
297 elif nextline.startswith(continuation):
297 elif nextline.startswith(continuation):
298 # The default ipython_rgx* treat the space following the colon as optional.
298 # The default ipython_rgx* treat the space following the colon as optional.
299 # However, If the space is there we must consume it or code
299 # However, If the space is there we must consume it or code
300 # employing the cython_magic extension will fail to execute.
300 # employing the cython_magic extension will fail to execute.
301 #
301 #
302 # This works with the default ipython_rgx* patterns,
302 # This works with the default ipython_rgx* patterns,
303 # If you modify them, YMMV.
303 # If you modify them, YMMV.
304 nextline = nextline[Nc:]
304 nextline = nextline[Nc:]
305 if nextline and nextline[0] == ' ':
305 if nextline and nextline[0] == ' ':
306 nextline = nextline[1:]
306 nextline = nextline[1:]
307
307
308 inputline += '\n' + nextline
308 inputline += '\n' + nextline
309 else:
309 else:
310 rest.append(nextline)
310 rest.append(nextline)
311 i+= 1
311 i+= 1
312
312
313 block.append((INPUT, (decorator, inputline, '\n'.join(rest))))
313 block.append((INPUT, (decorator, inputline, '\n'.join(rest))))
314 continue
314 continue
315
315
316 # if it looks like an output line grab all the text to the end
316 # if it looks like an output line grab all the text to the end
317 # of the block
317 # of the block
318 matchout = rgxout.match(line)
318 matchout = rgxout.match(line)
319 if matchout:
319 if matchout:
320 lineno, output = int(matchout.group(1)), matchout.group(2)
320 lineno, output = int(matchout.group(1)), matchout.group(2)
321 if i<N-1:
321 if i<N-1:
322 output = '\n'.join([output] + lines[i:])
322 output = '\n'.join([output] + lines[i:])
323
323
324 block.append((OUTPUT, output))
324 block.append((OUTPUT, output))
325 break
325 break
326
326
327 return block
327 return block
328
328
329
329
330 class EmbeddedSphinxShell(object):
330 class EmbeddedSphinxShell(object):
331 """An embedded IPython instance to run inside Sphinx"""
331 """An embedded IPython instance to run inside Sphinx"""
332
332
333 def __init__(self, exec_lines=None):
333 def __init__(self, exec_lines=None):
334
334
335 self.cout = StringIO()
335 self.cout = StringIO()
336
336
337 if exec_lines is None:
337 if exec_lines is None:
338 exec_lines = []
338 exec_lines = []
339
339
340 # Create config object for IPython
340 # Create config object for IPython
341 config = Config()
341 config = Config()
342 config.HistoryManager.hist_file = ':memory:'
342 config.HistoryManager.hist_file = ':memory:'
343 config.InteractiveShell.autocall = False
343 config.InteractiveShell.autocall = False
344 config.InteractiveShell.autoindent = False
344 config.InteractiveShell.autoindent = False
345 config.InteractiveShell.colors = 'NoColor'
345 config.InteractiveShell.colors = 'NoColor'
346
346
347 # create a profile so instance history isn't saved
347 # create a profile so instance history isn't saved
348 tmp_profile_dir = tempfile.mkdtemp(prefix='profile_')
348 tmp_profile_dir = tempfile.mkdtemp(prefix='profile_')
349 profname = 'auto_profile_sphinx_build'
349 profname = 'auto_profile_sphinx_build'
350 pdir = os.path.join(tmp_profile_dir,profname)
350 pdir = os.path.join(tmp_profile_dir,profname)
351 profile = ProfileDir.create_profile_dir(pdir)
351 profile = ProfileDir.create_profile_dir(pdir)
352
352
353 # Create and initialize global ipython, but don't start its mainloop.
353 # Create and initialize global ipython, but don't start its mainloop.
354 # This will persist across different EmbeddedSphinxShell instances.
354 # This will persist across different EmbeddedSphinxShell instances.
355 IP = InteractiveShell.instance(config=config, profile_dir=profile)
355 IP = InteractiveShell.instance(config=config, profile_dir=profile)
356 atexit.register(self.cleanup)
356 atexit.register(self.cleanup)
357
357
358 # Store a few parts of IPython we'll need.
358 # Store a few parts of IPython we'll need.
359 self.IP = IP
359 self.IP = IP
360 self.user_ns = self.IP.user_ns
360 self.user_ns = self.IP.user_ns
361 self.user_global_ns = self.IP.user_global_ns
361 self.user_global_ns = self.IP.user_global_ns
362
362
363 self.input = ''
363 self.input = ''
364 self.output = ''
364 self.output = ''
365 self.tmp_profile_dir = tmp_profile_dir
365 self.tmp_profile_dir = tmp_profile_dir
366
366
367 self.is_verbatim = False
367 self.is_verbatim = False
368 self.is_doctest = False
368 self.is_doctest = False
369 self.is_suppress = False
369 self.is_suppress = False
370
370
371 # Optionally, provide more detailed information to shell.
371 # Optionally, provide more detailed information to shell.
372 # this is assigned by the SetUp method of IPythonDirective
372 # this is assigned by the SetUp method of IPythonDirective
373 # to point at itself.
373 # to point at itself.
374 #
374 #
375 # So, you can access handy things at self.directive.state
375 # So, you can access handy things at self.directive.state
376 self.directive = None
376 self.directive = None
377
377
378 # on the first call to the savefig decorator, we'll import
378 # on the first call to the savefig decorator, we'll import
379 # pyplot as plt so we can make a call to the plt.gcf().savefig
379 # pyplot as plt so we can make a call to the plt.gcf().savefig
380 self._pyplot_imported = False
380 self._pyplot_imported = False
381
381
382 # Prepopulate the namespace.
382 # Prepopulate the namespace.
383 for line in exec_lines:
383 for line in exec_lines:
384 self.process_input_line(line, store_history=False)
384 self.process_input_line(line, store_history=False)
385
385
386 def cleanup(self):
386 def cleanup(self):
387 shutil.rmtree(self.tmp_profile_dir, ignore_errors=True)
387 shutil.rmtree(self.tmp_profile_dir, ignore_errors=True)
388
388
389 def clear_cout(self):
389 def clear_cout(self):
390 self.cout.seek(0)
390 self.cout.seek(0)
391 self.cout.truncate(0)
391 self.cout.truncate(0)
392
392
393 def process_input_line(self, line, store_history):
393 def process_input_line(self, line, store_history):
394 return self.process_input_lines([line], store_history=store_history)
394 return self.process_input_lines([line], store_history=store_history)
395
395
396 def process_input_lines(self, lines, store_history=True):
396 def process_input_lines(self, lines, store_history=True):
397 """process the input, capturing stdout"""
397 """process the input, capturing stdout"""
398 stdout = sys.stdout
398 stdout = sys.stdout
399 source_raw = '\n'.join(lines)
399 source_raw = '\n'.join(lines)
400 try:
400 try:
401 sys.stdout = self.cout
401 sys.stdout = self.cout
402 self.IP.run_cell(source_raw, store_history=store_history)
402 self.IP.run_cell(source_raw, store_history=store_history)
403 finally:
403 finally:
404 sys.stdout = stdout
404 sys.stdout = stdout
405
405
406 def process_image(self, decorator):
406 def process_image(self, decorator):
407 """
407 """
408 # build out an image directive like
408 # build out an image directive like
409 # .. image:: somefile.png
409 # .. image:: somefile.png
410 # :width 4in
410 # :width 4in
411 #
411 #
412 # from an input like
412 # from an input like
413 # savefig somefile.png width=4in
413 # savefig somefile.png width=4in
414 """
414 """
415 savefig_dir = self.savefig_dir
415 savefig_dir = self.savefig_dir
416 source_dir = self.source_dir
416 source_dir = self.source_dir
417 saveargs = decorator.split(' ')
417 saveargs = decorator.split(' ')
418 filename = saveargs[1]
418 filename = saveargs[1]
419 # insert relative path to image file in source
419 # insert relative path to image file in source
420 # as absolute path for Sphinx
420 # as absolute path for Sphinx
421 # sphinx expects a posix path, even on Windows
421 # sphinx expects a posix path, even on Windows
422 posix_path = pathlib.Path(savefig_dir,filename).as_posix()
422 posix_path = pathlib.Path(savefig_dir,filename).as_posix()
423 outfile = '/' + os.path.relpath(posix_path, source_dir)
423 outfile = '/' + os.path.relpath(posix_path, source_dir)
424
424
425 imagerows = ['.. image:: %s' % outfile]
425 imagerows = ['.. image:: %s' % outfile]
426
426
427 for kwarg in saveargs[2:]:
427 for kwarg in saveargs[2:]:
428 arg, val = kwarg.split('=')
428 arg, val = kwarg.split('=')
429 arg = arg.strip()
429 arg = arg.strip()
430 val = val.strip()
430 val = val.strip()
431 imagerows.append(' :%s: %s'%(arg, val))
431 imagerows.append(' :%s: %s'%(arg, val))
432
432
433 image_file = os.path.basename(outfile) # only return file name
433 image_file = os.path.basename(outfile) # only return file name
434 image_directive = '\n'.join(imagerows)
434 image_directive = '\n'.join(imagerows)
435 return image_file, image_directive
435 return image_file, image_directive
436
436
437 # Callbacks for each type of token
437 # Callbacks for each type of token
438 def process_input(self, data, input_prompt, lineno):
438 def process_input(self, data, input_prompt, lineno):
439 """
439 """
440 Process data block for INPUT token.
440 Process data block for INPUT token.
441
441
442 """
442 """
443 decorator, input, rest = data
443 decorator, input, rest = data
444 image_file = None
444 image_file = None
445 image_directive = None
445 image_directive = None
446
446
447 is_verbatim = decorator=='@verbatim' or self.is_verbatim
447 is_verbatim = decorator=='@verbatim' or self.is_verbatim
448 is_doctest = (decorator is not None and \
448 is_doctest = (decorator is not None and \
449 decorator.startswith('@doctest')) or self.is_doctest
449 decorator.startswith('@doctest')) or self.is_doctest
450 is_suppress = decorator=='@suppress' or self.is_suppress
450 is_suppress = decorator=='@suppress' or self.is_suppress
451 is_okexcept = decorator=='@okexcept' or self.is_okexcept
451 is_okexcept = decorator=='@okexcept' or self.is_okexcept
452 is_okwarning = decorator=='@okwarning' or self.is_okwarning
452 is_okwarning = decorator=='@okwarning' or self.is_okwarning
453 is_savefig = decorator is not None and \
453 is_savefig = decorator is not None and \
454 decorator.startswith('@savefig')
454 decorator.startswith('@savefig')
455
455
456 input_lines = input.split('\n')
456 input_lines = input.split('\n')
457 if len(input_lines) > 1:
457 if len(input_lines) > 1:
458 if input_lines[-1] != "":
458 if input_lines[-1] != "":
459 input_lines.append('') # make sure there's a blank line
459 input_lines.append('') # make sure there's a blank line
460 # so splitter buffer gets reset
460 # so splitter buffer gets reset
461
461
462 continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2))
462 continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2))
463
463
464 if is_savefig:
464 if is_savefig:
465 image_file, image_directive = self.process_image(decorator)
465 image_file, image_directive = self.process_image(decorator)
466
466
467 ret = []
467 ret = []
468 is_semicolon = False
468 is_semicolon = False
469
469
470 # Hold the execution count, if requested to do so.
470 # Hold the execution count, if requested to do so.
471 if is_suppress and self.hold_count:
471 if is_suppress and self.hold_count:
472 store_history = False
472 store_history = False
473 else:
473 else:
474 store_history = True
474 store_history = True
475
475
476 # Note: catch_warnings is not thread safe
476 # Note: catch_warnings is not thread safe
477 with warnings.catch_warnings(record=True) as ws:
477 with warnings.catch_warnings(record=True) as ws:
478 if input_lines[0].endswith(';'):
478 if input_lines[0].endswith(';'):
479 is_semicolon = True
479 is_semicolon = True
480 #for i, line in enumerate(input_lines):
480 #for i, line in enumerate(input_lines):
481
481
482 # process the first input line
482 # process the first input line
483 if is_verbatim:
483 if is_verbatim:
484 self.process_input_lines([''])
484 self.process_input_lines([''])
485 self.IP.execution_count += 1 # increment it anyway
485 self.IP.execution_count += 1 # increment it anyway
486 else:
486 else:
487 # only submit the line in non-verbatim mode
487 # only submit the line in non-verbatim mode
488 self.process_input_lines(input_lines, store_history=store_history)
488 self.process_input_lines(input_lines, store_history=store_history)
489
489
490 if not is_suppress:
490 if not is_suppress:
491 for i, line in enumerate(input_lines):
491 for i, line in enumerate(input_lines):
492 if i == 0:
492 if i == 0:
493 formatted_line = '%s %s'%(input_prompt, line)
493 formatted_line = '%s %s'%(input_prompt, line)
494 else:
494 else:
495 formatted_line = '%s %s'%(continuation, line)
495 formatted_line = '%s %s'%(continuation, line)
496 ret.append(formatted_line)
496 ret.append(formatted_line)
497
497
498 if not is_suppress and len(rest.strip()) and is_verbatim:
498 if not is_suppress and len(rest.strip()) and is_verbatim:
499 # The "rest" is the standard output of the input. This needs to be
499 # The "rest" is the standard output of the input. This needs to be
500 # added when in verbatim mode. If there is no "rest", then we don't
500 # added when in verbatim mode. If there is no "rest", then we don't
501 # add it, as the new line will be added by the processed output.
501 # add it, as the new line will be added by the processed output.
502 ret.append(rest)
502 ret.append(rest)
503
503
504 # Fetch the processed output. (This is not the submitted output.)
504 # Fetch the processed output. (This is not the submitted output.)
505 self.cout.seek(0)
505 self.cout.seek(0)
506 processed_output = self.cout.read()
506 processed_output = self.cout.read()
507 if not is_suppress and not is_semicolon:
507 if not is_suppress and not is_semicolon:
508 #
508 #
509 # In IPythonDirective.run, the elements of `ret` are eventually
509 # In IPythonDirective.run, the elements of `ret` are eventually
510 # combined such that '' entries correspond to newlines. So if
510 # combined such that '' entries correspond to newlines. So if
511 # `processed_output` is equal to '', then the adding it to `ret`
511 # `processed_output` is equal to '', then the adding it to `ret`
512 # ensures that there is a blank line between consecutive inputs
512 # ensures that there is a blank line between consecutive inputs
513 # that have no outputs, as in:
513 # that have no outputs, as in:
514 #
514 #
515 # In [1]: x = 4
515 # In [1]: x = 4
516 #
516 #
517 # In [2]: x = 5
517 # In [2]: x = 5
518 #
518 #
519 # When there is processed output, it has a '\n' at the tail end. So
519 # When there is processed output, it has a '\n' at the tail end. So
520 # adding the output to `ret` will provide the necessary spacing
520 # adding the output to `ret` will provide the necessary spacing
521 # between consecutive input/output blocks, as in:
521 # between consecutive input/output blocks, as in:
522 #
522 #
523 # In [1]: x
523 # In [1]: x
524 # Out[1]: 5
524 # Out[1]: 5
525 #
525 #
526 # In [2]: x
526 # In [2]: x
527 # Out[2]: 5
527 # Out[2]: 5
528 #
528 #
529 # When there is stdout from the input, it also has a '\n' at the
529 # When there is stdout from the input, it also has a '\n' at the
530 # tail end, and so this ensures proper spacing as well. E.g.:
530 # tail end, and so this ensures proper spacing as well. E.g.:
531 #
531 #
532 # In [1]: print x
532 # In [1]: print x
533 # 5
533 # 5
534 #
534 #
535 # In [2]: x = 5
535 # In [2]: x = 5
536 #
536 #
537 # When in verbatim mode, `processed_output` is empty (because
537 # When in verbatim mode, `processed_output` is empty (because
538 # nothing was passed to IP. Sometimes the submitted code block has
538 # nothing was passed to IP. Sometimes the submitted code block has
539 # an Out[] portion and sometimes it does not. When it does not, we
539 # an Out[] portion and sometimes it does not. When it does not, we
540 # need to ensure proper spacing, so we have to add '' to `ret`.
540 # need to ensure proper spacing, so we have to add '' to `ret`.
541 # However, if there is an Out[] in the submitted code, then we do
541 # However, if there is an Out[] in the submitted code, then we do
542 # not want to add a newline as `process_output` has stuff to add.
542 # not want to add a newline as `process_output` has stuff to add.
543 # The difficulty is that `process_input` doesn't know if
543 # The difficulty is that `process_input` doesn't know if
544 # `process_output` will be called---so it doesn't know if there is
544 # `process_output` will be called---so it doesn't know if there is
545 # Out[] in the code block. The requires that we include a hack in
545 # Out[] in the code block. The requires that we include a hack in
546 # `process_block`. See the comments there.
546 # `process_block`. See the comments there.
547 #
547 #
548 ret.append(processed_output)
548 ret.append(processed_output)
549 elif is_semicolon:
549 elif is_semicolon:
550 # Make sure there is a newline after the semicolon.
550 # Make sure there is a newline after the semicolon.
551 ret.append('')
551 ret.append('')
552
552
553 # context information
553 # context information
554 filename = "Unknown"
554 filename = "Unknown"
555 lineno = 0
555 lineno = 0
556 if self.directive.state:
556 if self.directive.state:
557 filename = self.directive.state.document.current_source
557 filename = self.directive.state.document.current_source
558 lineno = self.directive.state.document.current_line
558 lineno = self.directive.state.document.current_line
559
559
560 # output any exceptions raised during execution to stdout
560 # output any exceptions raised during execution to stdout
561 # unless :okexcept: has been specified.
561 # unless :okexcept: has been specified.
562 if not is_okexcept and (("Traceback" in processed_output) or ("SyntaxError" in processed_output)):
562 if not is_okexcept and (("Traceback" in processed_output) or ("SyntaxError" in processed_output)):
563 s = "\nException in %s at block ending on line %s\n" % (filename, lineno)
563 s = "\nException in %s at block ending on line %s\n" % (filename, lineno)
564 s += "Specify :okexcept: as an option in the ipython:: block to suppress this message\n"
564 s += "Specify :okexcept: as an option in the ipython:: block to suppress this message\n"
565 sys.stdout.write('\n\n>>>' + ('-' * 73))
565 sys.stdout.write('\n\n>>>' + ('-' * 73))
566 sys.stdout.write(s)
566 sys.stdout.write(s)
567 sys.stdout.write(processed_output)
567 sys.stdout.write(processed_output)
568 sys.stdout.write('<<<' + ('-' * 73) + '\n\n')
568 sys.stdout.write('<<<' + ('-' * 73) + '\n\n')
569 if self.warning_is_error:
569 if self.warning_is_error:
570 raise RuntimeError('Non Expected exception in `{}` line {}'.format(filename, lineno))
570 raise RuntimeError('Non Expected exception in `{}` line {}'.format(filename, lineno))
571
571
572 # output any warning raised during execution to stdout
572 # output any warning raised during execution to stdout
573 # unless :okwarning: has been specified.
573 # unless :okwarning: has been specified.
574 if not is_okwarning:
574 if not is_okwarning:
575 for w in ws:
575 for w in ws:
576 s = "\nWarning in %s at block ending on line %s\n" % (filename, lineno)
576 s = "\nWarning in %s at block ending on line %s\n" % (filename, lineno)
577 s += "Specify :okwarning: as an option in the ipython:: block to suppress this message\n"
577 s += "Specify :okwarning: as an option in the ipython:: block to suppress this message\n"
578 sys.stdout.write('\n\n>>>' + ('-' * 73))
578 sys.stdout.write('\n\n>>>' + ('-' * 73))
579 sys.stdout.write(s)
579 sys.stdout.write(s)
580 sys.stdout.write(('-' * 76) + '\n')
580 sys.stdout.write(('-' * 76) + '\n')
581 s=warnings.formatwarning(w.message, w.category,
581 s=warnings.formatwarning(w.message, w.category,
582 w.filename, w.lineno, w.line)
582 w.filename, w.lineno, w.line)
583 sys.stdout.write(s)
583 sys.stdout.write(s)
584 sys.stdout.write('<<<' + ('-' * 73) + '\n')
584 sys.stdout.write('<<<' + ('-' * 73) + '\n')
585 if self.warning_is_error:
585 if self.warning_is_error:
586 raise RuntimeError('Non Expected warning in `{}` line {}'.format(filename, lineno))
586 raise RuntimeError('Non Expected warning in `{}` line {}'.format(filename, lineno))
587
587
588 self.cout.truncate(0)
588 self.cout.truncate(0)
589 return (ret, input_lines, processed_output,
589 return (ret, input_lines, processed_output,
590 is_doctest, decorator, image_file, image_directive)
590 is_doctest, decorator, image_file, image_directive)
591
591
592
592
593 def process_output(self, data, output_prompt, input_lines, output,
593 def process_output(self, data, output_prompt, input_lines, output,
594 is_doctest, decorator, image_file):
594 is_doctest, decorator, image_file):
595 """
595 """
596 Process data block for OUTPUT token.
596 Process data block for OUTPUT token.
597
597
598 """
598 """
599 # Recall: `data` is the submitted output, and `output` is the processed
599 # Recall: `data` is the submitted output, and `output` is the processed
600 # output from `input_lines`.
600 # output from `input_lines`.
601
601
602 TAB = ' ' * 4
602 TAB = ' ' * 4
603
603
604 if is_doctest and output is not None:
604 if is_doctest and output is not None:
605
605
606 found = output # This is the processed output
606 found = output # This is the processed output
607 found = found.strip()
607 found = found.strip()
608 submitted = data.strip()
608 submitted = data.strip()
609
609
610 if self.directive is None:
610 if self.directive is None:
611 source = 'Unavailable'
611 source = 'Unavailable'
612 content = 'Unavailable'
612 content = 'Unavailable'
613 else:
613 else:
614 source = self.directive.state.document.current_source
614 source = self.directive.state.document.current_source
615 content = self.directive.content
615 content = self.directive.content
616 # Add tabs and join into a single string.
616 # Add tabs and join into a single string.
617 content = '\n'.join([TAB + line for line in content])
617 content = '\n'.join([TAB + line for line in content])
618
618
619 # Make sure the output contains the output prompt.
619 # Make sure the output contains the output prompt.
620 ind = found.find(output_prompt)
620 ind = found.find(output_prompt)
621 if ind < 0:
621 if ind < 0:
622 e = ('output does not contain output prompt\n\n'
622 e = ('output does not contain output prompt\n\n'
623 'Document source: {0}\n\n'
623 'Document source: {0}\n\n'
624 'Raw content: \n{1}\n\n'
624 'Raw content: \n{1}\n\n'
625 'Input line(s):\n{TAB}{2}\n\n'
625 'Input line(s):\n{TAB}{2}\n\n'
626 'Output line(s):\n{TAB}{3}\n\n')
626 'Output line(s):\n{TAB}{3}\n\n')
627 e = e.format(source, content, '\n'.join(input_lines),
627 e = e.format(source, content, '\n'.join(input_lines),
628 repr(found), TAB=TAB)
628 repr(found), TAB=TAB)
629 raise RuntimeError(e)
629 raise RuntimeError(e)
630 found = found[len(output_prompt):].strip()
630 found = found[len(output_prompt):].strip()
631
631
632 # Handle the actual doctest comparison.
632 # Handle the actual doctest comparison.
633 if decorator.strip() == '@doctest':
633 if decorator.strip() == '@doctest':
634 # Standard doctest
634 # Standard doctest
635 if found != submitted:
635 if found != submitted:
636 e = ('doctest failure\n\n'
636 e = ('doctest failure\n\n'
637 'Document source: {0}\n\n'
637 'Document source: {0}\n\n'
638 'Raw content: \n{1}\n\n'
638 'Raw content: \n{1}\n\n'
639 'On input line(s):\n{TAB}{2}\n\n'
639 'On input line(s):\n{TAB}{2}\n\n'
640 'we found output:\n{TAB}{3}\n\n'
640 'we found output:\n{TAB}{3}\n\n'
641 'instead of the expected:\n{TAB}{4}\n\n')
641 'instead of the expected:\n{TAB}{4}\n\n')
642 e = e.format(source, content, '\n'.join(input_lines),
642 e = e.format(source, content, '\n'.join(input_lines),
643 repr(found), repr(submitted), TAB=TAB)
643 repr(found), repr(submitted), TAB=TAB)
644 raise RuntimeError(e)
644 raise RuntimeError(e)
645 else:
645 else:
646 self.custom_doctest(decorator, input_lines, found, submitted)
646 self.custom_doctest(decorator, input_lines, found, submitted)
647
647
648 # When in verbatim mode, this holds additional submitted output
648 # When in verbatim mode, this holds additional submitted output
649 # to be written in the final Sphinx output.
649 # to be written in the final Sphinx output.
650 # https://github.com/ipython/ipython/issues/5776
650 # https://github.com/ipython/ipython/issues/5776
651 out_data = []
651 out_data = []
652
652
653 is_verbatim = decorator=='@verbatim' or self.is_verbatim
653 is_verbatim = decorator=='@verbatim' or self.is_verbatim
654 if is_verbatim and data.strip():
654 if is_verbatim and data.strip():
655 # Note that `ret` in `process_block` has '' as its last element if
655 # Note that `ret` in `process_block` has '' as its last element if
656 # the code block was in verbatim mode. So if there is no submitted
656 # the code block was in verbatim mode. So if there is no submitted
657 # output, then we will have proper spacing only if we do not add
657 # output, then we will have proper spacing only if we do not add
658 # an additional '' to `out_data`. This is why we condition on
658 # an additional '' to `out_data`. This is why we condition on
659 # `and data.strip()`.
659 # `and data.strip()`.
660
660
661 # The submitted output has no output prompt. If we want the
661 # The submitted output has no output prompt. If we want the
662 # prompt and the code to appear, we need to join them now
662 # prompt and the code to appear, we need to join them now
663 # instead of adding them separately---as this would create an
663 # instead of adding them separately---as this would create an
664 # undesired newline. How we do this ultimately depends on the
664 # undesired newline. How we do this ultimately depends on the
665 # format of the output regex. I'll do what works for the default
665 # format of the output regex. I'll do what works for the default
666 # prompt for now, and we might have to adjust if it doesn't work
666 # prompt for now, and we might have to adjust if it doesn't work
667 # in other cases. Finally, the submitted output does not have
667 # in other cases. Finally, the submitted output does not have
668 # a trailing newline, so we must add it manually.
668 # a trailing newline, so we must add it manually.
669 out_data.append("{0} {1}\n".format(output_prompt, data))
669 out_data.append("{0} {1}\n".format(output_prompt, data))
670
670
671 return out_data
671 return out_data
672
672
673 def process_comment(self, data):
673 def process_comment(self, data):
674 """Process data fPblock for COMMENT token."""
674 """Process data fPblock for COMMENT token."""
675 if not self.is_suppress:
675 if not self.is_suppress:
676 return [data]
676 return [data]
677
677
678 def save_image(self, image_file):
678 def save_image(self, image_file):
679 """
679 """
680 Saves the image file to disk.
680 Saves the image file to disk.
681 """
681 """
682 self.ensure_pyplot()
682 self.ensure_pyplot()
683 command = 'plt.gcf().savefig("%s")'%image_file
683 command = 'plt.gcf().savefig("%s")'%image_file
684 #print 'SAVEFIG', command # dbg
684 #print 'SAVEFIG', command # dbg
685 self.process_input_line('bookmark ipy_thisdir', store_history=False)
685 self.process_input_line('bookmark ipy_thisdir', store_history=False)
686 self.process_input_line('cd -b ipy_savedir', store_history=False)
686 self.process_input_line('cd -b ipy_savedir', store_history=False)
687 self.process_input_line(command, store_history=False)
687 self.process_input_line(command, store_history=False)
688 self.process_input_line('cd -b ipy_thisdir', store_history=False)
688 self.process_input_line('cd -b ipy_thisdir', store_history=False)
689 self.process_input_line('bookmark -d ipy_thisdir', store_history=False)
689 self.process_input_line('bookmark -d ipy_thisdir', store_history=False)
690 self.clear_cout()
690 self.clear_cout()
691
691
692 def process_block(self, block):
692 def process_block(self, block):
693 """
693 """
694 process block from the block_parser and return a list of processed lines
694 process block from the block_parser and return a list of processed lines
695 """
695 """
696 ret = []
696 ret = []
697 output = None
697 output = None
698 input_lines = None
698 input_lines = None
699 lineno = self.IP.execution_count
699 lineno = self.IP.execution_count
700
700
701 input_prompt = self.promptin % lineno
701 input_prompt = self.promptin % lineno
702 output_prompt = self.promptout % lineno
702 output_prompt = self.promptout % lineno
703 image_file = None
703 image_file = None
704 image_directive = None
704 image_directive = None
705
705
706 found_input = False
706 found_input = False
707 for token, data in block:
707 for token, data in block:
708 if token == COMMENT:
708 if token == COMMENT:
709 out_data = self.process_comment(data)
709 out_data = self.process_comment(data)
710 elif token == INPUT:
710 elif token == INPUT:
711 found_input = True
711 found_input = True
712 (out_data, input_lines, output, is_doctest,
712 (out_data, input_lines, output, is_doctest,
713 decorator, image_file, image_directive) = \
713 decorator, image_file, image_directive) = \
714 self.process_input(data, input_prompt, lineno)
714 self.process_input(data, input_prompt, lineno)
715 elif token == OUTPUT:
715 elif token == OUTPUT:
716 if not found_input:
716 if not found_input:
717
717
718 TAB = ' ' * 4
718 TAB = ' ' * 4
719 linenumber = 0
719 linenumber = 0
720 source = 'Unavailable'
720 source = 'Unavailable'
721 content = 'Unavailable'
721 content = 'Unavailable'
722 if self.directive:
722 if self.directive:
723 linenumber = self.directive.state.document.current_line
723 linenumber = self.directive.state.document.current_line
724 source = self.directive.state.document.current_source
724 source = self.directive.state.document.current_source
725 content = self.directive.content
725 content = self.directive.content
726 # Add tabs and join into a single string.
726 # Add tabs and join into a single string.
727 content = '\n'.join([TAB + line for line in content])
727 content = '\n'.join([TAB + line for line in content])
728
728
729 e = ('\n\nInvalid block: Block contains an output prompt '
729 e = ('\n\nInvalid block: Block contains an output prompt '
730 'without an input prompt.\n\n'
730 'without an input prompt.\n\n'
731 'Document source: {0}\n\n'
731 'Document source: {0}\n\n'
732 'Content begins at line {1}: \n\n{2}\n\n'
732 'Content begins at line {1}: \n\n{2}\n\n'
733 'Problematic block within content: \n\n{TAB}{3}\n\n')
733 'Problematic block within content: \n\n{TAB}{3}\n\n')
734 e = e.format(source, linenumber, content, block, TAB=TAB)
734 e = e.format(source, linenumber, content, block, TAB=TAB)
735
735
736 # Write, rather than include in exception, since Sphinx
736 # Write, rather than include in exception, since Sphinx
737 # will truncate tracebacks.
737 # will truncate tracebacks.
738 sys.stdout.write(e)
738 sys.stdout.write(e)
739 raise RuntimeError('An invalid block was detected.')
739 raise RuntimeError('An invalid block was detected.')
740 out_data = \
740 out_data = \
741 self.process_output(data, output_prompt, input_lines,
741 self.process_output(data, output_prompt, input_lines,
742 output, is_doctest, decorator,
742 output, is_doctest, decorator,
743 image_file)
743 image_file)
744 if out_data:
744 if out_data:
745 # Then there was user submitted output in verbatim mode.
745 # Then there was user submitted output in verbatim mode.
746 # We need to remove the last element of `ret` that was
746 # We need to remove the last element of `ret` that was
747 # added in `process_input`, as it is '' and would introduce
747 # added in `process_input`, as it is '' and would introduce
748 # an undesirable newline.
748 # an undesirable newline.
749 assert(ret[-1] == '')
749 assert(ret[-1] == '')
750 del ret[-1]
750 del ret[-1]
751
751
752 if out_data:
752 if out_data:
753 ret.extend(out_data)
753 ret.extend(out_data)
754
754
755 # save the image files
755 # save the image files
756 if image_file is not None:
756 if image_file is not None:
757 self.save_image(image_file)
757 self.save_image(image_file)
758
758
759 return ret, image_directive
759 return ret, image_directive
760
760
761 def ensure_pyplot(self):
761 def ensure_pyplot(self):
762 """
762 """
763 Ensures that pyplot has been imported into the embedded IPython shell.
763 Ensures that pyplot has been imported into the embedded IPython shell.
764
764
765 Also, makes sure to set the backend appropriately if not set already.
765 Also, makes sure to set the backend appropriately if not set already.
766
766
767 """
767 """
768 # We are here if the @figure pseudo decorator was used. Thus, it's
768 # We are here if the @figure pseudo decorator was used. Thus, it's
769 # possible that we could be here even if python_mplbackend were set to
769 # possible that we could be here even if python_mplbackend were set to
770 # `None`. That's also strange and perhaps worthy of raising an
770 # `None`. That's also strange and perhaps worthy of raising an
771 # exception, but for now, we just set the backend to 'agg'.
771 # exception, but for now, we just set the backend to 'agg'.
772
772
773 if not self._pyplot_imported:
773 if not self._pyplot_imported:
774 if 'matplotlib.backends' not in sys.modules:
774 if 'matplotlib.backends' not in sys.modules:
775 # Then ipython_matplotlib was set to None but there was a
775 # Then ipython_matplotlib was set to None but there was a
776 # call to the @figure decorator (and ipython_execlines did
776 # call to the @figure decorator (and ipython_execlines did
777 # not set a backend).
777 # not set a backend).
778 #raise Exception("No backend was set, but @figure was used!")
778 #raise Exception("No backend was set, but @figure was used!")
779 import matplotlib
779 import matplotlib
780 matplotlib.use('agg')
780 matplotlib.use('agg')
781
781
782 # Always import pyplot into embedded shell.
782 # Always import pyplot into embedded shell.
783 self.process_input_line('import matplotlib.pyplot as plt',
783 self.process_input_line('import matplotlib.pyplot as plt',
784 store_history=False)
784 store_history=False)
785 self._pyplot_imported = True
785 self._pyplot_imported = True
786
786
787 def process_pure_python(self, content):
787 def process_pure_python(self, content):
788 """
788 """
789 content is a list of strings. it is unedited directive content
789 content is a list of strings. it is unedited directive content
790
790
791 This runs it line by line in the InteractiveShell, prepends
791 This runs it line by line in the InteractiveShell, prepends
792 prompts as needed capturing stderr and stdout, then returns
792 prompts as needed capturing stderr and stdout, then returns
793 the content as a list as if it were ipython code
793 the content as a list as if it were ipython code
794 """
794 """
795 output = []
795 output = []
796 savefig = False # keep up with this to clear figure
796 savefig = False # keep up with this to clear figure
797 multiline = False # to handle line continuation
797 multiline = False # to handle line continuation
798 multiline_start = None
798 multiline_start = None
799 fmtin = self.promptin
799 fmtin = self.promptin
800
800
801 ct = 0
801 ct = 0
802
802
803 for lineno, line in enumerate(content):
803 for lineno, line in enumerate(content):
804
804
805 line_stripped = line.strip()
805 line_stripped = line.strip()
806 if not len(line):
806 if not len(line):
807 output.append(line)
807 output.append(line)
808 continue
808 continue
809
809
810 # handle decorators
810 # handle decorators
811 if line_stripped.startswith('@'):
811 if line_stripped.startswith('@'):
812 output.extend([line])
812 output.extend([line])
813 if 'savefig' in line:
813 if 'savefig' in line:
814 savefig = True # and need to clear figure
814 savefig = True # and need to clear figure
815 continue
815 continue
816
816
817 # handle comments
817 # handle comments
818 if line_stripped.startswith('#'):
818 if line_stripped.startswith('#'):
819 output.extend([line])
819 output.extend([line])
820 continue
820 continue
821
821
822 # deal with lines checking for multiline
822 # deal with lines checking for multiline
823 continuation = u' %s:'% ''.join(['.']*(len(str(ct))+2))
823 continuation = u' %s:'% ''.join(['.']*(len(str(ct))+2))
824 if not multiline:
824 if not multiline:
825 modified = u"%s %s" % (fmtin % ct, line_stripped)
825 modified = u"%s %s" % (fmtin % ct, line_stripped)
826 output.append(modified)
826 output.append(modified)
827 ct += 1
827 ct += 1
828 try:
828 try:
829 ast.parse(line_stripped)
829 ast.parse(line_stripped)
830 output.append(u'')
830 output.append(u'')
831 except Exception: # on a multiline
831 except Exception: # on a multiline
832 multiline = True
832 multiline = True
833 multiline_start = lineno
833 multiline_start = lineno
834 else: # still on a multiline
834 else: # still on a multiline
835 modified = u'%s %s' % (continuation, line)
835 modified = u'%s %s' % (continuation, line)
836 output.append(modified)
836 output.append(modified)
837
837
838 # if the next line is indented, it should be part of multiline
838 # if the next line is indented, it should be part of multiline
839 if len(content) > lineno + 1:
839 if len(content) > lineno + 1:
840 nextline = content[lineno + 1]
840 nextline = content[lineno + 1]
841 if len(nextline) - len(nextline.lstrip()) > 3:
841 if len(nextline) - len(nextline.lstrip()) > 3:
842 continue
842 continue
843 try:
843 try:
844 mod = ast.parse(
844 mod = ast.parse(
845 '\n'.join(content[multiline_start:lineno+1]))
845 '\n'.join(content[multiline_start:lineno+1]))
846 if isinstance(mod.body[0], ast.FunctionDef):
846 if isinstance(mod.body[0], ast.FunctionDef):
847 # check to see if we have the whole function
847 # check to see if we have the whole function
848 for element in mod.body[0].body:
848 for element in mod.body[0].body:
849 if isinstance(element, ast.Return):
849 if isinstance(element, ast.Return):
850 multiline = False
850 multiline = False
851 else:
851 else:
852 output.append(u'')
852 output.append(u'')
853 multiline = False
853 multiline = False
854 except Exception:
854 except Exception:
855 pass
855 pass
856
856
857 if savefig: # clear figure if plotted
857 if savefig: # clear figure if plotted
858 self.ensure_pyplot()
858 self.ensure_pyplot()
859 self.process_input_line('plt.clf()', store_history=False)
859 self.process_input_line('plt.clf()', store_history=False)
860 self.clear_cout()
860 self.clear_cout()
861 savefig = False
861 savefig = False
862
862
863 return output
863 return output
864
864
865 def custom_doctest(self, decorator, input_lines, found, submitted):
865 def custom_doctest(self, decorator, input_lines, found, submitted):
866 """
866 """
867 Perform a specialized doctest.
867 Perform a specialized doctest.
868
868
869 """
869 """
870 from .custom_doctests import doctests
870 from .custom_doctests import doctests
871
871
872 args = decorator.split()
872 args = decorator.split()
873 doctest_type = args[1]
873 doctest_type = args[1]
874 if doctest_type in doctests:
874 if doctest_type in doctests:
875 doctests[doctest_type](self, args, input_lines, found, submitted)
875 doctests[doctest_type](self, args, input_lines, found, submitted)
876 else:
876 else:
877 e = "Invalid option to @doctest: {0}".format(doctest_type)
877 e = "Invalid option to @doctest: {0}".format(doctest_type)
878 raise Exception(e)
878 raise Exception(e)
879
879
880
880
881 class IPythonDirective(Directive):
881 class IPythonDirective(Directive):
882
882
883 has_content = True
883 has_content = True
884 required_arguments = 0
884 required_arguments = 0
885 optional_arguments = 4 # python, suppress, verbatim, doctest
885 optional_arguments = 4 # python, suppress, verbatim, doctest
886 final_argumuent_whitespace = True
886 final_argumuent_whitespace = True
887 option_spec = { 'python': directives.unchanged,
887 option_spec = { 'python': directives.unchanged,
888 'suppress' : directives.flag,
888 'suppress' : directives.flag,
889 'verbatim' : directives.flag,
889 'verbatim' : directives.flag,
890 'doctest' : directives.flag,
890 'doctest' : directives.flag,
891 'okexcept': directives.flag,
891 'okexcept': directives.flag,
892 'okwarning': directives.flag
892 'okwarning': directives.flag
893 }
893 }
894
894
895 shell = None
895 shell = None
896
896
897 seen_docs = set()
897 seen_docs = set()
898
898
899 def get_config_options(self):
899 def get_config_options(self):
900 # contains sphinx configuration variables
900 # contains sphinx configuration variables
901 config = self.state.document.settings.env.config
901 config = self.state.document.settings.env.config
902
902
903 # get config variables to set figure output directory
903 # get config variables to set figure output directory
904 savefig_dir = config.ipython_savefig_dir
904 savefig_dir = config.ipython_savefig_dir
905 source_dir = self.state.document.settings.env.srcdir
905 source_dir = self.state.document.settings.env.srcdir
906 savefig_dir = os.path.join(source_dir, savefig_dir)
906 savefig_dir = os.path.join(source_dir, savefig_dir)
907
907
908 # get regex and prompt stuff
908 # get regex and prompt stuff
909 rgxin = config.ipython_rgxin
909 rgxin = config.ipython_rgxin
910 rgxout = config.ipython_rgxout
910 rgxout = config.ipython_rgxout
911 warning_is_error= config.ipython_warning_is_error
911 warning_is_error= config.ipython_warning_is_error
912 promptin = config.ipython_promptin
912 promptin = config.ipython_promptin
913 promptout = config.ipython_promptout
913 promptout = config.ipython_promptout
914 mplbackend = config.ipython_mplbackend
914 mplbackend = config.ipython_mplbackend
915 exec_lines = config.ipython_execlines
915 exec_lines = config.ipython_execlines
916 hold_count = config.ipython_holdcount
916 hold_count = config.ipython_holdcount
917
917
918 return (savefig_dir, source_dir, rgxin, rgxout,
918 return (savefig_dir, source_dir, rgxin, rgxout,
919 promptin, promptout, mplbackend, exec_lines, hold_count, warning_is_error)
919 promptin, promptout, mplbackend, exec_lines, hold_count, warning_is_error)
920
920
921 def setup(self):
921 def setup(self):
922 # Get configuration values.
922 # Get configuration values.
923 (savefig_dir, source_dir, rgxin, rgxout, promptin, promptout,
923 (savefig_dir, source_dir, rgxin, rgxout, promptin, promptout,
924 mplbackend, exec_lines, hold_count, warning_is_error) = self.get_config_options()
924 mplbackend, exec_lines, hold_count, warning_is_error) = self.get_config_options()
925
925
926 try:
926 try:
927 os.makedirs(savefig_dir)
927 os.makedirs(savefig_dir)
928 except OSError as e:
928 except OSError as e:
929 if e.errno != errno.EEXIST:
929 if e.errno != errno.EEXIST:
930 raise
930 raise
931
931
932 if self.shell is None:
932 if self.shell is None:
933 # We will be here many times. However, when the
933 # We will be here many times. However, when the
934 # EmbeddedSphinxShell is created, its interactive shell member
934 # EmbeddedSphinxShell is created, its interactive shell member
935 # is the same for each instance.
935 # is the same for each instance.
936
936
937 if mplbackend and 'matplotlib.backends' not in sys.modules and use_matpltolib:
937 if mplbackend and 'matplotlib.backends' not in sys.modules and use_matplotlib:
938 import matplotlib
938 import matplotlib
939 matplotlib.use(mplbackend)
939 matplotlib.use(mplbackend)
940
940
941 # Must be called after (potentially) importing matplotlib and
941 # Must be called after (potentially) importing matplotlib and
942 # setting its backend since exec_lines might import pylab.
942 # setting its backend since exec_lines might import pylab.
943 self.shell = EmbeddedSphinxShell(exec_lines)
943 self.shell = EmbeddedSphinxShell(exec_lines)
944
944
945 # Store IPython directive to enable better error messages
945 # Store IPython directive to enable better error messages
946 self.shell.directive = self
946 self.shell.directive = self
947
947
948 # reset the execution count if we haven't processed this doc
948 # reset the execution count if we haven't processed this doc
949 #NOTE: this may be borked if there are multiple seen_doc tmp files
949 #NOTE: this may be borked if there are multiple seen_doc tmp files
950 #check time stamp?
950 #check time stamp?
951 if not self.state.document.current_source in self.seen_docs:
951 if not self.state.document.current_source in self.seen_docs:
952 self.shell.IP.history_manager.reset()
952 self.shell.IP.history_manager.reset()
953 self.shell.IP.execution_count = 1
953 self.shell.IP.execution_count = 1
954 self.seen_docs.add(self.state.document.current_source)
954 self.seen_docs.add(self.state.document.current_source)
955
955
956 # and attach to shell so we don't have to pass them around
956 # and attach to shell so we don't have to pass them around
957 self.shell.rgxin = rgxin
957 self.shell.rgxin = rgxin
958 self.shell.rgxout = rgxout
958 self.shell.rgxout = rgxout
959 self.shell.promptin = promptin
959 self.shell.promptin = promptin
960 self.shell.promptout = promptout
960 self.shell.promptout = promptout
961 self.shell.savefig_dir = savefig_dir
961 self.shell.savefig_dir = savefig_dir
962 self.shell.source_dir = source_dir
962 self.shell.source_dir = source_dir
963 self.shell.hold_count = hold_count
963 self.shell.hold_count = hold_count
964 self.shell.warning_is_error = warning_is_error
964 self.shell.warning_is_error = warning_is_error
965
965
966 # setup bookmark for saving figures directory
966 # setup bookmark for saving figures directory
967 self.shell.process_input_line('bookmark ipy_savedir %s'%savefig_dir,
967 self.shell.process_input_line('bookmark ipy_savedir %s'%savefig_dir,
968 store_history=False)
968 store_history=False)
969 self.shell.clear_cout()
969 self.shell.clear_cout()
970
970
971 return rgxin, rgxout, promptin, promptout
971 return rgxin, rgxout, promptin, promptout
972
972
973 def teardown(self):
973 def teardown(self):
974 # delete last bookmark
974 # delete last bookmark
975 self.shell.process_input_line('bookmark -d ipy_savedir',
975 self.shell.process_input_line('bookmark -d ipy_savedir',
976 store_history=False)
976 store_history=False)
977 self.shell.clear_cout()
977 self.shell.clear_cout()
978
978
979 def run(self):
979 def run(self):
980 debug = False
980 debug = False
981
981
982 #TODO, any reason block_parser can't be a method of embeddable shell
982 #TODO, any reason block_parser can't be a method of embeddable shell
983 # then we wouldn't have to carry these around
983 # then we wouldn't have to carry these around
984 rgxin, rgxout, promptin, promptout = self.setup()
984 rgxin, rgxout, promptin, promptout = self.setup()
985
985
986 options = self.options
986 options = self.options
987 self.shell.is_suppress = 'suppress' in options
987 self.shell.is_suppress = 'suppress' in options
988 self.shell.is_doctest = 'doctest' in options
988 self.shell.is_doctest = 'doctest' in options
989 self.shell.is_verbatim = 'verbatim' in options
989 self.shell.is_verbatim = 'verbatim' in options
990 self.shell.is_okexcept = 'okexcept' in options
990 self.shell.is_okexcept = 'okexcept' in options
991 self.shell.is_okwarning = 'okwarning' in options
991 self.shell.is_okwarning = 'okwarning' in options
992
992
993 # handle pure python code
993 # handle pure python code
994 if 'python' in self.arguments:
994 if 'python' in self.arguments:
995 content = self.content
995 content = self.content
996 self.content = self.shell.process_pure_python(content)
996 self.content = self.shell.process_pure_python(content)
997
997
998 # parts consists of all text within the ipython-block.
998 # parts consists of all text within the ipython-block.
999 # Each part is an input/output block.
999 # Each part is an input/output block.
1000 parts = '\n'.join(self.content).split('\n\n')
1000 parts = '\n'.join(self.content).split('\n\n')
1001
1001
1002 lines = ['.. code-block:: ipython', '']
1002 lines = ['.. code-block:: ipython', '']
1003 figures = []
1003 figures = []
1004
1004
1005 for part in parts:
1005 for part in parts:
1006 block = block_parser(part, rgxin, rgxout, promptin, promptout)
1006 block = block_parser(part, rgxin, rgxout, promptin, promptout)
1007 if len(block):
1007 if len(block):
1008 rows, figure = self.shell.process_block(block)
1008 rows, figure = self.shell.process_block(block)
1009 for row in rows:
1009 for row in rows:
1010 lines.extend([' {0}'.format(line)
1010 lines.extend([' {0}'.format(line)
1011 for line in row.split('\n')])
1011 for line in row.split('\n')])
1012
1012
1013 if figure is not None:
1013 if figure is not None:
1014 figures.append(figure)
1014 figures.append(figure)
1015 else:
1015 else:
1016 message = 'Code input with no code at {}, line {}'\
1016 message = 'Code input with no code at {}, line {}'\
1017 .format(
1017 .format(
1018 self.state.document.current_source,
1018 self.state.document.current_source,
1019 self.state.document.current_line)
1019 self.state.document.current_line)
1020 if self.shell.warning_is_error:
1020 if self.shell.warning_is_error:
1021 raise RuntimeError(message)
1021 raise RuntimeError(message)
1022 else:
1022 else:
1023 warnings.warn(message)
1023 warnings.warn(message)
1024
1024
1025 for figure in figures:
1025 for figure in figures:
1026 lines.append('')
1026 lines.append('')
1027 lines.extend(figure.split('\n'))
1027 lines.extend(figure.split('\n'))
1028 lines.append('')
1028 lines.append('')
1029
1029
1030 if len(lines) > 2:
1030 if len(lines) > 2:
1031 if debug:
1031 if debug:
1032 print('\n'.join(lines))
1032 print('\n'.join(lines))
1033 else:
1033 else:
1034 # This has to do with input, not output. But if we comment
1034 # This has to do with input, not output. But if we comment
1035 # these lines out, then no IPython code will appear in the
1035 # these lines out, then no IPython code will appear in the
1036 # final output.
1036 # final output.
1037 self.state_machine.insert_input(
1037 self.state_machine.insert_input(
1038 lines, self.state_machine.input_lines.source(0))
1038 lines, self.state_machine.input_lines.source(0))
1039
1039
1040 # cleanup
1040 # cleanup
1041 self.teardown()
1041 self.teardown()
1042
1042
1043 return []
1043 return []
1044
1044
1045 # Enable as a proper Sphinx directive
1045 # Enable as a proper Sphinx directive
1046 def setup(app):
1046 def setup(app):
1047 setup.app = app
1047 setup.app = app
1048
1048
1049 app.add_directive('ipython', IPythonDirective)
1049 app.add_directive('ipython', IPythonDirective)
1050 app.add_config_value('ipython_savefig_dir', 'savefig', 'env')
1050 app.add_config_value('ipython_savefig_dir', 'savefig', 'env')
1051 app.add_config_value('ipython_warning_is_error', True, 'env')
1051 app.add_config_value('ipython_warning_is_error', True, 'env')
1052 app.add_config_value('ipython_rgxin',
1052 app.add_config_value('ipython_rgxin',
1053 re.compile(r'In \[(\d+)\]:\s?(.*)\s*'), 'env')
1053 re.compile(r'In \[(\d+)\]:\s?(.*)\s*'), 'env')
1054 app.add_config_value('ipython_rgxout',
1054 app.add_config_value('ipython_rgxout',
1055 re.compile(r'Out\[(\d+)\]:\s?(.*)\s*'), 'env')
1055 re.compile(r'Out\[(\d+)\]:\s?(.*)\s*'), 'env')
1056 app.add_config_value('ipython_promptin', 'In [%d]:', 'env')
1056 app.add_config_value('ipython_promptin', 'In [%d]:', 'env')
1057 app.add_config_value('ipython_promptout', 'Out[%d]:', 'env')
1057 app.add_config_value('ipython_promptout', 'Out[%d]:', 'env')
1058
1058
1059 # We could just let matplotlib pick whatever is specified as the default
1059 # We could just let matplotlib pick whatever is specified as the default
1060 # backend in the matplotlibrc file, but this would cause issues if the
1060 # backend in the matplotlibrc file, but this would cause issues if the
1061 # backend didn't work in headless environments. For this reason, 'agg'
1061 # backend didn't work in headless environments. For this reason, 'agg'
1062 # is a good default backend choice.
1062 # is a good default backend choice.
1063 app.add_config_value('ipython_mplbackend', 'agg', 'env')
1063 app.add_config_value('ipython_mplbackend', 'agg', 'env')
1064
1064
1065 # If the user sets this config value to `None`, then EmbeddedSphinxShell's
1065 # If the user sets this config value to `None`, then EmbeddedSphinxShell's
1066 # __init__ method will treat it as [].
1066 # __init__ method will treat it as [].
1067 execlines = ['import numpy as np']
1067 execlines = ['import numpy as np']
1068 if use_matpltolib:
1068 if use_matplotlib:
1069 execlines.append('import matplotlib.pyplot as plt')
1069 execlines.append('import matplotlib.pyplot as plt')
1070 app.add_config_value('ipython_execlines', execlines, 'env')
1070 app.add_config_value('ipython_execlines', execlines, 'env')
1071
1071
1072 app.add_config_value('ipython_holdcount', True, 'env')
1072 app.add_config_value('ipython_holdcount', True, 'env')
1073
1073
1074 metadata = {'parallel_read_safe': True, 'parallel_write_safe': True}
1074 metadata = {'parallel_read_safe': True, 'parallel_write_safe': True}
1075 return metadata
1075 return metadata
1076
1076
1077 # Simple smoke test, needs to be converted to a proper automatic test.
1077 # Simple smoke test, needs to be converted to a proper automatic test.
1078 def test():
1078 def test():
1079
1079
1080 examples = [
1080 examples = [
1081 r"""
1081 r"""
1082 In [9]: pwd
1082 In [9]: pwd
1083 Out[9]: '/home/jdhunter/py4science/book'
1083 Out[9]: '/home/jdhunter/py4science/book'
1084
1084
1085 In [10]: cd bookdata/
1085 In [10]: cd bookdata/
1086 /home/jdhunter/py4science/book/bookdata
1086 /home/jdhunter/py4science/book/bookdata
1087
1087
1088 In [2]: from pylab import *
1088 In [2]: from pylab import *
1089
1089
1090 In [2]: ion()
1090 In [2]: ion()
1091
1091
1092 In [3]: im = imread('stinkbug.png')
1092 In [3]: im = imread('stinkbug.png')
1093
1093
1094 @savefig mystinkbug.png width=4in
1094 @savefig mystinkbug.png width=4in
1095 In [4]: imshow(im)
1095 In [4]: imshow(im)
1096 Out[4]: <matplotlib.image.AxesImage object at 0x39ea850>
1096 Out[4]: <matplotlib.image.AxesImage object at 0x39ea850>
1097
1097
1098 """,
1098 """,
1099 r"""
1099 r"""
1100
1100
1101 In [1]: x = 'hello world'
1101 In [1]: x = 'hello world'
1102
1102
1103 # string methods can be
1103 # string methods can be
1104 # used to alter the string
1104 # used to alter the string
1105 @doctest
1105 @doctest
1106 In [2]: x.upper()
1106 In [2]: x.upper()
1107 Out[2]: 'HELLO WORLD'
1107 Out[2]: 'HELLO WORLD'
1108
1108
1109 @verbatim
1109 @verbatim
1110 In [3]: x.st<TAB>
1110 In [3]: x.st<TAB>
1111 x.startswith x.strip
1111 x.startswith x.strip
1112 """,
1112 """,
1113 r"""
1113 r"""
1114
1114
1115 In [130]: url = 'http://ichart.finance.yahoo.com/table.csv?s=CROX\
1115 In [130]: url = 'http://ichart.finance.yahoo.com/table.csv?s=CROX\
1116 .....: &d=9&e=22&f=2009&g=d&a=1&br=8&c=2006&ignore=.csv'
1116 .....: &d=9&e=22&f=2009&g=d&a=1&br=8&c=2006&ignore=.csv'
1117
1117
1118 In [131]: print url.split('&')
1118 In [131]: print url.split('&')
1119 ['http://ichart.finance.yahoo.com/table.csv?s=CROX', 'd=9', 'e=22', 'f=2009', 'g=d', 'a=1', 'b=8', 'c=2006', 'ignore=.csv']
1119 ['http://ichart.finance.yahoo.com/table.csv?s=CROX', 'd=9', 'e=22', 'f=2009', 'g=d', 'a=1', 'b=8', 'c=2006', 'ignore=.csv']
1120
1120
1121 In [60]: import urllib
1121 In [60]: import urllib
1122
1122
1123 """,
1123 """,
1124 r"""\
1124 r"""\
1125
1125
1126 In [133]: import numpy.random
1126 In [133]: import numpy.random
1127
1127
1128 @suppress
1128 @suppress
1129 In [134]: numpy.random.seed(2358)
1129 In [134]: numpy.random.seed(2358)
1130
1130
1131 @doctest
1131 @doctest
1132 In [135]: numpy.random.rand(10,2)
1132 In [135]: numpy.random.rand(10,2)
1133 Out[135]:
1133 Out[135]:
1134 array([[ 0.64524308, 0.59943846],
1134 array([[ 0.64524308, 0.59943846],
1135 [ 0.47102322, 0.8715456 ],
1135 [ 0.47102322, 0.8715456 ],
1136 [ 0.29370834, 0.74776844],
1136 [ 0.29370834, 0.74776844],
1137 [ 0.99539577, 0.1313423 ],
1137 [ 0.99539577, 0.1313423 ],
1138 [ 0.16250302, 0.21103583],
1138 [ 0.16250302, 0.21103583],
1139 [ 0.81626524, 0.1312433 ],
1139 [ 0.81626524, 0.1312433 ],
1140 [ 0.67338089, 0.72302393],
1140 [ 0.67338089, 0.72302393],
1141 [ 0.7566368 , 0.07033696],
1141 [ 0.7566368 , 0.07033696],
1142 [ 0.22591016, 0.77731835],
1142 [ 0.22591016, 0.77731835],
1143 [ 0.0072729 , 0.34273127]])
1143 [ 0.0072729 , 0.34273127]])
1144
1144
1145 """,
1145 """,
1146
1146
1147 r"""
1147 r"""
1148 In [106]: print x
1148 In [106]: print x
1149 jdh
1149 jdh
1150
1150
1151 In [109]: for i in range(10):
1151 In [109]: for i in range(10):
1152 .....: print i
1152 .....: print i
1153 .....:
1153 .....:
1154 .....:
1154 .....:
1155 0
1155 0
1156 1
1156 1
1157 2
1157 2
1158 3
1158 3
1159 4
1159 4
1160 5
1160 5
1161 6
1161 6
1162 7
1162 7
1163 8
1163 8
1164 9
1164 9
1165 """,
1165 """,
1166
1166
1167 r"""
1167 r"""
1168
1168
1169 In [144]: from pylab import *
1169 In [144]: from pylab import *
1170
1170
1171 In [145]: ion()
1171 In [145]: ion()
1172
1172
1173 # use a semicolon to suppress the output
1173 # use a semicolon to suppress the output
1174 @savefig test_hist.png width=4in
1174 @savefig test_hist.png width=4in
1175 In [151]: hist(np.random.randn(10000), 100);
1175 In [151]: hist(np.random.randn(10000), 100);
1176
1176
1177
1177
1178 @savefig test_plot.png width=4in
1178 @savefig test_plot.png width=4in
1179 In [151]: plot(np.random.randn(10000), 'o');
1179 In [151]: plot(np.random.randn(10000), 'o');
1180 """,
1180 """,
1181
1181
1182 r"""
1182 r"""
1183 # use a semicolon to suppress the output
1183 # use a semicolon to suppress the output
1184 In [151]: plt.clf()
1184 In [151]: plt.clf()
1185
1185
1186 @savefig plot_simple.png width=4in
1186 @savefig plot_simple.png width=4in
1187 In [151]: plot([1,2,3])
1187 In [151]: plot([1,2,3])
1188
1188
1189 @savefig hist_simple.png width=4in
1189 @savefig hist_simple.png width=4in
1190 In [151]: hist(np.random.randn(10000), 100);
1190 In [151]: hist(np.random.randn(10000), 100);
1191
1191
1192 """,
1192 """,
1193 r"""
1193 r"""
1194 # update the current fig
1194 # update the current fig
1195 In [151]: ylabel('number')
1195 In [151]: ylabel('number')
1196
1196
1197 In [152]: title('normal distribution')
1197 In [152]: title('normal distribution')
1198
1198
1199
1199
1200 @savefig hist_with_text.png
1200 @savefig hist_with_text.png
1201 In [153]: grid(True)
1201 In [153]: grid(True)
1202
1202
1203 @doctest float
1203 @doctest float
1204 In [154]: 0.1 + 0.2
1204 In [154]: 0.1 + 0.2
1205 Out[154]: 0.3
1205 Out[154]: 0.3
1206
1206
1207 @doctest float
1207 @doctest float
1208 In [155]: np.arange(16).reshape(4,4)
1208 In [155]: np.arange(16).reshape(4,4)
1209 Out[155]:
1209 Out[155]:
1210 array([[ 0, 1, 2, 3],
1210 array([[ 0, 1, 2, 3],
1211 [ 4, 5, 6, 7],
1211 [ 4, 5, 6, 7],
1212 [ 8, 9, 10, 11],
1212 [ 8, 9, 10, 11],
1213 [12, 13, 14, 15]])
1213 [12, 13, 14, 15]])
1214
1214
1215 In [1]: x = np.arange(16, dtype=float).reshape(4,4)
1215 In [1]: x = np.arange(16, dtype=float).reshape(4,4)
1216
1216
1217 In [2]: x[0,0] = np.inf
1217 In [2]: x[0,0] = np.inf
1218
1218
1219 In [3]: x[0,1] = np.nan
1219 In [3]: x[0,1] = np.nan
1220
1220
1221 @doctest float
1221 @doctest float
1222 In [4]: x
1222 In [4]: x
1223 Out[4]:
1223 Out[4]:
1224 array([[ inf, nan, 2., 3.],
1224 array([[ inf, nan, 2., 3.],
1225 [ 4., 5., 6., 7.],
1225 [ 4., 5., 6., 7.],
1226 [ 8., 9., 10., 11.],
1226 [ 8., 9., 10., 11.],
1227 [ 12., 13., 14., 15.]])
1227 [ 12., 13., 14., 15.]])
1228
1228
1229
1229
1230 """,
1230 """,
1231 ]
1231 ]
1232 # skip local-file depending first example:
1232 # skip local-file depending first example:
1233 examples = examples[1:]
1233 examples = examples[1:]
1234
1234
1235 #ipython_directive.DEBUG = True # dbg
1235 #ipython_directive.DEBUG = True # dbg
1236 #options = dict(suppress=True) # dbg
1236 #options = dict(suppress=True) # dbg
1237 options = {}
1237 options = {}
1238 for example in examples:
1238 for example in examples:
1239 content = example.split('\n')
1239 content = example.split('\n')
1240 IPythonDirective('debug', arguments=None, options=options,
1240 IPythonDirective('debug', arguments=None, options=options,
1241 content=content, lineno=0,
1241 content=content, lineno=0,
1242 content_offset=None, block_text=None,
1242 content_offset=None, block_text=None,
1243 state=None, state_machine=None,
1243 state=None, state_machine=None,
1244 )
1244 )
1245
1245
1246 # Run test suite as a script
1246 # Run test suite as a script
1247 if __name__=='__main__':
1247 if __name__=='__main__':
1248 if not os.path.isdir('_static'):
1248 if not os.path.isdir('_static'):
1249 os.mkdir('_static')
1249 os.mkdir('_static')
1250 test()
1250 test()
1251 print('All OK? Check figures in _static/')
1251 print('All OK? Check figures in _static/')
@@ -1,147 +1,147 b''
1 """Enable wxPython to be used interacively in prompt_toolkit
1 """Enable wxPython to be used interactively in prompt_toolkit
2 """
2 """
3
3
4 import sys
4 import sys
5 import signal
5 import signal
6 import time
6 import time
7 from timeit import default_timer as clock
7 from timeit import default_timer as clock
8 import wx
8 import wx
9
9
10
10
11 def inputhook_wx1(context):
11 def inputhook_wx1(context):
12 """Run the wx event loop by processing pending events only.
12 """Run the wx event loop by processing pending events only.
13
13
14 This approach seems to work, but its performance is not great as it
14 This approach seems to work, but its performance is not great as it
15 relies on having PyOS_InputHook called regularly.
15 relies on having PyOS_InputHook called regularly.
16 """
16 """
17 try:
17 try:
18 app = wx.GetApp()
18 app = wx.GetApp()
19 if app is not None:
19 if app is not None:
20 assert wx.Thread_IsMain()
20 assert wx.Thread_IsMain()
21
21
22 # Make a temporary event loop and process system events until
22 # Make a temporary event loop and process system events until
23 # there are no more waiting, then allow idle events (which
23 # there are no more waiting, then allow idle events (which
24 # will also deal with pending or posted wx events.)
24 # will also deal with pending or posted wx events.)
25 evtloop = wx.EventLoop()
25 evtloop = wx.EventLoop()
26 ea = wx.EventLoopActivator(evtloop)
26 ea = wx.EventLoopActivator(evtloop)
27 while evtloop.Pending():
27 while evtloop.Pending():
28 evtloop.Dispatch()
28 evtloop.Dispatch()
29 app.ProcessIdle()
29 app.ProcessIdle()
30 del ea
30 del ea
31 except KeyboardInterrupt:
31 except KeyboardInterrupt:
32 pass
32 pass
33 return 0
33 return 0
34
34
35 class EventLoopTimer(wx.Timer):
35 class EventLoopTimer(wx.Timer):
36
36
37 def __init__(self, func):
37 def __init__(self, func):
38 self.func = func
38 self.func = func
39 wx.Timer.__init__(self)
39 wx.Timer.__init__(self)
40
40
41 def Notify(self):
41 def Notify(self):
42 self.func()
42 self.func()
43
43
44 class EventLoopRunner(object):
44 class EventLoopRunner(object):
45
45
46 def Run(self, time, input_is_ready):
46 def Run(self, time, input_is_ready):
47 self.input_is_ready = input_is_ready
47 self.input_is_ready = input_is_ready
48 self.evtloop = wx.EventLoop()
48 self.evtloop = wx.EventLoop()
49 self.timer = EventLoopTimer(self.check_stdin)
49 self.timer = EventLoopTimer(self.check_stdin)
50 self.timer.Start(time)
50 self.timer.Start(time)
51 self.evtloop.Run()
51 self.evtloop.Run()
52
52
53 def check_stdin(self):
53 def check_stdin(self):
54 if self.input_is_ready():
54 if self.input_is_ready():
55 self.timer.Stop()
55 self.timer.Stop()
56 self.evtloop.Exit()
56 self.evtloop.Exit()
57
57
58 def inputhook_wx2(context):
58 def inputhook_wx2(context):
59 """Run the wx event loop, polling for stdin.
59 """Run the wx event loop, polling for stdin.
60
60
61 This version runs the wx eventloop for an undetermined amount of time,
61 This version runs the wx eventloop for an undetermined amount of time,
62 during which it periodically checks to see if anything is ready on
62 during which it periodically checks to see if anything is ready on
63 stdin. If anything is ready on stdin, the event loop exits.
63 stdin. If anything is ready on stdin, the event loop exits.
64
64
65 The argument to elr.Run controls how often the event loop looks at stdin.
65 The argument to elr.Run controls how often the event loop looks at stdin.
66 This determines the responsiveness at the keyboard. A setting of 1000
66 This determines the responsiveness at the keyboard. A setting of 1000
67 enables a user to type at most 1 char per second. I have found that a
67 enables a user to type at most 1 char per second. I have found that a
68 setting of 10 gives good keyboard response. We can shorten it further,
68 setting of 10 gives good keyboard response. We can shorten it further,
69 but eventually performance would suffer from calling select/kbhit too
69 but eventually performance would suffer from calling select/kbhit too
70 often.
70 often.
71 """
71 """
72 try:
72 try:
73 app = wx.GetApp()
73 app = wx.GetApp()
74 if app is not None:
74 if app is not None:
75 assert wx.Thread_IsMain()
75 assert wx.Thread_IsMain()
76 elr = EventLoopRunner()
76 elr = EventLoopRunner()
77 # As this time is made shorter, keyboard response improves, but idle
77 # As this time is made shorter, keyboard response improves, but idle
78 # CPU load goes up. 10 ms seems like a good compromise.
78 # CPU load goes up. 10 ms seems like a good compromise.
79 elr.Run(time=10, # CHANGE time here to control polling interval
79 elr.Run(time=10, # CHANGE time here to control polling interval
80 input_is_ready=context.input_is_ready)
80 input_is_ready=context.input_is_ready)
81 except KeyboardInterrupt:
81 except KeyboardInterrupt:
82 pass
82 pass
83 return 0
83 return 0
84
84
85 def inputhook_wx3(context):
85 def inputhook_wx3(context):
86 """Run the wx event loop by processing pending events only.
86 """Run the wx event loop by processing pending events only.
87
87
88 This is like inputhook_wx1, but it keeps processing pending events
88 This is like inputhook_wx1, but it keeps processing pending events
89 until stdin is ready. After processing all pending events, a call to
89 until stdin is ready. After processing all pending events, a call to
90 time.sleep is inserted. This is needed, otherwise, CPU usage is at 100%.
90 time.sleep is inserted. This is needed, otherwise, CPU usage is at 100%.
91 This sleep time should be tuned though for best performance.
91 This sleep time should be tuned though for best performance.
92 """
92 """
93 # We need to protect against a user pressing Control-C when IPython is
93 # We need to protect against a user pressing Control-C when IPython is
94 # idle and this is running. We trap KeyboardInterrupt and pass.
94 # idle and this is running. We trap KeyboardInterrupt and pass.
95 try:
95 try:
96 app = wx.GetApp()
96 app = wx.GetApp()
97 if app is not None:
97 if app is not None:
98 assert wx.Thread_IsMain()
98 assert wx.Thread_IsMain()
99
99
100 # The import of wx on Linux sets the handler for signal.SIGINT
100 # The import of wx on Linux sets the handler for signal.SIGINT
101 # to 0. This is a bug in wx or gtk. We fix by just setting it
101 # to 0. This is a bug in wx or gtk. We fix by just setting it
102 # back to the Python default.
102 # back to the Python default.
103 if not callable(signal.getsignal(signal.SIGINT)):
103 if not callable(signal.getsignal(signal.SIGINT)):
104 signal.signal(signal.SIGINT, signal.default_int_handler)
104 signal.signal(signal.SIGINT, signal.default_int_handler)
105
105
106 evtloop = wx.EventLoop()
106 evtloop = wx.EventLoop()
107 ea = wx.EventLoopActivator(evtloop)
107 ea = wx.EventLoopActivator(evtloop)
108 t = clock()
108 t = clock()
109 while not context.input_is_ready():
109 while not context.input_is_ready():
110 while evtloop.Pending():
110 while evtloop.Pending():
111 t = clock()
111 t = clock()
112 evtloop.Dispatch()
112 evtloop.Dispatch()
113 app.ProcessIdle()
113 app.ProcessIdle()
114 # We need to sleep at this point to keep the idle CPU load
114 # We need to sleep at this point to keep the idle CPU load
115 # low. However, if sleep to long, GUI response is poor. As
115 # low. However, if sleep to long, GUI response is poor. As
116 # a compromise, we watch how often GUI events are being processed
116 # a compromise, we watch how often GUI events are being processed
117 # and switch between a short and long sleep time. Here are some
117 # and switch between a short and long sleep time. Here are some
118 # stats useful in helping to tune this.
118 # stats useful in helping to tune this.
119 # time CPU load
119 # time CPU load
120 # 0.001 13%
120 # 0.001 13%
121 # 0.005 3%
121 # 0.005 3%
122 # 0.01 1.5%
122 # 0.01 1.5%
123 # 0.05 0.5%
123 # 0.05 0.5%
124 used_time = clock() - t
124 used_time = clock() - t
125 if used_time > 10.0:
125 if used_time > 10.0:
126 # print 'Sleep for 1 s' # dbg
126 # print 'Sleep for 1 s' # dbg
127 time.sleep(1.0)
127 time.sleep(1.0)
128 elif used_time > 0.1:
128 elif used_time > 0.1:
129 # Few GUI events coming in, so we can sleep longer
129 # Few GUI events coming in, so we can sleep longer
130 # print 'Sleep for 0.05 s' # dbg
130 # print 'Sleep for 0.05 s' # dbg
131 time.sleep(0.05)
131 time.sleep(0.05)
132 else:
132 else:
133 # Many GUI events coming in, so sleep only very little
133 # Many GUI events coming in, so sleep only very little
134 time.sleep(0.001)
134 time.sleep(0.001)
135 del ea
135 del ea
136 except KeyboardInterrupt:
136 except KeyboardInterrupt:
137 pass
137 pass
138 return 0
138 return 0
139
139
140 if sys.platform == 'darwin':
140 if sys.platform == 'darwin':
141 # On OSX, evtloop.Pending() always returns True, regardless of there being
141 # On OSX, evtloop.Pending() always returns True, regardless of there being
142 # any events pending. As such we can't use implementations 1 or 3 of the
142 # any events pending. As such we can't use implementations 1 or 3 of the
143 # inputhook as those depend on a pending/dispatch loop.
143 # inputhook as those depend on a pending/dispatch loop.
144 inputhook = inputhook_wx2
144 inputhook = inputhook_wx2
145 else:
145 else:
146 # This is our default implementation
146 # This is our default implementation
147 inputhook = inputhook_wx3
147 inputhook = inputhook_wx3
@@ -1,133 +1,133 b''
1 """Tests for tokenutil"""
1 """Tests for tokenutil"""
2 # Copyright (c) IPython Development Team.
2 # Copyright (c) IPython Development Team.
3 # Distributed under the terms of the Modified BSD License.
3 # Distributed under the terms of the Modified BSD License.
4
4
5 import nose.tools as nt
5 import nose.tools as nt
6
6
7 from IPython.utils.tokenutil import token_at_cursor, line_at_cursor
7 from IPython.utils.tokenutil import token_at_cursor, line_at_cursor
8
8
9 def expect_token(expected, cell, cursor_pos):
9 def expect_token(expected, cell, cursor_pos):
10 token = token_at_cursor(cell, cursor_pos)
10 token = token_at_cursor(cell, cursor_pos)
11 offset = 0
11 offset = 0
12 for line in cell.splitlines():
12 for line in cell.splitlines():
13 if offset + len(line) >= cursor_pos:
13 if offset + len(line) >= cursor_pos:
14 break
14 break
15 else:
15 else:
16 offset += len(line)+1
16 offset += len(line)+1
17 column = cursor_pos - offset
17 column = cursor_pos - offset
18 line_with_cursor = '%s|%s' % (line[:column], line[column:])
18 line_with_cursor = '%s|%s' % (line[:column], line[column:])
19 nt.assert_equal(token, expected,
19 nt.assert_equal(token, expected,
20 "Expected %r, got %r in: %r (pos %i)" % (
20 "Expected %r, got %r in: %r (pos %i)" % (
21 expected, token, line_with_cursor, cursor_pos)
21 expected, token, line_with_cursor, cursor_pos)
22 )
22 )
23
23
24 def test_simple():
24 def test_simple():
25 cell = "foo"
25 cell = "foo"
26 for i in range(len(cell)):
26 for i in range(len(cell)):
27 expect_token("foo", cell, i)
27 expect_token("foo", cell, i)
28
28
29 def test_function():
29 def test_function():
30 cell = "foo(a=5, b='10')"
30 cell = "foo(a=5, b='10')"
31 expected = 'foo'
31 expected = 'foo'
32 # up to `foo(|a=`
32 # up to `foo(|a=`
33 for i in range(cell.find('a=') + 1):
33 for i in range(cell.find('a=') + 1):
34 expect_token("foo", cell, i)
34 expect_token("foo", cell, i)
35 # find foo after `=`
35 # find foo after `=`
36 for i in [cell.find('=') + 1, cell.rfind('=') + 1]:
36 for i in [cell.find('=') + 1, cell.rfind('=') + 1]:
37 expect_token("foo", cell, i)
37 expect_token("foo", cell, i)
38 # in between `5,|` and `|b=`
38 # in between `5,|` and `|b=`
39 for i in range(cell.find(','), cell.find('b=')):
39 for i in range(cell.find(','), cell.find('b=')):
40 expect_token("foo", cell, i)
40 expect_token("foo", cell, i)
41
41
42 def test_multiline():
42 def test_multiline():
43 cell = '\n'.join([
43 cell = '\n'.join([
44 'a = 5',
44 'a = 5',
45 'b = hello("string", there)'
45 'b = hello("string", there)'
46 ])
46 ])
47 expected = 'hello'
47 expected = 'hello'
48 start = cell.index(expected) + 1
48 start = cell.index(expected) + 1
49 for i in range(start, start + len(expected)):
49 for i in range(start, start + len(expected)):
50 expect_token(expected, cell, i)
50 expect_token(expected, cell, i)
51 expected = 'hello'
51 expected = 'hello'
52 start = cell.index(expected) + 1
52 start = cell.index(expected) + 1
53 for i in range(start, start + len(expected)):
53 for i in range(start, start + len(expected)):
54 expect_token(expected, cell, i)
54 expect_token(expected, cell, i)
55
55
56 def test_multiline_token():
56 def test_multiline_token():
57 cell = '\n'.join([
57 cell = '\n'.join([
58 '"""\n\nxxxxxxxxxx\n\n"""',
58 '"""\n\nxxxxxxxxxx\n\n"""',
59 '5, """',
59 '5, """',
60 'docstring',
60 'docstring',
61 'multiline token',
61 'multiline token',
62 '""", [',
62 '""", [',
63 '2, 3, "complicated"]',
63 '2, 3, "complicated"]',
64 'b = hello("string", there)'
64 'b = hello("string", there)'
65 ])
65 ])
66 expected = 'hello'
66 expected = 'hello'
67 start = cell.index(expected) + 1
67 start = cell.index(expected) + 1
68 for i in range(start, start + len(expected)):
68 for i in range(start, start + len(expected)):
69 expect_token(expected, cell, i)
69 expect_token(expected, cell, i)
70 expected = 'hello'
70 expected = 'hello'
71 start = cell.index(expected) + 1
71 start = cell.index(expected) + 1
72 for i in range(start, start + len(expected)):
72 for i in range(start, start + len(expected)):
73 expect_token(expected, cell, i)
73 expect_token(expected, cell, i)
74
74
75 def test_nested_call():
75 def test_nested_call():
76 cell = "foo(bar(a=5), b=10)"
76 cell = "foo(bar(a=5), b=10)"
77 expected = 'foo'
77 expected = 'foo'
78 start = cell.index('bar') + 1
78 start = cell.index('bar') + 1
79 for i in range(start, start + 3):
79 for i in range(start, start + 3):
80 expect_token(expected, cell, i)
80 expect_token(expected, cell, i)
81 expected = 'bar'
81 expected = 'bar'
82 start = cell.index('a=')
82 start = cell.index('a=')
83 for i in range(start, start + 3):
83 for i in range(start, start + 3):
84 expect_token(expected, cell, i)
84 expect_token(expected, cell, i)
85 expected = 'foo'
85 expected = 'foo'
86 start = cell.index(')') + 1
86 start = cell.index(')') + 1
87 for i in range(start, len(cell)-1):
87 for i in range(start, len(cell)-1):
88 expect_token(expected, cell, i)
88 expect_token(expected, cell, i)
89
89
90 def test_attrs():
90 def test_attrs():
91 cell = "a = obj.attr.subattr"
91 cell = "a = obj.attr.subattr"
92 expected = 'obj'
92 expected = 'obj'
93 idx = cell.find('obj') + 1
93 idx = cell.find('obj') + 1
94 for i in range(idx, idx + 3):
94 for i in range(idx, idx + 3):
95 expect_token(expected, cell, i)
95 expect_token(expected, cell, i)
96 idx = cell.find('.attr') + 2
96 idx = cell.find('.attr') + 2
97 expected = 'obj.attr'
97 expected = 'obj.attr'
98 for i in range(idx, idx + 4):
98 for i in range(idx, idx + 4):
99 expect_token(expected, cell, i)
99 expect_token(expected, cell, i)
100 idx = cell.find('.subattr') + 2
100 idx = cell.find('.subattr') + 2
101 expected = 'obj.attr.subattr'
101 expected = 'obj.attr.subattr'
102 for i in range(idx, len(cell)):
102 for i in range(idx, len(cell)):
103 expect_token(expected, cell, i)
103 expect_token(expected, cell, i)
104
104
105 def test_line_at_cursor():
105 def test_line_at_cursor():
106 cell = ""
106 cell = ""
107 (line, offset) = line_at_cursor(cell, cursor_pos=11)
107 (line, offset) = line_at_cursor(cell, cursor_pos=11)
108 nt.assert_equal(line, "")
108 nt.assert_equal(line, "")
109 nt.assert_equal(offset, 0)
109 nt.assert_equal(offset, 0)
110
110
111 # The position after a newline should be the start of the following line.
111 # The position after a newline should be the start of the following line.
112 cell = "One\nTwo\n"
112 cell = "One\nTwo\n"
113 (line, offset) = line_at_cursor(cell, cursor_pos=4)
113 (line, offset) = line_at_cursor(cell, cursor_pos=4)
114 nt.assert_equal(line, "Two\n")
114 nt.assert_equal(line, "Two\n")
115 nt.assert_equal(offset, 4)
115 nt.assert_equal(offset, 4)
116
116
117 # The end of a cell should be on the last line
117 # The end of a cell should be on the last line
118 cell = "pri\npri"
118 cell = "pri\npri"
119 (line, offset) = line_at_cursor(cell, cursor_pos=7)
119 (line, offset) = line_at_cursor(cell, cursor_pos=7)
120 nt.assert_equal(line, "pri")
120 nt.assert_equal(line, "pri")
121 nt.assert_equal(offset, 4)
121 nt.assert_equal(offset, 4)
122
122
123 def test_muliline_statement():
123 def test_multiline_statement():
124 cell = """a = (1,
124 cell = """a = (1,
125 3)
125 3)
126
126
127 int()
127 int()
128 map()
128 map()
129 """
129 """
130 for c in range(16, 22):
130 for c in range(16, 22):
131 yield lambda cell, c: expect_token("int", cell, c), cell, c
131 yield lambda cell, c: expect_token("int", cell, c), cell, c
132 for c in range(22, 28):
132 for c in range(22, 28):
133 yield lambda cell, c: expect_token("map", cell, c), cell, c
133 yield lambda cell, c: expect_token("map", cell, c), cell, c
@@ -1,360 +1,360 b''
1 =============
1 =============
2 0.10 series
2 0.10 series
3 =============
3 =============
4
4
5 Release 0.10.2
5 Release 0.10.2
6 ==============
6 ==============
7
7
8 IPython 0.10.2 was released April 9, 2011. This is a minor bugfix release that
8 IPython 0.10.2 was released April 9, 2011. This is a minor bugfix release that
9 preserves backward compatibility. At this point, all IPython development
9 preserves backward compatibility. At this point, all IPython development
10 resources are focused on the 0.11 series that includes a complete architectural
10 resources are focused on the 0.11 series that includes a complete architectural
11 restructuring of the project as well as many new capabilities, so this is
11 restructuring of the project as well as many new capabilities, so this is
12 likely to be the last release of the 0.10.x series. We have tried to fix all
12 likely to be the last release of the 0.10.x series. We have tried to fix all
13 major bugs in this series so that it remains a viable platform for those not
13 major bugs in this series so that it remains a viable platform for those not
14 ready yet to transition to the 0.11 and newer codebase (since that will require
14 ready yet to transition to the 0.11 and newer codebase (since that will require
15 some porting effort, as a number of APIs have changed).
15 some porting effort, as a number of APIs have changed).
16
16
17 Thus, we are not opening a 0.10.3 active development branch yet, but if the
17 Thus, we are not opening a 0.10.3 active development branch yet, but if the
18 user community requires new patches and is willing to maintain/release such a
18 user community requires new patches and is willing to maintain/release such a
19 branch, we'll be happy to host it on the IPython github repositories.
19 branch, we'll be happy to host it on the IPython github repositories.
20
20
21 Highlights of this release:
21 Highlights of this release:
22
22
23 - The main one is the closing of github ticket #185, a major regression we had
23 - The main one is the closing of github ticket #185, a major regression we had
24 in 0.10.1 where pylab mode with GTK (or gthread) was not working correctly,
24 in 0.10.1 where pylab mode with GTK (or gthread) was not working correctly,
25 hence plots were blocking with GTK. Since this is the default matplotlib
25 hence plots were blocking with GTK. Since this is the default matplotlib
26 backend on Unix systems, this was a major annoyance for many users. Many
26 backend on Unix systems, this was a major annoyance for many users. Many
27 thanks to Paul Ivanov for helping resolve this issue.
27 thanks to Paul Ivanov for helping resolve this issue.
28
28
29 - Fix IOError bug on Windows when used with -gthread.
29 - Fix IOError bug on Windows when used with -gthread.
30 - Work robustly if $HOME is missing from environment.
30 - Work robustly if $HOME is missing from environment.
31 - Better POSIX support in ssh scripts (remove bash-specific idioms).
31 - Better POSIX support in ssh scripts (remove bash-specific idioms).
32 - Improved support for non-ascii characters in log files.
32 - Improved support for non-ascii characters in log files.
33 - Work correctly in environments where GTK can be imported but not started
33 - Work correctly in environments where GTK can be imported but not started
34 (such as a linux text console without X11).
34 (such as a linux text console without X11).
35
35
36 For this release we merged 24 commits, contributed by the following people
36 For this release we merged 24 commits, contributed by the following people
37 (please let us know if we omitted your name and we'll gladly fix this in the
37 (please let us know if we omitted your name and we'll gladly fix this in the
38 notes for the future):
38 notes for the future):
39
39
40 * Fernando Perez
40 * Fernando Perez
41 * MinRK
41 * MinRK
42 * Paul Ivanov
42 * Paul Ivanov
43 * Pieter Cristiaan de Groot
43 * Pieter Cristiaan de Groot
44 * TvrtkoM
44 * TvrtkoM
45
45
46 Release 0.10.1
46 Release 0.10.1
47 ==============
47 ==============
48
48
49 IPython 0.10.1 was released October 11, 2010, over a year after version 0.10.
49 IPython 0.10.1 was released October 11, 2010, over a year after version 0.10.
50 This is mostly a bugfix release, since after version 0.10 was released, the
50 This is mostly a bugfix release, since after version 0.10 was released, the
51 development team's energy has been focused on the 0.11 series. We have
51 development team's energy has been focused on the 0.11 series. We have
52 nonetheless tried to backport what fixes we could into 0.10.1, as it remains
52 nonetheless tried to backport what fixes we could into 0.10.1, as it remains
53 the stable series that many users have in production systems they rely on.
53 the stable series that many users have in production systems they rely on.
54
54
55 Since the 0.11 series changes many APIs in backwards-incompatible ways, we are
55 Since the 0.11 series changes many APIs in backwards-incompatible ways, we are
56 willing to continue maintaining the 0.10.x series. We don't really have time
56 willing to continue maintaining the 0.10.x series. We don't really have time
57 to actively write new code for 0.10.x, but we are happy to accept patches and
57 to actively write new code for 0.10.x, but we are happy to accept patches and
58 pull requests on the IPython `github site`_. If sufficient contributions are
58 pull requests on the IPython `github site`_. If sufficient contributions are
59 made that improve 0.10.1, we will roll them into future releases. For this
59 made that improve 0.10.1, we will roll them into future releases. For this
60 purpose, we will have a branch called 0.10.2 on github, on which you can base
60 purpose, we will have a branch called 0.10.2 on github, on which you can base
61 your contributions.
61 your contributions.
62
62
63 .. _github site: http://github.com/ipython
63 .. _github site: http://github.com/ipython
64
64
65 For this release, we applied approximately 60 commits totaling a diff of over
65 For this release, we applied approximately 60 commits totaling a diff of over
66 7000 lines::
66 7000 lines::
67
67
68 (0.10.1)amirbar[dist]> git diff --oneline rel-0.10.. | wc -l
68 (0.10.1)amirbar[dist]> git diff --oneline rel-0.10.. | wc -l
69 7296
69 7296
70
70
71 Highlights of this release:
71 Highlights of this release:
72
72
73 - The only significant new feature is that IPython's parallel computing
73 - The only significant new feature is that IPython's parallel computing
74 machinery now supports natively the Sun Grid Engine and LSF schedulers. This
74 machinery now supports natively the Sun Grid Engine and LSF schedulers. This
75 work was a joint contribution from Justin Riley, Satra Ghosh and Matthieu
75 work was a joint contribution from Justin Riley, Satra Ghosh and Matthieu
76 Brucher, who put a lot of work into it. We also improved traceback handling
76 Brucher, who put a lot of work into it. We also improved traceback handling
77 in remote tasks, as well as providing better control for remote task IDs.
77 in remote tasks, as well as providing better control for remote task IDs.
78
78
79 - New IPython Sphinx directive contributed by John Hunter. You can use this
79 - New IPython Sphinx directive contributed by John Hunter. You can use this
80 directive to mark blocks in reSructuredText documents as containing IPython
80 directive to mark blocks in reStructuredText documents as containing IPython
81 syntax (including figures) and the will be executed during the build:
81 syntax (including figures) and the will be executed during the build:
82
82
83 .. sourcecode:: ipython
83 .. sourcecode:: ipython
84
84
85 In [2]: plt.figure() # ensure a fresh figure
85 In [2]: plt.figure() # ensure a fresh figure
86
86
87 @savefig psimple.png width=4in
87 @savefig psimple.png width=4in
88 In [3]: plt.plot([1,2,3])
88 In [3]: plt.plot([1,2,3])
89 Out[3]: [<matplotlib.lines.Line2D object at 0x9b74d8c>]
89 Out[3]: [<matplotlib.lines.Line2D object at 0x9b74d8c>]
90
90
91 - Various fixes to the standalone ipython-wx application.
91 - Various fixes to the standalone ipython-wx application.
92
92
93 - We now ship internally the excellent argparse library, graciously licensed
93 - We now ship internally the excellent argparse library, graciously licensed
94 under BSD terms by Steven Bethard. Now (2010) that argparse has become part
94 under BSD terms by Steven Bethard. Now (2010) that argparse has become part
95 of Python 2.7 this will be less of an issue, but Steven's relicensing allowed
95 of Python 2.7 this will be less of an issue, but Steven's relicensing allowed
96 us to start updating IPython to using argparse well before Python 2.7. Many
96 us to start updating IPython to using argparse well before Python 2.7. Many
97 thanks!
97 thanks!
98
98
99 - Robustness improvements so that IPython doesn't crash if the readline library
99 - Robustness improvements so that IPython doesn't crash if the readline library
100 is absent (though obviously a lot of functionality that requires readline
100 is absent (though obviously a lot of functionality that requires readline
101 will not be available).
101 will not be available).
102
102
103 - Improvements to tab completion in Emacs with Python 2.6.
103 - Improvements to tab completion in Emacs with Python 2.6.
104
104
105 - Logging now supports timestamps (see ``%logstart?`` for full details).
105 - Logging now supports timestamps (see ``%logstart?`` for full details).
106
106
107 - A long-standing and quite annoying bug where parentheses would be added to
107 - A long-standing and quite annoying bug where parentheses would be added to
108 ``print`` statements, under Python 2.5 and 2.6, was finally fixed.
108 ``print`` statements, under Python 2.5 and 2.6, was finally fixed.
109
109
110 - Improved handling of libreadline on Apple OSX.
110 - Improved handling of libreadline on Apple OSX.
111
111
112 - Fix ``reload`` method of IPython demos, which was broken.
112 - Fix ``reload`` method of IPython demos, which was broken.
113
113
114 - Fixes for the ipipe/ibrowse system on OSX.
114 - Fixes for the ipipe/ibrowse system on OSX.
115
115
116 - Fixes for Zope profile.
116 - Fixes for Zope profile.
117
117
118 - Fix %timeit reporting when the time is longer than 1000s.
118 - Fix %timeit reporting when the time is longer than 1000s.
119
119
120 - Avoid lockups with ? or ?? in SunOS, due to a bug in termios.
120 - Avoid lockups with ? or ?? in SunOS, due to a bug in termios.
121
121
122 - The usual assortment of miscellaneous bug fixes and small improvements.
122 - The usual assortment of miscellaneous bug fixes and small improvements.
123
123
124 The following people contributed to this release (please let us know if we
124 The following people contributed to this release (please let us know if we
125 omitted your name and we'll gladly fix this in the notes for the future):
125 omitted your name and we'll gladly fix this in the notes for the future):
126
126
127 * Beni Cherniavsky
127 * Beni Cherniavsky
128 * Boyd Waters.
128 * Boyd Waters.
129 * David Warde-Farley
129 * David Warde-Farley
130 * Fernando Perez
130 * Fernando Perez
131 * Gökhan Sever
131 * Gökhan Sever
132 * John Hunter
132 * John Hunter
133 * Justin Riley
133 * Justin Riley
134 * Kiorky
134 * Kiorky
135 * Laurent Dufrechou
135 * Laurent Dufrechou
136 * Mark E. Smith
136 * Mark E. Smith
137 * Matthieu Brucher
137 * Matthieu Brucher
138 * Satrajit Ghosh
138 * Satrajit Ghosh
139 * Sebastian Busch
139 * Sebastian Busch
140 * Václav Šmilauer
140 * Václav Šmilauer
141
141
142 Release 0.10
142 Release 0.10
143 ============
143 ============
144
144
145 This release brings months of slow but steady development, and will be the last
145 This release brings months of slow but steady development, and will be the last
146 before a major restructuring and cleanup of IPython's internals that is already
146 before a major restructuring and cleanup of IPython's internals that is already
147 under way. For this reason, we hope that 0.10 will be a stable and robust
147 under way. For this reason, we hope that 0.10 will be a stable and robust
148 release so that while users adapt to some of the API changes that will come
148 release so that while users adapt to some of the API changes that will come
149 with the refactoring that will become IPython 0.11, they can safely use 0.10 in
149 with the refactoring that will become IPython 0.11, they can safely use 0.10 in
150 all existing projects with minimal changes (if any).
150 all existing projects with minimal changes (if any).
151
151
152 IPython 0.10 is now a medium-sized project, with roughly (as reported by David
152 IPython 0.10 is now a medium-sized project, with roughly (as reported by David
153 Wheeler's :command:`sloccount` utility) 40750 lines of Python code, and a diff
153 Wheeler's :command:`sloccount` utility) 40750 lines of Python code, and a diff
154 between 0.9.1 and this release that contains almost 28000 lines of code and
154 between 0.9.1 and this release that contains almost 28000 lines of code and
155 documentation. Our documentation, in PDF format, is a 495-page long PDF
155 documentation. Our documentation, in PDF format, is a 495-page long PDF
156 document (also available in HTML format, both generated from the same sources).
156 document (also available in HTML format, both generated from the same sources).
157
157
158 Many users and developers contributed code, features, bug reports and ideas to
158 Many users and developers contributed code, features, bug reports and ideas to
159 this release. Please do not hesitate in contacting us if we've failed to
159 this release. Please do not hesitate in contacting us if we've failed to
160 acknowledge your contribution here. In particular, for this release we have
160 acknowledge your contribution here. In particular, for this release we have
161 contribution from the following people, a mix of new and regular names (in
161 contribution from the following people, a mix of new and regular names (in
162 alphabetical order by first name):
162 alphabetical order by first name):
163
163
164 * Alexander Clausen: fix #341726.
164 * Alexander Clausen: fix #341726.
165 * Brian Granger: lots of work everywhere (features, bug fixes, etc).
165 * Brian Granger: lots of work everywhere (features, bug fixes, etc).
166 * Daniel Ashbrook: bug report on MemoryError during compilation, now fixed.
166 * Daniel Ashbrook: bug report on MemoryError during compilation, now fixed.
167 * Darren Dale: improvements to documentation build system, feedback, design
167 * Darren Dale: improvements to documentation build system, feedback, design
168 ideas.
168 ideas.
169 * Fernando Perez: various places.
169 * Fernando Perez: various places.
170 * Gaël Varoquaux: core code, ipythonx GUI, design discussions, etc. Lots...
170 * Gaël Varoquaux: core code, ipythonx GUI, design discussions, etc. Lots...
171 * John Hunter: suggestions, bug fixes, feedback.
171 * John Hunter: suggestions, bug fixes, feedback.
172 * Jorgen Stenarson: work on many fronts, tests, fixes, win32 support, etc.
172 * Jorgen Stenarson: work on many fronts, tests, fixes, win32 support, etc.
173 * Laurent Dufréchou: many improvements to ipython-wx standalone app.
173 * Laurent Dufréchou: many improvements to ipython-wx standalone app.
174 * Lukasz Pankowski: prefilter, `%edit`, demo improvements.
174 * Lukasz Pankowski: prefilter, `%edit`, demo improvements.
175 * Matt Foster: TextMate support in `%edit`.
175 * Matt Foster: TextMate support in `%edit`.
176 * Nathaniel Smith: fix #237073.
176 * Nathaniel Smith: fix #237073.
177 * Pauli Virtanen: fixes and improvements to extensions, documentation.
177 * Pauli Virtanen: fixes and improvements to extensions, documentation.
178 * Prabhu Ramachandran: improvements to `%timeit`.
178 * Prabhu Ramachandran: improvements to `%timeit`.
179 * Robert Kern: several extensions.
179 * Robert Kern: several extensions.
180 * Sameer D'Costa: help on critical bug #269966.
180 * Sameer D'Costa: help on critical bug #269966.
181 * Stephan Peijnik: feedback on Debian compliance and many man pages.
181 * Stephan Peijnik: feedback on Debian compliance and many man pages.
182 * Steven Bethard: we are now shipping his :mod:`argparse` module.
182 * Steven Bethard: we are now shipping his :mod:`argparse` module.
183 * Tom Fetherston: many improvements to :mod:`IPython.demo` module.
183 * Tom Fetherston: many improvements to :mod:`IPython.demo` module.
184 * Ville Vainio: lots of work everywhere (features, bug fixes, etc).
184 * Ville Vainio: lots of work everywhere (features, bug fixes, etc).
185 * Vishal Vasta: ssh support in ipcluster.
185 * Vishal Vasta: ssh support in ipcluster.
186 * Walter Doerwald: work on the :mod:`IPython.ipipe` system.
186 * Walter Doerwald: work on the :mod:`IPython.ipipe` system.
187
187
188 Below we give an overview of new features, bug fixes and backwards-incompatible
188 Below we give an overview of new features, bug fixes and backwards-incompatible
189 changes. For a detailed account of every change made, feel free to view the
189 changes. For a detailed account of every change made, feel free to view the
190 project log with :command:`bzr log`.
190 project log with :command:`bzr log`.
191
191
192 New features
192 New features
193 ------------
193 ------------
194
194
195 * New `%paste` magic automatically extracts current contents of clipboard and
195 * New `%paste` magic automatically extracts current contents of clipboard and
196 pastes it directly, while correctly handling code that is indented or
196 pastes it directly, while correctly handling code that is indented or
197 prepended with `>>>` or `...` python prompt markers. A very useful new
197 prepended with `>>>` or `...` python prompt markers. A very useful new
198 feature contributed by Robert Kern.
198 feature contributed by Robert Kern.
199
199
200 * IPython 'demos', created with the :mod:`IPython.demo` module, can now be
200 * IPython 'demos', created with the :mod:`IPython.demo` module, can now be
201 created from files on disk or strings in memory. Other fixes and
201 created from files on disk or strings in memory. Other fixes and
202 improvements to the demo system, by Tom Fetherston.
202 improvements to the demo system, by Tom Fetherston.
203
203
204 * Added :func:`find_cmd` function to :mod:`IPython.platutils` module, to find
204 * Added :func:`find_cmd` function to :mod:`IPython.platutils` module, to find
205 commands in a cross-platform manner.
205 commands in a cross-platform manner.
206
206
207 * Many improvements and fixes to Gaël Varoquaux's :command:`ipythonx`, a
207 * Many improvements and fixes to Gaël Varoquaux's :command:`ipythonx`, a
208 WX-based lightweight IPython instance that can be easily embedded in other WX
208 WX-based lightweight IPython instance that can be easily embedded in other WX
209 applications. These improvements have made it possible to now have an
209 applications. These improvements have made it possible to now have an
210 embedded IPython in Mayavi and other tools.
210 embedded IPython in Mayavi and other tools.
211
211
212 * :class:`MultiengineClient` objects now have a :meth:`benchmark` method.
212 * :class:`MultiengineClient` objects now have a :meth:`benchmark` method.
213
213
214 * The manual now includes a full set of auto-generated API documents from the
214 * The manual now includes a full set of auto-generated API documents from the
215 code sources, using Sphinx and some of our own support code. We are now
215 code sources, using Sphinx and some of our own support code. We are now
216 using the `Numpy Documentation Standard`_ for all docstrings, and we have
216 using the `Numpy Documentation Standard`_ for all docstrings, and we have
217 tried to update as many existing ones as possible to this format.
217 tried to update as many existing ones as possible to this format.
218
218
219 * The new :mod:`IPython.Extensions.ipy_pretty` extension by Robert Kern
219 * The new :mod:`IPython.Extensions.ipy_pretty` extension by Robert Kern
220 provides configurable pretty-printing.
220 provides configurable pretty-printing.
221
221
222 * Many improvements to the :command:`ipython-wx` standalone WX-based IPython
222 * Many improvements to the :command:`ipython-wx` standalone WX-based IPython
223 application by Laurent Dufréchou. It can optionally run in a thread, and
223 application by Laurent Dufréchou. It can optionally run in a thread, and
224 this can be toggled at runtime (allowing the loading of Matplotlib in a
224 this can be toggled at runtime (allowing the loading of Matplotlib in a
225 running session without ill effects).
225 running session without ill effects).
226
226
227 * IPython includes a copy of Steven Bethard's argparse_ in the
227 * IPython includes a copy of Steven Bethard's argparse_ in the
228 :mod:`IPython.external` package, so we can use it internally and it is also
228 :mod:`IPython.external` package, so we can use it internally and it is also
229 available to any IPython user. By installing it in this manner, we ensure
229 available to any IPython user. By installing it in this manner, we ensure
230 zero conflicts with any system-wide installation you may already have while
230 zero conflicts with any system-wide installation you may already have while
231 minimizing external dependencies for new users. In IPython 0.10, We ship
231 minimizing external dependencies for new users. In IPython 0.10, We ship
232 argparse version 1.0.
232 argparse version 1.0.
233
233
234 * An improved and much more robust test suite, that runs groups of tests in
234 * An improved and much more robust test suite, that runs groups of tests in
235 separate subprocesses using either Nose or Twisted's :command:`trial` runner
235 separate subprocesses using either Nose or Twisted's :command:`trial` runner
236 to ensure proper management of Twisted-using code. The test suite degrades
236 to ensure proper management of Twisted-using code. The test suite degrades
237 gracefully if optional dependencies are not available, so that the
237 gracefully if optional dependencies are not available, so that the
238 :command:`iptest` command can be run with only Nose installed and nothing
238 :command:`iptest` command can be run with only Nose installed and nothing
239 else. We also have more and cleaner test decorators to better select tests
239 else. We also have more and cleaner test decorators to better select tests
240 depending on runtime conditions, do setup/teardown, etc.
240 depending on runtime conditions, do setup/teardown, etc.
241
241
242 * The new ipcluster now has a fully working ssh mode that should work on
242 * The new ipcluster now has a fully working ssh mode that should work on
243 Linux, Unix and OS X. Thanks to Vishal Vatsa for implementing this!
243 Linux, Unix and OS X. Thanks to Vishal Vatsa for implementing this!
244
244
245 * The wonderful TextMate editor can now be used with %edit on OS X. Thanks
245 * The wonderful TextMate editor can now be used with %edit on OS X. Thanks
246 to Matt Foster for this patch.
246 to Matt Foster for this patch.
247
247
248 * The documentation regarding parallel uses of IPython, including MPI and PBS,
248 * The documentation regarding parallel uses of IPython, including MPI and PBS,
249 has been significantly updated and improved.
249 has been significantly updated and improved.
250
250
251 * The developer guidelines in the documentation have been updated to explain
251 * The developer guidelines in the documentation have been updated to explain
252 our workflow using :command:`bzr` and Launchpad.
252 our workflow using :command:`bzr` and Launchpad.
253
253
254 * Fully refactored :command:`ipcluster` command line program for starting
254 * Fully refactored :command:`ipcluster` command line program for starting
255 IPython clusters. This new version is a complete rewrite and 1) is fully
255 IPython clusters. This new version is a complete rewrite and 1) is fully
256 cross platform (we now use Twisted's process management), 2) has much
256 cross platform (we now use Twisted's process management), 2) has much
257 improved performance, 3) uses subcommands for different types of clusters, 4)
257 improved performance, 3) uses subcommands for different types of clusters, 4)
258 uses argparse for parsing command line options, 5) has better support for
258 uses argparse for parsing command line options, 5) has better support for
259 starting clusters using :command:`mpirun`, 6) has experimental support for
259 starting clusters using :command:`mpirun`, 6) has experimental support for
260 starting engines using PBS. It can also reuse FURL files, by appropriately
260 starting engines using PBS. It can also reuse FURL files, by appropriately
261 passing options to its subcommands. However, this new version of ipcluster
261 passing options to its subcommands. However, this new version of ipcluster
262 should be considered a technology preview. We plan on changing the API in
262 should be considered a technology preview. We plan on changing the API in
263 significant ways before it is final.
263 significant ways before it is final.
264
264
265 * Full description of the security model added to the docs.
265 * Full description of the security model added to the docs.
266
266
267 * cd completer: show bookmarks if no other completions are available.
267 * cd completer: show bookmarks if no other completions are available.
268
268
269 * sh profile: easy way to give 'title' to prompt: assign to variable
269 * sh profile: easy way to give 'title' to prompt: assign to variable
270 '_prompt_title'. It looks like this::
270 '_prompt_title'. It looks like this::
271
271
272 [~]|1> _prompt_title = 'sudo!'
272 [~]|1> _prompt_title = 'sudo!'
273 sudo![~]|2>
273 sudo![~]|2>
274
274
275 * %edit: If you do '%edit pasted_block', pasted_block variable gets updated
275 * %edit: If you do '%edit pasted_block', pasted_block variable gets updated
276 with new data (so repeated editing makes sense)
276 with new data (so repeated editing makes sense)
277
277
278 .. _Numpy Documentation Standard: https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt#docstring-standard
278 .. _Numpy Documentation Standard: https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt#docstring-standard
279
279
280 .. _argparse: http://code.google.com/p/argparse/
280 .. _argparse: http://code.google.com/p/argparse/
281
281
282 Bug fixes
282 Bug fixes
283 ---------
283 ---------
284
284
285 * Fix #368719, removed top-level debian/ directory to make the job of Debian
285 * Fix #368719, removed top-level debian/ directory to make the job of Debian
286 packagers easier.
286 packagers easier.
287
287
288 * Fix #291143 by including man pages contributed by Stephan Peijnik from the
288 * Fix #291143 by including man pages contributed by Stephan Peijnik from the
289 Debian project.
289 Debian project.
290
290
291 * Fix #358202, effectively a race condition, by properly synchronizing file
291 * Fix #358202, effectively a race condition, by properly synchronizing file
292 creation at cluster startup time.
292 creation at cluster startup time.
293
293
294 * `%timeit` now handles correctly functions that take a long time to execute
294 * `%timeit` now handles correctly functions that take a long time to execute
295 even the first time, by not repeating them.
295 even the first time, by not repeating them.
296
296
297 * Fix #239054, releasing of references after exiting.
297 * Fix #239054, releasing of references after exiting.
298
298
299 * Fix #341726, thanks to Alexander Clausen.
299 * Fix #341726, thanks to Alexander Clausen.
300
300
301 * Fix #269966. This long-standing and very difficult bug (which is actually a
301 * Fix #269966. This long-standing and very difficult bug (which is actually a
302 problem in Python itself) meant long-running sessions would inevitably grow
302 problem in Python itself) meant long-running sessions would inevitably grow
303 in memory size, often with catastrophic consequences if users had large
303 in memory size, often with catastrophic consequences if users had large
304 objects in their scripts. Now, using `%run` repeatedly should not cause any
304 objects in their scripts. Now, using `%run` repeatedly should not cause any
305 memory leaks. Special thanks to John Hunter and Sameer D'Costa for their
305 memory leaks. Special thanks to John Hunter and Sameer D'Costa for their
306 help with this bug.
306 help with this bug.
307
307
308 * Fix #295371, bug in `%history`.
308 * Fix #295371, bug in `%history`.
309
309
310 * Improved support for py2exe.
310 * Improved support for py2exe.
311
311
312 * Fix #270856: IPython hangs with PyGTK
312 * Fix #270856: IPython hangs with PyGTK
313
313
314 * Fix #270998: A magic with no docstring breaks the '%magic magic'
314 * Fix #270998: A magic with no docstring breaks the '%magic magic'
315
315
316 * fix #271684: -c startup commands screw up raw vs. native history
316 * fix #271684: -c startup commands screw up raw vs. native history
317
317
318 * Numerous bugs on Windows with the new ipcluster have been fixed.
318 * Numerous bugs on Windows with the new ipcluster have been fixed.
319
319
320 * The ipengine and ipcontroller scripts now handle missing furl files
320 * The ipengine and ipcontroller scripts now handle missing furl files
321 more gracefully by giving better error messages.
321 more gracefully by giving better error messages.
322
322
323 * %rehashx: Aliases no longer contain dots. python3.0 binary
323 * %rehashx: Aliases no longer contain dots. python3.0 binary
324 will create alias python30. Fixes:
324 will create alias python30. Fixes:
325 #259716 "commands with dots in them don't work"
325 #259716 "commands with dots in them don't work"
326
326
327 * %cpaste: %cpaste -r repeats the last pasted block.
327 * %cpaste: %cpaste -r repeats the last pasted block.
328 The block is assigned to pasted_block even if code
328 The block is assigned to pasted_block even if code
329 raises exception.
329 raises exception.
330
330
331 * Bug #274067 'The code in get_home_dir is broken for py2exe' was
331 * Bug #274067 'The code in get_home_dir is broken for py2exe' was
332 fixed.
332 fixed.
333
333
334 * Many other small bug fixes not listed here by number (see the bzr log for
334 * Many other small bug fixes not listed here by number (see the bzr log for
335 more info).
335 more info).
336
336
337 Backwards incompatible changes
337 Backwards incompatible changes
338 ------------------------------
338 ------------------------------
339
339
340 * `ipykit` and related files were unmaintained and have been removed.
340 * `ipykit` and related files were unmaintained and have been removed.
341
341
342 * The :func:`IPython.genutils.doctest_reload` does not actually call
342 * The :func:`IPython.genutils.doctest_reload` does not actually call
343 `reload(doctest)` anymore, as this was causing many problems with the test
343 `reload(doctest)` anymore, as this was causing many problems with the test
344 suite. It still resets `doctest.master` to None.
344 suite. It still resets `doctest.master` to None.
345
345
346 * While we have not deliberately broken Python 2.4 compatibility, only minor
346 * While we have not deliberately broken Python 2.4 compatibility, only minor
347 testing was done with Python 2.4, while 2.5 and 2.6 were fully tested. But
347 testing was done with Python 2.4, while 2.5 and 2.6 were fully tested. But
348 if you encounter problems with 2.4, please do report them as bugs.
348 if you encounter problems with 2.4, please do report them as bugs.
349
349
350 * The :command:`ipcluster` now requires a mode argument; for example to start a
350 * The :command:`ipcluster` now requires a mode argument; for example to start a
351 cluster on the local machine with 4 engines, you must now type::
351 cluster on the local machine with 4 engines, you must now type::
352
352
353 $ ipcluster local -n 4
353 $ ipcluster local -n 4
354
354
355 * The controller now has a ``-r`` flag that needs to be used if you want to
355 * The controller now has a ``-r`` flag that needs to be used if you want to
356 reuse existing furl files. Otherwise they are deleted (the default).
356 reuse existing furl files. Otherwise they are deleted (the default).
357
357
358 * Remove ipy_leo.py. You can use :command:`easy_install ipython-extension` to
358 * Remove ipy_leo.py. You can use :command:`easy_install ipython-extension` to
359 get it. (done to decouple it from ipython release cycle)
359 get it. (done to decouple it from ipython release cycle)
360
360
@@ -1,765 +1,765 b''
1 =============
1 =============
2 0.11 Series
2 0.11 Series
3 =============
3 =============
4
4
5 Release 0.11
5 Release 0.11
6 ============
6 ============
7
7
8 IPython 0.11 is a *major* overhaul of IPython, two years in the making. Most
8 IPython 0.11 is a *major* overhaul of IPython, two years in the making. Most
9 of the code base has been rewritten or at least reorganized, breaking backward
9 of the code base has been rewritten or at least reorganized, breaking backward
10 compatibility with several APIs in previous versions. It is the first major
10 compatibility with several APIs in previous versions. It is the first major
11 release in two years, and probably the most significant change to IPython since
11 release in two years, and probably the most significant change to IPython since
12 its inception. We plan to have a relatively quick succession of releases, as
12 its inception. We plan to have a relatively quick succession of releases, as
13 people discover new bugs and regressions. Once we iron out any significant
13 people discover new bugs and regressions. Once we iron out any significant
14 bugs in this process and settle down the new APIs, this series will become
14 bugs in this process and settle down the new APIs, this series will become
15 IPython 1.0. We encourage feedback now on the core APIs, which we hope to
15 IPython 1.0. We encourage feedback now on the core APIs, which we hope to
16 maintain stable during the 1.0 series.
16 maintain stable during the 1.0 series.
17
17
18 Since the internal APIs have changed so much, projects using IPython as a
18 Since the internal APIs have changed so much, projects using IPython as a
19 library (as opposed to end-users of the application) are the most likely to
19 library (as opposed to end-users of the application) are the most likely to
20 encounter regressions or changes that break their existing use patterns. We
20 encounter regressions or changes that break their existing use patterns. We
21 will make every effort to provide updated versions of the APIs to facilitate
21 will make every effort to provide updated versions of the APIs to facilitate
22 the transition, and we encourage you to contact us on the `development mailing
22 the transition, and we encourage you to contact us on the `development mailing
23 list`__ with questions and feedback.
23 list`__ with questions and feedback.
24
24
25 .. __: http://mail.scipy.org/mailman/listinfo/ipython-dev
25 .. __: http://mail.scipy.org/mailman/listinfo/ipython-dev
26
26
27 Chris Fonnesbeck recently wrote an `excellent post`__ that highlights some of
27 Chris Fonnesbeck recently wrote an `excellent post`__ that highlights some of
28 our major new features, with examples and screenshots. We encourage you to
28 our major new features, with examples and screenshots. We encourage you to
29 read it as it provides an illustrated, high-level overview complementing the
29 read it as it provides an illustrated, high-level overview complementing the
30 detailed feature breakdown in this document.
30 detailed feature breakdown in this document.
31
31
32 .. __: http://stronginference.com/post/innovations-in-ipython
32 .. __: http://stronginference.com/post/innovations-in-ipython
33
33
34 A quick summary of the major changes (see below for details):
34 A quick summary of the major changes (see below for details):
35
35
36 * **Standalone Qt console**: a new rich console has been added to IPython,
36 * **Standalone Qt console**: a new rich console has been added to IPython,
37 started with `ipython qtconsole`. In this application we have tried to
37 started with `ipython qtconsole`. In this application we have tried to
38 retain the feel of a terminal for fast and efficient workflows, while adding
38 retain the feel of a terminal for fast and efficient workflows, while adding
39 many features that a line-oriented terminal simply can not support, such as
39 many features that a line-oriented terminal simply can not support, such as
40 inline figures, full multiline editing with syntax highlighting, graphical
40 inline figures, full multiline editing with syntax highlighting, graphical
41 tooltips for function calls and much more. This development was sponsored by
41 tooltips for function calls and much more. This development was sponsored by
42 `Enthought Inc.`__. See :ref:`below <qtconsole_011>` for details.
42 `Enthought Inc.`__. See :ref:`below <qtconsole_011>` for details.
43
43
44 .. __: http://enthought.com
44 .. __: http://enthought.com
45
45
46 * **High-level parallel computing with ZeroMQ**. Using the same architecture
46 * **High-level parallel computing with ZeroMQ**. Using the same architecture
47 that our Qt console is based on, we have completely rewritten our high-level
47 that our Qt console is based on, we have completely rewritten our high-level
48 parallel computing machinery that in prior versions used the Twisted
48 parallel computing machinery that in prior versions used the Twisted
49 networking framework. While this change will require users to update their
49 networking framework. While this change will require users to update their
50 codes, the improvements in performance, memory control and internal
50 codes, the improvements in performance, memory control and internal
51 consistency across our codebase convinced us it was a price worth paying. We
51 consistency across our codebase convinced us it was a price worth paying. We
52 have tried to explain how to best proceed with this update, and will be happy
52 have tried to explain how to best proceed with this update, and will be happy
53 to answer questions that may arise. A full tutorial describing these
53 to answer questions that may arise. A full tutorial describing these
54 features `was presented at SciPy'11`__, more details :ref:`below
54 features `was presented at SciPy'11`__, more details :ref:`below
55 <parallel_011>`.
55 <parallel_011>`.
56
56
57 .. __: http://minrk.github.com/scipy-tutorial-2011
57 .. __: http://minrk.github.com/scipy-tutorial-2011
58
58
59 * **New model for GUI/plotting support in the terminal**. Now instead of the
59 * **New model for GUI/plotting support in the terminal**. Now instead of the
60 various `-Xthread` flags we had before, GUI support is provided without the
60 various `-Xthread` flags we had before, GUI support is provided without the
61 use of any threads, by directly integrating GUI event loops with Python's
61 use of any threads, by directly integrating GUI event loops with Python's
62 `PyOS_InputHook` API. A new command-line flag `--gui` controls GUI support,
62 `PyOS_InputHook` API. A new command-line flag `--gui` controls GUI support,
63 and it can also be enabled after IPython startup via the new `%gui` magic.
63 and it can also be enabled after IPython startup via the new `%gui` magic.
64 This requires some changes if you want to execute GUI-using scripts inside
64 This requires some changes if you want to execute GUI-using scripts inside
65 IPython, see :ref:`the GUI support section <gui_support>` for more details.
65 IPython, see :ref:`the GUI support section <gui_support>` for more details.
66
66
67 * **A two-process architecture.** The Qt console is the first use of a new
67 * **A two-process architecture.** The Qt console is the first use of a new
68 model that splits IPython between a kernel process where code is executed and
68 model that splits IPython between a kernel process where code is executed and
69 a client that handles user interaction. We plan on also providing terminal
69 a client that handles user interaction. We plan on also providing terminal
70 and web-browser based clients using this infrastructure in future releases.
70 and web-browser based clients using this infrastructure in future releases.
71 This model allows multiple clients to interact with an IPython process
71 This model allows multiple clients to interact with an IPython process
72 through a :ref:`well-documented messaging protocol <messaging>` using the
72 through a :ref:`well-documented messaging protocol <messaging>` using the
73 ZeroMQ networking library.
73 ZeroMQ networking library.
74
74
75 * **Refactoring.** the entire codebase has been refactored, in order to make it
75 * **Refactoring.** the entire codebase has been refactored, in order to make it
76 more modular and easier to contribute to. IPython has traditionally been a
76 more modular and easier to contribute to. IPython has traditionally been a
77 hard project to participate because the old codebase was very monolithic. We
77 hard project to participate because the old codebase was very monolithic. We
78 hope this (ongoing) restructuring will make it easier for new developers to
78 hope this (ongoing) restructuring will make it easier for new developers to
79 join us.
79 join us.
80
80
81 * **Vim integration**. Vim can be configured to seamlessly control an IPython
81 * **Vim integration**. Vim can be configured to seamlessly control an IPython
82 kernel, see the files in :file:`docs/examples/vim` for the full details.
82 kernel, see the files in :file:`docs/examples/vim` for the full details.
83 This work was done by Paul Ivanov, who prepared a nice `video
83 This work was done by Paul Ivanov, who prepared a nice `video
84 demonstration`__ of the features it provides.
84 demonstration`__ of the features it provides.
85
85
86 .. __: http://pirsquared.org/blog/2011/07/28/vim-ipython/
86 .. __: http://pirsquared.org/blog/2011/07/28/vim-ipython/
87
87
88 * **Integration into Microsoft Visual Studio**. Thanks to the work of the
88 * **Integration into Microsoft Visual Studio**. Thanks to the work of the
89 Microsoft `Python Tools for Visual Studio`__ team, this version of IPython
89 Microsoft `Python Tools for Visual Studio`__ team, this version of IPython
90 has been integrated into Microsoft Visual Studio's Python tools open source
90 has been integrated into Microsoft Visual Studio's Python tools open source
91 plug-in. `Details below`_
91 plug-in. `Details below`_
92
92
93 .. __: http://pytools.codeplex.com
93 .. __: http://pytools.codeplex.com
94 .. _details below: ms_visual_studio_011_
94 .. _details below: ms_visual_studio_011_
95
95
96 * **Improved unicode support**. We closed many bugs related to unicode input.
96 * **Improved unicode support**. We closed many bugs related to unicode input.
97
97
98 * **Python 3**. IPython now runs on Python 3.x. See :ref:`python3_011` for
98 * **Python 3**. IPython now runs on Python 3.x. See :ref:`python3_011` for
99 details.
99 details.
100
100
101 * **New profile model**. Profiles are now directories that contain all relevant
101 * **New profile model**. Profiles are now directories that contain all relevant
102 information for that session, and thus better isolate IPython use-cases.
102 information for that session, and thus better isolate IPython use-cases.
103
103
104 * **SQLite storage for history**. All history is now stored in a SQLite
104 * **SQLite storage for history**. All history is now stored in a SQLite
105 database, providing support for multiple simultaneous sessions that won't
105 database, providing support for multiple simultaneous sessions that won't
106 clobber each other as well as the ability to perform queries on all stored
106 clobber each other as well as the ability to perform queries on all stored
107 data.
107 data.
108
108
109 * **New configuration system**. All parts of IPython are now configured via a
109 * **New configuration system**. All parts of IPython are now configured via a
110 mechanism inspired by the Enthought Traits library. Any configurable element
110 mechanism inspired by the Enthought Traits library. Any configurable element
111 can have its attributes set either via files that now use real Python syntax
111 can have its attributes set either via files that now use real Python syntax
112 or from the command-line.
112 or from the command-line.
113
113
114 * **Pasting of code with prompts**. IPython now intelligently strips out input
114 * **Pasting of code with prompts**. IPython now intelligently strips out input
115 prompts , be they plain Python ones (``>>>`` and ``...``) or IPython ones
115 prompts , be they plain Python ones (``>>>`` and ``...``) or IPython ones
116 (``In [N]:`` and ``...:``). More details :ref:`here <pasting_with_prompts>`.
116 (``In [N]:`` and ``...:``). More details :ref:`here <pasting_with_prompts>`.
117
117
118
118
119 Authors and support
119 Authors and support
120 -------------------
120 -------------------
121
121
122 Over 60 separate authors have contributed to this release, see :ref:`below
122 Over 60 separate authors have contributed to this release, see :ref:`below
123 <credits_011>` for a full list. In particular, we want to highlight the
123 <credits_011>` for a full list. In particular, we want to highlight the
124 extremely active participation of two new core team members: Evan Patterson
124 extremely active participation of two new core team members: Evan Patterson
125 implemented the Qt console, and Thomas Kluyver started with our Python 3 port
125 implemented the Qt console, and Thomas Kluyver started with our Python 3 port
126 and by now has made major contributions to just about every area of IPython.
126 and by now has made major contributions to just about every area of IPython.
127
127
128 We are also grateful for the support we have received during this development
128 We are also grateful for the support we have received during this development
129 cycle from several institutions:
129 cycle from several institutions:
130
130
131 - `Enthought Inc`__ funded the development of our new Qt console, an effort that
131 - `Enthought Inc`__ funded the development of our new Qt console, an effort that
132 required developing major pieces of underlying infrastructure, which now
132 required developing major pieces of underlying infrastructure, which now
133 power not only the Qt console but also our new parallel machinery. We'd like
133 power not only the Qt console but also our new parallel machinery. We'd like
134 to thank Eric Jones and Travis Oliphant for their support, as well as Ilan
134 to thank Eric Jones and Travis Oliphant for their support, as well as Ilan
135 Schnell for his tireless work integrating and testing IPython in the
135 Schnell for his tireless work integrating and testing IPython in the
136 `Enthought Python Distribution`_.
136 `Enthought Python Distribution`_.
137
137
138 .. __: http://enthought.com
138 .. __: http://enthought.com
139 .. _Enthought Python Distribution: http://www.enthought.com/products/epd.php
139 .. _Enthought Python Distribution: http://www.enthought.com/products/epd.php
140
140
141 - Nipy/NIH: funding via the `NiPy project`__ (NIH grant 5R01MH081909-02) helped
141 - Nipy/NIH: funding via the `NiPy project`__ (NIH grant 5R01MH081909-02) helped
142 us jumpstart the development of this series by restructuring the entire
142 us jumpstart the development of this series by restructuring the entire
143 codebase two years ago in a way that would make modular development and
143 codebase two years ago in a way that would make modular development and
144 testing more approachable. Without this initial groundwork, all the new
144 testing more approachable. Without this initial groundwork, all the new
145 features we have added would have been impossible to develop.
145 features we have added would have been impossible to develop.
146
146
147 .. __: http://nipy.org
147 .. __: http://nipy.org
148
148
149 - Sage/NSF: funding via the grant `Sage: Unifying Mathematical Software for
149 - Sage/NSF: funding via the grant `Sage: Unifying Mathematical Software for
150 Scientists, Engineers, and Mathematicians`__ (NSF grant DMS-1015114)
150 Scientists, Engineers, and Mathematicians`__ (NSF grant DMS-1015114)
151 supported a meeting in spring 2011 of several of the core IPython developers
151 supported a meeting in spring 2011 of several of the core IPython developers
152 where major progress was made integrating the last key pieces leading to this
152 where major progress was made integrating the last key pieces leading to this
153 release.
153 release.
154
154
155 .. __: http://modular.math.washington.edu/grants/compmath09
155 .. __: http://modular.math.washington.edu/grants/compmath09
156
156
157 - Microsoft's team working on `Python Tools for Visual Studio`__ developed the
157 - Microsoft's team working on `Python Tools for Visual Studio`__ developed the
158 integraton of IPython into the Python plugin for Visual Studio 2010.
158 integratron of IPython into the Python plugin for Visual Studio 2010.
159
159
160 .. __: http://pytools.codeplex.com
160 .. __: http://pytools.codeplex.com
161
161
162 - Google Summer of Code: in 2010, we had two students developing prototypes of
162 - Google Summer of Code: in 2010, we had two students developing prototypes of
163 the new machinery that is now maturing in this release: `Omar Zapata`_ and
163 the new machinery that is now maturing in this release: `Omar Zapata`_ and
164 `Gerardo Gutiérrez`_.
164 `Gerardo Gutiérrez`_.
165
165
166 .. _Omar Zapata: http://ipythonzmq.blogspot.com/2010/08/ipython-zmq-status.html
166 .. _Omar Zapata: http://ipythonzmq.blogspot.com/2010/08/ipython-zmq-status.html
167 .. _Gerardo Gutiérrez: http://ipythonqt.blogspot.com/2010/04/ipython-qt-interface-gsoc-2010-proposal.html>
167 .. _Gerardo Gutiérrez: http://ipythonqt.blogspot.com/2010/04/ipython-qt-interface-gsoc-2010-proposal.html>
168
168
169
169
170 Development summary: moving to Git and Github
170 Development summary: moving to Git and Github
171 ---------------------------------------------
171 ---------------------------------------------
172
172
173 In April 2010, after `one breakage too many with bzr`__, we decided to move our
173 In April 2010, after `one breakage too many with bzr`__, we decided to move our
174 entire development process to Git and Github.com. This has proven to be one of
174 entire development process to Git and Github.com. This has proven to be one of
175 the best decisions in the project's history, as the combination of git and
175 the best decisions in the project's history, as the combination of git and
176 github have made us far, far more productive than we could be with our previous
176 github have made us far, far more productive than we could be with our previous
177 tools. We first converted our bzr repo to a git one without losing history,
177 tools. We first converted our bzr repo to a git one without losing history,
178 and a few weeks later ported all open Launchpad bugs to github issues with
178 and a few weeks later ported all open Launchpad bugs to github issues with
179 their comments mostly intact (modulo some formatting changes). This ensured a
179 their comments mostly intact (modulo some formatting changes). This ensured a
180 smooth transition where no development history or submitted bugs were lost.
180 smooth transition where no development history or submitted bugs were lost.
181 Feel free to use our little Launchpad to Github issues `porting script`_ if you
181 Feel free to use our little Launchpad to Github issues `porting script`_ if you
182 need to make a similar transition.
182 need to make a similar transition.
183
183
184 .. __: http://mail.scipy.org/pipermail/ipython-dev/2010-April/005944.html
184 .. __: http://mail.scipy.org/pipermail/ipython-dev/2010-April/005944.html
185 .. _porting script: https://gist.github.com/835577
185 .. _porting script: https://gist.github.com/835577
186
186
187 These simple statistics show how much work has been done on the new release, by
187 These simple statistics show how much work has been done on the new release, by
188 comparing the current code to the last point it had in common with the 0.10
188 comparing the current code to the last point it had in common with the 0.10
189 series. A huge diff and ~2200 commits make up this cycle::
189 series. A huge diff and ~2200 commits make up this cycle::
190
190
191 git diff $(git merge-base 0.10.2 HEAD) | wc -l
191 git diff $(git merge-base 0.10.2 HEAD) | wc -l
192 288019
192 288019
193
193
194 git log $(git merge-base 0.10.2 HEAD)..HEAD --oneline | wc -l
194 git log $(git merge-base 0.10.2 HEAD)..HEAD --oneline | wc -l
195 2200
195 2200
196
196
197 Since our move to github, 511 issues were closed, 226 of which were pull
197 Since our move to github, 511 issues were closed, 226 of which were pull
198 requests and 285 regular issues (:ref:`a full list with links
198 requests and 285 regular issues (:ref:`a full list with links
199 <issues_list_011>` is available for those interested in the details). Github's
199 <issues_list_011>` is available for those interested in the details). Github's
200 pull requests are a fantastic mechanism for reviewing code and building a
200 pull requests are a fantastic mechanism for reviewing code and building a
201 shared ownership of the project, and we are making enthusiastic use of it.
201 shared ownership of the project, and we are making enthusiastic use of it.
202
202
203 .. Note::
203 .. Note::
204
204
205 This undercounts the number of issues closed in this development cycle,
205 This undercounts the number of issues closed in this development cycle,
206 since we only moved to github for issue tracking in May 2010, but we have no
206 since we only moved to github for issue tracking in May 2010, but we have no
207 way of collecting statistics on the number of issues closed in the old
207 way of collecting statistics on the number of issues closed in the old
208 Launchpad bug tracker prior to that.
208 Launchpad bug tracker prior to that.
209
209
210
210
211 .. _qtconsole_011:
211 .. _qtconsole_011:
212
212
213 Qt Console
213 Qt Console
214 ----------
214 ----------
215
215
216 IPython now ships with a Qt application that feels very much like a terminal,
216 IPython now ships with a Qt application that feels very much like a terminal,
217 but is in fact a rich GUI that runs an IPython client but supports inline
217 but is in fact a rich GUI that runs an IPython client but supports inline
218 figures, saving sessions to PDF and HTML, multiline editing with syntax
218 figures, saving sessions to PDF and HTML, multiline editing with syntax
219 highlighting, graphical calltips and much more:
219 highlighting, graphical calltips and much more:
220
220
221 .. figure:: ../_images/qtconsole.png
221 .. figure:: ../_images/qtconsole.png
222 :width: 400px
222 :width: 400px
223 :alt: IPython Qt console with embedded plots
223 :alt: IPython Qt console with embedded plots
224 :align: center
224 :align: center
225 :target: ../_images/qtconsole.png
225 :target: ../_images/qtconsole.png
226
226
227 The Qt console for IPython, using inline matplotlib plots.
227 The Qt console for IPython, using inline matplotlib plots.
228
228
229 We hope that many projects will embed this widget, which we've kept
229 We hope that many projects will embed this widget, which we've kept
230 deliberately very lightweight, into their own environments. In the future we
230 deliberately very lightweight, into their own environments. In the future we
231 may also offer a slightly more featureful application (with menus and other GUI
231 may also offer a slightly more featureful application (with menus and other GUI
232 elements), but we remain committed to always shipping this easy to embed
232 elements), but we remain committed to always shipping this easy to embed
233 widget.
233 widget.
234
234
235 See the `Jupyter Qt Console site <https://jupyter.org/qtconsole>`_ for a detailed
235 See the `Jupyter Qt Console site <https://jupyter.org/qtconsole>`_ for a detailed
236 description of the console's features and use.
236 description of the console's features and use.
237
237
238
238
239 .. _parallel_011:
239 .. _parallel_011:
240
240
241 High-level parallel computing with ZeroMQ
241 High-level parallel computing with ZeroMQ
242 -----------------------------------------
242 -----------------------------------------
243
243
244 We have completely rewritten the Twisted-based code for high-level parallel
244 We have completely rewritten the Twisted-based code for high-level parallel
245 computing to work atop our new ZeroMQ architecture. While we realize this will
245 computing to work atop our new ZeroMQ architecture. While we realize this will
246 break compatibility for a number of users, we hope to make the transition as
246 break compatibility for a number of users, we hope to make the transition as
247 easy as possible with our docs, and we are convinced the change is worth it.
247 easy as possible with our docs, and we are convinced the change is worth it.
248 ZeroMQ provides us with much tighter control over memory, higher performance,
248 ZeroMQ provides us with much tighter control over memory, higher performance,
249 and its communications are impervious to the Python Global Interpreter Lock
249 and its communications are impervious to the Python Global Interpreter Lock
250 because they take place in a system-level C++ thread. The impact of the GIL in
250 because they take place in a system-level C++ thread. The impact of the GIL in
251 our previous code was something we could simply not work around, given that
251 our previous code was something we could simply not work around, given that
252 Twisted is itself a Python library. So while Twisted is a very capable
252 Twisted is itself a Python library. So while Twisted is a very capable
253 framework, we think ZeroMQ fits our needs much better and we hope you will find
253 framework, we think ZeroMQ fits our needs much better and we hope you will find
254 the change to be a significant improvement in the long run.
254 the change to be a significant improvement in the long run.
255
255
256 Our manual contains a full description of how to use IPython for parallel
256 Our manual contains a full description of how to use IPython for parallel
257 computing, and the `tutorial`__ presented by Min
257 computing, and the `tutorial`__ presented by Min
258 Ragan-Kelley at the SciPy 2011 conference provides a hands-on complement to the
258 Ragan-Kelley at the SciPy 2011 conference provides a hands-on complement to the
259 reference docs.
259 reference docs.
260
260
261 .. __: http://minrk.github.com/scipy-tutorial-2011
261 .. __: http://minrk.github.com/scipy-tutorial-2011
262
262
263
263
264 Refactoring
264 Refactoring
265 -----------
265 -----------
266
266
267 As of this release, a significant portion of IPython has been refactored. This
267 As of this release, a significant portion of IPython has been refactored. This
268 refactoring is founded on a number of new abstractions. The main new classes
268 refactoring is founded on a number of new abstractions. The main new classes
269 that implement these abstractions are:
269 that implement these abstractions are:
270
270
271 * :class:`traitlets.HasTraits`.
271 * :class:`traitlets.HasTraits`.
272 * :class:`traitlets.config.configurable.Configurable`.
272 * :class:`traitlets.config.configurable.Configurable`.
273 * :class:`traitlets.config.application.Application`.
273 * :class:`traitlets.config.application.Application`.
274 * :class:`traitlets.config.loader.ConfigLoader`.
274 * :class:`traitlets.config.loader.ConfigLoader`.
275 * :class:`traitlets.config.loader.Config`
275 * :class:`traitlets.config.loader.Config`
276
276
277 We are still in the process of writing developer focused documentation about
277 We are still in the process of writing developer focused documentation about
278 these classes, but for now our :ref:`configuration documentation
278 these classes, but for now our :ref:`configuration documentation
279 <config_overview>` contains a high level overview of the concepts that these
279 <config_overview>` contains a high level overview of the concepts that these
280 classes express.
280 classes express.
281
281
282 The biggest user-visible change is likely the move to using the config system
282 The biggest user-visible change is likely the move to using the config system
283 to determine the command-line arguments for IPython applications. The benefit
283 to determine the command-line arguments for IPython applications. The benefit
284 of this is that *all* configurable values in IPython are exposed on the
284 of this is that *all* configurable values in IPython are exposed on the
285 command-line, but the syntax for specifying values has changed. The gist is
285 command-line, but the syntax for specifying values has changed. The gist is
286 that assigning values is pure Python assignment. Simple flags exist for
286 that assigning values is pure Python assignment. Simple flags exist for
287 commonly used options, these are always prefixed with '--'.
287 commonly used options, these are always prefixed with '--'.
288
288
289 The IPython command-line help has the details of all the options (via
289 The IPython command-line help has the details of all the options (via
290 ``ipython --help``), but a simple example should clarify things; the ``pylab``
290 ``ipython --help``), but a simple example should clarify things; the ``pylab``
291 flag can be used to start in pylab mode with the qt4 backend::
291 flag can be used to start in pylab mode with the qt4 backend::
292
292
293 ipython --pylab=qt
293 ipython --pylab=qt
294
294
295 which is equivalent to using the fully qualified form::
295 which is equivalent to using the fully qualified form::
296
296
297 ipython --TerminalIPythonApp.pylab=qt
297 ipython --TerminalIPythonApp.pylab=qt
298
298
299 The long-form options can be listed via ``ipython --help-all``.
299 The long-form options can be listed via ``ipython --help-all``.
300
300
301
301
302 ZeroMQ architecture
302 ZeroMQ architecture
303 -------------------
303 -------------------
304
304
305 There is a new GUI framework for IPython, based on a client-server model in
305 There is a new GUI framework for IPython, based on a client-server model in
306 which multiple clients can communicate with one IPython kernel, using the
306 which multiple clients can communicate with one IPython kernel, using the
307 ZeroMQ messaging framework. There is already a Qt console client, which can
307 ZeroMQ messaging framework. There is already a Qt console client, which can
308 be started by calling ``ipython qtconsole``. The protocol is :ref:`documented
308 be started by calling ``ipython qtconsole``. The protocol is :ref:`documented
309 <messaging>`.
309 <messaging>`.
310
310
311 The parallel computing framework has also been rewritten using ZMQ. The
311 The parallel computing framework has also been rewritten using ZMQ. The
312 protocol is described :ref:`here <parallel_messages>`, and the code is in the
312 protocol is described :ref:`here <parallel_messages>`, and the code is in the
313 new :mod:`IPython.parallel` module.
313 new :mod:`IPython.parallel` module.
314
314
315 .. _python3_011:
315 .. _python3_011:
316
316
317 Python 3 support
317 Python 3 support
318 ----------------
318 ----------------
319
319
320 A Python 3 version of IPython has been prepared. For the time being, this is
320 A Python 3 version of IPython has been prepared. For the time being, this is
321 maintained separately and updated from the main codebase. Its code can be found
321 maintained separately and updated from the main codebase. Its code can be found
322 `here <https://github.com/ipython/ipython-py3k>`_. The parallel computing
322 `here <https://github.com/ipython/ipython-py3k>`_. The parallel computing
323 components are not perfect on Python3, but most functionality appears to be
323 components are not perfect on Python3, but most functionality appears to be
324 working. As this work is evolving quickly, the best place to find updated
324 working. As this work is evolving quickly, the best place to find updated
325 information about it is our `Python 3 wiki page`__.
325 information about it is our `Python 3 wiki page`__.
326
326
327 .. __: http://wiki.ipython.org/index.php?title=Python_3
327 .. __: http://wiki.ipython.org/index.php?title=Python_3
328
328
329
329
330 Unicode
330 Unicode
331 -------
331 -------
332
332
333 Entering non-ascii characters in unicode literals (``u"€ø"``) now works
333 Entering non-ascii characters in unicode literals (``u"€ø"``) now works
334 properly on all platforms. However, entering these in byte/string literals
334 properly on all platforms. However, entering these in byte/string literals
335 (``"€ø"``) will not work as expected on Windows (or any platform where the
335 (``"€ø"``) will not work as expected on Windows (or any platform where the
336 terminal encoding is not UTF-8, as it typically is for Linux & Mac OS X). You
336 terminal encoding is not UTF-8, as it typically is for Linux & Mac OS X). You
337 can use escape sequences (``"\xe9\x82"``) to get bytes above 128, or use
337 can use escape sequences (``"\xe9\x82"``) to get bytes above 128, or use
338 unicode literals and encode them. This is a limitation of Python 2 which we
338 unicode literals and encode them. This is a limitation of Python 2 which we
339 cannot easily work around.
339 cannot easily work around.
340
340
341 .. _ms_visual_studio_011:
341 .. _ms_visual_studio_011:
342
342
343 Integration with Microsoft Visual Studio
343 Integration with Microsoft Visual Studio
344 ----------------------------------------
344 ----------------------------------------
345
345
346 IPython can be used as the interactive shell in the `Python plugin for
346 IPython can be used as the interactive shell in the `Python plugin for
347 Microsoft Visual Studio`__, as seen here:
347 Microsoft Visual Studio`__, as seen here:
348
348
349 .. figure:: ../_images/ms_visual_studio.png
349 .. figure:: ../_images/ms_visual_studio.png
350 :width: 500px
350 :width: 500px
351 :alt: IPython console embedded in Microsoft Visual Studio.
351 :alt: IPython console embedded in Microsoft Visual Studio.
352 :align: center
352 :align: center
353 :target: ../_images/ms_visual_studio.png
353 :target: ../_images/ms_visual_studio.png
354
354
355 IPython console embedded in Microsoft Visual Studio.
355 IPython console embedded in Microsoft Visual Studio.
356
356
357 The Microsoft team developing this currently has a release candidate out using
357 The Microsoft team developing this currently has a release candidate out using
358 IPython 0.11. We will continue to collaborate with them to ensure that as they
358 IPython 0.11. We will continue to collaborate with them to ensure that as they
359 approach their final release date, the integration with IPython remains smooth.
359 approach their final release date, the integration with IPython remains smooth.
360 We'd like to thank Dino Viehland and Shahrokh Mortazavi for the work they have
360 We'd like to thank Dino Viehland and Shahrokh Mortazavi for the work they have
361 done towards this feature, as well as Wenming Ye for his support of our WinHPC
361 done towards this feature, as well as Wenming Ye for his support of our WinHPC
362 capabilities.
362 capabilities.
363
363
364 .. __: http://pytools.codeplex.com
364 .. __: http://pytools.codeplex.com
365
365
366
366
367 Additional new features
367 Additional new features
368 -----------------------
368 -----------------------
369
369
370 * Added ``Bytes`` traitlet, removing ``Str``. All 'string' traitlets should
370 * Added ``Bytes`` traitlet, removing ``Str``. All 'string' traitlets should
371 either be ``Unicode`` if a real string, or ``Bytes`` if a C-string. This
371 either be ``Unicode`` if a real string, or ``Bytes`` if a C-string. This
372 removes ambiguity and helps the Python 3 transition.
372 removes ambiguity and helps the Python 3 transition.
373
373
374 * New magic ``%loadpy`` loads a python file from disk or web URL into
374 * New magic ``%loadpy`` loads a python file from disk or web URL into
375 the current input buffer.
375 the current input buffer.
376
376
377 * New magic ``%pastebin`` for sharing code via the 'Lodge it' pastebin.
377 * New magic ``%pastebin`` for sharing code via the 'Lodge it' pastebin.
378
378
379 * New magic ``%precision`` for controlling float and numpy pretty printing.
379 * New magic ``%precision`` for controlling float and numpy pretty printing.
380
380
381 * IPython applications initiate logging, so any object can gain access to
381 * IPython applications initiate logging, so any object can gain access to
382 a the logger of the currently running Application with:
382 a the logger of the currently running Application with:
383
383
384 .. sourcecode:: python
384 .. sourcecode:: python
385
385
386 from traitlets.config.application import Application
386 from traitlets.config.application import Application
387 logger = Application.instance().log
387 logger = Application.instance().log
388
388
389 * You can now get help on an object halfway through typing a command. For
389 * You can now get help on an object halfway through typing a command. For
390 instance, typing ``a = zip?`` shows the details of :func:`zip`. It also
390 instance, typing ``a = zip?`` shows the details of :func:`zip`. It also
391 leaves the command at the next prompt so you can carry on with it.
391 leaves the command at the next prompt so you can carry on with it.
392
392
393 * The input history is now written to an SQLite database. The API for
393 * The input history is now written to an SQLite database. The API for
394 retrieving items from the history has also been redesigned.
394 retrieving items from the history has also been redesigned.
395
395
396 * The :mod:`IPython.extensions.pretty` extension has been moved out of
396 * The :mod:`IPython.extensions.pretty` extension has been moved out of
397 quarantine and fully updated to the new extension API.
397 quarantine and fully updated to the new extension API.
398
398
399 * New magics for loading/unloading/reloading extensions have been added:
399 * New magics for loading/unloading/reloading extensions have been added:
400 ``%load_ext``, ``%unload_ext`` and ``%reload_ext``.
400 ``%load_ext``, ``%unload_ext`` and ``%reload_ext``.
401
401
402 * The configuration system and configuration files are brand new. See the
402 * The configuration system and configuration files are brand new. See the
403 configuration system :ref:`documentation <config_index>` for more details.
403 configuration system :ref:`documentation <config_index>` for more details.
404
404
405 * The :class:`~IPython.core.interactiveshell.InteractiveShell` class is now a
405 * The :class:`~IPython.core.interactiveshell.InteractiveShell` class is now a
406 :class:`~traitlets.config.configurable.Configurable` subclass and has traitlets
406 :class:`~traitlets.config.configurable.Configurable` subclass and has traitlets
407 that determine the defaults and runtime environment. The ``__init__`` method
407 that determine the defaults and runtime environment. The ``__init__`` method
408 has also been refactored so this class can be instantiated and run without
408 has also been refactored so this class can be instantiated and run without
409 the old :mod:`ipmaker` module.
409 the old :mod:`ipmaker` module.
410
410
411 * The methods of :class:`~IPython.core.interactiveshell.InteractiveShell` have
411 * The methods of :class:`~IPython.core.interactiveshell.InteractiveShell` have
412 been organized into sections to make it easier to turn more sections
412 been organized into sections to make it easier to turn more sections
413 of functionality into components.
413 of functionality into components.
414
414
415 * The embedded shell has been refactored into a truly standalone subclass of
415 * The embedded shell has been refactored into a truly standalone subclass of
416 :class:`InteractiveShell` called :class:`InteractiveShellEmbed`. All
416 :class:`InteractiveShell` called :class:`InteractiveShellEmbed`. All
417 embedding logic has been taken out of the base class and put into the
417 embedding logic has been taken out of the base class and put into the
418 embedded subclass.
418 embedded subclass.
419
419
420 * Added methods of :class:`~IPython.core.interactiveshell.InteractiveShell` to
420 * Added methods of :class:`~IPython.core.interactiveshell.InteractiveShell` to
421 help it cleanup after itself. The :meth:`cleanup` method controls this. We
421 help it cleanup after itself. The :meth:`cleanup` method controls this. We
422 couldn't do this in :meth:`__del__` because we have cycles in our object
422 couldn't do this in :meth:`__del__` because we have cycles in our object
423 graph that prevent it from being called.
423 graph that prevent it from being called.
424
424
425 * Created a new module :mod:`IPython.utils.importstring` for resolving
425 * Created a new module :mod:`IPython.utils.importstring` for resolving
426 strings like ``foo.bar.Bar`` to the actual class.
426 strings like ``foo.bar.Bar`` to the actual class.
427
427
428 * Completely refactored the :mod:`IPython.core.prefilter` module into
428 * Completely refactored the :mod:`IPython.core.prefilter` module into
429 :class:`~traitlets.config.configurable.Configurable` subclasses. Added a new
429 :class:`~traitlets.config.configurable.Configurable` subclasses. Added a new
430 layer into the prefilter system, called "transformations" that all new
430 layer into the prefilter system, called "transformations" that all new
431 prefilter logic should use (rather than the older "checker/handler"
431 prefilter logic should use (rather than the older "checker/handler"
432 approach).
432 approach).
433
433
434 * Aliases are now components (:mod:`IPython.core.alias`).
434 * Aliases are now components (:mod:`IPython.core.alias`).
435
435
436 * New top level :func:`~IPython.frontend.terminal.embed.embed` function that can
436 * New top level :func:`~IPython.frontend.terminal.embed.embed` function that can
437 be called to embed IPython at any place in user's code. On the first call it
437 be called to embed IPython at any place in user's code. On the first call it
438 will create an :class:`~IPython.frontend.terminal.embed.InteractiveShellEmbed`
438 will create an :class:`~IPython.frontend.terminal.embed.InteractiveShellEmbed`
439 instance and call it. In later calls, it just calls the previously created
439 instance and call it. In later calls, it just calls the previously created
440 :class:`~IPython.frontend.terminal.embed.InteractiveShellEmbed`.
440 :class:`~IPython.frontend.terminal.embed.InteractiveShellEmbed`.
441
441
442 * Created a configuration system (:mod:`traitlets.config.configurable`) that is
442 * Created a configuration system (:mod:`traitlets.config.configurable`) that is
443 based on :mod:`traitlets`. Configurables are arranged into a
443 based on :mod:`traitlets`. Configurables are arranged into a
444 runtime containment tree (not inheritance) that i) automatically propagates
444 runtime containment tree (not inheritance) that i) automatically propagates
445 configuration information and ii) allows singletons to discover each other in
445 configuration information and ii) allows singletons to discover each other in
446 a loosely coupled manner. In the future all parts of IPython will be
446 a loosely coupled manner. In the future all parts of IPython will be
447 subclasses of :class:`~traitlets.config.configurable.Configurable`. All IPython
447 subclasses of :class:`~traitlets.config.configurable.Configurable`. All IPython
448 developers should become familiar with the config system.
448 developers should become familiar with the config system.
449
449
450 * Created a new :class:`~traitlets.config.loader.Config` for holding
450 * Created a new :class:`~traitlets.config.loader.Config` for holding
451 configuration information. This is a dict like class with a few extras: i)
451 configuration information. This is a dict like class with a few extras: i)
452 it supports attribute style access, ii) it has a merge function that merges
452 it supports attribute style access, ii) it has a merge function that merges
453 two :class:`~traitlets.config.loader.Config` instances recursively and iii) it
453 two :class:`~traitlets.config.loader.Config` instances recursively and iii) it
454 will automatically create sub-:class:`~traitlets.config.loader.Config`
454 will automatically create sub-:class:`~traitlets.config.loader.Config`
455 instances for attributes that start with an uppercase character.
455 instances for attributes that start with an uppercase character.
456
456
457 * Created new configuration loaders in :mod:`traitlets.config.loader`. These
457 * Created new configuration loaders in :mod:`traitlets.config.loader`. These
458 loaders provide a unified loading interface for all configuration
458 loaders provide a unified loading interface for all configuration
459 information including command line arguments and configuration files. We
459 information including command line arguments and configuration files. We
460 have two default implementations based on :mod:`argparse` and plain python
460 have two default implementations based on :mod:`argparse` and plain python
461 files. These are used to implement the new configuration system.
461 files. These are used to implement the new configuration system.
462
462
463 * Created a top-level :class:`Application` class in
463 * Created a top-level :class:`Application` class in
464 :mod:`IPython.core.application` that is designed to encapsulate the starting
464 :mod:`IPython.core.application` that is designed to encapsulate the starting
465 of any basic Python program. An application loads and merges all the
465 of any basic Python program. An application loads and merges all the
466 configuration objects, constructs the main application, configures and
466 configuration objects, constructs the main application, configures and
467 initiates logging, and creates and configures any :class:`Configurable`
467 initiates logging, and creates and configures any :class:`Configurable`
468 instances and then starts the application running. An extended
468 instances and then starts the application running. An extended
469 :class:`BaseIPythonApplication` class adds logic for handling the
469 :class:`BaseIPythonApplication` class adds logic for handling the
470 IPython directory as well as profiles, and all IPython entry points
470 IPython directory as well as profiles, and all IPython entry points
471 extend it.
471 extend it.
472
472
473 * The :class:`Type` and :class:`Instance` traitlets now handle classes given
473 * The :class:`Type` and :class:`Instance` traitlets now handle classes given
474 as strings, like ``foo.bar.Bar``. This is needed for forward declarations.
474 as strings, like ``foo.bar.Bar``. This is needed for forward declarations.
475 But, this was implemented in a careful way so that string to class
475 But, this was implemented in a careful way so that string to class
476 resolution is done at a single point, when the parent
476 resolution is done at a single point, when the parent
477 :class:`~traitlets.HasTraitlets` is instantiated.
477 :class:`~traitlets.HasTraitlets` is instantiated.
478
478
479 * :mod:`IPython.utils.ipstruct` has been refactored to be a subclass of
479 * :mod:`IPython.utils.ipstruct` has been refactored to be a subclass of
480 dict. It also now has full docstrings and doctests.
480 dict. It also now has full docstrings and doctests.
481
481
482 * Created a Traits like implementation in :mod:`traitlets`. This
482 * Created a Traits like implementation in :mod:`traitlets`. This
483 is a pure Python, lightweight version of a library that is similar to
483 is a pure Python, lightweight version of a library that is similar to
484 Enthought's Traits project, but has no dependencies on Enthought's code. We
484 Enthought's Traits project, but has no dependencies on Enthought's code. We
485 are using this for validation, defaults and notification in our new component
485 are using this for validation, defaults and notification in our new component
486 system. Although it is not 100% API compatible with Enthought's Traits, we
486 system. Although it is not 100% API compatible with Enthought's Traits, we
487 plan on moving in this direction so that eventually our implementation could
487 plan on moving in this direction so that eventually our implementation could
488 be replaced by a (yet to exist) pure Python version of Enthought Traits.
488 be replaced by a (yet to exist) pure Python version of Enthought Traits.
489
489
490 * Added a new module :mod:`IPython.lib.inputhook` to manage the integration
490 * Added a new module :mod:`IPython.lib.inputhook` to manage the integration
491 with GUI event loops using `PyOS_InputHook`. See the docstrings in this
491 with GUI event loops using `PyOS_InputHook`. See the docstrings in this
492 module or the main IPython docs for details.
492 module or the main IPython docs for details.
493
493
494 * For users, GUI event loop integration is now handled through the new
494 * For users, GUI event loop integration is now handled through the new
495 :command:`%gui` magic command. Type ``%gui?`` at an IPython prompt for
495 :command:`%gui` magic command. Type ``%gui?`` at an IPython prompt for
496 documentation.
496 documentation.
497
497
498 * For developers :mod:`IPython.lib.inputhook` provides a simple interface
498 * For developers :mod:`IPython.lib.inputhook` provides a simple interface
499 for managing the event loops in their interactive GUI applications.
499 for managing the event loops in their interactive GUI applications.
500 Examples can be found in our :file:`examples/lib` directory.
500 Examples can be found in our :file:`examples/lib` directory.
501
501
502 Backwards incompatible changes
502 Backwards incompatible changes
503 ------------------------------
503 ------------------------------
504
504
505 * The Twisted-based :mod:`IPython.kernel` has been removed, and completely
505 * The Twisted-based :mod:`IPython.kernel` has been removed, and completely
506 rewritten as :mod:`IPython.parallel`, using ZeroMQ.
506 rewritten as :mod:`IPython.parallel`, using ZeroMQ.
507
507
508 * Profiles are now directories. Instead of a profile being a single config file,
508 * Profiles are now directories. Instead of a profile being a single config file,
509 profiles are now self-contained directories. By default, profiles get their
509 profiles are now self-contained directories. By default, profiles get their
510 own IPython history, log files, and everything. To create a new profile, do
510 own IPython history, log files, and everything. To create a new profile, do
511 ``ipython profile create <name>``.
511 ``ipython profile create <name>``.
512
512
513 * All IPython applications have been rewritten to use
513 * All IPython applications have been rewritten to use
514 :class:`~traitlets.config.loader.KeyValueConfigLoader`. This means that
514 :class:`~traitlets.config.loader.KeyValueConfigLoader`. This means that
515 command-line options have changed. Now, all configurable values are accessible
515 command-line options have changed. Now, all configurable values are accessible
516 from the command-line with the same syntax as in a configuration file.
516 from the command-line with the same syntax as in a configuration file.
517
517
518 * The command line options ``-wthread``, ``-qthread`` and
518 * The command line options ``-wthread``, ``-qthread`` and
519 ``-gthread`` have been removed. Use ``--gui=wx``, ``--gui=qt``, ``--gui=gtk``
519 ``-gthread`` have been removed. Use ``--gui=wx``, ``--gui=qt``, ``--gui=gtk``
520 instead.
520 instead.
521
521
522 * The extension loading functions have been renamed to
522 * The extension loading functions have been renamed to
523 :func:`load_ipython_extension` and :func:`unload_ipython_extension`.
523 :func:`load_ipython_extension` and :func:`unload_ipython_extension`.
524
524
525 * :class:`~IPython.core.interactiveshell.InteractiveShell` no longer takes an
525 * :class:`~IPython.core.interactiveshell.InteractiveShell` no longer takes an
526 ``embedded`` argument. Instead just use the
526 ``embedded`` argument. Instead just use the
527 :class:`~IPython.core.interactiveshell.InteractiveShellEmbed` class.
527 :class:`~IPython.core.interactiveshell.InteractiveShellEmbed` class.
528
528
529 * ``__IPYTHON__`` is no longer injected into ``__builtin__``.
529 * ``__IPYTHON__`` is no longer injected into ``__builtin__``.
530
530
531 * :meth:`Struct.__init__` no longer takes `None` as its first argument. It
531 * :meth:`Struct.__init__` no longer takes `None` as its first argument. It
532 must be a :class:`dict` or :class:`Struct`.
532 must be a :class:`dict` or :class:`Struct`.
533
533
534 * :meth:`~IPython.core.interactiveshell.InteractiveShell.ipmagic` has been
534 * :meth:`~IPython.core.interactiveshell.InteractiveShell.ipmagic` has been
535 renamed :meth:`~IPython.core.interactiveshell.InteractiveShell.magic.`
535 renamed :meth:`~IPython.core.interactiveshell.InteractiveShell.magic.`
536
536
537 * The functions :func:`ipmagic` and :func:`ipalias` have been removed from
537 * The functions :func:`ipmagic` and :func:`ipalias` have been removed from
538 :mod:`__builtins__`.
538 :mod:`__builtins__`.
539
539
540 * The references to the global
540 * The references to the global
541 :class:`~IPython.core.interactivehell.InteractiveShell` instance (``_ip``, and
541 :class:`~IPython.core.interactivehell.InteractiveShell` instance (``_ip``, and
542 ``__IP``) have been removed from the user's namespace. They are replaced by a
542 ``__IP``) have been removed from the user's namespace. They are replaced by a
543 new function called :func:`get_ipython` that returns the current
543 new function called :func:`get_ipython` that returns the current
544 :class:`~IPython.core.interactiveshell.InteractiveShell` instance. This
544 :class:`~IPython.core.interactiveshell.InteractiveShell` instance. This
545 function is injected into the user's namespace and is now the main way of
545 function is injected into the user's namespace and is now the main way of
546 accessing the running IPython.
546 accessing the running IPython.
547
547
548 * Old style configuration files :file:`ipythonrc` and :file:`ipy_user_conf.py`
548 * Old style configuration files :file:`ipythonrc` and :file:`ipy_user_conf.py`
549 are no longer supported. Users should migrate there configuration files to
549 are no longer supported. Users should migrate there configuration files to
550 the new format described :doc:`here </config/intro>` and
550 the new format described :doc:`here </config/intro>` and
551 :ref:`here <config_overview>`.
551 :ref:`here <config_overview>`.
552
552
553 * The old IPython extension API that relied on :func:`ipapi` has been
553 * The old IPython extension API that relied on :func:`ipapi` has been
554 completely removed. The new extension API is described :ref:`here
554 completely removed. The new extension API is described :ref:`here
555 <extensions_overview>`.
555 <extensions_overview>`.
556
556
557 * Support for ``qt3`` has been dropped. Users who need this should use
557 * Support for ``qt3`` has been dropped. Users who need this should use
558 previous versions of IPython.
558 previous versions of IPython.
559
559
560 * Removed :mod:`shellglobals` as it was obsolete.
560 * Removed :mod:`shellglobals` as it was obsolete.
561
561
562 * Removed all the threaded shells in :mod:`IPython.core.shell`. These are no
562 * Removed all the threaded shells in :mod:`IPython.core.shell`. These are no
563 longer needed because of the new capabilities in
563 longer needed because of the new capabilities in
564 :mod:`IPython.lib.inputhook`.
564 :mod:`IPython.lib.inputhook`.
565
565
566 * New top-level sub-packages have been created: :mod:`IPython.core`,
566 * New top-level sub-packages have been created: :mod:`IPython.core`,
567 :mod:`IPython.lib`, :mod:`IPython.utils`, :mod:`IPython.deathrow`,
567 :mod:`IPython.lib`, :mod:`IPython.utils`, :mod:`IPython.deathrow`,
568 :mod:`IPython.quarantine`. All existing top-level modules have been
568 :mod:`IPython.quarantine`. All existing top-level modules have been
569 moved to appropriate sub-packages. All internal import statements
569 moved to appropriate sub-packages. All internal import statements
570 have been updated and tests have been added. The build system (setup.py
570 have been updated and tests have been added. The build system (setup.py
571 and friends) have been updated. See :doc:`/api/index` for details of these
571 and friends) have been updated. See :doc:`/api/index` for details of these
572 new sub-packages.
572 new sub-packages.
573
573
574 * :mod:`IPython.ipapi` has been moved to :mod:`IPython.core.ipapi`.
574 * :mod:`IPython.ipapi` has been moved to :mod:`IPython.core.ipapi`.
575 :mod:`IPython.Shell` and :mod:`IPython.iplib` have been split and removed as
575 :mod:`IPython.Shell` and :mod:`IPython.iplib` have been split and removed as
576 part of the refactor.
576 part of the refactor.
577
577
578 * :mod:`Extensions` has been moved to :mod:`extensions` and all existing
578 * :mod:`Extensions` has been moved to :mod:`extensions` and all existing
579 extensions have been moved to either :mod:`IPython.quarantine` or
579 extensions have been moved to either :mod:`IPython.quarantine` or
580 :mod:`IPython.deathrow`. :mod:`IPython.quarantine` contains modules that we
580 :mod:`IPython.deathrow`. :mod:`IPython.quarantine` contains modules that we
581 plan on keeping but that need to be updated. :mod:`IPython.deathrow` contains
581 plan on keeping but that need to be updated. :mod:`IPython.deathrow` contains
582 modules that are either dead or that should be maintained as third party
582 modules that are either dead or that should be maintained as third party
583 libraries.
583 libraries.
584
584
585 * Previous IPython GUIs in :mod:`IPython.frontend` and :mod:`IPython.gui` are
585 * Previous IPython GUIs in :mod:`IPython.frontend` and :mod:`IPython.gui` are
586 likely broken, and have been removed to :mod:`IPython.deathrow` because of the
586 likely broken, and have been removed to :mod:`IPython.deathrow` because of the
587 refactoring in the core. With proper updates, these should still work.
587 refactoring in the core. With proper updates, these should still work.
588
588
589
589
590 Known Regressions
590 Known Regressions
591 -----------------
591 -----------------
592
592
593 We do our best to improve IPython, but there are some known regressions in 0.11
593 We do our best to improve IPython, but there are some known regressions in 0.11
594 relative to 0.10.2. First of all, there are features that have yet to be
594 relative to 0.10.2. First of all, there are features that have yet to be
595 ported to the new APIs, and in order to ensure that all of the installed code
595 ported to the new APIs, and in order to ensure that all of the installed code
596 runs for our users, we have moved them to two separate directories in the
596 runs for our users, we have moved them to two separate directories in the
597 source distribution, `quarantine` and `deathrow`. Finally, we have some other
597 source distribution, `quarantine` and `deathrow`. Finally, we have some other
598 miscellaneous regressions that we hope to fix as soon as possible. We now
598 miscellaneous regressions that we hope to fix as soon as possible. We now
599 describe all of these in more detail.
599 describe all of these in more detail.
600
600
601 Quarantine
601 Quarantine
602 ~~~~~~~~~~
602 ~~~~~~~~~~
603
603
604 These are tools and extensions that we consider relatively easy to update to
604 These are tools and extensions that we consider relatively easy to update to
605 the new classes and APIs, but that we simply haven't had time for. Any user
605 the new classes and APIs, but that we simply haven't had time for. Any user
606 who is interested in one of these is encouraged to help us by porting it and
606 who is interested in one of these is encouraged to help us by porting it and
607 submitting a pull request on our `development site`_.
607 submitting a pull request on our `development site`_.
608
608
609 .. _development site: http://github.com/ipython/ipython
609 .. _development site: http://github.com/ipython/ipython
610
610
611 Currently, the quarantine directory contains::
611 Currently, the quarantine directory contains::
612
612
613 clearcmd.py ipy_fsops.py ipy_signals.py
613 clearcmd.py ipy_fsops.py ipy_signals.py
614 envpersist.py ipy_gnuglobal.py ipy_synchronize_with.py
614 envpersist.py ipy_gnuglobal.py ipy_synchronize_with.py
615 ext_rescapture.py ipy_greedycompleter.py ipy_system_conf.py
615 ext_rescapture.py ipy_greedycompleter.py ipy_system_conf.py
616 InterpreterExec.py ipy_jot.py ipy_which.py
616 InterpreterExec.py ipy_jot.py ipy_which.py
617 ipy_app_completers.py ipy_lookfor.py ipy_winpdb.py
617 ipy_app_completers.py ipy_lookfor.py ipy_winpdb.py
618 ipy_autoreload.py ipy_profile_doctest.py ipy_workdir.py
618 ipy_autoreload.py ipy_profile_doctest.py ipy_workdir.py
619 ipy_completers.py ipy_pydb.py jobctrl.py
619 ipy_completers.py ipy_pydb.py jobctrl.py
620 ipy_editors.py ipy_rehashdir.py ledit.py
620 ipy_editors.py ipy_rehashdir.py ledit.py
621 ipy_exportdb.py ipy_render.py pspersistence.py
621 ipy_exportdb.py ipy_render.py pspersistence.py
622 ipy_extutil.py ipy_server.py win32clip.py
622 ipy_extutil.py ipy_server.py win32clip.py
623
623
624 Deathrow
624 Deathrow
625 ~~~~~~~~
625 ~~~~~~~~
626
626
627 These packages may be harder to update or make most sense as third-party
627 These packages may be harder to update or make most sense as third-party
628 libraries. Some of them are completely obsolete and have been already replaced
628 libraries. Some of them are completely obsolete and have been already replaced
629 by better functionality (we simply haven't had the time to carefully weed them
629 by better functionality (we simply haven't had the time to carefully weed them
630 out so they are kept here for now). Others simply require fixes to code that
630 out so they are kept here for now). Others simply require fixes to code that
631 the current core team may not be familiar with. If a tool you were used to is
631 the current core team may not be familiar with. If a tool you were used to is
632 included here, we encourage you to contact the dev list and we can discuss
632 included here, we encourage you to contact the dev list and we can discuss
633 whether it makes sense to keep it in IPython (if it can be maintained).
633 whether it makes sense to keep it in IPython (if it can be maintained).
634
634
635 Currently, the deathrow directory contains::
635 Currently, the deathrow directory contains::
636
636
637 astyle.py ipy_defaults.py ipy_vimserver.py
637 astyle.py ipy_defaults.py ipy_vimserver.py
638 dtutils.py ipy_kitcfg.py numeric_formats.py
638 dtutils.py ipy_kitcfg.py numeric_formats.py
639 Gnuplot2.py ipy_legacy.py numutils.py
639 Gnuplot2.py ipy_legacy.py numutils.py
640 GnuplotInteractive.py ipy_p4.py outputtrap.py
640 GnuplotInteractive.py ipy_p4.py outputtrap.py
641 GnuplotRuntime.py ipy_profile_none.py PhysicalQInput.py
641 GnuplotRuntime.py ipy_profile_none.py PhysicalQInput.py
642 ibrowse.py ipy_profile_numpy.py PhysicalQInteractive.py
642 ibrowse.py ipy_profile_numpy.py PhysicalQInteractive.py
643 igrid.py ipy_profile_scipy.py quitter.py*
643 igrid.py ipy_profile_scipy.py quitter.py*
644 ipipe.py ipy_profile_sh.py scitedirector.py
644 ipipe.py ipy_profile_sh.py scitedirector.py
645 iplib.py ipy_profile_zope.py Shell.py
645 iplib.py ipy_profile_zope.py Shell.py
646 ipy_constants.py ipy_traits_completer.py twshell.py
646 ipy_constants.py ipy_traits_completer.py twshell.py
647
647
648
648
649 Other regressions
649 Other regressions
650 ~~~~~~~~~~~~~~~~~
650 ~~~~~~~~~~~~~~~~~
651
651
652 * The machinery that adds functionality to the 'sh' profile for using IPython
652 * The machinery that adds functionality to the 'sh' profile for using IPython
653 as your system shell has not been updated to use the new APIs. As a result,
653 as your system shell has not been updated to use the new APIs. As a result,
654 only the aesthetic (prompt) changes are still implemented. We intend to fix
654 only the aesthetic (prompt) changes are still implemented. We intend to fix
655 this by 0.12. Tracked as issue 547_.
655 this by 0.12. Tracked as issue 547_.
656
656
657 .. _547: https://github.com/ipython/ipython/issues/547
657 .. _547: https://github.com/ipython/ipython/issues/547
658
658
659 * The installation of scripts on Windows was broken without setuptools, so we
659 * The installation of scripts on Windows was broken without setuptools, so we
660 now depend on setuptools on Windows. We hope to fix setuptools-less
660 now depend on setuptools on Windows. We hope to fix setuptools-less
661 installation, and then remove the setuptools dependency. Issue 539_.
661 installation, and then remove the setuptools dependency. Issue 539_.
662
662
663 .. _539: https://github.com/ipython/ipython/issues/539
663 .. _539: https://github.com/ipython/ipython/issues/539
664
664
665 * The directory history `_dh` is not saved between sessions. Issue 634_.
665 * The directory history `_dh` is not saved between sessions. Issue 634_.
666
666
667 .. _634: https://github.com/ipython/ipython/issues/634
667 .. _634: https://github.com/ipython/ipython/issues/634
668
668
669
669
670 Removed Features
670 Removed Features
671 ----------------
671 ----------------
672
672
673 As part of the updating of IPython, we have removed a few features for the
673 As part of the updating of IPython, we have removed a few features for the
674 purposes of cleaning up the codebase and interfaces. These removals are
674 purposes of cleaning up the codebase and interfaces. These removals are
675 permanent, but for any item listed below, equivalent functionality is
675 permanent, but for any item listed below, equivalent functionality is
676 available.
676 available.
677
677
678 * The magics Exit and Quit have been dropped as ways to exit IPython. Instead,
678 * The magics Exit and Quit have been dropped as ways to exit IPython. Instead,
679 the lowercase forms of both work either as a bare name (``exit``) or a
679 the lowercase forms of both work either as a bare name (``exit``) or a
680 function call (``exit()``). You can assign these to other names using
680 function call (``exit()``). You can assign these to other names using
681 exec_lines in the config file.
681 exec_lines in the config file.
682
682
683
683
684 .. _credits_011:
684 .. _credits_011:
685
685
686 Credits
686 Credits
687 -------
687 -------
688
688
689 Many users and developers contributed code, features, bug reports and ideas to
689 Many users and developers contributed code, features, bug reports and ideas to
690 this release. Please do not hesitate in contacting us if we've failed to
690 this release. Please do not hesitate in contacting us if we've failed to
691 acknowledge your contribution here. In particular, for this release we have
691 acknowledge your contribution here. In particular, for this release we have
692 contribution from the following people, a mix of new and regular names (in
692 contribution from the following people, a mix of new and regular names (in
693 alphabetical order by first name):
693 alphabetical order by first name):
694
694
695 * Aenugu Sai Kiran Reddy <saikrn08-at-gmail.com>
695 * Aenugu Sai Kiran Reddy <saikrn08-at-gmail.com>
696 * andy wilson <wilson.andrew.j+github-at-gmail.com>
696 * andy wilson <wilson.andrew.j+github-at-gmail.com>
697 * Antonio Cuni <antocuni>
697 * Antonio Cuni <antocuni>
698 * Barry Wark <barrywark-at-gmail.com>
698 * Barry Wark <barrywark-at-gmail.com>
699 * Beetoju Anuradha <anu.beethoju-at-gmail.com>
699 * Beetoju Anuradha <anu.beethoju-at-gmail.com>
700 * Benjamin Ragan-Kelley <minrk-at-Mercury.local>
700 * Benjamin Ragan-Kelley <minrk-at-Mercury.local>
701 * Brad Reisfeld
701 * Brad Reisfeld
702 * Brian E. Granger <ellisonbg-at-gmail.com>
702 * Brian E. Granger <ellisonbg-at-gmail.com>
703 * Christoph Gohlke <cgohlke-at-uci.edu>
703 * Christoph Gohlke <cgohlke-at-uci.edu>
704 * Cody Precord
704 * Cody Precord
705 * dan.milstein
705 * dan.milstein
706 * Darren Dale <dsdale24-at-gmail.com>
706 * Darren Dale <dsdale24-at-gmail.com>
707 * Dav Clark <davclark-at-berkeley.edu>
707 * Dav Clark <davclark-at-berkeley.edu>
708 * David Warde-Farley <wardefar-at-iro.umontreal.ca>
708 * David Warde-Farley <wardefar-at-iro.umontreal.ca>
709 * epatters <ejpatters-at-gmail.com>
709 * epatters <ejpatters-at-gmail.com>
710 * epatters <epatters-at-caltech.edu>
710 * epatters <epatters-at-caltech.edu>
711 * epatters <epatters-at-enthought.com>
711 * epatters <epatters-at-enthought.com>
712 * Eric Firing <efiring-at-hawaii.edu>
712 * Eric Firing <efiring-at-hawaii.edu>
713 * Erik Tollerud <erik.tollerud-at-gmail.com>
713 * Erik Tollerud <erik.tollerud-at-gmail.com>
714 * Evan Patterson <epatters-at-enthought.com>
714 * Evan Patterson <epatters-at-enthought.com>
715 * Fernando Perez <Fernando.Perez-at-berkeley.edu>
715 * Fernando Perez <Fernando.Perez-at-berkeley.edu>
716 * Gael Varoquaux <gael.varoquaux-at-normalesup.org>
716 * Gael Varoquaux <gael.varoquaux-at-normalesup.org>
717 * Gerardo <muzgash-at-Muzpelheim>
717 * Gerardo <muzgash-at-Muzpelheim>
718 * Jason Grout <jason.grout-at-drake.edu>
718 * Jason Grout <jason.grout-at-drake.edu>
719 * John Hunter <jdh2358-at-gmail.com>
719 * John Hunter <jdh2358-at-gmail.com>
720 * Jens Hedegaard Nielsen <jenshnielsen-at-gmail.com>
720 * Jens Hedegaard Nielsen <jenshnielsen-at-gmail.com>
721 * Johann Cohen-Tanugi <johann.cohentanugi-at-gmail.com>
721 * Johann Cohen-Tanugi <johann.cohentanugi-at-gmail.com>
722 * Jörgen Stenarson <jorgen.stenarson-at-bostream.nu>
722 * Jörgen Stenarson <jorgen.stenarson-at-bostream.nu>
723 * Justin Riley <justin.t.riley-at-gmail.com>
723 * Justin Riley <justin.t.riley-at-gmail.com>
724 * Kiorky
724 * Kiorky
725 * Laurent Dufrechou <laurent.dufrechou-at-gmail.com>
725 * Laurent Dufrechou <laurent.dufrechou-at-gmail.com>
726 * Luis Pedro Coelho <lpc-at-cmu.edu>
726 * Luis Pedro Coelho <lpc-at-cmu.edu>
727 * Mani chandra <mchandra-at-iitk.ac.in>
727 * Mani chandra <mchandra-at-iitk.ac.in>
728 * Mark E. Smith
728 * Mark E. Smith
729 * Mark Voorhies <mark.voorhies-at-ucsf.edu>
729 * Mark Voorhies <mark.voorhies-at-ucsf.edu>
730 * Martin Spacek <git-at-mspacek.mm.st>
730 * Martin Spacek <git-at-mspacek.mm.st>
731 * Michael Droettboom <mdroe-at-stsci.edu>
731 * Michael Droettboom <mdroe-at-stsci.edu>
732 * MinRK <benjaminrk-at-gmail.com>
732 * MinRK <benjaminrk-at-gmail.com>
733 * muzuiget <muzuiget-at-gmail.com>
733 * muzuiget <muzuiget-at-gmail.com>
734 * Nick Tarleton <nick-at-quixey.com>
734 * Nick Tarleton <nick-at-quixey.com>
735 * Nicolas Rougier <Nicolas.rougier-at-inria.fr>
735 * Nicolas Rougier <Nicolas.rougier-at-inria.fr>
736 * Omar Andres Zapata Mesa <andresete.chaos-at-gmail.com>
736 * Omar Andres Zapata Mesa <andresete.chaos-at-gmail.com>
737 * Paul Ivanov <pivanov314-at-gmail.com>
737 * Paul Ivanov <pivanov314-at-gmail.com>
738 * Pauli Virtanen <pauli.virtanen-at-iki.fi>
738 * Pauli Virtanen <pauli.virtanen-at-iki.fi>
739 * Prabhu Ramachandran
739 * Prabhu Ramachandran
740 * Ramana <sramana9-at-gmail.com>
740 * Ramana <sramana9-at-gmail.com>
741 * Robert Kern <robert.kern-at-gmail.com>
741 * Robert Kern <robert.kern-at-gmail.com>
742 * Sathesh Chandra <satheshchandra88-at-gmail.com>
742 * Sathesh Chandra <satheshchandra88-at-gmail.com>
743 * Satrajit Ghosh <satra-at-mit.edu>
743 * Satrajit Ghosh <satra-at-mit.edu>
744 * Sebastian Busch
744 * Sebastian Busch
745 * Skipper Seabold <jsseabold-at-gmail.com>
745 * Skipper Seabold <jsseabold-at-gmail.com>
746 * Stefan van der Walt <bzr-at-mentat.za.net>
746 * Stefan van der Walt <bzr-at-mentat.za.net>
747 * Stephan Peijnik <debian-at-sp.or.at>
747 * Stephan Peijnik <debian-at-sp.or.at>
748 * Steven Bethard
748 * Steven Bethard
749 * Thomas Kluyver <takowl-at-gmail.com>
749 * Thomas Kluyver <takowl-at-gmail.com>
750 * Thomas Spura <tomspur-at-fedoraproject.org>
750 * Thomas Spura <tomspur-at-fedoraproject.org>
751 * Tom Fetherston <tfetherston-at-aol.com>
751 * Tom Fetherston <tfetherston-at-aol.com>
752 * Tom MacWright
752 * Tom MacWright
753 * tzanko
753 * tzanko
754 * vankayala sowjanya <hai.sowjanya-at-gmail.com>
754 * vankayala sowjanya <hai.sowjanya-at-gmail.com>
755 * Vivian De Smedt <vds2212-at-VIVIAN>
755 * Vivian De Smedt <vds2212-at-VIVIAN>
756 * Ville M. Vainio <vivainio-at-gmail.com>
756 * Ville M. Vainio <vivainio-at-gmail.com>
757 * Vishal Vatsa <vishal.vatsa-at-gmail.com>
757 * Vishal Vatsa <vishal.vatsa-at-gmail.com>
758 * Vishnu S G <sgvishnu777-at-gmail.com>
758 * Vishnu S G <sgvishnu777-at-gmail.com>
759 * Walter Doerwald <walter-at-livinglogic.de>
759 * Walter Doerwald <walter-at-livinglogic.de>
760
760
761 .. note::
761 .. note::
762
762
763 This list was generated with the output of
763 This list was generated with the output of
764 ``git log dev-0.11 HEAD --format='* %aN <%aE>' | sed 's/@/\-at\-/' | sed 's/<>//' | sort -u``
764 ``git log dev-0.11 HEAD --format='* %aN <%aE>' | sed 's/@/\-at\-/' | sed 's/<>//' | sort -u``
765 after some cleanup. If you should be on this list, please add yourself.
765 after some cleanup. If you should be on this list, please add yourself.
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now