##// END OF EJS Templates
Darken and mypy
Ian Thomas -
Show More
@@ -1,174 +1,178 b''
1 """Implementation of magic functions for matplotlib/pylab support.
1 """Implementation of magic functions for matplotlib/pylab support.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
4 # Copyright (c) 2012 The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 # Our own packages
15 # Our own packages
16 from traitlets.config.application import Application
16 from traitlets.config.application import Application
17 from IPython.core import magic_arguments
17 from IPython.core import magic_arguments
18 from IPython.core.magic import Magics, magics_class, line_magic
18 from IPython.core.magic import Magics, magics_class, line_magic
19 from IPython.testing.skipdoctest import skip_doctest
19 from IPython.testing.skipdoctest import skip_doctest
20 from warnings import warn
20 from warnings import warn
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Magic implementation classes
23 # Magic implementation classes
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 magic_gui_arg = magic_arguments.argument(
26 magic_gui_arg = magic_arguments.argument(
27 'gui', nargs='?',
27 "gui",
28 help="""Name of the matplotlib backend to use such as 'qt' or 'widget'.
28 nargs="?",
29 help="""Name of the matplotlib backend to use such as 'qt' or 'widget'.
29 If given, the corresponding matplotlib backend is used,
30 If given, the corresponding matplotlib backend is used,
30 otherwise it will be matplotlib's default
31 otherwise it will be matplotlib's default
31 (which you can set in your matplotlib config file).
32 (which you can set in your matplotlib config file).
32 """
33 """,
33 )
34 )
34
35
35
36
36 @magics_class
37 @magics_class
37 class PylabMagics(Magics):
38 class PylabMagics(Magics):
38 """Magics related to matplotlib's pylab support"""
39 """Magics related to matplotlib's pylab support"""
39
40
40 @skip_doctest
41 @skip_doctest
41 @line_magic
42 @line_magic
42 @magic_arguments.magic_arguments()
43 @magic_arguments.magic_arguments()
43 @magic_arguments.argument('-l', '--list', action='store_true',
44 @magic_arguments.argument('-l', '--list', action='store_true',
44 help='Show available matplotlib backends')
45 help='Show available matplotlib backends')
45 @magic_gui_arg
46 @magic_gui_arg
46 def matplotlib(self, line=''):
47 def matplotlib(self, line=''):
47 """Set up matplotlib to work interactively.
48 """Set up matplotlib to work interactively.
48
49
49 This function lets you activate matplotlib interactive support
50 This function lets you activate matplotlib interactive support
50 at any point during an IPython session. It does not import anything
51 at any point during an IPython session. It does not import anything
51 into the interactive namespace.
52 into the interactive namespace.
52
53
53 If you are using the inline matplotlib backend in the IPython Notebook
54 If you are using the inline matplotlib backend in the IPython Notebook
54 you can set which figure formats are enabled using the following::
55 you can set which figure formats are enabled using the following::
55
56
56 In [1]: from matplotlib_inline.backend_inline import set_matplotlib_formats
57 In [1]: from matplotlib_inline.backend_inline import set_matplotlib_formats
57
58
58 In [2]: set_matplotlib_formats('pdf', 'svg')
59 In [2]: set_matplotlib_formats('pdf', 'svg')
59
60
60 The default for inline figures sets `bbox_inches` to 'tight'. This can
61 The default for inline figures sets `bbox_inches` to 'tight'. This can
61 cause discrepancies between the displayed image and the identical
62 cause discrepancies between the displayed image and the identical
62 image created using `savefig`. This behavior can be disabled using the
63 image created using `savefig`. This behavior can be disabled using the
63 `%config` magic::
64 `%config` magic::
64
65
65 In [3]: %config InlineBackend.print_figure_kwargs = {'bbox_inches':None}
66 In [3]: %config InlineBackend.print_figure_kwargs = {'bbox_inches':None}
66
67
67 In addition, see the docstrings of
68 In addition, see the docstrings of
68 `matplotlib_inline.backend_inline.set_matplotlib_formats` and
69 `matplotlib_inline.backend_inline.set_matplotlib_formats` and
69 `matplotlib_inline.backend_inline.set_matplotlib_close` for more information on
70 `matplotlib_inline.backend_inline.set_matplotlib_close` for more information on
70 changing additional behaviors of the inline backend.
71 changing additional behaviors of the inline backend.
71
72
72 Examples
73 Examples
73 --------
74 --------
74 To enable the inline backend for usage with the IPython Notebook::
75 To enable the inline backend for usage with the IPython Notebook::
75
76
76 In [1]: %matplotlib inline
77 In [1]: %matplotlib inline
77
78
78 In this case, where the matplotlib default is TkAgg::
79 In this case, where the matplotlib default is TkAgg::
79
80
80 In [2]: %matplotlib
81 In [2]: %matplotlib
81 Using matplotlib backend: TkAgg
82 Using matplotlib backend: TkAgg
82
83
83 But you can explicitly request a different GUI backend::
84 But you can explicitly request a different GUI backend::
84
85
85 In [3]: %matplotlib qt
86 In [3]: %matplotlib qt
86
87
87 You can list the available backends using the -l/--list option::
88 You can list the available backends using the -l/--list option::
88
89
89 In [4]: %matplotlib --list
90 In [4]: %matplotlib --list
90 Available matplotlib backends: ['osx', 'qt4', 'qt5', 'gtk3', 'gtk4', 'notebook', 'wx', 'qt', 'nbagg',
91 Available matplotlib backends: ['osx', 'qt4', 'qt5', 'gtk3', 'gtk4', 'notebook', 'wx', 'qt', 'nbagg',
91 'gtk', 'tk', 'inline']
92 'gtk', 'tk', 'inline']
92 """
93 """
93 args = magic_arguments.parse_argstring(self.matplotlib, line)
94 args = magic_arguments.parse_argstring(self.matplotlib, line)
94 if args.list:
95 if args.list:
95 from IPython.core.pylabtools import _matplotlib_manages_backends
96 from IPython.core.pylabtools import _matplotlib_manages_backends
97
96 if _matplotlib_manages_backends():
98 if _matplotlib_manages_backends():
97 from matplotlib.backends.registry import backend_registry
99 from matplotlib.backends.registry import backend_registry
100
98 backends_list = backend_registry.list_all()
101 backends_list = backend_registry.list_all()
99 else:
102 else:
100 from IPython.core.pylabtools import backends
103 from IPython.core.pylabtools import backends
104
101 backends_list = list(backends.keys())
105 backends_list = list(backends.keys())
102 print("Available matplotlib backends: %s" % backends_list)
106 print("Available matplotlib backends: %s" % backends_list)
103 else:
107 else:
104 gui, backend = self.shell.enable_matplotlib(args.gui.lower() if isinstance(args.gui, str) else args.gui)
108 gui, backend = self.shell.enable_matplotlib(args.gui.lower() if isinstance(args.gui, str) else args.gui)
105 self._show_matplotlib_backend(args.gui, backend)
109 self._show_matplotlib_backend(args.gui, backend)
106
110
107 @skip_doctest
111 @skip_doctest
108 @line_magic
112 @line_magic
109 @magic_arguments.magic_arguments()
113 @magic_arguments.magic_arguments()
110 @magic_arguments.argument(
114 @magic_arguments.argument(
111 '--no-import-all', action='store_true', default=None,
115 '--no-import-all', action='store_true', default=None,
112 help="""Prevent IPython from performing ``import *`` into the interactive namespace.
116 help="""Prevent IPython from performing ``import *`` into the interactive namespace.
113
117
114 You can govern the default behavior of this flag with the
118 You can govern the default behavior of this flag with the
115 InteractiveShellApp.pylab_import_all configurable.
119 InteractiveShellApp.pylab_import_all configurable.
116 """
120 """
117 )
121 )
118 @magic_gui_arg
122 @magic_gui_arg
119 def pylab(self, line=''):
123 def pylab(self, line=''):
120 """Load numpy and matplotlib to work interactively.
124 """Load numpy and matplotlib to work interactively.
121
125
122 This function lets you activate pylab (matplotlib, numpy and
126 This function lets you activate pylab (matplotlib, numpy and
123 interactive support) at any point during an IPython session.
127 interactive support) at any point during an IPython session.
124
128
125 %pylab makes the following imports::
129 %pylab makes the following imports::
126
130
127 import numpy
131 import numpy
128 import matplotlib
132 import matplotlib
129 from matplotlib import pylab, mlab, pyplot
133 from matplotlib import pylab, mlab, pyplot
130 np = numpy
134 np = numpy
131 plt = pyplot
135 plt = pyplot
132
136
133 from IPython.display import display
137 from IPython.display import display
134 from IPython.core.pylabtools import figsize, getfigs
138 from IPython.core.pylabtools import figsize, getfigs
135
139
136 from pylab import *
140 from pylab import *
137 from numpy import *
141 from numpy import *
138
142
139 If you pass `--no-import-all`, the last two `*` imports will be excluded.
143 If you pass `--no-import-all`, the last two `*` imports will be excluded.
140
144
141 See the %matplotlib magic for more details about activating matplotlib
145 See the %matplotlib magic for more details about activating matplotlib
142 without affecting the interactive namespace.
146 without affecting the interactive namespace.
143 """
147 """
144 args = magic_arguments.parse_argstring(self.pylab, line)
148 args = magic_arguments.parse_argstring(self.pylab, line)
145 if args.no_import_all is None:
149 if args.no_import_all is None:
146 # get default from Application
150 # get default from Application
147 if Application.initialized():
151 if Application.initialized():
148 app = Application.instance()
152 app = Application.instance()
149 try:
153 try:
150 import_all = app.pylab_import_all
154 import_all = app.pylab_import_all
151 except AttributeError:
155 except AttributeError:
152 import_all = True
156 import_all = True
153 else:
157 else:
154 # nothing specified, no app - default True
158 # nothing specified, no app - default True
155 import_all = True
159 import_all = True
156 else:
160 else:
157 # invert no-import flag
161 # invert no-import flag
158 import_all = not args.no_import_all
162 import_all = not args.no_import_all
159
163
160 gui, backend, clobbered = self.shell.enable_pylab(args.gui, import_all=import_all)
164 gui, backend, clobbered = self.shell.enable_pylab(args.gui, import_all=import_all)
161 self._show_matplotlib_backend(args.gui, backend)
165 self._show_matplotlib_backend(args.gui, backend)
162 print(
166 print(
163 "%pylab is deprecated, use %matplotlib inline and import the required libraries."
167 "%pylab is deprecated, use %matplotlib inline and import the required libraries."
164 )
168 )
165 print("Populating the interactive namespace from numpy and matplotlib")
169 print("Populating the interactive namespace from numpy and matplotlib")
166 if clobbered:
170 if clobbered:
167 warn("pylab import has clobbered these variables: %s" % clobbered +
171 warn("pylab import has clobbered these variables: %s" % clobbered +
168 "\n`%matplotlib` prevents importing * from pylab and numpy"
172 "\n`%matplotlib` prevents importing * from pylab and numpy"
169 )
173 )
170
174
171 def _show_matplotlib_backend(self, gui, backend):
175 def _show_matplotlib_backend(self, gui, backend):
172 """show matplotlib message backend message"""
176 """show matplotlib message backend message"""
173 if not gui or gui == 'auto':
177 if not gui or gui == 'auto':
174 print("Using matplotlib backend: %s" % backend)
178 print("Using matplotlib backend: %s" % backend)
@@ -1,470 +1,475 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Pylab (matplotlib) support utilities."""
2 """Pylab (matplotlib) support utilities."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 from io import BytesIO
7 from io import BytesIO
8 from binascii import b2a_base64
8 from binascii import b2a_base64
9 from functools import partial
9 from functools import partial
10 import warnings
10 import warnings
11
11
12 from IPython.core.display import _pngxy
12 from IPython.core.display import _pngxy
13 from IPython.utils.decorators import flag_calls
13 from IPython.utils.decorators import flag_calls
14
14
15
15
16 # Matplotlib backend resolution functionality moved from IPython to Matplotlib
16 # Matplotlib backend resolution functionality moved from IPython to Matplotlib
17 # in IPython 8.23 and Matplotlib 3.9. Need to keep `backends` and `backend2gui`
17 # in IPython 8.23 and Matplotlib 3.9. Need to keep `backends` and `backend2gui`
18 # here for earlier Matplotlib and for external backend libraries such as
18 # here for earlier Matplotlib and for external backend libraries such as
19 # mplcairo that might rely upon it.
19 # mplcairo that might rely upon it.
20 _deprecated_backends = {
20 _deprecated_backends = {
21 "tk": "TkAgg",
21 "tk": "TkAgg",
22 "gtk": "GTKAgg",
22 "gtk": "GTKAgg",
23 "gtk3": "GTK3Agg",
23 "gtk3": "GTK3Agg",
24 "gtk4": "GTK4Agg",
24 "gtk4": "GTK4Agg",
25 "wx": "WXAgg",
25 "wx": "WXAgg",
26 "qt4": "Qt4Agg",
26 "qt4": "Qt4Agg",
27 "qt5": "Qt5Agg",
27 "qt5": "Qt5Agg",
28 "qt6": "QtAgg",
28 "qt6": "QtAgg",
29 "qt": "QtAgg",
29 "qt": "QtAgg",
30 "osx": "MacOSX",
30 "osx": "MacOSX",
31 "nbagg": "nbAgg",
31 "nbagg": "nbAgg",
32 "webagg": "WebAgg",
32 "webagg": "WebAgg",
33 "notebook": "nbAgg",
33 "notebook": "nbAgg",
34 "agg": "agg",
34 "agg": "agg",
35 "svg": "svg",
35 "svg": "svg",
36 "pdf": "pdf",
36 "pdf": "pdf",
37 "ps": "ps",
37 "ps": "ps",
38 "inline": "module://matplotlib_inline.backend_inline",
38 "inline": "module://matplotlib_inline.backend_inline",
39 "ipympl": "module://ipympl.backend_nbagg",
39 "ipympl": "module://ipympl.backend_nbagg",
40 "widget": "module://ipympl.backend_nbagg",
40 "widget": "module://ipympl.backend_nbagg",
41 }
41 }
42
42
43 # We also need a reverse backends2guis mapping that will properly choose which
43 # We also need a reverse backends2guis mapping that will properly choose which
44 # GUI support to activate based on the desired matplotlib backend. For the
44 # GUI support to activate based on the desired matplotlib backend. For the
45 # most part it's just a reverse of the above dict, but we also need to add a
45 # most part it's just a reverse of the above dict, but we also need to add a
46 # few others that map to the same GUI manually:
46 # few others that map to the same GUI manually:
47 _deprecated_backend2gui = dict(zip(_deprecated_backends.values(), _deprecated_backends.keys()))
47 _deprecated_backend2gui = dict(
48 zip(_deprecated_backends.values(), _deprecated_backends.keys())
49 )
48 # In the reverse mapping, there are a few extra valid matplotlib backends that
50 # In the reverse mapping, there are a few extra valid matplotlib backends that
49 # map to the same GUI support
51 # map to the same GUI support
50 _deprecated_backend2gui["GTK"] = _deprecated_backend2gui["GTKCairo"] = "gtk"
52 _deprecated_backend2gui["GTK"] = _deprecated_backend2gui["GTKCairo"] = "gtk"
51 _deprecated_backend2gui["GTK3Cairo"] = "gtk3"
53 _deprecated_backend2gui["GTK3Cairo"] = "gtk3"
52 _deprecated_backend2gui["GTK4Cairo"] = "gtk4"
54 _deprecated_backend2gui["GTK4Cairo"] = "gtk4"
53 _deprecated_backend2gui["WX"] = "wx"
55 _deprecated_backend2gui["WX"] = "wx"
54 _deprecated_backend2gui["CocoaAgg"] = "osx"
56 _deprecated_backend2gui["CocoaAgg"] = "osx"
55 # There needs to be a hysteresis here as the new QtAgg Matplotlib backend
57 # There needs to be a hysteresis here as the new QtAgg Matplotlib backend
56 # supports either Qt5 or Qt6 and the IPython qt event loop support Qt4, Qt5,
58 # supports either Qt5 or Qt6 and the IPython qt event loop support Qt4, Qt5,
57 # and Qt6.
59 # and Qt6.
58 _deprecated_backend2gui["QtAgg"] = "qt"
60 _deprecated_backend2gui["QtAgg"] = "qt"
59 _deprecated_backend2gui["Qt4Agg"] = "qt4"
61 _deprecated_backend2gui["Qt4Agg"] = "qt4"
60 _deprecated_backend2gui["Qt5Agg"] = "qt5"
62 _deprecated_backend2gui["Qt5Agg"] = "qt5"
61
63
62 # And some backends that don't need GUI integration
64 # And some backends that don't need GUI integration
63 del _deprecated_backend2gui["nbAgg"]
65 del _deprecated_backend2gui["nbAgg"]
64 del _deprecated_backend2gui["agg"]
66 del _deprecated_backend2gui["agg"]
65 del _deprecated_backend2gui["svg"]
67 del _deprecated_backend2gui["svg"]
66 del _deprecated_backend2gui["pdf"]
68 del _deprecated_backend2gui["pdf"]
67 del _deprecated_backend2gui["ps"]
69 del _deprecated_backend2gui["ps"]
68 del _deprecated_backend2gui["module://matplotlib_inline.backend_inline"]
70 del _deprecated_backend2gui["module://matplotlib_inline.backend_inline"]
69 del _deprecated_backend2gui["module://ipympl.backend_nbagg"]
71 del _deprecated_backend2gui["module://ipympl.backend_nbagg"]
70
72
71
73
72 # Deprecated attributes backends and backend2gui mostly following PEP 562.
74 # Deprecated attributes backends and backend2gui mostly following PEP 562.
73 def __getattr__(name):
75 def __getattr__(name):
74 if name in ("backends", "backend2gui"):
76 if name in ("backends", "backend2gui"):
75 warnings.warn(f"{name} is deprecated", DeprecationWarning)
77 warnings.warn(f"{name} is deprecated", DeprecationWarning)
76 return globals()[f"_deprecated_{name}"]
78 return globals()[f"_deprecated_{name}"]
77 raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
79 raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
78
80
79
81
80 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
81 # Matplotlib utilities
83 # Matplotlib utilities
82 #-----------------------------------------------------------------------------
84 #-----------------------------------------------------------------------------
83
85
84
86
85 def getfigs(*fig_nums):
87 def getfigs(*fig_nums):
86 """Get a list of matplotlib figures by figure numbers.
88 """Get a list of matplotlib figures by figure numbers.
87
89
88 If no arguments are given, all available figures are returned. If the
90 If no arguments are given, all available figures are returned. If the
89 argument list contains references to invalid figures, a warning is printed
91 argument list contains references to invalid figures, a warning is printed
90 but the function continues pasting further figures.
92 but the function continues pasting further figures.
91
93
92 Parameters
94 Parameters
93 ----------
95 ----------
94 figs : tuple
96 figs : tuple
95 A tuple of ints giving the figure numbers of the figures to return.
97 A tuple of ints giving the figure numbers of the figures to return.
96 """
98 """
97 from matplotlib._pylab_helpers import Gcf
99 from matplotlib._pylab_helpers import Gcf
98 if not fig_nums:
100 if not fig_nums:
99 fig_managers = Gcf.get_all_fig_managers()
101 fig_managers = Gcf.get_all_fig_managers()
100 return [fm.canvas.figure for fm in fig_managers]
102 return [fm.canvas.figure for fm in fig_managers]
101 else:
103 else:
102 figs = []
104 figs = []
103 for num in fig_nums:
105 for num in fig_nums:
104 f = Gcf.figs.get(num)
106 f = Gcf.figs.get(num)
105 if f is None:
107 if f is None:
106 print('Warning: figure %s not available.' % num)
108 print('Warning: figure %s not available.' % num)
107 else:
109 else:
108 figs.append(f.canvas.figure)
110 figs.append(f.canvas.figure)
109 return figs
111 return figs
110
112
111
113
112 def figsize(sizex, sizey):
114 def figsize(sizex, sizey):
113 """Set the default figure size to be [sizex, sizey].
115 """Set the default figure size to be [sizex, sizey].
114
116
115 This is just an easy to remember, convenience wrapper that sets::
117 This is just an easy to remember, convenience wrapper that sets::
116
118
117 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
119 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
118 """
120 """
119 import matplotlib
121 import matplotlib
120 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
122 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
121
123
122
124
123 def print_figure(fig, fmt="png", bbox_inches="tight", base64=False, **kwargs):
125 def print_figure(fig, fmt="png", bbox_inches="tight", base64=False, **kwargs):
124 """Print a figure to an image, and return the resulting file data
126 """Print a figure to an image, and return the resulting file data
125
127
126 Returned data will be bytes unless ``fmt='svg'``,
128 Returned data will be bytes unless ``fmt='svg'``,
127 in which case it will be unicode.
129 in which case it will be unicode.
128
130
129 Any keyword args are passed to fig.canvas.print_figure,
131 Any keyword args are passed to fig.canvas.print_figure,
130 such as ``quality`` or ``bbox_inches``.
132 such as ``quality`` or ``bbox_inches``.
131
133
132 If `base64` is True, return base64-encoded str instead of raw bytes
134 If `base64` is True, return base64-encoded str instead of raw bytes
133 for binary-encoded image formats
135 for binary-encoded image formats
134
136
135 .. versionadded:: 7.29
137 .. versionadded:: 7.29
136 base64 argument
138 base64 argument
137 """
139 """
138 # When there's an empty figure, we shouldn't return anything, otherwise we
140 # When there's an empty figure, we shouldn't return anything, otherwise we
139 # get big blank areas in the qt console.
141 # get big blank areas in the qt console.
140 if not fig.axes and not fig.lines:
142 if not fig.axes and not fig.lines:
141 return
143 return
142
144
143 dpi = fig.dpi
145 dpi = fig.dpi
144 if fmt == 'retina':
146 if fmt == 'retina':
145 dpi = dpi * 2
147 dpi = dpi * 2
146 fmt = 'png'
148 fmt = 'png'
147
149
148 # build keyword args
150 # build keyword args
149 kw = {
151 kw = {
150 "format":fmt,
152 "format":fmt,
151 "facecolor":fig.get_facecolor(),
153 "facecolor":fig.get_facecolor(),
152 "edgecolor":fig.get_edgecolor(),
154 "edgecolor":fig.get_edgecolor(),
153 "dpi":dpi,
155 "dpi":dpi,
154 "bbox_inches":bbox_inches,
156 "bbox_inches":bbox_inches,
155 }
157 }
156 # **kwargs get higher priority
158 # **kwargs get higher priority
157 kw.update(kwargs)
159 kw.update(kwargs)
158
160
159 bytes_io = BytesIO()
161 bytes_io = BytesIO()
160 if fig.canvas is None:
162 if fig.canvas is None:
161 from matplotlib.backend_bases import FigureCanvasBase
163 from matplotlib.backend_bases import FigureCanvasBase
162 FigureCanvasBase(fig)
164 FigureCanvasBase(fig)
163
165
164 fig.canvas.print_figure(bytes_io, **kw)
166 fig.canvas.print_figure(bytes_io, **kw)
165 data = bytes_io.getvalue()
167 data = bytes_io.getvalue()
166 if fmt == 'svg':
168 if fmt == 'svg':
167 data = data.decode('utf-8')
169 data = data.decode('utf-8')
168 elif base64:
170 elif base64:
169 data = b2a_base64(data, newline=False).decode("ascii")
171 data = b2a_base64(data, newline=False).decode("ascii")
170 return data
172 return data
171
173
172 def retina_figure(fig, base64=False, **kwargs):
174 def retina_figure(fig, base64=False, **kwargs):
173 """format a figure as a pixel-doubled (retina) PNG
175 """format a figure as a pixel-doubled (retina) PNG
174
176
175 If `base64` is True, return base64-encoded str instead of raw bytes
177 If `base64` is True, return base64-encoded str instead of raw bytes
176 for binary-encoded image formats
178 for binary-encoded image formats
177
179
178 .. versionadded:: 7.29
180 .. versionadded:: 7.29
179 base64 argument
181 base64 argument
180 """
182 """
181 pngdata = print_figure(fig, fmt="retina", base64=False, **kwargs)
183 pngdata = print_figure(fig, fmt="retina", base64=False, **kwargs)
182 # Make sure that retina_figure acts just like print_figure and returns
184 # Make sure that retina_figure acts just like print_figure and returns
183 # None when the figure is empty.
185 # None when the figure is empty.
184 if pngdata is None:
186 if pngdata is None:
185 return
187 return
186 w, h = _pngxy(pngdata)
188 w, h = _pngxy(pngdata)
187 metadata = {"width": w//2, "height":h//2}
189 metadata = {"width": w//2, "height":h//2}
188 if base64:
190 if base64:
189 pngdata = b2a_base64(pngdata, newline=False).decode("ascii")
191 pngdata = b2a_base64(pngdata, newline=False).decode("ascii")
190 return pngdata, metadata
192 return pngdata, metadata
191
193
192
194
193 # We need a little factory function here to create the closure where
195 # We need a little factory function here to create the closure where
194 # safe_execfile can live.
196 # safe_execfile can live.
195 def mpl_runner(safe_execfile):
197 def mpl_runner(safe_execfile):
196 """Factory to return a matplotlib-enabled runner for %run.
198 """Factory to return a matplotlib-enabled runner for %run.
197
199
198 Parameters
200 Parameters
199 ----------
201 ----------
200 safe_execfile : function
202 safe_execfile : function
201 This must be a function with the same interface as the
203 This must be a function with the same interface as the
202 :meth:`safe_execfile` method of IPython.
204 :meth:`safe_execfile` method of IPython.
203
205
204 Returns
206 Returns
205 -------
207 -------
206 A function suitable for use as the ``runner`` argument of the %run magic
208 A function suitable for use as the ``runner`` argument of the %run magic
207 function.
209 function.
208 """
210 """
209
211
210 def mpl_execfile(fname,*where,**kw):
212 def mpl_execfile(fname,*where,**kw):
211 """matplotlib-aware wrapper around safe_execfile.
213 """matplotlib-aware wrapper around safe_execfile.
212
214
213 Its interface is identical to that of the :func:`execfile` builtin.
215 Its interface is identical to that of the :func:`execfile` builtin.
214
216
215 This is ultimately a call to execfile(), but wrapped in safeties to
217 This is ultimately a call to execfile(), but wrapped in safeties to
216 properly handle interactive rendering."""
218 properly handle interactive rendering."""
217
219
218 import matplotlib
220 import matplotlib
219 import matplotlib.pyplot as plt
221 import matplotlib.pyplot as plt
220
222
221 #print '*** Matplotlib runner ***' # dbg
223 #print '*** Matplotlib runner ***' # dbg
222 # turn off rendering until end of script
224 # turn off rendering until end of script
223 with matplotlib.rc_context({"interactive": False}):
225 with matplotlib.rc_context({"interactive": False}):
224 safe_execfile(fname, *where, **kw)
226 safe_execfile(fname, *where, **kw)
225
227
226 if matplotlib.is_interactive():
228 if matplotlib.is_interactive():
227 plt.show()
229 plt.show()
228
230
229 # make rendering call now, if the user tried to do it
231 # make rendering call now, if the user tried to do it
230 if plt.draw_if_interactive.called:
232 if plt.draw_if_interactive.called:
231 plt.draw()
233 plt.draw()
232 plt.draw_if_interactive.called = False
234 plt.draw_if_interactive.called = False
233
235
234 # re-draw everything that is stale
236 # re-draw everything that is stale
235 try:
237 try:
236 da = plt.draw_all
238 da = plt.draw_all
237 except AttributeError:
239 except AttributeError:
238 pass
240 pass
239 else:
241 else:
240 da()
242 da()
241
243
242 return mpl_execfile
244 return mpl_execfile
243
245
244
246
245 def _reshow_nbagg_figure(fig):
247 def _reshow_nbagg_figure(fig):
246 """reshow an nbagg figure"""
248 """reshow an nbagg figure"""
247 try:
249 try:
248 reshow = fig.canvas.manager.reshow
250 reshow = fig.canvas.manager.reshow
249 except AttributeError as e:
251 except AttributeError as e:
250 raise NotImplementedError() from e
252 raise NotImplementedError() from e
251 else:
253 else:
252 reshow()
254 reshow()
253
255
254
256
255 def select_figure_formats(shell, formats, **kwargs):
257 def select_figure_formats(shell, formats, **kwargs):
256 """Select figure formats for the inline backend.
258 """Select figure formats for the inline backend.
257
259
258 Parameters
260 Parameters
259 ----------
261 ----------
260 shell : InteractiveShell
262 shell : InteractiveShell
261 The main IPython instance.
263 The main IPython instance.
262 formats : str or set
264 formats : str or set
263 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
265 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
264 **kwargs : any
266 **kwargs : any
265 Extra keyword arguments to be passed to fig.canvas.print_figure.
267 Extra keyword arguments to be passed to fig.canvas.print_figure.
266 """
268 """
267 import matplotlib
269 import matplotlib
268 from matplotlib.figure import Figure
270 from matplotlib.figure import Figure
269
271
270 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
272 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
271 png_formatter = shell.display_formatter.formatters['image/png']
273 png_formatter = shell.display_formatter.formatters['image/png']
272 jpg_formatter = shell.display_formatter.formatters['image/jpeg']
274 jpg_formatter = shell.display_formatter.formatters['image/jpeg']
273 pdf_formatter = shell.display_formatter.formatters['application/pdf']
275 pdf_formatter = shell.display_formatter.formatters['application/pdf']
274
276
275 if isinstance(formats, str):
277 if isinstance(formats, str):
276 formats = {formats}
278 formats = {formats}
277 # cast in case of list / tuple
279 # cast in case of list / tuple
278 formats = set(formats)
280 formats = set(formats)
279
281
280 [ f.pop(Figure, None) for f in shell.display_formatter.formatters.values() ]
282 [ f.pop(Figure, None) for f in shell.display_formatter.formatters.values() ]
281 mplbackend = matplotlib.get_backend().lower()
283 mplbackend = matplotlib.get_backend().lower()
282 if mplbackend in ('nbagg', 'ipympl', 'widget', 'module://ipympl.backend_nbagg'):
284 if mplbackend in ("nbagg", "ipympl", "widget", "module://ipympl.backend_nbagg"):
283 formatter = shell.display_formatter.ipython_display_formatter
285 formatter = shell.display_formatter.ipython_display_formatter
284 formatter.for_type(Figure, _reshow_nbagg_figure)
286 formatter.for_type(Figure, _reshow_nbagg_figure)
285
287
286 supported = {'png', 'png2x', 'retina', 'jpg', 'jpeg', 'svg', 'pdf'}
288 supported = {'png', 'png2x', 'retina', 'jpg', 'jpeg', 'svg', 'pdf'}
287 bad = formats.difference(supported)
289 bad = formats.difference(supported)
288 if bad:
290 if bad:
289 bs = "%s" % ','.join([repr(f) for f in bad])
291 bs = "%s" % ','.join([repr(f) for f in bad])
290 gs = "%s" % ','.join([repr(f) for f in supported])
292 gs = "%s" % ','.join([repr(f) for f in supported])
291 raise ValueError("supported formats are: %s not %s" % (gs, bs))
293 raise ValueError("supported formats are: %s not %s" % (gs, bs))
292
294
293 if "png" in formats:
295 if "png" in formats:
294 png_formatter.for_type(
296 png_formatter.for_type(
295 Figure, partial(print_figure, fmt="png", base64=True, **kwargs)
297 Figure, partial(print_figure, fmt="png", base64=True, **kwargs)
296 )
298 )
297 if "retina" in formats or "png2x" in formats:
299 if "retina" in formats or "png2x" in formats:
298 png_formatter.for_type(Figure, partial(retina_figure, base64=True, **kwargs))
300 png_formatter.for_type(Figure, partial(retina_figure, base64=True, **kwargs))
299 if "jpg" in formats or "jpeg" in formats:
301 if "jpg" in formats or "jpeg" in formats:
300 jpg_formatter.for_type(
302 jpg_formatter.for_type(
301 Figure, partial(print_figure, fmt="jpg", base64=True, **kwargs)
303 Figure, partial(print_figure, fmt="jpg", base64=True, **kwargs)
302 )
304 )
303 if "svg" in formats:
305 if "svg" in formats:
304 svg_formatter.for_type(Figure, partial(print_figure, fmt="svg", **kwargs))
306 svg_formatter.for_type(Figure, partial(print_figure, fmt="svg", **kwargs))
305 if "pdf" in formats:
307 if "pdf" in formats:
306 pdf_formatter.for_type(
308 pdf_formatter.for_type(
307 Figure, partial(print_figure, fmt="pdf", base64=True, **kwargs)
309 Figure, partial(print_figure, fmt="pdf", base64=True, **kwargs)
308 )
310 )
309
311
310 #-----------------------------------------------------------------------------
312 #-----------------------------------------------------------------------------
311 # Code for initializing matplotlib and importing pylab
313 # Code for initializing matplotlib and importing pylab
312 #-----------------------------------------------------------------------------
314 #-----------------------------------------------------------------------------
313
315
314
316
315 def find_gui_and_backend(gui=None, gui_select=None):
317 def find_gui_and_backend(gui=None, gui_select=None):
316 """Given a gui string return the gui and mpl backend.
318 """Given a gui string return the gui and mpl backend.
317
319
318 Parameters
320 Parameters
319 ----------
321 ----------
320 gui : str
322 gui : str
321 Can be one of ('tk','gtk','wx','qt','qt4','inline','agg').
323 Can be one of ('tk','gtk','wx','qt','qt4','inline','agg').
322 gui_select : str
324 gui_select : str
323 Can be one of ('tk','gtk','wx','qt','qt4','inline').
325 Can be one of ('tk','gtk','wx','qt','qt4','inline').
324 This is any gui already selected by the shell.
326 This is any gui already selected by the shell.
325
327
326 Returns
328 Returns
327 -------
329 -------
328 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
330 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
329 'WXAgg','Qt4Agg','module://matplotlib_inline.backend_inline','agg').
331 'WXAgg','Qt4Agg','module://matplotlib_inline.backend_inline','agg').
330 """
332 """
331
333
332 import matplotlib
334 import matplotlib
335
333 if _matplotlib_manages_backends():
336 if _matplotlib_manages_backends():
334 backend_registry = matplotlib.backends.registry.backend_registry
337 backend_registry = matplotlib.backends.registry.backend_registry
335
338
336 # gui argument may be a gui event loop or may be a backend name.
339 # gui argument may be a gui event loop or may be a backend name.
337 if gui in ("auto", None):
340 if gui in ("auto", None):
338 backend = matplotlib.rcParamsOrig['backend']
341 backend = matplotlib.rcParamsOrig["backend"]
339 backend, gui = backend_registry.resolve_backend(backend)
342 backend, gui = backend_registry.resolve_backend(backend)
340 else:
343 else:
341 backend, gui = backend_registry.resolve_gui_or_backend(gui)
344 backend, gui = backend_registry.resolve_gui_or_backend(gui)
342
345
343 return gui, backend
346 return gui, backend
344
347
345 # Fallback to previous behaviour (Matplotlib < 3.9)
348 # Fallback to previous behaviour (Matplotlib < 3.9)
346 mpl_version_info = getattr(matplotlib, "__version_info__", (0, 0))
349 mpl_version_info = getattr(matplotlib, "__version_info__", (0, 0))
347 has_unified_qt_backend = mpl_version_info >= (3, 5)
350 has_unified_qt_backend = mpl_version_info >= (3, 5)
348
351
349 from IPython.core.pylabtools import backends
352 from IPython.core.pylabtools import backends
353
350 backends_ = dict(backends)
354 backends_ = dict(backends)
351 if not has_unified_qt_backend:
355 if not has_unified_qt_backend:
352 backends_["qt"] = "qt5agg"
356 backends_["qt"] = "qt5agg"
353
357
354 if gui and gui != 'auto':
358 if gui and gui != 'auto':
355 # select backend based on requested gui
359 # select backend based on requested gui
356 backend = backends_[gui]
360 backend = backends_[gui]
357 if gui == 'agg':
361 if gui == 'agg':
358 gui = None
362 gui = None
359 else:
363 else:
360 # We need to read the backend from the original data structure, *not*
364 # We need to read the backend from the original data structure, *not*
361 # from mpl.rcParams, since a prior invocation of %matplotlib may have
365 # from mpl.rcParams, since a prior invocation of %matplotlib may have
362 # overwritten that.
366 # overwritten that.
363 # WARNING: this assumes matplotlib 1.1 or newer!!
367 # WARNING: this assumes matplotlib 1.1 or newer!!
364 backend = matplotlib.rcParamsOrig['backend']
368 backend = matplotlib.rcParamsOrig['backend']
365 # In this case, we need to find what the appropriate gui selection call
369 # In this case, we need to find what the appropriate gui selection call
366 # should be for IPython, so we can activate inputhook accordingly
370 # should be for IPython, so we can activate inputhook accordingly
367 from IPython.core.pylabtools import backend2gui
371 from IPython.core.pylabtools import backend2gui
368 gui = backend2gui.get(backend, None)
372 gui = backend2gui.get(backend, None)
369
373
370 # If we have already had a gui active, we need it and inline are the
374 # If we have already had a gui active, we need it and inline are the
371 # ones allowed.
375 # ones allowed.
372 if gui_select and gui != gui_select:
376 if gui_select and gui != gui_select:
373 gui = gui_select
377 gui = gui_select
374 backend = backends_[gui]
378 backend = backends_[gui]
375
379
376 # Since IPython 8.23.0 use None for no gui event loop rather than "inline".
380 # Since IPython 8.23.0 use None for no gui event loop rather than "inline".
377 if gui == "inline":
381 if gui == "inline":
378 gui = None
382 gui = None
379
383
380 return gui, backend
384 return gui, backend
381
385
382
386
383 def activate_matplotlib(backend):
387 def activate_matplotlib(backend):
384 """Activate the given backend and set interactive to True."""
388 """Activate the given backend and set interactive to True."""
385
389
386 import matplotlib
390 import matplotlib
387 matplotlib.interactive(True)
391 matplotlib.interactive(True)
388
392
389 # Matplotlib had a bug where even switch_backend could not force
393 # Matplotlib had a bug where even switch_backend could not force
390 # the rcParam to update. This needs to be set *before* the module
394 # the rcParam to update. This needs to be set *before* the module
391 # magic of switch_backend().
395 # magic of switch_backend().
392 matplotlib.rcParams['backend'] = backend
396 matplotlib.rcParams['backend'] = backend
393
397
394 # Due to circular imports, pyplot may be only partially initialised
398 # Due to circular imports, pyplot may be only partially initialised
395 # when this function runs.
399 # when this function runs.
396 # So avoid needing matplotlib attribute-lookup to access pyplot.
400 # So avoid needing matplotlib attribute-lookup to access pyplot.
397 from matplotlib import pyplot as plt
401 from matplotlib import pyplot as plt
398
402
399 plt.switch_backend(backend)
403 plt.switch_backend(backend)
400
404
401 plt.show._needmain = False
405 plt.show._needmain = False
402 # We need to detect at runtime whether show() is called by the user.
406 # We need to detect at runtime whether show() is called by the user.
403 # For this, we wrap it into a decorator which adds a 'called' flag.
407 # For this, we wrap it into a decorator which adds a 'called' flag.
404 plt.draw_if_interactive = flag_calls(plt.draw_if_interactive)
408 plt.draw_if_interactive = flag_calls(plt.draw_if_interactive)
405
409
406
410
407 def import_pylab(user_ns, import_all=True):
411 def import_pylab(user_ns, import_all=True):
408 """Populate the namespace with pylab-related values.
412 """Populate the namespace with pylab-related values.
409
413
410 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
414 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
411
415
412 Also imports a few names from IPython (figsize, display, getfigs)
416 Also imports a few names from IPython (figsize, display, getfigs)
413
417
414 """
418 """
415
419
416 # Import numpy as np/pyplot as plt are conventions we're trying to
420 # Import numpy as np/pyplot as plt are conventions we're trying to
417 # somewhat standardize on. Making them available to users by default
421 # somewhat standardize on. Making them available to users by default
418 # will greatly help this.
422 # will greatly help this.
419 s = ("import numpy\n"
423 s = ("import numpy\n"
420 "import matplotlib\n"
424 "import matplotlib\n"
421 "from matplotlib import pylab, mlab, pyplot\n"
425 "from matplotlib import pylab, mlab, pyplot\n"
422 "np = numpy\n"
426 "np = numpy\n"
423 "plt = pyplot\n"
427 "plt = pyplot\n"
424 )
428 )
425 exec(s, user_ns)
429 exec(s, user_ns)
426
430
427 if import_all:
431 if import_all:
428 s = ("from matplotlib.pylab import *\n"
432 s = ("from matplotlib.pylab import *\n"
429 "from numpy import *\n")
433 "from numpy import *\n")
430 exec(s, user_ns)
434 exec(s, user_ns)
431
435
432 # IPython symbols to add
436 # IPython symbols to add
433 user_ns['figsize'] = figsize
437 user_ns['figsize'] = figsize
434 from IPython.display import display
438 from IPython.display import display
435 # Add display and getfigs to the user's namespace
439 # Add display and getfigs to the user's namespace
436 user_ns['display'] = display
440 user_ns['display'] = display
437 user_ns['getfigs'] = getfigs
441 user_ns['getfigs'] = getfigs
438
442
439
443
440 def configure_inline_support(shell, backend):
444 def configure_inline_support(shell, backend):
441 """
445 """
442 .. deprecated:: 7.23
446 .. deprecated:: 7.23
443
447
444 use `matplotlib_inline.backend_inline.configure_inline_support()`
448 use `matplotlib_inline.backend_inline.configure_inline_support()`
445
449
446 Configure an IPython shell object for matplotlib use.
450 Configure an IPython shell object for matplotlib use.
447
451
448 Parameters
452 Parameters
449 ----------
453 ----------
450 shell : InteractiveShell instance
454 shell : InteractiveShell instance
451 backend : matplotlib backend
455 backend : matplotlib backend
452 """
456 """
453 warnings.warn(
457 warnings.warn(
454 "`configure_inline_support` is deprecated since IPython 7.23, directly "
458 "`configure_inline_support` is deprecated since IPython 7.23, directly "
455 "use `matplotlib_inline.backend_inline.configure_inline_support()`",
459 "use `matplotlib_inline.backend_inline.configure_inline_support()`",
456 DeprecationWarning,
460 DeprecationWarning,
457 stacklevel=2,
461 stacklevel=2,
458 )
462 )
459
463
460 from matplotlib_inline.backend_inline import (
464 from matplotlib_inline.backend_inline import (
461 configure_inline_support as configure_inline_support_orig,
465 configure_inline_support as configure_inline_support_orig,
462 )
466 )
463
467
464 configure_inline_support_orig(shell, backend)
468 configure_inline_support_orig(shell, backend)
465
469
466
470
467 def _matplotlib_manages_backends():
471 def _matplotlib_manages_backends():
468 import matplotlib
472 import matplotlib
473
469 mpl_version_info = getattr(matplotlib, "__version_info__", (0, 0))
474 mpl_version_info = getattr(matplotlib, "__version_info__", (0, 0))
470 return mpl_version_info >= (3, 9)
475 return mpl_version_info >= (3, 9)
@@ -1,450 +1,450 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 A mixin for :class:`~IPython.core.application.Application` classes that
3 A mixin for :class:`~IPython.core.application.Application` classes that
4 launch InteractiveShell instances, load extensions, etc.
4 launch InteractiveShell instances, load extensions, etc.
5 """
5 """
6
6
7 # Copyright (c) IPython Development Team.
7 # Copyright (c) IPython Development Team.
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9
9
10 import glob
10 import glob
11 from itertools import chain
11 from itertools import chain
12 import os
12 import os
13 import sys
13 import sys
14
14
15 from traitlets.config.application import boolean_flag
15 from traitlets.config.application import boolean_flag
16 from traitlets.config.configurable import Configurable
16 from traitlets.config.configurable import Configurable
17 from traitlets.config.loader import Config
17 from traitlets.config.loader import Config
18 from IPython.core.application import SYSTEM_CONFIG_DIRS, ENV_CONFIG_DIRS
18 from IPython.core.application import SYSTEM_CONFIG_DIRS, ENV_CONFIG_DIRS
19 from IPython.core import pylabtools
19 from IPython.core import pylabtools
20 from IPython.utils.contexts import preserve_keys
20 from IPython.utils.contexts import preserve_keys
21 from IPython.utils.path import filefind
21 from IPython.utils.path import filefind
22 from traitlets import (
22 from traitlets import (
23 Unicode, Instance, List, Bool, CaselessStrEnum, observe,
23 Unicode, Instance, List, Bool, CaselessStrEnum, observe,
24 DottedObjectName,
24 DottedObjectName,
25 )
25 )
26 from IPython.terminal import pt_inputhooks
26 from IPython.terminal import pt_inputhooks
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Aliases and Flags
29 # Aliases and Flags
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32 gui_keys = tuple(sorted(pt_inputhooks.backends) + sorted(pt_inputhooks.aliases))
32 gui_keys = tuple(sorted(pt_inputhooks.backends) + sorted(pt_inputhooks.aliases))
33
33
34 backend_keys = []
34 backend_keys: list[str] = []
35
35
36 shell_flags = {}
36 shell_flags = {}
37
37
38 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
38 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
39 addflag('autoindent', 'InteractiveShell.autoindent',
39 addflag('autoindent', 'InteractiveShell.autoindent',
40 'Turn on autoindenting.', 'Turn off autoindenting.'
40 'Turn on autoindenting.', 'Turn off autoindenting.'
41 )
41 )
42 addflag('automagic', 'InteractiveShell.automagic',
42 addflag('automagic', 'InteractiveShell.automagic',
43 """Turn on the auto calling of magic commands. Type %%magic at the
43 """Turn on the auto calling of magic commands. Type %%magic at the
44 IPython prompt for more information.""",
44 IPython prompt for more information.""",
45 'Turn off the auto calling of magic commands.'
45 'Turn off the auto calling of magic commands.'
46 )
46 )
47 addflag('pdb', 'InteractiveShell.pdb',
47 addflag('pdb', 'InteractiveShell.pdb',
48 "Enable auto calling the pdb debugger after every exception.",
48 "Enable auto calling the pdb debugger after every exception.",
49 "Disable auto calling the pdb debugger after every exception."
49 "Disable auto calling the pdb debugger after every exception."
50 )
50 )
51 addflag('pprint', 'PlainTextFormatter.pprint',
51 addflag('pprint', 'PlainTextFormatter.pprint',
52 "Enable auto pretty printing of results.",
52 "Enable auto pretty printing of results.",
53 "Disable auto pretty printing of results."
53 "Disable auto pretty printing of results."
54 )
54 )
55 addflag('color-info', 'InteractiveShell.color_info',
55 addflag('color-info', 'InteractiveShell.color_info',
56 """IPython can display information about objects via a set of functions,
56 """IPython can display information about objects via a set of functions,
57 and optionally can use colors for this, syntax highlighting
57 and optionally can use colors for this, syntax highlighting
58 source code and various other elements. This is on by default, but can cause
58 source code and various other elements. This is on by default, but can cause
59 problems with some pagers. If you see such problems, you can disable the
59 problems with some pagers. If you see such problems, you can disable the
60 colours.""",
60 colours.""",
61 "Disable using colors for info related things."
61 "Disable using colors for info related things."
62 )
62 )
63 addflag('ignore-cwd', 'InteractiveShellApp.ignore_cwd',
63 addflag('ignore-cwd', 'InteractiveShellApp.ignore_cwd',
64 "Exclude the current working directory from sys.path",
64 "Exclude the current working directory from sys.path",
65 "Include the current working directory in sys.path",
65 "Include the current working directory in sys.path",
66 )
66 )
67 nosep_config = Config()
67 nosep_config = Config()
68 nosep_config.InteractiveShell.separate_in = ''
68 nosep_config.InteractiveShell.separate_in = ''
69 nosep_config.InteractiveShell.separate_out = ''
69 nosep_config.InteractiveShell.separate_out = ''
70 nosep_config.InteractiveShell.separate_out2 = ''
70 nosep_config.InteractiveShell.separate_out2 = ''
71
71
72 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
72 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
73 shell_flags['pylab'] = (
73 shell_flags['pylab'] = (
74 {'InteractiveShellApp' : {'pylab' : 'auto'}},
74 {'InteractiveShellApp' : {'pylab' : 'auto'}},
75 """Pre-load matplotlib and numpy for interactive use with
75 """Pre-load matplotlib and numpy for interactive use with
76 the default matplotlib backend."""
76 the default matplotlib backend."""
77 )
77 )
78 shell_flags['matplotlib'] = (
78 shell_flags['matplotlib'] = (
79 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
79 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
80 """Configure matplotlib for interactive use with
80 """Configure matplotlib for interactive use with
81 the default matplotlib backend."""
81 the default matplotlib backend."""
82 )
82 )
83
83
84 # it's possible we don't want short aliases for *all* of these:
84 # it's possible we don't want short aliases for *all* of these:
85 shell_aliases = dict(
85 shell_aliases = dict(
86 autocall='InteractiveShell.autocall',
86 autocall='InteractiveShell.autocall',
87 colors='InteractiveShell.colors',
87 colors='InteractiveShell.colors',
88 logfile='InteractiveShell.logfile',
88 logfile='InteractiveShell.logfile',
89 logappend='InteractiveShell.logappend',
89 logappend='InteractiveShell.logappend',
90 c='InteractiveShellApp.code_to_run',
90 c='InteractiveShellApp.code_to_run',
91 m='InteractiveShellApp.module_to_run',
91 m='InteractiveShellApp.module_to_run',
92 ext="InteractiveShellApp.extra_extensions",
92 ext="InteractiveShellApp.extra_extensions",
93 gui='InteractiveShellApp.gui',
93 gui='InteractiveShellApp.gui',
94 pylab='InteractiveShellApp.pylab',
94 pylab='InteractiveShellApp.pylab',
95 matplotlib='InteractiveShellApp.matplotlib',
95 matplotlib='InteractiveShellApp.matplotlib',
96 )
96 )
97 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
97 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
98
98
99 #-----------------------------------------------------------------------------
99 #-----------------------------------------------------------------------------
100 # Main classes and functions
100 # Main classes and functions
101 #-----------------------------------------------------------------------------
101 #-----------------------------------------------------------------------------
102
102
103 class InteractiveShellApp(Configurable):
103 class InteractiveShellApp(Configurable):
104 """A Mixin for applications that start InteractiveShell instances.
104 """A Mixin for applications that start InteractiveShell instances.
105
105
106 Provides configurables for loading extensions and executing files
106 Provides configurables for loading extensions and executing files
107 as part of configuring a Shell environment.
107 as part of configuring a Shell environment.
108
108
109 The following methods should be called by the :meth:`initialize` method
109 The following methods should be called by the :meth:`initialize` method
110 of the subclass:
110 of the subclass:
111
111
112 - :meth:`init_path`
112 - :meth:`init_path`
113 - :meth:`init_shell` (to be implemented by the subclass)
113 - :meth:`init_shell` (to be implemented by the subclass)
114 - :meth:`init_gui_pylab`
114 - :meth:`init_gui_pylab`
115 - :meth:`init_extensions`
115 - :meth:`init_extensions`
116 - :meth:`init_code`
116 - :meth:`init_code`
117 """
117 """
118 extensions = List(Unicode(),
118 extensions = List(Unicode(),
119 help="A list of dotted module names of IPython extensions to load."
119 help="A list of dotted module names of IPython extensions to load."
120 ).tag(config=True)
120 ).tag(config=True)
121
121
122 extra_extensions = List(
122 extra_extensions = List(
123 DottedObjectName(),
123 DottedObjectName(),
124 help="""
124 help="""
125 Dotted module name(s) of one or more IPython extensions to load.
125 Dotted module name(s) of one or more IPython extensions to load.
126
126
127 For specifying extra extensions to load on the command-line.
127 For specifying extra extensions to load on the command-line.
128
128
129 .. versionadded:: 7.10
129 .. versionadded:: 7.10
130 """,
130 """,
131 ).tag(config=True)
131 ).tag(config=True)
132
132
133 reraise_ipython_extension_failures = Bool(False,
133 reraise_ipython_extension_failures = Bool(False,
134 help="Reraise exceptions encountered loading IPython extensions?",
134 help="Reraise exceptions encountered loading IPython extensions?",
135 ).tag(config=True)
135 ).tag(config=True)
136
136
137 # Extensions that are always loaded (not configurable)
137 # Extensions that are always loaded (not configurable)
138 default_extensions = List(Unicode(), [u'storemagic']).tag(config=False)
138 default_extensions = List(Unicode(), [u'storemagic']).tag(config=False)
139
139
140 hide_initial_ns = Bool(True,
140 hide_initial_ns = Bool(True,
141 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
141 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
142 be hidden from tools like %who?"""
142 be hidden from tools like %who?"""
143 ).tag(config=True)
143 ).tag(config=True)
144
144
145 exec_files = List(Unicode(),
145 exec_files = List(Unicode(),
146 help="""List of files to run at IPython startup."""
146 help="""List of files to run at IPython startup."""
147 ).tag(config=True)
147 ).tag(config=True)
148 exec_PYTHONSTARTUP = Bool(True,
148 exec_PYTHONSTARTUP = Bool(True,
149 help="""Run the file referenced by the PYTHONSTARTUP environment
149 help="""Run the file referenced by the PYTHONSTARTUP environment
150 variable at IPython startup."""
150 variable at IPython startup."""
151 ).tag(config=True)
151 ).tag(config=True)
152 file_to_run = Unicode('',
152 file_to_run = Unicode('',
153 help="""A file to be run""").tag(config=True)
153 help="""A file to be run""").tag(config=True)
154
154
155 exec_lines = List(Unicode(),
155 exec_lines = List(Unicode(),
156 help="""lines of code to run at IPython startup."""
156 help="""lines of code to run at IPython startup."""
157 ).tag(config=True)
157 ).tag(config=True)
158 code_to_run = Unicode('',
158 code_to_run = Unicode('',
159 help="Execute the given command string."
159 help="Execute the given command string."
160 ).tag(config=True)
160 ).tag(config=True)
161 module_to_run = Unicode('',
161 module_to_run = Unicode('',
162 help="Run the module as a script."
162 help="Run the module as a script."
163 ).tag(config=True)
163 ).tag(config=True)
164 gui = CaselessStrEnum(gui_keys, allow_none=True,
164 gui = CaselessStrEnum(gui_keys, allow_none=True,
165 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
165 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
166 ).tag(config=True)
166 ).tag(config=True)
167 matplotlib = CaselessStrEnum(backend_keys, allow_none=True,
167 matplotlib = CaselessStrEnum(backend_keys, allow_none=True,
168 help="""Configure matplotlib for interactive use with
168 help="""Configure matplotlib for interactive use with
169 the default matplotlib backend."""
169 the default matplotlib backend."""
170 ).tag(config=True)
170 ).tag(config=True)
171 pylab = CaselessStrEnum(backend_keys, allow_none=True,
171 pylab = CaselessStrEnum(backend_keys, allow_none=True,
172 help="""Pre-load matplotlib and numpy for interactive use,
172 help="""Pre-load matplotlib and numpy for interactive use,
173 selecting a particular matplotlib backend and loop integration.
173 selecting a particular matplotlib backend and loop integration.
174 """
174 """
175 ).tag(config=True)
175 ).tag(config=True)
176 pylab_import_all = Bool(True,
176 pylab_import_all = Bool(True,
177 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
177 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
178 and an ``import *`` is done from numpy and pylab, when using pylab mode.
178 and an ``import *`` is done from numpy and pylab, when using pylab mode.
179
179
180 When False, pylab mode should not import any names into the user namespace.
180 When False, pylab mode should not import any names into the user namespace.
181 """
181 """
182 ).tag(config=True)
182 ).tag(config=True)
183 ignore_cwd = Bool(
183 ignore_cwd = Bool(
184 False,
184 False,
185 help="""If True, IPython will not add the current working directory to sys.path.
185 help="""If True, IPython will not add the current working directory to sys.path.
186 When False, the current working directory is added to sys.path, allowing imports
186 When False, the current working directory is added to sys.path, allowing imports
187 of modules defined in the current directory."""
187 of modules defined in the current directory."""
188 ).tag(config=True)
188 ).tag(config=True)
189 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
189 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
190 allow_none=True)
190 allow_none=True)
191 # whether interact-loop should start
191 # whether interact-loop should start
192 interact = Bool(True)
192 interact = Bool(True)
193
193
194 user_ns = Instance(dict, args=None, allow_none=True)
194 user_ns = Instance(dict, args=None, allow_none=True)
195 @observe('user_ns')
195 @observe('user_ns')
196 def _user_ns_changed(self, change):
196 def _user_ns_changed(self, change):
197 if self.shell is not None:
197 if self.shell is not None:
198 self.shell.user_ns = change['new']
198 self.shell.user_ns = change['new']
199 self.shell.init_user_ns()
199 self.shell.init_user_ns()
200
200
201 def init_path(self):
201 def init_path(self):
202 """Add current working directory, '', to sys.path
202 """Add current working directory, '', to sys.path
203
203
204 Unlike Python's default, we insert before the first `site-packages`
204 Unlike Python's default, we insert before the first `site-packages`
205 or `dist-packages` directory,
205 or `dist-packages` directory,
206 so that it is after the standard library.
206 so that it is after the standard library.
207
207
208 .. versionchanged:: 7.2
208 .. versionchanged:: 7.2
209 Try to insert after the standard library, instead of first.
209 Try to insert after the standard library, instead of first.
210 .. versionchanged:: 8.0
210 .. versionchanged:: 8.0
211 Allow optionally not including the current directory in sys.path
211 Allow optionally not including the current directory in sys.path
212 """
212 """
213 if '' in sys.path or self.ignore_cwd:
213 if '' in sys.path or self.ignore_cwd:
214 return
214 return
215 for idx, path in enumerate(sys.path):
215 for idx, path in enumerate(sys.path):
216 parent, last_part = os.path.split(path)
216 parent, last_part = os.path.split(path)
217 if last_part in {'site-packages', 'dist-packages'}:
217 if last_part in {'site-packages', 'dist-packages'}:
218 break
218 break
219 else:
219 else:
220 # no site-packages or dist-packages found (?!)
220 # no site-packages or dist-packages found (?!)
221 # back to original behavior of inserting at the front
221 # back to original behavior of inserting at the front
222 idx = 0
222 idx = 0
223 sys.path.insert(idx, '')
223 sys.path.insert(idx, '')
224
224
225 def init_shell(self):
225 def init_shell(self):
226 raise NotImplementedError("Override in subclasses")
226 raise NotImplementedError("Override in subclasses")
227
227
228 def init_gui_pylab(self):
228 def init_gui_pylab(self):
229 """Enable GUI event loop integration, taking pylab into account."""
229 """Enable GUI event loop integration, taking pylab into account."""
230 enable = False
230 enable = False
231 shell = self.shell
231 shell = self.shell
232 if self.pylab:
232 if self.pylab:
233 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
233 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
234 key = self.pylab
234 key = self.pylab
235 elif self.matplotlib:
235 elif self.matplotlib:
236 enable = shell.enable_matplotlib
236 enable = shell.enable_matplotlib
237 key = self.matplotlib
237 key = self.matplotlib
238 elif self.gui:
238 elif self.gui:
239 enable = shell.enable_gui
239 enable = shell.enable_gui
240 key = self.gui
240 key = self.gui
241
241
242 if not enable:
242 if not enable:
243 return
243 return
244
244
245 try:
245 try:
246 r = enable(key)
246 r = enable(key)
247 except ImportError:
247 except ImportError:
248 self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?")
248 self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?")
249 self.shell.showtraceback()
249 self.shell.showtraceback()
250 return
250 return
251 except Exception:
251 except Exception:
252 self.log.warning("GUI event loop or pylab initialization failed")
252 self.log.warning("GUI event loop or pylab initialization failed")
253 self.shell.showtraceback()
253 self.shell.showtraceback()
254 return
254 return
255
255
256 if isinstance(r, tuple):
256 if isinstance(r, tuple):
257 gui, backend = r[:2]
257 gui, backend = r[:2]
258 self.log.info("Enabling GUI event loop integration, "
258 self.log.info("Enabling GUI event loop integration, "
259 "eventloop=%s, matplotlib=%s", gui, backend)
259 "eventloop=%s, matplotlib=%s", gui, backend)
260 if key == "auto":
260 if key == "auto":
261 print("Using matplotlib backend: %s" % backend)
261 print("Using matplotlib backend: %s" % backend)
262 else:
262 else:
263 gui = r
263 gui = r
264 self.log.info("Enabling GUI event loop integration, "
264 self.log.info("Enabling GUI event loop integration, "
265 "eventloop=%s", gui)
265 "eventloop=%s", gui)
266
266
267 def init_extensions(self):
267 def init_extensions(self):
268 """Load all IPython extensions in IPythonApp.extensions.
268 """Load all IPython extensions in IPythonApp.extensions.
269
269
270 This uses the :meth:`ExtensionManager.load_extensions` to load all
270 This uses the :meth:`ExtensionManager.load_extensions` to load all
271 the extensions listed in ``self.extensions``.
271 the extensions listed in ``self.extensions``.
272 """
272 """
273 try:
273 try:
274 self.log.debug("Loading IPython extensions...")
274 self.log.debug("Loading IPython extensions...")
275 extensions = (
275 extensions = (
276 self.default_extensions + self.extensions + self.extra_extensions
276 self.default_extensions + self.extensions + self.extra_extensions
277 )
277 )
278 for ext in extensions:
278 for ext in extensions:
279 try:
279 try:
280 self.log.info("Loading IPython extension: %s", ext)
280 self.log.info("Loading IPython extension: %s", ext)
281 self.shell.extension_manager.load_extension(ext)
281 self.shell.extension_manager.load_extension(ext)
282 except:
282 except:
283 if self.reraise_ipython_extension_failures:
283 if self.reraise_ipython_extension_failures:
284 raise
284 raise
285 msg = ("Error in loading extension: {ext}\n"
285 msg = ("Error in loading extension: {ext}\n"
286 "Check your config files in {location}".format(
286 "Check your config files in {location}".format(
287 ext=ext,
287 ext=ext,
288 location=self.profile_dir.location
288 location=self.profile_dir.location
289 ))
289 ))
290 self.log.warning(msg, exc_info=True)
290 self.log.warning(msg, exc_info=True)
291 except:
291 except:
292 if self.reraise_ipython_extension_failures:
292 if self.reraise_ipython_extension_failures:
293 raise
293 raise
294 self.log.warning("Unknown error in loading extensions:", exc_info=True)
294 self.log.warning("Unknown error in loading extensions:", exc_info=True)
295
295
296 def init_code(self):
296 def init_code(self):
297 """run the pre-flight code, specified via exec_lines"""
297 """run the pre-flight code, specified via exec_lines"""
298 self._run_startup_files()
298 self._run_startup_files()
299 self._run_exec_lines()
299 self._run_exec_lines()
300 self._run_exec_files()
300 self._run_exec_files()
301
301
302 # Hide variables defined here from %who etc.
302 # Hide variables defined here from %who etc.
303 if self.hide_initial_ns:
303 if self.hide_initial_ns:
304 self.shell.user_ns_hidden.update(self.shell.user_ns)
304 self.shell.user_ns_hidden.update(self.shell.user_ns)
305
305
306 # command-line execution (ipython -i script.py, ipython -m module)
306 # command-line execution (ipython -i script.py, ipython -m module)
307 # should *not* be excluded from %whos
307 # should *not* be excluded from %whos
308 self._run_cmd_line_code()
308 self._run_cmd_line_code()
309 self._run_module()
309 self._run_module()
310
310
311 # flush output, so itwon't be attached to the first cell
311 # flush output, so itwon't be attached to the first cell
312 sys.stdout.flush()
312 sys.stdout.flush()
313 sys.stderr.flush()
313 sys.stderr.flush()
314 self.shell._sys_modules_keys = set(sys.modules.keys())
314 self.shell._sys_modules_keys = set(sys.modules.keys())
315
315
316 def _run_exec_lines(self):
316 def _run_exec_lines(self):
317 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
317 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
318 if not self.exec_lines:
318 if not self.exec_lines:
319 return
319 return
320 try:
320 try:
321 self.log.debug("Running code from IPythonApp.exec_lines...")
321 self.log.debug("Running code from IPythonApp.exec_lines...")
322 for line in self.exec_lines:
322 for line in self.exec_lines:
323 try:
323 try:
324 self.log.info("Running code in user namespace: %s" %
324 self.log.info("Running code in user namespace: %s" %
325 line)
325 line)
326 self.shell.run_cell(line, store_history=False)
326 self.shell.run_cell(line, store_history=False)
327 except:
327 except:
328 self.log.warning("Error in executing line in user "
328 self.log.warning("Error in executing line in user "
329 "namespace: %s" % line)
329 "namespace: %s" % line)
330 self.shell.showtraceback()
330 self.shell.showtraceback()
331 except:
331 except:
332 self.log.warning("Unknown error in handling IPythonApp.exec_lines:")
332 self.log.warning("Unknown error in handling IPythonApp.exec_lines:")
333 self.shell.showtraceback()
333 self.shell.showtraceback()
334
334
335 def _exec_file(self, fname, shell_futures=False):
335 def _exec_file(self, fname, shell_futures=False):
336 try:
336 try:
337 full_filename = filefind(fname, [u'.', self.ipython_dir])
337 full_filename = filefind(fname, [u'.', self.ipython_dir])
338 except IOError:
338 except IOError:
339 self.log.warning("File not found: %r"%fname)
339 self.log.warning("File not found: %r"%fname)
340 return
340 return
341 # Make sure that the running script gets a proper sys.argv as if it
341 # Make sure that the running script gets a proper sys.argv as if it
342 # were run from a system shell.
342 # were run from a system shell.
343 save_argv = sys.argv
343 save_argv = sys.argv
344 sys.argv = [full_filename] + self.extra_args[1:]
344 sys.argv = [full_filename] + self.extra_args[1:]
345 try:
345 try:
346 if os.path.isfile(full_filename):
346 if os.path.isfile(full_filename):
347 self.log.info("Running file in user namespace: %s" %
347 self.log.info("Running file in user namespace: %s" %
348 full_filename)
348 full_filename)
349 # Ensure that __file__ is always defined to match Python
349 # Ensure that __file__ is always defined to match Python
350 # behavior.
350 # behavior.
351 with preserve_keys(self.shell.user_ns, '__file__'):
351 with preserve_keys(self.shell.user_ns, '__file__'):
352 self.shell.user_ns['__file__'] = fname
352 self.shell.user_ns['__file__'] = fname
353 if full_filename.endswith('.ipy') or full_filename.endswith('.ipynb'):
353 if full_filename.endswith('.ipy') or full_filename.endswith('.ipynb'):
354 self.shell.safe_execfile_ipy(full_filename,
354 self.shell.safe_execfile_ipy(full_filename,
355 shell_futures=shell_futures)
355 shell_futures=shell_futures)
356 else:
356 else:
357 # default to python, even without extension
357 # default to python, even without extension
358 self.shell.safe_execfile(full_filename,
358 self.shell.safe_execfile(full_filename,
359 self.shell.user_ns,
359 self.shell.user_ns,
360 shell_futures=shell_futures,
360 shell_futures=shell_futures,
361 raise_exceptions=True)
361 raise_exceptions=True)
362 finally:
362 finally:
363 sys.argv = save_argv
363 sys.argv = save_argv
364
364
365 def _run_startup_files(self):
365 def _run_startup_files(self):
366 """Run files from profile startup directory"""
366 """Run files from profile startup directory"""
367 startup_dirs = [self.profile_dir.startup_dir] + [
367 startup_dirs = [self.profile_dir.startup_dir] + [
368 os.path.join(p, 'startup') for p in chain(ENV_CONFIG_DIRS, SYSTEM_CONFIG_DIRS)
368 os.path.join(p, 'startup') for p in chain(ENV_CONFIG_DIRS, SYSTEM_CONFIG_DIRS)
369 ]
369 ]
370 startup_files = []
370 startup_files = []
371
371
372 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
372 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
373 not (self.file_to_run or self.code_to_run or self.module_to_run):
373 not (self.file_to_run or self.code_to_run or self.module_to_run):
374 python_startup = os.environ['PYTHONSTARTUP']
374 python_startup = os.environ['PYTHONSTARTUP']
375 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
375 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
376 try:
376 try:
377 self._exec_file(python_startup)
377 self._exec_file(python_startup)
378 except:
378 except:
379 self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
379 self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
380 self.shell.showtraceback()
380 self.shell.showtraceback()
381 for startup_dir in startup_dirs[::-1]:
381 for startup_dir in startup_dirs[::-1]:
382 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
382 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
383 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
383 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
384 if not startup_files:
384 if not startup_files:
385 return
385 return
386
386
387 self.log.debug("Running startup files from %s...", startup_dir)
387 self.log.debug("Running startup files from %s...", startup_dir)
388 try:
388 try:
389 for fname in sorted(startup_files):
389 for fname in sorted(startup_files):
390 self._exec_file(fname)
390 self._exec_file(fname)
391 except:
391 except:
392 self.log.warning("Unknown error in handling startup files:")
392 self.log.warning("Unknown error in handling startup files:")
393 self.shell.showtraceback()
393 self.shell.showtraceback()
394
394
395 def _run_exec_files(self):
395 def _run_exec_files(self):
396 """Run files from IPythonApp.exec_files"""
396 """Run files from IPythonApp.exec_files"""
397 if not self.exec_files:
397 if not self.exec_files:
398 return
398 return
399
399
400 self.log.debug("Running files in IPythonApp.exec_files...")
400 self.log.debug("Running files in IPythonApp.exec_files...")
401 try:
401 try:
402 for fname in self.exec_files:
402 for fname in self.exec_files:
403 self._exec_file(fname)
403 self._exec_file(fname)
404 except:
404 except:
405 self.log.warning("Unknown error in handling IPythonApp.exec_files:")
405 self.log.warning("Unknown error in handling IPythonApp.exec_files:")
406 self.shell.showtraceback()
406 self.shell.showtraceback()
407
407
408 def _run_cmd_line_code(self):
408 def _run_cmd_line_code(self):
409 """Run code or file specified at the command-line"""
409 """Run code or file specified at the command-line"""
410 if self.code_to_run:
410 if self.code_to_run:
411 line = self.code_to_run
411 line = self.code_to_run
412 try:
412 try:
413 self.log.info("Running code given at command line (c=): %s" %
413 self.log.info("Running code given at command line (c=): %s" %
414 line)
414 line)
415 self.shell.run_cell(line, store_history=False)
415 self.shell.run_cell(line, store_history=False)
416 except:
416 except:
417 self.log.warning("Error in executing line in user namespace: %s" %
417 self.log.warning("Error in executing line in user namespace: %s" %
418 line)
418 line)
419 self.shell.showtraceback()
419 self.shell.showtraceback()
420 if not self.interact:
420 if not self.interact:
421 self.exit(1)
421 self.exit(1)
422
422
423 # Like Python itself, ignore the second if the first of these is present
423 # Like Python itself, ignore the second if the first of these is present
424 elif self.file_to_run:
424 elif self.file_to_run:
425 fname = self.file_to_run
425 fname = self.file_to_run
426 if os.path.isdir(fname):
426 if os.path.isdir(fname):
427 fname = os.path.join(fname, "__main__.py")
427 fname = os.path.join(fname, "__main__.py")
428 if not os.path.exists(fname):
428 if not os.path.exists(fname):
429 self.log.warning("File '%s' doesn't exist", fname)
429 self.log.warning("File '%s' doesn't exist", fname)
430 if not self.interact:
430 if not self.interact:
431 self.exit(2)
431 self.exit(2)
432 try:
432 try:
433 self._exec_file(fname, shell_futures=True)
433 self._exec_file(fname, shell_futures=True)
434 except:
434 except:
435 self.shell.showtraceback(tb_offset=4)
435 self.shell.showtraceback(tb_offset=4)
436 if not self.interact:
436 if not self.interact:
437 self.exit(1)
437 self.exit(1)
438
438
439 def _run_module(self):
439 def _run_module(self):
440 """Run module specified at the command-line."""
440 """Run module specified at the command-line."""
441 if self.module_to_run:
441 if self.module_to_run:
442 # Make sure that the module gets a proper sys.argv as if it were
442 # Make sure that the module gets a proper sys.argv as if it were
443 # run using `python -m`.
443 # run using `python -m`.
444 save_argv = sys.argv
444 save_argv = sys.argv
445 sys.argv = [sys.executable] + self.extra_args
445 sys.argv = [sys.executable] + self.extra_args
446 try:
446 try:
447 self.shell.safe_run_module(self.module_to_run,
447 self.shell.safe_run_module(self.module_to_run,
448 self.shell.user_ns)
448 self.shell.user_ns)
449 finally:
449 finally:
450 sys.argv = save_argv
450 sys.argv = save_argv
General Comments 0
You need to be logged in to leave comments. Login now