##// END OF EJS Templates
Swallow potential exceptions from showtraceback() (#13934)...
Matthias Bussonnier -
r28101:e548ee23 merge
parent child Browse files
Show More
@@ -1,3861 +1,3862 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Main IPython class."""
2 """Main IPython class."""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2008-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13
13
14 import abc
14 import abc
15 import ast
15 import ast
16 import atexit
16 import atexit
17 import bdb
17 import bdb
18 import builtins as builtin_mod
18 import builtins as builtin_mod
19 import functools
19 import functools
20 import inspect
20 import inspect
21 import os
21 import os
22 import re
22 import re
23 import runpy
23 import runpy
24 import subprocess
24 import subprocess
25 import sys
25 import sys
26 import tempfile
26 import tempfile
27 import traceback
27 import traceback
28 import types
28 import types
29 import warnings
29 import warnings
30 from ast import stmt
30 from ast import stmt
31 from io import open as io_open
31 from io import open as io_open
32 from logging import error
32 from logging import error
33 from pathlib import Path
33 from pathlib import Path
34 from typing import Callable
34 from typing import Callable
35 from typing import List as ListType
35 from typing import List as ListType
36 from typing import Optional, Tuple
36 from typing import Optional, Tuple
37 from warnings import warn
37 from warnings import warn
38
38
39 from pickleshare import PickleShareDB
39 from pickleshare import PickleShareDB
40 from tempfile import TemporaryDirectory
40 from tempfile import TemporaryDirectory
41 from traitlets import (
41 from traitlets import (
42 Any,
42 Any,
43 Bool,
43 Bool,
44 CaselessStrEnum,
44 CaselessStrEnum,
45 Dict,
45 Dict,
46 Enum,
46 Enum,
47 Instance,
47 Instance,
48 Integer,
48 Integer,
49 List,
49 List,
50 Type,
50 Type,
51 Unicode,
51 Unicode,
52 default,
52 default,
53 observe,
53 observe,
54 validate,
54 validate,
55 )
55 )
56 from traitlets.config.configurable import SingletonConfigurable
56 from traitlets.config.configurable import SingletonConfigurable
57 from traitlets.utils.importstring import import_item
57 from traitlets.utils.importstring import import_item
58
58
59 import IPython.core.hooks
59 import IPython.core.hooks
60 from IPython.core import magic, oinspect, page, prefilter, ultratb
60 from IPython.core import magic, oinspect, page, prefilter, ultratb
61 from IPython.core.alias import Alias, AliasManager
61 from IPython.core.alias import Alias, AliasManager
62 from IPython.core.autocall import ExitAutocall
62 from IPython.core.autocall import ExitAutocall
63 from IPython.core.builtin_trap import BuiltinTrap
63 from IPython.core.builtin_trap import BuiltinTrap
64 from IPython.core.compilerop import CachingCompiler
64 from IPython.core.compilerop import CachingCompiler
65 from IPython.core.debugger import InterruptiblePdb
65 from IPython.core.debugger import InterruptiblePdb
66 from IPython.core.display_trap import DisplayTrap
66 from IPython.core.display_trap import DisplayTrap
67 from IPython.core.displayhook import DisplayHook
67 from IPython.core.displayhook import DisplayHook
68 from IPython.core.displaypub import DisplayPublisher
68 from IPython.core.displaypub import DisplayPublisher
69 from IPython.core.error import InputRejected, UsageError
69 from IPython.core.error import InputRejected, UsageError
70 from IPython.core.events import EventManager, available_events
70 from IPython.core.events import EventManager, available_events
71 from IPython.core.extensions import ExtensionManager
71 from IPython.core.extensions import ExtensionManager
72 from IPython.core.formatters import DisplayFormatter
72 from IPython.core.formatters import DisplayFormatter
73 from IPython.core.history import HistoryManager
73 from IPython.core.history import HistoryManager
74 from IPython.core.inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
74 from IPython.core.inputtransformer2 import ESC_MAGIC, ESC_MAGIC2
75 from IPython.core.logger import Logger
75 from IPython.core.logger import Logger
76 from IPython.core.macro import Macro
76 from IPython.core.macro import Macro
77 from IPython.core.payload import PayloadManager
77 from IPython.core.payload import PayloadManager
78 from IPython.core.prefilter import PrefilterManager
78 from IPython.core.prefilter import PrefilterManager
79 from IPython.core.profiledir import ProfileDir
79 from IPython.core.profiledir import ProfileDir
80 from IPython.core.usage import default_banner
80 from IPython.core.usage import default_banner
81 from IPython.display import display
81 from IPython.display import display
82 from IPython.paths import get_ipython_dir
82 from IPython.paths import get_ipython_dir
83 from IPython.testing.skipdoctest import skip_doctest
83 from IPython.testing.skipdoctest import skip_doctest
84 from IPython.utils import PyColorize, io, openpy, py3compat
84 from IPython.utils import PyColorize, io, openpy, py3compat
85 from IPython.utils.decorators import undoc
85 from IPython.utils.decorators import undoc
86 from IPython.utils.io import ask_yes_no
86 from IPython.utils.io import ask_yes_no
87 from IPython.utils.ipstruct import Struct
87 from IPython.utils.ipstruct import Struct
88 from IPython.utils.path import ensure_dir_exists, get_home_dir, get_py_filename
88 from IPython.utils.path import ensure_dir_exists, get_home_dir, get_py_filename
89 from IPython.utils.process import getoutput, system
89 from IPython.utils.process import getoutput, system
90 from IPython.utils.strdispatch import StrDispatch
90 from IPython.utils.strdispatch import StrDispatch
91 from IPython.utils.syspathcontext import prepended_to_syspath
91 from IPython.utils.syspathcontext import prepended_to_syspath
92 from IPython.utils.text import DollarFormatter, LSString, SList, format_screen
92 from IPython.utils.text import DollarFormatter, LSString, SList, format_screen
93
93
94 sphinxify: Optional[Callable]
94 sphinxify: Optional[Callable]
95
95
96 try:
96 try:
97 import docrepr.sphinxify as sphx
97 import docrepr.sphinxify as sphx
98
98
99 def sphinxify(oinfo):
99 def sphinxify(oinfo):
100 wrapped_docstring = sphx.wrap_main_docstring(oinfo)
100 wrapped_docstring = sphx.wrap_main_docstring(oinfo)
101
101
102 def sphinxify_docstring(docstring):
102 def sphinxify_docstring(docstring):
103 with TemporaryDirectory() as dirname:
103 with TemporaryDirectory() as dirname:
104 return {
104 return {
105 "text/html": sphx.sphinxify(wrapped_docstring, dirname),
105 "text/html": sphx.sphinxify(wrapped_docstring, dirname),
106 "text/plain": docstring,
106 "text/plain": docstring,
107 }
107 }
108
108
109 return sphinxify_docstring
109 return sphinxify_docstring
110 except ImportError:
110 except ImportError:
111 sphinxify = None
111 sphinxify = None
112
112
113
113
114 class ProvisionalWarning(DeprecationWarning):
114 class ProvisionalWarning(DeprecationWarning):
115 """
115 """
116 Warning class for unstable features
116 Warning class for unstable features
117 """
117 """
118 pass
118 pass
119
119
120 from ast import Module
120 from ast import Module
121
121
122 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
122 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
123 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
123 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
124
124
125 #-----------------------------------------------------------------------------
125 #-----------------------------------------------------------------------------
126 # Await Helpers
126 # Await Helpers
127 #-----------------------------------------------------------------------------
127 #-----------------------------------------------------------------------------
128
128
129 # we still need to run things using the asyncio eventloop, but there is no
129 # we still need to run things using the asyncio eventloop, but there is no
130 # async integration
130 # async integration
131 from .async_helpers import (
131 from .async_helpers import (
132 _asyncio_runner,
132 _asyncio_runner,
133 _curio_runner,
133 _curio_runner,
134 _pseudo_sync_runner,
134 _pseudo_sync_runner,
135 _should_be_async,
135 _should_be_async,
136 _trio_runner,
136 _trio_runner,
137 )
137 )
138
138
139 #-----------------------------------------------------------------------------
139 #-----------------------------------------------------------------------------
140 # Globals
140 # Globals
141 #-----------------------------------------------------------------------------
141 #-----------------------------------------------------------------------------
142
142
143 # compiled regexps for autoindent management
143 # compiled regexps for autoindent management
144 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
144 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
145
145
146 #-----------------------------------------------------------------------------
146 #-----------------------------------------------------------------------------
147 # Utilities
147 # Utilities
148 #-----------------------------------------------------------------------------
148 #-----------------------------------------------------------------------------
149
149
150
150
151 def is_integer_string(s: str):
151 def is_integer_string(s: str):
152 """
152 """
153 Variant of "str.isnumeric()" that allow negative values and other ints.
153 Variant of "str.isnumeric()" that allow negative values and other ints.
154 """
154 """
155 try:
155 try:
156 int(s)
156 int(s)
157 return True
157 return True
158 except ValueError:
158 except ValueError:
159 return False
159 return False
160 raise ValueError("Unexpected error")
160 raise ValueError("Unexpected error")
161
161
162
162
163 @undoc
163 @undoc
164 def softspace(file, newvalue):
164 def softspace(file, newvalue):
165 """Copied from code.py, to remove the dependency"""
165 """Copied from code.py, to remove the dependency"""
166
166
167 oldvalue = 0
167 oldvalue = 0
168 try:
168 try:
169 oldvalue = file.softspace
169 oldvalue = file.softspace
170 except AttributeError:
170 except AttributeError:
171 pass
171 pass
172 try:
172 try:
173 file.softspace = newvalue
173 file.softspace = newvalue
174 except (AttributeError, TypeError):
174 except (AttributeError, TypeError):
175 # "attribute-less object" or "read-only attributes"
175 # "attribute-less object" or "read-only attributes"
176 pass
176 pass
177 return oldvalue
177 return oldvalue
178
178
179 @undoc
179 @undoc
180 def no_op(*a, **kw):
180 def no_op(*a, **kw):
181 pass
181 pass
182
182
183
183
184 class SpaceInInput(Exception): pass
184 class SpaceInInput(Exception): pass
185
185
186
186
187 class SeparateUnicode(Unicode):
187 class SeparateUnicode(Unicode):
188 r"""A Unicode subclass to validate separate_in, separate_out, etc.
188 r"""A Unicode subclass to validate separate_in, separate_out, etc.
189
189
190 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
190 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
191 """
191 """
192
192
193 def validate(self, obj, value):
193 def validate(self, obj, value):
194 if value == '0': value = ''
194 if value == '0': value = ''
195 value = value.replace('\\n','\n')
195 value = value.replace('\\n','\n')
196 return super(SeparateUnicode, self).validate(obj, value)
196 return super(SeparateUnicode, self).validate(obj, value)
197
197
198
198
199 @undoc
199 @undoc
200 class DummyMod(object):
200 class DummyMod(object):
201 """A dummy module used for IPython's interactive module when
201 """A dummy module used for IPython's interactive module when
202 a namespace must be assigned to the module's __dict__."""
202 a namespace must be assigned to the module's __dict__."""
203 __spec__ = None
203 __spec__ = None
204
204
205
205
206 class ExecutionInfo(object):
206 class ExecutionInfo(object):
207 """The arguments used for a call to :meth:`InteractiveShell.run_cell`
207 """The arguments used for a call to :meth:`InteractiveShell.run_cell`
208
208
209 Stores information about what is going to happen.
209 Stores information about what is going to happen.
210 """
210 """
211 raw_cell = None
211 raw_cell = None
212 store_history = False
212 store_history = False
213 silent = False
213 silent = False
214 shell_futures = True
214 shell_futures = True
215 cell_id = None
215 cell_id = None
216
216
217 def __init__(self, raw_cell, store_history, silent, shell_futures, cell_id):
217 def __init__(self, raw_cell, store_history, silent, shell_futures, cell_id):
218 self.raw_cell = raw_cell
218 self.raw_cell = raw_cell
219 self.store_history = store_history
219 self.store_history = store_history
220 self.silent = silent
220 self.silent = silent
221 self.shell_futures = shell_futures
221 self.shell_futures = shell_futures
222 self.cell_id = cell_id
222 self.cell_id = cell_id
223
223
224 def __repr__(self):
224 def __repr__(self):
225 name = self.__class__.__qualname__
225 name = self.__class__.__qualname__
226 raw_cell = (
226 raw_cell = (
227 (self.raw_cell[:50] + "..") if len(self.raw_cell) > 50 else self.raw_cell
227 (self.raw_cell[:50] + "..") if len(self.raw_cell) > 50 else self.raw_cell
228 )
228 )
229 return (
229 return (
230 '<%s object at %x, raw_cell="%s" store_history=%s silent=%s shell_futures=%s cell_id=%s>'
230 '<%s object at %x, raw_cell="%s" store_history=%s silent=%s shell_futures=%s cell_id=%s>'
231 % (
231 % (
232 name,
232 name,
233 id(self),
233 id(self),
234 raw_cell,
234 raw_cell,
235 self.store_history,
235 self.store_history,
236 self.silent,
236 self.silent,
237 self.shell_futures,
237 self.shell_futures,
238 self.cell_id,
238 self.cell_id,
239 )
239 )
240 )
240 )
241
241
242
242
243 class ExecutionResult(object):
243 class ExecutionResult(object):
244 """The result of a call to :meth:`InteractiveShell.run_cell`
244 """The result of a call to :meth:`InteractiveShell.run_cell`
245
245
246 Stores information about what took place.
246 Stores information about what took place.
247 """
247 """
248 execution_count = None
248 execution_count = None
249 error_before_exec = None
249 error_before_exec = None
250 error_in_exec: Optional[BaseException] = None
250 error_in_exec: Optional[BaseException] = None
251 info = None
251 info = None
252 result = None
252 result = None
253
253
254 def __init__(self, info):
254 def __init__(self, info):
255 self.info = info
255 self.info = info
256
256
257 @property
257 @property
258 def success(self):
258 def success(self):
259 return (self.error_before_exec is None) and (self.error_in_exec is None)
259 return (self.error_before_exec is None) and (self.error_in_exec is None)
260
260
261 def raise_error(self):
261 def raise_error(self):
262 """Reraises error if `success` is `False`, otherwise does nothing"""
262 """Reraises error if `success` is `False`, otherwise does nothing"""
263 if self.error_before_exec is not None:
263 if self.error_before_exec is not None:
264 raise self.error_before_exec
264 raise self.error_before_exec
265 if self.error_in_exec is not None:
265 if self.error_in_exec is not None:
266 raise self.error_in_exec
266 raise self.error_in_exec
267
267
268 def __repr__(self):
268 def __repr__(self):
269 name = self.__class__.__qualname__
269 name = self.__class__.__qualname__
270 return '<%s object at %x, execution_count=%s error_before_exec=%s error_in_exec=%s info=%s result=%s>' %\
270 return '<%s object at %x, execution_count=%s error_before_exec=%s error_in_exec=%s info=%s result=%s>' %\
271 (name, id(self), self.execution_count, self.error_before_exec, self.error_in_exec, repr(self.info), repr(self.result))
271 (name, id(self), self.execution_count, self.error_before_exec, self.error_in_exec, repr(self.info), repr(self.result))
272
272
273 @functools.wraps(io_open)
273 @functools.wraps(io_open)
274 def _modified_open(file, *args, **kwargs):
274 def _modified_open(file, *args, **kwargs):
275 if file in {0, 1, 2}:
275 if file in {0, 1, 2}:
276 raise ValueError(
276 raise ValueError(
277 f"IPython won't let you open fd={file} by default "
277 f"IPython won't let you open fd={file} by default "
278 "as it is likely to crash IPython. If you know what you are doing, "
278 "as it is likely to crash IPython. If you know what you are doing, "
279 "you can use builtins' open."
279 "you can use builtins' open."
280 )
280 )
281
281
282 return io_open(file, *args, **kwargs)
282 return io_open(file, *args, **kwargs)
283
283
284 class InteractiveShell(SingletonConfigurable):
284 class InteractiveShell(SingletonConfigurable):
285 """An enhanced, interactive shell for Python."""
285 """An enhanced, interactive shell for Python."""
286
286
287 _instance = None
287 _instance = None
288
288
289 ast_transformers = List([], help=
289 ast_transformers = List([], help=
290 """
290 """
291 A list of ast.NodeTransformer subclass instances, which will be applied
291 A list of ast.NodeTransformer subclass instances, which will be applied
292 to user input before code is run.
292 to user input before code is run.
293 """
293 """
294 ).tag(config=True)
294 ).tag(config=True)
295
295
296 autocall = Enum((0,1,2), default_value=0, help=
296 autocall = Enum((0,1,2), default_value=0, help=
297 """
297 """
298 Make IPython automatically call any callable object even if you didn't
298 Make IPython automatically call any callable object even if you didn't
299 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
299 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
300 automatically. The value can be '0' to disable the feature, '1' for
300 automatically. The value can be '0' to disable the feature, '1' for
301 'smart' autocall, where it is not applied if there are no more
301 'smart' autocall, where it is not applied if there are no more
302 arguments on the line, and '2' for 'full' autocall, where all callable
302 arguments on the line, and '2' for 'full' autocall, where all callable
303 objects are automatically called (even if no arguments are present).
303 objects are automatically called (even if no arguments are present).
304 """
304 """
305 ).tag(config=True)
305 ).tag(config=True)
306
306
307 autoindent = Bool(True, help=
307 autoindent = Bool(True, help=
308 """
308 """
309 Autoindent IPython code entered interactively.
309 Autoindent IPython code entered interactively.
310 """
310 """
311 ).tag(config=True)
311 ).tag(config=True)
312
312
313 autoawait = Bool(True, help=
313 autoawait = Bool(True, help=
314 """
314 """
315 Automatically run await statement in the top level repl.
315 Automatically run await statement in the top level repl.
316 """
316 """
317 ).tag(config=True)
317 ).tag(config=True)
318
318
319 loop_runner_map ={
319 loop_runner_map ={
320 'asyncio':(_asyncio_runner, True),
320 'asyncio':(_asyncio_runner, True),
321 'curio':(_curio_runner, True),
321 'curio':(_curio_runner, True),
322 'trio':(_trio_runner, True),
322 'trio':(_trio_runner, True),
323 'sync': (_pseudo_sync_runner, False)
323 'sync': (_pseudo_sync_runner, False)
324 }
324 }
325
325
326 loop_runner = Any(default_value="IPython.core.interactiveshell._asyncio_runner",
326 loop_runner = Any(default_value="IPython.core.interactiveshell._asyncio_runner",
327 allow_none=True,
327 allow_none=True,
328 help="""Select the loop runner that will be used to execute top-level asynchronous code"""
328 help="""Select the loop runner that will be used to execute top-level asynchronous code"""
329 ).tag(config=True)
329 ).tag(config=True)
330
330
331 @default('loop_runner')
331 @default('loop_runner')
332 def _default_loop_runner(self):
332 def _default_loop_runner(self):
333 return import_item("IPython.core.interactiveshell._asyncio_runner")
333 return import_item("IPython.core.interactiveshell._asyncio_runner")
334
334
335 @validate('loop_runner')
335 @validate('loop_runner')
336 def _import_runner(self, proposal):
336 def _import_runner(self, proposal):
337 if isinstance(proposal.value, str):
337 if isinstance(proposal.value, str):
338 if proposal.value in self.loop_runner_map:
338 if proposal.value in self.loop_runner_map:
339 runner, autoawait = self.loop_runner_map[proposal.value]
339 runner, autoawait = self.loop_runner_map[proposal.value]
340 self.autoawait = autoawait
340 self.autoawait = autoawait
341 return runner
341 return runner
342 runner = import_item(proposal.value)
342 runner = import_item(proposal.value)
343 if not callable(runner):
343 if not callable(runner):
344 raise ValueError('loop_runner must be callable')
344 raise ValueError('loop_runner must be callable')
345 return runner
345 return runner
346 if not callable(proposal.value):
346 if not callable(proposal.value):
347 raise ValueError('loop_runner must be callable')
347 raise ValueError('loop_runner must be callable')
348 return proposal.value
348 return proposal.value
349
349
350 automagic = Bool(True, help=
350 automagic = Bool(True, help=
351 """
351 """
352 Enable magic commands to be called without the leading %.
352 Enable magic commands to be called without the leading %.
353 """
353 """
354 ).tag(config=True)
354 ).tag(config=True)
355
355
356 banner1 = Unicode(default_banner,
356 banner1 = Unicode(default_banner,
357 help="""The part of the banner to be printed before the profile"""
357 help="""The part of the banner to be printed before the profile"""
358 ).tag(config=True)
358 ).tag(config=True)
359 banner2 = Unicode('',
359 banner2 = Unicode('',
360 help="""The part of the banner to be printed after the profile"""
360 help="""The part of the banner to be printed after the profile"""
361 ).tag(config=True)
361 ).tag(config=True)
362
362
363 cache_size = Integer(1000, help=
363 cache_size = Integer(1000, help=
364 """
364 """
365 Set the size of the output cache. The default is 1000, you can
365 Set the size of the output cache. The default is 1000, you can
366 change it permanently in your config file. Setting it to 0 completely
366 change it permanently in your config file. Setting it to 0 completely
367 disables the caching system, and the minimum value accepted is 3 (if
367 disables the caching system, and the minimum value accepted is 3 (if
368 you provide a value less than 3, it is reset to 0 and a warning is
368 you provide a value less than 3, it is reset to 0 and a warning is
369 issued). This limit is defined because otherwise you'll spend more
369 issued). This limit is defined because otherwise you'll spend more
370 time re-flushing a too small cache than working
370 time re-flushing a too small cache than working
371 """
371 """
372 ).tag(config=True)
372 ).tag(config=True)
373 color_info = Bool(True, help=
373 color_info = Bool(True, help=
374 """
374 """
375 Use colors for displaying information about objects. Because this
375 Use colors for displaying information about objects. Because this
376 information is passed through a pager (like 'less'), and some pagers
376 information is passed through a pager (like 'less'), and some pagers
377 get confused with color codes, this capability can be turned off.
377 get confused with color codes, this capability can be turned off.
378 """
378 """
379 ).tag(config=True)
379 ).tag(config=True)
380 colors = CaselessStrEnum(('Neutral', 'NoColor','LightBG','Linux'),
380 colors = CaselessStrEnum(('Neutral', 'NoColor','LightBG','Linux'),
381 default_value='Neutral',
381 default_value='Neutral',
382 help="Set the color scheme (NoColor, Neutral, Linux, or LightBG)."
382 help="Set the color scheme (NoColor, Neutral, Linux, or LightBG)."
383 ).tag(config=True)
383 ).tag(config=True)
384 debug = Bool(False).tag(config=True)
384 debug = Bool(False).tag(config=True)
385 disable_failing_post_execute = Bool(False,
385 disable_failing_post_execute = Bool(False,
386 help="Don't call post-execute functions that have failed in the past."
386 help="Don't call post-execute functions that have failed in the past."
387 ).tag(config=True)
387 ).tag(config=True)
388 display_formatter = Instance(DisplayFormatter, allow_none=True)
388 display_formatter = Instance(DisplayFormatter, allow_none=True)
389 displayhook_class = Type(DisplayHook)
389 displayhook_class = Type(DisplayHook)
390 display_pub_class = Type(DisplayPublisher)
390 display_pub_class = Type(DisplayPublisher)
391 compiler_class = Type(CachingCompiler)
391 compiler_class = Type(CachingCompiler)
392 inspector_class = Type(
392 inspector_class = Type(
393 oinspect.Inspector, help="Class to use to instantiate the shell inspector"
393 oinspect.Inspector, help="Class to use to instantiate the shell inspector"
394 ).tag(config=True)
394 ).tag(config=True)
395
395
396 sphinxify_docstring = Bool(False, help=
396 sphinxify_docstring = Bool(False, help=
397 """
397 """
398 Enables rich html representation of docstrings. (This requires the
398 Enables rich html representation of docstrings. (This requires the
399 docrepr module).
399 docrepr module).
400 """).tag(config=True)
400 """).tag(config=True)
401
401
402 @observe("sphinxify_docstring")
402 @observe("sphinxify_docstring")
403 def _sphinxify_docstring_changed(self, change):
403 def _sphinxify_docstring_changed(self, change):
404 if change['new']:
404 if change['new']:
405 warn("`sphinxify_docstring` is provisional since IPython 5.0 and might change in future versions." , ProvisionalWarning)
405 warn("`sphinxify_docstring` is provisional since IPython 5.0 and might change in future versions." , ProvisionalWarning)
406
406
407 enable_html_pager = Bool(False, help=
407 enable_html_pager = Bool(False, help=
408 """
408 """
409 (Provisional API) enables html representation in mime bundles sent
409 (Provisional API) enables html representation in mime bundles sent
410 to pagers.
410 to pagers.
411 """).tag(config=True)
411 """).tag(config=True)
412
412
413 @observe("enable_html_pager")
413 @observe("enable_html_pager")
414 def _enable_html_pager_changed(self, change):
414 def _enable_html_pager_changed(self, change):
415 if change['new']:
415 if change['new']:
416 warn("`enable_html_pager` is provisional since IPython 5.0 and might change in future versions.", ProvisionalWarning)
416 warn("`enable_html_pager` is provisional since IPython 5.0 and might change in future versions.", ProvisionalWarning)
417
417
418 data_pub_class = None
418 data_pub_class = None
419
419
420 exit_now = Bool(False)
420 exit_now = Bool(False)
421 exiter = Instance(ExitAutocall)
421 exiter = Instance(ExitAutocall)
422 @default('exiter')
422 @default('exiter')
423 def _exiter_default(self):
423 def _exiter_default(self):
424 return ExitAutocall(self)
424 return ExitAutocall(self)
425 # Monotonically increasing execution counter
425 # Monotonically increasing execution counter
426 execution_count = Integer(1)
426 execution_count = Integer(1)
427 filename = Unicode("<ipython console>")
427 filename = Unicode("<ipython console>")
428 ipython_dir= Unicode('').tag(config=True) # Set to get_ipython_dir() in __init__
428 ipython_dir= Unicode('').tag(config=True) # Set to get_ipython_dir() in __init__
429
429
430 # Used to transform cells before running them, and check whether code is complete
430 # Used to transform cells before running them, and check whether code is complete
431 input_transformer_manager = Instance('IPython.core.inputtransformer2.TransformerManager',
431 input_transformer_manager = Instance('IPython.core.inputtransformer2.TransformerManager',
432 ())
432 ())
433
433
434 @property
434 @property
435 def input_transformers_cleanup(self):
435 def input_transformers_cleanup(self):
436 return self.input_transformer_manager.cleanup_transforms
436 return self.input_transformer_manager.cleanup_transforms
437
437
438 input_transformers_post = List([],
438 input_transformers_post = List([],
439 help="A list of string input transformers, to be applied after IPython's "
439 help="A list of string input transformers, to be applied after IPython's "
440 "own input transformations."
440 "own input transformations."
441 )
441 )
442
442
443 @property
443 @property
444 def input_splitter(self):
444 def input_splitter(self):
445 """Make this available for backward compatibility (pre-7.0 release) with existing code.
445 """Make this available for backward compatibility (pre-7.0 release) with existing code.
446
446
447 For example, ipykernel ipykernel currently uses
447 For example, ipykernel ipykernel currently uses
448 `shell.input_splitter.check_complete`
448 `shell.input_splitter.check_complete`
449 """
449 """
450 from warnings import warn
450 from warnings import warn
451 warn("`input_splitter` is deprecated since IPython 7.0, prefer `input_transformer_manager`.",
451 warn("`input_splitter` is deprecated since IPython 7.0, prefer `input_transformer_manager`.",
452 DeprecationWarning, stacklevel=2
452 DeprecationWarning, stacklevel=2
453 )
453 )
454 return self.input_transformer_manager
454 return self.input_transformer_manager
455
455
456 logstart = Bool(False, help=
456 logstart = Bool(False, help=
457 """
457 """
458 Start logging to the default log file in overwrite mode.
458 Start logging to the default log file in overwrite mode.
459 Use `logappend` to specify a log file to **append** logs to.
459 Use `logappend` to specify a log file to **append** logs to.
460 """
460 """
461 ).tag(config=True)
461 ).tag(config=True)
462 logfile = Unicode('', help=
462 logfile = Unicode('', help=
463 """
463 """
464 The name of the logfile to use.
464 The name of the logfile to use.
465 """
465 """
466 ).tag(config=True)
466 ).tag(config=True)
467 logappend = Unicode('', help=
467 logappend = Unicode('', help=
468 """
468 """
469 Start logging to the given file in append mode.
469 Start logging to the given file in append mode.
470 Use `logfile` to specify a log file to **overwrite** logs to.
470 Use `logfile` to specify a log file to **overwrite** logs to.
471 """
471 """
472 ).tag(config=True)
472 ).tag(config=True)
473 object_info_string_level = Enum((0,1,2), default_value=0,
473 object_info_string_level = Enum((0,1,2), default_value=0,
474 ).tag(config=True)
474 ).tag(config=True)
475 pdb = Bool(False, help=
475 pdb = Bool(False, help=
476 """
476 """
477 Automatically call the pdb debugger after every exception.
477 Automatically call the pdb debugger after every exception.
478 """
478 """
479 ).tag(config=True)
479 ).tag(config=True)
480 display_page = Bool(False,
480 display_page = Bool(False,
481 help="""If True, anything that would be passed to the pager
481 help="""If True, anything that would be passed to the pager
482 will be displayed as regular output instead."""
482 will be displayed as regular output instead."""
483 ).tag(config=True)
483 ).tag(config=True)
484
484
485
485
486 show_rewritten_input = Bool(True,
486 show_rewritten_input = Bool(True,
487 help="Show rewritten input, e.g. for autocall."
487 help="Show rewritten input, e.g. for autocall."
488 ).tag(config=True)
488 ).tag(config=True)
489
489
490 quiet = Bool(False).tag(config=True)
490 quiet = Bool(False).tag(config=True)
491
491
492 history_length = Integer(10000,
492 history_length = Integer(10000,
493 help='Total length of command history'
493 help='Total length of command history'
494 ).tag(config=True)
494 ).tag(config=True)
495
495
496 history_load_length = Integer(1000, help=
496 history_load_length = Integer(1000, help=
497 """
497 """
498 The number of saved history entries to be loaded
498 The number of saved history entries to be loaded
499 into the history buffer at startup.
499 into the history buffer at startup.
500 """
500 """
501 ).tag(config=True)
501 ).tag(config=True)
502
502
503 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'],
503 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'],
504 default_value='last_expr',
504 default_value='last_expr',
505 help="""
505 help="""
506 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying
506 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying
507 which nodes should be run interactively (displaying output from expressions).
507 which nodes should be run interactively (displaying output from expressions).
508 """
508 """
509 ).tag(config=True)
509 ).tag(config=True)
510
510
511 warn_venv = Bool(
511 warn_venv = Bool(
512 True,
512 True,
513 help="Warn if running in a virtual environment with no IPython installed (so IPython from the global environment is used).",
513 help="Warn if running in a virtual environment with no IPython installed (so IPython from the global environment is used).",
514 ).tag(config=True)
514 ).tag(config=True)
515
515
516 # TODO: this part of prompt management should be moved to the frontends.
516 # TODO: this part of prompt management should be moved to the frontends.
517 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
517 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
518 separate_in = SeparateUnicode('\n').tag(config=True)
518 separate_in = SeparateUnicode('\n').tag(config=True)
519 separate_out = SeparateUnicode('').tag(config=True)
519 separate_out = SeparateUnicode('').tag(config=True)
520 separate_out2 = SeparateUnicode('').tag(config=True)
520 separate_out2 = SeparateUnicode('').tag(config=True)
521 wildcards_case_sensitive = Bool(True).tag(config=True)
521 wildcards_case_sensitive = Bool(True).tag(config=True)
522 xmode = CaselessStrEnum(('Context', 'Plain', 'Verbose', 'Minimal'),
522 xmode = CaselessStrEnum(('Context', 'Plain', 'Verbose', 'Minimal'),
523 default_value='Context',
523 default_value='Context',
524 help="Switch modes for the IPython exception handlers."
524 help="Switch modes for the IPython exception handlers."
525 ).tag(config=True)
525 ).tag(config=True)
526
526
527 # Subcomponents of InteractiveShell
527 # Subcomponents of InteractiveShell
528 alias_manager = Instance('IPython.core.alias.AliasManager', allow_none=True)
528 alias_manager = Instance('IPython.core.alias.AliasManager', allow_none=True)
529 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
529 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
530 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap', allow_none=True)
530 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap', allow_none=True)
531 display_trap = Instance('IPython.core.display_trap.DisplayTrap', allow_none=True)
531 display_trap = Instance('IPython.core.display_trap.DisplayTrap', allow_none=True)
532 extension_manager = Instance('IPython.core.extensions.ExtensionManager', allow_none=True)
532 extension_manager = Instance('IPython.core.extensions.ExtensionManager', allow_none=True)
533 payload_manager = Instance('IPython.core.payload.PayloadManager', allow_none=True)
533 payload_manager = Instance('IPython.core.payload.PayloadManager', allow_none=True)
534 history_manager = Instance('IPython.core.history.HistoryAccessorBase', allow_none=True)
534 history_manager = Instance('IPython.core.history.HistoryAccessorBase', allow_none=True)
535 magics_manager = Instance('IPython.core.magic.MagicsManager', allow_none=True)
535 magics_manager = Instance('IPython.core.magic.MagicsManager', allow_none=True)
536
536
537 profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True)
537 profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True)
538 @property
538 @property
539 def profile(self):
539 def profile(self):
540 if self.profile_dir is not None:
540 if self.profile_dir is not None:
541 name = os.path.basename(self.profile_dir.location)
541 name = os.path.basename(self.profile_dir.location)
542 return name.replace('profile_','')
542 return name.replace('profile_','')
543
543
544
544
545 # Private interface
545 # Private interface
546 _post_execute = Dict()
546 _post_execute = Dict()
547
547
548 # Tracks any GUI loop loaded for pylab
548 # Tracks any GUI loop loaded for pylab
549 pylab_gui_select = None
549 pylab_gui_select = None
550
550
551 last_execution_succeeded = Bool(True, help='Did last executed command succeeded')
551 last_execution_succeeded = Bool(True, help='Did last executed command succeeded')
552
552
553 last_execution_result = Instance('IPython.core.interactiveshell.ExecutionResult', help='Result of executing the last command', allow_none=True)
553 last_execution_result = Instance('IPython.core.interactiveshell.ExecutionResult', help='Result of executing the last command', allow_none=True)
554
554
555 def __init__(self, ipython_dir=None, profile_dir=None,
555 def __init__(self, ipython_dir=None, profile_dir=None,
556 user_module=None, user_ns=None,
556 user_module=None, user_ns=None,
557 custom_exceptions=((), None), **kwargs):
557 custom_exceptions=((), None), **kwargs):
558 # This is where traits with a config_key argument are updated
558 # This is where traits with a config_key argument are updated
559 # from the values on config.
559 # from the values on config.
560 super(InteractiveShell, self).__init__(**kwargs)
560 super(InteractiveShell, self).__init__(**kwargs)
561 if 'PromptManager' in self.config:
561 if 'PromptManager' in self.config:
562 warn('As of IPython 5.0 `PromptManager` config will have no effect'
562 warn('As of IPython 5.0 `PromptManager` config will have no effect'
563 ' and has been replaced by TerminalInteractiveShell.prompts_class')
563 ' and has been replaced by TerminalInteractiveShell.prompts_class')
564 self.configurables = [self]
564 self.configurables = [self]
565
565
566 # These are relatively independent and stateless
566 # These are relatively independent and stateless
567 self.init_ipython_dir(ipython_dir)
567 self.init_ipython_dir(ipython_dir)
568 self.init_profile_dir(profile_dir)
568 self.init_profile_dir(profile_dir)
569 self.init_instance_attrs()
569 self.init_instance_attrs()
570 self.init_environment()
570 self.init_environment()
571
571
572 # Check if we're in a virtualenv, and set up sys.path.
572 # Check if we're in a virtualenv, and set up sys.path.
573 self.init_virtualenv()
573 self.init_virtualenv()
574
574
575 # Create namespaces (user_ns, user_global_ns, etc.)
575 # Create namespaces (user_ns, user_global_ns, etc.)
576 self.init_create_namespaces(user_module, user_ns)
576 self.init_create_namespaces(user_module, user_ns)
577 # This has to be done after init_create_namespaces because it uses
577 # This has to be done after init_create_namespaces because it uses
578 # something in self.user_ns, but before init_sys_modules, which
578 # something in self.user_ns, but before init_sys_modules, which
579 # is the first thing to modify sys.
579 # is the first thing to modify sys.
580 # TODO: When we override sys.stdout and sys.stderr before this class
580 # TODO: When we override sys.stdout and sys.stderr before this class
581 # is created, we are saving the overridden ones here. Not sure if this
581 # is created, we are saving the overridden ones here. Not sure if this
582 # is what we want to do.
582 # is what we want to do.
583 self.save_sys_module_state()
583 self.save_sys_module_state()
584 self.init_sys_modules()
584 self.init_sys_modules()
585
585
586 # While we're trying to have each part of the code directly access what
586 # While we're trying to have each part of the code directly access what
587 # it needs without keeping redundant references to objects, we have too
587 # it needs without keeping redundant references to objects, we have too
588 # much legacy code that expects ip.db to exist.
588 # much legacy code that expects ip.db to exist.
589 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
589 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
590
590
591 self.init_history()
591 self.init_history()
592 self.init_encoding()
592 self.init_encoding()
593 self.init_prefilter()
593 self.init_prefilter()
594
594
595 self.init_syntax_highlighting()
595 self.init_syntax_highlighting()
596 self.init_hooks()
596 self.init_hooks()
597 self.init_events()
597 self.init_events()
598 self.init_pushd_popd_magic()
598 self.init_pushd_popd_magic()
599 self.init_user_ns()
599 self.init_user_ns()
600 self.init_logger()
600 self.init_logger()
601 self.init_builtins()
601 self.init_builtins()
602
602
603 # The following was in post_config_initialization
603 # The following was in post_config_initialization
604 self.init_inspector()
604 self.init_inspector()
605 self.raw_input_original = input
605 self.raw_input_original = input
606 self.init_completer()
606 self.init_completer()
607 # TODO: init_io() needs to happen before init_traceback handlers
607 # TODO: init_io() needs to happen before init_traceback handlers
608 # because the traceback handlers hardcode the stdout/stderr streams.
608 # because the traceback handlers hardcode the stdout/stderr streams.
609 # This logic in in debugger.Pdb and should eventually be changed.
609 # This logic in in debugger.Pdb and should eventually be changed.
610 self.init_io()
610 self.init_io()
611 self.init_traceback_handlers(custom_exceptions)
611 self.init_traceback_handlers(custom_exceptions)
612 self.init_prompts()
612 self.init_prompts()
613 self.init_display_formatter()
613 self.init_display_formatter()
614 self.init_display_pub()
614 self.init_display_pub()
615 self.init_data_pub()
615 self.init_data_pub()
616 self.init_displayhook()
616 self.init_displayhook()
617 self.init_magics()
617 self.init_magics()
618 self.init_alias()
618 self.init_alias()
619 self.init_logstart()
619 self.init_logstart()
620 self.init_pdb()
620 self.init_pdb()
621 self.init_extension_manager()
621 self.init_extension_manager()
622 self.init_payload()
622 self.init_payload()
623 self.events.trigger('shell_initialized', self)
623 self.events.trigger('shell_initialized', self)
624 atexit.register(self.atexit_operations)
624 atexit.register(self.atexit_operations)
625
625
626 # The trio runner is used for running Trio in the foreground thread. It
626 # The trio runner is used for running Trio in the foreground thread. It
627 # is different from `_trio_runner(async_fn)` in `async_helpers.py`
627 # is different from `_trio_runner(async_fn)` in `async_helpers.py`
628 # which calls `trio.run()` for every cell. This runner runs all cells
628 # which calls `trio.run()` for every cell. This runner runs all cells
629 # inside a single Trio event loop. If used, it is set from
629 # inside a single Trio event loop. If used, it is set from
630 # `ipykernel.kernelapp`.
630 # `ipykernel.kernelapp`.
631 self.trio_runner = None
631 self.trio_runner = None
632
632
633 def get_ipython(self):
633 def get_ipython(self):
634 """Return the currently running IPython instance."""
634 """Return the currently running IPython instance."""
635 return self
635 return self
636
636
637 #-------------------------------------------------------------------------
637 #-------------------------------------------------------------------------
638 # Trait changed handlers
638 # Trait changed handlers
639 #-------------------------------------------------------------------------
639 #-------------------------------------------------------------------------
640 @observe('ipython_dir')
640 @observe('ipython_dir')
641 def _ipython_dir_changed(self, change):
641 def _ipython_dir_changed(self, change):
642 ensure_dir_exists(change['new'])
642 ensure_dir_exists(change['new'])
643
643
644 def set_autoindent(self,value=None):
644 def set_autoindent(self,value=None):
645 """Set the autoindent flag.
645 """Set the autoindent flag.
646
646
647 If called with no arguments, it acts as a toggle."""
647 If called with no arguments, it acts as a toggle."""
648 if value is None:
648 if value is None:
649 self.autoindent = not self.autoindent
649 self.autoindent = not self.autoindent
650 else:
650 else:
651 self.autoindent = value
651 self.autoindent = value
652
652
653 def set_trio_runner(self, tr):
653 def set_trio_runner(self, tr):
654 self.trio_runner = tr
654 self.trio_runner = tr
655
655
656 #-------------------------------------------------------------------------
656 #-------------------------------------------------------------------------
657 # init_* methods called by __init__
657 # init_* methods called by __init__
658 #-------------------------------------------------------------------------
658 #-------------------------------------------------------------------------
659
659
660 def init_ipython_dir(self, ipython_dir):
660 def init_ipython_dir(self, ipython_dir):
661 if ipython_dir is not None:
661 if ipython_dir is not None:
662 self.ipython_dir = ipython_dir
662 self.ipython_dir = ipython_dir
663 return
663 return
664
664
665 self.ipython_dir = get_ipython_dir()
665 self.ipython_dir = get_ipython_dir()
666
666
667 def init_profile_dir(self, profile_dir):
667 def init_profile_dir(self, profile_dir):
668 if profile_dir is not None:
668 if profile_dir is not None:
669 self.profile_dir = profile_dir
669 self.profile_dir = profile_dir
670 return
670 return
671 self.profile_dir = ProfileDir.create_profile_dir_by_name(
671 self.profile_dir = ProfileDir.create_profile_dir_by_name(
672 self.ipython_dir, "default"
672 self.ipython_dir, "default"
673 )
673 )
674
674
675 def init_instance_attrs(self):
675 def init_instance_attrs(self):
676 self.more = False
676 self.more = False
677
677
678 # command compiler
678 # command compiler
679 self.compile = self.compiler_class()
679 self.compile = self.compiler_class()
680
680
681 # Make an empty namespace, which extension writers can rely on both
681 # Make an empty namespace, which extension writers can rely on both
682 # existing and NEVER being used by ipython itself. This gives them a
682 # existing and NEVER being used by ipython itself. This gives them a
683 # convenient location for storing additional information and state
683 # convenient location for storing additional information and state
684 # their extensions may require, without fear of collisions with other
684 # their extensions may require, without fear of collisions with other
685 # ipython names that may develop later.
685 # ipython names that may develop later.
686 self.meta = Struct()
686 self.meta = Struct()
687
687
688 # Temporary files used for various purposes. Deleted at exit.
688 # Temporary files used for various purposes. Deleted at exit.
689 # The files here are stored with Path from Pathlib
689 # The files here are stored with Path from Pathlib
690 self.tempfiles = []
690 self.tempfiles = []
691 self.tempdirs = []
691 self.tempdirs = []
692
692
693 # keep track of where we started running (mainly for crash post-mortem)
693 # keep track of where we started running (mainly for crash post-mortem)
694 # This is not being used anywhere currently.
694 # This is not being used anywhere currently.
695 self.starting_dir = os.getcwd()
695 self.starting_dir = os.getcwd()
696
696
697 # Indentation management
697 # Indentation management
698 self.indent_current_nsp = 0
698 self.indent_current_nsp = 0
699
699
700 # Dict to track post-execution functions that have been registered
700 # Dict to track post-execution functions that have been registered
701 self._post_execute = {}
701 self._post_execute = {}
702
702
703 def init_environment(self):
703 def init_environment(self):
704 """Any changes we need to make to the user's environment."""
704 """Any changes we need to make to the user's environment."""
705 pass
705 pass
706
706
707 def init_encoding(self):
707 def init_encoding(self):
708 # Get system encoding at startup time. Certain terminals (like Emacs
708 # Get system encoding at startup time. Certain terminals (like Emacs
709 # under Win32 have it set to None, and we need to have a known valid
709 # under Win32 have it set to None, and we need to have a known valid
710 # encoding to use in the raw_input() method
710 # encoding to use in the raw_input() method
711 try:
711 try:
712 self.stdin_encoding = sys.stdin.encoding or 'ascii'
712 self.stdin_encoding = sys.stdin.encoding or 'ascii'
713 except AttributeError:
713 except AttributeError:
714 self.stdin_encoding = 'ascii'
714 self.stdin_encoding = 'ascii'
715
715
716
716
717 @observe('colors')
717 @observe('colors')
718 def init_syntax_highlighting(self, changes=None):
718 def init_syntax_highlighting(self, changes=None):
719 # Python source parser/formatter for syntax highlighting
719 # Python source parser/formatter for syntax highlighting
720 pyformat = PyColorize.Parser(style=self.colors, parent=self).format
720 pyformat = PyColorize.Parser(style=self.colors, parent=self).format
721 self.pycolorize = lambda src: pyformat(src,'str')
721 self.pycolorize = lambda src: pyformat(src,'str')
722
722
723 def refresh_style(self):
723 def refresh_style(self):
724 # No-op here, used in subclass
724 # No-op here, used in subclass
725 pass
725 pass
726
726
727 def init_pushd_popd_magic(self):
727 def init_pushd_popd_magic(self):
728 # for pushd/popd management
728 # for pushd/popd management
729 self.home_dir = get_home_dir()
729 self.home_dir = get_home_dir()
730
730
731 self.dir_stack = []
731 self.dir_stack = []
732
732
733 def init_logger(self):
733 def init_logger(self):
734 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
734 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
735 logmode='rotate')
735 logmode='rotate')
736
736
737 def init_logstart(self):
737 def init_logstart(self):
738 """Initialize logging in case it was requested at the command line.
738 """Initialize logging in case it was requested at the command line.
739 """
739 """
740 if self.logappend:
740 if self.logappend:
741 self.magic('logstart %s append' % self.logappend)
741 self.magic('logstart %s append' % self.logappend)
742 elif self.logfile:
742 elif self.logfile:
743 self.magic('logstart %s' % self.logfile)
743 self.magic('logstart %s' % self.logfile)
744 elif self.logstart:
744 elif self.logstart:
745 self.magic('logstart')
745 self.magic('logstart')
746
746
747
747
748 def init_builtins(self):
748 def init_builtins(self):
749 # A single, static flag that we set to True. Its presence indicates
749 # A single, static flag that we set to True. Its presence indicates
750 # that an IPython shell has been created, and we make no attempts at
750 # that an IPython shell has been created, and we make no attempts at
751 # removing on exit or representing the existence of more than one
751 # removing on exit or representing the existence of more than one
752 # IPython at a time.
752 # IPython at a time.
753 builtin_mod.__dict__['__IPYTHON__'] = True
753 builtin_mod.__dict__['__IPYTHON__'] = True
754 builtin_mod.__dict__['display'] = display
754 builtin_mod.__dict__['display'] = display
755
755
756 self.builtin_trap = BuiltinTrap(shell=self)
756 self.builtin_trap = BuiltinTrap(shell=self)
757
757
758 @observe('colors')
758 @observe('colors')
759 def init_inspector(self, changes=None):
759 def init_inspector(self, changes=None):
760 # Object inspector
760 # Object inspector
761 self.inspector = self.inspector_class(
761 self.inspector = self.inspector_class(
762 oinspect.InspectColors,
762 oinspect.InspectColors,
763 PyColorize.ANSICodeColors,
763 PyColorize.ANSICodeColors,
764 self.colors,
764 self.colors,
765 self.object_info_string_level,
765 self.object_info_string_level,
766 )
766 )
767
767
768 def init_io(self):
768 def init_io(self):
769 # implemented in subclasses, TerminalInteractiveShell does call
769 # implemented in subclasses, TerminalInteractiveShell does call
770 # colorama.init().
770 # colorama.init().
771 pass
771 pass
772
772
773 def init_prompts(self):
773 def init_prompts(self):
774 # Set system prompts, so that scripts can decide if they are running
774 # Set system prompts, so that scripts can decide if they are running
775 # interactively.
775 # interactively.
776 sys.ps1 = 'In : '
776 sys.ps1 = 'In : '
777 sys.ps2 = '...: '
777 sys.ps2 = '...: '
778 sys.ps3 = 'Out: '
778 sys.ps3 = 'Out: '
779
779
780 def init_display_formatter(self):
780 def init_display_formatter(self):
781 self.display_formatter = DisplayFormatter(parent=self)
781 self.display_formatter = DisplayFormatter(parent=self)
782 self.configurables.append(self.display_formatter)
782 self.configurables.append(self.display_formatter)
783
783
784 def init_display_pub(self):
784 def init_display_pub(self):
785 self.display_pub = self.display_pub_class(parent=self, shell=self)
785 self.display_pub = self.display_pub_class(parent=self, shell=self)
786 self.configurables.append(self.display_pub)
786 self.configurables.append(self.display_pub)
787
787
788 def init_data_pub(self):
788 def init_data_pub(self):
789 if not self.data_pub_class:
789 if not self.data_pub_class:
790 self.data_pub = None
790 self.data_pub = None
791 return
791 return
792 self.data_pub = self.data_pub_class(parent=self)
792 self.data_pub = self.data_pub_class(parent=self)
793 self.configurables.append(self.data_pub)
793 self.configurables.append(self.data_pub)
794
794
795 def init_displayhook(self):
795 def init_displayhook(self):
796 # Initialize displayhook, set in/out prompts and printing system
796 # Initialize displayhook, set in/out prompts and printing system
797 self.displayhook = self.displayhook_class(
797 self.displayhook = self.displayhook_class(
798 parent=self,
798 parent=self,
799 shell=self,
799 shell=self,
800 cache_size=self.cache_size,
800 cache_size=self.cache_size,
801 )
801 )
802 self.configurables.append(self.displayhook)
802 self.configurables.append(self.displayhook)
803 # This is a context manager that installs/revmoes the displayhook at
803 # This is a context manager that installs/revmoes the displayhook at
804 # the appropriate time.
804 # the appropriate time.
805 self.display_trap = DisplayTrap(hook=self.displayhook)
805 self.display_trap = DisplayTrap(hook=self.displayhook)
806
806
807 @staticmethod
807 @staticmethod
808 def get_path_links(p: Path):
808 def get_path_links(p: Path):
809 """Gets path links including all symlinks
809 """Gets path links including all symlinks
810
810
811 Examples
811 Examples
812 --------
812 --------
813 In [1]: from IPython.core.interactiveshell import InteractiveShell
813 In [1]: from IPython.core.interactiveshell import InteractiveShell
814
814
815 In [2]: import sys, pathlib
815 In [2]: import sys, pathlib
816
816
817 In [3]: paths = InteractiveShell.get_path_links(pathlib.Path(sys.executable))
817 In [3]: paths = InteractiveShell.get_path_links(pathlib.Path(sys.executable))
818
818
819 In [4]: len(paths) == len(set(paths))
819 In [4]: len(paths) == len(set(paths))
820 Out[4]: True
820 Out[4]: True
821
821
822 In [5]: bool(paths)
822 In [5]: bool(paths)
823 Out[5]: True
823 Out[5]: True
824 """
824 """
825 paths = [p]
825 paths = [p]
826 while p.is_symlink():
826 while p.is_symlink():
827 new_path = Path(os.readlink(p))
827 new_path = Path(os.readlink(p))
828 if not new_path.is_absolute():
828 if not new_path.is_absolute():
829 new_path = p.parent / new_path
829 new_path = p.parent / new_path
830 p = new_path
830 p = new_path
831 paths.append(p)
831 paths.append(p)
832 return paths
832 return paths
833
833
834 def init_virtualenv(self):
834 def init_virtualenv(self):
835 """Add the current virtualenv to sys.path so the user can import modules from it.
835 """Add the current virtualenv to sys.path so the user can import modules from it.
836 This isn't perfect: it doesn't use the Python interpreter with which the
836 This isn't perfect: it doesn't use the Python interpreter with which the
837 virtualenv was built, and it ignores the --no-site-packages option. A
837 virtualenv was built, and it ignores the --no-site-packages option. A
838 warning will appear suggesting the user installs IPython in the
838 warning will appear suggesting the user installs IPython in the
839 virtualenv, but for many cases, it probably works well enough.
839 virtualenv, but for many cases, it probably works well enough.
840
840
841 Adapted from code snippets online.
841 Adapted from code snippets online.
842
842
843 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
843 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
844 """
844 """
845 if 'VIRTUAL_ENV' not in os.environ:
845 if 'VIRTUAL_ENV' not in os.environ:
846 # Not in a virtualenv
846 # Not in a virtualenv
847 return
847 return
848 elif os.environ["VIRTUAL_ENV"] == "":
848 elif os.environ["VIRTUAL_ENV"] == "":
849 warn("Virtual env path set to '', please check if this is intended.")
849 warn("Virtual env path set to '', please check if this is intended.")
850 return
850 return
851
851
852 p = Path(sys.executable)
852 p = Path(sys.executable)
853 p_venv = Path(os.environ["VIRTUAL_ENV"])
853 p_venv = Path(os.environ["VIRTUAL_ENV"])
854
854
855 # fallback venv detection:
855 # fallback venv detection:
856 # stdlib venv may symlink sys.executable, so we can't use realpath.
856 # stdlib venv may symlink sys.executable, so we can't use realpath.
857 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
857 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
858 # So we just check every item in the symlink tree (generally <= 3)
858 # So we just check every item in the symlink tree (generally <= 3)
859 paths = self.get_path_links(p)
859 paths = self.get_path_links(p)
860
860
861 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
861 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
862 if p_venv.parts[1] == "cygdrive":
862 if p_venv.parts[1] == "cygdrive":
863 drive_name = p_venv.parts[2]
863 drive_name = p_venv.parts[2]
864 p_venv = (drive_name + ":/") / Path(*p_venv.parts[3:])
864 p_venv = (drive_name + ":/") / Path(*p_venv.parts[3:])
865
865
866 if any(p_venv == p.parents[1] for p in paths):
866 if any(p_venv == p.parents[1] for p in paths):
867 # Our exe is inside or has access to the virtualenv, don't need to do anything.
867 # Our exe is inside or has access to the virtualenv, don't need to do anything.
868 return
868 return
869
869
870 if sys.platform == "win32":
870 if sys.platform == "win32":
871 virtual_env = str(Path(os.environ["VIRTUAL_ENV"], "Lib", "site-packages"))
871 virtual_env = str(Path(os.environ["VIRTUAL_ENV"], "Lib", "site-packages"))
872 else:
872 else:
873 virtual_env_path = Path(
873 virtual_env_path = Path(
874 os.environ["VIRTUAL_ENV"], "lib", "python{}.{}", "site-packages"
874 os.environ["VIRTUAL_ENV"], "lib", "python{}.{}", "site-packages"
875 )
875 )
876 p_ver = sys.version_info[:2]
876 p_ver = sys.version_info[:2]
877
877
878 # Predict version from py[thon]-x.x in the $VIRTUAL_ENV
878 # Predict version from py[thon]-x.x in the $VIRTUAL_ENV
879 re_m = re.search(r"\bpy(?:thon)?([23])\.(\d+)\b", os.environ["VIRTUAL_ENV"])
879 re_m = re.search(r"\bpy(?:thon)?([23])\.(\d+)\b", os.environ["VIRTUAL_ENV"])
880 if re_m:
880 if re_m:
881 predicted_path = Path(str(virtual_env_path).format(*re_m.groups()))
881 predicted_path = Path(str(virtual_env_path).format(*re_m.groups()))
882 if predicted_path.exists():
882 if predicted_path.exists():
883 p_ver = re_m.groups()
883 p_ver = re_m.groups()
884
884
885 virtual_env = str(virtual_env_path).format(*p_ver)
885 virtual_env = str(virtual_env_path).format(*p_ver)
886 if self.warn_venv:
886 if self.warn_venv:
887 warn(
887 warn(
888 "Attempting to work in a virtualenv. If you encounter problems, "
888 "Attempting to work in a virtualenv. If you encounter problems, "
889 "please install IPython inside the virtualenv."
889 "please install IPython inside the virtualenv."
890 )
890 )
891 import site
891 import site
892 sys.path.insert(0, virtual_env)
892 sys.path.insert(0, virtual_env)
893 site.addsitedir(virtual_env)
893 site.addsitedir(virtual_env)
894
894
895 #-------------------------------------------------------------------------
895 #-------------------------------------------------------------------------
896 # Things related to injections into the sys module
896 # Things related to injections into the sys module
897 #-------------------------------------------------------------------------
897 #-------------------------------------------------------------------------
898
898
899 def save_sys_module_state(self):
899 def save_sys_module_state(self):
900 """Save the state of hooks in the sys module.
900 """Save the state of hooks in the sys module.
901
901
902 This has to be called after self.user_module is created.
902 This has to be called after self.user_module is created.
903 """
903 """
904 self._orig_sys_module_state = {'stdin': sys.stdin,
904 self._orig_sys_module_state = {'stdin': sys.stdin,
905 'stdout': sys.stdout,
905 'stdout': sys.stdout,
906 'stderr': sys.stderr,
906 'stderr': sys.stderr,
907 'excepthook': sys.excepthook}
907 'excepthook': sys.excepthook}
908 self._orig_sys_modules_main_name = self.user_module.__name__
908 self._orig_sys_modules_main_name = self.user_module.__name__
909 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
909 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
910
910
911 def restore_sys_module_state(self):
911 def restore_sys_module_state(self):
912 """Restore the state of the sys module."""
912 """Restore the state of the sys module."""
913 try:
913 try:
914 for k, v in self._orig_sys_module_state.items():
914 for k, v in self._orig_sys_module_state.items():
915 setattr(sys, k, v)
915 setattr(sys, k, v)
916 except AttributeError:
916 except AttributeError:
917 pass
917 pass
918 # Reset what what done in self.init_sys_modules
918 # Reset what what done in self.init_sys_modules
919 if self._orig_sys_modules_main_mod is not None:
919 if self._orig_sys_modules_main_mod is not None:
920 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
920 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
921
921
922 #-------------------------------------------------------------------------
922 #-------------------------------------------------------------------------
923 # Things related to the banner
923 # Things related to the banner
924 #-------------------------------------------------------------------------
924 #-------------------------------------------------------------------------
925
925
926 @property
926 @property
927 def banner(self):
927 def banner(self):
928 banner = self.banner1
928 banner = self.banner1
929 if self.profile and self.profile != 'default':
929 if self.profile and self.profile != 'default':
930 banner += '\nIPython profile: %s\n' % self.profile
930 banner += '\nIPython profile: %s\n' % self.profile
931 if self.banner2:
931 if self.banner2:
932 banner += '\n' + self.banner2
932 banner += '\n' + self.banner2
933 return banner
933 return banner
934
934
935 def show_banner(self, banner=None):
935 def show_banner(self, banner=None):
936 if banner is None:
936 if banner is None:
937 banner = self.banner
937 banner = self.banner
938 sys.stdout.write(banner)
938 sys.stdout.write(banner)
939
939
940 #-------------------------------------------------------------------------
940 #-------------------------------------------------------------------------
941 # Things related to hooks
941 # Things related to hooks
942 #-------------------------------------------------------------------------
942 #-------------------------------------------------------------------------
943
943
944 def init_hooks(self):
944 def init_hooks(self):
945 # hooks holds pointers used for user-side customizations
945 # hooks holds pointers used for user-side customizations
946 self.hooks = Struct()
946 self.hooks = Struct()
947
947
948 self.strdispatchers = {}
948 self.strdispatchers = {}
949
949
950 # Set all default hooks, defined in the IPython.hooks module.
950 # Set all default hooks, defined in the IPython.hooks module.
951 hooks = IPython.core.hooks
951 hooks = IPython.core.hooks
952 for hook_name in hooks.__all__:
952 for hook_name in hooks.__all__:
953 # default hooks have priority 100, i.e. low; user hooks should have
953 # default hooks have priority 100, i.e. low; user hooks should have
954 # 0-100 priority
954 # 0-100 priority
955 self.set_hook(hook_name, getattr(hooks, hook_name), 100)
955 self.set_hook(hook_name, getattr(hooks, hook_name), 100)
956
956
957 if self.display_page:
957 if self.display_page:
958 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
958 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
959
959
960 def set_hook(self, name, hook, priority=50, str_key=None, re_key=None):
960 def set_hook(self, name, hook, priority=50, str_key=None, re_key=None):
961 """set_hook(name,hook) -> sets an internal IPython hook.
961 """set_hook(name,hook) -> sets an internal IPython hook.
962
962
963 IPython exposes some of its internal API as user-modifiable hooks. By
963 IPython exposes some of its internal API as user-modifiable hooks. By
964 adding your function to one of these hooks, you can modify IPython's
964 adding your function to one of these hooks, you can modify IPython's
965 behavior to call at runtime your own routines."""
965 behavior to call at runtime your own routines."""
966
966
967 # At some point in the future, this should validate the hook before it
967 # At some point in the future, this should validate the hook before it
968 # accepts it. Probably at least check that the hook takes the number
968 # accepts it. Probably at least check that the hook takes the number
969 # of args it's supposed to.
969 # of args it's supposed to.
970
970
971 f = types.MethodType(hook,self)
971 f = types.MethodType(hook,self)
972
972
973 # check if the hook is for strdispatcher first
973 # check if the hook is for strdispatcher first
974 if str_key is not None:
974 if str_key is not None:
975 sdp = self.strdispatchers.get(name, StrDispatch())
975 sdp = self.strdispatchers.get(name, StrDispatch())
976 sdp.add_s(str_key, f, priority )
976 sdp.add_s(str_key, f, priority )
977 self.strdispatchers[name] = sdp
977 self.strdispatchers[name] = sdp
978 return
978 return
979 if re_key is not None:
979 if re_key is not None:
980 sdp = self.strdispatchers.get(name, StrDispatch())
980 sdp = self.strdispatchers.get(name, StrDispatch())
981 sdp.add_re(re.compile(re_key), f, priority )
981 sdp.add_re(re.compile(re_key), f, priority )
982 self.strdispatchers[name] = sdp
982 self.strdispatchers[name] = sdp
983 return
983 return
984
984
985 dp = getattr(self.hooks, name, None)
985 dp = getattr(self.hooks, name, None)
986 if name not in IPython.core.hooks.__all__:
986 if name not in IPython.core.hooks.__all__:
987 print("Warning! Hook '%s' is not one of %s" % \
987 print("Warning! Hook '%s' is not one of %s" % \
988 (name, IPython.core.hooks.__all__ ))
988 (name, IPython.core.hooks.__all__ ))
989
989
990 if name in IPython.core.hooks.deprecated:
990 if name in IPython.core.hooks.deprecated:
991 alternative = IPython.core.hooks.deprecated[name]
991 alternative = IPython.core.hooks.deprecated[name]
992 raise ValueError(
992 raise ValueError(
993 "Hook {} has been deprecated since IPython 5.0. Use {} instead.".format(
993 "Hook {} has been deprecated since IPython 5.0. Use {} instead.".format(
994 name, alternative
994 name, alternative
995 )
995 )
996 )
996 )
997
997
998 if not dp:
998 if not dp:
999 dp = IPython.core.hooks.CommandChainDispatcher()
999 dp = IPython.core.hooks.CommandChainDispatcher()
1000
1000
1001 try:
1001 try:
1002 dp.add(f,priority)
1002 dp.add(f,priority)
1003 except AttributeError:
1003 except AttributeError:
1004 # it was not commandchain, plain old func - replace
1004 # it was not commandchain, plain old func - replace
1005 dp = f
1005 dp = f
1006
1006
1007 setattr(self.hooks,name, dp)
1007 setattr(self.hooks,name, dp)
1008
1008
1009 #-------------------------------------------------------------------------
1009 #-------------------------------------------------------------------------
1010 # Things related to events
1010 # Things related to events
1011 #-------------------------------------------------------------------------
1011 #-------------------------------------------------------------------------
1012
1012
1013 def init_events(self):
1013 def init_events(self):
1014 self.events = EventManager(self, available_events)
1014 self.events = EventManager(self, available_events)
1015
1015
1016 self.events.register("pre_execute", self._clear_warning_registry)
1016 self.events.register("pre_execute", self._clear_warning_registry)
1017
1017
1018 def register_post_execute(self, func):
1018 def register_post_execute(self, func):
1019 """DEPRECATED: Use ip.events.register('post_run_cell', func)
1019 """DEPRECATED: Use ip.events.register('post_run_cell', func)
1020
1020
1021 Register a function for calling after code execution.
1021 Register a function for calling after code execution.
1022 """
1022 """
1023 raise ValueError(
1023 raise ValueError(
1024 "ip.register_post_execute is deprecated since IPython 1.0, use "
1024 "ip.register_post_execute is deprecated since IPython 1.0, use "
1025 "ip.events.register('post_run_cell', func) instead."
1025 "ip.events.register('post_run_cell', func) instead."
1026 )
1026 )
1027
1027
1028 def _clear_warning_registry(self):
1028 def _clear_warning_registry(self):
1029 # clear the warning registry, so that different code blocks with
1029 # clear the warning registry, so that different code blocks with
1030 # overlapping line number ranges don't cause spurious suppression of
1030 # overlapping line number ranges don't cause spurious suppression of
1031 # warnings (see gh-6611 for details)
1031 # warnings (see gh-6611 for details)
1032 if "__warningregistry__" in self.user_global_ns:
1032 if "__warningregistry__" in self.user_global_ns:
1033 del self.user_global_ns["__warningregistry__"]
1033 del self.user_global_ns["__warningregistry__"]
1034
1034
1035 #-------------------------------------------------------------------------
1035 #-------------------------------------------------------------------------
1036 # Things related to the "main" module
1036 # Things related to the "main" module
1037 #-------------------------------------------------------------------------
1037 #-------------------------------------------------------------------------
1038
1038
1039 def new_main_mod(self, filename, modname):
1039 def new_main_mod(self, filename, modname):
1040 """Return a new 'main' module object for user code execution.
1040 """Return a new 'main' module object for user code execution.
1041
1041
1042 ``filename`` should be the path of the script which will be run in the
1042 ``filename`` should be the path of the script which will be run in the
1043 module. Requests with the same filename will get the same module, with
1043 module. Requests with the same filename will get the same module, with
1044 its namespace cleared.
1044 its namespace cleared.
1045
1045
1046 ``modname`` should be the module name - normally either '__main__' or
1046 ``modname`` should be the module name - normally either '__main__' or
1047 the basename of the file without the extension.
1047 the basename of the file without the extension.
1048
1048
1049 When scripts are executed via %run, we must keep a reference to their
1049 When scripts are executed via %run, we must keep a reference to their
1050 __main__ module around so that Python doesn't
1050 __main__ module around so that Python doesn't
1051 clear it, rendering references to module globals useless.
1051 clear it, rendering references to module globals useless.
1052
1052
1053 This method keeps said reference in a private dict, keyed by the
1053 This method keeps said reference in a private dict, keyed by the
1054 absolute path of the script. This way, for multiple executions of the
1054 absolute path of the script. This way, for multiple executions of the
1055 same script we only keep one copy of the namespace (the last one),
1055 same script we only keep one copy of the namespace (the last one),
1056 thus preventing memory leaks from old references while allowing the
1056 thus preventing memory leaks from old references while allowing the
1057 objects from the last execution to be accessible.
1057 objects from the last execution to be accessible.
1058 """
1058 """
1059 filename = os.path.abspath(filename)
1059 filename = os.path.abspath(filename)
1060 try:
1060 try:
1061 main_mod = self._main_mod_cache[filename]
1061 main_mod = self._main_mod_cache[filename]
1062 except KeyError:
1062 except KeyError:
1063 main_mod = self._main_mod_cache[filename] = types.ModuleType(
1063 main_mod = self._main_mod_cache[filename] = types.ModuleType(
1064 modname,
1064 modname,
1065 doc="Module created for script run in IPython")
1065 doc="Module created for script run in IPython")
1066 else:
1066 else:
1067 main_mod.__dict__.clear()
1067 main_mod.__dict__.clear()
1068 main_mod.__name__ = modname
1068 main_mod.__name__ = modname
1069
1069
1070 main_mod.__file__ = filename
1070 main_mod.__file__ = filename
1071 # It seems pydoc (and perhaps others) needs any module instance to
1071 # It seems pydoc (and perhaps others) needs any module instance to
1072 # implement a __nonzero__ method
1072 # implement a __nonzero__ method
1073 main_mod.__nonzero__ = lambda : True
1073 main_mod.__nonzero__ = lambda : True
1074
1074
1075 return main_mod
1075 return main_mod
1076
1076
1077 def clear_main_mod_cache(self):
1077 def clear_main_mod_cache(self):
1078 """Clear the cache of main modules.
1078 """Clear the cache of main modules.
1079
1079
1080 Mainly for use by utilities like %reset.
1080 Mainly for use by utilities like %reset.
1081
1081
1082 Examples
1082 Examples
1083 --------
1083 --------
1084 In [15]: import IPython
1084 In [15]: import IPython
1085
1085
1086 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
1086 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
1087
1087
1088 In [17]: len(_ip._main_mod_cache) > 0
1088 In [17]: len(_ip._main_mod_cache) > 0
1089 Out[17]: True
1089 Out[17]: True
1090
1090
1091 In [18]: _ip.clear_main_mod_cache()
1091 In [18]: _ip.clear_main_mod_cache()
1092
1092
1093 In [19]: len(_ip._main_mod_cache) == 0
1093 In [19]: len(_ip._main_mod_cache) == 0
1094 Out[19]: True
1094 Out[19]: True
1095 """
1095 """
1096 self._main_mod_cache.clear()
1096 self._main_mod_cache.clear()
1097
1097
1098 #-------------------------------------------------------------------------
1098 #-------------------------------------------------------------------------
1099 # Things related to debugging
1099 # Things related to debugging
1100 #-------------------------------------------------------------------------
1100 #-------------------------------------------------------------------------
1101
1101
1102 def init_pdb(self):
1102 def init_pdb(self):
1103 # Set calling of pdb on exceptions
1103 # Set calling of pdb on exceptions
1104 # self.call_pdb is a property
1104 # self.call_pdb is a property
1105 self.call_pdb = self.pdb
1105 self.call_pdb = self.pdb
1106
1106
1107 def _get_call_pdb(self):
1107 def _get_call_pdb(self):
1108 return self._call_pdb
1108 return self._call_pdb
1109
1109
1110 def _set_call_pdb(self,val):
1110 def _set_call_pdb(self,val):
1111
1111
1112 if val not in (0,1,False,True):
1112 if val not in (0,1,False,True):
1113 raise ValueError('new call_pdb value must be boolean')
1113 raise ValueError('new call_pdb value must be boolean')
1114
1114
1115 # store value in instance
1115 # store value in instance
1116 self._call_pdb = val
1116 self._call_pdb = val
1117
1117
1118 # notify the actual exception handlers
1118 # notify the actual exception handlers
1119 self.InteractiveTB.call_pdb = val
1119 self.InteractiveTB.call_pdb = val
1120
1120
1121 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1121 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1122 'Control auto-activation of pdb at exceptions')
1122 'Control auto-activation of pdb at exceptions')
1123
1123
1124 def debugger(self,force=False):
1124 def debugger(self,force=False):
1125 """Call the pdb debugger.
1125 """Call the pdb debugger.
1126
1126
1127 Keywords:
1127 Keywords:
1128
1128
1129 - force(False): by default, this routine checks the instance call_pdb
1129 - force(False): by default, this routine checks the instance call_pdb
1130 flag and does not actually invoke the debugger if the flag is false.
1130 flag and does not actually invoke the debugger if the flag is false.
1131 The 'force' option forces the debugger to activate even if the flag
1131 The 'force' option forces the debugger to activate even if the flag
1132 is false.
1132 is false.
1133 """
1133 """
1134
1134
1135 if not (force or self.call_pdb):
1135 if not (force or self.call_pdb):
1136 return
1136 return
1137
1137
1138 if not hasattr(sys,'last_traceback'):
1138 if not hasattr(sys,'last_traceback'):
1139 error('No traceback has been produced, nothing to debug.')
1139 error('No traceback has been produced, nothing to debug.')
1140 return
1140 return
1141
1141
1142 self.InteractiveTB.debugger(force=True)
1142 self.InteractiveTB.debugger(force=True)
1143
1143
1144 #-------------------------------------------------------------------------
1144 #-------------------------------------------------------------------------
1145 # Things related to IPython's various namespaces
1145 # Things related to IPython's various namespaces
1146 #-------------------------------------------------------------------------
1146 #-------------------------------------------------------------------------
1147 default_user_namespaces = True
1147 default_user_namespaces = True
1148
1148
1149 def init_create_namespaces(self, user_module=None, user_ns=None):
1149 def init_create_namespaces(self, user_module=None, user_ns=None):
1150 # Create the namespace where the user will operate. user_ns is
1150 # Create the namespace where the user will operate. user_ns is
1151 # normally the only one used, and it is passed to the exec calls as
1151 # normally the only one used, and it is passed to the exec calls as
1152 # the locals argument. But we do carry a user_global_ns namespace
1152 # the locals argument. But we do carry a user_global_ns namespace
1153 # given as the exec 'globals' argument, This is useful in embedding
1153 # given as the exec 'globals' argument, This is useful in embedding
1154 # situations where the ipython shell opens in a context where the
1154 # situations where the ipython shell opens in a context where the
1155 # distinction between locals and globals is meaningful. For
1155 # distinction between locals and globals is meaningful. For
1156 # non-embedded contexts, it is just the same object as the user_ns dict.
1156 # non-embedded contexts, it is just the same object as the user_ns dict.
1157
1157
1158 # FIXME. For some strange reason, __builtins__ is showing up at user
1158 # FIXME. For some strange reason, __builtins__ is showing up at user
1159 # level as a dict instead of a module. This is a manual fix, but I
1159 # level as a dict instead of a module. This is a manual fix, but I
1160 # should really track down where the problem is coming from. Alex
1160 # should really track down where the problem is coming from. Alex
1161 # Schmolck reported this problem first.
1161 # Schmolck reported this problem first.
1162
1162
1163 # A useful post by Alex Martelli on this topic:
1163 # A useful post by Alex Martelli on this topic:
1164 # Re: inconsistent value from __builtins__
1164 # Re: inconsistent value from __builtins__
1165 # Von: Alex Martelli <aleaxit@yahoo.com>
1165 # Von: Alex Martelli <aleaxit@yahoo.com>
1166 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1166 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1167 # Gruppen: comp.lang.python
1167 # Gruppen: comp.lang.python
1168
1168
1169 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1169 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1170 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1170 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1171 # > <type 'dict'>
1171 # > <type 'dict'>
1172 # > >>> print type(__builtins__)
1172 # > >>> print type(__builtins__)
1173 # > <type 'module'>
1173 # > <type 'module'>
1174 # > Is this difference in return value intentional?
1174 # > Is this difference in return value intentional?
1175
1175
1176 # Well, it's documented that '__builtins__' can be either a dictionary
1176 # Well, it's documented that '__builtins__' can be either a dictionary
1177 # or a module, and it's been that way for a long time. Whether it's
1177 # or a module, and it's been that way for a long time. Whether it's
1178 # intentional (or sensible), I don't know. In any case, the idea is
1178 # intentional (or sensible), I don't know. In any case, the idea is
1179 # that if you need to access the built-in namespace directly, you
1179 # that if you need to access the built-in namespace directly, you
1180 # should start with "import __builtin__" (note, no 's') which will
1180 # should start with "import __builtin__" (note, no 's') which will
1181 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1181 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1182
1182
1183 # These routines return a properly built module and dict as needed by
1183 # These routines return a properly built module and dict as needed by
1184 # the rest of the code, and can also be used by extension writers to
1184 # the rest of the code, and can also be used by extension writers to
1185 # generate properly initialized namespaces.
1185 # generate properly initialized namespaces.
1186 if (user_ns is not None) or (user_module is not None):
1186 if (user_ns is not None) or (user_module is not None):
1187 self.default_user_namespaces = False
1187 self.default_user_namespaces = False
1188 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1188 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1189
1189
1190 # A record of hidden variables we have added to the user namespace, so
1190 # A record of hidden variables we have added to the user namespace, so
1191 # we can list later only variables defined in actual interactive use.
1191 # we can list later only variables defined in actual interactive use.
1192 self.user_ns_hidden = {}
1192 self.user_ns_hidden = {}
1193
1193
1194 # Now that FakeModule produces a real module, we've run into a nasty
1194 # Now that FakeModule produces a real module, we've run into a nasty
1195 # problem: after script execution (via %run), the module where the user
1195 # problem: after script execution (via %run), the module where the user
1196 # code ran is deleted. Now that this object is a true module (needed
1196 # code ran is deleted. Now that this object is a true module (needed
1197 # so doctest and other tools work correctly), the Python module
1197 # so doctest and other tools work correctly), the Python module
1198 # teardown mechanism runs over it, and sets to None every variable
1198 # teardown mechanism runs over it, and sets to None every variable
1199 # present in that module. Top-level references to objects from the
1199 # present in that module. Top-level references to objects from the
1200 # script survive, because the user_ns is updated with them. However,
1200 # script survive, because the user_ns is updated with them. However,
1201 # calling functions defined in the script that use other things from
1201 # calling functions defined in the script that use other things from
1202 # the script will fail, because the function's closure had references
1202 # the script will fail, because the function's closure had references
1203 # to the original objects, which are now all None. So we must protect
1203 # to the original objects, which are now all None. So we must protect
1204 # these modules from deletion by keeping a cache.
1204 # these modules from deletion by keeping a cache.
1205 #
1205 #
1206 # To avoid keeping stale modules around (we only need the one from the
1206 # To avoid keeping stale modules around (we only need the one from the
1207 # last run), we use a dict keyed with the full path to the script, so
1207 # last run), we use a dict keyed with the full path to the script, so
1208 # only the last version of the module is held in the cache. Note,
1208 # only the last version of the module is held in the cache. Note,
1209 # however, that we must cache the module *namespace contents* (their
1209 # however, that we must cache the module *namespace contents* (their
1210 # __dict__). Because if we try to cache the actual modules, old ones
1210 # __dict__). Because if we try to cache the actual modules, old ones
1211 # (uncached) could be destroyed while still holding references (such as
1211 # (uncached) could be destroyed while still holding references (such as
1212 # those held by GUI objects that tend to be long-lived)>
1212 # those held by GUI objects that tend to be long-lived)>
1213 #
1213 #
1214 # The %reset command will flush this cache. See the cache_main_mod()
1214 # The %reset command will flush this cache. See the cache_main_mod()
1215 # and clear_main_mod_cache() methods for details on use.
1215 # and clear_main_mod_cache() methods for details on use.
1216
1216
1217 # This is the cache used for 'main' namespaces
1217 # This is the cache used for 'main' namespaces
1218 self._main_mod_cache = {}
1218 self._main_mod_cache = {}
1219
1219
1220 # A table holding all the namespaces IPython deals with, so that
1220 # A table holding all the namespaces IPython deals with, so that
1221 # introspection facilities can search easily.
1221 # introspection facilities can search easily.
1222 self.ns_table = {'user_global':self.user_module.__dict__,
1222 self.ns_table = {'user_global':self.user_module.__dict__,
1223 'user_local':self.user_ns,
1223 'user_local':self.user_ns,
1224 'builtin':builtin_mod.__dict__
1224 'builtin':builtin_mod.__dict__
1225 }
1225 }
1226
1226
1227 @property
1227 @property
1228 def user_global_ns(self):
1228 def user_global_ns(self):
1229 return self.user_module.__dict__
1229 return self.user_module.__dict__
1230
1230
1231 def prepare_user_module(self, user_module=None, user_ns=None):
1231 def prepare_user_module(self, user_module=None, user_ns=None):
1232 """Prepare the module and namespace in which user code will be run.
1232 """Prepare the module and namespace in which user code will be run.
1233
1233
1234 When IPython is started normally, both parameters are None: a new module
1234 When IPython is started normally, both parameters are None: a new module
1235 is created automatically, and its __dict__ used as the namespace.
1235 is created automatically, and its __dict__ used as the namespace.
1236
1236
1237 If only user_module is provided, its __dict__ is used as the namespace.
1237 If only user_module is provided, its __dict__ is used as the namespace.
1238 If only user_ns is provided, a dummy module is created, and user_ns
1238 If only user_ns is provided, a dummy module is created, and user_ns
1239 becomes the global namespace. If both are provided (as they may be
1239 becomes the global namespace. If both are provided (as they may be
1240 when embedding), user_ns is the local namespace, and user_module
1240 when embedding), user_ns is the local namespace, and user_module
1241 provides the global namespace.
1241 provides the global namespace.
1242
1242
1243 Parameters
1243 Parameters
1244 ----------
1244 ----------
1245 user_module : module, optional
1245 user_module : module, optional
1246 The current user module in which IPython is being run. If None,
1246 The current user module in which IPython is being run. If None,
1247 a clean module will be created.
1247 a clean module will be created.
1248 user_ns : dict, optional
1248 user_ns : dict, optional
1249 A namespace in which to run interactive commands.
1249 A namespace in which to run interactive commands.
1250
1250
1251 Returns
1251 Returns
1252 -------
1252 -------
1253 A tuple of user_module and user_ns, each properly initialised.
1253 A tuple of user_module and user_ns, each properly initialised.
1254 """
1254 """
1255 if user_module is None and user_ns is not None:
1255 if user_module is None and user_ns is not None:
1256 user_ns.setdefault("__name__", "__main__")
1256 user_ns.setdefault("__name__", "__main__")
1257 user_module = DummyMod()
1257 user_module = DummyMod()
1258 user_module.__dict__ = user_ns
1258 user_module.__dict__ = user_ns
1259
1259
1260 if user_module is None:
1260 if user_module is None:
1261 user_module = types.ModuleType("__main__",
1261 user_module = types.ModuleType("__main__",
1262 doc="Automatically created module for IPython interactive environment")
1262 doc="Automatically created module for IPython interactive environment")
1263
1263
1264 # We must ensure that __builtin__ (without the final 's') is always
1264 # We must ensure that __builtin__ (without the final 's') is always
1265 # available and pointing to the __builtin__ *module*. For more details:
1265 # available and pointing to the __builtin__ *module*. For more details:
1266 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1266 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1267 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1267 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1268 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1268 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1269
1269
1270 if user_ns is None:
1270 if user_ns is None:
1271 user_ns = user_module.__dict__
1271 user_ns = user_module.__dict__
1272
1272
1273 return user_module, user_ns
1273 return user_module, user_ns
1274
1274
1275 def init_sys_modules(self):
1275 def init_sys_modules(self):
1276 # We need to insert into sys.modules something that looks like a
1276 # We need to insert into sys.modules something that looks like a
1277 # module but which accesses the IPython namespace, for shelve and
1277 # module but which accesses the IPython namespace, for shelve and
1278 # pickle to work interactively. Normally they rely on getting
1278 # pickle to work interactively. Normally they rely on getting
1279 # everything out of __main__, but for embedding purposes each IPython
1279 # everything out of __main__, but for embedding purposes each IPython
1280 # instance has its own private namespace, so we can't go shoving
1280 # instance has its own private namespace, so we can't go shoving
1281 # everything into __main__.
1281 # everything into __main__.
1282
1282
1283 # note, however, that we should only do this for non-embedded
1283 # note, however, that we should only do this for non-embedded
1284 # ipythons, which really mimic the __main__.__dict__ with their own
1284 # ipythons, which really mimic the __main__.__dict__ with their own
1285 # namespace. Embedded instances, on the other hand, should not do
1285 # namespace. Embedded instances, on the other hand, should not do
1286 # this because they need to manage the user local/global namespaces
1286 # this because they need to manage the user local/global namespaces
1287 # only, but they live within a 'normal' __main__ (meaning, they
1287 # only, but they live within a 'normal' __main__ (meaning, they
1288 # shouldn't overtake the execution environment of the script they're
1288 # shouldn't overtake the execution environment of the script they're
1289 # embedded in).
1289 # embedded in).
1290
1290
1291 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1291 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1292 main_name = self.user_module.__name__
1292 main_name = self.user_module.__name__
1293 sys.modules[main_name] = self.user_module
1293 sys.modules[main_name] = self.user_module
1294
1294
1295 def init_user_ns(self):
1295 def init_user_ns(self):
1296 """Initialize all user-visible namespaces to their minimum defaults.
1296 """Initialize all user-visible namespaces to their minimum defaults.
1297
1297
1298 Certain history lists are also initialized here, as they effectively
1298 Certain history lists are also initialized here, as they effectively
1299 act as user namespaces.
1299 act as user namespaces.
1300
1300
1301 Notes
1301 Notes
1302 -----
1302 -----
1303 All data structures here are only filled in, they are NOT reset by this
1303 All data structures here are only filled in, they are NOT reset by this
1304 method. If they were not empty before, data will simply be added to
1304 method. If they were not empty before, data will simply be added to
1305 them.
1305 them.
1306 """
1306 """
1307 # This function works in two parts: first we put a few things in
1307 # This function works in two parts: first we put a few things in
1308 # user_ns, and we sync that contents into user_ns_hidden so that these
1308 # user_ns, and we sync that contents into user_ns_hidden so that these
1309 # initial variables aren't shown by %who. After the sync, we add the
1309 # initial variables aren't shown by %who. After the sync, we add the
1310 # rest of what we *do* want the user to see with %who even on a new
1310 # rest of what we *do* want the user to see with %who even on a new
1311 # session (probably nothing, so they really only see their own stuff)
1311 # session (probably nothing, so they really only see their own stuff)
1312
1312
1313 # The user dict must *always* have a __builtin__ reference to the
1313 # The user dict must *always* have a __builtin__ reference to the
1314 # Python standard __builtin__ namespace, which must be imported.
1314 # Python standard __builtin__ namespace, which must be imported.
1315 # This is so that certain operations in prompt evaluation can be
1315 # This is so that certain operations in prompt evaluation can be
1316 # reliably executed with builtins. Note that we can NOT use
1316 # reliably executed with builtins. Note that we can NOT use
1317 # __builtins__ (note the 's'), because that can either be a dict or a
1317 # __builtins__ (note the 's'), because that can either be a dict or a
1318 # module, and can even mutate at runtime, depending on the context
1318 # module, and can even mutate at runtime, depending on the context
1319 # (Python makes no guarantees on it). In contrast, __builtin__ is
1319 # (Python makes no guarantees on it). In contrast, __builtin__ is
1320 # always a module object, though it must be explicitly imported.
1320 # always a module object, though it must be explicitly imported.
1321
1321
1322 # For more details:
1322 # For more details:
1323 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1323 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1324 ns = {}
1324 ns = {}
1325
1325
1326 # make global variables for user access to the histories
1326 # make global variables for user access to the histories
1327 ns['_ih'] = self.history_manager.input_hist_parsed
1327 ns['_ih'] = self.history_manager.input_hist_parsed
1328 ns['_oh'] = self.history_manager.output_hist
1328 ns['_oh'] = self.history_manager.output_hist
1329 ns['_dh'] = self.history_manager.dir_hist
1329 ns['_dh'] = self.history_manager.dir_hist
1330
1330
1331 # user aliases to input and output histories. These shouldn't show up
1331 # user aliases to input and output histories. These shouldn't show up
1332 # in %who, as they can have very large reprs.
1332 # in %who, as they can have very large reprs.
1333 ns['In'] = self.history_manager.input_hist_parsed
1333 ns['In'] = self.history_manager.input_hist_parsed
1334 ns['Out'] = self.history_manager.output_hist
1334 ns['Out'] = self.history_manager.output_hist
1335
1335
1336 # Store myself as the public api!!!
1336 # Store myself as the public api!!!
1337 ns['get_ipython'] = self.get_ipython
1337 ns['get_ipython'] = self.get_ipython
1338
1338
1339 ns['exit'] = self.exiter
1339 ns['exit'] = self.exiter
1340 ns['quit'] = self.exiter
1340 ns['quit'] = self.exiter
1341 ns["open"] = _modified_open
1341 ns["open"] = _modified_open
1342
1342
1343 # Sync what we've added so far to user_ns_hidden so these aren't seen
1343 # Sync what we've added so far to user_ns_hidden so these aren't seen
1344 # by %who
1344 # by %who
1345 self.user_ns_hidden.update(ns)
1345 self.user_ns_hidden.update(ns)
1346
1346
1347 # Anything put into ns now would show up in %who. Think twice before
1347 # Anything put into ns now would show up in %who. Think twice before
1348 # putting anything here, as we really want %who to show the user their
1348 # putting anything here, as we really want %who to show the user their
1349 # stuff, not our variables.
1349 # stuff, not our variables.
1350
1350
1351 # Finally, update the real user's namespace
1351 # Finally, update the real user's namespace
1352 self.user_ns.update(ns)
1352 self.user_ns.update(ns)
1353
1353
1354 @property
1354 @property
1355 def all_ns_refs(self):
1355 def all_ns_refs(self):
1356 """Get a list of references to all the namespace dictionaries in which
1356 """Get a list of references to all the namespace dictionaries in which
1357 IPython might store a user-created object.
1357 IPython might store a user-created object.
1358
1358
1359 Note that this does not include the displayhook, which also caches
1359 Note that this does not include the displayhook, which also caches
1360 objects from the output."""
1360 objects from the output."""
1361 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1361 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1362 [m.__dict__ for m in self._main_mod_cache.values()]
1362 [m.__dict__ for m in self._main_mod_cache.values()]
1363
1363
1364 def reset(self, new_session=True, aggressive=False):
1364 def reset(self, new_session=True, aggressive=False):
1365 """Clear all internal namespaces, and attempt to release references to
1365 """Clear all internal namespaces, and attempt to release references to
1366 user objects.
1366 user objects.
1367
1367
1368 If new_session is True, a new history session will be opened.
1368 If new_session is True, a new history session will be opened.
1369 """
1369 """
1370 # Clear histories
1370 # Clear histories
1371 self.history_manager.reset(new_session)
1371 self.history_manager.reset(new_session)
1372 # Reset counter used to index all histories
1372 # Reset counter used to index all histories
1373 if new_session:
1373 if new_session:
1374 self.execution_count = 1
1374 self.execution_count = 1
1375
1375
1376 # Reset last execution result
1376 # Reset last execution result
1377 self.last_execution_succeeded = True
1377 self.last_execution_succeeded = True
1378 self.last_execution_result = None
1378 self.last_execution_result = None
1379
1379
1380 # Flush cached output items
1380 # Flush cached output items
1381 if self.displayhook.do_full_cache:
1381 if self.displayhook.do_full_cache:
1382 self.displayhook.flush()
1382 self.displayhook.flush()
1383
1383
1384 # The main execution namespaces must be cleared very carefully,
1384 # The main execution namespaces must be cleared very carefully,
1385 # skipping the deletion of the builtin-related keys, because doing so
1385 # skipping the deletion of the builtin-related keys, because doing so
1386 # would cause errors in many object's __del__ methods.
1386 # would cause errors in many object's __del__ methods.
1387 if self.user_ns is not self.user_global_ns:
1387 if self.user_ns is not self.user_global_ns:
1388 self.user_ns.clear()
1388 self.user_ns.clear()
1389 ns = self.user_global_ns
1389 ns = self.user_global_ns
1390 drop_keys = set(ns.keys())
1390 drop_keys = set(ns.keys())
1391 drop_keys.discard('__builtin__')
1391 drop_keys.discard('__builtin__')
1392 drop_keys.discard('__builtins__')
1392 drop_keys.discard('__builtins__')
1393 drop_keys.discard('__name__')
1393 drop_keys.discard('__name__')
1394 for k in drop_keys:
1394 for k in drop_keys:
1395 del ns[k]
1395 del ns[k]
1396
1396
1397 self.user_ns_hidden.clear()
1397 self.user_ns_hidden.clear()
1398
1398
1399 # Restore the user namespaces to minimal usability
1399 # Restore the user namespaces to minimal usability
1400 self.init_user_ns()
1400 self.init_user_ns()
1401 if aggressive and not hasattr(self, "_sys_modules_keys"):
1401 if aggressive and not hasattr(self, "_sys_modules_keys"):
1402 print("Cannot restore sys.module, no snapshot")
1402 print("Cannot restore sys.module, no snapshot")
1403 elif aggressive:
1403 elif aggressive:
1404 print("culling sys module...")
1404 print("culling sys module...")
1405 current_keys = set(sys.modules.keys())
1405 current_keys = set(sys.modules.keys())
1406 for k in current_keys - self._sys_modules_keys:
1406 for k in current_keys - self._sys_modules_keys:
1407 if k.startswith("multiprocessing"):
1407 if k.startswith("multiprocessing"):
1408 continue
1408 continue
1409 del sys.modules[k]
1409 del sys.modules[k]
1410
1410
1411 # Restore the default and user aliases
1411 # Restore the default and user aliases
1412 self.alias_manager.clear_aliases()
1412 self.alias_manager.clear_aliases()
1413 self.alias_manager.init_aliases()
1413 self.alias_manager.init_aliases()
1414
1414
1415 # Now define aliases that only make sense on the terminal, because they
1415 # Now define aliases that only make sense on the terminal, because they
1416 # need direct access to the console in a way that we can't emulate in
1416 # need direct access to the console in a way that we can't emulate in
1417 # GUI or web frontend
1417 # GUI or web frontend
1418 if os.name == 'posix':
1418 if os.name == 'posix':
1419 for cmd in ('clear', 'more', 'less', 'man'):
1419 for cmd in ('clear', 'more', 'less', 'man'):
1420 if cmd not in self.magics_manager.magics['line']:
1420 if cmd not in self.magics_manager.magics['line']:
1421 self.alias_manager.soft_define_alias(cmd, cmd)
1421 self.alias_manager.soft_define_alias(cmd, cmd)
1422
1422
1423 # Flush the private list of module references kept for script
1423 # Flush the private list of module references kept for script
1424 # execution protection
1424 # execution protection
1425 self.clear_main_mod_cache()
1425 self.clear_main_mod_cache()
1426
1426
1427 def del_var(self, varname, by_name=False):
1427 def del_var(self, varname, by_name=False):
1428 """Delete a variable from the various namespaces, so that, as
1428 """Delete a variable from the various namespaces, so that, as
1429 far as possible, we're not keeping any hidden references to it.
1429 far as possible, we're not keeping any hidden references to it.
1430
1430
1431 Parameters
1431 Parameters
1432 ----------
1432 ----------
1433 varname : str
1433 varname : str
1434 The name of the variable to delete.
1434 The name of the variable to delete.
1435 by_name : bool
1435 by_name : bool
1436 If True, delete variables with the given name in each
1436 If True, delete variables with the given name in each
1437 namespace. If False (default), find the variable in the user
1437 namespace. If False (default), find the variable in the user
1438 namespace, and delete references to it.
1438 namespace, and delete references to it.
1439 """
1439 """
1440 if varname in ('__builtin__', '__builtins__'):
1440 if varname in ('__builtin__', '__builtins__'):
1441 raise ValueError("Refusing to delete %s" % varname)
1441 raise ValueError("Refusing to delete %s" % varname)
1442
1442
1443 ns_refs = self.all_ns_refs
1443 ns_refs = self.all_ns_refs
1444
1444
1445 if by_name: # Delete by name
1445 if by_name: # Delete by name
1446 for ns in ns_refs:
1446 for ns in ns_refs:
1447 try:
1447 try:
1448 del ns[varname]
1448 del ns[varname]
1449 except KeyError:
1449 except KeyError:
1450 pass
1450 pass
1451 else: # Delete by object
1451 else: # Delete by object
1452 try:
1452 try:
1453 obj = self.user_ns[varname]
1453 obj = self.user_ns[varname]
1454 except KeyError as e:
1454 except KeyError as e:
1455 raise NameError("name '%s' is not defined" % varname) from e
1455 raise NameError("name '%s' is not defined" % varname) from e
1456 # Also check in output history
1456 # Also check in output history
1457 ns_refs.append(self.history_manager.output_hist)
1457 ns_refs.append(self.history_manager.output_hist)
1458 for ns in ns_refs:
1458 for ns in ns_refs:
1459 to_delete = [n for n, o in ns.items() if o is obj]
1459 to_delete = [n for n, o in ns.items() if o is obj]
1460 for name in to_delete:
1460 for name in to_delete:
1461 del ns[name]
1461 del ns[name]
1462
1462
1463 # Ensure it is removed from the last execution result
1463 # Ensure it is removed from the last execution result
1464 if self.last_execution_result.result is obj:
1464 if self.last_execution_result.result is obj:
1465 self.last_execution_result = None
1465 self.last_execution_result = None
1466
1466
1467 # displayhook keeps extra references, but not in a dictionary
1467 # displayhook keeps extra references, but not in a dictionary
1468 for name in ('_', '__', '___'):
1468 for name in ('_', '__', '___'):
1469 if getattr(self.displayhook, name) is obj:
1469 if getattr(self.displayhook, name) is obj:
1470 setattr(self.displayhook, name, None)
1470 setattr(self.displayhook, name, None)
1471
1471
1472 def reset_selective(self, regex=None):
1472 def reset_selective(self, regex=None):
1473 """Clear selective variables from internal namespaces based on a
1473 """Clear selective variables from internal namespaces based on a
1474 specified regular expression.
1474 specified regular expression.
1475
1475
1476 Parameters
1476 Parameters
1477 ----------
1477 ----------
1478 regex : string or compiled pattern, optional
1478 regex : string or compiled pattern, optional
1479 A regular expression pattern that will be used in searching
1479 A regular expression pattern that will be used in searching
1480 variable names in the users namespaces.
1480 variable names in the users namespaces.
1481 """
1481 """
1482 if regex is not None:
1482 if regex is not None:
1483 try:
1483 try:
1484 m = re.compile(regex)
1484 m = re.compile(regex)
1485 except TypeError as e:
1485 except TypeError as e:
1486 raise TypeError('regex must be a string or compiled pattern') from e
1486 raise TypeError('regex must be a string or compiled pattern') from e
1487 # Search for keys in each namespace that match the given regex
1487 # Search for keys in each namespace that match the given regex
1488 # If a match is found, delete the key/value pair.
1488 # If a match is found, delete the key/value pair.
1489 for ns in self.all_ns_refs:
1489 for ns in self.all_ns_refs:
1490 for var in ns:
1490 for var in ns:
1491 if m.search(var):
1491 if m.search(var):
1492 del ns[var]
1492 del ns[var]
1493
1493
1494 def push(self, variables, interactive=True):
1494 def push(self, variables, interactive=True):
1495 """Inject a group of variables into the IPython user namespace.
1495 """Inject a group of variables into the IPython user namespace.
1496
1496
1497 Parameters
1497 Parameters
1498 ----------
1498 ----------
1499 variables : dict, str or list/tuple of str
1499 variables : dict, str or list/tuple of str
1500 The variables to inject into the user's namespace. If a dict, a
1500 The variables to inject into the user's namespace. If a dict, a
1501 simple update is done. If a str, the string is assumed to have
1501 simple update is done. If a str, the string is assumed to have
1502 variable names separated by spaces. A list/tuple of str can also
1502 variable names separated by spaces. A list/tuple of str can also
1503 be used to give the variable names. If just the variable names are
1503 be used to give the variable names. If just the variable names are
1504 give (list/tuple/str) then the variable values looked up in the
1504 give (list/tuple/str) then the variable values looked up in the
1505 callers frame.
1505 callers frame.
1506 interactive : bool
1506 interactive : bool
1507 If True (default), the variables will be listed with the ``who``
1507 If True (default), the variables will be listed with the ``who``
1508 magic.
1508 magic.
1509 """
1509 """
1510 vdict = None
1510 vdict = None
1511
1511
1512 # We need a dict of name/value pairs to do namespace updates.
1512 # We need a dict of name/value pairs to do namespace updates.
1513 if isinstance(variables, dict):
1513 if isinstance(variables, dict):
1514 vdict = variables
1514 vdict = variables
1515 elif isinstance(variables, (str, list, tuple)):
1515 elif isinstance(variables, (str, list, tuple)):
1516 if isinstance(variables, str):
1516 if isinstance(variables, str):
1517 vlist = variables.split()
1517 vlist = variables.split()
1518 else:
1518 else:
1519 vlist = variables
1519 vlist = variables
1520 vdict = {}
1520 vdict = {}
1521 cf = sys._getframe(1)
1521 cf = sys._getframe(1)
1522 for name in vlist:
1522 for name in vlist:
1523 try:
1523 try:
1524 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1524 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1525 except:
1525 except:
1526 print('Could not get variable %s from %s' %
1526 print('Could not get variable %s from %s' %
1527 (name,cf.f_code.co_name))
1527 (name,cf.f_code.co_name))
1528 else:
1528 else:
1529 raise ValueError('variables must be a dict/str/list/tuple')
1529 raise ValueError('variables must be a dict/str/list/tuple')
1530
1530
1531 # Propagate variables to user namespace
1531 # Propagate variables to user namespace
1532 self.user_ns.update(vdict)
1532 self.user_ns.update(vdict)
1533
1533
1534 # And configure interactive visibility
1534 # And configure interactive visibility
1535 user_ns_hidden = self.user_ns_hidden
1535 user_ns_hidden = self.user_ns_hidden
1536 if interactive:
1536 if interactive:
1537 for name in vdict:
1537 for name in vdict:
1538 user_ns_hidden.pop(name, None)
1538 user_ns_hidden.pop(name, None)
1539 else:
1539 else:
1540 user_ns_hidden.update(vdict)
1540 user_ns_hidden.update(vdict)
1541
1541
1542 def drop_by_id(self, variables):
1542 def drop_by_id(self, variables):
1543 """Remove a dict of variables from the user namespace, if they are the
1543 """Remove a dict of variables from the user namespace, if they are the
1544 same as the values in the dictionary.
1544 same as the values in the dictionary.
1545
1545
1546 This is intended for use by extensions: variables that they've added can
1546 This is intended for use by extensions: variables that they've added can
1547 be taken back out if they are unloaded, without removing any that the
1547 be taken back out if they are unloaded, without removing any that the
1548 user has overwritten.
1548 user has overwritten.
1549
1549
1550 Parameters
1550 Parameters
1551 ----------
1551 ----------
1552 variables : dict
1552 variables : dict
1553 A dictionary mapping object names (as strings) to the objects.
1553 A dictionary mapping object names (as strings) to the objects.
1554 """
1554 """
1555 for name, obj in variables.items():
1555 for name, obj in variables.items():
1556 if name in self.user_ns and self.user_ns[name] is obj:
1556 if name in self.user_ns and self.user_ns[name] is obj:
1557 del self.user_ns[name]
1557 del self.user_ns[name]
1558 self.user_ns_hidden.pop(name, None)
1558 self.user_ns_hidden.pop(name, None)
1559
1559
1560 #-------------------------------------------------------------------------
1560 #-------------------------------------------------------------------------
1561 # Things related to object introspection
1561 # Things related to object introspection
1562 #-------------------------------------------------------------------------
1562 #-------------------------------------------------------------------------
1563
1563
1564 def _ofind(self, oname, namespaces=None):
1564 def _ofind(self, oname, namespaces=None):
1565 """Find an object in the available namespaces.
1565 """Find an object in the available namespaces.
1566
1566
1567 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1567 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1568
1568
1569 Has special code to detect magic functions.
1569 Has special code to detect magic functions.
1570 """
1570 """
1571 oname = oname.strip()
1571 oname = oname.strip()
1572 raw_parts = oname.split(".")
1572 raw_parts = oname.split(".")
1573 parts = []
1573 parts = []
1574 parts_ok = True
1574 parts_ok = True
1575 for p in raw_parts:
1575 for p in raw_parts:
1576 if p.endswith("]"):
1576 if p.endswith("]"):
1577 var, *indices = p.split("[")
1577 var, *indices = p.split("[")
1578 if not var.isidentifier():
1578 if not var.isidentifier():
1579 parts_ok = False
1579 parts_ok = False
1580 break
1580 break
1581 parts.append(var)
1581 parts.append(var)
1582 for ind in indices:
1582 for ind in indices:
1583 if ind[-1] != "]" and not is_integer_string(ind[:-1]):
1583 if ind[-1] != "]" and not is_integer_string(ind[:-1]):
1584 parts_ok = False
1584 parts_ok = False
1585 break
1585 break
1586 parts.append(ind[:-1])
1586 parts.append(ind[:-1])
1587 continue
1587 continue
1588
1588
1589 if not p.isidentifier():
1589 if not p.isidentifier():
1590 parts_ok = False
1590 parts_ok = False
1591 parts.append(p)
1591 parts.append(p)
1592
1592
1593 if (
1593 if (
1594 not oname.startswith(ESC_MAGIC)
1594 not oname.startswith(ESC_MAGIC)
1595 and not oname.startswith(ESC_MAGIC2)
1595 and not oname.startswith(ESC_MAGIC2)
1596 and not parts_ok
1596 and not parts_ok
1597 ):
1597 ):
1598 return {"found": False}
1598 return {"found": False}
1599
1599
1600 if namespaces is None:
1600 if namespaces is None:
1601 # Namespaces to search in:
1601 # Namespaces to search in:
1602 # Put them in a list. The order is important so that we
1602 # Put them in a list. The order is important so that we
1603 # find things in the same order that Python finds them.
1603 # find things in the same order that Python finds them.
1604 namespaces = [ ('Interactive', self.user_ns),
1604 namespaces = [ ('Interactive', self.user_ns),
1605 ('Interactive (global)', self.user_global_ns),
1605 ('Interactive (global)', self.user_global_ns),
1606 ('Python builtin', builtin_mod.__dict__),
1606 ('Python builtin', builtin_mod.__dict__),
1607 ]
1607 ]
1608
1608
1609 ismagic = False
1609 ismagic = False
1610 isalias = False
1610 isalias = False
1611 found = False
1611 found = False
1612 ospace = None
1612 ospace = None
1613 parent = None
1613 parent = None
1614 obj = None
1614 obj = None
1615
1615
1616
1616
1617 # Look for the given name by splitting it in parts. If the head is
1617 # Look for the given name by splitting it in parts. If the head is
1618 # found, then we look for all the remaining parts as members, and only
1618 # found, then we look for all the remaining parts as members, and only
1619 # declare success if we can find them all.
1619 # declare success if we can find them all.
1620 oname_parts = parts
1620 oname_parts = parts
1621 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1621 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1622 for nsname,ns in namespaces:
1622 for nsname,ns in namespaces:
1623 try:
1623 try:
1624 obj = ns[oname_head]
1624 obj = ns[oname_head]
1625 except KeyError:
1625 except KeyError:
1626 continue
1626 continue
1627 else:
1627 else:
1628 for idx, part in enumerate(oname_rest):
1628 for idx, part in enumerate(oname_rest):
1629 try:
1629 try:
1630 parent = obj
1630 parent = obj
1631 # The last part is looked up in a special way to avoid
1631 # The last part is looked up in a special way to avoid
1632 # descriptor invocation as it may raise or have side
1632 # descriptor invocation as it may raise or have side
1633 # effects.
1633 # effects.
1634 if idx == len(oname_rest) - 1:
1634 if idx == len(oname_rest) - 1:
1635 obj = self._getattr_property(obj, part)
1635 obj = self._getattr_property(obj, part)
1636 else:
1636 else:
1637 if is_integer_string(part):
1637 if is_integer_string(part):
1638 obj = obj[int(part)]
1638 obj = obj[int(part)]
1639 else:
1639 else:
1640 obj = getattr(obj, part)
1640 obj = getattr(obj, part)
1641 except:
1641 except:
1642 # Blanket except b/c some badly implemented objects
1642 # Blanket except b/c some badly implemented objects
1643 # allow __getattr__ to raise exceptions other than
1643 # allow __getattr__ to raise exceptions other than
1644 # AttributeError, which then crashes IPython.
1644 # AttributeError, which then crashes IPython.
1645 break
1645 break
1646 else:
1646 else:
1647 # If we finish the for loop (no break), we got all members
1647 # If we finish the for loop (no break), we got all members
1648 found = True
1648 found = True
1649 ospace = nsname
1649 ospace = nsname
1650 break # namespace loop
1650 break # namespace loop
1651
1651
1652 # Try to see if it's magic
1652 # Try to see if it's magic
1653 if not found:
1653 if not found:
1654 obj = None
1654 obj = None
1655 if oname.startswith(ESC_MAGIC2):
1655 if oname.startswith(ESC_MAGIC2):
1656 oname = oname.lstrip(ESC_MAGIC2)
1656 oname = oname.lstrip(ESC_MAGIC2)
1657 obj = self.find_cell_magic(oname)
1657 obj = self.find_cell_magic(oname)
1658 elif oname.startswith(ESC_MAGIC):
1658 elif oname.startswith(ESC_MAGIC):
1659 oname = oname.lstrip(ESC_MAGIC)
1659 oname = oname.lstrip(ESC_MAGIC)
1660 obj = self.find_line_magic(oname)
1660 obj = self.find_line_magic(oname)
1661 else:
1661 else:
1662 # search without prefix, so run? will find %run?
1662 # search without prefix, so run? will find %run?
1663 obj = self.find_line_magic(oname)
1663 obj = self.find_line_magic(oname)
1664 if obj is None:
1664 if obj is None:
1665 obj = self.find_cell_magic(oname)
1665 obj = self.find_cell_magic(oname)
1666 if obj is not None:
1666 if obj is not None:
1667 found = True
1667 found = True
1668 ospace = 'IPython internal'
1668 ospace = 'IPython internal'
1669 ismagic = True
1669 ismagic = True
1670 isalias = isinstance(obj, Alias)
1670 isalias = isinstance(obj, Alias)
1671
1671
1672 # Last try: special-case some literals like '', [], {}, etc:
1672 # Last try: special-case some literals like '', [], {}, etc:
1673 if not found and oname_head in ["''",'""','[]','{}','()']:
1673 if not found and oname_head in ["''",'""','[]','{}','()']:
1674 obj = eval(oname_head)
1674 obj = eval(oname_head)
1675 found = True
1675 found = True
1676 ospace = 'Interactive'
1676 ospace = 'Interactive'
1677
1677
1678 return {
1678 return {
1679 'obj':obj,
1679 'obj':obj,
1680 'found':found,
1680 'found':found,
1681 'parent':parent,
1681 'parent':parent,
1682 'ismagic':ismagic,
1682 'ismagic':ismagic,
1683 'isalias':isalias,
1683 'isalias':isalias,
1684 'namespace':ospace
1684 'namespace':ospace
1685 }
1685 }
1686
1686
1687 @staticmethod
1687 @staticmethod
1688 def _getattr_property(obj, attrname):
1688 def _getattr_property(obj, attrname):
1689 """Property-aware getattr to use in object finding.
1689 """Property-aware getattr to use in object finding.
1690
1690
1691 If attrname represents a property, return it unevaluated (in case it has
1691 If attrname represents a property, return it unevaluated (in case it has
1692 side effects or raises an error.
1692 side effects or raises an error.
1693
1693
1694 """
1694 """
1695 if not isinstance(obj, type):
1695 if not isinstance(obj, type):
1696 try:
1696 try:
1697 # `getattr(type(obj), attrname)` is not guaranteed to return
1697 # `getattr(type(obj), attrname)` is not guaranteed to return
1698 # `obj`, but does so for property:
1698 # `obj`, but does so for property:
1699 #
1699 #
1700 # property.__get__(self, None, cls) -> self
1700 # property.__get__(self, None, cls) -> self
1701 #
1701 #
1702 # The universal alternative is to traverse the mro manually
1702 # The universal alternative is to traverse the mro manually
1703 # searching for attrname in class dicts.
1703 # searching for attrname in class dicts.
1704 if is_integer_string(attrname):
1704 if is_integer_string(attrname):
1705 return obj[int(attrname)]
1705 return obj[int(attrname)]
1706 else:
1706 else:
1707 attr = getattr(type(obj), attrname)
1707 attr = getattr(type(obj), attrname)
1708 except AttributeError:
1708 except AttributeError:
1709 pass
1709 pass
1710 else:
1710 else:
1711 # This relies on the fact that data descriptors (with both
1711 # This relies on the fact that data descriptors (with both
1712 # __get__ & __set__ magic methods) take precedence over
1712 # __get__ & __set__ magic methods) take precedence over
1713 # instance-level attributes:
1713 # instance-level attributes:
1714 #
1714 #
1715 # class A(object):
1715 # class A(object):
1716 # @property
1716 # @property
1717 # def foobar(self): return 123
1717 # def foobar(self): return 123
1718 # a = A()
1718 # a = A()
1719 # a.__dict__['foobar'] = 345
1719 # a.__dict__['foobar'] = 345
1720 # a.foobar # == 123
1720 # a.foobar # == 123
1721 #
1721 #
1722 # So, a property may be returned right away.
1722 # So, a property may be returned right away.
1723 if isinstance(attr, property):
1723 if isinstance(attr, property):
1724 return attr
1724 return attr
1725
1725
1726 # Nothing helped, fall back.
1726 # Nothing helped, fall back.
1727 return getattr(obj, attrname)
1727 return getattr(obj, attrname)
1728
1728
1729 def _object_find(self, oname, namespaces=None):
1729 def _object_find(self, oname, namespaces=None):
1730 """Find an object and return a struct with info about it."""
1730 """Find an object and return a struct with info about it."""
1731 return Struct(self._ofind(oname, namespaces))
1731 return Struct(self._ofind(oname, namespaces))
1732
1732
1733 def _inspect(self, meth, oname, namespaces=None, **kw):
1733 def _inspect(self, meth, oname, namespaces=None, **kw):
1734 """Generic interface to the inspector system.
1734 """Generic interface to the inspector system.
1735
1735
1736 This function is meant to be called by pdef, pdoc & friends.
1736 This function is meant to be called by pdef, pdoc & friends.
1737 """
1737 """
1738 info = self._object_find(oname, namespaces)
1738 info = self._object_find(oname, namespaces)
1739 docformat = (
1739 docformat = (
1740 sphinxify(self.object_inspect(oname)) if self.sphinxify_docstring else None
1740 sphinxify(self.object_inspect(oname)) if self.sphinxify_docstring else None
1741 )
1741 )
1742 if info.found:
1742 if info.found:
1743 pmethod = getattr(self.inspector, meth)
1743 pmethod = getattr(self.inspector, meth)
1744 # TODO: only apply format_screen to the plain/text repr of the mime
1744 # TODO: only apply format_screen to the plain/text repr of the mime
1745 # bundle.
1745 # bundle.
1746 formatter = format_screen if info.ismagic else docformat
1746 formatter = format_screen if info.ismagic else docformat
1747 if meth == 'pdoc':
1747 if meth == 'pdoc':
1748 pmethod(info.obj, oname, formatter)
1748 pmethod(info.obj, oname, formatter)
1749 elif meth == 'pinfo':
1749 elif meth == 'pinfo':
1750 pmethod(
1750 pmethod(
1751 info.obj,
1751 info.obj,
1752 oname,
1752 oname,
1753 formatter,
1753 formatter,
1754 info,
1754 info,
1755 enable_html_pager=self.enable_html_pager,
1755 enable_html_pager=self.enable_html_pager,
1756 **kw,
1756 **kw,
1757 )
1757 )
1758 else:
1758 else:
1759 pmethod(info.obj, oname)
1759 pmethod(info.obj, oname)
1760 else:
1760 else:
1761 print('Object `%s` not found.' % oname)
1761 print('Object `%s` not found.' % oname)
1762 return 'not found' # so callers can take other action
1762 return 'not found' # so callers can take other action
1763
1763
1764 def object_inspect(self, oname, detail_level=0):
1764 def object_inspect(self, oname, detail_level=0):
1765 """Get object info about oname"""
1765 """Get object info about oname"""
1766 with self.builtin_trap:
1766 with self.builtin_trap:
1767 info = self._object_find(oname)
1767 info = self._object_find(oname)
1768 if info.found:
1768 if info.found:
1769 return self.inspector.info(info.obj, oname, info=info,
1769 return self.inspector.info(info.obj, oname, info=info,
1770 detail_level=detail_level
1770 detail_level=detail_level
1771 )
1771 )
1772 else:
1772 else:
1773 return oinspect.object_info(name=oname, found=False)
1773 return oinspect.object_info(name=oname, found=False)
1774
1774
1775 def object_inspect_text(self, oname, detail_level=0):
1775 def object_inspect_text(self, oname, detail_level=0):
1776 """Get object info as formatted text"""
1776 """Get object info as formatted text"""
1777 return self.object_inspect_mime(oname, detail_level)['text/plain']
1777 return self.object_inspect_mime(oname, detail_level)['text/plain']
1778
1778
1779 def object_inspect_mime(self, oname, detail_level=0, omit_sections=()):
1779 def object_inspect_mime(self, oname, detail_level=0, omit_sections=()):
1780 """Get object info as a mimebundle of formatted representations.
1780 """Get object info as a mimebundle of formatted representations.
1781
1781
1782 A mimebundle is a dictionary, keyed by mime-type.
1782 A mimebundle is a dictionary, keyed by mime-type.
1783 It must always have the key `'text/plain'`.
1783 It must always have the key `'text/plain'`.
1784 """
1784 """
1785 with self.builtin_trap:
1785 with self.builtin_trap:
1786 info = self._object_find(oname)
1786 info = self._object_find(oname)
1787 if info.found:
1787 if info.found:
1788 docformat = (
1788 docformat = (
1789 sphinxify(self.object_inspect(oname))
1789 sphinxify(self.object_inspect(oname))
1790 if self.sphinxify_docstring
1790 if self.sphinxify_docstring
1791 else None
1791 else None
1792 )
1792 )
1793 return self.inspector._get_info(
1793 return self.inspector._get_info(
1794 info.obj,
1794 info.obj,
1795 oname,
1795 oname,
1796 info=info,
1796 info=info,
1797 detail_level=detail_level,
1797 detail_level=detail_level,
1798 formatter=docformat,
1798 formatter=docformat,
1799 omit_sections=omit_sections,
1799 omit_sections=omit_sections,
1800 )
1800 )
1801 else:
1801 else:
1802 raise KeyError(oname)
1802 raise KeyError(oname)
1803
1803
1804 #-------------------------------------------------------------------------
1804 #-------------------------------------------------------------------------
1805 # Things related to history management
1805 # Things related to history management
1806 #-------------------------------------------------------------------------
1806 #-------------------------------------------------------------------------
1807
1807
1808 def init_history(self):
1808 def init_history(self):
1809 """Sets up the command history, and starts regular autosaves."""
1809 """Sets up the command history, and starts regular autosaves."""
1810 self.history_manager = HistoryManager(shell=self, parent=self)
1810 self.history_manager = HistoryManager(shell=self, parent=self)
1811 self.configurables.append(self.history_manager)
1811 self.configurables.append(self.history_manager)
1812
1812
1813 #-------------------------------------------------------------------------
1813 #-------------------------------------------------------------------------
1814 # Things related to exception handling and tracebacks (not debugging)
1814 # Things related to exception handling and tracebacks (not debugging)
1815 #-------------------------------------------------------------------------
1815 #-------------------------------------------------------------------------
1816
1816
1817 debugger_cls = InterruptiblePdb
1817 debugger_cls = InterruptiblePdb
1818
1818
1819 def init_traceback_handlers(self, custom_exceptions):
1819 def init_traceback_handlers(self, custom_exceptions):
1820 # Syntax error handler.
1820 # Syntax error handler.
1821 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor', parent=self)
1821 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor', parent=self)
1822
1822
1823 # The interactive one is initialized with an offset, meaning we always
1823 # The interactive one is initialized with an offset, meaning we always
1824 # want to remove the topmost item in the traceback, which is our own
1824 # want to remove the topmost item in the traceback, which is our own
1825 # internal code. Valid modes: ['Plain','Context','Verbose','Minimal']
1825 # internal code. Valid modes: ['Plain','Context','Verbose','Minimal']
1826 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1826 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1827 color_scheme='NoColor',
1827 color_scheme='NoColor',
1828 tb_offset = 1,
1828 tb_offset = 1,
1829 debugger_cls=self.debugger_cls, parent=self)
1829 debugger_cls=self.debugger_cls, parent=self)
1830
1830
1831 # The instance will store a pointer to the system-wide exception hook,
1831 # The instance will store a pointer to the system-wide exception hook,
1832 # so that runtime code (such as magics) can access it. This is because
1832 # so that runtime code (such as magics) can access it. This is because
1833 # during the read-eval loop, it may get temporarily overwritten.
1833 # during the read-eval loop, it may get temporarily overwritten.
1834 self.sys_excepthook = sys.excepthook
1834 self.sys_excepthook = sys.excepthook
1835
1835
1836 # and add any custom exception handlers the user may have specified
1836 # and add any custom exception handlers the user may have specified
1837 self.set_custom_exc(*custom_exceptions)
1837 self.set_custom_exc(*custom_exceptions)
1838
1838
1839 # Set the exception mode
1839 # Set the exception mode
1840 self.InteractiveTB.set_mode(mode=self.xmode)
1840 self.InteractiveTB.set_mode(mode=self.xmode)
1841
1841
1842 def set_custom_exc(self, exc_tuple, handler):
1842 def set_custom_exc(self, exc_tuple, handler):
1843 """set_custom_exc(exc_tuple, handler)
1843 """set_custom_exc(exc_tuple, handler)
1844
1844
1845 Set a custom exception handler, which will be called if any of the
1845 Set a custom exception handler, which will be called if any of the
1846 exceptions in exc_tuple occur in the mainloop (specifically, in the
1846 exceptions in exc_tuple occur in the mainloop (specifically, in the
1847 run_code() method).
1847 run_code() method).
1848
1848
1849 Parameters
1849 Parameters
1850 ----------
1850 ----------
1851 exc_tuple : tuple of exception classes
1851 exc_tuple : tuple of exception classes
1852 A *tuple* of exception classes, for which to call the defined
1852 A *tuple* of exception classes, for which to call the defined
1853 handler. It is very important that you use a tuple, and NOT A
1853 handler. It is very important that you use a tuple, and NOT A
1854 LIST here, because of the way Python's except statement works. If
1854 LIST here, because of the way Python's except statement works. If
1855 you only want to trap a single exception, use a singleton tuple::
1855 you only want to trap a single exception, use a singleton tuple::
1856
1856
1857 exc_tuple == (MyCustomException,)
1857 exc_tuple == (MyCustomException,)
1858
1858
1859 handler : callable
1859 handler : callable
1860 handler must have the following signature::
1860 handler must have the following signature::
1861
1861
1862 def my_handler(self, etype, value, tb, tb_offset=None):
1862 def my_handler(self, etype, value, tb, tb_offset=None):
1863 ...
1863 ...
1864 return structured_traceback
1864 return structured_traceback
1865
1865
1866 Your handler must return a structured traceback (a list of strings),
1866 Your handler must return a structured traceback (a list of strings),
1867 or None.
1867 or None.
1868
1868
1869 This will be made into an instance method (via types.MethodType)
1869 This will be made into an instance method (via types.MethodType)
1870 of IPython itself, and it will be called if any of the exceptions
1870 of IPython itself, and it will be called if any of the exceptions
1871 listed in the exc_tuple are caught. If the handler is None, an
1871 listed in the exc_tuple are caught. If the handler is None, an
1872 internal basic one is used, which just prints basic info.
1872 internal basic one is used, which just prints basic info.
1873
1873
1874 To protect IPython from crashes, if your handler ever raises an
1874 To protect IPython from crashes, if your handler ever raises an
1875 exception or returns an invalid result, it will be immediately
1875 exception or returns an invalid result, it will be immediately
1876 disabled.
1876 disabled.
1877
1877
1878 Notes
1878 Notes
1879 -----
1879 -----
1880 WARNING: by putting in your own exception handler into IPython's main
1880 WARNING: by putting in your own exception handler into IPython's main
1881 execution loop, you run a very good chance of nasty crashes. This
1881 execution loop, you run a very good chance of nasty crashes. This
1882 facility should only be used if you really know what you are doing.
1882 facility should only be used if you really know what you are doing.
1883 """
1883 """
1884
1884
1885 if not isinstance(exc_tuple, tuple):
1885 if not isinstance(exc_tuple, tuple):
1886 raise TypeError("The custom exceptions must be given as a tuple.")
1886 raise TypeError("The custom exceptions must be given as a tuple.")
1887
1887
1888 def dummy_handler(self, etype, value, tb, tb_offset=None):
1888 def dummy_handler(self, etype, value, tb, tb_offset=None):
1889 print('*** Simple custom exception handler ***')
1889 print('*** Simple custom exception handler ***')
1890 print('Exception type :', etype)
1890 print('Exception type :', etype)
1891 print('Exception value:', value)
1891 print('Exception value:', value)
1892 print('Traceback :', tb)
1892 print('Traceback :', tb)
1893
1893
1894 def validate_stb(stb):
1894 def validate_stb(stb):
1895 """validate structured traceback return type
1895 """validate structured traceback return type
1896
1896
1897 return type of CustomTB *should* be a list of strings, but allow
1897 return type of CustomTB *should* be a list of strings, but allow
1898 single strings or None, which are harmless.
1898 single strings or None, which are harmless.
1899
1899
1900 This function will *always* return a list of strings,
1900 This function will *always* return a list of strings,
1901 and will raise a TypeError if stb is inappropriate.
1901 and will raise a TypeError if stb is inappropriate.
1902 """
1902 """
1903 msg = "CustomTB must return list of strings, not %r" % stb
1903 msg = "CustomTB must return list of strings, not %r" % stb
1904 if stb is None:
1904 if stb is None:
1905 return []
1905 return []
1906 elif isinstance(stb, str):
1906 elif isinstance(stb, str):
1907 return [stb]
1907 return [stb]
1908 elif not isinstance(stb, list):
1908 elif not isinstance(stb, list):
1909 raise TypeError(msg)
1909 raise TypeError(msg)
1910 # it's a list
1910 # it's a list
1911 for line in stb:
1911 for line in stb:
1912 # check every element
1912 # check every element
1913 if not isinstance(line, str):
1913 if not isinstance(line, str):
1914 raise TypeError(msg)
1914 raise TypeError(msg)
1915 return stb
1915 return stb
1916
1916
1917 if handler is None:
1917 if handler is None:
1918 wrapped = dummy_handler
1918 wrapped = dummy_handler
1919 else:
1919 else:
1920 def wrapped(self,etype,value,tb,tb_offset=None):
1920 def wrapped(self,etype,value,tb,tb_offset=None):
1921 """wrap CustomTB handler, to protect IPython from user code
1921 """wrap CustomTB handler, to protect IPython from user code
1922
1922
1923 This makes it harder (but not impossible) for custom exception
1923 This makes it harder (but not impossible) for custom exception
1924 handlers to crash IPython.
1924 handlers to crash IPython.
1925 """
1925 """
1926 try:
1926 try:
1927 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1927 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1928 return validate_stb(stb)
1928 return validate_stb(stb)
1929 except:
1929 except:
1930 # clear custom handler immediately
1930 # clear custom handler immediately
1931 self.set_custom_exc((), None)
1931 self.set_custom_exc((), None)
1932 print("Custom TB Handler failed, unregistering", file=sys.stderr)
1932 print("Custom TB Handler failed, unregistering", file=sys.stderr)
1933 # show the exception in handler first
1933 # show the exception in handler first
1934 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1934 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1935 print(self.InteractiveTB.stb2text(stb))
1935 print(self.InteractiveTB.stb2text(stb))
1936 print("The original exception:")
1936 print("The original exception:")
1937 stb = self.InteractiveTB.structured_traceback(
1937 stb = self.InteractiveTB.structured_traceback(
1938 (etype,value,tb), tb_offset=tb_offset
1938 (etype,value,tb), tb_offset=tb_offset
1939 )
1939 )
1940 return stb
1940 return stb
1941
1941
1942 self.CustomTB = types.MethodType(wrapped,self)
1942 self.CustomTB = types.MethodType(wrapped,self)
1943 self.custom_exceptions = exc_tuple
1943 self.custom_exceptions = exc_tuple
1944
1944
1945 def excepthook(self, etype, value, tb):
1945 def excepthook(self, etype, value, tb):
1946 """One more defense for GUI apps that call sys.excepthook.
1946 """One more defense for GUI apps that call sys.excepthook.
1947
1947
1948 GUI frameworks like wxPython trap exceptions and call
1948 GUI frameworks like wxPython trap exceptions and call
1949 sys.excepthook themselves. I guess this is a feature that
1949 sys.excepthook themselves. I guess this is a feature that
1950 enables them to keep running after exceptions that would
1950 enables them to keep running after exceptions that would
1951 otherwise kill their mainloop. This is a bother for IPython
1951 otherwise kill their mainloop. This is a bother for IPython
1952 which expects to catch all of the program exceptions with a try:
1952 which expects to catch all of the program exceptions with a try:
1953 except: statement.
1953 except: statement.
1954
1954
1955 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1955 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1956 any app directly invokes sys.excepthook, it will look to the user like
1956 any app directly invokes sys.excepthook, it will look to the user like
1957 IPython crashed. In order to work around this, we can disable the
1957 IPython crashed. In order to work around this, we can disable the
1958 CrashHandler and replace it with this excepthook instead, which prints a
1958 CrashHandler and replace it with this excepthook instead, which prints a
1959 regular traceback using our InteractiveTB. In this fashion, apps which
1959 regular traceback using our InteractiveTB. In this fashion, apps which
1960 call sys.excepthook will generate a regular-looking exception from
1960 call sys.excepthook will generate a regular-looking exception from
1961 IPython, and the CrashHandler will only be triggered by real IPython
1961 IPython, and the CrashHandler will only be triggered by real IPython
1962 crashes.
1962 crashes.
1963
1963
1964 This hook should be used sparingly, only in places which are not likely
1964 This hook should be used sparingly, only in places which are not likely
1965 to be true IPython errors.
1965 to be true IPython errors.
1966 """
1966 """
1967 self.showtraceback((etype, value, tb), tb_offset=0)
1967 self.showtraceback((etype, value, tb), tb_offset=0)
1968
1968
1969 def _get_exc_info(self, exc_tuple=None):
1969 def _get_exc_info(self, exc_tuple=None):
1970 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1970 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1971
1971
1972 Ensures sys.last_type,value,traceback hold the exc_info we found,
1972 Ensures sys.last_type,value,traceback hold the exc_info we found,
1973 from whichever source.
1973 from whichever source.
1974
1974
1975 raises ValueError if none of these contain any information
1975 raises ValueError if none of these contain any information
1976 """
1976 """
1977 if exc_tuple is None:
1977 if exc_tuple is None:
1978 etype, value, tb = sys.exc_info()
1978 etype, value, tb = sys.exc_info()
1979 else:
1979 else:
1980 etype, value, tb = exc_tuple
1980 etype, value, tb = exc_tuple
1981
1981
1982 if etype is None:
1982 if etype is None:
1983 if hasattr(sys, 'last_type'):
1983 if hasattr(sys, 'last_type'):
1984 etype, value, tb = sys.last_type, sys.last_value, \
1984 etype, value, tb = sys.last_type, sys.last_value, \
1985 sys.last_traceback
1985 sys.last_traceback
1986
1986
1987 if etype is None:
1987 if etype is None:
1988 raise ValueError("No exception to find")
1988 raise ValueError("No exception to find")
1989
1989
1990 # Now store the exception info in sys.last_type etc.
1990 # Now store the exception info in sys.last_type etc.
1991 # WARNING: these variables are somewhat deprecated and not
1991 # WARNING: these variables are somewhat deprecated and not
1992 # necessarily safe to use in a threaded environment, but tools
1992 # necessarily safe to use in a threaded environment, but tools
1993 # like pdb depend on their existence, so let's set them. If we
1993 # like pdb depend on their existence, so let's set them. If we
1994 # find problems in the field, we'll need to revisit their use.
1994 # find problems in the field, we'll need to revisit their use.
1995 sys.last_type = etype
1995 sys.last_type = etype
1996 sys.last_value = value
1996 sys.last_value = value
1997 sys.last_traceback = tb
1997 sys.last_traceback = tb
1998
1998
1999 return etype, value, tb
1999 return etype, value, tb
2000
2000
2001 def show_usage_error(self, exc):
2001 def show_usage_error(self, exc):
2002 """Show a short message for UsageErrors
2002 """Show a short message for UsageErrors
2003
2003
2004 These are special exceptions that shouldn't show a traceback.
2004 These are special exceptions that shouldn't show a traceback.
2005 """
2005 """
2006 print("UsageError: %s" % exc, file=sys.stderr)
2006 print("UsageError: %s" % exc, file=sys.stderr)
2007
2007
2008 def get_exception_only(self, exc_tuple=None):
2008 def get_exception_only(self, exc_tuple=None):
2009 """
2009 """
2010 Return as a string (ending with a newline) the exception that
2010 Return as a string (ending with a newline) the exception that
2011 just occurred, without any traceback.
2011 just occurred, without any traceback.
2012 """
2012 """
2013 etype, value, tb = self._get_exc_info(exc_tuple)
2013 etype, value, tb = self._get_exc_info(exc_tuple)
2014 msg = traceback.format_exception_only(etype, value)
2014 msg = traceback.format_exception_only(etype, value)
2015 return ''.join(msg)
2015 return ''.join(msg)
2016
2016
2017 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
2017 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
2018 exception_only=False, running_compiled_code=False):
2018 exception_only=False, running_compiled_code=False):
2019 """Display the exception that just occurred.
2019 """Display the exception that just occurred.
2020
2020
2021 If nothing is known about the exception, this is the method which
2021 If nothing is known about the exception, this is the method which
2022 should be used throughout the code for presenting user tracebacks,
2022 should be used throughout the code for presenting user tracebacks,
2023 rather than directly invoking the InteractiveTB object.
2023 rather than directly invoking the InteractiveTB object.
2024
2024
2025 A specific showsyntaxerror() also exists, but this method can take
2025 A specific showsyntaxerror() also exists, but this method can take
2026 care of calling it if needed, so unless you are explicitly catching a
2026 care of calling it if needed, so unless you are explicitly catching a
2027 SyntaxError exception, don't try to analyze the stack manually and
2027 SyntaxError exception, don't try to analyze the stack manually and
2028 simply call this method."""
2028 simply call this method."""
2029
2029
2030 try:
2030 try:
2031 try:
2031 try:
2032 etype, value, tb = self._get_exc_info(exc_tuple)
2032 etype, value, tb = self._get_exc_info(exc_tuple)
2033 except ValueError:
2033 except ValueError:
2034 print('No traceback available to show.', file=sys.stderr)
2034 print('No traceback available to show.', file=sys.stderr)
2035 return
2035 return
2036
2036
2037 if issubclass(etype, SyntaxError):
2037 if issubclass(etype, SyntaxError):
2038 # Though this won't be called by syntax errors in the input
2038 # Though this won't be called by syntax errors in the input
2039 # line, there may be SyntaxError cases with imported code.
2039 # line, there may be SyntaxError cases with imported code.
2040 self.showsyntaxerror(filename, running_compiled_code)
2040 self.showsyntaxerror(filename, running_compiled_code)
2041 elif etype is UsageError:
2041 elif etype is UsageError:
2042 self.show_usage_error(value)
2042 self.show_usage_error(value)
2043 else:
2043 else:
2044 if exception_only:
2044 if exception_only:
2045 stb = ['An exception has occurred, use %tb to see '
2045 stb = ['An exception has occurred, use %tb to see '
2046 'the full traceback.\n']
2046 'the full traceback.\n']
2047 stb.extend(self.InteractiveTB.get_exception_only(etype,
2047 stb.extend(self.InteractiveTB.get_exception_only(etype,
2048 value))
2048 value))
2049 else:
2049 else:
2050 try:
2050 try:
2051 # Exception classes can customise their traceback - we
2051 # Exception classes can customise their traceback - we
2052 # use this in IPython.parallel for exceptions occurring
2052 # use this in IPython.parallel for exceptions occurring
2053 # in the engines. This should return a list of strings.
2053 # in the engines. This should return a list of strings.
2054 if hasattr(value, "_render_traceback_"):
2054 if hasattr(value, "_render_traceback_"):
2055 stb = value._render_traceback_()
2055 stb = value._render_traceback_()
2056 else:
2056 else:
2057 stb = self.InteractiveTB.structured_traceback(
2057 stb = self.InteractiveTB.structured_traceback(
2058 etype, value, tb, tb_offset=tb_offset
2058 etype, value, tb, tb_offset=tb_offset
2059 )
2059 )
2060
2060
2061 except Exception:
2061 except Exception:
2062 print(
2062 print(
2063 "Unexpected exception formatting exception. Falling back to standard exception"
2063 "Unexpected exception formatting exception. Falling back to standard exception"
2064 )
2064 )
2065 traceback.print_exc()
2065 traceback.print_exc()
2066 return None
2066 return None
2067
2067
2068 self._showtraceback(etype, value, stb)
2068 self._showtraceback(etype, value, stb)
2069 if self.call_pdb:
2069 if self.call_pdb:
2070 # drop into debugger
2070 # drop into debugger
2071 self.debugger(force=True)
2071 self.debugger(force=True)
2072 return
2072 return
2073
2073
2074 # Actually show the traceback
2074 # Actually show the traceback
2075 self._showtraceback(etype, value, stb)
2075 self._showtraceback(etype, value, stb)
2076
2076
2077 except KeyboardInterrupt:
2077 except KeyboardInterrupt:
2078 print('\n' + self.get_exception_only(), file=sys.stderr)
2078 print('\n' + self.get_exception_only(), file=sys.stderr)
2079
2079
2080 def _showtraceback(self, etype, evalue, stb: str):
2080 def _showtraceback(self, etype, evalue, stb: str):
2081 """Actually show a traceback.
2081 """Actually show a traceback.
2082
2082
2083 Subclasses may override this method to put the traceback on a different
2083 Subclasses may override this method to put the traceback on a different
2084 place, like a side channel.
2084 place, like a side channel.
2085 """
2085 """
2086 val = self.InteractiveTB.stb2text(stb)
2086 val = self.InteractiveTB.stb2text(stb)
2087 try:
2087 try:
2088 print(val)
2088 print(val)
2089 except UnicodeEncodeError:
2089 except UnicodeEncodeError:
2090 print(val.encode("utf-8", "backslashreplace").decode())
2090 print(val.encode("utf-8", "backslashreplace").decode())
2091
2091
2092 def showsyntaxerror(self, filename=None, running_compiled_code=False):
2092 def showsyntaxerror(self, filename=None, running_compiled_code=False):
2093 """Display the syntax error that just occurred.
2093 """Display the syntax error that just occurred.
2094
2094
2095 This doesn't display a stack trace because there isn't one.
2095 This doesn't display a stack trace because there isn't one.
2096
2096
2097 If a filename is given, it is stuffed in the exception instead
2097 If a filename is given, it is stuffed in the exception instead
2098 of what was there before (because Python's parser always uses
2098 of what was there before (because Python's parser always uses
2099 "<string>" when reading from a string).
2099 "<string>" when reading from a string).
2100
2100
2101 If the syntax error occurred when running a compiled code (i.e. running_compile_code=True),
2101 If the syntax error occurred when running a compiled code (i.e. running_compile_code=True),
2102 longer stack trace will be displayed.
2102 longer stack trace will be displayed.
2103 """
2103 """
2104 etype, value, last_traceback = self._get_exc_info()
2104 etype, value, last_traceback = self._get_exc_info()
2105
2105
2106 if filename and issubclass(etype, SyntaxError):
2106 if filename and issubclass(etype, SyntaxError):
2107 try:
2107 try:
2108 value.filename = filename
2108 value.filename = filename
2109 except:
2109 except:
2110 # Not the format we expect; leave it alone
2110 # Not the format we expect; leave it alone
2111 pass
2111 pass
2112
2112
2113 # If the error occurred when executing compiled code, we should provide full stacktrace.
2113 # If the error occurred when executing compiled code, we should provide full stacktrace.
2114 elist = traceback.extract_tb(last_traceback) if running_compiled_code else []
2114 elist = traceback.extract_tb(last_traceback) if running_compiled_code else []
2115 stb = self.SyntaxTB.structured_traceback(etype, value, elist)
2115 stb = self.SyntaxTB.structured_traceback(etype, value, elist)
2116 self._showtraceback(etype, value, stb)
2116 self._showtraceback(etype, value, stb)
2117
2117
2118 # This is overridden in TerminalInteractiveShell to show a message about
2118 # This is overridden in TerminalInteractiveShell to show a message about
2119 # the %paste magic.
2119 # the %paste magic.
2120 def showindentationerror(self):
2120 def showindentationerror(self):
2121 """Called by _run_cell when there's an IndentationError in code entered
2121 """Called by _run_cell when there's an IndentationError in code entered
2122 at the prompt.
2122 at the prompt.
2123
2123
2124 This is overridden in TerminalInteractiveShell to show a message about
2124 This is overridden in TerminalInteractiveShell to show a message about
2125 the %paste magic."""
2125 the %paste magic."""
2126 self.showsyntaxerror()
2126 self.showsyntaxerror()
2127
2127
2128 @skip_doctest
2128 @skip_doctest
2129 def set_next_input(self, s, replace=False):
2129 def set_next_input(self, s, replace=False):
2130 """ Sets the 'default' input string for the next command line.
2130 """ Sets the 'default' input string for the next command line.
2131
2131
2132 Example::
2132 Example::
2133
2133
2134 In [1]: _ip.set_next_input("Hello Word")
2134 In [1]: _ip.set_next_input("Hello Word")
2135 In [2]: Hello Word_ # cursor is here
2135 In [2]: Hello Word_ # cursor is here
2136 """
2136 """
2137 self.rl_next_input = s
2137 self.rl_next_input = s
2138
2138
2139 def _indent_current_str(self):
2139 def _indent_current_str(self):
2140 """return the current level of indentation as a string"""
2140 """return the current level of indentation as a string"""
2141 return self.input_splitter.get_indent_spaces() * ' '
2141 return self.input_splitter.get_indent_spaces() * ' '
2142
2142
2143 #-------------------------------------------------------------------------
2143 #-------------------------------------------------------------------------
2144 # Things related to text completion
2144 # Things related to text completion
2145 #-------------------------------------------------------------------------
2145 #-------------------------------------------------------------------------
2146
2146
2147 def init_completer(self):
2147 def init_completer(self):
2148 """Initialize the completion machinery.
2148 """Initialize the completion machinery.
2149
2149
2150 This creates completion machinery that can be used by client code,
2150 This creates completion machinery that can be used by client code,
2151 either interactively in-process (typically triggered by the readline
2151 either interactively in-process (typically triggered by the readline
2152 library), programmatically (such as in test suites) or out-of-process
2152 library), programmatically (such as in test suites) or out-of-process
2153 (typically over the network by remote frontends).
2153 (typically over the network by remote frontends).
2154 """
2154 """
2155 from IPython.core.completer import IPCompleter
2155 from IPython.core.completer import IPCompleter
2156 from IPython.core.completerlib import (
2156 from IPython.core.completerlib import (
2157 cd_completer,
2157 cd_completer,
2158 magic_run_completer,
2158 magic_run_completer,
2159 module_completer,
2159 module_completer,
2160 reset_completer,
2160 reset_completer,
2161 )
2161 )
2162
2162
2163 self.Completer = IPCompleter(shell=self,
2163 self.Completer = IPCompleter(shell=self,
2164 namespace=self.user_ns,
2164 namespace=self.user_ns,
2165 global_namespace=self.user_global_ns,
2165 global_namespace=self.user_global_ns,
2166 parent=self,
2166 parent=self,
2167 )
2167 )
2168 self.configurables.append(self.Completer)
2168 self.configurables.append(self.Completer)
2169
2169
2170 # Add custom completers to the basic ones built into IPCompleter
2170 # Add custom completers to the basic ones built into IPCompleter
2171 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2171 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2172 self.strdispatchers['complete_command'] = sdisp
2172 self.strdispatchers['complete_command'] = sdisp
2173 self.Completer.custom_completers = sdisp
2173 self.Completer.custom_completers = sdisp
2174
2174
2175 self.set_hook('complete_command', module_completer, str_key = 'import')
2175 self.set_hook('complete_command', module_completer, str_key = 'import')
2176 self.set_hook('complete_command', module_completer, str_key = 'from')
2176 self.set_hook('complete_command', module_completer, str_key = 'from')
2177 self.set_hook('complete_command', module_completer, str_key = '%aimport')
2177 self.set_hook('complete_command', module_completer, str_key = '%aimport')
2178 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2178 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2179 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2179 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2180 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2180 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2181
2181
2182 @skip_doctest
2182 @skip_doctest
2183 def complete(self, text, line=None, cursor_pos=None):
2183 def complete(self, text, line=None, cursor_pos=None):
2184 """Return the completed text and a list of completions.
2184 """Return the completed text and a list of completions.
2185
2185
2186 Parameters
2186 Parameters
2187 ----------
2187 ----------
2188 text : string
2188 text : string
2189 A string of text to be completed on. It can be given as empty and
2189 A string of text to be completed on. It can be given as empty and
2190 instead a line/position pair are given. In this case, the
2190 instead a line/position pair are given. In this case, the
2191 completer itself will split the line like readline does.
2191 completer itself will split the line like readline does.
2192 line : string, optional
2192 line : string, optional
2193 The complete line that text is part of.
2193 The complete line that text is part of.
2194 cursor_pos : int, optional
2194 cursor_pos : int, optional
2195 The position of the cursor on the input line.
2195 The position of the cursor on the input line.
2196
2196
2197 Returns
2197 Returns
2198 -------
2198 -------
2199 text : string
2199 text : string
2200 The actual text that was completed.
2200 The actual text that was completed.
2201 matches : list
2201 matches : list
2202 A sorted list with all possible completions.
2202 A sorted list with all possible completions.
2203
2203
2204 Notes
2204 Notes
2205 -----
2205 -----
2206 The optional arguments allow the completion to take more context into
2206 The optional arguments allow the completion to take more context into
2207 account, and are part of the low-level completion API.
2207 account, and are part of the low-level completion API.
2208
2208
2209 This is a wrapper around the completion mechanism, similar to what
2209 This is a wrapper around the completion mechanism, similar to what
2210 readline does at the command line when the TAB key is hit. By
2210 readline does at the command line when the TAB key is hit. By
2211 exposing it as a method, it can be used by other non-readline
2211 exposing it as a method, it can be used by other non-readline
2212 environments (such as GUIs) for text completion.
2212 environments (such as GUIs) for text completion.
2213
2213
2214 Examples
2214 Examples
2215 --------
2215 --------
2216 In [1]: x = 'hello'
2216 In [1]: x = 'hello'
2217
2217
2218 In [2]: _ip.complete('x.l')
2218 In [2]: _ip.complete('x.l')
2219 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2219 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2220 """
2220 """
2221
2221
2222 # Inject names into __builtin__ so we can complete on the added names.
2222 # Inject names into __builtin__ so we can complete on the added names.
2223 with self.builtin_trap:
2223 with self.builtin_trap:
2224 return self.Completer.complete(text, line, cursor_pos)
2224 return self.Completer.complete(text, line, cursor_pos)
2225
2225
2226 def set_custom_completer(self, completer, pos=0) -> None:
2226 def set_custom_completer(self, completer, pos=0) -> None:
2227 """Adds a new custom completer function.
2227 """Adds a new custom completer function.
2228
2228
2229 The position argument (defaults to 0) is the index in the completers
2229 The position argument (defaults to 0) is the index in the completers
2230 list where you want the completer to be inserted.
2230 list where you want the completer to be inserted.
2231
2231
2232 `completer` should have the following signature::
2232 `completer` should have the following signature::
2233
2233
2234 def completion(self: Completer, text: string) -> List[str]:
2234 def completion(self: Completer, text: string) -> List[str]:
2235 raise NotImplementedError
2235 raise NotImplementedError
2236
2236
2237 It will be bound to the current Completer instance and pass some text
2237 It will be bound to the current Completer instance and pass some text
2238 and return a list with current completions to suggest to the user.
2238 and return a list with current completions to suggest to the user.
2239 """
2239 """
2240
2240
2241 newcomp = types.MethodType(completer, self.Completer)
2241 newcomp = types.MethodType(completer, self.Completer)
2242 self.Completer.custom_matchers.insert(pos,newcomp)
2242 self.Completer.custom_matchers.insert(pos,newcomp)
2243
2243
2244 def set_completer_frame(self, frame=None):
2244 def set_completer_frame(self, frame=None):
2245 """Set the frame of the completer."""
2245 """Set the frame of the completer."""
2246 if frame:
2246 if frame:
2247 self.Completer.namespace = frame.f_locals
2247 self.Completer.namespace = frame.f_locals
2248 self.Completer.global_namespace = frame.f_globals
2248 self.Completer.global_namespace = frame.f_globals
2249 else:
2249 else:
2250 self.Completer.namespace = self.user_ns
2250 self.Completer.namespace = self.user_ns
2251 self.Completer.global_namespace = self.user_global_ns
2251 self.Completer.global_namespace = self.user_global_ns
2252
2252
2253 #-------------------------------------------------------------------------
2253 #-------------------------------------------------------------------------
2254 # Things related to magics
2254 # Things related to magics
2255 #-------------------------------------------------------------------------
2255 #-------------------------------------------------------------------------
2256
2256
2257 def init_magics(self):
2257 def init_magics(self):
2258 from IPython.core import magics as m
2258 from IPython.core import magics as m
2259 self.magics_manager = magic.MagicsManager(shell=self,
2259 self.magics_manager = magic.MagicsManager(shell=self,
2260 parent=self,
2260 parent=self,
2261 user_magics=m.UserMagics(self))
2261 user_magics=m.UserMagics(self))
2262 self.configurables.append(self.magics_manager)
2262 self.configurables.append(self.magics_manager)
2263
2263
2264 # Expose as public API from the magics manager
2264 # Expose as public API from the magics manager
2265 self.register_magics = self.magics_manager.register
2265 self.register_magics = self.magics_manager.register
2266
2266
2267 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2267 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2268 m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics,
2268 m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics,
2269 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2269 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2270 m.NamespaceMagics, m.OSMagics, m.PackagingMagics,
2270 m.NamespaceMagics, m.OSMagics, m.PackagingMagics,
2271 m.PylabMagics, m.ScriptMagics,
2271 m.PylabMagics, m.ScriptMagics,
2272 )
2272 )
2273 self.register_magics(m.AsyncMagics)
2273 self.register_magics(m.AsyncMagics)
2274
2274
2275 # Register Magic Aliases
2275 # Register Magic Aliases
2276 mman = self.magics_manager
2276 mman = self.magics_manager
2277 # FIXME: magic aliases should be defined by the Magics classes
2277 # FIXME: magic aliases should be defined by the Magics classes
2278 # or in MagicsManager, not here
2278 # or in MagicsManager, not here
2279 mman.register_alias('ed', 'edit')
2279 mman.register_alias('ed', 'edit')
2280 mman.register_alias('hist', 'history')
2280 mman.register_alias('hist', 'history')
2281 mman.register_alias('rep', 'recall')
2281 mman.register_alias('rep', 'recall')
2282 mman.register_alias('SVG', 'svg', 'cell')
2282 mman.register_alias('SVG', 'svg', 'cell')
2283 mman.register_alias('HTML', 'html', 'cell')
2283 mman.register_alias('HTML', 'html', 'cell')
2284 mman.register_alias('file', 'writefile', 'cell')
2284 mman.register_alias('file', 'writefile', 'cell')
2285
2285
2286 # FIXME: Move the color initialization to the DisplayHook, which
2286 # FIXME: Move the color initialization to the DisplayHook, which
2287 # should be split into a prompt manager and displayhook. We probably
2287 # should be split into a prompt manager and displayhook. We probably
2288 # even need a centralize colors management object.
2288 # even need a centralize colors management object.
2289 self.run_line_magic('colors', self.colors)
2289 self.run_line_magic('colors', self.colors)
2290
2290
2291 # Defined here so that it's included in the documentation
2291 # Defined here so that it's included in the documentation
2292 @functools.wraps(magic.MagicsManager.register_function)
2292 @functools.wraps(magic.MagicsManager.register_function)
2293 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2293 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2294 self.magics_manager.register_function(
2294 self.magics_manager.register_function(
2295 func, magic_kind=magic_kind, magic_name=magic_name
2295 func, magic_kind=magic_kind, magic_name=magic_name
2296 )
2296 )
2297
2297
2298 def _find_with_lazy_load(self, /, type_, magic_name: str):
2298 def _find_with_lazy_load(self, /, type_, magic_name: str):
2299 """
2299 """
2300 Try to find a magic potentially lazy-loading it.
2300 Try to find a magic potentially lazy-loading it.
2301
2301
2302 Parameters
2302 Parameters
2303 ----------
2303 ----------
2304
2304
2305 type_: "line"|"cell"
2305 type_: "line"|"cell"
2306 the type of magics we are trying to find/lazy load.
2306 the type of magics we are trying to find/lazy load.
2307 magic_name: str
2307 magic_name: str
2308 The name of the magic we are trying to find/lazy load
2308 The name of the magic we are trying to find/lazy load
2309
2309
2310
2310
2311 Note that this may have any side effects
2311 Note that this may have any side effects
2312 """
2312 """
2313 finder = {"line": self.find_line_magic, "cell": self.find_cell_magic}[type_]
2313 finder = {"line": self.find_line_magic, "cell": self.find_cell_magic}[type_]
2314 fn = finder(magic_name)
2314 fn = finder(magic_name)
2315 if fn is not None:
2315 if fn is not None:
2316 return fn
2316 return fn
2317 lazy = self.magics_manager.lazy_magics.get(magic_name)
2317 lazy = self.magics_manager.lazy_magics.get(magic_name)
2318 if lazy is None:
2318 if lazy is None:
2319 return None
2319 return None
2320
2320
2321 self.run_line_magic("load_ext", lazy)
2321 self.run_line_magic("load_ext", lazy)
2322 res = finder(magic_name)
2322 res = finder(magic_name)
2323 return res
2323 return res
2324
2324
2325 def run_line_magic(self, magic_name: str, line, _stack_depth=1):
2325 def run_line_magic(self, magic_name: str, line, _stack_depth=1):
2326 """Execute the given line magic.
2326 """Execute the given line magic.
2327
2327
2328 Parameters
2328 Parameters
2329 ----------
2329 ----------
2330 magic_name : str
2330 magic_name : str
2331 Name of the desired magic function, without '%' prefix.
2331 Name of the desired magic function, without '%' prefix.
2332 line : str
2332 line : str
2333 The rest of the input line as a single string.
2333 The rest of the input line as a single string.
2334 _stack_depth : int
2334 _stack_depth : int
2335 If run_line_magic() is called from magic() then _stack_depth=2.
2335 If run_line_magic() is called from magic() then _stack_depth=2.
2336 This is added to ensure backward compatibility for use of 'get_ipython().magic()'
2336 This is added to ensure backward compatibility for use of 'get_ipython().magic()'
2337 """
2337 """
2338 fn = self._find_with_lazy_load("line", magic_name)
2338 fn = self._find_with_lazy_load("line", magic_name)
2339 if fn is None:
2339 if fn is None:
2340 lazy = self.magics_manager.lazy_magics.get(magic_name)
2340 lazy = self.magics_manager.lazy_magics.get(magic_name)
2341 if lazy:
2341 if lazy:
2342 self.run_line_magic("load_ext", lazy)
2342 self.run_line_magic("load_ext", lazy)
2343 fn = self.find_line_magic(magic_name)
2343 fn = self.find_line_magic(magic_name)
2344 if fn is None:
2344 if fn is None:
2345 cm = self.find_cell_magic(magic_name)
2345 cm = self.find_cell_magic(magic_name)
2346 etpl = "Line magic function `%%%s` not found%s."
2346 etpl = "Line magic function `%%%s` not found%s."
2347 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2347 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2348 'did you mean that instead?)' % magic_name )
2348 'did you mean that instead?)' % magic_name )
2349 raise UsageError(etpl % (magic_name, extra))
2349 raise UsageError(etpl % (magic_name, extra))
2350 else:
2350 else:
2351 # Note: this is the distance in the stack to the user's frame.
2351 # Note: this is the distance in the stack to the user's frame.
2352 # This will need to be updated if the internal calling logic gets
2352 # This will need to be updated if the internal calling logic gets
2353 # refactored, or else we'll be expanding the wrong variables.
2353 # refactored, or else we'll be expanding the wrong variables.
2354
2354
2355 # Determine stack_depth depending on where run_line_magic() has been called
2355 # Determine stack_depth depending on where run_line_magic() has been called
2356 stack_depth = _stack_depth
2356 stack_depth = _stack_depth
2357 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2357 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2358 # magic has opted out of var_expand
2358 # magic has opted out of var_expand
2359 magic_arg_s = line
2359 magic_arg_s = line
2360 else:
2360 else:
2361 magic_arg_s = self.var_expand(line, stack_depth)
2361 magic_arg_s = self.var_expand(line, stack_depth)
2362 # Put magic args in a list so we can call with f(*a) syntax
2362 # Put magic args in a list so we can call with f(*a) syntax
2363 args = [magic_arg_s]
2363 args = [magic_arg_s]
2364 kwargs = {}
2364 kwargs = {}
2365 # Grab local namespace if we need it:
2365 # Grab local namespace if we need it:
2366 if getattr(fn, "needs_local_scope", False):
2366 if getattr(fn, "needs_local_scope", False):
2367 kwargs['local_ns'] = self.get_local_scope(stack_depth)
2367 kwargs['local_ns'] = self.get_local_scope(stack_depth)
2368 with self.builtin_trap:
2368 with self.builtin_trap:
2369 result = fn(*args, **kwargs)
2369 result = fn(*args, **kwargs)
2370
2370
2371 # The code below prevents the output from being displayed
2371 # The code below prevents the output from being displayed
2372 # when using magics with decodator @output_can_be_silenced
2372 # when using magics with decodator @output_can_be_silenced
2373 # when the last Python token in the expression is a ';'.
2373 # when the last Python token in the expression is a ';'.
2374 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
2374 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
2375 if DisplayHook.semicolon_at_end_of_expression(magic_arg_s):
2375 if DisplayHook.semicolon_at_end_of_expression(magic_arg_s):
2376 return None
2376 return None
2377
2377
2378 return result
2378 return result
2379
2379
2380 def get_local_scope(self, stack_depth):
2380 def get_local_scope(self, stack_depth):
2381 """Get local scope at given stack depth.
2381 """Get local scope at given stack depth.
2382
2382
2383 Parameters
2383 Parameters
2384 ----------
2384 ----------
2385 stack_depth : int
2385 stack_depth : int
2386 Depth relative to calling frame
2386 Depth relative to calling frame
2387 """
2387 """
2388 return sys._getframe(stack_depth + 1).f_locals
2388 return sys._getframe(stack_depth + 1).f_locals
2389
2389
2390 def run_cell_magic(self, magic_name, line, cell):
2390 def run_cell_magic(self, magic_name, line, cell):
2391 """Execute the given cell magic.
2391 """Execute the given cell magic.
2392
2392
2393 Parameters
2393 Parameters
2394 ----------
2394 ----------
2395 magic_name : str
2395 magic_name : str
2396 Name of the desired magic function, without '%' prefix.
2396 Name of the desired magic function, without '%' prefix.
2397 line : str
2397 line : str
2398 The rest of the first input line as a single string.
2398 The rest of the first input line as a single string.
2399 cell : str
2399 cell : str
2400 The body of the cell as a (possibly multiline) string.
2400 The body of the cell as a (possibly multiline) string.
2401 """
2401 """
2402 fn = self._find_with_lazy_load("cell", magic_name)
2402 fn = self._find_with_lazy_load("cell", magic_name)
2403 if fn is None:
2403 if fn is None:
2404 lm = self.find_line_magic(magic_name)
2404 lm = self.find_line_magic(magic_name)
2405 etpl = "Cell magic `%%{0}` not found{1}."
2405 etpl = "Cell magic `%%{0}` not found{1}."
2406 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2406 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2407 'did you mean that instead?)'.format(magic_name))
2407 'did you mean that instead?)'.format(magic_name))
2408 raise UsageError(etpl.format(magic_name, extra))
2408 raise UsageError(etpl.format(magic_name, extra))
2409 elif cell == '':
2409 elif cell == '':
2410 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2410 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2411 if self.find_line_magic(magic_name) is not None:
2411 if self.find_line_magic(magic_name) is not None:
2412 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2412 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2413 raise UsageError(message)
2413 raise UsageError(message)
2414 else:
2414 else:
2415 # Note: this is the distance in the stack to the user's frame.
2415 # Note: this is the distance in the stack to the user's frame.
2416 # This will need to be updated if the internal calling logic gets
2416 # This will need to be updated if the internal calling logic gets
2417 # refactored, or else we'll be expanding the wrong variables.
2417 # refactored, or else we'll be expanding the wrong variables.
2418 stack_depth = 2
2418 stack_depth = 2
2419 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2419 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2420 # magic has opted out of var_expand
2420 # magic has opted out of var_expand
2421 magic_arg_s = line
2421 magic_arg_s = line
2422 else:
2422 else:
2423 magic_arg_s = self.var_expand(line, stack_depth)
2423 magic_arg_s = self.var_expand(line, stack_depth)
2424 kwargs = {}
2424 kwargs = {}
2425 if getattr(fn, "needs_local_scope", False):
2425 if getattr(fn, "needs_local_scope", False):
2426 kwargs['local_ns'] = self.user_ns
2426 kwargs['local_ns'] = self.user_ns
2427
2427
2428 with self.builtin_trap:
2428 with self.builtin_trap:
2429 args = (magic_arg_s, cell)
2429 args = (magic_arg_s, cell)
2430 result = fn(*args, **kwargs)
2430 result = fn(*args, **kwargs)
2431
2431
2432 # The code below prevents the output from being displayed
2432 # The code below prevents the output from being displayed
2433 # when using magics with decodator @output_can_be_silenced
2433 # when using magics with decodator @output_can_be_silenced
2434 # when the last Python token in the expression is a ';'.
2434 # when the last Python token in the expression is a ';'.
2435 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
2435 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
2436 if DisplayHook.semicolon_at_end_of_expression(cell):
2436 if DisplayHook.semicolon_at_end_of_expression(cell):
2437 return None
2437 return None
2438
2438
2439 return result
2439 return result
2440
2440
2441 def find_line_magic(self, magic_name):
2441 def find_line_magic(self, magic_name):
2442 """Find and return a line magic by name.
2442 """Find and return a line magic by name.
2443
2443
2444 Returns None if the magic isn't found."""
2444 Returns None if the magic isn't found."""
2445 return self.magics_manager.magics['line'].get(magic_name)
2445 return self.magics_manager.magics['line'].get(magic_name)
2446
2446
2447 def find_cell_magic(self, magic_name):
2447 def find_cell_magic(self, magic_name):
2448 """Find and return a cell magic by name.
2448 """Find and return a cell magic by name.
2449
2449
2450 Returns None if the magic isn't found."""
2450 Returns None if the magic isn't found."""
2451 return self.magics_manager.magics['cell'].get(magic_name)
2451 return self.magics_manager.magics['cell'].get(magic_name)
2452
2452
2453 def find_magic(self, magic_name, magic_kind='line'):
2453 def find_magic(self, magic_name, magic_kind='line'):
2454 """Find and return a magic of the given type by name.
2454 """Find and return a magic of the given type by name.
2455
2455
2456 Returns None if the magic isn't found."""
2456 Returns None if the magic isn't found."""
2457 return self.magics_manager.magics[magic_kind].get(magic_name)
2457 return self.magics_manager.magics[magic_kind].get(magic_name)
2458
2458
2459 def magic(self, arg_s):
2459 def magic(self, arg_s):
2460 """
2460 """
2461 DEPRECATED
2461 DEPRECATED
2462
2462
2463 Deprecated since IPython 0.13 (warning added in
2463 Deprecated since IPython 0.13 (warning added in
2464 8.1), use run_line_magic(magic_name, parameter_s).
2464 8.1), use run_line_magic(magic_name, parameter_s).
2465
2465
2466 Call a magic function by name.
2466 Call a magic function by name.
2467
2467
2468 Input: a string containing the name of the magic function to call and
2468 Input: a string containing the name of the magic function to call and
2469 any additional arguments to be passed to the magic.
2469 any additional arguments to be passed to the magic.
2470
2470
2471 magic('name -opt foo bar') is equivalent to typing at the ipython
2471 magic('name -opt foo bar') is equivalent to typing at the ipython
2472 prompt:
2472 prompt:
2473
2473
2474 In[1]: %name -opt foo bar
2474 In[1]: %name -opt foo bar
2475
2475
2476 To call a magic without arguments, simply use magic('name').
2476 To call a magic without arguments, simply use magic('name').
2477
2477
2478 This provides a proper Python function to call IPython's magics in any
2478 This provides a proper Python function to call IPython's magics in any
2479 valid Python code you can type at the interpreter, including loops and
2479 valid Python code you can type at the interpreter, including loops and
2480 compound statements.
2480 compound statements.
2481 """
2481 """
2482 warnings.warn(
2482 warnings.warn(
2483 "`magic(...)` is deprecated since IPython 0.13 (warning added in "
2483 "`magic(...)` is deprecated since IPython 0.13 (warning added in "
2484 "8.1), use run_line_magic(magic_name, parameter_s).",
2484 "8.1), use run_line_magic(magic_name, parameter_s).",
2485 DeprecationWarning,
2485 DeprecationWarning,
2486 stacklevel=2,
2486 stacklevel=2,
2487 )
2487 )
2488 # TODO: should we issue a loud deprecation warning here?
2488 # TODO: should we issue a loud deprecation warning here?
2489 magic_name, _, magic_arg_s = arg_s.partition(' ')
2489 magic_name, _, magic_arg_s = arg_s.partition(' ')
2490 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2490 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2491 return self.run_line_magic(magic_name, magic_arg_s, _stack_depth=2)
2491 return self.run_line_magic(magic_name, magic_arg_s, _stack_depth=2)
2492
2492
2493 #-------------------------------------------------------------------------
2493 #-------------------------------------------------------------------------
2494 # Things related to macros
2494 # Things related to macros
2495 #-------------------------------------------------------------------------
2495 #-------------------------------------------------------------------------
2496
2496
2497 def define_macro(self, name, themacro):
2497 def define_macro(self, name, themacro):
2498 """Define a new macro
2498 """Define a new macro
2499
2499
2500 Parameters
2500 Parameters
2501 ----------
2501 ----------
2502 name : str
2502 name : str
2503 The name of the macro.
2503 The name of the macro.
2504 themacro : str or Macro
2504 themacro : str or Macro
2505 The action to do upon invoking the macro. If a string, a new
2505 The action to do upon invoking the macro. If a string, a new
2506 Macro object is created by passing the string to it.
2506 Macro object is created by passing the string to it.
2507 """
2507 """
2508
2508
2509 from IPython.core import macro
2509 from IPython.core import macro
2510
2510
2511 if isinstance(themacro, str):
2511 if isinstance(themacro, str):
2512 themacro = macro.Macro(themacro)
2512 themacro = macro.Macro(themacro)
2513 if not isinstance(themacro, macro.Macro):
2513 if not isinstance(themacro, macro.Macro):
2514 raise ValueError('A macro must be a string or a Macro instance.')
2514 raise ValueError('A macro must be a string or a Macro instance.')
2515 self.user_ns[name] = themacro
2515 self.user_ns[name] = themacro
2516
2516
2517 #-------------------------------------------------------------------------
2517 #-------------------------------------------------------------------------
2518 # Things related to the running of system commands
2518 # Things related to the running of system commands
2519 #-------------------------------------------------------------------------
2519 #-------------------------------------------------------------------------
2520
2520
2521 def system_piped(self, cmd):
2521 def system_piped(self, cmd):
2522 """Call the given cmd in a subprocess, piping stdout/err
2522 """Call the given cmd in a subprocess, piping stdout/err
2523
2523
2524 Parameters
2524 Parameters
2525 ----------
2525 ----------
2526 cmd : str
2526 cmd : str
2527 Command to execute (can not end in '&', as background processes are
2527 Command to execute (can not end in '&', as background processes are
2528 not supported. Should not be a command that expects input
2528 not supported. Should not be a command that expects input
2529 other than simple text.
2529 other than simple text.
2530 """
2530 """
2531 if cmd.rstrip().endswith('&'):
2531 if cmd.rstrip().endswith('&'):
2532 # this is *far* from a rigorous test
2532 # this is *far* from a rigorous test
2533 # We do not support backgrounding processes because we either use
2533 # We do not support backgrounding processes because we either use
2534 # pexpect or pipes to read from. Users can always just call
2534 # pexpect or pipes to read from. Users can always just call
2535 # os.system() or use ip.system=ip.system_raw
2535 # os.system() or use ip.system=ip.system_raw
2536 # if they really want a background process.
2536 # if they really want a background process.
2537 raise OSError("Background processes not supported.")
2537 raise OSError("Background processes not supported.")
2538
2538
2539 # we explicitly do NOT return the subprocess status code, because
2539 # we explicitly do NOT return the subprocess status code, because
2540 # a non-None value would trigger :func:`sys.displayhook` calls.
2540 # a non-None value would trigger :func:`sys.displayhook` calls.
2541 # Instead, we store the exit_code in user_ns.
2541 # Instead, we store the exit_code in user_ns.
2542 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2542 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2543
2543
2544 def system_raw(self, cmd):
2544 def system_raw(self, cmd):
2545 """Call the given cmd in a subprocess using os.system on Windows or
2545 """Call the given cmd in a subprocess using os.system on Windows or
2546 subprocess.call using the system shell on other platforms.
2546 subprocess.call using the system shell on other platforms.
2547
2547
2548 Parameters
2548 Parameters
2549 ----------
2549 ----------
2550 cmd : str
2550 cmd : str
2551 Command to execute.
2551 Command to execute.
2552 """
2552 """
2553 cmd = self.var_expand(cmd, depth=1)
2553 cmd = self.var_expand(cmd, depth=1)
2554 # warn if there is an IPython magic alternative.
2554 # warn if there is an IPython magic alternative.
2555 main_cmd = cmd.split()[0]
2555 main_cmd = cmd.split()[0]
2556 has_magic_alternatives = ("pip", "conda", "cd")
2556 has_magic_alternatives = ("pip", "conda", "cd")
2557
2557
2558 if main_cmd in has_magic_alternatives:
2558 if main_cmd in has_magic_alternatives:
2559 warnings.warn(
2559 warnings.warn(
2560 (
2560 (
2561 "You executed the system command !{0} which may not work "
2561 "You executed the system command !{0} which may not work "
2562 "as expected. Try the IPython magic %{0} instead."
2562 "as expected. Try the IPython magic %{0} instead."
2563 ).format(main_cmd)
2563 ).format(main_cmd)
2564 )
2564 )
2565
2565
2566 # protect os.system from UNC paths on Windows, which it can't handle:
2566 # protect os.system from UNC paths on Windows, which it can't handle:
2567 if sys.platform == 'win32':
2567 if sys.platform == 'win32':
2568 from IPython.utils._process_win32 import AvoidUNCPath
2568 from IPython.utils._process_win32 import AvoidUNCPath
2569 with AvoidUNCPath() as path:
2569 with AvoidUNCPath() as path:
2570 if path is not None:
2570 if path is not None:
2571 cmd = '"pushd %s &&"%s' % (path, cmd)
2571 cmd = '"pushd %s &&"%s' % (path, cmd)
2572 try:
2572 try:
2573 ec = os.system(cmd)
2573 ec = os.system(cmd)
2574 except KeyboardInterrupt:
2574 except KeyboardInterrupt:
2575 print('\n' + self.get_exception_only(), file=sys.stderr)
2575 print('\n' + self.get_exception_only(), file=sys.stderr)
2576 ec = -2
2576 ec = -2
2577 else:
2577 else:
2578 # For posix the result of the subprocess.call() below is an exit
2578 # For posix the result of the subprocess.call() below is an exit
2579 # code, which by convention is zero for success, positive for
2579 # code, which by convention is zero for success, positive for
2580 # program failure. Exit codes above 128 are reserved for signals,
2580 # program failure. Exit codes above 128 are reserved for signals,
2581 # and the formula for converting a signal to an exit code is usually
2581 # and the formula for converting a signal to an exit code is usually
2582 # signal_number+128. To more easily differentiate between exit
2582 # signal_number+128. To more easily differentiate between exit
2583 # codes and signals, ipython uses negative numbers. For instance
2583 # codes and signals, ipython uses negative numbers. For instance
2584 # since control-c is signal 2 but exit code 130, ipython's
2584 # since control-c is signal 2 but exit code 130, ipython's
2585 # _exit_code variable will read -2. Note that some shells like
2585 # _exit_code variable will read -2. Note that some shells like
2586 # csh and fish don't follow sh/bash conventions for exit codes.
2586 # csh and fish don't follow sh/bash conventions for exit codes.
2587 executable = os.environ.get('SHELL', None)
2587 executable = os.environ.get('SHELL', None)
2588 try:
2588 try:
2589 # Use env shell instead of default /bin/sh
2589 # Use env shell instead of default /bin/sh
2590 ec = subprocess.call(cmd, shell=True, executable=executable)
2590 ec = subprocess.call(cmd, shell=True, executable=executable)
2591 except KeyboardInterrupt:
2591 except KeyboardInterrupt:
2592 # intercept control-C; a long traceback is not useful here
2592 # intercept control-C; a long traceback is not useful here
2593 print('\n' + self.get_exception_only(), file=sys.stderr)
2593 print('\n' + self.get_exception_only(), file=sys.stderr)
2594 ec = 130
2594 ec = 130
2595 if ec > 128:
2595 if ec > 128:
2596 ec = -(ec - 128)
2596 ec = -(ec - 128)
2597
2597
2598 # We explicitly do NOT return the subprocess status code, because
2598 # We explicitly do NOT return the subprocess status code, because
2599 # a non-None value would trigger :func:`sys.displayhook` calls.
2599 # a non-None value would trigger :func:`sys.displayhook` calls.
2600 # Instead, we store the exit_code in user_ns. Note the semantics
2600 # Instead, we store the exit_code in user_ns. Note the semantics
2601 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2601 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2602 # but raising SystemExit(_exit_code) will give status 254!
2602 # but raising SystemExit(_exit_code) will give status 254!
2603 self.user_ns['_exit_code'] = ec
2603 self.user_ns['_exit_code'] = ec
2604
2604
2605 # use piped system by default, because it is better behaved
2605 # use piped system by default, because it is better behaved
2606 system = system_piped
2606 system = system_piped
2607
2607
2608 def getoutput(self, cmd, split=True, depth=0):
2608 def getoutput(self, cmd, split=True, depth=0):
2609 """Get output (possibly including stderr) from a subprocess.
2609 """Get output (possibly including stderr) from a subprocess.
2610
2610
2611 Parameters
2611 Parameters
2612 ----------
2612 ----------
2613 cmd : str
2613 cmd : str
2614 Command to execute (can not end in '&', as background processes are
2614 Command to execute (can not end in '&', as background processes are
2615 not supported.
2615 not supported.
2616 split : bool, optional
2616 split : bool, optional
2617 If True, split the output into an IPython SList. Otherwise, an
2617 If True, split the output into an IPython SList. Otherwise, an
2618 IPython LSString is returned. These are objects similar to normal
2618 IPython LSString is returned. These are objects similar to normal
2619 lists and strings, with a few convenience attributes for easier
2619 lists and strings, with a few convenience attributes for easier
2620 manipulation of line-based output. You can use '?' on them for
2620 manipulation of line-based output. You can use '?' on them for
2621 details.
2621 details.
2622 depth : int, optional
2622 depth : int, optional
2623 How many frames above the caller are the local variables which should
2623 How many frames above the caller are the local variables which should
2624 be expanded in the command string? The default (0) assumes that the
2624 be expanded in the command string? The default (0) assumes that the
2625 expansion variables are in the stack frame calling this function.
2625 expansion variables are in the stack frame calling this function.
2626 """
2626 """
2627 if cmd.rstrip().endswith('&'):
2627 if cmd.rstrip().endswith('&'):
2628 # this is *far* from a rigorous test
2628 # this is *far* from a rigorous test
2629 raise OSError("Background processes not supported.")
2629 raise OSError("Background processes not supported.")
2630 out = getoutput(self.var_expand(cmd, depth=depth+1))
2630 out = getoutput(self.var_expand(cmd, depth=depth+1))
2631 if split:
2631 if split:
2632 out = SList(out.splitlines())
2632 out = SList(out.splitlines())
2633 else:
2633 else:
2634 out = LSString(out)
2634 out = LSString(out)
2635 return out
2635 return out
2636
2636
2637 #-------------------------------------------------------------------------
2637 #-------------------------------------------------------------------------
2638 # Things related to aliases
2638 # Things related to aliases
2639 #-------------------------------------------------------------------------
2639 #-------------------------------------------------------------------------
2640
2640
2641 def init_alias(self):
2641 def init_alias(self):
2642 self.alias_manager = AliasManager(shell=self, parent=self)
2642 self.alias_manager = AliasManager(shell=self, parent=self)
2643 self.configurables.append(self.alias_manager)
2643 self.configurables.append(self.alias_manager)
2644
2644
2645 #-------------------------------------------------------------------------
2645 #-------------------------------------------------------------------------
2646 # Things related to extensions
2646 # Things related to extensions
2647 #-------------------------------------------------------------------------
2647 #-------------------------------------------------------------------------
2648
2648
2649 def init_extension_manager(self):
2649 def init_extension_manager(self):
2650 self.extension_manager = ExtensionManager(shell=self, parent=self)
2650 self.extension_manager = ExtensionManager(shell=self, parent=self)
2651 self.configurables.append(self.extension_manager)
2651 self.configurables.append(self.extension_manager)
2652
2652
2653 #-------------------------------------------------------------------------
2653 #-------------------------------------------------------------------------
2654 # Things related to payloads
2654 # Things related to payloads
2655 #-------------------------------------------------------------------------
2655 #-------------------------------------------------------------------------
2656
2656
2657 def init_payload(self):
2657 def init_payload(self):
2658 self.payload_manager = PayloadManager(parent=self)
2658 self.payload_manager = PayloadManager(parent=self)
2659 self.configurables.append(self.payload_manager)
2659 self.configurables.append(self.payload_manager)
2660
2660
2661 #-------------------------------------------------------------------------
2661 #-------------------------------------------------------------------------
2662 # Things related to the prefilter
2662 # Things related to the prefilter
2663 #-------------------------------------------------------------------------
2663 #-------------------------------------------------------------------------
2664
2664
2665 def init_prefilter(self):
2665 def init_prefilter(self):
2666 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2666 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2667 self.configurables.append(self.prefilter_manager)
2667 self.configurables.append(self.prefilter_manager)
2668 # Ultimately this will be refactored in the new interpreter code, but
2668 # Ultimately this will be refactored in the new interpreter code, but
2669 # for now, we should expose the main prefilter method (there's legacy
2669 # for now, we should expose the main prefilter method (there's legacy
2670 # code out there that may rely on this).
2670 # code out there that may rely on this).
2671 self.prefilter = self.prefilter_manager.prefilter_lines
2671 self.prefilter = self.prefilter_manager.prefilter_lines
2672
2672
2673 def auto_rewrite_input(self, cmd):
2673 def auto_rewrite_input(self, cmd):
2674 """Print to the screen the rewritten form of the user's command.
2674 """Print to the screen the rewritten form of the user's command.
2675
2675
2676 This shows visual feedback by rewriting input lines that cause
2676 This shows visual feedback by rewriting input lines that cause
2677 automatic calling to kick in, like::
2677 automatic calling to kick in, like::
2678
2678
2679 /f x
2679 /f x
2680
2680
2681 into::
2681 into::
2682
2682
2683 ------> f(x)
2683 ------> f(x)
2684
2684
2685 after the user's input prompt. This helps the user understand that the
2685 after the user's input prompt. This helps the user understand that the
2686 input line was transformed automatically by IPython.
2686 input line was transformed automatically by IPython.
2687 """
2687 """
2688 if not self.show_rewritten_input:
2688 if not self.show_rewritten_input:
2689 return
2689 return
2690
2690
2691 # This is overridden in TerminalInteractiveShell to use fancy prompts
2691 # This is overridden in TerminalInteractiveShell to use fancy prompts
2692 print("------> " + cmd)
2692 print("------> " + cmd)
2693
2693
2694 #-------------------------------------------------------------------------
2694 #-------------------------------------------------------------------------
2695 # Things related to extracting values/expressions from kernel and user_ns
2695 # Things related to extracting values/expressions from kernel and user_ns
2696 #-------------------------------------------------------------------------
2696 #-------------------------------------------------------------------------
2697
2697
2698 def _user_obj_error(self):
2698 def _user_obj_error(self):
2699 """return simple exception dict
2699 """return simple exception dict
2700
2700
2701 for use in user_expressions
2701 for use in user_expressions
2702 """
2702 """
2703
2703
2704 etype, evalue, tb = self._get_exc_info()
2704 etype, evalue, tb = self._get_exc_info()
2705 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2705 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2706
2706
2707 exc_info = {
2707 exc_info = {
2708 "status": "error",
2708 "status": "error",
2709 "traceback": stb,
2709 "traceback": stb,
2710 "ename": etype.__name__,
2710 "ename": etype.__name__,
2711 "evalue": py3compat.safe_unicode(evalue),
2711 "evalue": py3compat.safe_unicode(evalue),
2712 }
2712 }
2713
2713
2714 return exc_info
2714 return exc_info
2715
2715
2716 def _format_user_obj(self, obj):
2716 def _format_user_obj(self, obj):
2717 """format a user object to display dict
2717 """format a user object to display dict
2718
2718
2719 for use in user_expressions
2719 for use in user_expressions
2720 """
2720 """
2721
2721
2722 data, md = self.display_formatter.format(obj)
2722 data, md = self.display_formatter.format(obj)
2723 value = {
2723 value = {
2724 'status' : 'ok',
2724 'status' : 'ok',
2725 'data' : data,
2725 'data' : data,
2726 'metadata' : md,
2726 'metadata' : md,
2727 }
2727 }
2728 return value
2728 return value
2729
2729
2730 def user_expressions(self, expressions):
2730 def user_expressions(self, expressions):
2731 """Evaluate a dict of expressions in the user's namespace.
2731 """Evaluate a dict of expressions in the user's namespace.
2732
2732
2733 Parameters
2733 Parameters
2734 ----------
2734 ----------
2735 expressions : dict
2735 expressions : dict
2736 A dict with string keys and string values. The expression values
2736 A dict with string keys and string values. The expression values
2737 should be valid Python expressions, each of which will be evaluated
2737 should be valid Python expressions, each of which will be evaluated
2738 in the user namespace.
2738 in the user namespace.
2739
2739
2740 Returns
2740 Returns
2741 -------
2741 -------
2742 A dict, keyed like the input expressions dict, with the rich mime-typed
2742 A dict, keyed like the input expressions dict, with the rich mime-typed
2743 display_data of each value.
2743 display_data of each value.
2744 """
2744 """
2745 out = {}
2745 out = {}
2746 user_ns = self.user_ns
2746 user_ns = self.user_ns
2747 global_ns = self.user_global_ns
2747 global_ns = self.user_global_ns
2748
2748
2749 for key, expr in expressions.items():
2749 for key, expr in expressions.items():
2750 try:
2750 try:
2751 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2751 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2752 except:
2752 except:
2753 value = self._user_obj_error()
2753 value = self._user_obj_error()
2754 out[key] = value
2754 out[key] = value
2755 return out
2755 return out
2756
2756
2757 #-------------------------------------------------------------------------
2757 #-------------------------------------------------------------------------
2758 # Things related to the running of code
2758 # Things related to the running of code
2759 #-------------------------------------------------------------------------
2759 #-------------------------------------------------------------------------
2760
2760
2761 def ex(self, cmd):
2761 def ex(self, cmd):
2762 """Execute a normal python statement in user namespace."""
2762 """Execute a normal python statement in user namespace."""
2763 with self.builtin_trap:
2763 with self.builtin_trap:
2764 exec(cmd, self.user_global_ns, self.user_ns)
2764 exec(cmd, self.user_global_ns, self.user_ns)
2765
2765
2766 def ev(self, expr):
2766 def ev(self, expr):
2767 """Evaluate python expression expr in user namespace.
2767 """Evaluate python expression expr in user namespace.
2768
2768
2769 Returns the result of evaluation
2769 Returns the result of evaluation
2770 """
2770 """
2771 with self.builtin_trap:
2771 with self.builtin_trap:
2772 return eval(expr, self.user_global_ns, self.user_ns)
2772 return eval(expr, self.user_global_ns, self.user_ns)
2773
2773
2774 def safe_execfile(self, fname, *where, exit_ignore=False, raise_exceptions=False, shell_futures=False):
2774 def safe_execfile(self, fname, *where, exit_ignore=False, raise_exceptions=False, shell_futures=False):
2775 """A safe version of the builtin execfile().
2775 """A safe version of the builtin execfile().
2776
2776
2777 This version will never throw an exception, but instead print
2777 This version will never throw an exception, but instead print
2778 helpful error messages to the screen. This only works on pure
2778 helpful error messages to the screen. This only works on pure
2779 Python files with the .py extension.
2779 Python files with the .py extension.
2780
2780
2781 Parameters
2781 Parameters
2782 ----------
2782 ----------
2783 fname : string
2783 fname : string
2784 The name of the file to be executed.
2784 The name of the file to be executed.
2785 *where : tuple
2785 *where : tuple
2786 One or two namespaces, passed to execfile() as (globals,locals).
2786 One or two namespaces, passed to execfile() as (globals,locals).
2787 If only one is given, it is passed as both.
2787 If only one is given, it is passed as both.
2788 exit_ignore : bool (False)
2788 exit_ignore : bool (False)
2789 If True, then silence SystemExit for non-zero status (it is always
2789 If True, then silence SystemExit for non-zero status (it is always
2790 silenced for zero status, as it is so common).
2790 silenced for zero status, as it is so common).
2791 raise_exceptions : bool (False)
2791 raise_exceptions : bool (False)
2792 If True raise exceptions everywhere. Meant for testing.
2792 If True raise exceptions everywhere. Meant for testing.
2793 shell_futures : bool (False)
2793 shell_futures : bool (False)
2794 If True, the code will share future statements with the interactive
2794 If True, the code will share future statements with the interactive
2795 shell. It will both be affected by previous __future__ imports, and
2795 shell. It will both be affected by previous __future__ imports, and
2796 any __future__ imports in the code will affect the shell. If False,
2796 any __future__ imports in the code will affect the shell. If False,
2797 __future__ imports are not shared in either direction.
2797 __future__ imports are not shared in either direction.
2798
2798
2799 """
2799 """
2800 fname = Path(fname).expanduser().resolve()
2800 fname = Path(fname).expanduser().resolve()
2801
2801
2802 # Make sure we can open the file
2802 # Make sure we can open the file
2803 try:
2803 try:
2804 with fname.open("rb"):
2804 with fname.open("rb"):
2805 pass
2805 pass
2806 except:
2806 except:
2807 warn('Could not open file <%s> for safe execution.' % fname)
2807 warn('Could not open file <%s> for safe execution.' % fname)
2808 return
2808 return
2809
2809
2810 # Find things also in current directory. This is needed to mimic the
2810 # Find things also in current directory. This is needed to mimic the
2811 # behavior of running a script from the system command line, where
2811 # behavior of running a script from the system command line, where
2812 # Python inserts the script's directory into sys.path
2812 # Python inserts the script's directory into sys.path
2813 dname = str(fname.parent)
2813 dname = str(fname.parent)
2814
2814
2815 with prepended_to_syspath(dname), self.builtin_trap:
2815 with prepended_to_syspath(dname), self.builtin_trap:
2816 try:
2816 try:
2817 glob, loc = (where + (None, ))[:2]
2817 glob, loc = (where + (None, ))[:2]
2818 py3compat.execfile(
2818 py3compat.execfile(
2819 fname, glob, loc,
2819 fname, glob, loc,
2820 self.compile if shell_futures else None)
2820 self.compile if shell_futures else None)
2821 except SystemExit as status:
2821 except SystemExit as status:
2822 # If the call was made with 0 or None exit status (sys.exit(0)
2822 # If the call was made with 0 or None exit status (sys.exit(0)
2823 # or sys.exit() ), don't bother showing a traceback, as both of
2823 # or sys.exit() ), don't bother showing a traceback, as both of
2824 # these are considered normal by the OS:
2824 # these are considered normal by the OS:
2825 # > python -c'import sys;sys.exit(0)'; echo $?
2825 # > python -c'import sys;sys.exit(0)'; echo $?
2826 # 0
2826 # 0
2827 # > python -c'import sys;sys.exit()'; echo $?
2827 # > python -c'import sys;sys.exit()'; echo $?
2828 # 0
2828 # 0
2829 # For other exit status, we show the exception unless
2829 # For other exit status, we show the exception unless
2830 # explicitly silenced, but only in short form.
2830 # explicitly silenced, but only in short form.
2831 if status.code:
2831 if status.code:
2832 if raise_exceptions:
2832 if raise_exceptions:
2833 raise
2833 raise
2834 if not exit_ignore:
2834 if not exit_ignore:
2835 self.showtraceback(exception_only=True)
2835 self.showtraceback(exception_only=True)
2836 except:
2836 except:
2837 if raise_exceptions:
2837 if raise_exceptions:
2838 raise
2838 raise
2839 # tb offset is 2 because we wrap execfile
2839 # tb offset is 2 because we wrap execfile
2840 self.showtraceback(tb_offset=2)
2840 self.showtraceback(tb_offset=2)
2841
2841
2842 def safe_execfile_ipy(self, fname, shell_futures=False, raise_exceptions=False):
2842 def safe_execfile_ipy(self, fname, shell_futures=False, raise_exceptions=False):
2843 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2843 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2844
2844
2845 Parameters
2845 Parameters
2846 ----------
2846 ----------
2847 fname : str
2847 fname : str
2848 The name of the file to execute. The filename must have a
2848 The name of the file to execute. The filename must have a
2849 .ipy or .ipynb extension.
2849 .ipy or .ipynb extension.
2850 shell_futures : bool (False)
2850 shell_futures : bool (False)
2851 If True, the code will share future statements with the interactive
2851 If True, the code will share future statements with the interactive
2852 shell. It will both be affected by previous __future__ imports, and
2852 shell. It will both be affected by previous __future__ imports, and
2853 any __future__ imports in the code will affect the shell. If False,
2853 any __future__ imports in the code will affect the shell. If False,
2854 __future__ imports are not shared in either direction.
2854 __future__ imports are not shared in either direction.
2855 raise_exceptions : bool (False)
2855 raise_exceptions : bool (False)
2856 If True raise exceptions everywhere. Meant for testing.
2856 If True raise exceptions everywhere. Meant for testing.
2857 """
2857 """
2858 fname = Path(fname).expanduser().resolve()
2858 fname = Path(fname).expanduser().resolve()
2859
2859
2860 # Make sure we can open the file
2860 # Make sure we can open the file
2861 try:
2861 try:
2862 with fname.open("rb"):
2862 with fname.open("rb"):
2863 pass
2863 pass
2864 except:
2864 except:
2865 warn('Could not open file <%s> for safe execution.' % fname)
2865 warn('Could not open file <%s> for safe execution.' % fname)
2866 return
2866 return
2867
2867
2868 # Find things also in current directory. This is needed to mimic the
2868 # Find things also in current directory. This is needed to mimic the
2869 # behavior of running a script from the system command line, where
2869 # behavior of running a script from the system command line, where
2870 # Python inserts the script's directory into sys.path
2870 # Python inserts the script's directory into sys.path
2871 dname = str(fname.parent)
2871 dname = str(fname.parent)
2872
2872
2873 def get_cells():
2873 def get_cells():
2874 """generator for sequence of code blocks to run"""
2874 """generator for sequence of code blocks to run"""
2875 if fname.suffix == ".ipynb":
2875 if fname.suffix == ".ipynb":
2876 from nbformat import read
2876 from nbformat import read
2877 nb = read(fname, as_version=4)
2877 nb = read(fname, as_version=4)
2878 if not nb.cells:
2878 if not nb.cells:
2879 return
2879 return
2880 for cell in nb.cells:
2880 for cell in nb.cells:
2881 if cell.cell_type == 'code':
2881 if cell.cell_type == 'code':
2882 yield cell.source
2882 yield cell.source
2883 else:
2883 else:
2884 yield fname.read_text(encoding="utf-8")
2884 yield fname.read_text(encoding="utf-8")
2885
2885
2886 with prepended_to_syspath(dname):
2886 with prepended_to_syspath(dname):
2887 try:
2887 try:
2888 for cell in get_cells():
2888 for cell in get_cells():
2889 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2889 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2890 if raise_exceptions:
2890 if raise_exceptions:
2891 result.raise_error()
2891 result.raise_error()
2892 elif not result.success:
2892 elif not result.success:
2893 break
2893 break
2894 except:
2894 except:
2895 if raise_exceptions:
2895 if raise_exceptions:
2896 raise
2896 raise
2897 self.showtraceback()
2897 self.showtraceback()
2898 warn('Unknown failure executing file: <%s>' % fname)
2898 warn('Unknown failure executing file: <%s>' % fname)
2899
2899
2900 def safe_run_module(self, mod_name, where):
2900 def safe_run_module(self, mod_name, where):
2901 """A safe version of runpy.run_module().
2901 """A safe version of runpy.run_module().
2902
2902
2903 This version will never throw an exception, but instead print
2903 This version will never throw an exception, but instead print
2904 helpful error messages to the screen.
2904 helpful error messages to the screen.
2905
2905
2906 `SystemExit` exceptions with status code 0 or None are ignored.
2906 `SystemExit` exceptions with status code 0 or None are ignored.
2907
2907
2908 Parameters
2908 Parameters
2909 ----------
2909 ----------
2910 mod_name : string
2910 mod_name : string
2911 The name of the module to be executed.
2911 The name of the module to be executed.
2912 where : dict
2912 where : dict
2913 The globals namespace.
2913 The globals namespace.
2914 """
2914 """
2915 try:
2915 try:
2916 try:
2916 try:
2917 where.update(
2917 where.update(
2918 runpy.run_module(str(mod_name), run_name="__main__",
2918 runpy.run_module(str(mod_name), run_name="__main__",
2919 alter_sys=True)
2919 alter_sys=True)
2920 )
2920 )
2921 except SystemExit as status:
2921 except SystemExit as status:
2922 if status.code:
2922 if status.code:
2923 raise
2923 raise
2924 except:
2924 except:
2925 self.showtraceback()
2925 self.showtraceback()
2926 warn('Unknown failure executing module: <%s>' % mod_name)
2926 warn('Unknown failure executing module: <%s>' % mod_name)
2927
2927
2928 def run_cell(
2928 def run_cell(
2929 self,
2929 self,
2930 raw_cell,
2930 raw_cell,
2931 store_history=False,
2931 store_history=False,
2932 silent=False,
2932 silent=False,
2933 shell_futures=True,
2933 shell_futures=True,
2934 cell_id=None,
2934 cell_id=None,
2935 ):
2935 ):
2936 """Run a complete IPython cell.
2936 """Run a complete IPython cell.
2937
2937
2938 Parameters
2938 Parameters
2939 ----------
2939 ----------
2940 raw_cell : str
2940 raw_cell : str
2941 The code (including IPython code such as %magic functions) to run.
2941 The code (including IPython code such as %magic functions) to run.
2942 store_history : bool
2942 store_history : bool
2943 If True, the raw and translated cell will be stored in IPython's
2943 If True, the raw and translated cell will be stored in IPython's
2944 history. For user code calling back into IPython's machinery, this
2944 history. For user code calling back into IPython's machinery, this
2945 should be set to False.
2945 should be set to False.
2946 silent : bool
2946 silent : bool
2947 If True, avoid side-effects, such as implicit displayhooks and
2947 If True, avoid side-effects, such as implicit displayhooks and
2948 and logging. silent=True forces store_history=False.
2948 and logging. silent=True forces store_history=False.
2949 shell_futures : bool
2949 shell_futures : bool
2950 If True, the code will share future statements with the interactive
2950 If True, the code will share future statements with the interactive
2951 shell. It will both be affected by previous __future__ imports, and
2951 shell. It will both be affected by previous __future__ imports, and
2952 any __future__ imports in the code will affect the shell. If False,
2952 any __future__ imports in the code will affect the shell. If False,
2953 __future__ imports are not shared in either direction.
2953 __future__ imports are not shared in either direction.
2954
2954
2955 Returns
2955 Returns
2956 -------
2956 -------
2957 result : :class:`ExecutionResult`
2957 result : :class:`ExecutionResult`
2958 """
2958 """
2959 result = None
2959 result = None
2960 try:
2960 try:
2961 result = self._run_cell(
2961 result = self._run_cell(
2962 raw_cell, store_history, silent, shell_futures, cell_id
2962 raw_cell, store_history, silent, shell_futures, cell_id
2963 )
2963 )
2964 finally:
2964 finally:
2965 self.events.trigger('post_execute')
2965 self.events.trigger('post_execute')
2966 if not silent:
2966 if not silent:
2967 self.events.trigger('post_run_cell', result)
2967 self.events.trigger('post_run_cell', result)
2968 return result
2968 return result
2969
2969
2970 def _run_cell(
2970 def _run_cell(
2971 self,
2971 self,
2972 raw_cell: str,
2972 raw_cell: str,
2973 store_history: bool,
2973 store_history: bool,
2974 silent: bool,
2974 silent: bool,
2975 shell_futures: bool,
2975 shell_futures: bool,
2976 cell_id: str,
2976 cell_id: str,
2977 ) -> ExecutionResult:
2977 ) -> ExecutionResult:
2978 """Internal method to run a complete IPython cell."""
2978 """Internal method to run a complete IPython cell."""
2979
2979
2980 # we need to avoid calling self.transform_cell multiple time on the same thing
2980 # we need to avoid calling self.transform_cell multiple time on the same thing
2981 # so we need to store some results:
2981 # so we need to store some results:
2982 preprocessing_exc_tuple = None
2982 preprocessing_exc_tuple = None
2983 try:
2983 try:
2984 transformed_cell = self.transform_cell(raw_cell)
2984 transformed_cell = self.transform_cell(raw_cell)
2985 except Exception:
2985 except Exception:
2986 transformed_cell = raw_cell
2986 transformed_cell = raw_cell
2987 preprocessing_exc_tuple = sys.exc_info()
2987 preprocessing_exc_tuple = sys.exc_info()
2988
2988
2989 assert transformed_cell is not None
2989 assert transformed_cell is not None
2990 coro = self.run_cell_async(
2990 coro = self.run_cell_async(
2991 raw_cell,
2991 raw_cell,
2992 store_history=store_history,
2992 store_history=store_history,
2993 silent=silent,
2993 silent=silent,
2994 shell_futures=shell_futures,
2994 shell_futures=shell_futures,
2995 transformed_cell=transformed_cell,
2995 transformed_cell=transformed_cell,
2996 preprocessing_exc_tuple=preprocessing_exc_tuple,
2996 preprocessing_exc_tuple=preprocessing_exc_tuple,
2997 cell_id=cell_id,
2997 cell_id=cell_id,
2998 )
2998 )
2999
2999
3000 # run_cell_async is async, but may not actually need an eventloop.
3000 # run_cell_async is async, but may not actually need an eventloop.
3001 # when this is the case, we want to run it using the pseudo_sync_runner
3001 # when this is the case, we want to run it using the pseudo_sync_runner
3002 # so that code can invoke eventloops (for example via the %run , and
3002 # so that code can invoke eventloops (for example via the %run , and
3003 # `%paste` magic.
3003 # `%paste` magic.
3004 if self.trio_runner:
3004 if self.trio_runner:
3005 runner = self.trio_runner
3005 runner = self.trio_runner
3006 elif self.should_run_async(
3006 elif self.should_run_async(
3007 raw_cell,
3007 raw_cell,
3008 transformed_cell=transformed_cell,
3008 transformed_cell=transformed_cell,
3009 preprocessing_exc_tuple=preprocessing_exc_tuple,
3009 preprocessing_exc_tuple=preprocessing_exc_tuple,
3010 ):
3010 ):
3011 runner = self.loop_runner
3011 runner = self.loop_runner
3012 else:
3012 else:
3013 runner = _pseudo_sync_runner
3013 runner = _pseudo_sync_runner
3014
3014
3015 try:
3015 try:
3016 return runner(coro)
3016 result = runner(coro)
3017 except BaseException as e:
3017 except BaseException as e:
3018 info = ExecutionInfo(
3018 info = ExecutionInfo(
3019 raw_cell, store_history, silent, shell_futures, cell_id
3019 raw_cell, store_history, silent, shell_futures, cell_id
3020 )
3020 )
3021 result = ExecutionResult(info)
3021 result = ExecutionResult(info)
3022 result.error_in_exec = e
3022 result.error_in_exec = e
3023 self.showtraceback(running_compiled_code=True)
3023 self.showtraceback(running_compiled_code=True)
3024 finally:
3024 return result
3025 return result
3025
3026
3026 def should_run_async(
3027 def should_run_async(
3027 self, raw_cell: str, *, transformed_cell=None, preprocessing_exc_tuple=None
3028 self, raw_cell: str, *, transformed_cell=None, preprocessing_exc_tuple=None
3028 ) -> bool:
3029 ) -> bool:
3029 """Return whether a cell should be run asynchronously via a coroutine runner
3030 """Return whether a cell should be run asynchronously via a coroutine runner
3030
3031
3031 Parameters
3032 Parameters
3032 ----------
3033 ----------
3033 raw_cell : str
3034 raw_cell : str
3034 The code to be executed
3035 The code to be executed
3035
3036
3036 Returns
3037 Returns
3037 -------
3038 -------
3038 result: bool
3039 result: bool
3039 Whether the code needs to be run with a coroutine runner or not
3040 Whether the code needs to be run with a coroutine runner or not
3040 .. versionadded:: 7.0
3041 .. versionadded:: 7.0
3041 """
3042 """
3042 if not self.autoawait:
3043 if not self.autoawait:
3043 return False
3044 return False
3044 if preprocessing_exc_tuple is not None:
3045 if preprocessing_exc_tuple is not None:
3045 return False
3046 return False
3046 assert preprocessing_exc_tuple is None
3047 assert preprocessing_exc_tuple is None
3047 if transformed_cell is None:
3048 if transformed_cell is None:
3048 warnings.warn(
3049 warnings.warn(
3049 "`should_run_async` will not call `transform_cell`"
3050 "`should_run_async` will not call `transform_cell`"
3050 " automatically in the future. Please pass the result to"
3051 " automatically in the future. Please pass the result to"
3051 " `transformed_cell` argument and any exception that happen"
3052 " `transformed_cell` argument and any exception that happen"
3052 " during the"
3053 " during the"
3053 "transform in `preprocessing_exc_tuple` in"
3054 "transform in `preprocessing_exc_tuple` in"
3054 " IPython 7.17 and above.",
3055 " IPython 7.17 and above.",
3055 DeprecationWarning,
3056 DeprecationWarning,
3056 stacklevel=2,
3057 stacklevel=2,
3057 )
3058 )
3058 try:
3059 try:
3059 cell = self.transform_cell(raw_cell)
3060 cell = self.transform_cell(raw_cell)
3060 except Exception:
3061 except Exception:
3061 # any exception during transform will be raised
3062 # any exception during transform will be raised
3062 # prior to execution
3063 # prior to execution
3063 return False
3064 return False
3064 else:
3065 else:
3065 cell = transformed_cell
3066 cell = transformed_cell
3066 return _should_be_async(cell)
3067 return _should_be_async(cell)
3067
3068
3068 async def run_cell_async(
3069 async def run_cell_async(
3069 self,
3070 self,
3070 raw_cell: str,
3071 raw_cell: str,
3071 store_history=False,
3072 store_history=False,
3072 silent=False,
3073 silent=False,
3073 shell_futures=True,
3074 shell_futures=True,
3074 *,
3075 *,
3075 transformed_cell: Optional[str] = None,
3076 transformed_cell: Optional[str] = None,
3076 preprocessing_exc_tuple: Optional[Any] = None,
3077 preprocessing_exc_tuple: Optional[Any] = None,
3077 cell_id=None,
3078 cell_id=None,
3078 ) -> ExecutionResult:
3079 ) -> ExecutionResult:
3079 """Run a complete IPython cell asynchronously.
3080 """Run a complete IPython cell asynchronously.
3080
3081
3081 Parameters
3082 Parameters
3082 ----------
3083 ----------
3083 raw_cell : str
3084 raw_cell : str
3084 The code (including IPython code such as %magic functions) to run.
3085 The code (including IPython code such as %magic functions) to run.
3085 store_history : bool
3086 store_history : bool
3086 If True, the raw and translated cell will be stored in IPython's
3087 If True, the raw and translated cell will be stored in IPython's
3087 history. For user code calling back into IPython's machinery, this
3088 history. For user code calling back into IPython's machinery, this
3088 should be set to False.
3089 should be set to False.
3089 silent : bool
3090 silent : bool
3090 If True, avoid side-effects, such as implicit displayhooks and
3091 If True, avoid side-effects, such as implicit displayhooks and
3091 and logging. silent=True forces store_history=False.
3092 and logging. silent=True forces store_history=False.
3092 shell_futures : bool
3093 shell_futures : bool
3093 If True, the code will share future statements with the interactive
3094 If True, the code will share future statements with the interactive
3094 shell. It will both be affected by previous __future__ imports, and
3095 shell. It will both be affected by previous __future__ imports, and
3095 any __future__ imports in the code will affect the shell. If False,
3096 any __future__ imports in the code will affect the shell. If False,
3096 __future__ imports are not shared in either direction.
3097 __future__ imports are not shared in either direction.
3097 transformed_cell: str
3098 transformed_cell: str
3098 cell that was passed through transformers
3099 cell that was passed through transformers
3099 preprocessing_exc_tuple:
3100 preprocessing_exc_tuple:
3100 trace if the transformation failed.
3101 trace if the transformation failed.
3101
3102
3102 Returns
3103 Returns
3103 -------
3104 -------
3104 result : :class:`ExecutionResult`
3105 result : :class:`ExecutionResult`
3105
3106
3106 .. versionadded:: 7.0
3107 .. versionadded:: 7.0
3107 """
3108 """
3108 info = ExecutionInfo(raw_cell, store_history, silent, shell_futures, cell_id)
3109 info = ExecutionInfo(raw_cell, store_history, silent, shell_futures, cell_id)
3109 result = ExecutionResult(info)
3110 result = ExecutionResult(info)
3110
3111
3111 if (not raw_cell) or raw_cell.isspace():
3112 if (not raw_cell) or raw_cell.isspace():
3112 self.last_execution_succeeded = True
3113 self.last_execution_succeeded = True
3113 self.last_execution_result = result
3114 self.last_execution_result = result
3114 return result
3115 return result
3115
3116
3116 if silent:
3117 if silent:
3117 store_history = False
3118 store_history = False
3118
3119
3119 if store_history:
3120 if store_history:
3120 result.execution_count = self.execution_count
3121 result.execution_count = self.execution_count
3121
3122
3122 def error_before_exec(value):
3123 def error_before_exec(value):
3123 if store_history:
3124 if store_history:
3124 self.execution_count += 1
3125 self.execution_count += 1
3125 result.error_before_exec = value
3126 result.error_before_exec = value
3126 self.last_execution_succeeded = False
3127 self.last_execution_succeeded = False
3127 self.last_execution_result = result
3128 self.last_execution_result = result
3128 return result
3129 return result
3129
3130
3130 self.events.trigger('pre_execute')
3131 self.events.trigger('pre_execute')
3131 if not silent:
3132 if not silent:
3132 self.events.trigger('pre_run_cell', info)
3133 self.events.trigger('pre_run_cell', info)
3133
3134
3134 if transformed_cell is None:
3135 if transformed_cell is None:
3135 warnings.warn(
3136 warnings.warn(
3136 "`run_cell_async` will not call `transform_cell`"
3137 "`run_cell_async` will not call `transform_cell`"
3137 " automatically in the future. Please pass the result to"
3138 " automatically in the future. Please pass the result to"
3138 " `transformed_cell` argument and any exception that happen"
3139 " `transformed_cell` argument and any exception that happen"
3139 " during the"
3140 " during the"
3140 "transform in `preprocessing_exc_tuple` in"
3141 "transform in `preprocessing_exc_tuple` in"
3141 " IPython 7.17 and above.",
3142 " IPython 7.17 and above.",
3142 DeprecationWarning,
3143 DeprecationWarning,
3143 stacklevel=2,
3144 stacklevel=2,
3144 )
3145 )
3145 # If any of our input transformation (input_transformer_manager or
3146 # If any of our input transformation (input_transformer_manager or
3146 # prefilter_manager) raises an exception, we store it in this variable
3147 # prefilter_manager) raises an exception, we store it in this variable
3147 # so that we can display the error after logging the input and storing
3148 # so that we can display the error after logging the input and storing
3148 # it in the history.
3149 # it in the history.
3149 try:
3150 try:
3150 cell = self.transform_cell(raw_cell)
3151 cell = self.transform_cell(raw_cell)
3151 except Exception:
3152 except Exception:
3152 preprocessing_exc_tuple = sys.exc_info()
3153 preprocessing_exc_tuple = sys.exc_info()
3153 cell = raw_cell # cell has to exist so it can be stored/logged
3154 cell = raw_cell # cell has to exist so it can be stored/logged
3154 else:
3155 else:
3155 preprocessing_exc_tuple = None
3156 preprocessing_exc_tuple = None
3156 else:
3157 else:
3157 if preprocessing_exc_tuple is None:
3158 if preprocessing_exc_tuple is None:
3158 cell = transformed_cell
3159 cell = transformed_cell
3159 else:
3160 else:
3160 cell = raw_cell
3161 cell = raw_cell
3161
3162
3162 # Do NOT store paste/cpaste magic history
3163 # Do NOT store paste/cpaste magic history
3163 if "get_ipython().run_line_magic(" in cell and "paste" in cell:
3164 if "get_ipython().run_line_magic(" in cell and "paste" in cell:
3164 store_history = False
3165 store_history = False
3165
3166
3166 # Store raw and processed history
3167 # Store raw and processed history
3167 if store_history:
3168 if store_history:
3168 self.history_manager.store_inputs(self.execution_count, cell, raw_cell)
3169 self.history_manager.store_inputs(self.execution_count, cell, raw_cell)
3169 if not silent:
3170 if not silent:
3170 self.logger.log(cell, raw_cell)
3171 self.logger.log(cell, raw_cell)
3171
3172
3172 # Display the exception if input processing failed.
3173 # Display the exception if input processing failed.
3173 if preprocessing_exc_tuple is not None:
3174 if preprocessing_exc_tuple is not None:
3174 self.showtraceback(preprocessing_exc_tuple)
3175 self.showtraceback(preprocessing_exc_tuple)
3175 if store_history:
3176 if store_history:
3176 self.execution_count += 1
3177 self.execution_count += 1
3177 return error_before_exec(preprocessing_exc_tuple[1])
3178 return error_before_exec(preprocessing_exc_tuple[1])
3178
3179
3179 # Our own compiler remembers the __future__ environment. If we want to
3180 # Our own compiler remembers the __future__ environment. If we want to
3180 # run code with a separate __future__ environment, use the default
3181 # run code with a separate __future__ environment, use the default
3181 # compiler
3182 # compiler
3182 compiler = self.compile if shell_futures else self.compiler_class()
3183 compiler = self.compile if shell_futures else self.compiler_class()
3183
3184
3184 _run_async = False
3185 _run_async = False
3185
3186
3186 with self.builtin_trap:
3187 with self.builtin_trap:
3187 cell_name = compiler.cache(cell, self.execution_count, raw_code=raw_cell)
3188 cell_name = compiler.cache(cell, self.execution_count, raw_code=raw_cell)
3188
3189
3189 with self.display_trap:
3190 with self.display_trap:
3190 # Compile to bytecode
3191 # Compile to bytecode
3191 try:
3192 try:
3192 code_ast = compiler.ast_parse(cell, filename=cell_name)
3193 code_ast = compiler.ast_parse(cell, filename=cell_name)
3193 except self.custom_exceptions as e:
3194 except self.custom_exceptions as e:
3194 etype, value, tb = sys.exc_info()
3195 etype, value, tb = sys.exc_info()
3195 self.CustomTB(etype, value, tb)
3196 self.CustomTB(etype, value, tb)
3196 return error_before_exec(e)
3197 return error_before_exec(e)
3197 except IndentationError as e:
3198 except IndentationError as e:
3198 self.showindentationerror()
3199 self.showindentationerror()
3199 return error_before_exec(e)
3200 return error_before_exec(e)
3200 except (OverflowError, SyntaxError, ValueError, TypeError,
3201 except (OverflowError, SyntaxError, ValueError, TypeError,
3201 MemoryError) as e:
3202 MemoryError) as e:
3202 self.showsyntaxerror()
3203 self.showsyntaxerror()
3203 return error_before_exec(e)
3204 return error_before_exec(e)
3204
3205
3205 # Apply AST transformations
3206 # Apply AST transformations
3206 try:
3207 try:
3207 code_ast = self.transform_ast(code_ast)
3208 code_ast = self.transform_ast(code_ast)
3208 except InputRejected as e:
3209 except InputRejected as e:
3209 self.showtraceback()
3210 self.showtraceback()
3210 return error_before_exec(e)
3211 return error_before_exec(e)
3211
3212
3212 # Give the displayhook a reference to our ExecutionResult so it
3213 # Give the displayhook a reference to our ExecutionResult so it
3213 # can fill in the output value.
3214 # can fill in the output value.
3214 self.displayhook.exec_result = result
3215 self.displayhook.exec_result = result
3215
3216
3216 # Execute the user code
3217 # Execute the user code
3217 interactivity = "none" if silent else self.ast_node_interactivity
3218 interactivity = "none" if silent else self.ast_node_interactivity
3218
3219
3219
3220
3220 has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
3221 has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
3221 interactivity=interactivity, compiler=compiler, result=result)
3222 interactivity=interactivity, compiler=compiler, result=result)
3222
3223
3223 self.last_execution_succeeded = not has_raised
3224 self.last_execution_succeeded = not has_raised
3224 self.last_execution_result = result
3225 self.last_execution_result = result
3225
3226
3226 # Reset this so later displayed values do not modify the
3227 # Reset this so later displayed values do not modify the
3227 # ExecutionResult
3228 # ExecutionResult
3228 self.displayhook.exec_result = None
3229 self.displayhook.exec_result = None
3229
3230
3230 if store_history:
3231 if store_history:
3231 # Write output to the database. Does nothing unless
3232 # Write output to the database. Does nothing unless
3232 # history output logging is enabled.
3233 # history output logging is enabled.
3233 self.history_manager.store_output(self.execution_count)
3234 self.history_manager.store_output(self.execution_count)
3234 # Each cell is a *single* input, regardless of how many lines it has
3235 # Each cell is a *single* input, regardless of how many lines it has
3235 self.execution_count += 1
3236 self.execution_count += 1
3236
3237
3237 return result
3238 return result
3238
3239
3239 def transform_cell(self, raw_cell):
3240 def transform_cell(self, raw_cell):
3240 """Transform an input cell before parsing it.
3241 """Transform an input cell before parsing it.
3241
3242
3242 Static transformations, implemented in IPython.core.inputtransformer2,
3243 Static transformations, implemented in IPython.core.inputtransformer2,
3243 deal with things like ``%magic`` and ``!system`` commands.
3244 deal with things like ``%magic`` and ``!system`` commands.
3244 These run on all input.
3245 These run on all input.
3245 Dynamic transformations, for things like unescaped magics and the exit
3246 Dynamic transformations, for things like unescaped magics and the exit
3246 autocall, depend on the state of the interpreter.
3247 autocall, depend on the state of the interpreter.
3247 These only apply to single line inputs.
3248 These only apply to single line inputs.
3248
3249
3249 These string-based transformations are followed by AST transformations;
3250 These string-based transformations are followed by AST transformations;
3250 see :meth:`transform_ast`.
3251 see :meth:`transform_ast`.
3251 """
3252 """
3252 # Static input transformations
3253 # Static input transformations
3253 cell = self.input_transformer_manager.transform_cell(raw_cell)
3254 cell = self.input_transformer_manager.transform_cell(raw_cell)
3254
3255
3255 if len(cell.splitlines()) == 1:
3256 if len(cell.splitlines()) == 1:
3256 # Dynamic transformations - only applied for single line commands
3257 # Dynamic transformations - only applied for single line commands
3257 with self.builtin_trap:
3258 with self.builtin_trap:
3258 # use prefilter_lines to handle trailing newlines
3259 # use prefilter_lines to handle trailing newlines
3259 # restore trailing newline for ast.parse
3260 # restore trailing newline for ast.parse
3260 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
3261 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
3261
3262
3262 lines = cell.splitlines(keepends=True)
3263 lines = cell.splitlines(keepends=True)
3263 for transform in self.input_transformers_post:
3264 for transform in self.input_transformers_post:
3264 lines = transform(lines)
3265 lines = transform(lines)
3265 cell = ''.join(lines)
3266 cell = ''.join(lines)
3266
3267
3267 return cell
3268 return cell
3268
3269
3269 def transform_ast(self, node):
3270 def transform_ast(self, node):
3270 """Apply the AST transformations from self.ast_transformers
3271 """Apply the AST transformations from self.ast_transformers
3271
3272
3272 Parameters
3273 Parameters
3273 ----------
3274 ----------
3274 node : ast.Node
3275 node : ast.Node
3275 The root node to be transformed. Typically called with the ast.Module
3276 The root node to be transformed. Typically called with the ast.Module
3276 produced by parsing user input.
3277 produced by parsing user input.
3277
3278
3278 Returns
3279 Returns
3279 -------
3280 -------
3280 An ast.Node corresponding to the node it was called with. Note that it
3281 An ast.Node corresponding to the node it was called with. Note that it
3281 may also modify the passed object, so don't rely on references to the
3282 may also modify the passed object, so don't rely on references to the
3282 original AST.
3283 original AST.
3283 """
3284 """
3284 for transformer in self.ast_transformers:
3285 for transformer in self.ast_transformers:
3285 try:
3286 try:
3286 node = transformer.visit(node)
3287 node = transformer.visit(node)
3287 except InputRejected:
3288 except InputRejected:
3288 # User-supplied AST transformers can reject an input by raising
3289 # User-supplied AST transformers can reject an input by raising
3289 # an InputRejected. Short-circuit in this case so that we
3290 # an InputRejected. Short-circuit in this case so that we
3290 # don't unregister the transform.
3291 # don't unregister the transform.
3291 raise
3292 raise
3292 except Exception:
3293 except Exception:
3293 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
3294 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
3294 self.ast_transformers.remove(transformer)
3295 self.ast_transformers.remove(transformer)
3295
3296
3296 if self.ast_transformers:
3297 if self.ast_transformers:
3297 ast.fix_missing_locations(node)
3298 ast.fix_missing_locations(node)
3298 return node
3299 return node
3299
3300
3300 async def run_ast_nodes(
3301 async def run_ast_nodes(
3301 self,
3302 self,
3302 nodelist: ListType[stmt],
3303 nodelist: ListType[stmt],
3303 cell_name: str,
3304 cell_name: str,
3304 interactivity="last_expr",
3305 interactivity="last_expr",
3305 compiler=compile,
3306 compiler=compile,
3306 result=None,
3307 result=None,
3307 ):
3308 ):
3308 """Run a sequence of AST nodes. The execution mode depends on the
3309 """Run a sequence of AST nodes. The execution mode depends on the
3309 interactivity parameter.
3310 interactivity parameter.
3310
3311
3311 Parameters
3312 Parameters
3312 ----------
3313 ----------
3313 nodelist : list
3314 nodelist : list
3314 A sequence of AST nodes to run.
3315 A sequence of AST nodes to run.
3315 cell_name : str
3316 cell_name : str
3316 Will be passed to the compiler as the filename of the cell. Typically
3317 Will be passed to the compiler as the filename of the cell. Typically
3317 the value returned by ip.compile.cache(cell).
3318 the value returned by ip.compile.cache(cell).
3318 interactivity : str
3319 interactivity : str
3319 'all', 'last', 'last_expr' , 'last_expr_or_assign' or 'none',
3320 'all', 'last', 'last_expr' , 'last_expr_or_assign' or 'none',
3320 specifying which nodes should be run interactively (displaying output
3321 specifying which nodes should be run interactively (displaying output
3321 from expressions). 'last_expr' will run the last node interactively
3322 from expressions). 'last_expr' will run the last node interactively
3322 only if it is an expression (i.e. expressions in loops or other blocks
3323 only if it is an expression (i.e. expressions in loops or other blocks
3323 are not displayed) 'last_expr_or_assign' will run the last expression
3324 are not displayed) 'last_expr_or_assign' will run the last expression
3324 or the last assignment. Other values for this parameter will raise a
3325 or the last assignment. Other values for this parameter will raise a
3325 ValueError.
3326 ValueError.
3326
3327
3327 compiler : callable
3328 compiler : callable
3328 A function with the same interface as the built-in compile(), to turn
3329 A function with the same interface as the built-in compile(), to turn
3329 the AST nodes into code objects. Default is the built-in compile().
3330 the AST nodes into code objects. Default is the built-in compile().
3330 result : ExecutionResult, optional
3331 result : ExecutionResult, optional
3331 An object to store exceptions that occur during execution.
3332 An object to store exceptions that occur during execution.
3332
3333
3333 Returns
3334 Returns
3334 -------
3335 -------
3335 True if an exception occurred while running code, False if it finished
3336 True if an exception occurred while running code, False if it finished
3336 running.
3337 running.
3337 """
3338 """
3338 if not nodelist:
3339 if not nodelist:
3339 return
3340 return
3340
3341
3341
3342
3342 if interactivity == 'last_expr_or_assign':
3343 if interactivity == 'last_expr_or_assign':
3343 if isinstance(nodelist[-1], _assign_nodes):
3344 if isinstance(nodelist[-1], _assign_nodes):
3344 asg = nodelist[-1]
3345 asg = nodelist[-1]
3345 if isinstance(asg, ast.Assign) and len(asg.targets) == 1:
3346 if isinstance(asg, ast.Assign) and len(asg.targets) == 1:
3346 target = asg.targets[0]
3347 target = asg.targets[0]
3347 elif isinstance(asg, _single_targets_nodes):
3348 elif isinstance(asg, _single_targets_nodes):
3348 target = asg.target
3349 target = asg.target
3349 else:
3350 else:
3350 target = None
3351 target = None
3351 if isinstance(target, ast.Name):
3352 if isinstance(target, ast.Name):
3352 nnode = ast.Expr(ast.Name(target.id, ast.Load()))
3353 nnode = ast.Expr(ast.Name(target.id, ast.Load()))
3353 ast.fix_missing_locations(nnode)
3354 ast.fix_missing_locations(nnode)
3354 nodelist.append(nnode)
3355 nodelist.append(nnode)
3355 interactivity = 'last_expr'
3356 interactivity = 'last_expr'
3356
3357
3357 _async = False
3358 _async = False
3358 if interactivity == 'last_expr':
3359 if interactivity == 'last_expr':
3359 if isinstance(nodelist[-1], ast.Expr):
3360 if isinstance(nodelist[-1], ast.Expr):
3360 interactivity = "last"
3361 interactivity = "last"
3361 else:
3362 else:
3362 interactivity = "none"
3363 interactivity = "none"
3363
3364
3364 if interactivity == 'none':
3365 if interactivity == 'none':
3365 to_run_exec, to_run_interactive = nodelist, []
3366 to_run_exec, to_run_interactive = nodelist, []
3366 elif interactivity == 'last':
3367 elif interactivity == 'last':
3367 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
3368 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
3368 elif interactivity == 'all':
3369 elif interactivity == 'all':
3369 to_run_exec, to_run_interactive = [], nodelist
3370 to_run_exec, to_run_interactive = [], nodelist
3370 else:
3371 else:
3371 raise ValueError("Interactivity was %r" % interactivity)
3372 raise ValueError("Interactivity was %r" % interactivity)
3372
3373
3373 try:
3374 try:
3374
3375
3375 def compare(code):
3376 def compare(code):
3376 is_async = inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE
3377 is_async = inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE
3377 return is_async
3378 return is_async
3378
3379
3379 # refactor that to just change the mod constructor.
3380 # refactor that to just change the mod constructor.
3380 to_run = []
3381 to_run = []
3381 for node in to_run_exec:
3382 for node in to_run_exec:
3382 to_run.append((node, "exec"))
3383 to_run.append((node, "exec"))
3383
3384
3384 for node in to_run_interactive:
3385 for node in to_run_interactive:
3385 to_run.append((node, "single"))
3386 to_run.append((node, "single"))
3386
3387
3387 for node, mode in to_run:
3388 for node, mode in to_run:
3388 if mode == "exec":
3389 if mode == "exec":
3389 mod = Module([node], [])
3390 mod = Module([node], [])
3390 elif mode == "single":
3391 elif mode == "single":
3391 mod = ast.Interactive([node])
3392 mod = ast.Interactive([node])
3392 with compiler.extra_flags(
3393 with compiler.extra_flags(
3393 getattr(ast, "PyCF_ALLOW_TOP_LEVEL_AWAIT", 0x0)
3394 getattr(ast, "PyCF_ALLOW_TOP_LEVEL_AWAIT", 0x0)
3394 if self.autoawait
3395 if self.autoawait
3395 else 0x0
3396 else 0x0
3396 ):
3397 ):
3397 code = compiler(mod, cell_name, mode)
3398 code = compiler(mod, cell_name, mode)
3398 asy = compare(code)
3399 asy = compare(code)
3399 if await self.run_code(code, result, async_=asy):
3400 if await self.run_code(code, result, async_=asy):
3400 return True
3401 return True
3401
3402
3402 # Flush softspace
3403 # Flush softspace
3403 if softspace(sys.stdout, 0):
3404 if softspace(sys.stdout, 0):
3404 print()
3405 print()
3405
3406
3406 except:
3407 except:
3407 # It's possible to have exceptions raised here, typically by
3408 # It's possible to have exceptions raised here, typically by
3408 # compilation of odd code (such as a naked 'return' outside a
3409 # compilation of odd code (such as a naked 'return' outside a
3409 # function) that did parse but isn't valid. Typically the exception
3410 # function) that did parse but isn't valid. Typically the exception
3410 # is a SyntaxError, but it's safest just to catch anything and show
3411 # is a SyntaxError, but it's safest just to catch anything and show
3411 # the user a traceback.
3412 # the user a traceback.
3412
3413
3413 # We do only one try/except outside the loop to minimize the impact
3414 # We do only one try/except outside the loop to minimize the impact
3414 # on runtime, and also because if any node in the node list is
3415 # on runtime, and also because if any node in the node list is
3415 # broken, we should stop execution completely.
3416 # broken, we should stop execution completely.
3416 if result:
3417 if result:
3417 result.error_before_exec = sys.exc_info()[1]
3418 result.error_before_exec = sys.exc_info()[1]
3418 self.showtraceback()
3419 self.showtraceback()
3419 return True
3420 return True
3420
3421
3421 return False
3422 return False
3422
3423
3423 async def run_code(self, code_obj, result=None, *, async_=False):
3424 async def run_code(self, code_obj, result=None, *, async_=False):
3424 """Execute a code object.
3425 """Execute a code object.
3425
3426
3426 When an exception occurs, self.showtraceback() is called to display a
3427 When an exception occurs, self.showtraceback() is called to display a
3427 traceback.
3428 traceback.
3428
3429
3429 Parameters
3430 Parameters
3430 ----------
3431 ----------
3431 code_obj : code object
3432 code_obj : code object
3432 A compiled code object, to be executed
3433 A compiled code object, to be executed
3433 result : ExecutionResult, optional
3434 result : ExecutionResult, optional
3434 An object to store exceptions that occur during execution.
3435 An object to store exceptions that occur during execution.
3435 async_ : Bool (Experimental)
3436 async_ : Bool (Experimental)
3436 Attempt to run top-level asynchronous code in a default loop.
3437 Attempt to run top-level asynchronous code in a default loop.
3437
3438
3438 Returns
3439 Returns
3439 -------
3440 -------
3440 False : successful execution.
3441 False : successful execution.
3441 True : an error occurred.
3442 True : an error occurred.
3442 """
3443 """
3443 # special value to say that anything above is IPython and should be
3444 # special value to say that anything above is IPython and should be
3444 # hidden.
3445 # hidden.
3445 __tracebackhide__ = "__ipython_bottom__"
3446 __tracebackhide__ = "__ipython_bottom__"
3446 # Set our own excepthook in case the user code tries to call it
3447 # Set our own excepthook in case the user code tries to call it
3447 # directly, so that the IPython crash handler doesn't get triggered
3448 # directly, so that the IPython crash handler doesn't get triggered
3448 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3449 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3449
3450
3450 # we save the original sys.excepthook in the instance, in case config
3451 # we save the original sys.excepthook in the instance, in case config
3451 # code (such as magics) needs access to it.
3452 # code (such as magics) needs access to it.
3452 self.sys_excepthook = old_excepthook
3453 self.sys_excepthook = old_excepthook
3453 outflag = True # happens in more places, so it's easier as default
3454 outflag = True # happens in more places, so it's easier as default
3454 try:
3455 try:
3455 try:
3456 try:
3456 if async_:
3457 if async_:
3457 await eval(code_obj, self.user_global_ns, self.user_ns)
3458 await eval(code_obj, self.user_global_ns, self.user_ns)
3458 else:
3459 else:
3459 exec(code_obj, self.user_global_ns, self.user_ns)
3460 exec(code_obj, self.user_global_ns, self.user_ns)
3460 finally:
3461 finally:
3461 # Reset our crash handler in place
3462 # Reset our crash handler in place
3462 sys.excepthook = old_excepthook
3463 sys.excepthook = old_excepthook
3463 except SystemExit as e:
3464 except SystemExit as e:
3464 if result is not None:
3465 if result is not None:
3465 result.error_in_exec = e
3466 result.error_in_exec = e
3466 self.showtraceback(exception_only=True)
3467 self.showtraceback(exception_only=True)
3467 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
3468 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
3468 except bdb.BdbQuit:
3469 except bdb.BdbQuit:
3469 etype, value, tb = sys.exc_info()
3470 etype, value, tb = sys.exc_info()
3470 if result is not None:
3471 if result is not None:
3471 result.error_in_exec = value
3472 result.error_in_exec = value
3472 # the BdbQuit stops here
3473 # the BdbQuit stops here
3473 except self.custom_exceptions:
3474 except self.custom_exceptions:
3474 etype, value, tb = sys.exc_info()
3475 etype, value, tb = sys.exc_info()
3475 if result is not None:
3476 if result is not None:
3476 result.error_in_exec = value
3477 result.error_in_exec = value
3477 self.CustomTB(etype, value, tb)
3478 self.CustomTB(etype, value, tb)
3478 except:
3479 except:
3479 if result is not None:
3480 if result is not None:
3480 result.error_in_exec = sys.exc_info()[1]
3481 result.error_in_exec = sys.exc_info()[1]
3481 self.showtraceback(running_compiled_code=True)
3482 self.showtraceback(running_compiled_code=True)
3482 else:
3483 else:
3483 outflag = False
3484 outflag = False
3484 return outflag
3485 return outflag
3485
3486
3486 # For backwards compatibility
3487 # For backwards compatibility
3487 runcode = run_code
3488 runcode = run_code
3488
3489
3489 def check_complete(self, code: str) -> Tuple[str, str]:
3490 def check_complete(self, code: str) -> Tuple[str, str]:
3490 """Return whether a block of code is ready to execute, or should be continued
3491 """Return whether a block of code is ready to execute, or should be continued
3491
3492
3492 Parameters
3493 Parameters
3493 ----------
3494 ----------
3494 code : string
3495 code : string
3495 Python input code, which can be multiline.
3496 Python input code, which can be multiline.
3496
3497
3497 Returns
3498 Returns
3498 -------
3499 -------
3499 status : str
3500 status : str
3500 One of 'complete', 'incomplete', or 'invalid' if source is not a
3501 One of 'complete', 'incomplete', or 'invalid' if source is not a
3501 prefix of valid code.
3502 prefix of valid code.
3502 indent : str
3503 indent : str
3503 When status is 'incomplete', this is some whitespace to insert on
3504 When status is 'incomplete', this is some whitespace to insert on
3504 the next line of the prompt.
3505 the next line of the prompt.
3505 """
3506 """
3506 status, nspaces = self.input_transformer_manager.check_complete(code)
3507 status, nspaces = self.input_transformer_manager.check_complete(code)
3507 return status, ' ' * (nspaces or 0)
3508 return status, ' ' * (nspaces or 0)
3508
3509
3509 #-------------------------------------------------------------------------
3510 #-------------------------------------------------------------------------
3510 # Things related to GUI support and pylab
3511 # Things related to GUI support and pylab
3511 #-------------------------------------------------------------------------
3512 #-------------------------------------------------------------------------
3512
3513
3513 active_eventloop = None
3514 active_eventloop = None
3514
3515
3515 def enable_gui(self, gui=None):
3516 def enable_gui(self, gui=None):
3516 raise NotImplementedError('Implement enable_gui in a subclass')
3517 raise NotImplementedError('Implement enable_gui in a subclass')
3517
3518
3518 def enable_matplotlib(self, gui=None):
3519 def enable_matplotlib(self, gui=None):
3519 """Enable interactive matplotlib and inline figure support.
3520 """Enable interactive matplotlib and inline figure support.
3520
3521
3521 This takes the following steps:
3522 This takes the following steps:
3522
3523
3523 1. select the appropriate eventloop and matplotlib backend
3524 1. select the appropriate eventloop and matplotlib backend
3524 2. set up matplotlib for interactive use with that backend
3525 2. set up matplotlib for interactive use with that backend
3525 3. configure formatters for inline figure display
3526 3. configure formatters for inline figure display
3526 4. enable the selected gui eventloop
3527 4. enable the selected gui eventloop
3527
3528
3528 Parameters
3529 Parameters
3529 ----------
3530 ----------
3530 gui : optional, string
3531 gui : optional, string
3531 If given, dictates the choice of matplotlib GUI backend to use
3532 If given, dictates the choice of matplotlib GUI backend to use
3532 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3533 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3533 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3534 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3534 matplotlib (as dictated by the matplotlib build-time options plus the
3535 matplotlib (as dictated by the matplotlib build-time options plus the
3535 user's matplotlibrc configuration file). Note that not all backends
3536 user's matplotlibrc configuration file). Note that not all backends
3536 make sense in all contexts, for example a terminal ipython can't
3537 make sense in all contexts, for example a terminal ipython can't
3537 display figures inline.
3538 display figures inline.
3538 """
3539 """
3539 from matplotlib_inline.backend_inline import configure_inline_support
3540 from matplotlib_inline.backend_inline import configure_inline_support
3540
3541
3541 from IPython.core import pylabtools as pt
3542 from IPython.core import pylabtools as pt
3542 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3543 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3543
3544
3544 if gui != 'inline':
3545 if gui != 'inline':
3545 # If we have our first gui selection, store it
3546 # If we have our first gui selection, store it
3546 if self.pylab_gui_select is None:
3547 if self.pylab_gui_select is None:
3547 self.pylab_gui_select = gui
3548 self.pylab_gui_select = gui
3548 # Otherwise if they are different
3549 # Otherwise if they are different
3549 elif gui != self.pylab_gui_select:
3550 elif gui != self.pylab_gui_select:
3550 print('Warning: Cannot change to a different GUI toolkit: %s.'
3551 print('Warning: Cannot change to a different GUI toolkit: %s.'
3551 ' Using %s instead.' % (gui, self.pylab_gui_select))
3552 ' Using %s instead.' % (gui, self.pylab_gui_select))
3552 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3553 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3553
3554
3554 pt.activate_matplotlib(backend)
3555 pt.activate_matplotlib(backend)
3555 configure_inline_support(self, backend)
3556 configure_inline_support(self, backend)
3556
3557
3557 # Now we must activate the gui pylab wants to use, and fix %run to take
3558 # Now we must activate the gui pylab wants to use, and fix %run to take
3558 # plot updates into account
3559 # plot updates into account
3559 self.enable_gui(gui)
3560 self.enable_gui(gui)
3560 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3561 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3561 pt.mpl_runner(self.safe_execfile)
3562 pt.mpl_runner(self.safe_execfile)
3562
3563
3563 return gui, backend
3564 return gui, backend
3564
3565
3565 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3566 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3566 """Activate pylab support at runtime.
3567 """Activate pylab support at runtime.
3567
3568
3568 This turns on support for matplotlib, preloads into the interactive
3569 This turns on support for matplotlib, preloads into the interactive
3569 namespace all of numpy and pylab, and configures IPython to correctly
3570 namespace all of numpy and pylab, and configures IPython to correctly
3570 interact with the GUI event loop. The GUI backend to be used can be
3571 interact with the GUI event loop. The GUI backend to be used can be
3571 optionally selected with the optional ``gui`` argument.
3572 optionally selected with the optional ``gui`` argument.
3572
3573
3573 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3574 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3574
3575
3575 Parameters
3576 Parameters
3576 ----------
3577 ----------
3577 gui : optional, string
3578 gui : optional, string
3578 If given, dictates the choice of matplotlib GUI backend to use
3579 If given, dictates the choice of matplotlib GUI backend to use
3579 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3580 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3580 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3581 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3581 matplotlib (as dictated by the matplotlib build-time options plus the
3582 matplotlib (as dictated by the matplotlib build-time options plus the
3582 user's matplotlibrc configuration file). Note that not all backends
3583 user's matplotlibrc configuration file). Note that not all backends
3583 make sense in all contexts, for example a terminal ipython can't
3584 make sense in all contexts, for example a terminal ipython can't
3584 display figures inline.
3585 display figures inline.
3585 import_all : optional, bool, default: True
3586 import_all : optional, bool, default: True
3586 Whether to do `from numpy import *` and `from pylab import *`
3587 Whether to do `from numpy import *` and `from pylab import *`
3587 in addition to module imports.
3588 in addition to module imports.
3588 welcome_message : deprecated
3589 welcome_message : deprecated
3589 This argument is ignored, no welcome message will be displayed.
3590 This argument is ignored, no welcome message will be displayed.
3590 """
3591 """
3591 from IPython.core.pylabtools import import_pylab
3592 from IPython.core.pylabtools import import_pylab
3592
3593
3593 gui, backend = self.enable_matplotlib(gui)
3594 gui, backend = self.enable_matplotlib(gui)
3594
3595
3595 # We want to prevent the loading of pylab to pollute the user's
3596 # We want to prevent the loading of pylab to pollute the user's
3596 # namespace as shown by the %who* magics, so we execute the activation
3597 # namespace as shown by the %who* magics, so we execute the activation
3597 # code in an empty namespace, and we update *both* user_ns and
3598 # code in an empty namespace, and we update *both* user_ns and
3598 # user_ns_hidden with this information.
3599 # user_ns_hidden with this information.
3599 ns = {}
3600 ns = {}
3600 import_pylab(ns, import_all)
3601 import_pylab(ns, import_all)
3601 # warn about clobbered names
3602 # warn about clobbered names
3602 ignored = {"__builtins__"}
3603 ignored = {"__builtins__"}
3603 both = set(ns).intersection(self.user_ns).difference(ignored)
3604 both = set(ns).intersection(self.user_ns).difference(ignored)
3604 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3605 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3605 self.user_ns.update(ns)
3606 self.user_ns.update(ns)
3606 self.user_ns_hidden.update(ns)
3607 self.user_ns_hidden.update(ns)
3607 return gui, backend, clobbered
3608 return gui, backend, clobbered
3608
3609
3609 #-------------------------------------------------------------------------
3610 #-------------------------------------------------------------------------
3610 # Utilities
3611 # Utilities
3611 #-------------------------------------------------------------------------
3612 #-------------------------------------------------------------------------
3612
3613
3613 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3614 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3614 """Expand python variables in a string.
3615 """Expand python variables in a string.
3615
3616
3616 The depth argument indicates how many frames above the caller should
3617 The depth argument indicates how many frames above the caller should
3617 be walked to look for the local namespace where to expand variables.
3618 be walked to look for the local namespace where to expand variables.
3618
3619
3619 The global namespace for expansion is always the user's interactive
3620 The global namespace for expansion is always the user's interactive
3620 namespace.
3621 namespace.
3621 """
3622 """
3622 ns = self.user_ns.copy()
3623 ns = self.user_ns.copy()
3623 try:
3624 try:
3624 frame = sys._getframe(depth+1)
3625 frame = sys._getframe(depth+1)
3625 except ValueError:
3626 except ValueError:
3626 # This is thrown if there aren't that many frames on the stack,
3627 # This is thrown if there aren't that many frames on the stack,
3627 # e.g. if a script called run_line_magic() directly.
3628 # e.g. if a script called run_line_magic() directly.
3628 pass
3629 pass
3629 else:
3630 else:
3630 ns.update(frame.f_locals)
3631 ns.update(frame.f_locals)
3631
3632
3632 try:
3633 try:
3633 # We have to use .vformat() here, because 'self' is a valid and common
3634 # We have to use .vformat() here, because 'self' is a valid and common
3634 # name, and expanding **ns for .format() would make it collide with
3635 # name, and expanding **ns for .format() would make it collide with
3635 # the 'self' argument of the method.
3636 # the 'self' argument of the method.
3636 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3637 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3637 except Exception:
3638 except Exception:
3638 # if formatter couldn't format, just let it go untransformed
3639 # if formatter couldn't format, just let it go untransformed
3639 pass
3640 pass
3640 return cmd
3641 return cmd
3641
3642
3642 def mktempfile(self, data=None, prefix='ipython_edit_'):
3643 def mktempfile(self, data=None, prefix='ipython_edit_'):
3643 """Make a new tempfile and return its filename.
3644 """Make a new tempfile and return its filename.
3644
3645
3645 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3646 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3646 but it registers the created filename internally so ipython cleans it up
3647 but it registers the created filename internally so ipython cleans it up
3647 at exit time.
3648 at exit time.
3648
3649
3649 Optional inputs:
3650 Optional inputs:
3650
3651
3651 - data(None): if data is given, it gets written out to the temp file
3652 - data(None): if data is given, it gets written out to the temp file
3652 immediately, and the file is closed again."""
3653 immediately, and the file is closed again."""
3653
3654
3654 dir_path = Path(tempfile.mkdtemp(prefix=prefix))
3655 dir_path = Path(tempfile.mkdtemp(prefix=prefix))
3655 self.tempdirs.append(dir_path)
3656 self.tempdirs.append(dir_path)
3656
3657
3657 handle, filename = tempfile.mkstemp(".py", prefix, dir=str(dir_path))
3658 handle, filename = tempfile.mkstemp(".py", prefix, dir=str(dir_path))
3658 os.close(handle) # On Windows, there can only be one open handle on a file
3659 os.close(handle) # On Windows, there can only be one open handle on a file
3659
3660
3660 file_path = Path(filename)
3661 file_path = Path(filename)
3661 self.tempfiles.append(file_path)
3662 self.tempfiles.append(file_path)
3662
3663
3663 if data:
3664 if data:
3664 file_path.write_text(data, encoding="utf-8")
3665 file_path.write_text(data, encoding="utf-8")
3665 return filename
3666 return filename
3666
3667
3667 def ask_yes_no(self, prompt, default=None, interrupt=None):
3668 def ask_yes_no(self, prompt, default=None, interrupt=None):
3668 if self.quiet:
3669 if self.quiet:
3669 return True
3670 return True
3670 return ask_yes_no(prompt,default,interrupt)
3671 return ask_yes_no(prompt,default,interrupt)
3671
3672
3672 def show_usage(self):
3673 def show_usage(self):
3673 """Show a usage message"""
3674 """Show a usage message"""
3674 page.page(IPython.core.usage.interactive_usage)
3675 page.page(IPython.core.usage.interactive_usage)
3675
3676
3676 def extract_input_lines(self, range_str, raw=False):
3677 def extract_input_lines(self, range_str, raw=False):
3677 """Return as a string a set of input history slices.
3678 """Return as a string a set of input history slices.
3678
3679
3679 Parameters
3680 Parameters
3680 ----------
3681 ----------
3681 range_str : str
3682 range_str : str
3682 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3683 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3683 since this function is for use by magic functions which get their
3684 since this function is for use by magic functions which get their
3684 arguments as strings. The number before the / is the session
3685 arguments as strings. The number before the / is the session
3685 number: ~n goes n back from the current session.
3686 number: ~n goes n back from the current session.
3686
3687
3687 If empty string is given, returns history of current session
3688 If empty string is given, returns history of current session
3688 without the last input.
3689 without the last input.
3689
3690
3690 raw : bool, optional
3691 raw : bool, optional
3691 By default, the processed input is used. If this is true, the raw
3692 By default, the processed input is used. If this is true, the raw
3692 input history is used instead.
3693 input history is used instead.
3693
3694
3694 Notes
3695 Notes
3695 -----
3696 -----
3696 Slices can be described with two notations:
3697 Slices can be described with two notations:
3697
3698
3698 * ``N:M`` -> standard python form, means including items N...(M-1).
3699 * ``N:M`` -> standard python form, means including items N...(M-1).
3699 * ``N-M`` -> include items N..M (closed endpoint).
3700 * ``N-M`` -> include items N..M (closed endpoint).
3700 """
3701 """
3701 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3702 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3702 text = "\n".join(x for _, _, x in lines)
3703 text = "\n".join(x for _, _, x in lines)
3703
3704
3704 # Skip the last line, as it's probably the magic that called this
3705 # Skip the last line, as it's probably the magic that called this
3705 if not range_str:
3706 if not range_str:
3706 if "\n" not in text:
3707 if "\n" not in text:
3707 text = ""
3708 text = ""
3708 else:
3709 else:
3709 text = text[: text.rfind("\n")]
3710 text = text[: text.rfind("\n")]
3710
3711
3711 return text
3712 return text
3712
3713
3713 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3714 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3714 """Get a code string from history, file, url, or a string or macro.
3715 """Get a code string from history, file, url, or a string or macro.
3715
3716
3716 This is mainly used by magic functions.
3717 This is mainly used by magic functions.
3717
3718
3718 Parameters
3719 Parameters
3719 ----------
3720 ----------
3720 target : str
3721 target : str
3721 A string specifying code to retrieve. This will be tried respectively
3722 A string specifying code to retrieve. This will be tried respectively
3722 as: ranges of input history (see %history for syntax), url,
3723 as: ranges of input history (see %history for syntax), url,
3723 corresponding .py file, filename, or an expression evaluating to a
3724 corresponding .py file, filename, or an expression evaluating to a
3724 string or Macro in the user namespace.
3725 string or Macro in the user namespace.
3725
3726
3726 If empty string is given, returns complete history of current
3727 If empty string is given, returns complete history of current
3727 session, without the last line.
3728 session, without the last line.
3728
3729
3729 raw : bool
3730 raw : bool
3730 If true (default), retrieve raw history. Has no effect on the other
3731 If true (default), retrieve raw history. Has no effect on the other
3731 retrieval mechanisms.
3732 retrieval mechanisms.
3732
3733
3733 py_only : bool (default False)
3734 py_only : bool (default False)
3734 Only try to fetch python code, do not try alternative methods to decode file
3735 Only try to fetch python code, do not try alternative methods to decode file
3735 if unicode fails.
3736 if unicode fails.
3736
3737
3737 Returns
3738 Returns
3738 -------
3739 -------
3739 A string of code.
3740 A string of code.
3740 ValueError is raised if nothing is found, and TypeError if it evaluates
3741 ValueError is raised if nothing is found, and TypeError if it evaluates
3741 to an object of another type. In each case, .args[0] is a printable
3742 to an object of another type. In each case, .args[0] is a printable
3742 message.
3743 message.
3743 """
3744 """
3744 code = self.extract_input_lines(target, raw=raw) # Grab history
3745 code = self.extract_input_lines(target, raw=raw) # Grab history
3745 if code:
3746 if code:
3746 return code
3747 return code
3747 try:
3748 try:
3748 if target.startswith(('http://', 'https://')):
3749 if target.startswith(('http://', 'https://')):
3749 return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
3750 return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
3750 except UnicodeDecodeError as e:
3751 except UnicodeDecodeError as e:
3751 if not py_only :
3752 if not py_only :
3752 # Deferred import
3753 # Deferred import
3753 from urllib.request import urlopen
3754 from urllib.request import urlopen
3754 response = urlopen(target)
3755 response = urlopen(target)
3755 return response.read().decode('latin1')
3756 return response.read().decode('latin1')
3756 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3757 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3757
3758
3758 potential_target = [target]
3759 potential_target = [target]
3759 try :
3760 try :
3760 potential_target.insert(0,get_py_filename(target))
3761 potential_target.insert(0,get_py_filename(target))
3761 except IOError:
3762 except IOError:
3762 pass
3763 pass
3763
3764
3764 for tgt in potential_target :
3765 for tgt in potential_target :
3765 if os.path.isfile(tgt): # Read file
3766 if os.path.isfile(tgt): # Read file
3766 try :
3767 try :
3767 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3768 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3768 except UnicodeDecodeError as e:
3769 except UnicodeDecodeError as e:
3769 if not py_only :
3770 if not py_only :
3770 with io_open(tgt,'r', encoding='latin1') as f :
3771 with io_open(tgt,'r', encoding='latin1') as f :
3771 return f.read()
3772 return f.read()
3772 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3773 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3773 elif os.path.isdir(os.path.expanduser(tgt)):
3774 elif os.path.isdir(os.path.expanduser(tgt)):
3774 raise ValueError("'%s' is a directory, not a regular file." % target)
3775 raise ValueError("'%s' is a directory, not a regular file." % target)
3775
3776
3776 if search_ns:
3777 if search_ns:
3777 # Inspect namespace to load object source
3778 # Inspect namespace to load object source
3778 object_info = self.object_inspect(target, detail_level=1)
3779 object_info = self.object_inspect(target, detail_level=1)
3779 if object_info['found'] and object_info['source']:
3780 if object_info['found'] and object_info['source']:
3780 return object_info['source']
3781 return object_info['source']
3781
3782
3782 try: # User namespace
3783 try: # User namespace
3783 codeobj = eval(target, self.user_ns)
3784 codeobj = eval(target, self.user_ns)
3784 except Exception as e:
3785 except Exception as e:
3785 raise ValueError(("'%s' was not found in history, as a file, url, "
3786 raise ValueError(("'%s' was not found in history, as a file, url, "
3786 "nor in the user namespace.") % target) from e
3787 "nor in the user namespace.") % target) from e
3787
3788
3788 if isinstance(codeobj, str):
3789 if isinstance(codeobj, str):
3789 return codeobj
3790 return codeobj
3790 elif isinstance(codeobj, Macro):
3791 elif isinstance(codeobj, Macro):
3791 return codeobj.value
3792 return codeobj.value
3792
3793
3793 raise TypeError("%s is neither a string nor a macro." % target,
3794 raise TypeError("%s is neither a string nor a macro." % target,
3794 codeobj)
3795 codeobj)
3795
3796
3796 def _atexit_once(self):
3797 def _atexit_once(self):
3797 """
3798 """
3798 At exist operation that need to be called at most once.
3799 At exist operation that need to be called at most once.
3799 Second call to this function per instance will do nothing.
3800 Second call to this function per instance will do nothing.
3800 """
3801 """
3801
3802
3802 if not getattr(self, "_atexit_once_called", False):
3803 if not getattr(self, "_atexit_once_called", False):
3803 self._atexit_once_called = True
3804 self._atexit_once_called = True
3804 # Clear all user namespaces to release all references cleanly.
3805 # Clear all user namespaces to release all references cleanly.
3805 self.reset(new_session=False)
3806 self.reset(new_session=False)
3806 # Close the history session (this stores the end time and line count)
3807 # Close the history session (this stores the end time and line count)
3807 # this must be *before* the tempfile cleanup, in case of temporary
3808 # this must be *before* the tempfile cleanup, in case of temporary
3808 # history db
3809 # history db
3809 self.history_manager.end_session()
3810 self.history_manager.end_session()
3810 self.history_manager = None
3811 self.history_manager = None
3811
3812
3812 #-------------------------------------------------------------------------
3813 #-------------------------------------------------------------------------
3813 # Things related to IPython exiting
3814 # Things related to IPython exiting
3814 #-------------------------------------------------------------------------
3815 #-------------------------------------------------------------------------
3815 def atexit_operations(self):
3816 def atexit_operations(self):
3816 """This will be executed at the time of exit.
3817 """This will be executed at the time of exit.
3817
3818
3818 Cleanup operations and saving of persistent data that is done
3819 Cleanup operations and saving of persistent data that is done
3819 unconditionally by IPython should be performed here.
3820 unconditionally by IPython should be performed here.
3820
3821
3821 For things that may depend on startup flags or platform specifics (such
3822 For things that may depend on startup flags or platform specifics (such
3822 as having readline or not), register a separate atexit function in the
3823 as having readline or not), register a separate atexit function in the
3823 code that has the appropriate information, rather than trying to
3824 code that has the appropriate information, rather than trying to
3824 clutter
3825 clutter
3825 """
3826 """
3826 self._atexit_once()
3827 self._atexit_once()
3827
3828
3828 # Cleanup all tempfiles and folders left around
3829 # Cleanup all tempfiles and folders left around
3829 for tfile in self.tempfiles:
3830 for tfile in self.tempfiles:
3830 try:
3831 try:
3831 tfile.unlink()
3832 tfile.unlink()
3832 self.tempfiles.remove(tfile)
3833 self.tempfiles.remove(tfile)
3833 except FileNotFoundError:
3834 except FileNotFoundError:
3834 pass
3835 pass
3835 del self.tempfiles
3836 del self.tempfiles
3836 for tdir in self.tempdirs:
3837 for tdir in self.tempdirs:
3837 try:
3838 try:
3838 tdir.rmdir()
3839 tdir.rmdir()
3839 self.tempdirs.remove(tdir)
3840 self.tempdirs.remove(tdir)
3840 except FileNotFoundError:
3841 except FileNotFoundError:
3841 pass
3842 pass
3842 del self.tempdirs
3843 del self.tempdirs
3843
3844
3844 # Restore user's cursor
3845 # Restore user's cursor
3845 if hasattr(self, "editing_mode") and self.editing_mode == "vi":
3846 if hasattr(self, "editing_mode") and self.editing_mode == "vi":
3846 sys.stdout.write("\x1b[0 q")
3847 sys.stdout.write("\x1b[0 q")
3847 sys.stdout.flush()
3848 sys.stdout.flush()
3848
3849
3849 def cleanup(self):
3850 def cleanup(self):
3850 self.restore_sys_module_state()
3851 self.restore_sys_module_state()
3851
3852
3852
3853
3853 # Overridden in terminal subclass to change prompts
3854 # Overridden in terminal subclass to change prompts
3854 def switch_doctest_mode(self, mode):
3855 def switch_doctest_mode(self, mode):
3855 pass
3856 pass
3856
3857
3857
3858
3858 class InteractiveShellABC(metaclass=abc.ABCMeta):
3859 class InteractiveShellABC(metaclass=abc.ABCMeta):
3859 """An abstract base class for InteractiveShell."""
3860 """An abstract base class for InteractiveShell."""
3860
3861
3861 InteractiveShellABC.register(InteractiveShell)
3862 InteractiveShellABC.register(InteractiveShell)
@@ -1,1129 +1,1175 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for the key interactiveshell module.
2 """Tests for the key interactiveshell module.
3
3
4 Historically the main classes in interactiveshell have been under-tested. This
4 Historically the main classes in interactiveshell have been under-tested. This
5 module should grow as many single-method tests as possible to trap many of the
5 module should grow as many single-method tests as possible to trap many of the
6 recurring bugs we seem to encounter with high-level interaction.
6 recurring bugs we seem to encounter with high-level interaction.
7 """
7 """
8
8
9 # Copyright (c) IPython Development Team.
9 # Copyright (c) IPython Development Team.
10 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
11
11
12 import asyncio
12 import asyncio
13 import ast
13 import ast
14 import os
14 import os
15 import signal
15 import signal
16 import shutil
16 import shutil
17 import sys
17 import sys
18 import tempfile
18 import tempfile
19 import unittest
19 import unittest
20 import pytest
20 import pytest
21 from unittest import mock
21 from unittest import mock
22
22
23 from os.path import join
23 from os.path import join
24
24
25 from IPython.core.error import InputRejected
25 from IPython.core.error import InputRejected
26 from IPython.core.inputtransformer import InputTransformer
26 from IPython.core.inputtransformer import InputTransformer
27 from IPython.core import interactiveshell
27 from IPython.core import interactiveshell
28 from IPython.testing.decorators import (
28 from IPython.testing.decorators import (
29 skipif, skip_win32, onlyif_unicode_paths, onlyif_cmds_exist,
29 skipif, skip_win32, onlyif_unicode_paths, onlyif_cmds_exist,
30 )
30 )
31 from IPython.testing import tools as tt
31 from IPython.testing import tools as tt
32 from IPython.utils.process import find_cmd
32 from IPython.utils.process import find_cmd
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Globals
35 # Globals
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37 # This is used by every single test, no point repeating it ad nauseam
37 # This is used by every single test, no point repeating it ad nauseam
38
38
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40 # Tests
40 # Tests
41 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
42
42
43 class DerivedInterrupt(KeyboardInterrupt):
43 class DerivedInterrupt(KeyboardInterrupt):
44 pass
44 pass
45
45
46 class InteractiveShellTestCase(unittest.TestCase):
46 class InteractiveShellTestCase(unittest.TestCase):
47 def test_naked_string_cells(self):
47 def test_naked_string_cells(self):
48 """Test that cells with only naked strings are fully executed"""
48 """Test that cells with only naked strings are fully executed"""
49 # First, single-line inputs
49 # First, single-line inputs
50 ip.run_cell('"a"\n')
50 ip.run_cell('"a"\n')
51 self.assertEqual(ip.user_ns['_'], 'a')
51 self.assertEqual(ip.user_ns['_'], 'a')
52 # And also multi-line cells
52 # And also multi-line cells
53 ip.run_cell('"""a\nb"""\n')
53 ip.run_cell('"""a\nb"""\n')
54 self.assertEqual(ip.user_ns['_'], 'a\nb')
54 self.assertEqual(ip.user_ns['_'], 'a\nb')
55
55
56 def test_run_empty_cell(self):
56 def test_run_empty_cell(self):
57 """Just make sure we don't get a horrible error with a blank
57 """Just make sure we don't get a horrible error with a blank
58 cell of input. Yes, I did overlook that."""
58 cell of input. Yes, I did overlook that."""
59 old_xc = ip.execution_count
59 old_xc = ip.execution_count
60 res = ip.run_cell('')
60 res = ip.run_cell('')
61 self.assertEqual(ip.execution_count, old_xc)
61 self.assertEqual(ip.execution_count, old_xc)
62 self.assertEqual(res.execution_count, None)
62 self.assertEqual(res.execution_count, None)
63
63
64 def test_run_cell_multiline(self):
64 def test_run_cell_multiline(self):
65 """Multi-block, multi-line cells must execute correctly.
65 """Multi-block, multi-line cells must execute correctly.
66 """
66 """
67 src = '\n'.join(["x=1",
67 src = '\n'.join(["x=1",
68 "y=2",
68 "y=2",
69 "if 1:",
69 "if 1:",
70 " x += 1",
70 " x += 1",
71 " y += 1",])
71 " y += 1",])
72 res = ip.run_cell(src)
72 res = ip.run_cell(src)
73 self.assertEqual(ip.user_ns['x'], 2)
73 self.assertEqual(ip.user_ns['x'], 2)
74 self.assertEqual(ip.user_ns['y'], 3)
74 self.assertEqual(ip.user_ns['y'], 3)
75 self.assertEqual(res.success, True)
75 self.assertEqual(res.success, True)
76 self.assertEqual(res.result, None)
76 self.assertEqual(res.result, None)
77
77
78 def test_multiline_string_cells(self):
78 def test_multiline_string_cells(self):
79 "Code sprinkled with multiline strings should execute (GH-306)"
79 "Code sprinkled with multiline strings should execute (GH-306)"
80 ip.run_cell('tmp=0')
80 ip.run_cell('tmp=0')
81 self.assertEqual(ip.user_ns['tmp'], 0)
81 self.assertEqual(ip.user_ns['tmp'], 0)
82 res = ip.run_cell('tmp=1;"""a\nb"""\n')
82 res = ip.run_cell('tmp=1;"""a\nb"""\n')
83 self.assertEqual(ip.user_ns['tmp'], 1)
83 self.assertEqual(ip.user_ns['tmp'], 1)
84 self.assertEqual(res.success, True)
84 self.assertEqual(res.success, True)
85 self.assertEqual(res.result, "a\nb")
85 self.assertEqual(res.result, "a\nb")
86
86
87 def test_dont_cache_with_semicolon(self):
87 def test_dont_cache_with_semicolon(self):
88 "Ending a line with semicolon should not cache the returned object (GH-307)"
88 "Ending a line with semicolon should not cache the returned object (GH-307)"
89 oldlen = len(ip.user_ns['Out'])
89 oldlen = len(ip.user_ns['Out'])
90 for cell in ['1;', '1;1;']:
90 for cell in ['1;', '1;1;']:
91 res = ip.run_cell(cell, store_history=True)
91 res = ip.run_cell(cell, store_history=True)
92 newlen = len(ip.user_ns['Out'])
92 newlen = len(ip.user_ns['Out'])
93 self.assertEqual(oldlen, newlen)
93 self.assertEqual(oldlen, newlen)
94 self.assertIsNone(res.result)
94 self.assertIsNone(res.result)
95 i = 0
95 i = 0
96 #also test the default caching behavior
96 #also test the default caching behavior
97 for cell in ['1', '1;1']:
97 for cell in ['1', '1;1']:
98 ip.run_cell(cell, store_history=True)
98 ip.run_cell(cell, store_history=True)
99 newlen = len(ip.user_ns['Out'])
99 newlen = len(ip.user_ns['Out'])
100 i += 1
100 i += 1
101 self.assertEqual(oldlen+i, newlen)
101 self.assertEqual(oldlen+i, newlen)
102
102
103 def test_syntax_error(self):
103 def test_syntax_error(self):
104 res = ip.run_cell("raise = 3")
104 res = ip.run_cell("raise = 3")
105 self.assertIsInstance(res.error_before_exec, SyntaxError)
105 self.assertIsInstance(res.error_before_exec, SyntaxError)
106
106
107 def test_open_standard_input_stream(self):
107 def test_open_standard_input_stream(self):
108 res = ip.run_cell("open(0)")
108 res = ip.run_cell("open(0)")
109 self.assertIsInstance(res.error_in_exec, ValueError)
109 self.assertIsInstance(res.error_in_exec, ValueError)
110
110
111 def test_open_standard_output_stream(self):
111 def test_open_standard_output_stream(self):
112 res = ip.run_cell("open(1)")
112 res = ip.run_cell("open(1)")
113 self.assertIsInstance(res.error_in_exec, ValueError)
113 self.assertIsInstance(res.error_in_exec, ValueError)
114
114
115 def test_open_standard_error_stream(self):
115 def test_open_standard_error_stream(self):
116 res = ip.run_cell("open(2)")
116 res = ip.run_cell("open(2)")
117 self.assertIsInstance(res.error_in_exec, ValueError)
117 self.assertIsInstance(res.error_in_exec, ValueError)
118
118
119 def test_In_variable(self):
119 def test_In_variable(self):
120 "Verify that In variable grows with user input (GH-284)"
120 "Verify that In variable grows with user input (GH-284)"
121 oldlen = len(ip.user_ns['In'])
121 oldlen = len(ip.user_ns['In'])
122 ip.run_cell('1;', store_history=True)
122 ip.run_cell('1;', store_history=True)
123 newlen = len(ip.user_ns['In'])
123 newlen = len(ip.user_ns['In'])
124 self.assertEqual(oldlen+1, newlen)
124 self.assertEqual(oldlen+1, newlen)
125 self.assertEqual(ip.user_ns['In'][-1],'1;')
125 self.assertEqual(ip.user_ns['In'][-1],'1;')
126
126
127 def test_magic_names_in_string(self):
127 def test_magic_names_in_string(self):
128 ip.run_cell('a = """\n%exit\n"""')
128 ip.run_cell('a = """\n%exit\n"""')
129 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
129 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
130
130
131 def test_trailing_newline(self):
131 def test_trailing_newline(self):
132 """test that running !(command) does not raise a SyntaxError"""
132 """test that running !(command) does not raise a SyntaxError"""
133 ip.run_cell('!(true)\n', False)
133 ip.run_cell('!(true)\n', False)
134 ip.run_cell('!(true)\n\n\n', False)
134 ip.run_cell('!(true)\n\n\n', False)
135
135
136 def test_gh_597(self):
136 def test_gh_597(self):
137 """Pretty-printing lists of objects with non-ascii reprs may cause
137 """Pretty-printing lists of objects with non-ascii reprs may cause
138 problems."""
138 problems."""
139 class Spam(object):
139 class Spam(object):
140 def __repr__(self):
140 def __repr__(self):
141 return "\xe9"*50
141 return "\xe9"*50
142 import IPython.core.formatters
142 import IPython.core.formatters
143 f = IPython.core.formatters.PlainTextFormatter()
143 f = IPython.core.formatters.PlainTextFormatter()
144 f([Spam(),Spam()])
144 f([Spam(),Spam()])
145
145
146
146
147 def test_future_flags(self):
147 def test_future_flags(self):
148 """Check that future flags are used for parsing code (gh-777)"""
148 """Check that future flags are used for parsing code (gh-777)"""
149 ip.run_cell('from __future__ import barry_as_FLUFL')
149 ip.run_cell('from __future__ import barry_as_FLUFL')
150 try:
150 try:
151 ip.run_cell('prfunc_return_val = 1 <> 2')
151 ip.run_cell('prfunc_return_val = 1 <> 2')
152 assert 'prfunc_return_val' in ip.user_ns
152 assert 'prfunc_return_val' in ip.user_ns
153 finally:
153 finally:
154 # Reset compiler flags so we don't mess up other tests.
154 # Reset compiler flags so we don't mess up other tests.
155 ip.compile.reset_compiler_flags()
155 ip.compile.reset_compiler_flags()
156
156
157 def test_can_pickle(self):
157 def test_can_pickle(self):
158 "Can we pickle objects defined interactively (GH-29)"
158 "Can we pickle objects defined interactively (GH-29)"
159 ip = get_ipython()
159 ip = get_ipython()
160 ip.reset()
160 ip.reset()
161 ip.run_cell(("class Mylist(list):\n"
161 ip.run_cell(("class Mylist(list):\n"
162 " def __init__(self,x=[]):\n"
162 " def __init__(self,x=[]):\n"
163 " list.__init__(self,x)"))
163 " list.__init__(self,x)"))
164 ip.run_cell("w=Mylist([1,2,3])")
164 ip.run_cell("w=Mylist([1,2,3])")
165
165
166 from pickle import dumps
166 from pickle import dumps
167
167
168 # We need to swap in our main module - this is only necessary
168 # We need to swap in our main module - this is only necessary
169 # inside the test framework, because IPython puts the interactive module
169 # inside the test framework, because IPython puts the interactive module
170 # in place (but the test framework undoes this).
170 # in place (but the test framework undoes this).
171 _main = sys.modules['__main__']
171 _main = sys.modules['__main__']
172 sys.modules['__main__'] = ip.user_module
172 sys.modules['__main__'] = ip.user_module
173 try:
173 try:
174 res = dumps(ip.user_ns["w"])
174 res = dumps(ip.user_ns["w"])
175 finally:
175 finally:
176 sys.modules['__main__'] = _main
176 sys.modules['__main__'] = _main
177 self.assertTrue(isinstance(res, bytes))
177 self.assertTrue(isinstance(res, bytes))
178
178
179 def test_global_ns(self):
179 def test_global_ns(self):
180 "Code in functions must be able to access variables outside them."
180 "Code in functions must be able to access variables outside them."
181 ip = get_ipython()
181 ip = get_ipython()
182 ip.run_cell("a = 10")
182 ip.run_cell("a = 10")
183 ip.run_cell(("def f(x):\n"
183 ip.run_cell(("def f(x):\n"
184 " return x + a"))
184 " return x + a"))
185 ip.run_cell("b = f(12)")
185 ip.run_cell("b = f(12)")
186 self.assertEqual(ip.user_ns["b"], 22)
186 self.assertEqual(ip.user_ns["b"], 22)
187
187
188 def test_bad_custom_tb(self):
188 def test_bad_custom_tb(self):
189 """Check that InteractiveShell is protected from bad custom exception handlers"""
189 """Check that InteractiveShell is protected from bad custom exception handlers"""
190 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
190 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
191 self.assertEqual(ip.custom_exceptions, (IOError,))
191 self.assertEqual(ip.custom_exceptions, (IOError,))
192 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
192 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
193 ip.run_cell(u'raise IOError("foo")')
193 ip.run_cell(u'raise IOError("foo")')
194 self.assertEqual(ip.custom_exceptions, ())
194 self.assertEqual(ip.custom_exceptions, ())
195
195
196 def test_bad_custom_tb_return(self):
196 def test_bad_custom_tb_return(self):
197 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
197 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
198 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
198 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
199 self.assertEqual(ip.custom_exceptions, (NameError,))
199 self.assertEqual(ip.custom_exceptions, (NameError,))
200 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
200 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
201 ip.run_cell(u'a=abracadabra')
201 ip.run_cell(u'a=abracadabra')
202 self.assertEqual(ip.custom_exceptions, ())
202 self.assertEqual(ip.custom_exceptions, ())
203
203
204 def test_drop_by_id(self):
204 def test_drop_by_id(self):
205 myvars = {"a":object(), "b":object(), "c": object()}
205 myvars = {"a":object(), "b":object(), "c": object()}
206 ip.push(myvars, interactive=False)
206 ip.push(myvars, interactive=False)
207 for name in myvars:
207 for name in myvars:
208 assert name in ip.user_ns, name
208 assert name in ip.user_ns, name
209 assert name in ip.user_ns_hidden, name
209 assert name in ip.user_ns_hidden, name
210 ip.user_ns['b'] = 12
210 ip.user_ns['b'] = 12
211 ip.drop_by_id(myvars)
211 ip.drop_by_id(myvars)
212 for name in ["a", "c"]:
212 for name in ["a", "c"]:
213 assert name not in ip.user_ns, name
213 assert name not in ip.user_ns, name
214 assert name not in ip.user_ns_hidden, name
214 assert name not in ip.user_ns_hidden, name
215 assert ip.user_ns['b'] == 12
215 assert ip.user_ns['b'] == 12
216 ip.reset()
216 ip.reset()
217
217
218 def test_var_expand(self):
218 def test_var_expand(self):
219 ip.user_ns['f'] = u'Ca\xf1o'
219 ip.user_ns['f'] = u'Ca\xf1o'
220 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
220 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
221 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
221 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
222 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
222 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
223 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
223 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
224
224
225 self.assertEqual(ip.var_expand(u"grep x | awk '{print $1}'"), u"grep x | awk '{print $1}'")
225 self.assertEqual(ip.var_expand(u"grep x | awk '{print $1}'"), u"grep x | awk '{print $1}'")
226
226
227 ip.user_ns['f'] = b'Ca\xc3\xb1o'
227 ip.user_ns['f'] = b'Ca\xc3\xb1o'
228 # This should not raise any exception:
228 # This should not raise any exception:
229 ip.var_expand(u'echo $f')
229 ip.var_expand(u'echo $f')
230
230
231 def test_var_expand_local(self):
231 def test_var_expand_local(self):
232 """Test local variable expansion in !system and %magic calls"""
232 """Test local variable expansion in !system and %magic calls"""
233 # !system
233 # !system
234 ip.run_cell(
234 ip.run_cell(
235 "def test():\n"
235 "def test():\n"
236 ' lvar = "ttt"\n'
236 ' lvar = "ttt"\n'
237 " ret = !echo {lvar}\n"
237 " ret = !echo {lvar}\n"
238 " return ret[0]\n"
238 " return ret[0]\n"
239 )
239 )
240 res = ip.user_ns["test"]()
240 res = ip.user_ns["test"]()
241 self.assertIn("ttt", res)
241 self.assertIn("ttt", res)
242
242
243 # %magic
243 # %magic
244 ip.run_cell(
244 ip.run_cell(
245 "def makemacro():\n"
245 "def makemacro():\n"
246 ' macroname = "macro_var_expand_locals"\n'
246 ' macroname = "macro_var_expand_locals"\n'
247 " %macro {macroname} codestr\n"
247 " %macro {macroname} codestr\n"
248 )
248 )
249 ip.user_ns["codestr"] = "str(12)"
249 ip.user_ns["codestr"] = "str(12)"
250 ip.run_cell("makemacro()")
250 ip.run_cell("makemacro()")
251 self.assertIn("macro_var_expand_locals", ip.user_ns)
251 self.assertIn("macro_var_expand_locals", ip.user_ns)
252
252
253 def test_var_expand_self(self):
253 def test_var_expand_self(self):
254 """Test variable expansion with the name 'self', which was failing.
254 """Test variable expansion with the name 'self', which was failing.
255
255
256 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
256 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
257 """
257 """
258 ip.run_cell(
258 ip.run_cell(
259 "class cTest:\n"
259 "class cTest:\n"
260 ' classvar="see me"\n'
260 ' classvar="see me"\n'
261 " def test(self):\n"
261 " def test(self):\n"
262 " res = !echo Variable: {self.classvar}\n"
262 " res = !echo Variable: {self.classvar}\n"
263 " return res[0]\n"
263 " return res[0]\n"
264 )
264 )
265 self.assertIn("see me", ip.user_ns["cTest"]().test())
265 self.assertIn("see me", ip.user_ns["cTest"]().test())
266
266
267 def test_bad_var_expand(self):
267 def test_bad_var_expand(self):
268 """var_expand on invalid formats shouldn't raise"""
268 """var_expand on invalid formats shouldn't raise"""
269 # SyntaxError
269 # SyntaxError
270 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
270 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
271 # NameError
271 # NameError
272 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
272 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
273 # ZeroDivisionError
273 # ZeroDivisionError
274 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
274 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
275
275
276 def test_silent_postexec(self):
276 def test_silent_postexec(self):
277 """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks"""
277 """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks"""
278 pre_explicit = mock.Mock()
278 pre_explicit = mock.Mock()
279 pre_always = mock.Mock()
279 pre_always = mock.Mock()
280 post_explicit = mock.Mock()
280 post_explicit = mock.Mock()
281 post_always = mock.Mock()
281 post_always = mock.Mock()
282 all_mocks = [pre_explicit, pre_always, post_explicit, post_always]
282 all_mocks = [pre_explicit, pre_always, post_explicit, post_always]
283
283
284 ip.events.register('pre_run_cell', pre_explicit)
284 ip.events.register('pre_run_cell', pre_explicit)
285 ip.events.register('pre_execute', pre_always)
285 ip.events.register('pre_execute', pre_always)
286 ip.events.register('post_run_cell', post_explicit)
286 ip.events.register('post_run_cell', post_explicit)
287 ip.events.register('post_execute', post_always)
287 ip.events.register('post_execute', post_always)
288
288
289 try:
289 try:
290 ip.run_cell("1", silent=True)
290 ip.run_cell("1", silent=True)
291 assert pre_always.called
291 assert pre_always.called
292 assert not pre_explicit.called
292 assert not pre_explicit.called
293 assert post_always.called
293 assert post_always.called
294 assert not post_explicit.called
294 assert not post_explicit.called
295 # double-check that non-silent exec did what we expected
295 # double-check that non-silent exec did what we expected
296 # silent to avoid
296 # silent to avoid
297 ip.run_cell("1")
297 ip.run_cell("1")
298 assert pre_explicit.called
298 assert pre_explicit.called
299 assert post_explicit.called
299 assert post_explicit.called
300 info, = pre_explicit.call_args[0]
300 info, = pre_explicit.call_args[0]
301 result, = post_explicit.call_args[0]
301 result, = post_explicit.call_args[0]
302 self.assertEqual(info, result.info)
302 self.assertEqual(info, result.info)
303 # check that post hooks are always called
303 # check that post hooks are always called
304 [m.reset_mock() for m in all_mocks]
304 [m.reset_mock() for m in all_mocks]
305 ip.run_cell("syntax error")
305 ip.run_cell("syntax error")
306 assert pre_always.called
306 assert pre_always.called
307 assert pre_explicit.called
307 assert pre_explicit.called
308 assert post_always.called
308 assert post_always.called
309 assert post_explicit.called
309 assert post_explicit.called
310 info, = pre_explicit.call_args[0]
310 info, = pre_explicit.call_args[0]
311 result, = post_explicit.call_args[0]
311 result, = post_explicit.call_args[0]
312 self.assertEqual(info, result.info)
312 self.assertEqual(info, result.info)
313 finally:
313 finally:
314 # remove post-exec
314 # remove post-exec
315 ip.events.unregister('pre_run_cell', pre_explicit)
315 ip.events.unregister('pre_run_cell', pre_explicit)
316 ip.events.unregister('pre_execute', pre_always)
316 ip.events.unregister('pre_execute', pre_always)
317 ip.events.unregister('post_run_cell', post_explicit)
317 ip.events.unregister('post_run_cell', post_explicit)
318 ip.events.unregister('post_execute', post_always)
318 ip.events.unregister('post_execute', post_always)
319
319
320 def test_silent_noadvance(self):
320 def test_silent_noadvance(self):
321 """run_cell(silent=True) doesn't advance execution_count"""
321 """run_cell(silent=True) doesn't advance execution_count"""
322 ec = ip.execution_count
322 ec = ip.execution_count
323 # silent should force store_history=False
323 # silent should force store_history=False
324 ip.run_cell("1", store_history=True, silent=True)
324 ip.run_cell("1", store_history=True, silent=True)
325
325
326 self.assertEqual(ec, ip.execution_count)
326 self.assertEqual(ec, ip.execution_count)
327 # double-check that non-silent exec did what we expected
327 # double-check that non-silent exec did what we expected
328 # silent to avoid
328 # silent to avoid
329 ip.run_cell("1", store_history=True)
329 ip.run_cell("1", store_history=True)
330 self.assertEqual(ec+1, ip.execution_count)
330 self.assertEqual(ec+1, ip.execution_count)
331
331
332 def test_silent_nodisplayhook(self):
332 def test_silent_nodisplayhook(self):
333 """run_cell(silent=True) doesn't trigger displayhook"""
333 """run_cell(silent=True) doesn't trigger displayhook"""
334 d = dict(called=False)
334 d = dict(called=False)
335
335
336 trap = ip.display_trap
336 trap = ip.display_trap
337 save_hook = trap.hook
337 save_hook = trap.hook
338
338
339 def failing_hook(*args, **kwargs):
339 def failing_hook(*args, **kwargs):
340 d['called'] = True
340 d['called'] = True
341
341
342 try:
342 try:
343 trap.hook = failing_hook
343 trap.hook = failing_hook
344 res = ip.run_cell("1", silent=True)
344 res = ip.run_cell("1", silent=True)
345 self.assertFalse(d['called'])
345 self.assertFalse(d['called'])
346 self.assertIsNone(res.result)
346 self.assertIsNone(res.result)
347 # double-check that non-silent exec did what we expected
347 # double-check that non-silent exec did what we expected
348 # silent to avoid
348 # silent to avoid
349 ip.run_cell("1")
349 ip.run_cell("1")
350 self.assertTrue(d['called'])
350 self.assertTrue(d['called'])
351 finally:
351 finally:
352 trap.hook = save_hook
352 trap.hook = save_hook
353
353
354 def test_ofind_line_magic(self):
354 def test_ofind_line_magic(self):
355 from IPython.core.magic import register_line_magic
355 from IPython.core.magic import register_line_magic
356
356
357 @register_line_magic
357 @register_line_magic
358 def lmagic(line):
358 def lmagic(line):
359 "A line magic"
359 "A line magic"
360
360
361 # Get info on line magic
361 # Get info on line magic
362 lfind = ip._ofind("lmagic")
362 lfind = ip._ofind("lmagic")
363 info = dict(
363 info = dict(
364 found=True,
364 found=True,
365 isalias=False,
365 isalias=False,
366 ismagic=True,
366 ismagic=True,
367 namespace="IPython internal",
367 namespace="IPython internal",
368 obj=lmagic,
368 obj=lmagic,
369 parent=None,
369 parent=None,
370 )
370 )
371 self.assertEqual(lfind, info)
371 self.assertEqual(lfind, info)
372
372
373 def test_ofind_cell_magic(self):
373 def test_ofind_cell_magic(self):
374 from IPython.core.magic import register_cell_magic
374 from IPython.core.magic import register_cell_magic
375
375
376 @register_cell_magic
376 @register_cell_magic
377 def cmagic(line, cell):
377 def cmagic(line, cell):
378 "A cell magic"
378 "A cell magic"
379
379
380 # Get info on cell magic
380 # Get info on cell magic
381 find = ip._ofind("cmagic")
381 find = ip._ofind("cmagic")
382 info = dict(
382 info = dict(
383 found=True,
383 found=True,
384 isalias=False,
384 isalias=False,
385 ismagic=True,
385 ismagic=True,
386 namespace="IPython internal",
386 namespace="IPython internal",
387 obj=cmagic,
387 obj=cmagic,
388 parent=None,
388 parent=None,
389 )
389 )
390 self.assertEqual(find, info)
390 self.assertEqual(find, info)
391
391
392 def test_ofind_property_with_error(self):
392 def test_ofind_property_with_error(self):
393 class A(object):
393 class A(object):
394 @property
394 @property
395 def foo(self):
395 def foo(self):
396 raise NotImplementedError() # pragma: no cover
396 raise NotImplementedError() # pragma: no cover
397
397
398 a = A()
398 a = A()
399
399
400 found = ip._ofind('a.foo', [('locals', locals())])
400 found = ip._ofind('a.foo', [('locals', locals())])
401 info = dict(found=True, isalias=False, ismagic=False,
401 info = dict(found=True, isalias=False, ismagic=False,
402 namespace='locals', obj=A.foo, parent=a)
402 namespace='locals', obj=A.foo, parent=a)
403 self.assertEqual(found, info)
403 self.assertEqual(found, info)
404
404
405 def test_ofind_multiple_attribute_lookups(self):
405 def test_ofind_multiple_attribute_lookups(self):
406 class A(object):
406 class A(object):
407 @property
407 @property
408 def foo(self):
408 def foo(self):
409 raise NotImplementedError() # pragma: no cover
409 raise NotImplementedError() # pragma: no cover
410
410
411 a = A()
411 a = A()
412 a.a = A()
412 a.a = A()
413 a.a.a = A()
413 a.a.a = A()
414
414
415 found = ip._ofind('a.a.a.foo', [('locals', locals())])
415 found = ip._ofind('a.a.a.foo', [('locals', locals())])
416 info = dict(found=True, isalias=False, ismagic=False,
416 info = dict(found=True, isalias=False, ismagic=False,
417 namespace='locals', obj=A.foo, parent=a.a.a)
417 namespace='locals', obj=A.foo, parent=a.a.a)
418 self.assertEqual(found, info)
418 self.assertEqual(found, info)
419
419
420 def test_ofind_slotted_attributes(self):
420 def test_ofind_slotted_attributes(self):
421 class A(object):
421 class A(object):
422 __slots__ = ['foo']
422 __slots__ = ['foo']
423 def __init__(self):
423 def __init__(self):
424 self.foo = 'bar'
424 self.foo = 'bar'
425
425
426 a = A()
426 a = A()
427 found = ip._ofind('a.foo', [('locals', locals())])
427 found = ip._ofind('a.foo', [('locals', locals())])
428 info = dict(found=True, isalias=False, ismagic=False,
428 info = dict(found=True, isalias=False, ismagic=False,
429 namespace='locals', obj=a.foo, parent=a)
429 namespace='locals', obj=a.foo, parent=a)
430 self.assertEqual(found, info)
430 self.assertEqual(found, info)
431
431
432 found = ip._ofind('a.bar', [('locals', locals())])
432 found = ip._ofind('a.bar', [('locals', locals())])
433 info = dict(found=False, isalias=False, ismagic=False,
433 info = dict(found=False, isalias=False, ismagic=False,
434 namespace=None, obj=None, parent=a)
434 namespace=None, obj=None, parent=a)
435 self.assertEqual(found, info)
435 self.assertEqual(found, info)
436
436
437 def test_ofind_prefers_property_to_instance_level_attribute(self):
437 def test_ofind_prefers_property_to_instance_level_attribute(self):
438 class A(object):
438 class A(object):
439 @property
439 @property
440 def foo(self):
440 def foo(self):
441 return 'bar'
441 return 'bar'
442 a = A()
442 a = A()
443 a.__dict__["foo"] = "baz"
443 a.__dict__["foo"] = "baz"
444 self.assertEqual(a.foo, "bar")
444 self.assertEqual(a.foo, "bar")
445 found = ip._ofind("a.foo", [("locals", locals())])
445 found = ip._ofind("a.foo", [("locals", locals())])
446 self.assertIs(found["obj"], A.foo)
446 self.assertIs(found["obj"], A.foo)
447
447
448 def test_custom_syntaxerror_exception(self):
448 def test_custom_syntaxerror_exception(self):
449 called = []
449 called = []
450 def my_handler(shell, etype, value, tb, tb_offset=None):
450 def my_handler(shell, etype, value, tb, tb_offset=None):
451 called.append(etype)
451 called.append(etype)
452 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
452 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
453
453
454 ip.set_custom_exc((SyntaxError,), my_handler)
454 ip.set_custom_exc((SyntaxError,), my_handler)
455 try:
455 try:
456 ip.run_cell("1f")
456 ip.run_cell("1f")
457 # Check that this was called, and only once.
457 # Check that this was called, and only once.
458 self.assertEqual(called, [SyntaxError])
458 self.assertEqual(called, [SyntaxError])
459 finally:
459 finally:
460 # Reset the custom exception hook
460 # Reset the custom exception hook
461 ip.set_custom_exc((), None)
461 ip.set_custom_exc((), None)
462
462
463 def test_custom_exception(self):
463 def test_custom_exception(self):
464 called = []
464 called = []
465 def my_handler(shell, etype, value, tb, tb_offset=None):
465 def my_handler(shell, etype, value, tb, tb_offset=None):
466 called.append(etype)
466 called.append(etype)
467 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
467 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
468
468
469 ip.set_custom_exc((ValueError,), my_handler)
469 ip.set_custom_exc((ValueError,), my_handler)
470 try:
470 try:
471 res = ip.run_cell("raise ValueError('test')")
471 res = ip.run_cell("raise ValueError('test')")
472 # Check that this was called, and only once.
472 # Check that this was called, and only once.
473 self.assertEqual(called, [ValueError])
473 self.assertEqual(called, [ValueError])
474 # Check that the error is on the result object
474 # Check that the error is on the result object
475 self.assertIsInstance(res.error_in_exec, ValueError)
475 self.assertIsInstance(res.error_in_exec, ValueError)
476 finally:
476 finally:
477 # Reset the custom exception hook
477 # Reset the custom exception hook
478 ip.set_custom_exc((), None)
478 ip.set_custom_exc((), None)
479
479
480 @mock.patch("builtins.print")
480 @mock.patch("builtins.print")
481 def test_showtraceback_with_surrogates(self, mocked_print):
481 def test_showtraceback_with_surrogates(self, mocked_print):
482 values = []
482 values = []
483
483
484 def mock_print_func(value, sep=" ", end="\n", file=sys.stdout, flush=False):
484 def mock_print_func(value, sep=" ", end="\n", file=sys.stdout, flush=False):
485 values.append(value)
485 values.append(value)
486 if value == chr(0xD8FF):
486 if value == chr(0xD8FF):
487 raise UnicodeEncodeError("utf-8", chr(0xD8FF), 0, 1, "")
487 raise UnicodeEncodeError("utf-8", chr(0xD8FF), 0, 1, "")
488
488
489 # mock builtins.print
489 # mock builtins.print
490 mocked_print.side_effect = mock_print_func
490 mocked_print.side_effect = mock_print_func
491
491
492 # ip._showtraceback() is replaced in globalipapp.py.
492 # ip._showtraceback() is replaced in globalipapp.py.
493 # Call original method to test.
493 # Call original method to test.
494 interactiveshell.InteractiveShell._showtraceback(ip, None, None, chr(0xD8FF))
494 interactiveshell.InteractiveShell._showtraceback(ip, None, None, chr(0xD8FF))
495
495
496 self.assertEqual(mocked_print.call_count, 2)
496 self.assertEqual(mocked_print.call_count, 2)
497 self.assertEqual(values, [chr(0xD8FF), "\\ud8ff"])
497 self.assertEqual(values, [chr(0xD8FF), "\\ud8ff"])
498
498
499 def test_mktempfile(self):
499 def test_mktempfile(self):
500 filename = ip.mktempfile()
500 filename = ip.mktempfile()
501 # Check that we can open the file again on Windows
501 # Check that we can open the file again on Windows
502 with open(filename, "w", encoding="utf-8") as f:
502 with open(filename, "w", encoding="utf-8") as f:
503 f.write("abc")
503 f.write("abc")
504
504
505 filename = ip.mktempfile(data="blah")
505 filename = ip.mktempfile(data="blah")
506 with open(filename, "r", encoding="utf-8") as f:
506 with open(filename, "r", encoding="utf-8") as f:
507 self.assertEqual(f.read(), "blah")
507 self.assertEqual(f.read(), "blah")
508
508
509 def test_new_main_mod(self):
509 def test_new_main_mod(self):
510 # Smoketest to check that this accepts a unicode module name
510 # Smoketest to check that this accepts a unicode module name
511 name = u'jiefmw'
511 name = u'jiefmw'
512 mod = ip.new_main_mod(u'%s.py' % name, name)
512 mod = ip.new_main_mod(u'%s.py' % name, name)
513 self.assertEqual(mod.__name__, name)
513 self.assertEqual(mod.__name__, name)
514
514
515 def test_get_exception_only(self):
515 def test_get_exception_only(self):
516 try:
516 try:
517 raise KeyboardInterrupt
517 raise KeyboardInterrupt
518 except KeyboardInterrupt:
518 except KeyboardInterrupt:
519 msg = ip.get_exception_only()
519 msg = ip.get_exception_only()
520 self.assertEqual(msg, 'KeyboardInterrupt\n')
520 self.assertEqual(msg, 'KeyboardInterrupt\n')
521
521
522 try:
522 try:
523 raise DerivedInterrupt("foo")
523 raise DerivedInterrupt("foo")
524 except KeyboardInterrupt:
524 except KeyboardInterrupt:
525 msg = ip.get_exception_only()
525 msg = ip.get_exception_only()
526 self.assertEqual(msg, 'IPython.core.tests.test_interactiveshell.DerivedInterrupt: foo\n')
526 self.assertEqual(msg, 'IPython.core.tests.test_interactiveshell.DerivedInterrupt: foo\n')
527
527
528 def test_inspect_text(self):
528 def test_inspect_text(self):
529 ip.run_cell('a = 5')
529 ip.run_cell('a = 5')
530 text = ip.object_inspect_text('a')
530 text = ip.object_inspect_text('a')
531 self.assertIsInstance(text, str)
531 self.assertIsInstance(text, str)
532
532
533 def test_last_execution_result(self):
533 def test_last_execution_result(self):
534 """ Check that last execution result gets set correctly (GH-10702) """
534 """ Check that last execution result gets set correctly (GH-10702) """
535 result = ip.run_cell('a = 5; a')
535 result = ip.run_cell('a = 5; a')
536 self.assertTrue(ip.last_execution_succeeded)
536 self.assertTrue(ip.last_execution_succeeded)
537 self.assertEqual(ip.last_execution_result.result, 5)
537 self.assertEqual(ip.last_execution_result.result, 5)
538
538
539 result = ip.run_cell('a = x_invalid_id_x')
539 result = ip.run_cell('a = x_invalid_id_x')
540 self.assertFalse(ip.last_execution_succeeded)
540 self.assertFalse(ip.last_execution_succeeded)
541 self.assertFalse(ip.last_execution_result.success)
541 self.assertFalse(ip.last_execution_result.success)
542 self.assertIsInstance(ip.last_execution_result.error_in_exec, NameError)
542 self.assertIsInstance(ip.last_execution_result.error_in_exec, NameError)
543
543
544 def test_reset_aliasing(self):
544 def test_reset_aliasing(self):
545 """ Check that standard posix aliases work after %reset. """
545 """ Check that standard posix aliases work after %reset. """
546 if os.name != 'posix':
546 if os.name != 'posix':
547 return
547 return
548
548
549 ip.reset()
549 ip.reset()
550 for cmd in ('clear', 'more', 'less', 'man'):
550 for cmd in ('clear', 'more', 'less', 'man'):
551 res = ip.run_cell('%' + cmd)
551 res = ip.run_cell('%' + cmd)
552 self.assertEqual(res.success, True)
552 self.assertEqual(res.success, True)
553
553
554
554
555 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
555 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
556
556
557 @onlyif_unicode_paths
557 @onlyif_unicode_paths
558 def setUp(self):
558 def setUp(self):
559 self.BASETESTDIR = tempfile.mkdtemp()
559 self.BASETESTDIR = tempfile.mkdtemp()
560 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
560 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
561 os.mkdir(self.TESTDIR)
561 os.mkdir(self.TESTDIR)
562 with open(
562 with open(
563 join(self.TESTDIR, "Γ₯Àâtestscript.py"), "w", encoding="utf-8"
563 join(self.TESTDIR, "Γ₯Àâtestscript.py"), "w", encoding="utf-8"
564 ) as sfile:
564 ) as sfile:
565 sfile.write("pass\n")
565 sfile.write("pass\n")
566 self.oldpath = os.getcwd()
566 self.oldpath = os.getcwd()
567 os.chdir(self.TESTDIR)
567 os.chdir(self.TESTDIR)
568 self.fname = u"Γ₯Àâtestscript.py"
568 self.fname = u"Γ₯Àâtestscript.py"
569
569
570 def tearDown(self):
570 def tearDown(self):
571 os.chdir(self.oldpath)
571 os.chdir(self.oldpath)
572 shutil.rmtree(self.BASETESTDIR)
572 shutil.rmtree(self.BASETESTDIR)
573
573
574 @onlyif_unicode_paths
574 @onlyif_unicode_paths
575 def test_1(self):
575 def test_1(self):
576 """Test safe_execfile with non-ascii path
576 """Test safe_execfile with non-ascii path
577 """
577 """
578 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
578 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
579
579
580 class ExitCodeChecks(tt.TempFileMixin):
580 class ExitCodeChecks(tt.TempFileMixin):
581
581
582 def setUp(self):
582 def setUp(self):
583 self.system = ip.system_raw
583 self.system = ip.system_raw
584
584
585 def test_exit_code_ok(self):
585 def test_exit_code_ok(self):
586 self.system('exit 0')
586 self.system('exit 0')
587 self.assertEqual(ip.user_ns['_exit_code'], 0)
587 self.assertEqual(ip.user_ns['_exit_code'], 0)
588
588
589 def test_exit_code_error(self):
589 def test_exit_code_error(self):
590 self.system('exit 1')
590 self.system('exit 1')
591 self.assertEqual(ip.user_ns['_exit_code'], 1)
591 self.assertEqual(ip.user_ns['_exit_code'], 1)
592
592
593 @skipif(not hasattr(signal, 'SIGALRM'))
593 @skipif(not hasattr(signal, 'SIGALRM'))
594 def test_exit_code_signal(self):
594 def test_exit_code_signal(self):
595 self.mktmp("import signal, time\n"
595 self.mktmp("import signal, time\n"
596 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
596 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
597 "time.sleep(1)\n")
597 "time.sleep(1)\n")
598 self.system("%s %s" % (sys.executable, self.fname))
598 self.system("%s %s" % (sys.executable, self.fname))
599 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
599 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
600
600
601 @onlyif_cmds_exist("csh")
601 @onlyif_cmds_exist("csh")
602 def test_exit_code_signal_csh(self): # pragma: no cover
602 def test_exit_code_signal_csh(self): # pragma: no cover
603 SHELL = os.environ.get("SHELL", None)
603 SHELL = os.environ.get("SHELL", None)
604 os.environ["SHELL"] = find_cmd("csh")
604 os.environ["SHELL"] = find_cmd("csh")
605 try:
605 try:
606 self.test_exit_code_signal()
606 self.test_exit_code_signal()
607 finally:
607 finally:
608 if SHELL is not None:
608 if SHELL is not None:
609 os.environ['SHELL'] = SHELL
609 os.environ['SHELL'] = SHELL
610 else:
610 else:
611 del os.environ['SHELL']
611 del os.environ['SHELL']
612
612
613
613
614 class TestSystemRaw(ExitCodeChecks):
614 class TestSystemRaw(ExitCodeChecks):
615
615
616 def setUp(self):
616 def setUp(self):
617 super().setUp()
617 super().setUp()
618 self.system = ip.system_raw
618 self.system = ip.system_raw
619
619
620 @onlyif_unicode_paths
620 @onlyif_unicode_paths
621 def test_1(self):
621 def test_1(self):
622 """Test system_raw with non-ascii cmd
622 """Test system_raw with non-ascii cmd
623 """
623 """
624 cmd = u'''python -c "'Γ₯Àâ'" '''
624 cmd = u'''python -c "'Γ₯Àâ'" '''
625 ip.system_raw(cmd)
625 ip.system_raw(cmd)
626
626
627 @mock.patch('subprocess.call', side_effect=KeyboardInterrupt)
627 @mock.patch('subprocess.call', side_effect=KeyboardInterrupt)
628 @mock.patch('os.system', side_effect=KeyboardInterrupt)
628 @mock.patch('os.system', side_effect=KeyboardInterrupt)
629 def test_control_c(self, *mocks):
629 def test_control_c(self, *mocks):
630 try:
630 try:
631 self.system("sleep 1 # wont happen")
631 self.system("sleep 1 # wont happen")
632 except KeyboardInterrupt: # pragma: no cove
632 except KeyboardInterrupt: # pragma: no cove
633 self.fail(
633 self.fail(
634 "system call should intercept "
634 "system call should intercept "
635 "keyboard interrupt from subprocess.call"
635 "keyboard interrupt from subprocess.call"
636 )
636 )
637 self.assertEqual(ip.user_ns["_exit_code"], -signal.SIGINT)
637 self.assertEqual(ip.user_ns["_exit_code"], -signal.SIGINT)
638
638
639
639
640 @pytest.mark.parametrize("magic_cmd", ["pip", "conda", "cd"])
640 @pytest.mark.parametrize("magic_cmd", ["pip", "conda", "cd"])
641 def test_magic_warnings(magic_cmd):
641 def test_magic_warnings(magic_cmd):
642 if sys.platform == "win32":
642 if sys.platform == "win32":
643 to_mock = "os.system"
643 to_mock = "os.system"
644 expected_arg, expected_kwargs = magic_cmd, dict()
644 expected_arg, expected_kwargs = magic_cmd, dict()
645 else:
645 else:
646 to_mock = "subprocess.call"
646 to_mock = "subprocess.call"
647 expected_arg, expected_kwargs = magic_cmd, dict(
647 expected_arg, expected_kwargs = magic_cmd, dict(
648 shell=True, executable=os.environ.get("SHELL", None)
648 shell=True, executable=os.environ.get("SHELL", None)
649 )
649 )
650
650
651 with mock.patch(to_mock, return_value=0) as mock_sub:
651 with mock.patch(to_mock, return_value=0) as mock_sub:
652 with pytest.warns(Warning, match=r"You executed the system command"):
652 with pytest.warns(Warning, match=r"You executed the system command"):
653 ip.system_raw(magic_cmd)
653 ip.system_raw(magic_cmd)
654 mock_sub.assert_called_once_with(expected_arg, **expected_kwargs)
654 mock_sub.assert_called_once_with(expected_arg, **expected_kwargs)
655
655
656
656
657 # TODO: Exit codes are currently ignored on Windows.
657 # TODO: Exit codes are currently ignored on Windows.
658 class TestSystemPipedExitCode(ExitCodeChecks):
658 class TestSystemPipedExitCode(ExitCodeChecks):
659
659
660 def setUp(self):
660 def setUp(self):
661 super().setUp()
661 super().setUp()
662 self.system = ip.system_piped
662 self.system = ip.system_piped
663
663
664 @skip_win32
664 @skip_win32
665 def test_exit_code_ok(self):
665 def test_exit_code_ok(self):
666 ExitCodeChecks.test_exit_code_ok(self)
666 ExitCodeChecks.test_exit_code_ok(self)
667
667
668 @skip_win32
668 @skip_win32
669 def test_exit_code_error(self):
669 def test_exit_code_error(self):
670 ExitCodeChecks.test_exit_code_error(self)
670 ExitCodeChecks.test_exit_code_error(self)
671
671
672 @skip_win32
672 @skip_win32
673 def test_exit_code_signal(self):
673 def test_exit_code_signal(self):
674 ExitCodeChecks.test_exit_code_signal(self)
674 ExitCodeChecks.test_exit_code_signal(self)
675
675
676 class TestModules(tt.TempFileMixin):
676 class TestModules(tt.TempFileMixin):
677 def test_extraneous_loads(self):
677 def test_extraneous_loads(self):
678 """Test we're not loading modules on startup that we shouldn't.
678 """Test we're not loading modules on startup that we shouldn't.
679 """
679 """
680 self.mktmp("import sys\n"
680 self.mktmp("import sys\n"
681 "print('numpy' in sys.modules)\n"
681 "print('numpy' in sys.modules)\n"
682 "print('ipyparallel' in sys.modules)\n"
682 "print('ipyparallel' in sys.modules)\n"
683 "print('ipykernel' in sys.modules)\n"
683 "print('ipykernel' in sys.modules)\n"
684 )
684 )
685 out = "False\nFalse\nFalse\n"
685 out = "False\nFalse\nFalse\n"
686 tt.ipexec_validate(self.fname, out)
686 tt.ipexec_validate(self.fname, out)
687
687
688 class Negator(ast.NodeTransformer):
688 class Negator(ast.NodeTransformer):
689 """Negates all number literals in an AST."""
689 """Negates all number literals in an AST."""
690
690
691 # for python 3.7 and earlier
691 # for python 3.7 and earlier
692 def visit_Num(self, node):
692 def visit_Num(self, node):
693 node.n = -node.n
693 node.n = -node.n
694 return node
694 return node
695
695
696 # for python 3.8+
696 # for python 3.8+
697 def visit_Constant(self, node):
697 def visit_Constant(self, node):
698 if isinstance(node.value, int):
698 if isinstance(node.value, int):
699 return self.visit_Num(node)
699 return self.visit_Num(node)
700 return node
700 return node
701
701
702 class TestAstTransform(unittest.TestCase):
702 class TestAstTransform(unittest.TestCase):
703 def setUp(self):
703 def setUp(self):
704 self.negator = Negator()
704 self.negator = Negator()
705 ip.ast_transformers.append(self.negator)
705 ip.ast_transformers.append(self.negator)
706
706
707 def tearDown(self):
707 def tearDown(self):
708 ip.ast_transformers.remove(self.negator)
708 ip.ast_transformers.remove(self.negator)
709
709
710 def test_non_int_const(self):
710 def test_non_int_const(self):
711 with tt.AssertPrints("hello"):
711 with tt.AssertPrints("hello"):
712 ip.run_cell('print("hello")')
712 ip.run_cell('print("hello")')
713
713
714 def test_run_cell(self):
714 def test_run_cell(self):
715 with tt.AssertPrints("-34"):
715 with tt.AssertPrints("-34"):
716 ip.run_cell("print(12 + 22)")
716 ip.run_cell("print(12 + 22)")
717
717
718 # A named reference to a number shouldn't be transformed.
718 # A named reference to a number shouldn't be transformed.
719 ip.user_ns["n"] = 55
719 ip.user_ns["n"] = 55
720 with tt.AssertNotPrints("-55"):
720 with tt.AssertNotPrints("-55"):
721 ip.run_cell("print(n)")
721 ip.run_cell("print(n)")
722
722
723 def test_timeit(self):
723 def test_timeit(self):
724 called = set()
724 called = set()
725 def f(x):
725 def f(x):
726 called.add(x)
726 called.add(x)
727 ip.push({'f':f})
727 ip.push({'f':f})
728
728
729 with tt.AssertPrints("std. dev. of"):
729 with tt.AssertPrints("std. dev. of"):
730 ip.run_line_magic("timeit", "-n1 f(1)")
730 ip.run_line_magic("timeit", "-n1 f(1)")
731 self.assertEqual(called, {-1})
731 self.assertEqual(called, {-1})
732 called.clear()
732 called.clear()
733
733
734 with tt.AssertPrints("std. dev. of"):
734 with tt.AssertPrints("std. dev. of"):
735 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
735 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
736 self.assertEqual(called, {-2, -3})
736 self.assertEqual(called, {-2, -3})
737
737
738 def test_time(self):
738 def test_time(self):
739 called = []
739 called = []
740 def f(x):
740 def f(x):
741 called.append(x)
741 called.append(x)
742 ip.push({'f':f})
742 ip.push({'f':f})
743
743
744 # Test with an expression
744 # Test with an expression
745 with tt.AssertPrints("Wall time: "):
745 with tt.AssertPrints("Wall time: "):
746 ip.run_line_magic("time", "f(5+9)")
746 ip.run_line_magic("time", "f(5+9)")
747 self.assertEqual(called, [-14])
747 self.assertEqual(called, [-14])
748 called[:] = []
748 called[:] = []
749
749
750 # Test with a statement (different code path)
750 # Test with a statement (different code path)
751 with tt.AssertPrints("Wall time: "):
751 with tt.AssertPrints("Wall time: "):
752 ip.run_line_magic("time", "a = f(-3 + -2)")
752 ip.run_line_magic("time", "a = f(-3 + -2)")
753 self.assertEqual(called, [5])
753 self.assertEqual(called, [5])
754
754
755 def test_macro(self):
755 def test_macro(self):
756 ip.push({'a':10})
756 ip.push({'a':10})
757 # The AST transformation makes this do a+=-1
757 # The AST transformation makes this do a+=-1
758 ip.define_macro("amacro", "a+=1\nprint(a)")
758 ip.define_macro("amacro", "a+=1\nprint(a)")
759
759
760 with tt.AssertPrints("9"):
760 with tt.AssertPrints("9"):
761 ip.run_cell("amacro")
761 ip.run_cell("amacro")
762 with tt.AssertPrints("8"):
762 with tt.AssertPrints("8"):
763 ip.run_cell("amacro")
763 ip.run_cell("amacro")
764
764
765 class TestMiscTransform(unittest.TestCase):
765 class TestMiscTransform(unittest.TestCase):
766
766
767
767
768 def test_transform_only_once(self):
768 def test_transform_only_once(self):
769 cleanup = 0
769 cleanup = 0
770 line_t = 0
770 line_t = 0
771 def count_cleanup(lines):
771 def count_cleanup(lines):
772 nonlocal cleanup
772 nonlocal cleanup
773 cleanup += 1
773 cleanup += 1
774 return lines
774 return lines
775
775
776 def count_line_t(lines):
776 def count_line_t(lines):
777 nonlocal line_t
777 nonlocal line_t
778 line_t += 1
778 line_t += 1
779 return lines
779 return lines
780
780
781 ip.input_transformer_manager.cleanup_transforms.append(count_cleanup)
781 ip.input_transformer_manager.cleanup_transforms.append(count_cleanup)
782 ip.input_transformer_manager.line_transforms.append(count_line_t)
782 ip.input_transformer_manager.line_transforms.append(count_line_t)
783
783
784 ip.run_cell('1')
784 ip.run_cell('1')
785
785
786 assert cleanup == 1
786 assert cleanup == 1
787 assert line_t == 1
787 assert line_t == 1
788
788
789 class IntegerWrapper(ast.NodeTransformer):
789 class IntegerWrapper(ast.NodeTransformer):
790 """Wraps all integers in a call to Integer()"""
790 """Wraps all integers in a call to Integer()"""
791
791
792 # for Python 3.7 and earlier
792 # for Python 3.7 and earlier
793
793
794 # for Python 3.7 and earlier
794 # for Python 3.7 and earlier
795 def visit_Num(self, node):
795 def visit_Num(self, node):
796 if isinstance(node.n, int):
796 if isinstance(node.n, int):
797 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
797 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
798 args=[node], keywords=[])
798 args=[node], keywords=[])
799 return node
799 return node
800
800
801 # For Python 3.8+
801 # For Python 3.8+
802 def visit_Constant(self, node):
802 def visit_Constant(self, node):
803 if isinstance(node.value, int):
803 if isinstance(node.value, int):
804 return self.visit_Num(node)
804 return self.visit_Num(node)
805 return node
805 return node
806
806
807
807
808 class TestAstTransform2(unittest.TestCase):
808 class TestAstTransform2(unittest.TestCase):
809 def setUp(self):
809 def setUp(self):
810 self.intwrapper = IntegerWrapper()
810 self.intwrapper = IntegerWrapper()
811 ip.ast_transformers.append(self.intwrapper)
811 ip.ast_transformers.append(self.intwrapper)
812
812
813 self.calls = []
813 self.calls = []
814 def Integer(*args):
814 def Integer(*args):
815 self.calls.append(args)
815 self.calls.append(args)
816 return args
816 return args
817 ip.push({"Integer": Integer})
817 ip.push({"Integer": Integer})
818
818
819 def tearDown(self):
819 def tearDown(self):
820 ip.ast_transformers.remove(self.intwrapper)
820 ip.ast_transformers.remove(self.intwrapper)
821 del ip.user_ns['Integer']
821 del ip.user_ns['Integer']
822
822
823 def test_run_cell(self):
823 def test_run_cell(self):
824 ip.run_cell("n = 2")
824 ip.run_cell("n = 2")
825 self.assertEqual(self.calls, [(2,)])
825 self.assertEqual(self.calls, [(2,)])
826
826
827 # This shouldn't throw an error
827 # This shouldn't throw an error
828 ip.run_cell("o = 2.0")
828 ip.run_cell("o = 2.0")
829 self.assertEqual(ip.user_ns['o'], 2.0)
829 self.assertEqual(ip.user_ns['o'], 2.0)
830
830
831 def test_run_cell_non_int(self):
831 def test_run_cell_non_int(self):
832 ip.run_cell("n = 'a'")
832 ip.run_cell("n = 'a'")
833 assert self.calls == []
833 assert self.calls == []
834
834
835 def test_timeit(self):
835 def test_timeit(self):
836 called = set()
836 called = set()
837 def f(x):
837 def f(x):
838 called.add(x)
838 called.add(x)
839 ip.push({'f':f})
839 ip.push({'f':f})
840
840
841 with tt.AssertPrints("std. dev. of"):
841 with tt.AssertPrints("std. dev. of"):
842 ip.run_line_magic("timeit", "-n1 f(1)")
842 ip.run_line_magic("timeit", "-n1 f(1)")
843 self.assertEqual(called, {(1,)})
843 self.assertEqual(called, {(1,)})
844 called.clear()
844 called.clear()
845
845
846 with tt.AssertPrints("std. dev. of"):
846 with tt.AssertPrints("std. dev. of"):
847 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
847 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
848 self.assertEqual(called, {(2,), (3,)})
848 self.assertEqual(called, {(2,), (3,)})
849
849
850 class ErrorTransformer(ast.NodeTransformer):
850 class ErrorTransformer(ast.NodeTransformer):
851 """Throws an error when it sees a number."""
851 """Throws an error when it sees a number."""
852
852
853 def visit_Constant(self, node):
853 def visit_Constant(self, node):
854 if isinstance(node.value, int):
854 if isinstance(node.value, int):
855 raise ValueError("test")
855 raise ValueError("test")
856 return node
856 return node
857
857
858
858
859 class TestAstTransformError(unittest.TestCase):
859 class TestAstTransformError(unittest.TestCase):
860 def test_unregistering(self):
860 def test_unregistering(self):
861 err_transformer = ErrorTransformer()
861 err_transformer = ErrorTransformer()
862 ip.ast_transformers.append(err_transformer)
862 ip.ast_transformers.append(err_transformer)
863
863
864 with self.assertWarnsRegex(UserWarning, "It will be unregistered"):
864 with self.assertWarnsRegex(UserWarning, "It will be unregistered"):
865 ip.run_cell("1 + 2")
865 ip.run_cell("1 + 2")
866
866
867 # This should have been removed.
867 # This should have been removed.
868 self.assertNotIn(err_transformer, ip.ast_transformers)
868 self.assertNotIn(err_transformer, ip.ast_transformers)
869
869
870
870
871 class StringRejector(ast.NodeTransformer):
871 class StringRejector(ast.NodeTransformer):
872 """Throws an InputRejected when it sees a string literal.
872 """Throws an InputRejected when it sees a string literal.
873
873
874 Used to verify that NodeTransformers can signal that a piece of code should
874 Used to verify that NodeTransformers can signal that a piece of code should
875 not be executed by throwing an InputRejected.
875 not be executed by throwing an InputRejected.
876 """
876 """
877
877
878 # 3.8 only
878 # 3.8 only
879 def visit_Constant(self, node):
879 def visit_Constant(self, node):
880 if isinstance(node.value, str):
880 if isinstance(node.value, str):
881 raise InputRejected("test")
881 raise InputRejected("test")
882 return node
882 return node
883
883
884
884
885 class TestAstTransformInputRejection(unittest.TestCase):
885 class TestAstTransformInputRejection(unittest.TestCase):
886
886
887 def setUp(self):
887 def setUp(self):
888 self.transformer = StringRejector()
888 self.transformer = StringRejector()
889 ip.ast_transformers.append(self.transformer)
889 ip.ast_transformers.append(self.transformer)
890
890
891 def tearDown(self):
891 def tearDown(self):
892 ip.ast_transformers.remove(self.transformer)
892 ip.ast_transformers.remove(self.transformer)
893
893
894 def test_input_rejection(self):
894 def test_input_rejection(self):
895 """Check that NodeTransformers can reject input."""
895 """Check that NodeTransformers can reject input."""
896
896
897 expect_exception_tb = tt.AssertPrints("InputRejected: test")
897 expect_exception_tb = tt.AssertPrints("InputRejected: test")
898 expect_no_cell_output = tt.AssertNotPrints("'unsafe'", suppress=False)
898 expect_no_cell_output = tt.AssertNotPrints("'unsafe'", suppress=False)
899
899
900 # Run the same check twice to verify that the transformer is not
900 # Run the same check twice to verify that the transformer is not
901 # disabled after raising.
901 # disabled after raising.
902 with expect_exception_tb, expect_no_cell_output:
902 with expect_exception_tb, expect_no_cell_output:
903 ip.run_cell("'unsafe'")
903 ip.run_cell("'unsafe'")
904
904
905 with expect_exception_tb, expect_no_cell_output:
905 with expect_exception_tb, expect_no_cell_output:
906 res = ip.run_cell("'unsafe'")
906 res = ip.run_cell("'unsafe'")
907
907
908 self.assertIsInstance(res.error_before_exec, InputRejected)
908 self.assertIsInstance(res.error_before_exec, InputRejected)
909
909
910 def test__IPYTHON__():
910 def test__IPYTHON__():
911 # This shouldn't raise a NameError, that's all
911 # This shouldn't raise a NameError, that's all
912 __IPYTHON__
912 __IPYTHON__
913
913
914
914
915 class DummyRepr(object):
915 class DummyRepr(object):
916 def __repr__(self):
916 def __repr__(self):
917 return "DummyRepr"
917 return "DummyRepr"
918
918
919 def _repr_html_(self):
919 def _repr_html_(self):
920 return "<b>dummy</b>"
920 return "<b>dummy</b>"
921
921
922 def _repr_javascript_(self):
922 def _repr_javascript_(self):
923 return "console.log('hi');", {'key': 'value'}
923 return "console.log('hi');", {'key': 'value'}
924
924
925
925
926 def test_user_variables():
926 def test_user_variables():
927 # enable all formatters
927 # enable all formatters
928 ip.display_formatter.active_types = ip.display_formatter.format_types
928 ip.display_formatter.active_types = ip.display_formatter.format_types
929
929
930 ip.user_ns['dummy'] = d = DummyRepr()
930 ip.user_ns['dummy'] = d = DummyRepr()
931 keys = {'dummy', 'doesnotexist'}
931 keys = {'dummy', 'doesnotexist'}
932 r = ip.user_expressions({ key:key for key in keys})
932 r = ip.user_expressions({ key:key for key in keys})
933
933
934 assert keys == set(r.keys())
934 assert keys == set(r.keys())
935 dummy = r["dummy"]
935 dummy = r["dummy"]
936 assert {"status", "data", "metadata"} == set(dummy.keys())
936 assert {"status", "data", "metadata"} == set(dummy.keys())
937 assert dummy["status"] == "ok"
937 assert dummy["status"] == "ok"
938 data = dummy["data"]
938 data = dummy["data"]
939 metadata = dummy["metadata"]
939 metadata = dummy["metadata"]
940 assert data.get("text/html") == d._repr_html_()
940 assert data.get("text/html") == d._repr_html_()
941 js, jsmd = d._repr_javascript_()
941 js, jsmd = d._repr_javascript_()
942 assert data.get("application/javascript") == js
942 assert data.get("application/javascript") == js
943 assert metadata.get("application/javascript") == jsmd
943 assert metadata.get("application/javascript") == jsmd
944
944
945 dne = r["doesnotexist"]
945 dne = r["doesnotexist"]
946 assert dne["status"] == "error"
946 assert dne["status"] == "error"
947 assert dne["ename"] == "NameError"
947 assert dne["ename"] == "NameError"
948
948
949 # back to text only
949 # back to text only
950 ip.display_formatter.active_types = ['text/plain']
950 ip.display_formatter.active_types = ['text/plain']
951
951
952 def test_user_expression():
952 def test_user_expression():
953 # enable all formatters
953 # enable all formatters
954 ip.display_formatter.active_types = ip.display_formatter.format_types
954 ip.display_formatter.active_types = ip.display_formatter.format_types
955 query = {
955 query = {
956 'a' : '1 + 2',
956 'a' : '1 + 2',
957 'b' : '1/0',
957 'b' : '1/0',
958 }
958 }
959 r = ip.user_expressions(query)
959 r = ip.user_expressions(query)
960 import pprint
960 import pprint
961 pprint.pprint(r)
961 pprint.pprint(r)
962 assert set(r.keys()) == set(query.keys())
962 assert set(r.keys()) == set(query.keys())
963 a = r["a"]
963 a = r["a"]
964 assert {"status", "data", "metadata"} == set(a.keys())
964 assert {"status", "data", "metadata"} == set(a.keys())
965 assert a["status"] == "ok"
965 assert a["status"] == "ok"
966 data = a["data"]
966 data = a["data"]
967 metadata = a["metadata"]
967 metadata = a["metadata"]
968 assert data.get("text/plain") == "3"
968 assert data.get("text/plain") == "3"
969
969
970 b = r["b"]
970 b = r["b"]
971 assert b["status"] == "error"
971 assert b["status"] == "error"
972 assert b["ename"] == "ZeroDivisionError"
972 assert b["ename"] == "ZeroDivisionError"
973
973
974 # back to text only
974 # back to text only
975 ip.display_formatter.active_types = ['text/plain']
975 ip.display_formatter.active_types = ['text/plain']
976
976
977
977
978 class TestSyntaxErrorTransformer(unittest.TestCase):
978 class TestSyntaxErrorTransformer(unittest.TestCase):
979 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
979 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
980
980
981 @staticmethod
981 @staticmethod
982 def transformer(lines):
982 def transformer(lines):
983 for line in lines:
983 for line in lines:
984 pos = line.find('syntaxerror')
984 pos = line.find('syntaxerror')
985 if pos >= 0:
985 if pos >= 0:
986 e = SyntaxError('input contains "syntaxerror"')
986 e = SyntaxError('input contains "syntaxerror"')
987 e.text = line
987 e.text = line
988 e.offset = pos + 1
988 e.offset = pos + 1
989 raise e
989 raise e
990 return lines
990 return lines
991
991
992 def setUp(self):
992 def setUp(self):
993 ip.input_transformers_post.append(self.transformer)
993 ip.input_transformers_post.append(self.transformer)
994
994
995 def tearDown(self):
995 def tearDown(self):
996 ip.input_transformers_post.remove(self.transformer)
996 ip.input_transformers_post.remove(self.transformer)
997
997
998 def test_syntaxerror_input_transformer(self):
998 def test_syntaxerror_input_transformer(self):
999 with tt.AssertPrints('1234'):
999 with tt.AssertPrints('1234'):
1000 ip.run_cell('1234')
1000 ip.run_cell('1234')
1001 with tt.AssertPrints('SyntaxError: invalid syntax'):
1001 with tt.AssertPrints('SyntaxError: invalid syntax'):
1002 ip.run_cell('1 2 3') # plain python syntax error
1002 ip.run_cell('1 2 3') # plain python syntax error
1003 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
1003 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
1004 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
1004 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
1005 with tt.AssertPrints('3456'):
1005 with tt.AssertPrints('3456'):
1006 ip.run_cell('3456')
1006 ip.run_cell('3456')
1007
1007
1008
1008
1009 class TestWarningSuppression(unittest.TestCase):
1009 class TestWarningSuppression(unittest.TestCase):
1010 def test_warning_suppression(self):
1010 def test_warning_suppression(self):
1011 ip.run_cell("import warnings")
1011 ip.run_cell("import warnings")
1012 try:
1012 try:
1013 with self.assertWarnsRegex(UserWarning, "asdf"):
1013 with self.assertWarnsRegex(UserWarning, "asdf"):
1014 ip.run_cell("warnings.warn('asdf')")
1014 ip.run_cell("warnings.warn('asdf')")
1015 # Here's the real test -- if we run that again, we should get the
1015 # Here's the real test -- if we run that again, we should get the
1016 # warning again. Traditionally, each warning was only issued once per
1016 # warning again. Traditionally, each warning was only issued once per
1017 # IPython session (approximately), even if the user typed in new and
1017 # IPython session (approximately), even if the user typed in new and
1018 # different code that should have also triggered the warning, leading
1018 # different code that should have also triggered the warning, leading
1019 # to much confusion.
1019 # to much confusion.
1020 with self.assertWarnsRegex(UserWarning, "asdf"):
1020 with self.assertWarnsRegex(UserWarning, "asdf"):
1021 ip.run_cell("warnings.warn('asdf')")
1021 ip.run_cell("warnings.warn('asdf')")
1022 finally:
1022 finally:
1023 ip.run_cell("del warnings")
1023 ip.run_cell("del warnings")
1024
1024
1025
1025
1026 def test_deprecation_warning(self):
1026 def test_deprecation_warning(self):
1027 ip.run_cell("""
1027 ip.run_cell("""
1028 import warnings
1028 import warnings
1029 def wrn():
1029 def wrn():
1030 warnings.warn(
1030 warnings.warn(
1031 "I AM A WARNING",
1031 "I AM A WARNING",
1032 DeprecationWarning
1032 DeprecationWarning
1033 )
1033 )
1034 """)
1034 """)
1035 try:
1035 try:
1036 with self.assertWarnsRegex(DeprecationWarning, "I AM A WARNING"):
1036 with self.assertWarnsRegex(DeprecationWarning, "I AM A WARNING"):
1037 ip.run_cell("wrn()")
1037 ip.run_cell("wrn()")
1038 finally:
1038 finally:
1039 ip.run_cell("del warnings")
1039 ip.run_cell("del warnings")
1040 ip.run_cell("del wrn")
1040 ip.run_cell("del wrn")
1041
1041
1042
1042
1043 class TestImportNoDeprecate(tt.TempFileMixin):
1043 class TestImportNoDeprecate(tt.TempFileMixin):
1044
1044
1045 def setUp(self):
1045 def setUp(self):
1046 """Make a valid python temp file."""
1046 """Make a valid python temp file."""
1047 self.mktmp("""
1047 self.mktmp("""
1048 import warnings
1048 import warnings
1049 def wrn():
1049 def wrn():
1050 warnings.warn(
1050 warnings.warn(
1051 "I AM A WARNING",
1051 "I AM A WARNING",
1052 DeprecationWarning
1052 DeprecationWarning
1053 )
1053 )
1054 """)
1054 """)
1055 super().setUp()
1055 super().setUp()
1056
1056
1057 def test_no_dep(self):
1057 def test_no_dep(self):
1058 """
1058 """
1059 No deprecation warning should be raised from imported functions
1059 No deprecation warning should be raised from imported functions
1060 """
1060 """
1061 ip.run_cell("from {} import wrn".format(self.fname))
1061 ip.run_cell("from {} import wrn".format(self.fname))
1062
1062
1063 with tt.AssertNotPrints("I AM A WARNING"):
1063 with tt.AssertNotPrints("I AM A WARNING"):
1064 ip.run_cell("wrn()")
1064 ip.run_cell("wrn()")
1065 ip.run_cell("del wrn")
1065 ip.run_cell("del wrn")
1066
1066
1067
1067
1068 def test_custom_exc_count():
1068 def test_custom_exc_count():
1069 hook = mock.Mock(return_value=None)
1069 hook = mock.Mock(return_value=None)
1070 ip.set_custom_exc((SyntaxError,), hook)
1070 ip.set_custom_exc((SyntaxError,), hook)
1071 before = ip.execution_count
1071 before = ip.execution_count
1072 ip.run_cell("def foo()", store_history=True)
1072 ip.run_cell("def foo()", store_history=True)
1073 # restore default excepthook
1073 # restore default excepthook
1074 ip.set_custom_exc((), None)
1074 ip.set_custom_exc((), None)
1075 assert hook.call_count == 1
1075 assert hook.call_count == 1
1076 assert ip.execution_count == before + 1
1076 assert ip.execution_count == before + 1
1077
1077
1078
1078
1079 def test_run_cell_async():
1079 def test_run_cell_async():
1080 ip.run_cell("import asyncio")
1080 ip.run_cell("import asyncio")
1081 coro = ip.run_cell_async("await asyncio.sleep(0.01)\n5")
1081 coro = ip.run_cell_async("await asyncio.sleep(0.01)\n5")
1082 assert asyncio.iscoroutine(coro)
1082 assert asyncio.iscoroutine(coro)
1083 loop = asyncio.new_event_loop()
1083 loop = asyncio.new_event_loop()
1084 result = loop.run_until_complete(coro)
1084 result = loop.run_until_complete(coro)
1085 assert isinstance(result, interactiveshell.ExecutionResult)
1085 assert isinstance(result, interactiveshell.ExecutionResult)
1086 assert result.result == 5
1086 assert result.result == 5
1087
1087
1088
1088
1089 def test_run_cell_await():
1089 def test_run_cell_await():
1090 ip.run_cell("import asyncio")
1090 ip.run_cell("import asyncio")
1091 result = ip.run_cell("await asyncio.sleep(0.01); 10")
1091 result = ip.run_cell("await asyncio.sleep(0.01); 10")
1092 assert ip.user_ns["_"] == 10
1092 assert ip.user_ns["_"] == 10
1093
1093
1094
1094
1095 def test_run_cell_asyncio_run():
1095 def test_run_cell_asyncio_run():
1096 ip.run_cell("import asyncio")
1096 ip.run_cell("import asyncio")
1097 result = ip.run_cell("await asyncio.sleep(0.01); 1")
1097 result = ip.run_cell("await asyncio.sleep(0.01); 1")
1098 assert ip.user_ns["_"] == 1
1098 assert ip.user_ns["_"] == 1
1099 result = ip.run_cell("asyncio.run(asyncio.sleep(0.01)); 2")
1099 result = ip.run_cell("asyncio.run(asyncio.sleep(0.01)); 2")
1100 assert ip.user_ns["_"] == 2
1100 assert ip.user_ns["_"] == 2
1101 result = ip.run_cell("await asyncio.sleep(0.01); 3")
1101 result = ip.run_cell("await asyncio.sleep(0.01); 3")
1102 assert ip.user_ns["_"] == 3
1102 assert ip.user_ns["_"] == 3
1103
1103
1104
1104
1105 def test_should_run_async():
1105 def test_should_run_async():
1106 assert not ip.should_run_async("a = 5", transformed_cell="a = 5")
1106 assert not ip.should_run_async("a = 5", transformed_cell="a = 5")
1107 assert ip.should_run_async("await x", transformed_cell="await x")
1107 assert ip.should_run_async("await x", transformed_cell="await x")
1108 assert ip.should_run_async(
1108 assert ip.should_run_async(
1109 "import asyncio; await asyncio.sleep(1)",
1109 "import asyncio; await asyncio.sleep(1)",
1110 transformed_cell="import asyncio; await asyncio.sleep(1)",
1110 transformed_cell="import asyncio; await asyncio.sleep(1)",
1111 )
1111 )
1112
1112
1113
1113
1114 def test_set_custom_completer():
1114 def test_set_custom_completer():
1115 num_completers = len(ip.Completer.matchers)
1115 num_completers = len(ip.Completer.matchers)
1116
1116
1117 def foo(*args, **kwargs):
1117 def foo(*args, **kwargs):
1118 return "I'm a completer!"
1118 return "I'm a completer!"
1119
1119
1120 ip.set_custom_completer(foo, 0)
1120 ip.set_custom_completer(foo, 0)
1121
1121
1122 # check that we've really added a new completer
1122 # check that we've really added a new completer
1123 assert len(ip.Completer.matchers) == num_completers + 1
1123 assert len(ip.Completer.matchers) == num_completers + 1
1124
1124
1125 # check that the first completer is the function we defined
1125 # check that the first completer is the function we defined
1126 assert ip.Completer.matchers[0]() == "I'm a completer!"
1126 assert ip.Completer.matchers[0]() == "I'm a completer!"
1127
1127
1128 # clean up
1128 # clean up
1129 ip.Completer.custom_matchers.pop()
1129 ip.Completer.custom_matchers.pop()
1130
1131
1132 class TestShowTracebackAttack(unittest.TestCase):
1133 """Test that the interactive shell is resilient against the client attack of
1134 manipulating the showtracebacks method. These attacks shouldn't result in an
1135 unhandled exception in the kernel."""
1136
1137 def setUp(self):
1138 self.orig_showtraceback = interactiveshell.InteractiveShell.showtraceback
1139
1140 def tearDown(self):
1141 interactiveshell.InteractiveShell.showtraceback = self.orig_showtraceback
1142
1143 def test_set_show_tracebacks_none(self):
1144 """Test the case of the client setting showtracebacks to None"""
1145
1146 result = ip.run_cell(
1147 """
1148 import IPython.core.interactiveshell
1149 IPython.core.interactiveshell.InteractiveShell.showtraceback = None
1150
1151 assert False, "This should not raise an exception"
1152 """
1153 )
1154 print(result)
1155
1156 assert result.result is None
1157 assert isinstance(result.error_in_exec, TypeError)
1158 assert str(result.error_in_exec) == "'NoneType' object is not callable"
1159
1160 def test_set_show_tracebacks_noop(self):
1161 """Test the case of the client setting showtracebacks to a no op lambda"""
1162
1163 result = ip.run_cell(
1164 """
1165 import IPython.core.interactiveshell
1166 IPython.core.interactiveshell.InteractiveShell.showtraceback = lambda *args, **kwargs: None
1167
1168 assert False, "This should not raise an exception"
1169 """
1170 )
1171 print(result)
1172
1173 assert result.result is None
1174 assert isinstance(result.error_in_exec, AssertionError)
1175 assert str(result.error_in_exec) == "This should not raise an exception"
General Comments 0
You need to be logged in to leave comments. Login now