##// END OF EJS Templates
ipython_kernel is now ipykernel
Min RK -
Show More
@@ -1,145 +1,145 b''
1 1 # encoding: utf-8
2 2 """
3 3 IPython: tools for interactive and parallel computing in Python.
4 4
5 5 http://ipython.org
6 6 """
7 7 #-----------------------------------------------------------------------------
8 8 # Copyright (c) 2008-2011, IPython Development Team.
9 9 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
10 10 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
11 11 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
12 12 #
13 13 # Distributed under the terms of the Modified BSD License.
14 14 #
15 15 # The full license is in the file COPYING.txt, distributed with this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21 from __future__ import absolute_import
22 22
23 23 import os
24 24 import sys
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Setup everything
28 28 #-----------------------------------------------------------------------------
29 29
30 30 # Don't forget to also update setup.py when this changes!
31 31 v = sys.version_info
32 32 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
33 33 raise ImportError('IPython requires Python version 2.7 or 3.3 or above.')
34 34 del v
35 35
36 36 # Make it easy to import extensions - they are always directly on pythonpath.
37 37 # Therefore, non-IPython modules can be added to extensions directory.
38 38 # This should probably be in ipapp.py.
39 39 sys.path.append(os.path.join(os.path.dirname(__file__), "extensions"))
40 40
41 41 #-----------------------------------------------------------------------------
42 42 # Setup the top level names
43 43 #-----------------------------------------------------------------------------
44 44
45 45 from .core.getipython import get_ipython
46 46 from .core import release
47 47 from .core.application import Application
48 48 from .terminal.embed import embed
49 49
50 50 from .core.interactiveshell import InteractiveShell
51 51 from .testing import test
52 52 from .utils.sysinfo import sys_info
53 53 from .utils.frame import extract_module_locals
54 54
55 55 # Release data
56 56 __author__ = '%s <%s>' % (release.author, release.author_email)
57 57 __license__ = release.license
58 58 __version__ = release.version
59 59 version_info = release.version_info
60 60
61 61 def embed_kernel(module=None, local_ns=None, **kwargs):
62 62 """Embed and start an IPython kernel in a given scope.
63 63
64 64 If you don't want the kernel to initialize the namespace
65 65 from the scope of the surrounding function,
66 66 and/or you want to load full IPython configuration,
67 67 you probably want `IPython.start_kernel()` instead.
68 68
69 69 Parameters
70 70 ----------
71 71 module : ModuleType, optional
72 72 The module to load into IPython globals (default: caller)
73 73 local_ns : dict, optional
74 74 The namespace to load into IPython user namespace (default: caller)
75 75
76 76 kwargs : various, optional
77 77 Further keyword args are relayed to the IPKernelApp constructor,
78 78 allowing configuration of the Kernel. Will only have an effect
79 79 on the first embed_kernel call for a given process.
80 80 """
81 81
82 82 (caller_module, caller_locals) = extract_module_locals(1)
83 83 if module is None:
84 84 module = caller_module
85 85 if local_ns is None:
86 86 local_ns = caller_locals
87 87
88 88 # Only import .zmq when we really need it
89 from ipython_kernel.embed import embed_kernel as real_embed_kernel
89 from ipykernel.embed import embed_kernel as real_embed_kernel
90 90 real_embed_kernel(module=module, local_ns=local_ns, **kwargs)
91 91
92 92 def start_ipython(argv=None, **kwargs):
93 93 """Launch a normal IPython instance (as opposed to embedded)
94 94
95 95 `IPython.embed()` puts a shell in a particular calling scope,
96 96 such as a function or method for debugging purposes,
97 97 which is often not desirable.
98 98
99 99 `start_ipython()` does full, regular IPython initialization,
100 100 including loading startup files, configuration, etc.
101 101 much of which is skipped by `embed()`.
102 102
103 103 This is a public API method, and will survive implementation changes.
104 104
105 105 Parameters
106 106 ----------
107 107
108 108 argv : list or None, optional
109 109 If unspecified or None, IPython will parse command-line options from sys.argv.
110 110 To prevent any command-line parsing, pass an empty list: `argv=[]`.
111 111 user_ns : dict, optional
112 112 specify this dictionary to initialize the IPython user namespace with particular values.
113 113 kwargs : various, optional
114 114 Any other kwargs will be passed to the Application constructor,
115 115 such as `config`.
116 116 """
117 117 from IPython.terminal.ipapp import launch_new_instance
118 118 return launch_new_instance(argv=argv, **kwargs)
119 119
120 120 def start_kernel(argv=None, **kwargs):
121 121 """Launch a normal IPython kernel instance (as opposed to embedded)
122 122
123 123 `IPython.embed_kernel()` puts a shell in a particular calling scope,
124 124 such as a function or method for debugging purposes,
125 125 which is often not desirable.
126 126
127 127 `start_kernel()` does full, regular IPython initialization,
128 128 including loading startup files, configuration, etc.
129 129 much of which is skipped by `embed()`.
130 130
131 131 Parameters
132 132 ----------
133 133
134 134 argv : list or None, optional
135 135 If unspecified or None, IPython will parse command-line options from sys.argv.
136 136 To prevent any command-line parsing, pass an empty list: `argv=[]`.
137 137 user_ns : dict, optional
138 138 specify this dictionary to initialize the IPython user namespace with particular values.
139 139 kwargs : various, optional
140 140 Any other kwargs will be passed to the Application constructor,
141 141 such as `config`.
142 142 """
143 143 from IPython.kernel.zmq.kernelapp import launch_new_instance
144 144 return launch_new_instance(argv=argv, **kwargs)
145 145
@@ -1,967 +1,967 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Top-level display functions for displaying object in different formats."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 from __future__ import print_function
8 8
9 9 import json
10 10 import mimetypes
11 11 import os
12 12 import struct
13 13 import warnings
14 14
15 15 from IPython.core.formatters import _safe_get_formatter_method
16 16 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
17 17 unicode_type)
18 18 from IPython.testing.skipdoctest import skip_doctest
19 19
20 20 __all__ = ['display', 'display_pretty', 'display_html', 'display_markdown',
21 21 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json',
22 22 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject',
23 23 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'JSON', 'Javascript',
24 24 'Image', 'clear_output', 'set_matplotlib_formats', 'set_matplotlib_close',
25 25 'publish_display_data']
26 26
27 27 #-----------------------------------------------------------------------------
28 28 # utility functions
29 29 #-----------------------------------------------------------------------------
30 30
31 31 def _safe_exists(path):
32 32 """Check path, but don't let exceptions raise"""
33 33 try:
34 34 return os.path.exists(path)
35 35 except Exception:
36 36 return False
37 37
38 38 def _merge(d1, d2):
39 39 """Like update, but merges sub-dicts instead of clobbering at the top level.
40 40
41 41 Updates d1 in-place
42 42 """
43 43
44 44 if not isinstance(d2, dict) or not isinstance(d1, dict):
45 45 return d2
46 46 for key, value in d2.items():
47 47 d1[key] = _merge(d1.get(key), value)
48 48 return d1
49 49
50 50 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
51 51 """internal implementation of all display_foo methods
52 52
53 53 Parameters
54 54 ----------
55 55 mimetype : str
56 56 The mimetype to be published (e.g. 'image/png')
57 57 objs : tuple of objects
58 58 The Python objects to display, or if raw=True raw text data to
59 59 display.
60 60 raw : bool
61 61 Are the data objects raw data or Python objects that need to be
62 62 formatted before display? [default: False]
63 63 metadata : dict (optional)
64 64 Metadata to be associated with the specific mimetype output.
65 65 """
66 66 if metadata:
67 67 metadata = {mimetype: metadata}
68 68 if raw:
69 69 # turn list of pngdata into list of { 'image/png': pngdata }
70 70 objs = [ {mimetype: obj} for obj in objs ]
71 71 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
72 72
73 73 #-----------------------------------------------------------------------------
74 74 # Main functions
75 75 #-----------------------------------------------------------------------------
76 76
77 77 def publish_display_data(data, metadata=None, source=None):
78 78 """Publish data and metadata to all frontends.
79 79
80 80 See the ``display_data`` message in the messaging documentation for
81 81 more details about this message type.
82 82
83 83 The following MIME types are currently implemented:
84 84
85 85 * text/plain
86 86 * text/html
87 87 * text/markdown
88 88 * text/latex
89 89 * application/json
90 90 * application/javascript
91 91 * image/png
92 92 * image/jpeg
93 93 * image/svg+xml
94 94
95 95 Parameters
96 96 ----------
97 97 data : dict
98 98 A dictionary having keys that are valid MIME types (like
99 99 'text/plain' or 'image/svg+xml') and values that are the data for
100 100 that MIME type. The data itself must be a JSON'able data
101 101 structure. Minimally all data should have the 'text/plain' data,
102 102 which can be displayed by all frontends. If more than the plain
103 103 text is given, it is up to the frontend to decide which
104 104 representation to use.
105 105 metadata : dict
106 106 A dictionary for metadata related to the data. This can contain
107 107 arbitrary key, value pairs that frontends can use to interpret
108 108 the data. mime-type keys matching those in data can be used
109 109 to specify metadata about particular representations.
110 110 source : str, deprecated
111 111 Unused.
112 112 """
113 113 from IPython.core.interactiveshell import InteractiveShell
114 114 InteractiveShell.instance().display_pub.publish(
115 115 data=data,
116 116 metadata=metadata,
117 117 )
118 118
119 119 def display(*objs, **kwargs):
120 120 """Display a Python object in all frontends.
121 121
122 122 By default all representations will be computed and sent to the frontends.
123 123 Frontends can decide which representation is used and how.
124 124
125 125 Parameters
126 126 ----------
127 127 objs : tuple of objects
128 128 The Python objects to display.
129 129 raw : bool, optional
130 130 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
131 131 or Python objects that need to be formatted before display? [default: False]
132 132 include : list or tuple, optional
133 133 A list of format type strings (MIME types) to include in the
134 134 format data dict. If this is set *only* the format types included
135 135 in this list will be computed.
136 136 exclude : list or tuple, optional
137 137 A list of format type strings (MIME types) to exclude in the format
138 138 data dict. If this is set all format types will be computed,
139 139 except for those included in this argument.
140 140 metadata : dict, optional
141 141 A dictionary of metadata to associate with the output.
142 142 mime-type keys in this dictionary will be associated with the individual
143 143 representation formats, if they exist.
144 144 """
145 145 raw = kwargs.get('raw', False)
146 146 include = kwargs.get('include')
147 147 exclude = kwargs.get('exclude')
148 148 metadata = kwargs.get('metadata')
149 149
150 150 from IPython.core.interactiveshell import InteractiveShell
151 151
152 152 if not raw:
153 153 format = InteractiveShell.instance().display_formatter.format
154 154
155 155 for obj in objs:
156 156 if raw:
157 157 publish_display_data(data=obj, metadata=metadata)
158 158 else:
159 159 format_dict, md_dict = format(obj, include=include, exclude=exclude)
160 160 if not format_dict:
161 161 # nothing to display (e.g. _ipython_display_ took over)
162 162 continue
163 163 if metadata:
164 164 # kwarg-specified metadata gets precedence
165 165 _merge(md_dict, metadata)
166 166 publish_display_data(data=format_dict, metadata=md_dict)
167 167
168 168
169 169 def display_pretty(*objs, **kwargs):
170 170 """Display the pretty (default) representation of an object.
171 171
172 172 Parameters
173 173 ----------
174 174 objs : tuple of objects
175 175 The Python objects to display, or if raw=True raw text data to
176 176 display.
177 177 raw : bool
178 178 Are the data objects raw data or Python objects that need to be
179 179 formatted before display? [default: False]
180 180 metadata : dict (optional)
181 181 Metadata to be associated with the specific mimetype output.
182 182 """
183 183 _display_mimetype('text/plain', objs, **kwargs)
184 184
185 185
186 186 def display_html(*objs, **kwargs):
187 187 """Display the HTML representation of an object.
188 188
189 189 Parameters
190 190 ----------
191 191 objs : tuple of objects
192 192 The Python objects to display, or if raw=True raw HTML data to
193 193 display.
194 194 raw : bool
195 195 Are the data objects raw data or Python objects that need to be
196 196 formatted before display? [default: False]
197 197 metadata : dict (optional)
198 198 Metadata to be associated with the specific mimetype output.
199 199 """
200 200 _display_mimetype('text/html', objs, **kwargs)
201 201
202 202
203 203 def display_markdown(*objs, **kwargs):
204 204 """Displays the Markdown representation of an object.
205 205
206 206 Parameters
207 207 ----------
208 208 objs : tuple of objects
209 209 The Python objects to display, or if raw=True raw markdown data to
210 210 display.
211 211 raw : bool
212 212 Are the data objects raw data or Python objects that need to be
213 213 formatted before display? [default: False]
214 214 metadata : dict (optional)
215 215 Metadata to be associated with the specific mimetype output.
216 216 """
217 217
218 218 _display_mimetype('text/markdown', objs, **kwargs)
219 219
220 220
221 221 def display_svg(*objs, **kwargs):
222 222 """Display the SVG representation of an object.
223 223
224 224 Parameters
225 225 ----------
226 226 objs : tuple of objects
227 227 The Python objects to display, or if raw=True raw svg data to
228 228 display.
229 229 raw : bool
230 230 Are the data objects raw data or Python objects that need to be
231 231 formatted before display? [default: False]
232 232 metadata : dict (optional)
233 233 Metadata to be associated with the specific mimetype output.
234 234 """
235 235 _display_mimetype('image/svg+xml', objs, **kwargs)
236 236
237 237
238 238 def display_png(*objs, **kwargs):
239 239 """Display the PNG representation of an object.
240 240
241 241 Parameters
242 242 ----------
243 243 objs : tuple of objects
244 244 The Python objects to display, or if raw=True raw png data to
245 245 display.
246 246 raw : bool
247 247 Are the data objects raw data or Python objects that need to be
248 248 formatted before display? [default: False]
249 249 metadata : dict (optional)
250 250 Metadata to be associated with the specific mimetype output.
251 251 """
252 252 _display_mimetype('image/png', objs, **kwargs)
253 253
254 254
255 255 def display_jpeg(*objs, **kwargs):
256 256 """Display the JPEG representation of an object.
257 257
258 258 Parameters
259 259 ----------
260 260 objs : tuple of objects
261 261 The Python objects to display, or if raw=True raw JPEG data to
262 262 display.
263 263 raw : bool
264 264 Are the data objects raw data or Python objects that need to be
265 265 formatted before display? [default: False]
266 266 metadata : dict (optional)
267 267 Metadata to be associated with the specific mimetype output.
268 268 """
269 269 _display_mimetype('image/jpeg', objs, **kwargs)
270 270
271 271
272 272 def display_latex(*objs, **kwargs):
273 273 """Display the LaTeX representation of an object.
274 274
275 275 Parameters
276 276 ----------
277 277 objs : tuple of objects
278 278 The Python objects to display, or if raw=True raw latex data to
279 279 display.
280 280 raw : bool
281 281 Are the data objects raw data or Python objects that need to be
282 282 formatted before display? [default: False]
283 283 metadata : dict (optional)
284 284 Metadata to be associated with the specific mimetype output.
285 285 """
286 286 _display_mimetype('text/latex', objs, **kwargs)
287 287
288 288
289 289 def display_json(*objs, **kwargs):
290 290 """Display the JSON representation of an object.
291 291
292 292 Note that not many frontends support displaying JSON.
293 293
294 294 Parameters
295 295 ----------
296 296 objs : tuple of objects
297 297 The Python objects to display, or if raw=True raw json data to
298 298 display.
299 299 raw : bool
300 300 Are the data objects raw data or Python objects that need to be
301 301 formatted before display? [default: False]
302 302 metadata : dict (optional)
303 303 Metadata to be associated with the specific mimetype output.
304 304 """
305 305 _display_mimetype('application/json', objs, **kwargs)
306 306
307 307
308 308 def display_javascript(*objs, **kwargs):
309 309 """Display the Javascript representation of an object.
310 310
311 311 Parameters
312 312 ----------
313 313 objs : tuple of objects
314 314 The Python objects to display, or if raw=True raw javascript data to
315 315 display.
316 316 raw : bool
317 317 Are the data objects raw data or Python objects that need to be
318 318 formatted before display? [default: False]
319 319 metadata : dict (optional)
320 320 Metadata to be associated with the specific mimetype output.
321 321 """
322 322 _display_mimetype('application/javascript', objs, **kwargs)
323 323
324 324
325 325 def display_pdf(*objs, **kwargs):
326 326 """Display the PDF representation of an object.
327 327
328 328 Parameters
329 329 ----------
330 330 objs : tuple of objects
331 331 The Python objects to display, or if raw=True raw javascript data to
332 332 display.
333 333 raw : bool
334 334 Are the data objects raw data or Python objects that need to be
335 335 formatted before display? [default: False]
336 336 metadata : dict (optional)
337 337 Metadata to be associated with the specific mimetype output.
338 338 """
339 339 _display_mimetype('application/pdf', objs, **kwargs)
340 340
341 341
342 342 #-----------------------------------------------------------------------------
343 343 # Smart classes
344 344 #-----------------------------------------------------------------------------
345 345
346 346
347 347 class DisplayObject(object):
348 348 """An object that wraps data to be displayed."""
349 349
350 350 _read_flags = 'r'
351 351 _show_mem_addr = False
352 352
353 353 def __init__(self, data=None, url=None, filename=None):
354 354 """Create a display object given raw data.
355 355
356 356 When this object is returned by an expression or passed to the
357 357 display function, it will result in the data being displayed
358 358 in the frontend. The MIME type of the data should match the
359 359 subclasses used, so the Png subclass should be used for 'image/png'
360 360 data. If the data is a URL, the data will first be downloaded
361 361 and then displayed. If
362 362
363 363 Parameters
364 364 ----------
365 365 data : unicode, str or bytes
366 366 The raw data or a URL or file to load the data from
367 367 url : unicode
368 368 A URL to download the data from.
369 369 filename : unicode
370 370 Path to a local file to load the data from.
371 371 """
372 372 if data is not None and isinstance(data, string_types):
373 373 if data.startswith('http') and url is None:
374 374 url = data
375 375 filename = None
376 376 data = None
377 377 elif _safe_exists(data) and filename is None:
378 378 url = None
379 379 filename = data
380 380 data = None
381 381
382 382 self.data = data
383 383 self.url = url
384 384 self.filename = None if filename is None else unicode_type(filename)
385 385
386 386 self.reload()
387 387 self._check_data()
388 388
389 389 def __repr__(self):
390 390 if not self._show_mem_addr:
391 391 cls = self.__class__
392 392 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
393 393 else:
394 394 r = super(DisplayObject, self).__repr__()
395 395 return r
396 396
397 397 def _check_data(self):
398 398 """Override in subclasses if there's something to check."""
399 399 pass
400 400
401 401 def reload(self):
402 402 """Reload the raw data from file or URL."""
403 403 if self.filename is not None:
404 404 with open(self.filename, self._read_flags) as f:
405 405 self.data = f.read()
406 406 elif self.url is not None:
407 407 try:
408 408 try:
409 409 from urllib.request import urlopen # Py3
410 410 except ImportError:
411 411 from urllib2 import urlopen
412 412 response = urlopen(self.url)
413 413 self.data = response.read()
414 414 # extract encoding from header, if there is one:
415 415 encoding = None
416 416 for sub in response.headers['content-type'].split(';'):
417 417 sub = sub.strip()
418 418 if sub.startswith('charset'):
419 419 encoding = sub.split('=')[-1].strip()
420 420 break
421 421 # decode data, if an encoding was specified
422 422 if encoding:
423 423 self.data = self.data.decode(encoding, 'replace')
424 424 except:
425 425 self.data = None
426 426
427 427 class TextDisplayObject(DisplayObject):
428 428 """Validate that display data is text"""
429 429 def _check_data(self):
430 430 if self.data is not None and not isinstance(self.data, string_types):
431 431 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
432 432
433 433 class Pretty(TextDisplayObject):
434 434
435 435 def _repr_pretty_(self):
436 436 return self.data
437 437
438 438
439 439 class HTML(TextDisplayObject):
440 440
441 441 def _repr_html_(self):
442 442 return self.data
443 443
444 444 def __html__(self):
445 445 """
446 446 This method exists to inform other HTML-using modules (e.g. Markupsafe,
447 447 htmltag, etc) that this object is HTML and does not need things like
448 448 special characters (<>&) escaped.
449 449 """
450 450 return self._repr_html_()
451 451
452 452
453 453 class Markdown(TextDisplayObject):
454 454
455 455 def _repr_markdown_(self):
456 456 return self.data
457 457
458 458
459 459 class Math(TextDisplayObject):
460 460
461 461 def _repr_latex_(self):
462 462 s = self.data.strip('$')
463 463 return "$$%s$$" % s
464 464
465 465
466 466 class Latex(TextDisplayObject):
467 467
468 468 def _repr_latex_(self):
469 469 return self.data
470 470
471 471
472 472 class SVG(DisplayObject):
473 473
474 474 # wrap data in a property, which extracts the <svg> tag, discarding
475 475 # document headers
476 476 _data = None
477 477
478 478 @property
479 479 def data(self):
480 480 return self._data
481 481
482 482 @data.setter
483 483 def data(self, svg):
484 484 if svg is None:
485 485 self._data = None
486 486 return
487 487 # parse into dom object
488 488 from xml.dom import minidom
489 489 svg = cast_bytes_py2(svg)
490 490 x = minidom.parseString(svg)
491 491 # get svg tag (should be 1)
492 492 found_svg = x.getElementsByTagName('svg')
493 493 if found_svg:
494 494 svg = found_svg[0].toxml()
495 495 else:
496 496 # fallback on the input, trust the user
497 497 # but this is probably an error.
498 498 pass
499 499 svg = cast_unicode(svg)
500 500 self._data = svg
501 501
502 502 def _repr_svg_(self):
503 503 return self.data
504 504
505 505
506 506 class JSON(DisplayObject):
507 507 """JSON expects a JSON-able dict or list
508 508
509 509 not an already-serialized JSON string.
510 510
511 511 Scalar types (None, number, string) are not allowed, only dict or list containers.
512 512 """
513 513 # wrap data in a property, which warns about passing already-serialized JSON
514 514 _data = None
515 515 def _check_data(self):
516 516 if self.data is not None and not isinstance(self.data, (dict, list)):
517 517 raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data))
518 518
519 519 @property
520 520 def data(self):
521 521 return self._data
522 522
523 523 @data.setter
524 524 def data(self, data):
525 525 if isinstance(data, string_types):
526 526 warnings.warn("JSON expects JSONable dict or list, not JSON strings")
527 527 data = json.loads(data)
528 528 self._data = data
529 529
530 530 def _repr_json_(self):
531 531 return self.data
532 532
533 533 css_t = """$("head").append($("<link/>").attr({
534 534 rel: "stylesheet",
535 535 type: "text/css",
536 536 href: "%s"
537 537 }));
538 538 """
539 539
540 540 lib_t1 = """$.getScript("%s", function () {
541 541 """
542 542 lib_t2 = """});
543 543 """
544 544
545 545 class Javascript(TextDisplayObject):
546 546
547 547 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
548 548 """Create a Javascript display object given raw data.
549 549
550 550 When this object is returned by an expression or passed to the
551 551 display function, it will result in the data being displayed
552 552 in the frontend. If the data is a URL, the data will first be
553 553 downloaded and then displayed.
554 554
555 555 In the Notebook, the containing element will be available as `element`,
556 556 and jQuery will be available. Content appended to `element` will be
557 557 visible in the output area.
558 558
559 559 Parameters
560 560 ----------
561 561 data : unicode, str or bytes
562 562 The Javascript source code or a URL to download it from.
563 563 url : unicode
564 564 A URL to download the data from.
565 565 filename : unicode
566 566 Path to a local file to load the data from.
567 567 lib : list or str
568 568 A sequence of Javascript library URLs to load asynchronously before
569 569 running the source code. The full URLs of the libraries should
570 570 be given. A single Javascript library URL can also be given as a
571 571 string.
572 572 css: : list or str
573 573 A sequence of css files to load before running the source code.
574 574 The full URLs of the css files should be given. A single css URL
575 575 can also be given as a string.
576 576 """
577 577 if isinstance(lib, string_types):
578 578 lib = [lib]
579 579 elif lib is None:
580 580 lib = []
581 581 if isinstance(css, string_types):
582 582 css = [css]
583 583 elif css is None:
584 584 css = []
585 585 if not isinstance(lib, (list,tuple)):
586 586 raise TypeError('expected sequence, got: %r' % lib)
587 587 if not isinstance(css, (list,tuple)):
588 588 raise TypeError('expected sequence, got: %r' % css)
589 589 self.lib = lib
590 590 self.css = css
591 591 super(Javascript, self).__init__(data=data, url=url, filename=filename)
592 592
593 593 def _repr_javascript_(self):
594 594 r = ''
595 595 for c in self.css:
596 596 r += css_t % c
597 597 for l in self.lib:
598 598 r += lib_t1 % l
599 599 r += self.data
600 600 r += lib_t2*len(self.lib)
601 601 return r
602 602
603 603 # constants for identifying png/jpeg data
604 604 _PNG = b'\x89PNG\r\n\x1a\n'
605 605 _JPEG = b'\xff\xd8'
606 606
607 607 def _pngxy(data):
608 608 """read the (width, height) from a PNG header"""
609 609 ihdr = data.index(b'IHDR')
610 610 # next 8 bytes are width/height
611 611 w4h4 = data[ihdr+4:ihdr+12]
612 612 return struct.unpack('>ii', w4h4)
613 613
614 614 def _jpegxy(data):
615 615 """read the (width, height) from a JPEG header"""
616 616 # adapted from http://www.64lines.com/jpeg-width-height
617 617
618 618 idx = 4
619 619 while True:
620 620 block_size = struct.unpack('>H', data[idx:idx+2])[0]
621 621 idx = idx + block_size
622 622 if data[idx:idx+2] == b'\xFF\xC0':
623 623 # found Start of Frame
624 624 iSOF = idx
625 625 break
626 626 else:
627 627 # read another block
628 628 idx += 2
629 629
630 630 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
631 631 return w, h
632 632
633 633 class Image(DisplayObject):
634 634
635 635 _read_flags = 'rb'
636 636 _FMT_JPEG = u'jpeg'
637 637 _FMT_PNG = u'png'
638 638 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
639 639
640 640 def __init__(self, data=None, url=None, filename=None, format=u'png',
641 641 embed=None, width=None, height=None, retina=False,
642 642 unconfined=False, metadata=None):
643 643 """Create a PNG/JPEG image object given raw data.
644 644
645 645 When this object is returned by an input cell or passed to the
646 646 display function, it will result in the image being displayed
647 647 in the frontend.
648 648
649 649 Parameters
650 650 ----------
651 651 data : unicode, str or bytes
652 652 The raw image data or a URL or filename to load the data from.
653 653 This always results in embedded image data.
654 654 url : unicode
655 655 A URL to download the data from. If you specify `url=`,
656 656 the image data will not be embedded unless you also specify `embed=True`.
657 657 filename : unicode
658 658 Path to a local file to load the data from.
659 659 Images from a file are always embedded.
660 660 format : unicode
661 661 The format of the image data (png/jpeg/jpg). If a filename or URL is given
662 662 for format will be inferred from the filename extension.
663 663 embed : bool
664 664 Should the image data be embedded using a data URI (True) or be
665 665 loaded using an <img> tag. Set this to True if you want the image
666 666 to be viewable later with no internet connection in the notebook.
667 667
668 668 Default is `True`, unless the keyword argument `url` is set, then
669 669 default value is `False`.
670 670
671 671 Note that QtConsole is not able to display images if `embed` is set to `False`
672 672 width : int
673 673 Width to which to constrain the image in html
674 674 height : int
675 675 Height to which to constrain the image in html
676 676 retina : bool
677 677 Automatically set the width and height to half of the measured
678 678 width and height.
679 679 This only works for embedded images because it reads the width/height
680 680 from image data.
681 681 For non-embedded images, you can just set the desired display width
682 682 and height directly.
683 683 unconfined: bool
684 684 Set unconfined=True to disable max-width confinement of the image.
685 685 metadata: dict
686 686 Specify extra metadata to attach to the image.
687 687
688 688 Examples
689 689 --------
690 690 # embedded image data, works in qtconsole and notebook
691 691 # when passed positionally, the first arg can be any of raw image data,
692 692 # a URL, or a filename from which to load image data.
693 693 # The result is always embedding image data for inline images.
694 694 Image('http://www.google.fr/images/srpr/logo3w.png')
695 695 Image('/path/to/image.jpg')
696 696 Image(b'RAW_PNG_DATA...')
697 697
698 698 # Specifying Image(url=...) does not embed the image data,
699 699 # it only generates `<img>` tag with a link to the source.
700 700 # This will not work in the qtconsole or offline.
701 701 Image(url='http://www.google.fr/images/srpr/logo3w.png')
702 702
703 703 """
704 704 if filename is not None:
705 705 ext = self._find_ext(filename)
706 706 elif url is not None:
707 707 ext = self._find_ext(url)
708 708 elif data is None:
709 709 raise ValueError("No image data found. Expecting filename, url, or data.")
710 710 elif isinstance(data, string_types) and (
711 711 data.startswith('http') or _safe_exists(data)
712 712 ):
713 713 ext = self._find_ext(data)
714 714 else:
715 715 ext = None
716 716
717 717 if ext is not None:
718 718 format = ext.lower()
719 719 if ext == u'jpg' or ext == u'jpeg':
720 720 format = self._FMT_JPEG
721 721 if ext == u'png':
722 722 format = self._FMT_PNG
723 723 elif isinstance(data, bytes) and format == 'png':
724 724 # infer image type from image data header,
725 725 # only if format might not have been specified.
726 726 if data[:2] == _JPEG:
727 727 format = 'jpeg'
728 728
729 729 self.format = unicode_type(format).lower()
730 730 self.embed = embed if embed is not None else (url is None)
731 731
732 732 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
733 733 raise ValueError("Cannot embed the '%s' image format" % (self.format))
734 734 self.width = width
735 735 self.height = height
736 736 self.retina = retina
737 737 self.unconfined = unconfined
738 738 self.metadata = metadata
739 739 super(Image, self).__init__(data=data, url=url, filename=filename)
740 740
741 741 if retina:
742 742 self._retina_shape()
743 743
744 744 def _retina_shape(self):
745 745 """load pixel-doubled width and height from image data"""
746 746 if not self.embed:
747 747 return
748 748 if self.format == 'png':
749 749 w, h = _pngxy(self.data)
750 750 elif self.format == 'jpeg':
751 751 w, h = _jpegxy(self.data)
752 752 else:
753 753 # retina only supports png
754 754 return
755 755 self.width = w // 2
756 756 self.height = h // 2
757 757
758 758 def reload(self):
759 759 """Reload the raw data from file or URL."""
760 760 if self.embed:
761 761 super(Image,self).reload()
762 762 if self.retina:
763 763 self._retina_shape()
764 764
765 765 def _repr_html_(self):
766 766 if not self.embed:
767 767 width = height = klass = ''
768 768 if self.width:
769 769 width = ' width="%d"' % self.width
770 770 if self.height:
771 771 height = ' height="%d"' % self.height
772 772 if self.unconfined:
773 773 klass = ' class="unconfined"'
774 774 return u'<img src="{url}"{width}{height}{klass}/>'.format(
775 775 url=self.url,
776 776 width=width,
777 777 height=height,
778 778 klass=klass,
779 779 )
780 780
781 781 def _data_and_metadata(self):
782 782 """shortcut for returning metadata with shape information, if defined"""
783 783 md = {}
784 784 if self.width:
785 785 md['width'] = self.width
786 786 if self.height:
787 787 md['height'] = self.height
788 788 if self.unconfined:
789 789 md['unconfined'] = self.unconfined
790 790 if self.metadata:
791 791 md.update(self.metadata)
792 792 if md:
793 793 return self.data, md
794 794 else:
795 795 return self.data
796 796
797 797 def _repr_png_(self):
798 798 if self.embed and self.format == u'png':
799 799 return self._data_and_metadata()
800 800
801 801 def _repr_jpeg_(self):
802 802 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
803 803 return self._data_and_metadata()
804 804
805 805 def _find_ext(self, s):
806 806 return unicode_type(s.split('.')[-1].lower())
807 807
808 808 class Video(DisplayObject):
809 809
810 810 def __init__(self, data=None, url=None, filename=None, embed=None, mimetype=None):
811 811 """Create a video object given raw data or an URL.
812 812
813 813 When this object is returned by an input cell or passed to the
814 814 display function, it will result in the video being displayed
815 815 in the frontend.
816 816
817 817 Parameters
818 818 ----------
819 819 data : unicode, str or bytes
820 820 The raw image data or a URL or filename to load the data from.
821 821 This always results in embedded image data.
822 822 url : unicode
823 823 A URL to download the data from. If you specify `url=`,
824 824 the image data will not be embedded unless you also specify `embed=True`.
825 825 filename : unicode
826 826 Path to a local file to load the data from.
827 827 Videos from a file are always embedded.
828 828 embed : bool
829 829 Should the image data be embedded using a data URI (True) or be
830 830 loaded using an <img> tag. Set this to True if you want the image
831 831 to be viewable later with no internet connection in the notebook.
832 832
833 833 Default is `True`, unless the keyword argument `url` is set, then
834 834 default value is `False`.
835 835
836 836 Note that QtConsole is not able to display images if `embed` is set to `False`
837 837 mimetype: unicode
838 838 Specify the mimetype in case you load in a encoded video.
839 839 Examples
840 840 --------
841 841 Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4')
842 842 Video('path/to/video.mp4')
843 843 Video('path/to/video.mp4', embed=False)
844 844 """
845 845 if url is None and (data.startswith('http') or data.startswith('https')):
846 846 url = data
847 847 data = None
848 848 embed = False
849 849 elif os.path.exists(data):
850 850 filename = data
851 851 data = None
852 852
853 853 self.mimetype = mimetype
854 854 self.embed = embed if embed is not None else (filename is not None)
855 855 super(Video, self).__init__(data=data, url=url, filename=filename)
856 856
857 857 def _repr_html_(self):
858 858 # External URLs and potentially local files are not embedded into the
859 859 # notebook output.
860 860 if not self.embed:
861 861 url = self.url if self.url is not None else self.filename
862 862 output = """<video src="{0}" controls>
863 863 Your browser does not support the <code>video</code> element.
864 864 </video>""".format(url)
865 865 return output
866 866 # Embedded videos uses base64 encoded videos.
867 867 if self.filename is not None:
868 868 mimetypes.init()
869 869 mimetype, encoding = mimetypes.guess_type(self.filename)
870 870
871 871 video = open(self.filename, 'rb').read()
872 872 video_encoded = video.encode('base64')
873 873 else:
874 874 video_encoded = self.data
875 875 mimetype = self.mimetype
876 876 output = """<video controls>
877 877 <source src="data:{0};base64,{1}" type="{0}">
878 878 Your browser does not support the video tag.
879 879 </video>""".format(mimetype, video_encoded)
880 880 return output
881 881
882 882 def reload(self):
883 883 # TODO
884 884 pass
885 885
886 886 def _repr_png_(self):
887 887 # TODO
888 888 pass
889 889 def _repr_jpeg_(self):
890 890 # TODO
891 891 pass
892 892
893 893 def clear_output(wait=False):
894 894 """Clear the output of the current cell receiving output.
895 895
896 896 Parameters
897 897 ----------
898 898 wait : bool [default: false]
899 899 Wait to clear the output until new output is available to replace it."""
900 900 from IPython.core.interactiveshell import InteractiveShell
901 901 if InteractiveShell.initialized():
902 902 InteractiveShell.instance().display_pub.clear_output(wait)
903 903 else:
904 904 from IPython.utils import io
905 905 print('\033[2K\r', file=io.stdout, end='')
906 906 io.stdout.flush()
907 907 print('\033[2K\r', file=io.stderr, end='')
908 908 io.stderr.flush()
909 909
910 910
911 911 @skip_doctest
912 912 def set_matplotlib_formats(*formats, **kwargs):
913 913 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
914 914
915 915 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
916 916
917 917 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
918 918
919 919 To set this in your config files use the following::
920 920
921 921 c.InlineBackend.figure_formats = {'png', 'jpeg'}
922 922 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
923 923
924 924 Parameters
925 925 ----------
926 926 *formats : strs
927 927 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
928 928 **kwargs :
929 929 Keyword args will be relayed to ``figure.canvas.print_figure``.
930 930 """
931 931 from IPython.core.interactiveshell import InteractiveShell
932 932 from IPython.core.pylabtools import select_figure_formats
933 933 # build kwargs, starting with InlineBackend config
934 934 kw = {}
935 from ipython_kernel.pylab.config import InlineBackend
935 from ipykernel.pylab.config import InlineBackend
936 936 cfg = InlineBackend.instance()
937 937 kw.update(cfg.print_figure_kwargs)
938 938 kw.update(**kwargs)
939 939 shell = InteractiveShell.instance()
940 940 select_figure_formats(shell, formats, **kw)
941 941
942 942 @skip_doctest
943 943 def set_matplotlib_close(close=True):
944 944 """Set whether the inline backend closes all figures automatically or not.
945 945
946 946 By default, the inline backend used in the IPython Notebook will close all
947 947 matplotlib figures automatically after each cell is run. This means that
948 948 plots in different cells won't interfere. Sometimes, you may want to make
949 949 a plot in one cell and then refine it in later cells. This can be accomplished
950 950 by::
951 951
952 952 In [1]: set_matplotlib_close(False)
953 953
954 954 To set this in your config files use the following::
955 955
956 956 c.InlineBackend.close_figures = False
957 957
958 958 Parameters
959 959 ----------
960 960 close : bool
961 961 Should all matplotlib figures be automatically closed after each cell is
962 962 run?
963 963 """
964 from ipython_kernel.pylab.config import InlineBackend
964 from ipykernel.pylab.config import InlineBackend
965 965 cfg = InlineBackend.instance()
966 966 cfg.close_figures = close
967 967
@@ -1,311 +1,311 b''
1 1 # encoding: utf-8
2 2 """
3 3 An application for managing IPython profiles.
4 4
5 5 To be invoked as the `ipython profile` subcommand.
6 6
7 7 Authors:
8 8
9 9 * Min RK
10 10
11 11 """
12 12 from __future__ import print_function
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Copyright (C) 2008 The IPython Development Team
16 16 #
17 17 # Distributed under the terms of the BSD License. The full license is in
18 18 # the file COPYING, distributed as part of this software.
19 19 #-----------------------------------------------------------------------------
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Imports
23 23 #-----------------------------------------------------------------------------
24 24
25 25 import os
26 26
27 27 from traitlets.config.application import Application
28 28 from IPython.core.application import (
29 29 BaseIPythonApplication, base_flags
30 30 )
31 31 from IPython.core.profiledir import ProfileDir
32 32 from IPython.utils.importstring import import_item
33 33 from IPython.paths import get_ipython_dir, get_ipython_package_dir
34 34 from IPython.utils import py3compat
35 35 from traitlets import Unicode, Bool, Dict
36 36
37 37 #-----------------------------------------------------------------------------
38 38 # Constants
39 39 #-----------------------------------------------------------------------------
40 40
41 41 create_help = """Create an IPython profile by name
42 42
43 43 Create an ipython profile directory by its name or
44 44 profile directory path. Profile directories contain
45 45 configuration, log and security related files and are named
46 46 using the convention 'profile_<name>'. By default they are
47 47 located in your ipython directory. Once created, you will
48 48 can edit the configuration files in the profile
49 49 directory to configure IPython. Most users will create a
50 50 profile directory by name,
51 51 `ipython profile create myprofile`, which will put the directory
52 52 in `<ipython_dir>/profile_myprofile`.
53 53 """
54 54 list_help = """List available IPython profiles
55 55
56 56 List all available profiles, by profile location, that can
57 57 be found in the current working directly or in the ipython
58 58 directory. Profile directories are named using the convention
59 59 'profile_<profile>'.
60 60 """
61 61 profile_help = """Manage IPython profiles
62 62
63 63 Profile directories contain
64 64 configuration, log and security related files and are named
65 65 using the convention 'profile_<name>'. By default they are
66 66 located in your ipython directory. You can create profiles
67 67 with `ipython profile create <name>`, or see the profiles you
68 68 already have with `ipython profile list`
69 69
70 70 To get started configuring IPython, simply do:
71 71
72 72 $> ipython profile create
73 73
74 74 and IPython will create the default profile in <ipython_dir>/profile_default,
75 75 where you can edit ipython_config.py to start configuring IPython.
76 76
77 77 """
78 78
79 79 _list_examples = "ipython profile list # list all profiles"
80 80
81 81 _create_examples = """
82 82 ipython profile create foo # create profile foo w/ default config files
83 83 ipython profile create foo --reset # restage default config files over current
84 84 ipython profile create foo --parallel # also stage parallel config files
85 85 """
86 86
87 87 _main_examples = """
88 88 ipython profile create -h # show the help string for the create subcommand
89 89 ipython profile list -h # show the help string for the list subcommand
90 90
91 91 ipython locate profile foo # print the path to the directory for profile 'foo'
92 92 """
93 93
94 94 #-----------------------------------------------------------------------------
95 95 # Profile Application Class (for `ipython profile` subcommand)
96 96 #-----------------------------------------------------------------------------
97 97
98 98
99 99 def list_profiles_in(path):
100 100 """list profiles in a given root directory"""
101 101 files = os.listdir(path)
102 102 profiles = []
103 103 for f in files:
104 104 try:
105 105 full_path = os.path.join(path, f)
106 106 except UnicodeError:
107 107 continue
108 108 if os.path.isdir(full_path) and f.startswith('profile_'):
109 109 profiles.append(f.split('_',1)[-1])
110 110 return profiles
111 111
112 112
113 113 def list_bundled_profiles():
114 114 """list profiles that are bundled with IPython."""
115 115 path = os.path.join(get_ipython_package_dir(), u'core', u'profile')
116 116 files = os.listdir(path)
117 117 profiles = []
118 118 for profile in files:
119 119 full_path = os.path.join(path, profile)
120 120 if os.path.isdir(full_path) and profile != "__pycache__":
121 121 profiles.append(profile)
122 122 return profiles
123 123
124 124
125 125 class ProfileLocate(BaseIPythonApplication):
126 126 description = """print the path to an IPython profile dir"""
127 127
128 128 def parse_command_line(self, argv=None):
129 129 super(ProfileLocate, self).parse_command_line(argv)
130 130 if self.extra_args:
131 131 self.profile = self.extra_args[0]
132 132
133 133 def start(self):
134 134 print(self.profile_dir.location)
135 135
136 136
137 137 class ProfileList(Application):
138 138 name = u'ipython-profile'
139 139 description = list_help
140 140 examples = _list_examples
141 141
142 142 aliases = Dict({
143 143 'ipython-dir' : 'ProfileList.ipython_dir',
144 144 'log-level' : 'Application.log_level',
145 145 })
146 146 flags = Dict(dict(
147 147 debug = ({'Application' : {'log_level' : 0}},
148 148 "Set Application.log_level to 0, maximizing log output."
149 149 )
150 150 ))
151 151
152 152 ipython_dir = Unicode(get_ipython_dir(), config=True,
153 153 help="""
154 154 The name of the IPython directory. This directory is used for logging
155 155 configuration (through profiles), history storage, etc. The default
156 156 is usually $HOME/.ipython. This options can also be specified through
157 157 the environment variable IPYTHONDIR.
158 158 """
159 159 )
160 160
161 161
162 162 def _print_profiles(self, profiles):
163 163 """print list of profiles, indented."""
164 164 for profile in profiles:
165 165 print(' %s' % profile)
166 166
167 167 def list_profile_dirs(self):
168 168 profiles = list_bundled_profiles()
169 169 if profiles:
170 170 print()
171 171 print("Available profiles in IPython:")
172 172 self._print_profiles(profiles)
173 173 print()
174 174 print(" The first request for a bundled profile will copy it")
175 175 print(" into your IPython directory (%s)," % self.ipython_dir)
176 176 print(" where you can customize it.")
177 177
178 178 profiles = list_profiles_in(self.ipython_dir)
179 179 if profiles:
180 180 print()
181 181 print("Available profiles in %s:" % self.ipython_dir)
182 182 self._print_profiles(profiles)
183 183
184 184 profiles = list_profiles_in(py3compat.getcwd())
185 185 if profiles:
186 186 print()
187 187 print("Available profiles in current directory (%s):" % py3compat.getcwd())
188 188 self._print_profiles(profiles)
189 189
190 190 print()
191 191 print("To use any of the above profiles, start IPython with:")
192 192 print(" ipython --profile=<name>")
193 193 print()
194 194
195 195 def start(self):
196 196 self.list_profile_dirs()
197 197
198 198
199 199 create_flags = {}
200 200 create_flags.update(base_flags)
201 201 # don't include '--init' flag, which implies running profile create in other apps
202 202 create_flags.pop('init')
203 203 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
204 204 "reset config files in this profile to the defaults.")
205 205 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
206 206 "Include the config files for parallel "
207 207 "computing apps (ipengine, ipcontroller, etc.)")
208 208
209 209
210 210 class ProfileCreate(BaseIPythonApplication):
211 211 name = u'ipython-profile'
212 212 description = create_help
213 213 examples = _create_examples
214 214 auto_create = Bool(True, config=False)
215 215 def _log_format_default(self):
216 216 return "[%(name)s] %(message)s"
217 217
218 218 def _copy_config_files_default(self):
219 219 return True
220 220
221 221 parallel = Bool(False, config=True,
222 222 help="whether to include parallel computing config files")
223 223 def _parallel_changed(self, name, old, new):
224 224 parallel_files = [ 'ipcontroller_config.py',
225 225 'ipengine_config.py',
226 226 'ipcluster_config.py'
227 227 ]
228 228 if new:
229 229 for cf in parallel_files:
230 230 self.config_files.append(cf)
231 231 else:
232 232 for cf in parallel_files:
233 233 if cf in self.config_files:
234 234 self.config_files.remove(cf)
235 235
236 236 def parse_command_line(self, argv):
237 237 super(ProfileCreate, self).parse_command_line(argv)
238 238 # accept positional arg as profile name
239 239 if self.extra_args:
240 240 self.profile = self.extra_args[0]
241 241
242 242 flags = Dict(create_flags)
243 243
244 244 classes = [ProfileDir]
245 245
246 246 def _import_app(self, app_path):
247 247 """import an app class"""
248 248 app = None
249 249 name = app_path.rsplit('.', 1)[-1]
250 250 try:
251 251 app = import_item(app_path)
252 252 except ImportError:
253 253 self.log.info("Couldn't import %s, config file will be excluded", name)
254 254 except Exception:
255 255 self.log.warn('Unexpected error importing %s', name, exc_info=True)
256 256 return app
257 257
258 258 def init_config_files(self):
259 259 super(ProfileCreate, self).init_config_files()
260 260 # use local imports, since these classes may import from here
261 261 from IPython.terminal.ipapp import TerminalIPythonApp
262 262 apps = [TerminalIPythonApp]
263 263 for app_path in (
264 'ipython_kernel.kernelapp.IPKernelApp',
264 'ipykernel.kernelapp.IPKernelApp',
265 265 ):
266 266 app = self._import_app(app_path)
267 267 if app is not None:
268 268 apps.append(app)
269 269 if self.parallel:
270 270 from ipyparallel.apps.ipcontrollerapp import IPControllerApp
271 271 from ipyparallel.apps.ipengineapp import IPEngineApp
272 272 from ipyparallel.apps.ipclusterapp import IPClusterStart
273 273 apps.extend([
274 274 IPControllerApp,
275 275 IPEngineApp,
276 276 IPClusterStart,
277 277 ])
278 278 for App in apps:
279 279 app = App()
280 280 app.config.update(self.config)
281 281 app.log = self.log
282 282 app.overwrite = self.overwrite
283 283 app.copy_config_files=True
284 284 app.ipython_dir=self.ipython_dir
285 285 app.profile_dir=self.profile_dir
286 286 app.init_config_files()
287 287
288 288 def stage_default_config_file(self):
289 289 pass
290 290
291 291
292 292 class ProfileApp(Application):
293 293 name = u'ipython profile'
294 294 description = profile_help
295 295 examples = _main_examples
296 296
297 297 subcommands = Dict(dict(
298 298 create = (ProfileCreate, ProfileCreate.description.splitlines()[0]),
299 299 list = (ProfileList, ProfileList.description.splitlines()[0]),
300 300 locate = (ProfileLocate, ProfileLocate.description.splitlines()[0]),
301 301 ))
302 302
303 303 def start(self):
304 304 if self.subapp is None:
305 305 print("No subcommand specified. Must specify one of: %s"%(self.subcommands.keys()))
306 306 print()
307 307 self.print_description()
308 308 self.print_subcommands()
309 309 self.exit(1)
310 310 else:
311 311 return self.subapp.start()
@@ -1,369 +1,369 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Pylab (matplotlib) support utilities."""
3 3 from __future__ import print_function
4 4
5 5 # Copyright (c) IPython Development Team.
6 6 # Distributed under the terms of the Modified BSD License.
7 7
8 8 from io import BytesIO
9 9
10 10 from IPython.core.display import _pngxy
11 11 from IPython.utils.decorators import flag_calls
12 12 from IPython.utils import py3compat
13 13
14 14 # If user specifies a GUI, that dictates the backend, otherwise we read the
15 15 # user's mpl default from the mpl rc structure
16 16 backends = {'tk': 'TkAgg',
17 17 'gtk': 'GTKAgg',
18 18 'gtk3': 'GTK3Agg',
19 19 'wx': 'WXAgg',
20 20 'qt': 'Qt4Agg', # qt3 not supported
21 21 'qt4': 'Qt4Agg',
22 22 'qt5': 'Qt5Agg',
23 23 'osx': 'MacOSX',
24 24 'nbagg': 'nbAgg',
25 25 'notebook': 'nbAgg',
26 'inline' : 'module://ipython_kernel.pylab.backend_inline'}
26 'inline' : 'module://ipykernel.pylab.backend_inline'}
27 27
28 28 # We also need a reverse backends2guis mapping that will properly choose which
29 29 # GUI support to activate based on the desired matplotlib backend. For the
30 30 # most part it's just a reverse of the above dict, but we also need to add a
31 31 # few others that map to the same GUI manually:
32 32 backend2gui = dict(zip(backends.values(), backends.keys()))
33 33 # Our tests expect backend2gui to just return 'qt'
34 34 backend2gui['Qt4Agg'] = 'qt'
35 35 # In the reverse mapping, there are a few extra valid matplotlib backends that
36 36 # map to the same GUI support
37 37 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
38 38 backend2gui['GTK3Cairo'] = 'gtk3'
39 39 backend2gui['WX'] = 'wx'
40 40 backend2gui['CocoaAgg'] = 'osx'
41 41
42 42 #-----------------------------------------------------------------------------
43 43 # Matplotlib utilities
44 44 #-----------------------------------------------------------------------------
45 45
46 46
47 47 def getfigs(*fig_nums):
48 48 """Get a list of matplotlib figures by figure numbers.
49 49
50 50 If no arguments are given, all available figures are returned. If the
51 51 argument list contains references to invalid figures, a warning is printed
52 52 but the function continues pasting further figures.
53 53
54 54 Parameters
55 55 ----------
56 56 figs : tuple
57 57 A tuple of ints giving the figure numbers of the figures to return.
58 58 """
59 59 from matplotlib._pylab_helpers import Gcf
60 60 if not fig_nums:
61 61 fig_managers = Gcf.get_all_fig_managers()
62 62 return [fm.canvas.figure for fm in fig_managers]
63 63 else:
64 64 figs = []
65 65 for num in fig_nums:
66 66 f = Gcf.figs.get(num)
67 67 if f is None:
68 68 print('Warning: figure %s not available.' % num)
69 69 else:
70 70 figs.append(f.canvas.figure)
71 71 return figs
72 72
73 73
74 74 def figsize(sizex, sizey):
75 75 """Set the default figure size to be [sizex, sizey].
76 76
77 77 This is just an easy to remember, convenience wrapper that sets::
78 78
79 79 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
80 80 """
81 81 import matplotlib
82 82 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
83 83
84 84
85 85 def print_figure(fig, fmt='png', bbox_inches='tight', **kwargs):
86 86 """Print a figure to an image, and return the resulting file data
87 87
88 88 Returned data will be bytes unless ``fmt='svg'``,
89 89 in which case it will be unicode.
90 90
91 91 Any keyword args are passed to fig.canvas.print_figure,
92 92 such as ``quality`` or ``bbox_inches``.
93 93 """
94 94 from matplotlib import rcParams
95 95 # When there's an empty figure, we shouldn't return anything, otherwise we
96 96 # get big blank areas in the qt console.
97 97 if not fig.axes and not fig.lines:
98 98 return
99 99
100 100 dpi = rcParams['savefig.dpi']
101 101 if fmt == 'retina':
102 102 dpi = dpi * 2
103 103 fmt = 'png'
104 104
105 105 # build keyword args
106 106 kw = dict(
107 107 format=fmt,
108 108 facecolor=fig.get_facecolor(),
109 109 edgecolor=fig.get_edgecolor(),
110 110 dpi=dpi,
111 111 bbox_inches=bbox_inches,
112 112 )
113 113 # **kwargs get higher priority
114 114 kw.update(kwargs)
115 115
116 116 bytes_io = BytesIO()
117 117 fig.canvas.print_figure(bytes_io, **kw)
118 118 data = bytes_io.getvalue()
119 119 if fmt == 'svg':
120 120 data = data.decode('utf-8')
121 121 return data
122 122
123 123 def retina_figure(fig, **kwargs):
124 124 """format a figure as a pixel-doubled (retina) PNG"""
125 125 pngdata = print_figure(fig, fmt='retina', **kwargs)
126 126 w, h = _pngxy(pngdata)
127 127 metadata = dict(width=w//2, height=h//2)
128 128 return pngdata, metadata
129 129
130 130 # We need a little factory function here to create the closure where
131 131 # safe_execfile can live.
132 132 def mpl_runner(safe_execfile):
133 133 """Factory to return a matplotlib-enabled runner for %run.
134 134
135 135 Parameters
136 136 ----------
137 137 safe_execfile : function
138 138 This must be a function with the same interface as the
139 139 :meth:`safe_execfile` method of IPython.
140 140
141 141 Returns
142 142 -------
143 143 A function suitable for use as the ``runner`` argument of the %run magic
144 144 function.
145 145 """
146 146
147 147 def mpl_execfile(fname,*where,**kw):
148 148 """matplotlib-aware wrapper around safe_execfile.
149 149
150 150 Its interface is identical to that of the :func:`execfile` builtin.
151 151
152 152 This is ultimately a call to execfile(), but wrapped in safeties to
153 153 properly handle interactive rendering."""
154 154
155 155 import matplotlib
156 156 import matplotlib.pylab as pylab
157 157
158 158 #print '*** Matplotlib runner ***' # dbg
159 159 # turn off rendering until end of script
160 160 is_interactive = matplotlib.rcParams['interactive']
161 161 matplotlib.interactive(False)
162 162 safe_execfile(fname,*where,**kw)
163 163 matplotlib.interactive(is_interactive)
164 164 # make rendering call now, if the user tried to do it
165 165 if pylab.draw_if_interactive.called:
166 166 pylab.draw()
167 167 pylab.draw_if_interactive.called = False
168 168
169 169 return mpl_execfile
170 170
171 171
172 172 def select_figure_formats(shell, formats, **kwargs):
173 173 """Select figure formats for the inline backend.
174 174
175 175 Parameters
176 176 ==========
177 177 shell : InteractiveShell
178 178 The main IPython instance.
179 179 formats : str or set
180 180 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
181 181 **kwargs : any
182 182 Extra keyword arguments to be passed to fig.canvas.print_figure.
183 183 """
184 184 from matplotlib.figure import Figure
185 from ipython_kernel.pylab import backend_inline
185 from ipykernel.pylab import backend_inline
186 186
187 187 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
188 188 png_formatter = shell.display_formatter.formatters['image/png']
189 189 jpg_formatter = shell.display_formatter.formatters['image/jpeg']
190 190 pdf_formatter = shell.display_formatter.formatters['application/pdf']
191 191
192 192 if isinstance(formats, py3compat.string_types):
193 193 formats = {formats}
194 194 # cast in case of list / tuple
195 195 formats = set(formats)
196 196
197 197 [ f.pop(Figure, None) for f in shell.display_formatter.formatters.values() ]
198 198
199 199 supported = {'png', 'png2x', 'retina', 'jpg', 'jpeg', 'svg', 'pdf'}
200 200 bad = formats.difference(supported)
201 201 if bad:
202 202 bs = "%s" % ','.join([repr(f) for f in bad])
203 203 gs = "%s" % ','.join([repr(f) for f in supported])
204 204 raise ValueError("supported formats are: %s not %s" % (gs, bs))
205 205
206 206 if 'png' in formats:
207 207 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
208 208 if 'retina' in formats or 'png2x' in formats:
209 209 png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))
210 210 if 'jpg' in formats or 'jpeg' in formats:
211 211 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', **kwargs))
212 212 if 'svg' in formats:
213 213 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg', **kwargs))
214 214 if 'pdf' in formats:
215 215 pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf', **kwargs))
216 216
217 217 #-----------------------------------------------------------------------------
218 218 # Code for initializing matplotlib and importing pylab
219 219 #-----------------------------------------------------------------------------
220 220
221 221
222 222 def find_gui_and_backend(gui=None, gui_select=None):
223 223 """Given a gui string return the gui and mpl backend.
224 224
225 225 Parameters
226 226 ----------
227 227 gui : str
228 228 Can be one of ('tk','gtk','wx','qt','qt4','inline').
229 229 gui_select : str
230 230 Can be one of ('tk','gtk','wx','qt','qt4','inline').
231 231 This is any gui already selected by the shell.
232 232
233 233 Returns
234 234 -------
235 235 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
236 'WXAgg','Qt4Agg','module://ipython_kernel.pylab.backend_inline').
236 'WXAgg','Qt4Agg','module://ipykernel.pylab.backend_inline').
237 237 """
238 238
239 239 import matplotlib
240 240
241 241 if gui and gui != 'auto':
242 242 # select backend based on requested gui
243 243 backend = backends[gui]
244 244 else:
245 245 # We need to read the backend from the original data structure, *not*
246 246 # from mpl.rcParams, since a prior invocation of %matplotlib may have
247 247 # overwritten that.
248 248 # WARNING: this assumes matplotlib 1.1 or newer!!
249 249 backend = matplotlib.rcParamsOrig['backend']
250 250 # In this case, we need to find what the appropriate gui selection call
251 251 # should be for IPython, so we can activate inputhook accordingly
252 252 gui = backend2gui.get(backend, None)
253 253
254 254 # If we have already had a gui active, we need it and inline are the
255 255 # ones allowed.
256 256 if gui_select and gui != gui_select:
257 257 gui = gui_select
258 258 backend = backends[gui]
259 259
260 260 return gui, backend
261 261
262 262
263 263 def activate_matplotlib(backend):
264 264 """Activate the given backend and set interactive to True."""
265 265
266 266 import matplotlib
267 267 matplotlib.interactive(True)
268 268
269 269 # Matplotlib had a bug where even switch_backend could not force
270 270 # the rcParam to update. This needs to be set *before* the module
271 271 # magic of switch_backend().
272 272 matplotlib.rcParams['backend'] = backend
273 273
274 274 import matplotlib.pyplot
275 275 matplotlib.pyplot.switch_backend(backend)
276 276
277 277 # This must be imported last in the matplotlib series, after
278 278 # backend/interactivity choices have been made
279 279 import matplotlib.pylab as pylab
280 280
281 281 pylab.show._needmain = False
282 282 # We need to detect at runtime whether show() is called by the user.
283 283 # For this, we wrap it into a decorator which adds a 'called' flag.
284 284 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
285 285
286 286
287 287 def import_pylab(user_ns, import_all=True):
288 288 """Populate the namespace with pylab-related values.
289 289
290 290 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
291 291
292 292 Also imports a few names from IPython (figsize, display, getfigs)
293 293
294 294 """
295 295
296 296 # Import numpy as np/pyplot as plt are conventions we're trying to
297 297 # somewhat standardize on. Making them available to users by default
298 298 # will greatly help this.
299 299 s = ("import numpy\n"
300 300 "import matplotlib\n"
301 301 "from matplotlib import pylab, mlab, pyplot\n"
302 302 "np = numpy\n"
303 303 "plt = pyplot\n"
304 304 )
305 305 exec(s, user_ns)
306 306
307 307 if import_all:
308 308 s = ("from matplotlib.pylab import *\n"
309 309 "from numpy import *\n")
310 310 exec(s, user_ns)
311 311
312 312 # IPython symbols to add
313 313 user_ns['figsize'] = figsize
314 314 from IPython.core.display import display
315 315 # Add display and getfigs to the user's namespace
316 316 user_ns['display'] = display
317 317 user_ns['getfigs'] = getfigs
318 318
319 319
320 320 def configure_inline_support(shell, backend):
321 321 """Configure an IPython shell object for matplotlib use.
322 322
323 323 Parameters
324 324 ----------
325 325 shell : InteractiveShell instance
326 326
327 327 backend : matplotlib backend
328 328 """
329 329 # If using our svg payload backend, register the post-execution
330 330 # function that will pick up the results for display. This can only be
331 331 # done with access to the real shell object.
332 332
333 333 # Note: if we can't load the inline backend, then there's no point
334 334 # continuing (such as in terminal-only shells in environments without
335 335 # zeromq available).
336 336 try:
337 from ipython_kernel.pylab.backend_inline import InlineBackend
337 from ipykernel.pylab.backend_inline import InlineBackend
338 338 except ImportError:
339 339 return
340 340 from matplotlib import pyplot
341 341
342 342 cfg = InlineBackend.instance(parent=shell)
343 343 cfg.shell = shell
344 344 if cfg not in shell.configurables:
345 345 shell.configurables.append(cfg)
346 346
347 347 if backend == backends['inline']:
348 from ipython_kernel.pylab.backend_inline import flush_figures
348 from ipykernel.pylab.backend_inline import flush_figures
349 349 shell.events.register('post_execute', flush_figures)
350 350
351 351 # Save rcParams that will be overwrittern
352 352 shell._saved_rcParams = dict()
353 353 for k in cfg.rc:
354 354 shell._saved_rcParams[k] = pyplot.rcParams[k]
355 355 # load inline_rc
356 356 pyplot.rcParams.update(cfg.rc)
357 357 else:
358 from ipython_kernel.pylab.backend_inline import flush_figures
358 from ipykernel.pylab.backend_inline import flush_figures
359 359 try:
360 360 shell.events.unregister('post_execute', flush_figures)
361 361 except ValueError:
362 362 pass
363 363 if hasattr(shell, '_saved_rcParams'):
364 364 pyplot.rcParams.update(shell._saved_rcParams)
365 365 del shell._saved_rcParams
366 366
367 367 # Setup the default figure format
368 368 select_figure_formats(shell, cfg.figure_formats, **cfg.print_figure_kwargs)
369 369
@@ -1,152 +1,152 b''
1 1 # Copyright (c) IPython Development Team.
2 2 # Distributed under the terms of the Modified BSD License.
3 3
4 4 import json
5 5 import os
6 6 import warnings
7 7
8 8 import nose.tools as nt
9 9
10 10 from IPython.core import display
11 11 from IPython.core.getipython import get_ipython
12 12 from IPython import paths as ipath
13 13
14 14 import IPython.testing.decorators as dec
15 15
16 16 def test_image_size():
17 17 """Simple test for display.Image(args, width=x,height=y)"""
18 18 thisurl = 'http://www.google.fr/images/srpr/logo3w.png'
19 19 img = display.Image(url=thisurl, width=200, height=200)
20 20 nt.assert_equal(u'<img src="%s" width="200" height="200"/>' % (thisurl), img._repr_html_())
21 21 img = display.Image(url=thisurl, width=200)
22 22 nt.assert_equal(u'<img src="%s" width="200"/>' % (thisurl), img._repr_html_())
23 23 img = display.Image(url=thisurl)
24 24 nt.assert_equal(u'<img src="%s"/>' % (thisurl), img._repr_html_())
25 25 img = display.Image(url=thisurl, unconfined=True)
26 26 nt.assert_equal(u'<img src="%s" class="unconfined"/>' % (thisurl), img._repr_html_())
27 27
28 28 def test_retina_png():
29 29 here = os.path.dirname(__file__)
30 30 img = display.Image(os.path.join(here, "2x2.png"), retina=True)
31 31 nt.assert_equal(img.height, 1)
32 32 nt.assert_equal(img.width, 1)
33 33 data, md = img._repr_png_()
34 34 nt.assert_equal(md['width'], 1)
35 35 nt.assert_equal(md['height'], 1)
36 36
37 37 def test_retina_jpeg():
38 38 here = os.path.dirname(__file__)
39 39 img = display.Image(os.path.join(here, "2x2.jpg"), retina=True)
40 40 nt.assert_equal(img.height, 1)
41 41 nt.assert_equal(img.width, 1)
42 42 data, md = img._repr_jpeg_()
43 43 nt.assert_equal(md['width'], 1)
44 44 nt.assert_equal(md['height'], 1)
45 45
46 46 def test_image_filename_defaults():
47 47 '''test format constraint, and validity of jpeg and png'''
48 48 tpath = ipath.get_ipython_package_dir()
49 49 nt.assert_raises(ValueError, display.Image, filename=os.path.join(tpath, 'testing/tests/badformat.gif'),
50 50 embed=True)
51 51 nt.assert_raises(ValueError, display.Image)
52 52 nt.assert_raises(ValueError, display.Image, data='this is not an image', format='badformat', embed=True)
53 53 # check boths paths to allow packages to test at build and install time
54 54 imgfile = os.path.join(tpath, 'core/tests/2x2.png')
55 55 img = display.Image(filename=imgfile)
56 56 nt.assert_equal('png', img.format)
57 57 nt.assert_is_not_none(img._repr_png_())
58 58 img = display.Image(filename=os.path.join(tpath, 'testing/tests/logo.jpg'), embed=False)
59 59 nt.assert_equal('jpeg', img.format)
60 60 nt.assert_is_none(img._repr_jpeg_())
61 61
62 62 def _get_inline_config():
63 from ipython_kernel.pylab.config import InlineBackend
63 from ipykernel.pylab.config import InlineBackend
64 64 return InlineBackend.instance()
65 65
66 66 @dec.skip_without('matplotlib')
67 67 def test_set_matplotlib_close():
68 68 cfg = _get_inline_config()
69 69 cfg.close_figures = False
70 70 display.set_matplotlib_close()
71 71 assert cfg.close_figures
72 72 display.set_matplotlib_close(False)
73 73 assert not cfg.close_figures
74 74
75 75 _fmt_mime_map = {
76 76 'png': 'image/png',
77 77 'jpeg': 'image/jpeg',
78 78 'pdf': 'application/pdf',
79 79 'retina': 'image/png',
80 80 'svg': 'image/svg+xml',
81 81 }
82 82
83 83 @dec.skip_without('matplotlib')
84 84 def test_set_matplotlib_formats():
85 85 from matplotlib.figure import Figure
86 86 formatters = get_ipython().display_formatter.formatters
87 87 for formats in [
88 88 ('png',),
89 89 ('pdf', 'svg'),
90 90 ('jpeg', 'retina', 'png'),
91 91 (),
92 92 ]:
93 93 active_mimes = {_fmt_mime_map[fmt] for fmt in formats}
94 94 display.set_matplotlib_formats(*formats)
95 95 for mime, f in formatters.items():
96 96 if mime in active_mimes:
97 97 nt.assert_in(Figure, f)
98 98 else:
99 99 nt.assert_not_in(Figure, f)
100 100
101 101 @dec.skip_without('matplotlib')
102 102 def test_set_matplotlib_formats_kwargs():
103 103 from matplotlib.figure import Figure
104 104 ip = get_ipython()
105 105 cfg = _get_inline_config()
106 106 cfg.print_figure_kwargs.update(dict(foo='bar'))
107 107 kwargs = dict(quality=10)
108 108 display.set_matplotlib_formats('png', **kwargs)
109 109 formatter = ip.display_formatter.formatters['image/png']
110 110 f = formatter.lookup_by_type(Figure)
111 111 cell = f.__closure__[0].cell_contents
112 112 expected = kwargs
113 113 expected.update(cfg.print_figure_kwargs)
114 114 nt.assert_equal(cell, expected)
115 115
116 116 def test_displayobject_repr():
117 117 h = display.HTML('<br />')
118 118 nt.assert_equal(repr(h), '<IPython.core.display.HTML object>')
119 119 h._show_mem_addr = True
120 120 nt.assert_equal(repr(h), object.__repr__(h))
121 121 h._show_mem_addr = False
122 122 nt.assert_equal(repr(h), '<IPython.core.display.HTML object>')
123 123
124 124 j = display.Javascript('')
125 125 nt.assert_equal(repr(j), '<IPython.core.display.Javascript object>')
126 126 j._show_mem_addr = True
127 127 nt.assert_equal(repr(j), object.__repr__(j))
128 128 j._show_mem_addr = False
129 129 nt.assert_equal(repr(j), '<IPython.core.display.Javascript object>')
130 130
131 131 def test_json():
132 132 d = {'a': 5}
133 133 lis = [d]
134 134 j = display.JSON(d)
135 135 nt.assert_equal(j._repr_json_(), d)
136 136
137 137 with warnings.catch_warnings(record=True) as w:
138 138 warnings.simplefilter("always")
139 139 j = display.JSON(json.dumps(d))
140 140 nt.assert_equal(len(w), 1)
141 141 nt.assert_equal(j._repr_json_(), d)
142 142
143 143 j = display.JSON(lis)
144 144 nt.assert_equal(j._repr_json_(), lis)
145 145
146 146 with warnings.catch_warnings(record=True) as w:
147 147 warnings.simplefilter("always")
148 148 j = display.JSON(json.dumps(lis))
149 149 nt.assert_equal(len(w), 1)
150 150 nt.assert_equal(j._repr_json_(), lis)
151 151
152 152
@@ -1,903 +1,903 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for the key interactiveshell module.
3 3
4 4 Historically the main classes in interactiveshell have been under-tested. This
5 5 module should grow as many single-method tests as possible to trap many of the
6 6 recurring bugs we seem to encounter with high-level interaction.
7 7 """
8 8
9 9 # Copyright (c) IPython Development Team.
10 10 # Distributed under the terms of the Modified BSD License.
11 11
12 12 import ast
13 13 import os
14 14 import signal
15 15 import shutil
16 16 import sys
17 17 import tempfile
18 18 import unittest
19 19 try:
20 20 from unittest import mock
21 21 except ImportError:
22 22 import mock
23 23 from os.path import join
24 24
25 25 import nose.tools as nt
26 26
27 27 from IPython.core.error import InputRejected
28 28 from IPython.core.inputtransformer import InputTransformer
29 29 from IPython.testing.decorators import (
30 30 skipif, skip_win32, onlyif_unicode_paths, onlyif_cmds_exist,
31 31 )
32 32 from IPython.testing import tools as tt
33 33 from IPython.utils import io
34 34 from IPython.utils.process import find_cmd
35 35 from IPython.utils import py3compat
36 36 from IPython.utils.py3compat import unicode_type, PY3
37 37
38 38 if PY3:
39 39 from io import StringIO
40 40 else:
41 41 from StringIO import StringIO
42 42
43 43 #-----------------------------------------------------------------------------
44 44 # Globals
45 45 #-----------------------------------------------------------------------------
46 46 # This is used by every single test, no point repeating it ad nauseam
47 47 ip = get_ipython()
48 48
49 49 #-----------------------------------------------------------------------------
50 50 # Tests
51 51 #-----------------------------------------------------------------------------
52 52
53 53 class DerivedInterrupt(KeyboardInterrupt):
54 54 pass
55 55
56 56 class InteractiveShellTestCase(unittest.TestCase):
57 57 def test_naked_string_cells(self):
58 58 """Test that cells with only naked strings are fully executed"""
59 59 # First, single-line inputs
60 60 ip.run_cell('"a"\n')
61 61 self.assertEqual(ip.user_ns['_'], 'a')
62 62 # And also multi-line cells
63 63 ip.run_cell('"""a\nb"""\n')
64 64 self.assertEqual(ip.user_ns['_'], 'a\nb')
65 65
66 66 def test_run_empty_cell(self):
67 67 """Just make sure we don't get a horrible error with a blank
68 68 cell of input. Yes, I did overlook that."""
69 69 old_xc = ip.execution_count
70 70 res = ip.run_cell('')
71 71 self.assertEqual(ip.execution_count, old_xc)
72 72 self.assertEqual(res.execution_count, None)
73 73
74 74 def test_run_cell_multiline(self):
75 75 """Multi-block, multi-line cells must execute correctly.
76 76 """
77 77 src = '\n'.join(["x=1",
78 78 "y=2",
79 79 "if 1:",
80 80 " x += 1",
81 81 " y += 1",])
82 82 res = ip.run_cell(src)
83 83 self.assertEqual(ip.user_ns['x'], 2)
84 84 self.assertEqual(ip.user_ns['y'], 3)
85 85 self.assertEqual(res.success, True)
86 86 self.assertEqual(res.result, None)
87 87
88 88 def test_multiline_string_cells(self):
89 89 "Code sprinkled with multiline strings should execute (GH-306)"
90 90 ip.run_cell('tmp=0')
91 91 self.assertEqual(ip.user_ns['tmp'], 0)
92 92 res = ip.run_cell('tmp=1;"""a\nb"""\n')
93 93 self.assertEqual(ip.user_ns['tmp'], 1)
94 94 self.assertEqual(res.success, True)
95 95 self.assertEqual(res.result, "a\nb")
96 96
97 97 def test_dont_cache_with_semicolon(self):
98 98 "Ending a line with semicolon should not cache the returned object (GH-307)"
99 99 oldlen = len(ip.user_ns['Out'])
100 100 for cell in ['1;', '1;1;']:
101 101 res = ip.run_cell(cell, store_history=True)
102 102 newlen = len(ip.user_ns['Out'])
103 103 self.assertEqual(oldlen, newlen)
104 104 self.assertIsNone(res.result)
105 105 i = 0
106 106 #also test the default caching behavior
107 107 for cell in ['1', '1;1']:
108 108 ip.run_cell(cell, store_history=True)
109 109 newlen = len(ip.user_ns['Out'])
110 110 i += 1
111 111 self.assertEqual(oldlen+i, newlen)
112 112
113 113 def test_syntax_error(self):
114 114 res = ip.run_cell("raise = 3")
115 115 self.assertIsInstance(res.error_before_exec, SyntaxError)
116 116
117 117 def test_In_variable(self):
118 118 "Verify that In variable grows with user input (GH-284)"
119 119 oldlen = len(ip.user_ns['In'])
120 120 ip.run_cell('1;', store_history=True)
121 121 newlen = len(ip.user_ns['In'])
122 122 self.assertEqual(oldlen+1, newlen)
123 123 self.assertEqual(ip.user_ns['In'][-1],'1;')
124 124
125 125 def test_magic_names_in_string(self):
126 126 ip.run_cell('a = """\n%exit\n"""')
127 127 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
128 128
129 129 def test_trailing_newline(self):
130 130 """test that running !(command) does not raise a SyntaxError"""
131 131 ip.run_cell('!(true)\n', False)
132 132 ip.run_cell('!(true)\n\n\n', False)
133 133
134 134 def test_gh_597(self):
135 135 """Pretty-printing lists of objects with non-ascii reprs may cause
136 136 problems."""
137 137 class Spam(object):
138 138 def __repr__(self):
139 139 return "\xe9"*50
140 140 import IPython.core.formatters
141 141 f = IPython.core.formatters.PlainTextFormatter()
142 142 f([Spam(),Spam()])
143 143
144 144
145 145 def test_future_flags(self):
146 146 """Check that future flags are used for parsing code (gh-777)"""
147 147 ip.run_cell('from __future__ import print_function')
148 148 try:
149 149 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
150 150 assert 'prfunc_return_val' in ip.user_ns
151 151 finally:
152 152 # Reset compiler flags so we don't mess up other tests.
153 153 ip.compile.reset_compiler_flags()
154 154
155 155 def test_future_unicode(self):
156 156 """Check that unicode_literals is imported from __future__ (gh #786)"""
157 157 try:
158 158 ip.run_cell(u'byte_str = "a"')
159 159 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
160 160 ip.run_cell('from __future__ import unicode_literals')
161 161 ip.run_cell(u'unicode_str = "a"')
162 162 assert isinstance(ip.user_ns['unicode_str'], unicode_type) # strings literals are now unicode
163 163 finally:
164 164 # Reset compiler flags so we don't mess up other tests.
165 165 ip.compile.reset_compiler_flags()
166 166
167 167 def test_can_pickle(self):
168 168 "Can we pickle objects defined interactively (GH-29)"
169 169 ip = get_ipython()
170 170 ip.reset()
171 171 ip.run_cell(("class Mylist(list):\n"
172 172 " def __init__(self,x=[]):\n"
173 173 " list.__init__(self,x)"))
174 174 ip.run_cell("w=Mylist([1,2,3])")
175 175
176 176 from pickle import dumps
177 177
178 178 # We need to swap in our main module - this is only necessary
179 179 # inside the test framework, because IPython puts the interactive module
180 180 # in place (but the test framework undoes this).
181 181 _main = sys.modules['__main__']
182 182 sys.modules['__main__'] = ip.user_module
183 183 try:
184 184 res = dumps(ip.user_ns["w"])
185 185 finally:
186 186 sys.modules['__main__'] = _main
187 187 self.assertTrue(isinstance(res, bytes))
188 188
189 189 def test_global_ns(self):
190 190 "Code in functions must be able to access variables outside them."
191 191 ip = get_ipython()
192 192 ip.run_cell("a = 10")
193 193 ip.run_cell(("def f(x):\n"
194 194 " return x + a"))
195 195 ip.run_cell("b = f(12)")
196 196 self.assertEqual(ip.user_ns["b"], 22)
197 197
198 198 def test_bad_custom_tb(self):
199 199 """Check that InteractiveShell is protected from bad custom exception handlers"""
200 200 from IPython.utils import io
201 201 save_stderr = io.stderr
202 202 try:
203 203 # capture stderr
204 204 io.stderr = StringIO()
205 205 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
206 206 self.assertEqual(ip.custom_exceptions, (IOError,))
207 207 ip.run_cell(u'raise IOError("foo")')
208 208 self.assertEqual(ip.custom_exceptions, ())
209 209 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
210 210 finally:
211 211 io.stderr = save_stderr
212 212
213 213 def test_bad_custom_tb_return(self):
214 214 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
215 215 from IPython.utils import io
216 216 save_stderr = io.stderr
217 217 try:
218 218 # capture stderr
219 219 io.stderr = StringIO()
220 220 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
221 221 self.assertEqual(ip.custom_exceptions, (NameError,))
222 222 ip.run_cell(u'a=abracadabra')
223 223 self.assertEqual(ip.custom_exceptions, ())
224 224 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
225 225 finally:
226 226 io.stderr = save_stderr
227 227
228 228 def test_drop_by_id(self):
229 229 myvars = {"a":object(), "b":object(), "c": object()}
230 230 ip.push(myvars, interactive=False)
231 231 for name in myvars:
232 232 assert name in ip.user_ns, name
233 233 assert name in ip.user_ns_hidden, name
234 234 ip.user_ns['b'] = 12
235 235 ip.drop_by_id(myvars)
236 236 for name in ["a", "c"]:
237 237 assert name not in ip.user_ns, name
238 238 assert name not in ip.user_ns_hidden, name
239 239 assert ip.user_ns['b'] == 12
240 240 ip.reset()
241 241
242 242 def test_var_expand(self):
243 243 ip.user_ns['f'] = u'Ca\xf1o'
244 244 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
245 245 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
246 246 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
247 247 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
248 248
249 249 ip.user_ns['f'] = b'Ca\xc3\xb1o'
250 250 # This should not raise any exception:
251 251 ip.var_expand(u'echo $f')
252 252
253 253 def test_var_expand_local(self):
254 254 """Test local variable expansion in !system and %magic calls"""
255 255 # !system
256 256 ip.run_cell('def test():\n'
257 257 ' lvar = "ttt"\n'
258 258 ' ret = !echo {lvar}\n'
259 259 ' return ret[0]\n')
260 260 res = ip.user_ns['test']()
261 261 nt.assert_in('ttt', res)
262 262
263 263 # %magic
264 264 ip.run_cell('def makemacro():\n'
265 265 ' macroname = "macro_var_expand_locals"\n'
266 266 ' %macro {macroname} codestr\n')
267 267 ip.user_ns['codestr'] = "str(12)"
268 268 ip.run_cell('makemacro()')
269 269 nt.assert_in('macro_var_expand_locals', ip.user_ns)
270 270
271 271 def test_var_expand_self(self):
272 272 """Test variable expansion with the name 'self', which was failing.
273 273
274 274 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
275 275 """
276 276 ip.run_cell('class cTest:\n'
277 277 ' classvar="see me"\n'
278 278 ' def test(self):\n'
279 279 ' res = !echo Variable: {self.classvar}\n'
280 280 ' return res[0]\n')
281 281 nt.assert_in('see me', ip.user_ns['cTest']().test())
282 282
283 283 def test_bad_var_expand(self):
284 284 """var_expand on invalid formats shouldn't raise"""
285 285 # SyntaxError
286 286 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
287 287 # NameError
288 288 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
289 289 # ZeroDivisionError
290 290 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
291 291
292 292 def test_silent_postexec(self):
293 293 """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks"""
294 294 pre_explicit = mock.Mock()
295 295 pre_always = mock.Mock()
296 296 post_explicit = mock.Mock()
297 297 post_always = mock.Mock()
298 298
299 299 ip.events.register('pre_run_cell', pre_explicit)
300 300 ip.events.register('pre_execute', pre_always)
301 301 ip.events.register('post_run_cell', post_explicit)
302 302 ip.events.register('post_execute', post_always)
303 303
304 304 try:
305 305 ip.run_cell("1", silent=True)
306 306 assert pre_always.called
307 307 assert not pre_explicit.called
308 308 assert post_always.called
309 309 assert not post_explicit.called
310 310 # double-check that non-silent exec did what we expected
311 311 # silent to avoid
312 312 ip.run_cell("1")
313 313 assert pre_explicit.called
314 314 assert post_explicit.called
315 315 finally:
316 316 # remove post-exec
317 317 ip.events.unregister('pre_run_cell', pre_explicit)
318 318 ip.events.unregister('pre_execute', pre_always)
319 319 ip.events.unregister('post_run_cell', post_explicit)
320 320 ip.events.unregister('post_execute', post_always)
321 321
322 322 def test_silent_noadvance(self):
323 323 """run_cell(silent=True) doesn't advance execution_count"""
324 324 ec = ip.execution_count
325 325 # silent should force store_history=False
326 326 ip.run_cell("1", store_history=True, silent=True)
327 327
328 328 self.assertEqual(ec, ip.execution_count)
329 329 # double-check that non-silent exec did what we expected
330 330 # silent to avoid
331 331 ip.run_cell("1", store_history=True)
332 332 self.assertEqual(ec+1, ip.execution_count)
333 333
334 334 def test_silent_nodisplayhook(self):
335 335 """run_cell(silent=True) doesn't trigger displayhook"""
336 336 d = dict(called=False)
337 337
338 338 trap = ip.display_trap
339 339 save_hook = trap.hook
340 340
341 341 def failing_hook(*args, **kwargs):
342 342 d['called'] = True
343 343
344 344 try:
345 345 trap.hook = failing_hook
346 346 res = ip.run_cell("1", silent=True)
347 347 self.assertFalse(d['called'])
348 348 self.assertIsNone(res.result)
349 349 # double-check that non-silent exec did what we expected
350 350 # silent to avoid
351 351 ip.run_cell("1")
352 352 self.assertTrue(d['called'])
353 353 finally:
354 354 trap.hook = save_hook
355 355
356 356 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
357 357 def test_print_softspace(self):
358 358 """Verify that softspace is handled correctly when executing multiple
359 359 statements.
360 360
361 361 In [1]: print 1; print 2
362 362 1
363 363 2
364 364
365 365 In [2]: print 1,; print 2
366 366 1 2
367 367 """
368 368
369 369 def test_ofind_line_magic(self):
370 370 from IPython.core.magic import register_line_magic
371 371
372 372 @register_line_magic
373 373 def lmagic(line):
374 374 "A line magic"
375 375
376 376 # Get info on line magic
377 377 lfind = ip._ofind('lmagic')
378 378 info = dict(found=True, isalias=False, ismagic=True,
379 379 namespace = 'IPython internal', obj= lmagic.__wrapped__,
380 380 parent = None)
381 381 nt.assert_equal(lfind, info)
382 382
383 383 def test_ofind_cell_magic(self):
384 384 from IPython.core.magic import register_cell_magic
385 385
386 386 @register_cell_magic
387 387 def cmagic(line, cell):
388 388 "A cell magic"
389 389
390 390 # Get info on cell magic
391 391 find = ip._ofind('cmagic')
392 392 info = dict(found=True, isalias=False, ismagic=True,
393 393 namespace = 'IPython internal', obj= cmagic.__wrapped__,
394 394 parent = None)
395 395 nt.assert_equal(find, info)
396 396
397 397 def test_ofind_property_with_error(self):
398 398 class A(object):
399 399 @property
400 400 def foo(self):
401 401 raise NotImplementedError()
402 402 a = A()
403 403
404 404 found = ip._ofind('a.foo', [('locals', locals())])
405 405 info = dict(found=True, isalias=False, ismagic=False,
406 406 namespace='locals', obj=A.foo, parent=a)
407 407 nt.assert_equal(found, info)
408 408
409 409 def test_ofind_multiple_attribute_lookups(self):
410 410 class A(object):
411 411 @property
412 412 def foo(self):
413 413 raise NotImplementedError()
414 414
415 415 a = A()
416 416 a.a = A()
417 417 a.a.a = A()
418 418
419 419 found = ip._ofind('a.a.a.foo', [('locals', locals())])
420 420 info = dict(found=True, isalias=False, ismagic=False,
421 421 namespace='locals', obj=A.foo, parent=a.a.a)
422 422 nt.assert_equal(found, info)
423 423
424 424 def test_ofind_slotted_attributes(self):
425 425 class A(object):
426 426 __slots__ = ['foo']
427 427 def __init__(self):
428 428 self.foo = 'bar'
429 429
430 430 a = A()
431 431 found = ip._ofind('a.foo', [('locals', locals())])
432 432 info = dict(found=True, isalias=False, ismagic=False,
433 433 namespace='locals', obj=a.foo, parent=a)
434 434 nt.assert_equal(found, info)
435 435
436 436 found = ip._ofind('a.bar', [('locals', locals())])
437 437 info = dict(found=False, isalias=False, ismagic=False,
438 438 namespace=None, obj=None, parent=a)
439 439 nt.assert_equal(found, info)
440 440
441 441 def test_ofind_prefers_property_to_instance_level_attribute(self):
442 442 class A(object):
443 443 @property
444 444 def foo(self):
445 445 return 'bar'
446 446 a = A()
447 447 a.__dict__['foo'] = 'baz'
448 448 nt.assert_equal(a.foo, 'bar')
449 449 found = ip._ofind('a.foo', [('locals', locals())])
450 450 nt.assert_is(found['obj'], A.foo)
451 451
452 452 def test_custom_exception(self):
453 453 called = []
454 454 def my_handler(shell, etype, value, tb, tb_offset=None):
455 455 called.append(etype)
456 456 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
457 457
458 458 ip.set_custom_exc((ValueError,), my_handler)
459 459 try:
460 460 res = ip.run_cell("raise ValueError('test')")
461 461 # Check that this was called, and only once.
462 462 self.assertEqual(called, [ValueError])
463 463 # Check that the error is on the result object
464 464 self.assertIsInstance(res.error_in_exec, ValueError)
465 465 finally:
466 466 # Reset the custom exception hook
467 467 ip.set_custom_exc((), None)
468 468
469 469 @skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
470 470 def test_future_environment(self):
471 471 "Can we run code with & without the shell's __future__ imports?"
472 472 ip.run_cell("from __future__ import division")
473 473 ip.run_cell("a = 1/2", shell_futures=True)
474 474 self.assertEqual(ip.user_ns['a'], 0.5)
475 475 ip.run_cell("b = 1/2", shell_futures=False)
476 476 self.assertEqual(ip.user_ns['b'], 0)
477 477
478 478 ip.compile.reset_compiler_flags()
479 479 # This shouldn't leak to the shell's compiler
480 480 ip.run_cell("from __future__ import division \nc=1/2", shell_futures=False)
481 481 self.assertEqual(ip.user_ns['c'], 0.5)
482 482 ip.run_cell("d = 1/2", shell_futures=True)
483 483 self.assertEqual(ip.user_ns['d'], 0)
484 484
485 485 def test_mktempfile(self):
486 486 filename = ip.mktempfile()
487 487 # Check that we can open the file again on Windows
488 488 with open(filename, 'w') as f:
489 489 f.write('abc')
490 490
491 491 filename = ip.mktempfile(data='blah')
492 492 with open(filename, 'r') as f:
493 493 self.assertEqual(f.read(), 'blah')
494 494
495 495 def test_new_main_mod(self):
496 496 # Smoketest to check that this accepts a unicode module name
497 497 name = u'jiefmw'
498 498 mod = ip.new_main_mod(u'%s.py' % name, name)
499 499 self.assertEqual(mod.__name__, name)
500 500
501 501 def test_get_exception_only(self):
502 502 try:
503 503 raise KeyboardInterrupt
504 504 except KeyboardInterrupt:
505 505 msg = ip.get_exception_only()
506 506 self.assertEqual(msg, 'KeyboardInterrupt\n')
507 507
508 508 try:
509 509 raise DerivedInterrupt("foo")
510 510 except KeyboardInterrupt:
511 511 msg = ip.get_exception_only()
512 512 if sys.version_info[0] <= 2:
513 513 self.assertEqual(msg, 'DerivedInterrupt: foo\n')
514 514 else:
515 515 self.assertEqual(msg, 'IPython.core.tests.test_interactiveshell.DerivedInterrupt: foo\n')
516 516
517 517 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
518 518
519 519 @onlyif_unicode_paths
520 520 def setUp(self):
521 521 self.BASETESTDIR = tempfile.mkdtemp()
522 522 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
523 523 os.mkdir(self.TESTDIR)
524 524 with open(join(self.TESTDIR, u"Γ₯Àâtestscript.py"), "w") as sfile:
525 525 sfile.write("pass\n")
526 526 self.oldpath = py3compat.getcwd()
527 527 os.chdir(self.TESTDIR)
528 528 self.fname = u"Γ₯Àâtestscript.py"
529 529
530 530 def tearDown(self):
531 531 os.chdir(self.oldpath)
532 532 shutil.rmtree(self.BASETESTDIR)
533 533
534 534 @onlyif_unicode_paths
535 535 def test_1(self):
536 536 """Test safe_execfile with non-ascii path
537 537 """
538 538 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
539 539
540 540 class ExitCodeChecks(tt.TempFileMixin):
541 541 def test_exit_code_ok(self):
542 542 self.system('exit 0')
543 543 self.assertEqual(ip.user_ns['_exit_code'], 0)
544 544
545 545 def test_exit_code_error(self):
546 546 self.system('exit 1')
547 547 self.assertEqual(ip.user_ns['_exit_code'], 1)
548 548
549 549 @skipif(not hasattr(signal, 'SIGALRM'))
550 550 def test_exit_code_signal(self):
551 551 self.mktmp("import signal, time\n"
552 552 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
553 553 "time.sleep(1)\n")
554 554 self.system("%s %s" % (sys.executable, self.fname))
555 555 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
556 556
557 557 @onlyif_cmds_exist("csh")
558 558 def test_exit_code_signal_csh(self):
559 559 SHELL = os.environ.get('SHELL', None)
560 560 os.environ['SHELL'] = find_cmd("csh")
561 561 try:
562 562 self.test_exit_code_signal()
563 563 finally:
564 564 if SHELL is not None:
565 565 os.environ['SHELL'] = SHELL
566 566 else:
567 567 del os.environ['SHELL']
568 568
569 569 class TestSystemRaw(unittest.TestCase, ExitCodeChecks):
570 570 system = ip.system_raw
571 571
572 572 @onlyif_unicode_paths
573 573 def test_1(self):
574 574 """Test system_raw with non-ascii cmd
575 575 """
576 576 cmd = u'''python -c "'Γ₯Àâ'" '''
577 577 ip.system_raw(cmd)
578 578
579 579 @mock.patch('subprocess.call', side_effect=KeyboardInterrupt)
580 580 @mock.patch('os.system', side_effect=KeyboardInterrupt)
581 581 def test_control_c(self, *mocks):
582 582 try:
583 583 self.system("sleep 1 # wont happen")
584 584 except KeyboardInterrupt:
585 585 self.fail("system call should intercept "
586 586 "keyboard interrupt from subprocess.call")
587 587 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGINT)
588 588
589 589 # TODO: Exit codes are currently ignored on Windows.
590 590 class TestSystemPipedExitCode(unittest.TestCase, ExitCodeChecks):
591 591 system = ip.system_piped
592 592
593 593 @skip_win32
594 594 def test_exit_code_ok(self):
595 595 ExitCodeChecks.test_exit_code_ok(self)
596 596
597 597 @skip_win32
598 598 def test_exit_code_error(self):
599 599 ExitCodeChecks.test_exit_code_error(self)
600 600
601 601 @skip_win32
602 602 def test_exit_code_signal(self):
603 603 ExitCodeChecks.test_exit_code_signal(self)
604 604
605 605 class TestModules(unittest.TestCase, tt.TempFileMixin):
606 606 def test_extraneous_loads(self):
607 607 """Test we're not loading modules on startup that we shouldn't.
608 608 """
609 609 self.mktmp("import sys\n"
610 610 "print('numpy' in sys.modules)\n"
611 611 "print('ipyparallel' in sys.modules)\n"
612 "print('ipython_kernel' in sys.modules)\n"
612 "print('ipykernel' in sys.modules)\n"
613 613 )
614 614 out = "False\nFalse\nFalse\n"
615 615 tt.ipexec_validate(self.fname, out)
616 616
617 617 class Negator(ast.NodeTransformer):
618 618 """Negates all number literals in an AST."""
619 619 def visit_Num(self, node):
620 620 node.n = -node.n
621 621 return node
622 622
623 623 class TestAstTransform(unittest.TestCase):
624 624 def setUp(self):
625 625 self.negator = Negator()
626 626 ip.ast_transformers.append(self.negator)
627 627
628 628 def tearDown(self):
629 629 ip.ast_transformers.remove(self.negator)
630 630
631 631 def test_run_cell(self):
632 632 with tt.AssertPrints('-34'):
633 633 ip.run_cell('print (12 + 22)')
634 634
635 635 # A named reference to a number shouldn't be transformed.
636 636 ip.user_ns['n'] = 55
637 637 with tt.AssertNotPrints('-55'):
638 638 ip.run_cell('print (n)')
639 639
640 640 def test_timeit(self):
641 641 called = set()
642 642 def f(x):
643 643 called.add(x)
644 644 ip.push({'f':f})
645 645
646 646 with tt.AssertPrints("best of "):
647 647 ip.run_line_magic("timeit", "-n1 f(1)")
648 648 self.assertEqual(called, set([-1]))
649 649 called.clear()
650 650
651 651 with tt.AssertPrints("best of "):
652 652 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
653 653 self.assertEqual(called, set([-2, -3]))
654 654
655 655 def test_time(self):
656 656 called = []
657 657 def f(x):
658 658 called.append(x)
659 659 ip.push({'f':f})
660 660
661 661 # Test with an expression
662 662 with tt.AssertPrints("Wall time: "):
663 663 ip.run_line_magic("time", "f(5+9)")
664 664 self.assertEqual(called, [-14])
665 665 called[:] = []
666 666
667 667 # Test with a statement (different code path)
668 668 with tt.AssertPrints("Wall time: "):
669 669 ip.run_line_magic("time", "a = f(-3 + -2)")
670 670 self.assertEqual(called, [5])
671 671
672 672 def test_macro(self):
673 673 ip.push({'a':10})
674 674 # The AST transformation makes this do a+=-1
675 675 ip.define_macro("amacro", "a+=1\nprint(a)")
676 676
677 677 with tt.AssertPrints("9"):
678 678 ip.run_cell("amacro")
679 679 with tt.AssertPrints("8"):
680 680 ip.run_cell("amacro")
681 681
682 682 class IntegerWrapper(ast.NodeTransformer):
683 683 """Wraps all integers in a call to Integer()"""
684 684 def visit_Num(self, node):
685 685 if isinstance(node.n, int):
686 686 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
687 687 args=[node], keywords=[])
688 688 return node
689 689
690 690 class TestAstTransform2(unittest.TestCase):
691 691 def setUp(self):
692 692 self.intwrapper = IntegerWrapper()
693 693 ip.ast_transformers.append(self.intwrapper)
694 694
695 695 self.calls = []
696 696 def Integer(*args):
697 697 self.calls.append(args)
698 698 return args
699 699 ip.push({"Integer": Integer})
700 700
701 701 def tearDown(self):
702 702 ip.ast_transformers.remove(self.intwrapper)
703 703 del ip.user_ns['Integer']
704 704
705 705 def test_run_cell(self):
706 706 ip.run_cell("n = 2")
707 707 self.assertEqual(self.calls, [(2,)])
708 708
709 709 # This shouldn't throw an error
710 710 ip.run_cell("o = 2.0")
711 711 self.assertEqual(ip.user_ns['o'], 2.0)
712 712
713 713 def test_timeit(self):
714 714 called = set()
715 715 def f(x):
716 716 called.add(x)
717 717 ip.push({'f':f})
718 718
719 719 with tt.AssertPrints("best of "):
720 720 ip.run_line_magic("timeit", "-n1 f(1)")
721 721 self.assertEqual(called, set([(1,)]))
722 722 called.clear()
723 723
724 724 with tt.AssertPrints("best of "):
725 725 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
726 726 self.assertEqual(called, set([(2,), (3,)]))
727 727
728 728 class ErrorTransformer(ast.NodeTransformer):
729 729 """Throws an error when it sees a number."""
730 730 def visit_Num(self, node):
731 731 raise ValueError("test")
732 732
733 733 class TestAstTransformError(unittest.TestCase):
734 734 def test_unregistering(self):
735 735 err_transformer = ErrorTransformer()
736 736 ip.ast_transformers.append(err_transformer)
737 737
738 738 with tt.AssertPrints("unregister", channel='stderr'):
739 739 ip.run_cell("1 + 2")
740 740
741 741 # This should have been removed.
742 742 nt.assert_not_in(err_transformer, ip.ast_transformers)
743 743
744 744
745 745 class StringRejector(ast.NodeTransformer):
746 746 """Throws an InputRejected when it sees a string literal.
747 747
748 748 Used to verify that NodeTransformers can signal that a piece of code should
749 749 not be executed by throwing an InputRejected.
750 750 """
751 751
752 752 def visit_Str(self, node):
753 753 raise InputRejected("test")
754 754
755 755
756 756 class TestAstTransformInputRejection(unittest.TestCase):
757 757
758 758 def setUp(self):
759 759 self.transformer = StringRejector()
760 760 ip.ast_transformers.append(self.transformer)
761 761
762 762 def tearDown(self):
763 763 ip.ast_transformers.remove(self.transformer)
764 764
765 765 def test_input_rejection(self):
766 766 """Check that NodeTransformers can reject input."""
767 767
768 768 expect_exception_tb = tt.AssertPrints("InputRejected: test")
769 769 expect_no_cell_output = tt.AssertNotPrints("'unsafe'", suppress=False)
770 770
771 771 # Run the same check twice to verify that the transformer is not
772 772 # disabled after raising.
773 773 with expect_exception_tb, expect_no_cell_output:
774 774 ip.run_cell("'unsafe'")
775 775
776 776 with expect_exception_tb, expect_no_cell_output:
777 777 res = ip.run_cell("'unsafe'")
778 778
779 779 self.assertIsInstance(res.error_before_exec, InputRejected)
780 780
781 781 def test__IPYTHON__():
782 782 # This shouldn't raise a NameError, that's all
783 783 __IPYTHON__
784 784
785 785
786 786 class DummyRepr(object):
787 787 def __repr__(self):
788 788 return "DummyRepr"
789 789
790 790 def _repr_html_(self):
791 791 return "<b>dummy</b>"
792 792
793 793 def _repr_javascript_(self):
794 794 return "console.log('hi');", {'key': 'value'}
795 795
796 796
797 797 def test_user_variables():
798 798 # enable all formatters
799 799 ip.display_formatter.active_types = ip.display_formatter.format_types
800 800
801 801 ip.user_ns['dummy'] = d = DummyRepr()
802 802 keys = set(['dummy', 'doesnotexist'])
803 803 r = ip.user_expressions({ key:key for key in keys})
804 804
805 805 nt.assert_equal(keys, set(r.keys()))
806 806 dummy = r['dummy']
807 807 nt.assert_equal(set(['status', 'data', 'metadata']), set(dummy.keys()))
808 808 nt.assert_equal(dummy['status'], 'ok')
809 809 data = dummy['data']
810 810 metadata = dummy['metadata']
811 811 nt.assert_equal(data.get('text/html'), d._repr_html_())
812 812 js, jsmd = d._repr_javascript_()
813 813 nt.assert_equal(data.get('application/javascript'), js)
814 814 nt.assert_equal(metadata.get('application/javascript'), jsmd)
815 815
816 816 dne = r['doesnotexist']
817 817 nt.assert_equal(dne['status'], 'error')
818 818 nt.assert_equal(dne['ename'], 'NameError')
819 819
820 820 # back to text only
821 821 ip.display_formatter.active_types = ['text/plain']
822 822
823 823 def test_user_expression():
824 824 # enable all formatters
825 825 ip.display_formatter.active_types = ip.display_formatter.format_types
826 826 query = {
827 827 'a' : '1 + 2',
828 828 'b' : '1/0',
829 829 }
830 830 r = ip.user_expressions(query)
831 831 import pprint
832 832 pprint.pprint(r)
833 833 nt.assert_equal(set(r.keys()), set(query.keys()))
834 834 a = r['a']
835 835 nt.assert_equal(set(['status', 'data', 'metadata']), set(a.keys()))
836 836 nt.assert_equal(a['status'], 'ok')
837 837 data = a['data']
838 838 metadata = a['metadata']
839 839 nt.assert_equal(data.get('text/plain'), '3')
840 840
841 841 b = r['b']
842 842 nt.assert_equal(b['status'], 'error')
843 843 nt.assert_equal(b['ename'], 'ZeroDivisionError')
844 844
845 845 # back to text only
846 846 ip.display_formatter.active_types = ['text/plain']
847 847
848 848
849 849
850 850
851 851
852 852 class TestSyntaxErrorTransformer(unittest.TestCase):
853 853 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
854 854
855 855 class SyntaxErrorTransformer(InputTransformer):
856 856
857 857 def push(self, line):
858 858 pos = line.find('syntaxerror')
859 859 if pos >= 0:
860 860 e = SyntaxError('input contains "syntaxerror"')
861 861 e.text = line
862 862 e.offset = pos + 1
863 863 raise e
864 864 return line
865 865
866 866 def reset(self):
867 867 pass
868 868
869 869 def setUp(self):
870 870 self.transformer = TestSyntaxErrorTransformer.SyntaxErrorTransformer()
871 871 ip.input_splitter.python_line_transforms.append(self.transformer)
872 872 ip.input_transformer_manager.python_line_transforms.append(self.transformer)
873 873
874 874 def tearDown(self):
875 875 ip.input_splitter.python_line_transforms.remove(self.transformer)
876 876 ip.input_transformer_manager.python_line_transforms.remove(self.transformer)
877 877
878 878 def test_syntaxerror_input_transformer(self):
879 879 with tt.AssertPrints('1234'):
880 880 ip.run_cell('1234')
881 881 with tt.AssertPrints('SyntaxError: invalid syntax'):
882 882 ip.run_cell('1 2 3') # plain python syntax error
883 883 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
884 884 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
885 885 with tt.AssertPrints('3456'):
886 886 ip.run_cell('3456')
887 887
888 888
889 889
890 890 def test_warning_suppression():
891 891 ip.run_cell("import warnings")
892 892 try:
893 893 with tt.AssertPrints("UserWarning: asdf", channel="stderr"):
894 894 ip.run_cell("warnings.warn('asdf')")
895 895 # Here's the real test -- if we run that again, we should get the
896 896 # warning again. Traditionally, each warning was only issued once per
897 897 # IPython session (approximately), even if the user typed in new and
898 898 # different code that should have also triggered the warning, leading
899 899 # to much confusion.
900 900 with tt.AssertPrints("UserWarning: asdf", channel="stderr"):
901 901 ip.run_cell("warnings.warn('asdf')")
902 902 finally:
903 903 ip.run_cell("del warnings")
@@ -1,35 +1,35 b''
1 1 """
2 2 Shim to maintain backwards compatibility with old IPython.kernel imports.
3 3 """
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 import sys
8 8 from warnings import warn
9 9
10 10 warn("The `IPython.kernel` package has been deprecated. "
11 "You should import from ipython_kernel or jupyter_client instead.")
11 "You should import from ipykernel or jupyter_client instead.")
12 12
13 13
14 14 from IPython.utils.shimmodule import ShimModule
15 15
16 16 # zmq subdir is gone
17 17 sys.modules['IPython.kernel.zmq.session'] = ShimModule(
18 18 src='IPython.kernel.zmq.session', mirror='jupyter_client.session')
19 19 sys.modules['IPython.kernel.zmq'] = ShimModule(
20 src='IPython.kernel.zmq', mirror='ipython_kernel')
20 src='IPython.kernel.zmq', mirror='ipykernel')
21 21
22 22 for pkg in ('comm', 'inprocess'):
23 23 src = 'IPython.kernel.%s' % pkg
24 sys.modules[src] = ShimModule(src=src, mirror='ipython_kernel.%s' % pkg)
24 sys.modules[src] = ShimModule(src=src, mirror='ipykernel.%s' % pkg)
25 25
26 26 for pkg in ('ioloop', 'blocking'):
27 27 src = 'IPython.kernel.%s' % pkg
28 28 sys.modules[src] = ShimModule(src=src, mirror='jupyter_client.%s' % pkg)
29 29
30 30 # required for `from IPython.kernel import PKG`
31 from ipython_kernel import comm, inprocess
31 from ipykernel import comm, inprocess
32 32 from jupyter_client import ioloop, blocking
33 33 # public API
34 from ipython_kernel.connect import *
34 from ipykernel.connect import *
35 35 from jupyter_client import *
@@ -1,3 +1,3 b''
1 1 if __name__ == '__main__':
2 from ipython_kernel import kernelapp as app
2 from ipykernel import kernelapp as app
3 3 app.launch_new_instance()
@@ -1,2 +1,2 b''
1 from ipython_kernel.connect import *
1 from ipykernel.connect import *
2 2 from jupyter_client.connect import *
@@ -1,12 +1,12 b''
1 1 """[DEPRECATED] Utilities for connecting to kernels
2 2
3 3 Moved to IPython.kernel.connect
4 4 """
5 5
6 6 import warnings
7 7 warnings.warn("IPython.lib.kernel moved to IPython.kernel.connect in IPython 1.0",
8 8 DeprecationWarning
9 9 )
10 10
11 from ipython_kernel.connect import *
11 from ipykernel.connect import *
12 12
@@ -1,374 +1,374 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 The :class:`~IPython.core.application.Application` object for the command
5 5 line :command:`ipython` program.
6 6 """
7 7
8 8 # Copyright (c) IPython Development Team.
9 9 # Distributed under the terms of the Modified BSD License.
10 10
11 11 from __future__ import absolute_import
12 12 from __future__ import print_function
13 13
14 14 import logging
15 15 import os
16 16 import sys
17 17
18 18 from traitlets.config.loader import Config
19 19 from traitlets.config.application import boolean_flag, catch_config_error, Application
20 20 from IPython.core import release
21 21 from IPython.core import usage
22 22 from IPython.core.completer import IPCompleter
23 23 from IPython.core.crashhandler import CrashHandler
24 24 from IPython.core.formatters import PlainTextFormatter
25 25 from IPython.core.history import HistoryManager
26 26 from IPython.core.prompts import PromptManager
27 27 from IPython.core.application import (
28 28 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
29 29 )
30 30 from IPython.core.magics import ScriptMagics
31 31 from IPython.core.shellapp import (
32 32 InteractiveShellApp, shell_flags, shell_aliases
33 33 )
34 34 from IPython.extensions.storemagic import StoreMagics
35 35 from IPython.terminal.interactiveshell import TerminalInteractiveShell
36 36 from IPython.utils import warn
37 37 from IPython.paths import get_ipython_dir
38 38 from traitlets import (
39 39 Bool, List, Dict,
40 40 )
41 41
42 42 #-----------------------------------------------------------------------------
43 43 # Globals, utilities and helpers
44 44 #-----------------------------------------------------------------------------
45 45
46 46 _examples = """
47 47 ipython --matplotlib # enable matplotlib integration
48 48 ipython --matplotlib=qt # enable matplotlib integration with qt4 backend
49 49
50 50 ipython --log-level=DEBUG # set logging to DEBUG
51 51 ipython --profile=foo # start with profile foo
52 52
53 53 ipython qtconsole # start the qtconsole GUI application
54 54 ipython help qtconsole # show the help for the qtconsole subcmd
55 55
56 56 ipython console # start the terminal-based console application
57 57 ipython help console # show the help for the console subcmd
58 58
59 59 ipython notebook # start the IPython notebook
60 60 ipython help notebook # show the help for the notebook subcmd
61 61
62 62 ipython profile create foo # create profile foo w/ default config files
63 63 ipython help profile # show the help for the profile subcmd
64 64
65 65 ipython locate # print the path to the IPython directory
66 66 ipython locate profile foo # print the path to the directory for profile `foo`
67 67
68 68 ipython nbconvert # convert notebooks to/from other formats
69 69 """
70 70
71 71 #-----------------------------------------------------------------------------
72 72 # Crash handler for this application
73 73 #-----------------------------------------------------------------------------
74 74
75 75 class IPAppCrashHandler(CrashHandler):
76 76 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
77 77
78 78 def __init__(self, app):
79 79 contact_name = release.author
80 80 contact_email = release.author_email
81 81 bug_tracker = 'https://github.com/ipython/ipython/issues'
82 82 super(IPAppCrashHandler,self).__init__(
83 83 app, contact_name, contact_email, bug_tracker
84 84 )
85 85
86 86 def make_report(self,traceback):
87 87 """Return a string containing a crash report."""
88 88
89 89 sec_sep = self.section_sep
90 90 # Start with parent report
91 91 report = [super(IPAppCrashHandler, self).make_report(traceback)]
92 92 # Add interactive-specific info we may have
93 93 rpt_add = report.append
94 94 try:
95 95 rpt_add(sec_sep+"History of session input:")
96 96 for line in self.app.shell.user_ns['_ih']:
97 97 rpt_add(line)
98 98 rpt_add('\n*** Last line of input (may not be in above history):\n')
99 99 rpt_add(self.app.shell._last_input_line+'\n')
100 100 except:
101 101 pass
102 102
103 103 return ''.join(report)
104 104
105 105 #-----------------------------------------------------------------------------
106 106 # Aliases and Flags
107 107 #-----------------------------------------------------------------------------
108 108 flags = dict(base_flags)
109 109 flags.update(shell_flags)
110 110 frontend_flags = {}
111 111 addflag = lambda *args: frontend_flags.update(boolean_flag(*args))
112 112 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
113 113 'Turn on auto editing of files with syntax errors.',
114 114 'Turn off auto editing of files with syntax errors.'
115 115 )
116 116 addflag('banner', 'TerminalIPythonApp.display_banner',
117 117 "Display a banner upon starting IPython.",
118 118 "Don't display a banner upon starting IPython."
119 119 )
120 120 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
121 121 """Set to confirm when you try to exit IPython with an EOF (Control-D
122 122 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
123 123 you can force a direct exit without any confirmation.""",
124 124 "Don't prompt the user when exiting."
125 125 )
126 126 addflag('term-title', 'TerminalInteractiveShell.term_title',
127 127 "Enable auto setting the terminal title.",
128 128 "Disable auto setting the terminal title."
129 129 )
130 130 classic_config = Config()
131 131 classic_config.InteractiveShell.cache_size = 0
132 132 classic_config.PlainTextFormatter.pprint = False
133 133 classic_config.PromptManager.in_template = '>>> '
134 134 classic_config.PromptManager.in2_template = '... '
135 135 classic_config.PromptManager.out_template = ''
136 136 classic_config.InteractiveShell.separate_in = ''
137 137 classic_config.InteractiveShell.separate_out = ''
138 138 classic_config.InteractiveShell.separate_out2 = ''
139 139 classic_config.InteractiveShell.colors = 'NoColor'
140 140 classic_config.InteractiveShell.xmode = 'Plain'
141 141
142 142 frontend_flags['classic']=(
143 143 classic_config,
144 144 "Gives IPython a similar feel to the classic Python prompt."
145 145 )
146 146 # # log doesn't make so much sense this way anymore
147 147 # paa('--log','-l',
148 148 # action='store_true', dest='InteractiveShell.logstart',
149 149 # help="Start logging to the default log file (./ipython_log.py).")
150 150 #
151 151 # # quick is harder to implement
152 152 frontend_flags['quick']=(
153 153 {'TerminalIPythonApp' : {'quick' : True}},
154 154 "Enable quick startup with no config files."
155 155 )
156 156
157 157 frontend_flags['i'] = (
158 158 {'TerminalIPythonApp' : {'force_interact' : True}},
159 159 """If running code from the command line, become interactive afterwards."""
160 160 )
161 161 flags.update(frontend_flags)
162 162
163 163 aliases = dict(base_aliases)
164 164 aliases.update(shell_aliases)
165 165
166 166 #-----------------------------------------------------------------------------
167 167 # Main classes and functions
168 168 #-----------------------------------------------------------------------------
169 169
170 170
171 171 class LocateIPythonApp(BaseIPythonApplication):
172 172 description = """print the path to the IPython dir"""
173 173 subcommands = Dict(dict(
174 174 profile=('IPython.core.profileapp.ProfileLocate',
175 175 "print the path to an IPython profile directory",
176 176 ),
177 177 ))
178 178 def start(self):
179 179 if self.subapp is not None:
180 180 return self.subapp.start()
181 181 else:
182 182 print(self.ipython_dir)
183 183
184 184
185 185 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
186 186 name = u'ipython'
187 187 description = usage.cl_usage
188 188 crash_handler_class = IPAppCrashHandler
189 189 examples = _examples
190 190
191 191 flags = Dict(flags)
192 192 aliases = Dict(aliases)
193 193 classes = List()
194 194 def _classes_default(self):
195 195 """This has to be in a method, for TerminalIPythonApp to be available."""
196 196 return [
197 197 InteractiveShellApp, # ShellApp comes before TerminalApp, because
198 198 self.__class__, # it will also affect subclasses (e.g. QtConsole)
199 199 TerminalInteractiveShell,
200 200 PromptManager,
201 201 HistoryManager,
202 202 ProfileDir,
203 203 PlainTextFormatter,
204 204 IPCompleter,
205 205 ScriptMagics,
206 206 StoreMagics,
207 207 ]
208 208
209 209 subcommands = dict(
210 210 qtconsole=('jupyter_qtconsole.console.qtconsoleapp.JupyterQtConsoleApp',
211 211 """DEPRECATD: Launch the Jupyter Qt Console."""
212 212 ),
213 213 notebook=('jupyter_notebook.notebookapp.NotebookApp',
214 214 """DEPRECATED: Launch the IPython HTML Notebook Server."""
215 215 ),
216 216 profile = ("IPython.core.profileapp.ProfileApp",
217 217 "Create and manage IPython profiles."
218 218 ),
219 kernel = ("ipython_kernel.kernelapp.IPKernelApp",
219 kernel = ("ipykernel.kernelapp.IPKernelApp",
220 220 "Start a kernel without an attached frontend."
221 221 ),
222 222 console=('jupyter_console.app.ZMQTerminalIPythonApp',
223 223 """DEPRECATED: Launch the Jupyter terminal-based Console."""
224 224 ),
225 225 locate=('IPython.terminal.ipapp.LocateIPythonApp',
226 226 LocateIPythonApp.description
227 227 ),
228 228 history=('IPython.core.historyapp.HistoryApp',
229 229 "Manage the IPython history database."
230 230 ),
231 231 nbconvert=('jupyter_nbconvert.nbconvertapp.NbConvertApp',
232 232 "DEPRECATED: Convert notebooks to/from other formats."
233 233 ),
234 234 trust=('jupyter_nbformat.sign.TrustNotebookApp',
235 235 "DEPRECATED: Sign notebooks to trust their potentially unsafe contents at load."
236 236 ),
237 237 kernelspec=('jupyter_client.kernelspecapp.KernelSpecApp',
238 238 "DEPRECATED: Manage Jupyter kernel specifications."
239 239 ),
240 240 )
241 241 subcommands['install-nbextension'] = (
242 242 "jupyter_notebook.nbextensions.NBExtensionApp",
243 243 "DEPRECATED: Install Jupyter notebook extension files"
244 244 )
245 245
246 246 # *do* autocreate requested profile, but don't create the config file.
247 247 auto_create=Bool(True)
248 248 # configurables
249 249 quick = Bool(False, config=True,
250 250 help="""Start IPython quickly by skipping the loading of config files."""
251 251 )
252 252 def _quick_changed(self, name, old, new):
253 253 if new:
254 254 self.load_config_file = lambda *a, **kw: None
255 255
256 256 display_banner = Bool(True, config=True,
257 257 help="Whether to display a banner upon starting IPython."
258 258 )
259 259
260 260 # if there is code of files to run from the cmd line, don't interact
261 261 # unless the --i flag (App.force_interact) is true.
262 262 force_interact = Bool(False, config=True,
263 263 help="""If a command or file is given via the command-line,
264 264 e.g. 'ipython foo.py', start an interactive shell after executing the
265 265 file or command."""
266 266 )
267 267 def _force_interact_changed(self, name, old, new):
268 268 if new:
269 269 self.interact = True
270 270
271 271 def _file_to_run_changed(self, name, old, new):
272 272 if new:
273 273 self.something_to_run = True
274 274 if new and not self.force_interact:
275 275 self.interact = False
276 276 _code_to_run_changed = _file_to_run_changed
277 277 _module_to_run_changed = _file_to_run_changed
278 278
279 279 # internal, not-configurable
280 280 interact=Bool(True)
281 281 something_to_run=Bool(False)
282 282
283 283 def parse_command_line(self, argv=None):
284 284 """override to allow old '-pylab' flag with deprecation warning"""
285 285
286 286 argv = sys.argv[1:] if argv is None else argv
287 287
288 288 if '-pylab' in argv:
289 289 # deprecated `-pylab` given,
290 290 # warn and transform into current syntax
291 291 argv = argv[:] # copy, don't clobber
292 292 idx = argv.index('-pylab')
293 293 warn.warn("`-pylab` flag has been deprecated.\n"
294 294 " Use `--matplotlib <backend>` and import pylab manually.")
295 295 argv[idx] = '--pylab'
296 296
297 297 return super(TerminalIPythonApp, self).parse_command_line(argv)
298 298
299 299 @catch_config_error
300 300 def initialize(self, argv=None):
301 301 """Do actions after construct, but before starting the app."""
302 302 super(TerminalIPythonApp, self).initialize(argv)
303 303 if self.subapp is not None:
304 304 # don't bother initializing further, starting subapp
305 305 return
306 306 # print self.extra_args
307 307 if self.extra_args and not self.something_to_run:
308 308 self.file_to_run = self.extra_args[0]
309 309 self.init_path()
310 310 # create the shell
311 311 self.init_shell()
312 312 # and draw the banner
313 313 self.init_banner()
314 314 # Now a variety of things that happen after the banner is printed.
315 315 self.init_gui_pylab()
316 316 self.init_extensions()
317 317 self.init_code()
318 318
319 319 def init_shell(self):
320 320 """initialize the InteractiveShell instance"""
321 321 # Create an InteractiveShell instance.
322 322 # shell.display_banner should always be False for the terminal
323 323 # based app, because we call shell.show_banner() by hand below
324 324 # so the banner shows *before* all extension loading stuff.
325 325 self.shell = TerminalInteractiveShell.instance(parent=self,
326 326 display_banner=False, profile_dir=self.profile_dir,
327 327 ipython_dir=self.ipython_dir, user_ns=self.user_ns)
328 328 self.shell.configurables.append(self)
329 329
330 330 def init_banner(self):
331 331 """optionally display the banner"""
332 332 if self.display_banner and self.interact:
333 333 self.shell.show_banner()
334 334 # Make sure there is a space below the banner.
335 335 if self.log_level <= logging.INFO: print()
336 336
337 337 def _pylab_changed(self, name, old, new):
338 338 """Replace --pylab='inline' with --pylab='auto'"""
339 339 if new == 'inline':
340 340 warn.warn("'inline' not available as pylab backend, "
341 341 "using 'auto' instead.")
342 342 self.pylab = 'auto'
343 343
344 344 def start(self):
345 345 if self.subapp is not None:
346 346 return self.subapp.start()
347 347 # perform any prexec steps:
348 348 if self.interact:
349 349 self.log.debug("Starting IPython's mainloop...")
350 350 self.shell.mainloop()
351 351 else:
352 352 self.log.debug("IPython not interactive...")
353 353
354 354 def load_default_config(ipython_dir=None):
355 355 """Load the default config file from the default ipython_dir.
356 356
357 357 This is useful for embedded shells.
358 358 """
359 359 if ipython_dir is None:
360 360 ipython_dir = get_ipython_dir()
361 361
362 362 profile_dir = os.path.join(ipython_dir, 'profile_default')
363 363
364 364 config = Config()
365 365 for cf in Application._load_config_files("ipython_config", path=profile_dir):
366 366 config.update(cf)
367 367
368 368 return config
369 369
370 370 launch_new_instance = TerminalIPythonApp.launch_instance
371 371
372 372
373 373 if __name__ == '__main__':
374 374 launch_new_instance()
@@ -1,5 +1,5 b''
1 1 from warnings import warn
2 2
3 warn("IPython.utils.pickleutil has moved to ipython_kernel.pickleutil")
3 warn("IPython.utils.pickleutil has moved to ipykernel.pickleutil")
4 4
5 from ipython_kernel.pickleutil import *
5 from ipykernel.pickleutil import *
@@ -1,288 +1,288 b''
1 1 #!/usr/bin/env python
2 2 # -*- coding: utf-8 -*-
3 3 """Setup script for IPython.
4 4
5 5 Under Posix environments it works like a typical setup.py script.
6 6 Under Windows, the command sdist is not supported, since IPython
7 7 requires utilities which are not available under Windows."""
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (c) 2008-2011, IPython Development Team.
11 11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 14 #
15 15 # Distributed under the terms of the Modified BSD License.
16 16 #
17 17 # The full license is in the file COPYING.rst, distributed with this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Minimal Python version sanity check
22 22 #-----------------------------------------------------------------------------
23 23 from __future__ import print_function
24 24
25 25 import sys
26 26
27 27 # This check is also made in IPython/__init__, don't forget to update both when
28 28 # changing Python version requirements.
29 29 v = sys.version_info
30 30 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
31 31 error = "ERROR: IPython requires Python version 2.7 or 3.3 or above."
32 32 print(error, file=sys.stderr)
33 33 sys.exit(1)
34 34
35 35 PY3 = (sys.version_info[0] >= 3)
36 36
37 37 # At least we're on the python version we need, move on.
38 38
39 39 #-------------------------------------------------------------------------------
40 40 # Imports
41 41 #-------------------------------------------------------------------------------
42 42
43 43 # Stdlib imports
44 44 import os
45 45 import shutil
46 46
47 47 from glob import glob
48 48
49 49 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
50 50 # update it when the contents of directories change.
51 51 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
52 52
53 53 from distutils.core import setup
54 54
55 55 # Our own imports
56 56 from setupbase import target_update
57 57
58 58 from setupbase import (
59 59 setup_args,
60 60 find_packages,
61 61 find_package_data,
62 62 check_package_data_first,
63 63 find_entry_points,
64 64 build_scripts_entrypt,
65 65 find_data_files,
66 66 check_for_readline,
67 67 git_prebuild,
68 68 get_bdist_wheel,
69 69 install_symlinked,
70 70 install_lib_symlink,
71 71 install_scripts_for_symlink,
72 72 unsymlink,
73 73 )
74 74
75 75 isfile = os.path.isfile
76 76 pjoin = os.path.join
77 77
78 78 #-------------------------------------------------------------------------------
79 79 # Handle OS specific things
80 80 #-------------------------------------------------------------------------------
81 81
82 82 if os.name in ('nt','dos'):
83 83 os_name = 'windows'
84 84 else:
85 85 os_name = os.name
86 86
87 87 # Under Windows, 'sdist' has not been supported. Now that the docs build with
88 88 # Sphinx it might work, but let's not turn it on until someone confirms that it
89 89 # actually works.
90 90 if os_name == 'windows' and 'sdist' in sys.argv:
91 91 print('The sdist command is not available under Windows. Exiting.')
92 92 sys.exit(1)
93 93
94 94
95 95 #-------------------------------------------------------------------------------
96 96 # Things related to the IPython documentation
97 97 #-------------------------------------------------------------------------------
98 98
99 99 # update the manuals when building a source dist
100 100 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
101 101
102 102 # List of things to be updated. Each entry is a triplet of args for
103 103 # target_update()
104 104 to_update = [
105 105 ('docs/man/ipython.1.gz',
106 106 ['docs/man/ipython.1'],
107 107 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
108 108 ]
109 109
110 110
111 111 [ target_update(*t) for t in to_update ]
112 112
113 113 #---------------------------------------------------------------------------
114 114 # Find all the packages, package data, and data_files
115 115 #---------------------------------------------------------------------------
116 116
117 117 packages = find_packages()
118 118 package_data = find_package_data()
119 119
120 120 data_files = find_data_files()
121 121
122 122 setup_args['packages'] = packages
123 123 setup_args['package_data'] = package_data
124 124 setup_args['data_files'] = data_files
125 125
126 126 #---------------------------------------------------------------------------
127 127 # custom distutils commands
128 128 #---------------------------------------------------------------------------
129 129 # imports here, so they are after setuptools import if there was one
130 130 from distutils.command.sdist import sdist
131 131 from distutils.command.upload import upload
132 132
133 133 class UploadWindowsInstallers(upload):
134 134
135 135 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
136 136 user_options = upload.user_options + [
137 137 ('files=', 'f', 'exe file (or glob) to upload')
138 138 ]
139 139 def initialize_options(self):
140 140 upload.initialize_options(self)
141 141 meta = self.distribution.metadata
142 142 base = '{name}-{version}'.format(
143 143 name=meta.get_name(),
144 144 version=meta.get_version()
145 145 )
146 146 self.files = os.path.join('dist', '%s.*.exe' % base)
147 147
148 148 def run(self):
149 149 for dist_file in glob(self.files):
150 150 self.upload_file('bdist_wininst', 'any', dist_file)
151 151
152 152 setup_args['cmdclass'] = {
153 153 'build_py': \
154 154 check_package_data_first(git_prebuild('IPython')),
155 155 'sdist' : git_prebuild('IPython', sdist),
156 156 'upload_wininst' : UploadWindowsInstallers,
157 157 'symlink': install_symlinked,
158 158 'install_lib_symlink': install_lib_symlink,
159 159 'install_scripts_sym': install_scripts_for_symlink,
160 160 'unsymlink': unsymlink,
161 161 }
162 162
163 163 ### Temporarily disable install while it's broken during the big split
164 164 from textwrap import dedent
165 165 from distutils.command.install import install
166 166
167 167 class DisabledInstall(install):
168 168 def run(self):
169 169 msg = dedent("""
170 170 While we are in the midst of The Big Split,
171 171 IPython cannot be installed from master.
172 172 You can use `pip install -e .` for an editable install,
173 173 which still works.
174 174 """)
175 175 print(msg, file=sys.stderr)
176 176 raise SystemExit(1)
177 177
178 178 setup_args['cmdclass']['install'] = DisabledInstall
179 179
180 180
181 181 #---------------------------------------------------------------------------
182 182 # Handle scripts, dependencies, and setuptools specific things
183 183 #---------------------------------------------------------------------------
184 184
185 185 # For some commands, use setuptools. Note that we do NOT list install here!
186 186 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
187 187 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
188 188 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
189 189 'egg_info', 'easy_install', 'upload', 'install_egg_info',
190 190 ))
191 191
192 192 if len(needs_setuptools.intersection(sys.argv)) > 0:
193 193 import setuptools
194 194
195 195 # This dict is used for passing extra arguments that are setuptools
196 196 # specific to setup
197 197 setuptools_extra_args = {}
198 198
199 199 # setuptools requirements
200 200
201 201 pyzmq = 'pyzmq>=13'
202 202
203 203 extras_require = dict(
204 204 parallel = ['ipyparallel'],
205 205 qtconsole = ['jupyter_qtconsole'],
206 206 doc = ['Sphinx>=1.1', 'numpydoc'],
207 207 test = ['nose>=0.10.1', 'requests'],
208 208 terminal = [],
209 kernel = ['ipython_kernel'],
209 kernel = ['ipykernel'],
210 210 nbformat = ['jupyter_nbformat'],
211 211 notebook = ['jupyter_notebook'],
212 212 nbconvert = ['jupyter_nbconvert']
213 213 )
214 214
215 215 if sys.version_info < (3, 3):
216 216 extras_require['test'].append('mock')
217 217
218 218 install_requires = [
219 219 'decorator',
220 220 'pickleshare',
221 221 'simplegeneric>0.8',
222 222 'traitlets',
223 223 ]
224 224
225 225 # add platform-specific dependencies
226 226 if sys.platform == 'darwin':
227 227 install_requires.append('appnope')
228 228 if 'bdist_wheel' in sys.argv[1:] or not check_for_readline():
229 229 install_requires.append('gnureadline')
230 230
231 231 if sys.platform.startswith('win'):
232 232 extras_require['terminal'].append('pyreadline>=2.0')
233 233 else:
234 234 install_requires.append('pexpect')
235 235
236 236 everything = set()
237 237 for deps in extras_require.values():
238 238 everything.update(deps)
239 239 extras_require['all'] = everything
240 240
241 241 if 'setuptools' in sys.modules:
242 242 setup_args['cmdclass']['bdist_wheel'] = get_bdist_wheel()
243 243
244 244 setuptools_extra_args['zip_safe'] = False
245 245 setuptools_extra_args['entry_points'] = {
246 246 'console_scripts': find_entry_points(),
247 247 'pygments.lexers': [
248 248 'ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer',
249 249 'ipython = IPython.lib.lexers:IPythonLexer',
250 250 'ipython3 = IPython.lib.lexers:IPython3Lexer',
251 251 ],
252 252 }
253 253 setup_args['extras_require'] = extras_require
254 254 requires = setup_args['install_requires'] = install_requires
255 255
256 256 # Script to be run by the windows binary installer after the default setup
257 257 # routine, to add shortcuts and similar windows-only things. Windows
258 258 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
259 259 # doesn't find them.
260 260 if 'bdist_wininst' in sys.argv:
261 261 if len(sys.argv) > 2 and \
262 262 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
263 263 print("ERROR: bdist_wininst must be run alone. Exiting.", file=sys.stderr)
264 264 sys.exit(1)
265 265 setup_args['data_files'].append(
266 266 ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')])
267 267 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
268 268 setup_args['options'] = {"bdist_wininst":
269 269 {"install_script":
270 270 "ipython_win_post_install.py"}}
271 271
272 272 else:
273 273 # scripts has to be a non-empty list, or install_scripts isn't called
274 274 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
275 275
276 276 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
277 277
278 278 #---------------------------------------------------------------------------
279 279 # Do the actual setup now
280 280 #---------------------------------------------------------------------------
281 281
282 282 setup_args.update(setuptools_extra_args)
283 283
284 284 def main():
285 285 setup(**setup_args)
286 286
287 287 if __name__ == '__main__':
288 288 main()
General Comments 0
You need to be logged in to leave comments. Login now