##// END OF EJS Templates
Statically type OInfo. (#13973)...
Matthias Bussonnier -
r28166:29b451fc merge
parent child Browse files
Show More
@@ -1,3862 +1,3898 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, Dict as DictType, Any as AnyType
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 from IPython.core.oinspect import OInfo
94
93
95
94 sphinxify: Optional[Callable]
96 sphinxify: Optional[Callable]
95
97
96 try:
98 try:
97 import docrepr.sphinxify as sphx
99 import docrepr.sphinxify as sphx
98
100
99 def sphinxify(oinfo):
101 def sphinxify(oinfo):
100 wrapped_docstring = sphx.wrap_main_docstring(oinfo)
102 wrapped_docstring = sphx.wrap_main_docstring(oinfo)
101
103
102 def sphinxify_docstring(docstring):
104 def sphinxify_docstring(docstring):
103 with TemporaryDirectory() as dirname:
105 with TemporaryDirectory() as dirname:
104 return {
106 return {
105 "text/html": sphx.sphinxify(wrapped_docstring, dirname),
107 "text/html": sphx.sphinxify(wrapped_docstring, dirname),
106 "text/plain": docstring,
108 "text/plain": docstring,
107 }
109 }
108
110
109 return sphinxify_docstring
111 return sphinxify_docstring
110 except ImportError:
112 except ImportError:
111 sphinxify = None
113 sphinxify = None
112
114
113
115
114 class ProvisionalWarning(DeprecationWarning):
116 class ProvisionalWarning(DeprecationWarning):
115 """
117 """
116 Warning class for unstable features
118 Warning class for unstable features
117 """
119 """
118 pass
120 pass
119
121
120 from ast import Module
122 from ast import Module
121
123
122 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
124 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
123 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
125 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
124
126
125 #-----------------------------------------------------------------------------
127 #-----------------------------------------------------------------------------
126 # Await Helpers
128 # Await Helpers
127 #-----------------------------------------------------------------------------
129 #-----------------------------------------------------------------------------
128
130
129 # we still need to run things using the asyncio eventloop, but there is no
131 # we still need to run things using the asyncio eventloop, but there is no
130 # async integration
132 # async integration
131 from .async_helpers import (
133 from .async_helpers import (
132 _asyncio_runner,
134 _asyncio_runner,
133 _curio_runner,
135 _curio_runner,
134 _pseudo_sync_runner,
136 _pseudo_sync_runner,
135 _should_be_async,
137 _should_be_async,
136 _trio_runner,
138 _trio_runner,
137 )
139 )
138
140
139 #-----------------------------------------------------------------------------
141 #-----------------------------------------------------------------------------
140 # Globals
142 # Globals
141 #-----------------------------------------------------------------------------
143 #-----------------------------------------------------------------------------
142
144
143 # compiled regexps for autoindent management
145 # compiled regexps for autoindent management
144 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
146 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
145
147
146 #-----------------------------------------------------------------------------
148 #-----------------------------------------------------------------------------
147 # Utilities
149 # Utilities
148 #-----------------------------------------------------------------------------
150 #-----------------------------------------------------------------------------
149
151
150
152
151 def is_integer_string(s: str):
153 def is_integer_string(s: str):
152 """
154 """
153 Variant of "str.isnumeric()" that allow negative values and other ints.
155 Variant of "str.isnumeric()" that allow negative values and other ints.
154 """
156 """
155 try:
157 try:
156 int(s)
158 int(s)
157 return True
159 return True
158 except ValueError:
160 except ValueError:
159 return False
161 return False
160 raise ValueError("Unexpected error")
162 raise ValueError("Unexpected error")
161
163
162
164
163 @undoc
165 @undoc
164 def softspace(file, newvalue):
166 def softspace(file, newvalue):
165 """Copied from code.py, to remove the dependency"""
167 """Copied from code.py, to remove the dependency"""
166
168
167 oldvalue = 0
169 oldvalue = 0
168 try:
170 try:
169 oldvalue = file.softspace
171 oldvalue = file.softspace
170 except AttributeError:
172 except AttributeError:
171 pass
173 pass
172 try:
174 try:
173 file.softspace = newvalue
175 file.softspace = newvalue
174 except (AttributeError, TypeError):
176 except (AttributeError, TypeError):
175 # "attribute-less object" or "read-only attributes"
177 # "attribute-less object" or "read-only attributes"
176 pass
178 pass
177 return oldvalue
179 return oldvalue
178
180
179 @undoc
181 @undoc
180 def no_op(*a, **kw):
182 def no_op(*a, **kw):
181 pass
183 pass
182
184
183
185
184 class SpaceInInput(Exception): pass
186 class SpaceInInput(Exception): pass
185
187
186
188
187 class SeparateUnicode(Unicode):
189 class SeparateUnicode(Unicode):
188 r"""A Unicode subclass to validate separate_in, separate_out, etc.
190 r"""A Unicode subclass to validate separate_in, separate_out, etc.
189
191
190 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
192 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
191 """
193 """
192
194
193 def validate(self, obj, value):
195 def validate(self, obj, value):
194 if value == '0': value = ''
196 if value == '0': value = ''
195 value = value.replace('\\n','\n')
197 value = value.replace('\\n','\n')
196 return super(SeparateUnicode, self).validate(obj, value)
198 return super(SeparateUnicode, self).validate(obj, value)
197
199
198
200
199 @undoc
201 @undoc
200 class DummyMod(object):
202 class DummyMod(object):
201 """A dummy module used for IPython's interactive module when
203 """A dummy module used for IPython's interactive module when
202 a namespace must be assigned to the module's __dict__."""
204 a namespace must be assigned to the module's __dict__."""
203 __spec__ = None
205 __spec__ = None
204
206
205
207
206 class ExecutionInfo(object):
208 class ExecutionInfo(object):
207 """The arguments used for a call to :meth:`InteractiveShell.run_cell`
209 """The arguments used for a call to :meth:`InteractiveShell.run_cell`
208
210
209 Stores information about what is going to happen.
211 Stores information about what is going to happen.
210 """
212 """
211 raw_cell = None
213 raw_cell = None
212 store_history = False
214 store_history = False
213 silent = False
215 silent = False
214 shell_futures = True
216 shell_futures = True
215 cell_id = None
217 cell_id = None
216
218
217 def __init__(self, raw_cell, store_history, silent, shell_futures, cell_id):
219 def __init__(self, raw_cell, store_history, silent, shell_futures, cell_id):
218 self.raw_cell = raw_cell
220 self.raw_cell = raw_cell
219 self.store_history = store_history
221 self.store_history = store_history
220 self.silent = silent
222 self.silent = silent
221 self.shell_futures = shell_futures
223 self.shell_futures = shell_futures
222 self.cell_id = cell_id
224 self.cell_id = cell_id
223
225
224 def __repr__(self):
226 def __repr__(self):
225 name = self.__class__.__qualname__
227 name = self.__class__.__qualname__
226 raw_cell = (
228 raw_cell = (
227 (self.raw_cell[:50] + "..") if len(self.raw_cell) > 50 else self.raw_cell
229 (self.raw_cell[:50] + "..") if len(self.raw_cell) > 50 else self.raw_cell
228 )
230 )
229 return (
231 return (
230 '<%s object at %x, raw_cell="%s" store_history=%s silent=%s shell_futures=%s cell_id=%s>'
232 '<%s object at %x, raw_cell="%s" store_history=%s silent=%s shell_futures=%s cell_id=%s>'
231 % (
233 % (
232 name,
234 name,
233 id(self),
235 id(self),
234 raw_cell,
236 raw_cell,
235 self.store_history,
237 self.store_history,
236 self.silent,
238 self.silent,
237 self.shell_futures,
239 self.shell_futures,
238 self.cell_id,
240 self.cell_id,
239 )
241 )
240 )
242 )
241
243
242
244
243 class ExecutionResult(object):
245 class ExecutionResult(object):
244 """The result of a call to :meth:`InteractiveShell.run_cell`
246 """The result of a call to :meth:`InteractiveShell.run_cell`
245
247
246 Stores information about what took place.
248 Stores information about what took place.
247 """
249 """
248 execution_count = None
250 execution_count = None
249 error_before_exec = None
251 error_before_exec = None
250 error_in_exec: Optional[BaseException] = None
252 error_in_exec: Optional[BaseException] = None
251 info = None
253 info = None
252 result = None
254 result = None
253
255
254 def __init__(self, info):
256 def __init__(self, info):
255 self.info = info
257 self.info = info
256
258
257 @property
259 @property
258 def success(self):
260 def success(self):
259 return (self.error_before_exec is None) and (self.error_in_exec is None)
261 return (self.error_before_exec is None) and (self.error_in_exec is None)
260
262
261 def raise_error(self):
263 def raise_error(self):
262 """Reraises error if `success` is `False`, otherwise does nothing"""
264 """Reraises error if `success` is `False`, otherwise does nothing"""
263 if self.error_before_exec is not None:
265 if self.error_before_exec is not None:
264 raise self.error_before_exec
266 raise self.error_before_exec
265 if self.error_in_exec is not None:
267 if self.error_in_exec is not None:
266 raise self.error_in_exec
268 raise self.error_in_exec
267
269
268 def __repr__(self):
270 def __repr__(self):
269 name = self.__class__.__qualname__
271 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>' %\
272 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))
273 (name, id(self), self.execution_count, self.error_before_exec, self.error_in_exec, repr(self.info), repr(self.result))
272
274
273 @functools.wraps(io_open)
275 @functools.wraps(io_open)
274 def _modified_open(file, *args, **kwargs):
276 def _modified_open(file, *args, **kwargs):
275 if file in {0, 1, 2}:
277 if file in {0, 1, 2}:
276 raise ValueError(
278 raise ValueError(
277 f"IPython won't let you open fd={file} by default "
279 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, "
280 "as it is likely to crash IPython. If you know what you are doing, "
279 "you can use builtins' open."
281 "you can use builtins' open."
280 )
282 )
281
283
282 return io_open(file, *args, **kwargs)
284 return io_open(file, *args, **kwargs)
283
285
284 class InteractiveShell(SingletonConfigurable):
286 class InteractiveShell(SingletonConfigurable):
285 """An enhanced, interactive shell for Python."""
287 """An enhanced, interactive shell for Python."""
286
288
287 _instance = None
289 _instance = None
288
290
289 ast_transformers = List([], help=
291 ast_transformers = List([], help=
290 """
292 """
291 A list of ast.NodeTransformer subclass instances, which will be applied
293 A list of ast.NodeTransformer subclass instances, which will be applied
292 to user input before code is run.
294 to user input before code is run.
293 """
295 """
294 ).tag(config=True)
296 ).tag(config=True)
295
297
296 autocall = Enum((0,1,2), default_value=0, help=
298 autocall = Enum((0,1,2), default_value=0, help=
297 """
299 """
298 Make IPython automatically call any callable object even if you didn't
300 Make IPython automatically call any callable object even if you didn't
299 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
301 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
300 automatically. The value can be '0' to disable the feature, '1' for
302 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
303 '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
304 arguments on the line, and '2' for 'full' autocall, where all callable
303 objects are automatically called (even if no arguments are present).
305 objects are automatically called (even if no arguments are present).
304 """
306 """
305 ).tag(config=True)
307 ).tag(config=True)
306
308
307 autoindent = Bool(True, help=
309 autoindent = Bool(True, help=
308 """
310 """
309 Autoindent IPython code entered interactively.
311 Autoindent IPython code entered interactively.
310 """
312 """
311 ).tag(config=True)
313 ).tag(config=True)
312
314
313 autoawait = Bool(True, help=
315 autoawait = Bool(True, help=
314 """
316 """
315 Automatically run await statement in the top level repl.
317 Automatically run await statement in the top level repl.
316 """
318 """
317 ).tag(config=True)
319 ).tag(config=True)
318
320
319 loop_runner_map ={
321 loop_runner_map ={
320 'asyncio':(_asyncio_runner, True),
322 'asyncio':(_asyncio_runner, True),
321 'curio':(_curio_runner, True),
323 'curio':(_curio_runner, True),
322 'trio':(_trio_runner, True),
324 'trio':(_trio_runner, True),
323 'sync': (_pseudo_sync_runner, False)
325 'sync': (_pseudo_sync_runner, False)
324 }
326 }
325
327
326 loop_runner = Any(default_value="IPython.core.interactiveshell._asyncio_runner",
328 loop_runner = Any(default_value="IPython.core.interactiveshell._asyncio_runner",
327 allow_none=True,
329 allow_none=True,
328 help="""Select the loop runner that will be used to execute top-level asynchronous code"""
330 help="""Select the loop runner that will be used to execute top-level asynchronous code"""
329 ).tag(config=True)
331 ).tag(config=True)
330
332
331 @default('loop_runner')
333 @default('loop_runner')
332 def _default_loop_runner(self):
334 def _default_loop_runner(self):
333 return import_item("IPython.core.interactiveshell._asyncio_runner")
335 return import_item("IPython.core.interactiveshell._asyncio_runner")
334
336
335 @validate('loop_runner')
337 @validate('loop_runner')
336 def _import_runner(self, proposal):
338 def _import_runner(self, proposal):
337 if isinstance(proposal.value, str):
339 if isinstance(proposal.value, str):
338 if proposal.value in self.loop_runner_map:
340 if proposal.value in self.loop_runner_map:
339 runner, autoawait = self.loop_runner_map[proposal.value]
341 runner, autoawait = self.loop_runner_map[proposal.value]
340 self.autoawait = autoawait
342 self.autoawait = autoawait
341 return runner
343 return runner
342 runner = import_item(proposal.value)
344 runner = import_item(proposal.value)
343 if not callable(runner):
345 if not callable(runner):
344 raise ValueError('loop_runner must be callable')
346 raise ValueError('loop_runner must be callable')
345 return runner
347 return runner
346 if not callable(proposal.value):
348 if not callable(proposal.value):
347 raise ValueError('loop_runner must be callable')
349 raise ValueError('loop_runner must be callable')
348 return proposal.value
350 return proposal.value
349
351
350 automagic = Bool(True, help=
352 automagic = Bool(True, help=
351 """
353 """
352 Enable magic commands to be called without the leading %.
354 Enable magic commands to be called without the leading %.
353 """
355 """
354 ).tag(config=True)
356 ).tag(config=True)
355
357
356 banner1 = Unicode(default_banner,
358 banner1 = Unicode(default_banner,
357 help="""The part of the banner to be printed before the profile"""
359 help="""The part of the banner to be printed before the profile"""
358 ).tag(config=True)
360 ).tag(config=True)
359 banner2 = Unicode('',
361 banner2 = Unicode('',
360 help="""The part of the banner to be printed after the profile"""
362 help="""The part of the banner to be printed after the profile"""
361 ).tag(config=True)
363 ).tag(config=True)
362
364
363 cache_size = Integer(1000, help=
365 cache_size = Integer(1000, help=
364 """
366 """
365 Set the size of the output cache. The default is 1000, you can
367 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
368 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
369 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
370 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
371 issued). This limit is defined because otherwise you'll spend more
370 time re-flushing a too small cache than working
372 time re-flushing a too small cache than working
371 """
373 """
372 ).tag(config=True)
374 ).tag(config=True)
373 color_info = Bool(True, help=
375 color_info = Bool(True, help=
374 """
376 """
375 Use colors for displaying information about objects. Because this
377 Use colors for displaying information about objects. Because this
376 information is passed through a pager (like 'less'), and some pagers
378 information is passed through a pager (like 'less'), and some pagers
377 get confused with color codes, this capability can be turned off.
379 get confused with color codes, this capability can be turned off.
378 """
380 """
379 ).tag(config=True)
381 ).tag(config=True)
380 colors = CaselessStrEnum(('Neutral', 'NoColor','LightBG','Linux'),
382 colors = CaselessStrEnum(('Neutral', 'NoColor','LightBG','Linux'),
381 default_value='Neutral',
383 default_value='Neutral',
382 help="Set the color scheme (NoColor, Neutral, Linux, or LightBG)."
384 help="Set the color scheme (NoColor, Neutral, Linux, or LightBG)."
383 ).tag(config=True)
385 ).tag(config=True)
384 debug = Bool(False).tag(config=True)
386 debug = Bool(False).tag(config=True)
385 disable_failing_post_execute = Bool(False,
387 disable_failing_post_execute = Bool(False,
386 help="Don't call post-execute functions that have failed in the past."
388 help="Don't call post-execute functions that have failed in the past."
387 ).tag(config=True)
389 ).tag(config=True)
388 display_formatter = Instance(DisplayFormatter, allow_none=True)
390 display_formatter = Instance(DisplayFormatter, allow_none=True)
389 displayhook_class = Type(DisplayHook)
391 displayhook_class = Type(DisplayHook)
390 display_pub_class = Type(DisplayPublisher)
392 display_pub_class = Type(DisplayPublisher)
391 compiler_class = Type(CachingCompiler)
393 compiler_class = Type(CachingCompiler)
392 inspector_class = Type(
394 inspector_class = Type(
393 oinspect.Inspector, help="Class to use to instantiate the shell inspector"
395 oinspect.Inspector, help="Class to use to instantiate the shell inspector"
394 ).tag(config=True)
396 ).tag(config=True)
395
397
396 sphinxify_docstring = Bool(False, help=
398 sphinxify_docstring = Bool(False, help=
397 """
399 """
398 Enables rich html representation of docstrings. (This requires the
400 Enables rich html representation of docstrings. (This requires the
399 docrepr module).
401 docrepr module).
400 """).tag(config=True)
402 """).tag(config=True)
401
403
402 @observe("sphinxify_docstring")
404 @observe("sphinxify_docstring")
403 def _sphinxify_docstring_changed(self, change):
405 def _sphinxify_docstring_changed(self, change):
404 if change['new']:
406 if change['new']:
405 warn("`sphinxify_docstring` is provisional since IPython 5.0 and might change in future versions." , ProvisionalWarning)
407 warn("`sphinxify_docstring` is provisional since IPython 5.0 and might change in future versions." , ProvisionalWarning)
406
408
407 enable_html_pager = Bool(False, help=
409 enable_html_pager = Bool(False, help=
408 """
410 """
409 (Provisional API) enables html representation in mime bundles sent
411 (Provisional API) enables html representation in mime bundles sent
410 to pagers.
412 to pagers.
411 """).tag(config=True)
413 """).tag(config=True)
412
414
413 @observe("enable_html_pager")
415 @observe("enable_html_pager")
414 def _enable_html_pager_changed(self, change):
416 def _enable_html_pager_changed(self, change):
415 if change['new']:
417 if change['new']:
416 warn("`enable_html_pager` is provisional since IPython 5.0 and might change in future versions.", ProvisionalWarning)
418 warn("`enable_html_pager` is provisional since IPython 5.0 and might change in future versions.", ProvisionalWarning)
417
419
418 data_pub_class = None
420 data_pub_class = None
419
421
420 exit_now = Bool(False)
422 exit_now = Bool(False)
421 exiter = Instance(ExitAutocall)
423 exiter = Instance(ExitAutocall)
422 @default('exiter')
424 @default('exiter')
423 def _exiter_default(self):
425 def _exiter_default(self):
424 return ExitAutocall(self)
426 return ExitAutocall(self)
425 # Monotonically increasing execution counter
427 # Monotonically increasing execution counter
426 execution_count = Integer(1)
428 execution_count = Integer(1)
427 filename = Unicode("<ipython console>")
429 filename = Unicode("<ipython console>")
428 ipython_dir= Unicode('').tag(config=True) # Set to get_ipython_dir() in __init__
430 ipython_dir= Unicode('').tag(config=True) # Set to get_ipython_dir() in __init__
429
431
430 # Used to transform cells before running them, and check whether code is complete
432 # Used to transform cells before running them, and check whether code is complete
431 input_transformer_manager = Instance('IPython.core.inputtransformer2.TransformerManager',
433 input_transformer_manager = Instance('IPython.core.inputtransformer2.TransformerManager',
432 ())
434 ())
433
435
434 @property
436 @property
435 def input_transformers_cleanup(self):
437 def input_transformers_cleanup(self):
436 return self.input_transformer_manager.cleanup_transforms
438 return self.input_transformer_manager.cleanup_transforms
437
439
438 input_transformers_post = List([],
440 input_transformers_post = List([],
439 help="A list of string input transformers, to be applied after IPython's "
441 help="A list of string input transformers, to be applied after IPython's "
440 "own input transformations."
442 "own input transformations."
441 )
443 )
442
444
443 @property
445 @property
444 def input_splitter(self):
446 def input_splitter(self):
445 """Make this available for backward compatibility (pre-7.0 release) with existing code.
447 """Make this available for backward compatibility (pre-7.0 release) with existing code.
446
448
447 For example, ipykernel ipykernel currently uses
449 For example, ipykernel ipykernel currently uses
448 `shell.input_splitter.check_complete`
450 `shell.input_splitter.check_complete`
449 """
451 """
450 from warnings import warn
452 from warnings import warn
451 warn("`input_splitter` is deprecated since IPython 7.0, prefer `input_transformer_manager`.",
453 warn("`input_splitter` is deprecated since IPython 7.0, prefer `input_transformer_manager`.",
452 DeprecationWarning, stacklevel=2
454 DeprecationWarning, stacklevel=2
453 )
455 )
454 return self.input_transformer_manager
456 return self.input_transformer_manager
455
457
456 logstart = Bool(False, help=
458 logstart = Bool(False, help=
457 """
459 """
458 Start logging to the default log file in overwrite mode.
460 Start logging to the default log file in overwrite mode.
459 Use `logappend` to specify a log file to **append** logs to.
461 Use `logappend` to specify a log file to **append** logs to.
460 """
462 """
461 ).tag(config=True)
463 ).tag(config=True)
462 logfile = Unicode('', help=
464 logfile = Unicode('', help=
463 """
465 """
464 The name of the logfile to use.
466 The name of the logfile to use.
465 """
467 """
466 ).tag(config=True)
468 ).tag(config=True)
467 logappend = Unicode('', help=
469 logappend = Unicode('', help=
468 """
470 """
469 Start logging to the given file in append mode.
471 Start logging to the given file in append mode.
470 Use `logfile` to specify a log file to **overwrite** logs to.
472 Use `logfile` to specify a log file to **overwrite** logs to.
471 """
473 """
472 ).tag(config=True)
474 ).tag(config=True)
473 object_info_string_level = Enum((0,1,2), default_value=0,
475 object_info_string_level = Enum((0,1,2), default_value=0,
474 ).tag(config=True)
476 ).tag(config=True)
475 pdb = Bool(False, help=
477 pdb = Bool(False, help=
476 """
478 """
477 Automatically call the pdb debugger after every exception.
479 Automatically call the pdb debugger after every exception.
478 """
480 """
479 ).tag(config=True)
481 ).tag(config=True)
480 display_page = Bool(False,
482 display_page = Bool(False,
481 help="""If True, anything that would be passed to the pager
483 help="""If True, anything that would be passed to the pager
482 will be displayed as regular output instead."""
484 will be displayed as regular output instead."""
483 ).tag(config=True)
485 ).tag(config=True)
484
486
485
487
486 show_rewritten_input = Bool(True,
488 show_rewritten_input = Bool(True,
487 help="Show rewritten input, e.g. for autocall."
489 help="Show rewritten input, e.g. for autocall."
488 ).tag(config=True)
490 ).tag(config=True)
489
491
490 quiet = Bool(False).tag(config=True)
492 quiet = Bool(False).tag(config=True)
491
493
492 history_length = Integer(10000,
494 history_length = Integer(10000,
493 help='Total length of command history'
495 help='Total length of command history'
494 ).tag(config=True)
496 ).tag(config=True)
495
497
496 history_load_length = Integer(1000, help=
498 history_load_length = Integer(1000, help=
497 """
499 """
498 The number of saved history entries to be loaded
500 The number of saved history entries to be loaded
499 into the history buffer at startup.
501 into the history buffer at startup.
500 """
502 """
501 ).tag(config=True)
503 ).tag(config=True)
502
504
503 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'],
505 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'],
504 default_value='last_expr',
506 default_value='last_expr',
505 help="""
507 help="""
506 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying
508 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying
507 which nodes should be run interactively (displaying output from expressions).
509 which nodes should be run interactively (displaying output from expressions).
508 """
510 """
509 ).tag(config=True)
511 ).tag(config=True)
510
512
511 warn_venv = Bool(
513 warn_venv = Bool(
512 True,
514 True,
513 help="Warn if running in a virtual environment with no IPython installed (so IPython from the global environment is used).",
515 help="Warn if running in a virtual environment with no IPython installed (so IPython from the global environment is used).",
514 ).tag(config=True)
516 ).tag(config=True)
515
517
516 # TODO: this part of prompt management should be moved to the frontends.
518 # TODO: this part of prompt management should be moved to the frontends.
517 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
519 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
518 separate_in = SeparateUnicode('\n').tag(config=True)
520 separate_in = SeparateUnicode('\n').tag(config=True)
519 separate_out = SeparateUnicode('').tag(config=True)
521 separate_out = SeparateUnicode('').tag(config=True)
520 separate_out2 = SeparateUnicode('').tag(config=True)
522 separate_out2 = SeparateUnicode('').tag(config=True)
521 wildcards_case_sensitive = Bool(True).tag(config=True)
523 wildcards_case_sensitive = Bool(True).tag(config=True)
522 xmode = CaselessStrEnum(('Context', 'Plain', 'Verbose', 'Minimal'),
524 xmode = CaselessStrEnum(('Context', 'Plain', 'Verbose', 'Minimal'),
523 default_value='Context',
525 default_value='Context',
524 help="Switch modes for the IPython exception handlers."
526 help="Switch modes for the IPython exception handlers."
525 ).tag(config=True)
527 ).tag(config=True)
526
528
527 # Subcomponents of InteractiveShell
529 # Subcomponents of InteractiveShell
528 alias_manager = Instance('IPython.core.alias.AliasManager', allow_none=True)
530 alias_manager = Instance('IPython.core.alias.AliasManager', allow_none=True)
529 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
531 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
530 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap', allow_none=True)
532 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap', allow_none=True)
531 display_trap = Instance('IPython.core.display_trap.DisplayTrap', allow_none=True)
533 display_trap = Instance('IPython.core.display_trap.DisplayTrap', allow_none=True)
532 extension_manager = Instance('IPython.core.extensions.ExtensionManager', allow_none=True)
534 extension_manager = Instance('IPython.core.extensions.ExtensionManager', allow_none=True)
533 payload_manager = Instance('IPython.core.payload.PayloadManager', allow_none=True)
535 payload_manager = Instance('IPython.core.payload.PayloadManager', allow_none=True)
534 history_manager = Instance('IPython.core.history.HistoryAccessorBase', allow_none=True)
536 history_manager = Instance('IPython.core.history.HistoryAccessorBase', allow_none=True)
535 magics_manager = Instance('IPython.core.magic.MagicsManager', allow_none=True)
537 magics_manager = Instance('IPython.core.magic.MagicsManager', allow_none=True)
536
538
537 profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True)
539 profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True)
538 @property
540 @property
539 def profile(self):
541 def profile(self):
540 if self.profile_dir is not None:
542 if self.profile_dir is not None:
541 name = os.path.basename(self.profile_dir.location)
543 name = os.path.basename(self.profile_dir.location)
542 return name.replace('profile_','')
544 return name.replace('profile_','')
543
545
544
546
545 # Private interface
547 # Private interface
546 _post_execute = Dict()
548 _post_execute = Dict()
547
549
548 # Tracks any GUI loop loaded for pylab
550 # Tracks any GUI loop loaded for pylab
549 pylab_gui_select = None
551 pylab_gui_select = None
550
552
551 last_execution_succeeded = Bool(True, help='Did last executed command succeeded')
553 last_execution_succeeded = Bool(True, help='Did last executed command succeeded')
552
554
553 last_execution_result = Instance('IPython.core.interactiveshell.ExecutionResult', help='Result of executing the last command', allow_none=True)
555 last_execution_result = Instance('IPython.core.interactiveshell.ExecutionResult', help='Result of executing the last command', allow_none=True)
554
556
555 def __init__(self, ipython_dir=None, profile_dir=None,
557 def __init__(self, ipython_dir=None, profile_dir=None,
556 user_module=None, user_ns=None,
558 user_module=None, user_ns=None,
557 custom_exceptions=((), None), **kwargs):
559 custom_exceptions=((), None), **kwargs):
558 # This is where traits with a config_key argument are updated
560 # This is where traits with a config_key argument are updated
559 # from the values on config.
561 # from the values on config.
560 super(InteractiveShell, self).__init__(**kwargs)
562 super(InteractiveShell, self).__init__(**kwargs)
561 if 'PromptManager' in self.config:
563 if 'PromptManager' in self.config:
562 warn('As of IPython 5.0 `PromptManager` config will have no effect'
564 warn('As of IPython 5.0 `PromptManager` config will have no effect'
563 ' and has been replaced by TerminalInteractiveShell.prompts_class')
565 ' and has been replaced by TerminalInteractiveShell.prompts_class')
564 self.configurables = [self]
566 self.configurables = [self]
565
567
566 # These are relatively independent and stateless
568 # These are relatively independent and stateless
567 self.init_ipython_dir(ipython_dir)
569 self.init_ipython_dir(ipython_dir)
568 self.init_profile_dir(profile_dir)
570 self.init_profile_dir(profile_dir)
569 self.init_instance_attrs()
571 self.init_instance_attrs()
570 self.init_environment()
572 self.init_environment()
571
573
572 # Check if we're in a virtualenv, and set up sys.path.
574 # Check if we're in a virtualenv, and set up sys.path.
573 self.init_virtualenv()
575 self.init_virtualenv()
574
576
575 # Create namespaces (user_ns, user_global_ns, etc.)
577 # Create namespaces (user_ns, user_global_ns, etc.)
576 self.init_create_namespaces(user_module, user_ns)
578 self.init_create_namespaces(user_module, user_ns)
577 # This has to be done after init_create_namespaces because it uses
579 # This has to be done after init_create_namespaces because it uses
578 # something in self.user_ns, but before init_sys_modules, which
580 # something in self.user_ns, but before init_sys_modules, which
579 # is the first thing to modify sys.
581 # is the first thing to modify sys.
580 # TODO: When we override sys.stdout and sys.stderr before this class
582 # 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
583 # is created, we are saving the overridden ones here. Not sure if this
582 # is what we want to do.
584 # is what we want to do.
583 self.save_sys_module_state()
585 self.save_sys_module_state()
584 self.init_sys_modules()
586 self.init_sys_modules()
585
587
586 # While we're trying to have each part of the code directly access what
588 # 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
589 # it needs without keeping redundant references to objects, we have too
588 # much legacy code that expects ip.db to exist.
590 # much legacy code that expects ip.db to exist.
589 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
591 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
590
592
591 self.init_history()
593 self.init_history()
592 self.init_encoding()
594 self.init_encoding()
593 self.init_prefilter()
595 self.init_prefilter()
594
596
595 self.init_syntax_highlighting()
597 self.init_syntax_highlighting()
596 self.init_hooks()
598 self.init_hooks()
597 self.init_events()
599 self.init_events()
598 self.init_pushd_popd_magic()
600 self.init_pushd_popd_magic()
599 self.init_user_ns()
601 self.init_user_ns()
600 self.init_logger()
602 self.init_logger()
601 self.init_builtins()
603 self.init_builtins()
602
604
603 # The following was in post_config_initialization
605 # The following was in post_config_initialization
604 self.init_inspector()
606 self.init_inspector()
605 self.raw_input_original = input
607 self.raw_input_original = input
606 self.init_completer()
608 self.init_completer()
607 # TODO: init_io() needs to happen before init_traceback handlers
609 # TODO: init_io() needs to happen before init_traceback handlers
608 # because the traceback handlers hardcode the stdout/stderr streams.
610 # because the traceback handlers hardcode the stdout/stderr streams.
609 # This logic in in debugger.Pdb and should eventually be changed.
611 # This logic in in debugger.Pdb and should eventually be changed.
610 self.init_io()
612 self.init_io()
611 self.init_traceback_handlers(custom_exceptions)
613 self.init_traceback_handlers(custom_exceptions)
612 self.init_prompts()
614 self.init_prompts()
613 self.init_display_formatter()
615 self.init_display_formatter()
614 self.init_display_pub()
616 self.init_display_pub()
615 self.init_data_pub()
617 self.init_data_pub()
616 self.init_displayhook()
618 self.init_displayhook()
617 self.init_magics()
619 self.init_magics()
618 self.init_alias()
620 self.init_alias()
619 self.init_logstart()
621 self.init_logstart()
620 self.init_pdb()
622 self.init_pdb()
621 self.init_extension_manager()
623 self.init_extension_manager()
622 self.init_payload()
624 self.init_payload()
623 self.events.trigger('shell_initialized', self)
625 self.events.trigger('shell_initialized', self)
624 atexit.register(self.atexit_operations)
626 atexit.register(self.atexit_operations)
625
627
626 # The trio runner is used for running Trio in the foreground thread. It
628 # 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`
629 # is different from `_trio_runner(async_fn)` in `async_helpers.py`
628 # which calls `trio.run()` for every cell. This runner runs all cells
630 # 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
631 # inside a single Trio event loop. If used, it is set from
630 # `ipykernel.kernelapp`.
632 # `ipykernel.kernelapp`.
631 self.trio_runner = None
633 self.trio_runner = None
632
634
633 def get_ipython(self):
635 def get_ipython(self):
634 """Return the currently running IPython instance."""
636 """Return the currently running IPython instance."""
635 return self
637 return self
636
638
637 #-------------------------------------------------------------------------
639 #-------------------------------------------------------------------------
638 # Trait changed handlers
640 # Trait changed handlers
639 #-------------------------------------------------------------------------
641 #-------------------------------------------------------------------------
640 @observe('ipython_dir')
642 @observe('ipython_dir')
641 def _ipython_dir_changed(self, change):
643 def _ipython_dir_changed(self, change):
642 ensure_dir_exists(change['new'])
644 ensure_dir_exists(change['new'])
643
645
644 def set_autoindent(self,value=None):
646 def set_autoindent(self,value=None):
645 """Set the autoindent flag.
647 """Set the autoindent flag.
646
648
647 If called with no arguments, it acts as a toggle."""
649 If called with no arguments, it acts as a toggle."""
648 if value is None:
650 if value is None:
649 self.autoindent = not self.autoindent
651 self.autoindent = not self.autoindent
650 else:
652 else:
651 self.autoindent = value
653 self.autoindent = value
652
654
653 def set_trio_runner(self, tr):
655 def set_trio_runner(self, tr):
654 self.trio_runner = tr
656 self.trio_runner = tr
655
657
656 #-------------------------------------------------------------------------
658 #-------------------------------------------------------------------------
657 # init_* methods called by __init__
659 # init_* methods called by __init__
658 #-------------------------------------------------------------------------
660 #-------------------------------------------------------------------------
659
661
660 def init_ipython_dir(self, ipython_dir):
662 def init_ipython_dir(self, ipython_dir):
661 if ipython_dir is not None:
663 if ipython_dir is not None:
662 self.ipython_dir = ipython_dir
664 self.ipython_dir = ipython_dir
663 return
665 return
664
666
665 self.ipython_dir = get_ipython_dir()
667 self.ipython_dir = get_ipython_dir()
666
668
667 def init_profile_dir(self, profile_dir):
669 def init_profile_dir(self, profile_dir):
668 if profile_dir is not None:
670 if profile_dir is not None:
669 self.profile_dir = profile_dir
671 self.profile_dir = profile_dir
670 return
672 return
671 self.profile_dir = ProfileDir.create_profile_dir_by_name(
673 self.profile_dir = ProfileDir.create_profile_dir_by_name(
672 self.ipython_dir, "default"
674 self.ipython_dir, "default"
673 )
675 )
674
676
675 def init_instance_attrs(self):
677 def init_instance_attrs(self):
676 self.more = False
678 self.more = False
677
679
678 # command compiler
680 # command compiler
679 self.compile = self.compiler_class()
681 self.compile = self.compiler_class()
680
682
681 # Make an empty namespace, which extension writers can rely on both
683 # Make an empty namespace, which extension writers can rely on both
682 # existing and NEVER being used by ipython itself. This gives them a
684 # existing and NEVER being used by ipython itself. This gives them a
683 # convenient location for storing additional information and state
685 # convenient location for storing additional information and state
684 # their extensions may require, without fear of collisions with other
686 # their extensions may require, without fear of collisions with other
685 # ipython names that may develop later.
687 # ipython names that may develop later.
686 self.meta = Struct()
688 self.meta = Struct()
687
689
688 # Temporary files used for various purposes. Deleted at exit.
690 # Temporary files used for various purposes. Deleted at exit.
689 # The files here are stored with Path from Pathlib
691 # The files here are stored with Path from Pathlib
690 self.tempfiles = []
692 self.tempfiles = []
691 self.tempdirs = []
693 self.tempdirs = []
692
694
693 # keep track of where we started running (mainly for crash post-mortem)
695 # keep track of where we started running (mainly for crash post-mortem)
694 # This is not being used anywhere currently.
696 # This is not being used anywhere currently.
695 self.starting_dir = os.getcwd()
697 self.starting_dir = os.getcwd()
696
698
697 # Indentation management
699 # Indentation management
698 self.indent_current_nsp = 0
700 self.indent_current_nsp = 0
699
701
700 # Dict to track post-execution functions that have been registered
702 # Dict to track post-execution functions that have been registered
701 self._post_execute = {}
703 self._post_execute = {}
702
704
703 def init_environment(self):
705 def init_environment(self):
704 """Any changes we need to make to the user's environment."""
706 """Any changes we need to make to the user's environment."""
705 pass
707 pass
706
708
707 def init_encoding(self):
709 def init_encoding(self):
708 # Get system encoding at startup time. Certain terminals (like Emacs
710 # 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
711 # under Win32 have it set to None, and we need to have a known valid
710 # encoding to use in the raw_input() method
712 # encoding to use in the raw_input() method
711 try:
713 try:
712 self.stdin_encoding = sys.stdin.encoding or 'ascii'
714 self.stdin_encoding = sys.stdin.encoding or 'ascii'
713 except AttributeError:
715 except AttributeError:
714 self.stdin_encoding = 'ascii'
716 self.stdin_encoding = 'ascii'
715
717
716
718
717 @observe('colors')
719 @observe('colors')
718 def init_syntax_highlighting(self, changes=None):
720 def init_syntax_highlighting(self, changes=None):
719 # Python source parser/formatter for syntax highlighting
721 # Python source parser/formatter for syntax highlighting
720 pyformat = PyColorize.Parser(style=self.colors, parent=self).format
722 pyformat = PyColorize.Parser(style=self.colors, parent=self).format
721 self.pycolorize = lambda src: pyformat(src,'str')
723 self.pycolorize = lambda src: pyformat(src,'str')
722
724
723 def refresh_style(self):
725 def refresh_style(self):
724 # No-op here, used in subclass
726 # No-op here, used in subclass
725 pass
727 pass
726
728
727 def init_pushd_popd_magic(self):
729 def init_pushd_popd_magic(self):
728 # for pushd/popd management
730 # for pushd/popd management
729 self.home_dir = get_home_dir()
731 self.home_dir = get_home_dir()
730
732
731 self.dir_stack = []
733 self.dir_stack = []
732
734
733 def init_logger(self):
735 def init_logger(self):
734 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
736 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
735 logmode='rotate')
737 logmode='rotate')
736
738
737 def init_logstart(self):
739 def init_logstart(self):
738 """Initialize logging in case it was requested at the command line.
740 """Initialize logging in case it was requested at the command line.
739 """
741 """
740 if self.logappend:
742 if self.logappend:
741 self.magic('logstart %s append' % self.logappend)
743 self.magic('logstart %s append' % self.logappend)
742 elif self.logfile:
744 elif self.logfile:
743 self.magic('logstart %s' % self.logfile)
745 self.magic('logstart %s' % self.logfile)
744 elif self.logstart:
746 elif self.logstart:
745 self.magic('logstart')
747 self.magic('logstart')
746
748
747
749
748 def init_builtins(self):
750 def init_builtins(self):
749 # A single, static flag that we set to True. Its presence indicates
751 # 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
752 # 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
753 # removing on exit or representing the existence of more than one
752 # IPython at a time.
754 # IPython at a time.
753 builtin_mod.__dict__['__IPYTHON__'] = True
755 builtin_mod.__dict__['__IPYTHON__'] = True
754 builtin_mod.__dict__['display'] = display
756 builtin_mod.__dict__['display'] = display
755
757
756 self.builtin_trap = BuiltinTrap(shell=self)
758 self.builtin_trap = BuiltinTrap(shell=self)
757
759
758 @observe('colors')
760 @observe('colors')
759 def init_inspector(self, changes=None):
761 def init_inspector(self, changes=None):
760 # Object inspector
762 # Object inspector
761 self.inspector = self.inspector_class(
763 self.inspector = self.inspector_class(
762 oinspect.InspectColors,
764 oinspect.InspectColors,
763 PyColorize.ANSICodeColors,
765 PyColorize.ANSICodeColors,
764 self.colors,
766 self.colors,
765 self.object_info_string_level,
767 self.object_info_string_level,
766 )
768 )
767
769
768 def init_io(self):
770 def init_io(self):
769 # implemented in subclasses, TerminalInteractiveShell does call
771 # implemented in subclasses, TerminalInteractiveShell does call
770 # colorama.init().
772 # colorama.init().
771 pass
773 pass
772
774
773 def init_prompts(self):
775 def init_prompts(self):
774 # Set system prompts, so that scripts can decide if they are running
776 # Set system prompts, so that scripts can decide if they are running
775 # interactively.
777 # interactively.
776 sys.ps1 = 'In : '
778 sys.ps1 = 'In : '
777 sys.ps2 = '...: '
779 sys.ps2 = '...: '
778 sys.ps3 = 'Out: '
780 sys.ps3 = 'Out: '
779
781
780 def init_display_formatter(self):
782 def init_display_formatter(self):
781 self.display_formatter = DisplayFormatter(parent=self)
783 self.display_formatter = DisplayFormatter(parent=self)
782 self.configurables.append(self.display_formatter)
784 self.configurables.append(self.display_formatter)
783
785
784 def init_display_pub(self):
786 def init_display_pub(self):
785 self.display_pub = self.display_pub_class(parent=self, shell=self)
787 self.display_pub = self.display_pub_class(parent=self, shell=self)
786 self.configurables.append(self.display_pub)
788 self.configurables.append(self.display_pub)
787
789
788 def init_data_pub(self):
790 def init_data_pub(self):
789 if not self.data_pub_class:
791 if not self.data_pub_class:
790 self.data_pub = None
792 self.data_pub = None
791 return
793 return
792 self.data_pub = self.data_pub_class(parent=self)
794 self.data_pub = self.data_pub_class(parent=self)
793 self.configurables.append(self.data_pub)
795 self.configurables.append(self.data_pub)
794
796
795 def init_displayhook(self):
797 def init_displayhook(self):
796 # Initialize displayhook, set in/out prompts and printing system
798 # Initialize displayhook, set in/out prompts and printing system
797 self.displayhook = self.displayhook_class(
799 self.displayhook = self.displayhook_class(
798 parent=self,
800 parent=self,
799 shell=self,
801 shell=self,
800 cache_size=self.cache_size,
802 cache_size=self.cache_size,
801 )
803 )
802 self.configurables.append(self.displayhook)
804 self.configurables.append(self.displayhook)
803 # This is a context manager that installs/revmoes the displayhook at
805 # This is a context manager that installs/revmoes the displayhook at
804 # the appropriate time.
806 # the appropriate time.
805 self.display_trap = DisplayTrap(hook=self.displayhook)
807 self.display_trap = DisplayTrap(hook=self.displayhook)
806
808
807 @staticmethod
809 @staticmethod
808 def get_path_links(p: Path):
810 def get_path_links(p: Path):
809 """Gets path links including all symlinks
811 """Gets path links including all symlinks
810
812
811 Examples
813 Examples
812 --------
814 --------
813 In [1]: from IPython.core.interactiveshell import InteractiveShell
815 In [1]: from IPython.core.interactiveshell import InteractiveShell
814
816
815 In [2]: import sys, pathlib
817 In [2]: import sys, pathlib
816
818
817 In [3]: paths = InteractiveShell.get_path_links(pathlib.Path(sys.executable))
819 In [3]: paths = InteractiveShell.get_path_links(pathlib.Path(sys.executable))
818
820
819 In [4]: len(paths) == len(set(paths))
821 In [4]: len(paths) == len(set(paths))
820 Out[4]: True
822 Out[4]: True
821
823
822 In [5]: bool(paths)
824 In [5]: bool(paths)
823 Out[5]: True
825 Out[5]: True
824 """
826 """
825 paths = [p]
827 paths = [p]
826 while p.is_symlink():
828 while p.is_symlink():
827 new_path = Path(os.readlink(p))
829 new_path = Path(os.readlink(p))
828 if not new_path.is_absolute():
830 if not new_path.is_absolute():
829 new_path = p.parent / new_path
831 new_path = p.parent / new_path
830 p = new_path
832 p = new_path
831 paths.append(p)
833 paths.append(p)
832 return paths
834 return paths
833
835
834 def init_virtualenv(self):
836 def init_virtualenv(self):
835 """Add the current virtualenv to sys.path so the user can import modules from it.
837 """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
838 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
839 virtualenv was built, and it ignores the --no-site-packages option. A
838 warning will appear suggesting the user installs IPython in the
840 warning will appear suggesting the user installs IPython in the
839 virtualenv, but for many cases, it probably works well enough.
841 virtualenv, but for many cases, it probably works well enough.
840
842
841 Adapted from code snippets online.
843 Adapted from code snippets online.
842
844
843 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
845 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
844 """
846 """
845 if 'VIRTUAL_ENV' not in os.environ:
847 if 'VIRTUAL_ENV' not in os.environ:
846 # Not in a virtualenv
848 # Not in a virtualenv
847 return
849 return
848 elif os.environ["VIRTUAL_ENV"] == "":
850 elif os.environ["VIRTUAL_ENV"] == "":
849 warn("Virtual env path set to '', please check if this is intended.")
851 warn("Virtual env path set to '', please check if this is intended.")
850 return
852 return
851
853
852 p = Path(sys.executable)
854 p = Path(sys.executable)
853 p_venv = Path(os.environ["VIRTUAL_ENV"])
855 p_venv = Path(os.environ["VIRTUAL_ENV"])
854
856
855 # fallback venv detection:
857 # fallback venv detection:
856 # stdlib venv may symlink sys.executable, so we can't use realpath.
858 # 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.
859 # 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)
860 # So we just check every item in the symlink tree (generally <= 3)
859 paths = self.get_path_links(p)
861 paths = self.get_path_links(p)
860
862
861 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
863 # In Cygwin paths like "c:\..." and '\cygdrive\c\...' are possible
862 if p_venv.parts[1] == "cygdrive":
864 if p_venv.parts[1] == "cygdrive":
863 drive_name = p_venv.parts[2]
865 drive_name = p_venv.parts[2]
864 p_venv = (drive_name + ":/") / Path(*p_venv.parts[3:])
866 p_venv = (drive_name + ":/") / Path(*p_venv.parts[3:])
865
867
866 if any(p_venv == p.parents[1] for p in paths):
868 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.
869 # Our exe is inside or has access to the virtualenv, don't need to do anything.
868 return
870 return
869
871
870 if sys.platform == "win32":
872 if sys.platform == "win32":
871 virtual_env = str(Path(os.environ["VIRTUAL_ENV"], "Lib", "site-packages"))
873 virtual_env = str(Path(os.environ["VIRTUAL_ENV"], "Lib", "site-packages"))
872 else:
874 else:
873 virtual_env_path = Path(
875 virtual_env_path = Path(
874 os.environ["VIRTUAL_ENV"], "lib", "python{}.{}", "site-packages"
876 os.environ["VIRTUAL_ENV"], "lib", "python{}.{}", "site-packages"
875 )
877 )
876 p_ver = sys.version_info[:2]
878 p_ver = sys.version_info[:2]
877
879
878 # Predict version from py[thon]-x.x in the $VIRTUAL_ENV
880 # 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"])
881 re_m = re.search(r"\bpy(?:thon)?([23])\.(\d+)\b", os.environ["VIRTUAL_ENV"])
880 if re_m:
882 if re_m:
881 predicted_path = Path(str(virtual_env_path).format(*re_m.groups()))
883 predicted_path = Path(str(virtual_env_path).format(*re_m.groups()))
882 if predicted_path.exists():
884 if predicted_path.exists():
883 p_ver = re_m.groups()
885 p_ver = re_m.groups()
884
886
885 virtual_env = str(virtual_env_path).format(*p_ver)
887 virtual_env = str(virtual_env_path).format(*p_ver)
886 if self.warn_venv:
888 if self.warn_venv:
887 warn(
889 warn(
888 "Attempting to work in a virtualenv. If you encounter problems, "
890 "Attempting to work in a virtualenv. If you encounter problems, "
889 "please install IPython inside the virtualenv."
891 "please install IPython inside the virtualenv."
890 )
892 )
891 import site
893 import site
892 sys.path.insert(0, virtual_env)
894 sys.path.insert(0, virtual_env)
893 site.addsitedir(virtual_env)
895 site.addsitedir(virtual_env)
894
896
895 #-------------------------------------------------------------------------
897 #-------------------------------------------------------------------------
896 # Things related to injections into the sys module
898 # Things related to injections into the sys module
897 #-------------------------------------------------------------------------
899 #-------------------------------------------------------------------------
898
900
899 def save_sys_module_state(self):
901 def save_sys_module_state(self):
900 """Save the state of hooks in the sys module.
902 """Save the state of hooks in the sys module.
901
903
902 This has to be called after self.user_module is created.
904 This has to be called after self.user_module is created.
903 """
905 """
904 self._orig_sys_module_state = {'stdin': sys.stdin,
906 self._orig_sys_module_state = {'stdin': sys.stdin,
905 'stdout': sys.stdout,
907 'stdout': sys.stdout,
906 'stderr': sys.stderr,
908 'stderr': sys.stderr,
907 'excepthook': sys.excepthook}
909 'excepthook': sys.excepthook}
908 self._orig_sys_modules_main_name = self.user_module.__name__
910 self._orig_sys_modules_main_name = self.user_module.__name__
909 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
911 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
910
912
911 def restore_sys_module_state(self):
913 def restore_sys_module_state(self):
912 """Restore the state of the sys module."""
914 """Restore the state of the sys module."""
913 try:
915 try:
914 for k, v in self._orig_sys_module_state.items():
916 for k, v in self._orig_sys_module_state.items():
915 setattr(sys, k, v)
917 setattr(sys, k, v)
916 except AttributeError:
918 except AttributeError:
917 pass
919 pass
918 # Reset what what done in self.init_sys_modules
920 # Reset what what done in self.init_sys_modules
919 if self._orig_sys_modules_main_mod is not None:
921 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
922 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
921
923
922 #-------------------------------------------------------------------------
924 #-------------------------------------------------------------------------
923 # Things related to the banner
925 # Things related to the banner
924 #-------------------------------------------------------------------------
926 #-------------------------------------------------------------------------
925
927
926 @property
928 @property
927 def banner(self):
929 def banner(self):
928 banner = self.banner1
930 banner = self.banner1
929 if self.profile and self.profile != 'default':
931 if self.profile and self.profile != 'default':
930 banner += '\nIPython profile: %s\n' % self.profile
932 banner += '\nIPython profile: %s\n' % self.profile
931 if self.banner2:
933 if self.banner2:
932 banner += '\n' + self.banner2
934 banner += '\n' + self.banner2
933 return banner
935 return banner
934
936
935 def show_banner(self, banner=None):
937 def show_banner(self, banner=None):
936 if banner is None:
938 if banner is None:
937 banner = self.banner
939 banner = self.banner
938 sys.stdout.write(banner)
940 sys.stdout.write(banner)
939
941
940 #-------------------------------------------------------------------------
942 #-------------------------------------------------------------------------
941 # Things related to hooks
943 # Things related to hooks
942 #-------------------------------------------------------------------------
944 #-------------------------------------------------------------------------
943
945
944 def init_hooks(self):
946 def init_hooks(self):
945 # hooks holds pointers used for user-side customizations
947 # hooks holds pointers used for user-side customizations
946 self.hooks = Struct()
948 self.hooks = Struct()
947
949
948 self.strdispatchers = {}
950 self.strdispatchers = {}
949
951
950 # Set all default hooks, defined in the IPython.hooks module.
952 # Set all default hooks, defined in the IPython.hooks module.
951 hooks = IPython.core.hooks
953 hooks = IPython.core.hooks
952 for hook_name in hooks.__all__:
954 for hook_name in hooks.__all__:
953 # default hooks have priority 100, i.e. low; user hooks should have
955 # default hooks have priority 100, i.e. low; user hooks should have
954 # 0-100 priority
956 # 0-100 priority
955 self.set_hook(hook_name, getattr(hooks, hook_name), 100)
957 self.set_hook(hook_name, getattr(hooks, hook_name), 100)
956
958
957 if self.display_page:
959 if self.display_page:
958 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
960 self.set_hook('show_in_pager', page.as_hook(page.display_page), 90)
959
961
960 def set_hook(self, name, hook, priority=50, str_key=None, re_key=None):
962 def set_hook(self, name, hook, priority=50, str_key=None, re_key=None):
961 """set_hook(name,hook) -> sets an internal IPython hook.
963 """set_hook(name,hook) -> sets an internal IPython hook.
962
964
963 IPython exposes some of its internal API as user-modifiable hooks. By
965 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
966 adding your function to one of these hooks, you can modify IPython's
965 behavior to call at runtime your own routines."""
967 behavior to call at runtime your own routines."""
966
968
967 # At some point in the future, this should validate the hook before it
969 # 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
970 # accepts it. Probably at least check that the hook takes the number
969 # of args it's supposed to.
971 # of args it's supposed to.
970
972
971 f = types.MethodType(hook,self)
973 f = types.MethodType(hook,self)
972
974
973 # check if the hook is for strdispatcher first
975 # check if the hook is for strdispatcher first
974 if str_key is not None:
976 if str_key is not None:
975 sdp = self.strdispatchers.get(name, StrDispatch())
977 sdp = self.strdispatchers.get(name, StrDispatch())
976 sdp.add_s(str_key, f, priority )
978 sdp.add_s(str_key, f, priority )
977 self.strdispatchers[name] = sdp
979 self.strdispatchers[name] = sdp
978 return
980 return
979 if re_key is not None:
981 if re_key is not None:
980 sdp = self.strdispatchers.get(name, StrDispatch())
982 sdp = self.strdispatchers.get(name, StrDispatch())
981 sdp.add_re(re.compile(re_key), f, priority )
983 sdp.add_re(re.compile(re_key), f, priority )
982 self.strdispatchers[name] = sdp
984 self.strdispatchers[name] = sdp
983 return
985 return
984
986
985 dp = getattr(self.hooks, name, None)
987 dp = getattr(self.hooks, name, None)
986 if name not in IPython.core.hooks.__all__:
988 if name not in IPython.core.hooks.__all__:
987 print("Warning! Hook '%s' is not one of %s" % \
989 print("Warning! Hook '%s' is not one of %s" % \
988 (name, IPython.core.hooks.__all__ ))
990 (name, IPython.core.hooks.__all__ ))
989
991
990 if name in IPython.core.hooks.deprecated:
992 if name in IPython.core.hooks.deprecated:
991 alternative = IPython.core.hooks.deprecated[name]
993 alternative = IPython.core.hooks.deprecated[name]
992 raise ValueError(
994 raise ValueError(
993 "Hook {} has been deprecated since IPython 5.0. Use {} instead.".format(
995 "Hook {} has been deprecated since IPython 5.0. Use {} instead.".format(
994 name, alternative
996 name, alternative
995 )
997 )
996 )
998 )
997
999
998 if not dp:
1000 if not dp:
999 dp = IPython.core.hooks.CommandChainDispatcher()
1001 dp = IPython.core.hooks.CommandChainDispatcher()
1000
1002
1001 try:
1003 try:
1002 dp.add(f,priority)
1004 dp.add(f,priority)
1003 except AttributeError:
1005 except AttributeError:
1004 # it was not commandchain, plain old func - replace
1006 # it was not commandchain, plain old func - replace
1005 dp = f
1007 dp = f
1006
1008
1007 setattr(self.hooks,name, dp)
1009 setattr(self.hooks,name, dp)
1008
1010
1009 #-------------------------------------------------------------------------
1011 #-------------------------------------------------------------------------
1010 # Things related to events
1012 # Things related to events
1011 #-------------------------------------------------------------------------
1013 #-------------------------------------------------------------------------
1012
1014
1013 def init_events(self):
1015 def init_events(self):
1014 self.events = EventManager(self, available_events)
1016 self.events = EventManager(self, available_events)
1015
1017
1016 self.events.register("pre_execute", self._clear_warning_registry)
1018 self.events.register("pre_execute", self._clear_warning_registry)
1017
1019
1018 def register_post_execute(self, func):
1020 def register_post_execute(self, func):
1019 """DEPRECATED: Use ip.events.register('post_run_cell', func)
1021 """DEPRECATED: Use ip.events.register('post_run_cell', func)
1020
1022
1021 Register a function for calling after code execution.
1023 Register a function for calling after code execution.
1022 """
1024 """
1023 raise ValueError(
1025 raise ValueError(
1024 "ip.register_post_execute is deprecated since IPython 1.0, use "
1026 "ip.register_post_execute is deprecated since IPython 1.0, use "
1025 "ip.events.register('post_run_cell', func) instead."
1027 "ip.events.register('post_run_cell', func) instead."
1026 )
1028 )
1027
1029
1028 def _clear_warning_registry(self):
1030 def _clear_warning_registry(self):
1029 # clear the warning registry, so that different code blocks with
1031 # clear the warning registry, so that different code blocks with
1030 # overlapping line number ranges don't cause spurious suppression of
1032 # overlapping line number ranges don't cause spurious suppression of
1031 # warnings (see gh-6611 for details)
1033 # warnings (see gh-6611 for details)
1032 if "__warningregistry__" in self.user_global_ns:
1034 if "__warningregistry__" in self.user_global_ns:
1033 del self.user_global_ns["__warningregistry__"]
1035 del self.user_global_ns["__warningregistry__"]
1034
1036
1035 #-------------------------------------------------------------------------
1037 #-------------------------------------------------------------------------
1036 # Things related to the "main" module
1038 # Things related to the "main" module
1037 #-------------------------------------------------------------------------
1039 #-------------------------------------------------------------------------
1038
1040
1039 def new_main_mod(self, filename, modname):
1041 def new_main_mod(self, filename, modname):
1040 """Return a new 'main' module object for user code execution.
1042 """Return a new 'main' module object for user code execution.
1041
1043
1042 ``filename`` should be the path of the script which will be run in the
1044 ``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
1045 module. Requests with the same filename will get the same module, with
1044 its namespace cleared.
1046 its namespace cleared.
1045
1047
1046 ``modname`` should be the module name - normally either '__main__' or
1048 ``modname`` should be the module name - normally either '__main__' or
1047 the basename of the file without the extension.
1049 the basename of the file without the extension.
1048
1050
1049 When scripts are executed via %run, we must keep a reference to their
1051 When scripts are executed via %run, we must keep a reference to their
1050 __main__ module around so that Python doesn't
1052 __main__ module around so that Python doesn't
1051 clear it, rendering references to module globals useless.
1053 clear it, rendering references to module globals useless.
1052
1054
1053 This method keeps said reference in a private dict, keyed by the
1055 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
1056 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),
1057 same script we only keep one copy of the namespace (the last one),
1056 thus preventing memory leaks from old references while allowing the
1058 thus preventing memory leaks from old references while allowing the
1057 objects from the last execution to be accessible.
1059 objects from the last execution to be accessible.
1058 """
1060 """
1059 filename = os.path.abspath(filename)
1061 filename = os.path.abspath(filename)
1060 try:
1062 try:
1061 main_mod = self._main_mod_cache[filename]
1063 main_mod = self._main_mod_cache[filename]
1062 except KeyError:
1064 except KeyError:
1063 main_mod = self._main_mod_cache[filename] = types.ModuleType(
1065 main_mod = self._main_mod_cache[filename] = types.ModuleType(
1064 modname,
1066 modname,
1065 doc="Module created for script run in IPython")
1067 doc="Module created for script run in IPython")
1066 else:
1068 else:
1067 main_mod.__dict__.clear()
1069 main_mod.__dict__.clear()
1068 main_mod.__name__ = modname
1070 main_mod.__name__ = modname
1069
1071
1070 main_mod.__file__ = filename
1072 main_mod.__file__ = filename
1071 # It seems pydoc (and perhaps others) needs any module instance to
1073 # It seems pydoc (and perhaps others) needs any module instance to
1072 # implement a __nonzero__ method
1074 # implement a __nonzero__ method
1073 main_mod.__nonzero__ = lambda : True
1075 main_mod.__nonzero__ = lambda : True
1074
1076
1075 return main_mod
1077 return main_mod
1076
1078
1077 def clear_main_mod_cache(self):
1079 def clear_main_mod_cache(self):
1078 """Clear the cache of main modules.
1080 """Clear the cache of main modules.
1079
1081
1080 Mainly for use by utilities like %reset.
1082 Mainly for use by utilities like %reset.
1081
1083
1082 Examples
1084 Examples
1083 --------
1085 --------
1084 In [15]: import IPython
1086 In [15]: import IPython
1085
1087
1086 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
1088 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
1087
1089
1088 In [17]: len(_ip._main_mod_cache) > 0
1090 In [17]: len(_ip._main_mod_cache) > 0
1089 Out[17]: True
1091 Out[17]: True
1090
1092
1091 In [18]: _ip.clear_main_mod_cache()
1093 In [18]: _ip.clear_main_mod_cache()
1092
1094
1093 In [19]: len(_ip._main_mod_cache) == 0
1095 In [19]: len(_ip._main_mod_cache) == 0
1094 Out[19]: True
1096 Out[19]: True
1095 """
1097 """
1096 self._main_mod_cache.clear()
1098 self._main_mod_cache.clear()
1097
1099
1098 #-------------------------------------------------------------------------
1100 #-------------------------------------------------------------------------
1099 # Things related to debugging
1101 # Things related to debugging
1100 #-------------------------------------------------------------------------
1102 #-------------------------------------------------------------------------
1101
1103
1102 def init_pdb(self):
1104 def init_pdb(self):
1103 # Set calling of pdb on exceptions
1105 # Set calling of pdb on exceptions
1104 # self.call_pdb is a property
1106 # self.call_pdb is a property
1105 self.call_pdb = self.pdb
1107 self.call_pdb = self.pdb
1106
1108
1107 def _get_call_pdb(self):
1109 def _get_call_pdb(self):
1108 return self._call_pdb
1110 return self._call_pdb
1109
1111
1110 def _set_call_pdb(self,val):
1112 def _set_call_pdb(self,val):
1111
1113
1112 if val not in (0,1,False,True):
1114 if val not in (0,1,False,True):
1113 raise ValueError('new call_pdb value must be boolean')
1115 raise ValueError('new call_pdb value must be boolean')
1114
1116
1115 # store value in instance
1117 # store value in instance
1116 self._call_pdb = val
1118 self._call_pdb = val
1117
1119
1118 # notify the actual exception handlers
1120 # notify the actual exception handlers
1119 self.InteractiveTB.call_pdb = val
1121 self.InteractiveTB.call_pdb = val
1120
1122
1121 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1123 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
1122 'Control auto-activation of pdb at exceptions')
1124 'Control auto-activation of pdb at exceptions')
1123
1125
1124 def debugger(self,force=False):
1126 def debugger(self,force=False):
1125 """Call the pdb debugger.
1127 """Call the pdb debugger.
1126
1128
1127 Keywords:
1129 Keywords:
1128
1130
1129 - force(False): by default, this routine checks the instance call_pdb
1131 - 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.
1132 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
1133 The 'force' option forces the debugger to activate even if the flag
1132 is false.
1134 is false.
1133 """
1135 """
1134
1136
1135 if not (force or self.call_pdb):
1137 if not (force or self.call_pdb):
1136 return
1138 return
1137
1139
1138 if not hasattr(sys,'last_traceback'):
1140 if not hasattr(sys,'last_traceback'):
1139 error('No traceback has been produced, nothing to debug.')
1141 error('No traceback has been produced, nothing to debug.')
1140 return
1142 return
1141
1143
1142 self.InteractiveTB.debugger(force=True)
1144 self.InteractiveTB.debugger(force=True)
1143
1145
1144 #-------------------------------------------------------------------------
1146 #-------------------------------------------------------------------------
1145 # Things related to IPython's various namespaces
1147 # Things related to IPython's various namespaces
1146 #-------------------------------------------------------------------------
1148 #-------------------------------------------------------------------------
1147 default_user_namespaces = True
1149 default_user_namespaces = True
1148
1150
1149 def init_create_namespaces(self, user_module=None, user_ns=None):
1151 def init_create_namespaces(self, user_module=None, user_ns=None):
1150 # Create the namespace where the user will operate. user_ns is
1152 # 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
1153 # 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
1154 # the locals argument. But we do carry a user_global_ns namespace
1153 # given as the exec 'globals' argument, This is useful in embedding
1155 # given as the exec 'globals' argument, This is useful in embedding
1154 # situations where the ipython shell opens in a context where the
1156 # situations where the ipython shell opens in a context where the
1155 # distinction between locals and globals is meaningful. For
1157 # distinction between locals and globals is meaningful. For
1156 # non-embedded contexts, it is just the same object as the user_ns dict.
1158 # non-embedded contexts, it is just the same object as the user_ns dict.
1157
1159
1158 # FIXME. For some strange reason, __builtins__ is showing up at user
1160 # 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
1161 # 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
1162 # should really track down where the problem is coming from. Alex
1161 # Schmolck reported this problem first.
1163 # Schmolck reported this problem first.
1162
1164
1163 # A useful post by Alex Martelli on this topic:
1165 # A useful post by Alex Martelli on this topic:
1164 # Re: inconsistent value from __builtins__
1166 # Re: inconsistent value from __builtins__
1165 # Von: Alex Martelli <aleaxit@yahoo.com>
1167 # Von: Alex Martelli <aleaxit@yahoo.com>
1166 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1168 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
1167 # Gruppen: comp.lang.python
1169 # Gruppen: comp.lang.python
1168
1170
1169 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1171 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
1170 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1172 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
1171 # > <type 'dict'>
1173 # > <type 'dict'>
1172 # > >>> print type(__builtins__)
1174 # > >>> print type(__builtins__)
1173 # > <type 'module'>
1175 # > <type 'module'>
1174 # > Is this difference in return value intentional?
1176 # > Is this difference in return value intentional?
1175
1177
1176 # Well, it's documented that '__builtins__' can be either a dictionary
1178 # 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
1179 # 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
1180 # 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
1181 # that if you need to access the built-in namespace directly, you
1180 # should start with "import __builtin__" (note, no 's') which will
1182 # should start with "import __builtin__" (note, no 's') which will
1181 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1183 # definitely give you a module. Yeah, it's somewhat confusing:-(.
1182
1184
1183 # These routines return a properly built module and dict as needed by
1185 # 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
1186 # the rest of the code, and can also be used by extension writers to
1185 # generate properly initialized namespaces.
1187 # generate properly initialized namespaces.
1186 if (user_ns is not None) or (user_module is not None):
1188 if (user_ns is not None) or (user_module is not None):
1187 self.default_user_namespaces = False
1189 self.default_user_namespaces = False
1188 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1190 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
1189
1191
1190 # A record of hidden variables we have added to the user namespace, so
1192 # 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.
1193 # we can list later only variables defined in actual interactive use.
1192 self.user_ns_hidden = {}
1194 self.user_ns_hidden = {}
1193
1195
1194 # Now that FakeModule produces a real module, we've run into a nasty
1196 # 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
1197 # 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
1198 # code ran is deleted. Now that this object is a true module (needed
1197 # so doctest and other tools work correctly), the Python module
1199 # so doctest and other tools work correctly), the Python module
1198 # teardown mechanism runs over it, and sets to None every variable
1200 # teardown mechanism runs over it, and sets to None every variable
1199 # present in that module. Top-level references to objects from the
1201 # present in that module. Top-level references to objects from the
1200 # script survive, because the user_ns is updated with them. However,
1202 # script survive, because the user_ns is updated with them. However,
1201 # calling functions defined in the script that use other things from
1203 # calling functions defined in the script that use other things from
1202 # the script will fail, because the function's closure had references
1204 # 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
1205 # to the original objects, which are now all None. So we must protect
1204 # these modules from deletion by keeping a cache.
1206 # these modules from deletion by keeping a cache.
1205 #
1207 #
1206 # To avoid keeping stale modules around (we only need the one from the
1208 # 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
1209 # 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,
1210 # only the last version of the module is held in the cache. Note,
1209 # however, that we must cache the module *namespace contents* (their
1211 # however, that we must cache the module *namespace contents* (their
1210 # __dict__). Because if we try to cache the actual modules, old ones
1212 # __dict__). Because if we try to cache the actual modules, old ones
1211 # (uncached) could be destroyed while still holding references (such as
1213 # (uncached) could be destroyed while still holding references (such as
1212 # those held by GUI objects that tend to be long-lived)>
1214 # those held by GUI objects that tend to be long-lived)>
1213 #
1215 #
1214 # The %reset command will flush this cache. See the cache_main_mod()
1216 # The %reset command will flush this cache. See the cache_main_mod()
1215 # and clear_main_mod_cache() methods for details on use.
1217 # and clear_main_mod_cache() methods for details on use.
1216
1218
1217 # This is the cache used for 'main' namespaces
1219 # This is the cache used for 'main' namespaces
1218 self._main_mod_cache = {}
1220 self._main_mod_cache = {}
1219
1221
1220 # A table holding all the namespaces IPython deals with, so that
1222 # A table holding all the namespaces IPython deals with, so that
1221 # introspection facilities can search easily.
1223 # introspection facilities can search easily.
1222 self.ns_table = {'user_global':self.user_module.__dict__,
1224 self.ns_table = {'user_global':self.user_module.__dict__,
1223 'user_local':self.user_ns,
1225 'user_local':self.user_ns,
1224 'builtin':builtin_mod.__dict__
1226 'builtin':builtin_mod.__dict__
1225 }
1227 }
1226
1228
1227 @property
1229 @property
1228 def user_global_ns(self):
1230 def user_global_ns(self):
1229 return self.user_module.__dict__
1231 return self.user_module.__dict__
1230
1232
1231 def prepare_user_module(self, user_module=None, user_ns=None):
1233 def prepare_user_module(self, user_module=None, user_ns=None):
1232 """Prepare the module and namespace in which user code will be run.
1234 """Prepare the module and namespace in which user code will be run.
1233
1235
1234 When IPython is started normally, both parameters are None: a new module
1236 When IPython is started normally, both parameters are None: a new module
1235 is created automatically, and its __dict__ used as the namespace.
1237 is created automatically, and its __dict__ used as the namespace.
1236
1238
1237 If only user_module is provided, its __dict__ is used as the namespace.
1239 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
1240 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
1241 becomes the global namespace. If both are provided (as they may be
1240 when embedding), user_ns is the local namespace, and user_module
1242 when embedding), user_ns is the local namespace, and user_module
1241 provides the global namespace.
1243 provides the global namespace.
1242
1244
1243 Parameters
1245 Parameters
1244 ----------
1246 ----------
1245 user_module : module, optional
1247 user_module : module, optional
1246 The current user module in which IPython is being run. If None,
1248 The current user module in which IPython is being run. If None,
1247 a clean module will be created.
1249 a clean module will be created.
1248 user_ns : dict, optional
1250 user_ns : dict, optional
1249 A namespace in which to run interactive commands.
1251 A namespace in which to run interactive commands.
1250
1252
1251 Returns
1253 Returns
1252 -------
1254 -------
1253 A tuple of user_module and user_ns, each properly initialised.
1255 A tuple of user_module and user_ns, each properly initialised.
1254 """
1256 """
1255 if user_module is None and user_ns is not None:
1257 if user_module is None and user_ns is not None:
1256 user_ns.setdefault("__name__", "__main__")
1258 user_ns.setdefault("__name__", "__main__")
1257 user_module = DummyMod()
1259 user_module = DummyMod()
1258 user_module.__dict__ = user_ns
1260 user_module.__dict__ = user_ns
1259
1261
1260 if user_module is None:
1262 if user_module is None:
1261 user_module = types.ModuleType("__main__",
1263 user_module = types.ModuleType("__main__",
1262 doc="Automatically created module for IPython interactive environment")
1264 doc="Automatically created module for IPython interactive environment")
1263
1265
1264 # We must ensure that __builtin__ (without the final 's') is always
1266 # We must ensure that __builtin__ (without the final 's') is always
1265 # available and pointing to the __builtin__ *module*. For more details:
1267 # available and pointing to the __builtin__ *module*. For more details:
1266 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1268 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1267 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1269 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1268 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1270 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1269
1271
1270 if user_ns is None:
1272 if user_ns is None:
1271 user_ns = user_module.__dict__
1273 user_ns = user_module.__dict__
1272
1274
1273 return user_module, user_ns
1275 return user_module, user_ns
1274
1276
1275 def init_sys_modules(self):
1277 def init_sys_modules(self):
1276 # We need to insert into sys.modules something that looks like a
1278 # We need to insert into sys.modules something that looks like a
1277 # module but which accesses the IPython namespace, for shelve and
1279 # module but which accesses the IPython namespace, for shelve and
1278 # pickle to work interactively. Normally they rely on getting
1280 # pickle to work interactively. Normally they rely on getting
1279 # everything out of __main__, but for embedding purposes each IPython
1281 # everything out of __main__, but for embedding purposes each IPython
1280 # instance has its own private namespace, so we can't go shoving
1282 # instance has its own private namespace, so we can't go shoving
1281 # everything into __main__.
1283 # everything into __main__.
1282
1284
1283 # note, however, that we should only do this for non-embedded
1285 # note, however, that we should only do this for non-embedded
1284 # ipythons, which really mimic the __main__.__dict__ with their own
1286 # ipythons, which really mimic the __main__.__dict__ with their own
1285 # namespace. Embedded instances, on the other hand, should not do
1287 # namespace. Embedded instances, on the other hand, should not do
1286 # this because they need to manage the user local/global namespaces
1288 # this because they need to manage the user local/global namespaces
1287 # only, but they live within a 'normal' __main__ (meaning, they
1289 # only, but they live within a 'normal' __main__ (meaning, they
1288 # shouldn't overtake the execution environment of the script they're
1290 # shouldn't overtake the execution environment of the script they're
1289 # embedded in).
1291 # embedded in).
1290
1292
1291 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1293 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1292 main_name = self.user_module.__name__
1294 main_name = self.user_module.__name__
1293 sys.modules[main_name] = self.user_module
1295 sys.modules[main_name] = self.user_module
1294
1296
1295 def init_user_ns(self):
1297 def init_user_ns(self):
1296 """Initialize all user-visible namespaces to their minimum defaults.
1298 """Initialize all user-visible namespaces to their minimum defaults.
1297
1299
1298 Certain history lists are also initialized here, as they effectively
1300 Certain history lists are also initialized here, as they effectively
1299 act as user namespaces.
1301 act as user namespaces.
1300
1302
1301 Notes
1303 Notes
1302 -----
1304 -----
1303 All data structures here are only filled in, they are NOT reset by this
1305 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
1306 method. If they were not empty before, data will simply be added to
1305 them.
1307 them.
1306 """
1308 """
1307 # This function works in two parts: first we put a few things in
1309 # 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
1310 # 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
1311 # 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
1312 # 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)
1313 # session (probably nothing, so they really only see their own stuff)
1312
1314
1313 # The user dict must *always* have a __builtin__ reference to the
1315 # The user dict must *always* have a __builtin__ reference to the
1314 # Python standard __builtin__ namespace, which must be imported.
1316 # Python standard __builtin__ namespace, which must be imported.
1315 # This is so that certain operations in prompt evaluation can be
1317 # This is so that certain operations in prompt evaluation can be
1316 # reliably executed with builtins. Note that we can NOT use
1318 # reliably executed with builtins. Note that we can NOT use
1317 # __builtins__ (note the 's'), because that can either be a dict or a
1319 # __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
1320 # module, and can even mutate at runtime, depending on the context
1319 # (Python makes no guarantees on it). In contrast, __builtin__ is
1321 # (Python makes no guarantees on it). In contrast, __builtin__ is
1320 # always a module object, though it must be explicitly imported.
1322 # always a module object, though it must be explicitly imported.
1321
1323
1322 # For more details:
1324 # For more details:
1323 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1325 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1324 ns = {}
1326 ns = {}
1325
1327
1326 # make global variables for user access to the histories
1328 # make global variables for user access to the histories
1327 ns['_ih'] = self.history_manager.input_hist_parsed
1329 ns['_ih'] = self.history_manager.input_hist_parsed
1328 ns['_oh'] = self.history_manager.output_hist
1330 ns['_oh'] = self.history_manager.output_hist
1329 ns['_dh'] = self.history_manager.dir_hist
1331 ns['_dh'] = self.history_manager.dir_hist
1330
1332
1331 # user aliases to input and output histories. These shouldn't show up
1333 # user aliases to input and output histories. These shouldn't show up
1332 # in %who, as they can have very large reprs.
1334 # in %who, as they can have very large reprs.
1333 ns['In'] = self.history_manager.input_hist_parsed
1335 ns['In'] = self.history_manager.input_hist_parsed
1334 ns['Out'] = self.history_manager.output_hist
1336 ns['Out'] = self.history_manager.output_hist
1335
1337
1336 # Store myself as the public api!!!
1338 # Store myself as the public api!!!
1337 ns['get_ipython'] = self.get_ipython
1339 ns['get_ipython'] = self.get_ipython
1338
1340
1339 ns['exit'] = self.exiter
1341 ns['exit'] = self.exiter
1340 ns['quit'] = self.exiter
1342 ns['quit'] = self.exiter
1341 ns["open"] = _modified_open
1343 ns["open"] = _modified_open
1342
1344
1343 # Sync what we've added so far to user_ns_hidden so these aren't seen
1345 # Sync what we've added so far to user_ns_hidden so these aren't seen
1344 # by %who
1346 # by %who
1345 self.user_ns_hidden.update(ns)
1347 self.user_ns_hidden.update(ns)
1346
1348
1347 # Anything put into ns now would show up in %who. Think twice before
1349 # 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
1350 # putting anything here, as we really want %who to show the user their
1349 # stuff, not our variables.
1351 # stuff, not our variables.
1350
1352
1351 # Finally, update the real user's namespace
1353 # Finally, update the real user's namespace
1352 self.user_ns.update(ns)
1354 self.user_ns.update(ns)
1353
1355
1354 @property
1356 @property
1355 def all_ns_refs(self):
1357 def all_ns_refs(self):
1356 """Get a list of references to all the namespace dictionaries in which
1358 """Get a list of references to all the namespace dictionaries in which
1357 IPython might store a user-created object.
1359 IPython might store a user-created object.
1358
1360
1359 Note that this does not include the displayhook, which also caches
1361 Note that this does not include the displayhook, which also caches
1360 objects from the output."""
1362 objects from the output."""
1361 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1363 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1362 [m.__dict__ for m in self._main_mod_cache.values()]
1364 [m.__dict__ for m in self._main_mod_cache.values()]
1363
1365
1364 def reset(self, new_session=True, aggressive=False):
1366 def reset(self, new_session=True, aggressive=False):
1365 """Clear all internal namespaces, and attempt to release references to
1367 """Clear all internal namespaces, and attempt to release references to
1366 user objects.
1368 user objects.
1367
1369
1368 If new_session is True, a new history session will be opened.
1370 If new_session is True, a new history session will be opened.
1369 """
1371 """
1370 # Clear histories
1372 # Clear histories
1371 self.history_manager.reset(new_session)
1373 self.history_manager.reset(new_session)
1372 # Reset counter used to index all histories
1374 # Reset counter used to index all histories
1373 if new_session:
1375 if new_session:
1374 self.execution_count = 1
1376 self.execution_count = 1
1375
1377
1376 # Reset last execution result
1378 # Reset last execution result
1377 self.last_execution_succeeded = True
1379 self.last_execution_succeeded = True
1378 self.last_execution_result = None
1380 self.last_execution_result = None
1379
1381
1380 # Flush cached output items
1382 # Flush cached output items
1381 if self.displayhook.do_full_cache:
1383 if self.displayhook.do_full_cache:
1382 self.displayhook.flush()
1384 self.displayhook.flush()
1383
1385
1384 # The main execution namespaces must be cleared very carefully,
1386 # The main execution namespaces must be cleared very carefully,
1385 # skipping the deletion of the builtin-related keys, because doing so
1387 # skipping the deletion of the builtin-related keys, because doing so
1386 # would cause errors in many object's __del__ methods.
1388 # would cause errors in many object's __del__ methods.
1387 if self.user_ns is not self.user_global_ns:
1389 if self.user_ns is not self.user_global_ns:
1388 self.user_ns.clear()
1390 self.user_ns.clear()
1389 ns = self.user_global_ns
1391 ns = self.user_global_ns
1390 drop_keys = set(ns.keys())
1392 drop_keys = set(ns.keys())
1391 drop_keys.discard('__builtin__')
1393 drop_keys.discard('__builtin__')
1392 drop_keys.discard('__builtins__')
1394 drop_keys.discard('__builtins__')
1393 drop_keys.discard('__name__')
1395 drop_keys.discard('__name__')
1394 for k in drop_keys:
1396 for k in drop_keys:
1395 del ns[k]
1397 del ns[k]
1396
1398
1397 self.user_ns_hidden.clear()
1399 self.user_ns_hidden.clear()
1398
1400
1399 # Restore the user namespaces to minimal usability
1401 # Restore the user namespaces to minimal usability
1400 self.init_user_ns()
1402 self.init_user_ns()
1401 if aggressive and not hasattr(self, "_sys_modules_keys"):
1403 if aggressive and not hasattr(self, "_sys_modules_keys"):
1402 print("Cannot restore sys.module, no snapshot")
1404 print("Cannot restore sys.module, no snapshot")
1403 elif aggressive:
1405 elif aggressive:
1404 print("culling sys module...")
1406 print("culling sys module...")
1405 current_keys = set(sys.modules.keys())
1407 current_keys = set(sys.modules.keys())
1406 for k in current_keys - self._sys_modules_keys:
1408 for k in current_keys - self._sys_modules_keys:
1407 if k.startswith("multiprocessing"):
1409 if k.startswith("multiprocessing"):
1408 continue
1410 continue
1409 del sys.modules[k]
1411 del sys.modules[k]
1410
1412
1411 # Restore the default and user aliases
1413 # Restore the default and user aliases
1412 self.alias_manager.clear_aliases()
1414 self.alias_manager.clear_aliases()
1413 self.alias_manager.init_aliases()
1415 self.alias_manager.init_aliases()
1414
1416
1415 # Now define aliases that only make sense on the terminal, because they
1417 # 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
1418 # need direct access to the console in a way that we can't emulate in
1417 # GUI or web frontend
1419 # GUI or web frontend
1418 if os.name == 'posix':
1420 if os.name == 'posix':
1419 for cmd in ('clear', 'more', 'less', 'man'):
1421 for cmd in ('clear', 'more', 'less', 'man'):
1420 if cmd not in self.magics_manager.magics['line']:
1422 if cmd not in self.magics_manager.magics['line']:
1421 self.alias_manager.soft_define_alias(cmd, cmd)
1423 self.alias_manager.soft_define_alias(cmd, cmd)
1422
1424
1423 # Flush the private list of module references kept for script
1425 # Flush the private list of module references kept for script
1424 # execution protection
1426 # execution protection
1425 self.clear_main_mod_cache()
1427 self.clear_main_mod_cache()
1426
1428
1427 def del_var(self, varname, by_name=False):
1429 def del_var(self, varname, by_name=False):
1428 """Delete a variable from the various namespaces, so that, as
1430 """Delete a variable from the various namespaces, so that, as
1429 far as possible, we're not keeping any hidden references to it.
1431 far as possible, we're not keeping any hidden references to it.
1430
1432
1431 Parameters
1433 Parameters
1432 ----------
1434 ----------
1433 varname : str
1435 varname : str
1434 The name of the variable to delete.
1436 The name of the variable to delete.
1435 by_name : bool
1437 by_name : bool
1436 If True, delete variables with the given name in each
1438 If True, delete variables with the given name in each
1437 namespace. If False (default), find the variable in the user
1439 namespace. If False (default), find the variable in the user
1438 namespace, and delete references to it.
1440 namespace, and delete references to it.
1439 """
1441 """
1440 if varname in ('__builtin__', '__builtins__'):
1442 if varname in ('__builtin__', '__builtins__'):
1441 raise ValueError("Refusing to delete %s" % varname)
1443 raise ValueError("Refusing to delete %s" % varname)
1442
1444
1443 ns_refs = self.all_ns_refs
1445 ns_refs = self.all_ns_refs
1444
1446
1445 if by_name: # Delete by name
1447 if by_name: # Delete by name
1446 for ns in ns_refs:
1448 for ns in ns_refs:
1447 try:
1449 try:
1448 del ns[varname]
1450 del ns[varname]
1449 except KeyError:
1451 except KeyError:
1450 pass
1452 pass
1451 else: # Delete by object
1453 else: # Delete by object
1452 try:
1454 try:
1453 obj = self.user_ns[varname]
1455 obj = self.user_ns[varname]
1454 except KeyError as e:
1456 except KeyError as e:
1455 raise NameError("name '%s' is not defined" % varname) from e
1457 raise NameError("name '%s' is not defined" % varname) from e
1456 # Also check in output history
1458 # Also check in output history
1457 ns_refs.append(self.history_manager.output_hist)
1459 ns_refs.append(self.history_manager.output_hist)
1458 for ns in ns_refs:
1460 for ns in ns_refs:
1459 to_delete = [n for n, o in ns.items() if o is obj]
1461 to_delete = [n for n, o in ns.items() if o is obj]
1460 for name in to_delete:
1462 for name in to_delete:
1461 del ns[name]
1463 del ns[name]
1462
1464
1463 # Ensure it is removed from the last execution result
1465 # Ensure it is removed from the last execution result
1464 if self.last_execution_result.result is obj:
1466 if self.last_execution_result.result is obj:
1465 self.last_execution_result = None
1467 self.last_execution_result = None
1466
1468
1467 # displayhook keeps extra references, but not in a dictionary
1469 # displayhook keeps extra references, but not in a dictionary
1468 for name in ('_', '__', '___'):
1470 for name in ('_', '__', '___'):
1469 if getattr(self.displayhook, name) is obj:
1471 if getattr(self.displayhook, name) is obj:
1470 setattr(self.displayhook, name, None)
1472 setattr(self.displayhook, name, None)
1471
1473
1472 def reset_selective(self, regex=None):
1474 def reset_selective(self, regex=None):
1473 """Clear selective variables from internal namespaces based on a
1475 """Clear selective variables from internal namespaces based on a
1474 specified regular expression.
1476 specified regular expression.
1475
1477
1476 Parameters
1478 Parameters
1477 ----------
1479 ----------
1478 regex : string or compiled pattern, optional
1480 regex : string or compiled pattern, optional
1479 A regular expression pattern that will be used in searching
1481 A regular expression pattern that will be used in searching
1480 variable names in the users namespaces.
1482 variable names in the users namespaces.
1481 """
1483 """
1482 if regex is not None:
1484 if regex is not None:
1483 try:
1485 try:
1484 m = re.compile(regex)
1486 m = re.compile(regex)
1485 except TypeError as e:
1487 except TypeError as e:
1486 raise TypeError('regex must be a string or compiled pattern') from e
1488 raise TypeError('regex must be a string or compiled pattern') from e
1487 # Search for keys in each namespace that match the given regex
1489 # Search for keys in each namespace that match the given regex
1488 # If a match is found, delete the key/value pair.
1490 # If a match is found, delete the key/value pair.
1489 for ns in self.all_ns_refs:
1491 for ns in self.all_ns_refs:
1490 for var in ns:
1492 for var in ns:
1491 if m.search(var):
1493 if m.search(var):
1492 del ns[var]
1494 del ns[var]
1493
1495
1494 def push(self, variables, interactive=True):
1496 def push(self, variables, interactive=True):
1495 """Inject a group of variables into the IPython user namespace.
1497 """Inject a group of variables into the IPython user namespace.
1496
1498
1497 Parameters
1499 Parameters
1498 ----------
1500 ----------
1499 variables : dict, str or list/tuple of str
1501 variables : dict, str or list/tuple of str
1500 The variables to inject into the user's namespace. If a dict, a
1502 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
1503 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
1504 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
1505 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
1506 give (list/tuple/str) then the variable values looked up in the
1505 callers frame.
1507 callers frame.
1506 interactive : bool
1508 interactive : bool
1507 If True (default), the variables will be listed with the ``who``
1509 If True (default), the variables will be listed with the ``who``
1508 magic.
1510 magic.
1509 """
1511 """
1510 vdict = None
1512 vdict = None
1511
1513
1512 # We need a dict of name/value pairs to do namespace updates.
1514 # We need a dict of name/value pairs to do namespace updates.
1513 if isinstance(variables, dict):
1515 if isinstance(variables, dict):
1514 vdict = variables
1516 vdict = variables
1515 elif isinstance(variables, (str, list, tuple)):
1517 elif isinstance(variables, (str, list, tuple)):
1516 if isinstance(variables, str):
1518 if isinstance(variables, str):
1517 vlist = variables.split()
1519 vlist = variables.split()
1518 else:
1520 else:
1519 vlist = variables
1521 vlist = variables
1520 vdict = {}
1522 vdict = {}
1521 cf = sys._getframe(1)
1523 cf = sys._getframe(1)
1522 for name in vlist:
1524 for name in vlist:
1523 try:
1525 try:
1524 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1526 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1525 except:
1527 except:
1526 print('Could not get variable %s from %s' %
1528 print('Could not get variable %s from %s' %
1527 (name,cf.f_code.co_name))
1529 (name,cf.f_code.co_name))
1528 else:
1530 else:
1529 raise ValueError('variables must be a dict/str/list/tuple')
1531 raise ValueError('variables must be a dict/str/list/tuple')
1530
1532
1531 # Propagate variables to user namespace
1533 # Propagate variables to user namespace
1532 self.user_ns.update(vdict)
1534 self.user_ns.update(vdict)
1533
1535
1534 # And configure interactive visibility
1536 # And configure interactive visibility
1535 user_ns_hidden = self.user_ns_hidden
1537 user_ns_hidden = self.user_ns_hidden
1536 if interactive:
1538 if interactive:
1537 for name in vdict:
1539 for name in vdict:
1538 user_ns_hidden.pop(name, None)
1540 user_ns_hidden.pop(name, None)
1539 else:
1541 else:
1540 user_ns_hidden.update(vdict)
1542 user_ns_hidden.update(vdict)
1541
1543
1542 def drop_by_id(self, variables):
1544 def drop_by_id(self, variables):
1543 """Remove a dict of variables from the user namespace, if they are the
1545 """Remove a dict of variables from the user namespace, if they are the
1544 same as the values in the dictionary.
1546 same as the values in the dictionary.
1545
1547
1546 This is intended for use by extensions: variables that they've added can
1548 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
1549 be taken back out if they are unloaded, without removing any that the
1548 user has overwritten.
1550 user has overwritten.
1549
1551
1550 Parameters
1552 Parameters
1551 ----------
1553 ----------
1552 variables : dict
1554 variables : dict
1553 A dictionary mapping object names (as strings) to the objects.
1555 A dictionary mapping object names (as strings) to the objects.
1554 """
1556 """
1555 for name, obj in variables.items():
1557 for name, obj in variables.items():
1556 if name in self.user_ns and self.user_ns[name] is obj:
1558 if name in self.user_ns and self.user_ns[name] is obj:
1557 del self.user_ns[name]
1559 del self.user_ns[name]
1558 self.user_ns_hidden.pop(name, None)
1560 self.user_ns_hidden.pop(name, None)
1559
1561
1560 #-------------------------------------------------------------------------
1562 #-------------------------------------------------------------------------
1561 # Things related to object introspection
1563 # Things related to object introspection
1562 #-------------------------------------------------------------------------
1564 #-------------------------------------------------------------------------
1565 @staticmethod
1566 def _find_parts(oname: str) -> ListType[str]:
1567 """
1568 Given an object name, return a list of parts of this object name.
1569
1570 Basically split on docs when using attribute access,
1571 and extract the value when using square bracket.
1572
1573
1574 For example foo.bar[3].baz[x] -> foo, bar, 3, baz, x
1575
1576
1577 Returns
1578 -------
1579 parts_ok: bool
1580 wether we were properly able to parse parts.
1581 parts: list of str
1582 extracted parts
1563
1583
1564 def _ofind(self, oname, namespaces=None):
1565 """Find an object in the available namespaces.
1566
1584
1567 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1568
1585
1569 Has special code to detect magic functions.
1570 """
1586 """
1571 oname = oname.strip()
1572 raw_parts = oname.split(".")
1587 raw_parts = oname.split(".")
1573 parts = []
1588 parts = []
1574 parts_ok = True
1589 parts_ok = True
1575 for p in raw_parts:
1590 for p in raw_parts:
1576 if p.endswith("]"):
1591 if p.endswith("]"):
1577 var, *indices = p.split("[")
1592 var, *indices = p.split("[")
1578 if not var.isidentifier():
1593 if not var.isidentifier():
1579 parts_ok = False
1594 parts_ok = False
1580 break
1595 break
1581 parts.append(var)
1596 parts.append(var)
1582 for ind in indices:
1597 for ind in indices:
1583 if ind[-1] != "]" and not is_integer_string(ind[:-1]):
1598 if ind[-1] != "]" and not is_integer_string(ind[:-1]):
1584 parts_ok = False
1599 parts_ok = False
1585 break
1600 break
1586 parts.append(ind[:-1])
1601 parts.append(ind[:-1])
1587 continue
1602 continue
1588
1603
1589 if not p.isidentifier():
1604 if not p.isidentifier():
1590 parts_ok = False
1605 parts_ok = False
1591 parts.append(p)
1606 parts.append(p)
1592
1607
1608 return parts_ok, parts
1609
1610 def _ofind(self, oname: str, namespaces: DictType[str, AnyType] = None):
1611 """Find an object in the available namespaces.
1612
1613 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1614
1615 Has special code to detect magic functions.
1616 """
1617 oname = oname.strip()
1618 parts_ok, parts = self._find_parts(oname)
1619
1593 if (
1620 if (
1594 not oname.startswith(ESC_MAGIC)
1621 not oname.startswith(ESC_MAGIC)
1595 and not oname.startswith(ESC_MAGIC2)
1622 and not oname.startswith(ESC_MAGIC2)
1596 and not parts_ok
1623 and not parts_ok
1597 ):
1624 ):
1598 return {"found": False}
1625 return OInfo(
1626 ismagic=False,
1627 isalias=False,
1628 found=False,
1629 obj=None,
1630 namespace="",
1631 parent=None,
1632 )
1599
1633
1600 if namespaces is None:
1634 if namespaces is None:
1601 # Namespaces to search in:
1635 # Namespaces to search in:
1602 # Put them in a list. The order is important so that we
1636 # Put them in a list. The order is important so that we
1603 # find things in the same order that Python finds them.
1637 # find things in the same order that Python finds them.
1604 namespaces = [ ('Interactive', self.user_ns),
1638 namespaces = [ ('Interactive', self.user_ns),
1605 ('Interactive (global)', self.user_global_ns),
1639 ('Interactive (global)', self.user_global_ns),
1606 ('Python builtin', builtin_mod.__dict__),
1640 ('Python builtin', builtin_mod.__dict__),
1607 ]
1641 ]
1608
1642
1609 ismagic = False
1643 ismagic = False
1610 isalias = False
1644 isalias = False
1611 found = False
1645 found = False
1612 ospace = None
1646 ospace = None
1613 parent = None
1647 parent = None
1614 obj = None
1648 obj = None
1615
1649
1616
1650
1617 # Look for the given name by splitting it in parts. If the head is
1651 # 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
1652 # found, then we look for all the remaining parts as members, and only
1619 # declare success if we can find them all.
1653 # declare success if we can find them all.
1620 oname_parts = parts
1654 oname_parts = parts
1621 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1655 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1622 for nsname,ns in namespaces:
1656 for nsname,ns in namespaces:
1623 try:
1657 try:
1624 obj = ns[oname_head]
1658 obj = ns[oname_head]
1625 except KeyError:
1659 except KeyError:
1626 continue
1660 continue
1627 else:
1661 else:
1628 for idx, part in enumerate(oname_rest):
1662 for idx, part in enumerate(oname_rest):
1629 try:
1663 try:
1630 parent = obj
1664 parent = obj
1631 # The last part is looked up in a special way to avoid
1665 # The last part is looked up in a special way to avoid
1632 # descriptor invocation as it may raise or have side
1666 # descriptor invocation as it may raise or have side
1633 # effects.
1667 # effects.
1634 if idx == len(oname_rest) - 1:
1668 if idx == len(oname_rest) - 1:
1635 obj = self._getattr_property(obj, part)
1669 obj = self._getattr_property(obj, part)
1636 else:
1670 else:
1637 if is_integer_string(part):
1671 if is_integer_string(part):
1638 obj = obj[int(part)]
1672 obj = obj[int(part)]
1639 else:
1673 else:
1640 obj = getattr(obj, part)
1674 obj = getattr(obj, part)
1641 except:
1675 except:
1642 # Blanket except b/c some badly implemented objects
1676 # Blanket except b/c some badly implemented objects
1643 # allow __getattr__ to raise exceptions other than
1677 # allow __getattr__ to raise exceptions other than
1644 # AttributeError, which then crashes IPython.
1678 # AttributeError, which then crashes IPython.
1645 break
1679 break
1646 else:
1680 else:
1647 # If we finish the for loop (no break), we got all members
1681 # If we finish the for loop (no break), we got all members
1648 found = True
1682 found = True
1649 ospace = nsname
1683 ospace = nsname
1650 break # namespace loop
1684 break # namespace loop
1651
1685
1652 # Try to see if it's magic
1686 # Try to see if it's magic
1653 if not found:
1687 if not found:
1654 obj = None
1688 obj = None
1655 if oname.startswith(ESC_MAGIC2):
1689 if oname.startswith(ESC_MAGIC2):
1656 oname = oname.lstrip(ESC_MAGIC2)
1690 oname = oname.lstrip(ESC_MAGIC2)
1657 obj = self.find_cell_magic(oname)
1691 obj = self.find_cell_magic(oname)
1658 elif oname.startswith(ESC_MAGIC):
1692 elif oname.startswith(ESC_MAGIC):
1659 oname = oname.lstrip(ESC_MAGIC)
1693 oname = oname.lstrip(ESC_MAGIC)
1660 obj = self.find_line_magic(oname)
1694 obj = self.find_line_magic(oname)
1661 else:
1695 else:
1662 # search without prefix, so run? will find %run?
1696 # search without prefix, so run? will find %run?
1663 obj = self.find_line_magic(oname)
1697 obj = self.find_line_magic(oname)
1664 if obj is None:
1698 if obj is None:
1665 obj = self.find_cell_magic(oname)
1699 obj = self.find_cell_magic(oname)
1666 if obj is not None:
1700 if obj is not None:
1667 found = True
1701 found = True
1668 ospace = 'IPython internal'
1702 ospace = 'IPython internal'
1669 ismagic = True
1703 ismagic = True
1670 isalias = isinstance(obj, Alias)
1704 isalias = isinstance(obj, Alias)
1671
1705
1672 # Last try: special-case some literals like '', [], {}, etc:
1706 # Last try: special-case some literals like '', [], {}, etc:
1673 if not found and oname_head in ["''",'""','[]','{}','()']:
1707 if not found and oname_head in ["''",'""','[]','{}','()']:
1674 obj = eval(oname_head)
1708 obj = eval(oname_head)
1675 found = True
1709 found = True
1676 ospace = 'Interactive'
1710 ospace = 'Interactive'
1677
1711
1678 return {
1712 return OInfo(
1679 'obj':obj,
1713 **{
1680 'found':found,
1714 "obj": obj,
1681 'parent':parent,
1715 "found": found,
1682 'ismagic':ismagic,
1716 "parent": parent,
1683 'isalias':isalias,
1717 "ismagic": ismagic,
1684 'namespace':ospace
1718 "isalias": isalias,
1685 }
1719 "namespace": ospace,
1720 }
1721 )
1686
1722
1687 @staticmethod
1723 @staticmethod
1688 def _getattr_property(obj, attrname):
1724 def _getattr_property(obj, attrname):
1689 """Property-aware getattr to use in object finding.
1725 """Property-aware getattr to use in object finding.
1690
1726
1691 If attrname represents a property, return it unevaluated (in case it has
1727 If attrname represents a property, return it unevaluated (in case it has
1692 side effects or raises an error.
1728 side effects or raises an error.
1693
1729
1694 """
1730 """
1695 if not isinstance(obj, type):
1731 if not isinstance(obj, type):
1696 try:
1732 try:
1697 # `getattr(type(obj), attrname)` is not guaranteed to return
1733 # `getattr(type(obj), attrname)` is not guaranteed to return
1698 # `obj`, but does so for property:
1734 # `obj`, but does so for property:
1699 #
1735 #
1700 # property.__get__(self, None, cls) -> self
1736 # property.__get__(self, None, cls) -> self
1701 #
1737 #
1702 # The universal alternative is to traverse the mro manually
1738 # The universal alternative is to traverse the mro manually
1703 # searching for attrname in class dicts.
1739 # searching for attrname in class dicts.
1704 if is_integer_string(attrname):
1740 if is_integer_string(attrname):
1705 return obj[int(attrname)]
1741 return obj[int(attrname)]
1706 else:
1742 else:
1707 attr = getattr(type(obj), attrname)
1743 attr = getattr(type(obj), attrname)
1708 except AttributeError:
1744 except AttributeError:
1709 pass
1745 pass
1710 else:
1746 else:
1711 # This relies on the fact that data descriptors (with both
1747 # This relies on the fact that data descriptors (with both
1712 # __get__ & __set__ magic methods) take precedence over
1748 # __get__ & __set__ magic methods) take precedence over
1713 # instance-level attributes:
1749 # instance-level attributes:
1714 #
1750 #
1715 # class A(object):
1751 # class A(object):
1716 # @property
1752 # @property
1717 # def foobar(self): return 123
1753 # def foobar(self): return 123
1718 # a = A()
1754 # a = A()
1719 # a.__dict__['foobar'] = 345
1755 # a.__dict__['foobar'] = 345
1720 # a.foobar # == 123
1756 # a.foobar # == 123
1721 #
1757 #
1722 # So, a property may be returned right away.
1758 # So, a property may be returned right away.
1723 if isinstance(attr, property):
1759 if isinstance(attr, property):
1724 return attr
1760 return attr
1725
1761
1726 # Nothing helped, fall back.
1762 # Nothing helped, fall back.
1727 return getattr(obj, attrname)
1763 return getattr(obj, attrname)
1728
1764
1729 def _object_find(self, oname, namespaces=None):
1765 def _object_find(self, oname, namespaces=None) -> OInfo:
1730 """Find an object and return a struct with info about it."""
1766 """Find an object and return a struct with info about it."""
1731 return Struct(self._ofind(oname, namespaces))
1767 return self._ofind(oname, namespaces)
1732
1768
1733 def _inspect(self, meth, oname, namespaces=None, **kw):
1769 def _inspect(self, meth, oname, namespaces=None, **kw):
1734 """Generic interface to the inspector system.
1770 """Generic interface to the inspector system.
1735
1771
1736 This function is meant to be called by pdef, pdoc & friends.
1772 This function is meant to be called by pdef, pdoc & friends.
1737 """
1773 """
1738 info = self._object_find(oname, namespaces)
1774 info = self._object_find(oname, namespaces)
1739 docformat = (
1775 docformat = (
1740 sphinxify(self.object_inspect(oname)) if self.sphinxify_docstring else None
1776 sphinxify(self.object_inspect(oname)) if self.sphinxify_docstring else None
1741 )
1777 )
1742 if info.found:
1778 if info.found:
1743 pmethod = getattr(self.inspector, meth)
1779 pmethod = getattr(self.inspector, meth)
1744 # TODO: only apply format_screen to the plain/text repr of the mime
1780 # TODO: only apply format_screen to the plain/text repr of the mime
1745 # bundle.
1781 # bundle.
1746 formatter = format_screen if info.ismagic else docformat
1782 formatter = format_screen if info.ismagic else docformat
1747 if meth == 'pdoc':
1783 if meth == 'pdoc':
1748 pmethod(info.obj, oname, formatter)
1784 pmethod(info.obj, oname, formatter)
1749 elif meth == 'pinfo':
1785 elif meth == 'pinfo':
1750 pmethod(
1786 pmethod(
1751 info.obj,
1787 info.obj,
1752 oname,
1788 oname,
1753 formatter,
1789 formatter,
1754 info,
1790 info,
1755 enable_html_pager=self.enable_html_pager,
1791 enable_html_pager=self.enable_html_pager,
1756 **kw,
1792 **kw,
1757 )
1793 )
1758 else:
1794 else:
1759 pmethod(info.obj, oname)
1795 pmethod(info.obj, oname)
1760 else:
1796 else:
1761 print('Object `%s` not found.' % oname)
1797 print('Object `%s` not found.' % oname)
1762 return 'not found' # so callers can take other action
1798 return 'not found' # so callers can take other action
1763
1799
1764 def object_inspect(self, oname, detail_level=0):
1800 def object_inspect(self, oname, detail_level=0):
1765 """Get object info about oname"""
1801 """Get object info about oname"""
1766 with self.builtin_trap:
1802 with self.builtin_trap:
1767 info = self._object_find(oname)
1803 info = self._object_find(oname)
1768 if info.found:
1804 if info.found:
1769 return self.inspector.info(info.obj, oname, info=info,
1805 return self.inspector.info(info.obj, oname, info=info,
1770 detail_level=detail_level
1806 detail_level=detail_level
1771 )
1807 )
1772 else:
1808 else:
1773 return oinspect.object_info(name=oname, found=False)
1809 return oinspect.object_info(name=oname, found=False)
1774
1810
1775 def object_inspect_text(self, oname, detail_level=0):
1811 def object_inspect_text(self, oname, detail_level=0):
1776 """Get object info as formatted text"""
1812 """Get object info as formatted text"""
1777 return self.object_inspect_mime(oname, detail_level)['text/plain']
1813 return self.object_inspect_mime(oname, detail_level)['text/plain']
1778
1814
1779 def object_inspect_mime(self, oname, detail_level=0, omit_sections=()):
1815 def object_inspect_mime(self, oname, detail_level=0, omit_sections=()):
1780 """Get object info as a mimebundle of formatted representations.
1816 """Get object info as a mimebundle of formatted representations.
1781
1817
1782 A mimebundle is a dictionary, keyed by mime-type.
1818 A mimebundle is a dictionary, keyed by mime-type.
1783 It must always have the key `'text/plain'`.
1819 It must always have the key `'text/plain'`.
1784 """
1820 """
1785 with self.builtin_trap:
1821 with self.builtin_trap:
1786 info = self._object_find(oname)
1822 info = self._object_find(oname)
1787 if info.found:
1823 if info.found:
1788 docformat = (
1824 docformat = (
1789 sphinxify(self.object_inspect(oname))
1825 sphinxify(self.object_inspect(oname))
1790 if self.sphinxify_docstring
1826 if self.sphinxify_docstring
1791 else None
1827 else None
1792 )
1828 )
1793 return self.inspector._get_info(
1829 return self.inspector._get_info(
1794 info.obj,
1830 info.obj,
1795 oname,
1831 oname,
1796 info=info,
1832 info=info,
1797 detail_level=detail_level,
1833 detail_level=detail_level,
1798 formatter=docformat,
1834 formatter=docformat,
1799 omit_sections=omit_sections,
1835 omit_sections=omit_sections,
1800 )
1836 )
1801 else:
1837 else:
1802 raise KeyError(oname)
1838 raise KeyError(oname)
1803
1839
1804 #-------------------------------------------------------------------------
1840 #-------------------------------------------------------------------------
1805 # Things related to history management
1841 # Things related to history management
1806 #-------------------------------------------------------------------------
1842 #-------------------------------------------------------------------------
1807
1843
1808 def init_history(self):
1844 def init_history(self):
1809 """Sets up the command history, and starts regular autosaves."""
1845 """Sets up the command history, and starts regular autosaves."""
1810 self.history_manager = HistoryManager(shell=self, parent=self)
1846 self.history_manager = HistoryManager(shell=self, parent=self)
1811 self.configurables.append(self.history_manager)
1847 self.configurables.append(self.history_manager)
1812
1848
1813 #-------------------------------------------------------------------------
1849 #-------------------------------------------------------------------------
1814 # Things related to exception handling and tracebacks (not debugging)
1850 # Things related to exception handling and tracebacks (not debugging)
1815 #-------------------------------------------------------------------------
1851 #-------------------------------------------------------------------------
1816
1852
1817 debugger_cls = InterruptiblePdb
1853 debugger_cls = InterruptiblePdb
1818
1854
1819 def init_traceback_handlers(self, custom_exceptions):
1855 def init_traceback_handlers(self, custom_exceptions):
1820 # Syntax error handler.
1856 # Syntax error handler.
1821 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor', parent=self)
1857 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor', parent=self)
1822
1858
1823 # The interactive one is initialized with an offset, meaning we always
1859 # 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
1860 # want to remove the topmost item in the traceback, which is our own
1825 # internal code. Valid modes: ['Plain','Context','Verbose','Minimal']
1861 # internal code. Valid modes: ['Plain','Context','Verbose','Minimal']
1826 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1862 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1827 color_scheme='NoColor',
1863 color_scheme='NoColor',
1828 tb_offset = 1,
1864 tb_offset = 1,
1829 debugger_cls=self.debugger_cls, parent=self)
1865 debugger_cls=self.debugger_cls, parent=self)
1830
1866
1831 # The instance will store a pointer to the system-wide exception hook,
1867 # 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
1868 # so that runtime code (such as magics) can access it. This is because
1833 # during the read-eval loop, it may get temporarily overwritten.
1869 # during the read-eval loop, it may get temporarily overwritten.
1834 self.sys_excepthook = sys.excepthook
1870 self.sys_excepthook = sys.excepthook
1835
1871
1836 # and add any custom exception handlers the user may have specified
1872 # and add any custom exception handlers the user may have specified
1837 self.set_custom_exc(*custom_exceptions)
1873 self.set_custom_exc(*custom_exceptions)
1838
1874
1839 # Set the exception mode
1875 # Set the exception mode
1840 self.InteractiveTB.set_mode(mode=self.xmode)
1876 self.InteractiveTB.set_mode(mode=self.xmode)
1841
1877
1842 def set_custom_exc(self, exc_tuple, handler):
1878 def set_custom_exc(self, exc_tuple, handler):
1843 """set_custom_exc(exc_tuple, handler)
1879 """set_custom_exc(exc_tuple, handler)
1844
1880
1845 Set a custom exception handler, which will be called if any of the
1881 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
1882 exceptions in exc_tuple occur in the mainloop (specifically, in the
1847 run_code() method).
1883 run_code() method).
1848
1884
1849 Parameters
1885 Parameters
1850 ----------
1886 ----------
1851 exc_tuple : tuple of exception classes
1887 exc_tuple : tuple of exception classes
1852 A *tuple* of exception classes, for which to call the defined
1888 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
1889 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
1890 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::
1891 you only want to trap a single exception, use a singleton tuple::
1856
1892
1857 exc_tuple == (MyCustomException,)
1893 exc_tuple == (MyCustomException,)
1858
1894
1859 handler : callable
1895 handler : callable
1860 handler must have the following signature::
1896 handler must have the following signature::
1861
1897
1862 def my_handler(self, etype, value, tb, tb_offset=None):
1898 def my_handler(self, etype, value, tb, tb_offset=None):
1863 ...
1899 ...
1864 return structured_traceback
1900 return structured_traceback
1865
1901
1866 Your handler must return a structured traceback (a list of strings),
1902 Your handler must return a structured traceback (a list of strings),
1867 or None.
1903 or None.
1868
1904
1869 This will be made into an instance method (via types.MethodType)
1905 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
1906 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
1907 listed in the exc_tuple are caught. If the handler is None, an
1872 internal basic one is used, which just prints basic info.
1908 internal basic one is used, which just prints basic info.
1873
1909
1874 To protect IPython from crashes, if your handler ever raises an
1910 To protect IPython from crashes, if your handler ever raises an
1875 exception or returns an invalid result, it will be immediately
1911 exception or returns an invalid result, it will be immediately
1876 disabled.
1912 disabled.
1877
1913
1878 Notes
1914 Notes
1879 -----
1915 -----
1880 WARNING: by putting in your own exception handler into IPython's main
1916 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
1917 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.
1918 facility should only be used if you really know what you are doing.
1883 """
1919 """
1884
1920
1885 if not isinstance(exc_tuple, tuple):
1921 if not isinstance(exc_tuple, tuple):
1886 raise TypeError("The custom exceptions must be given as a tuple.")
1922 raise TypeError("The custom exceptions must be given as a tuple.")
1887
1923
1888 def dummy_handler(self, etype, value, tb, tb_offset=None):
1924 def dummy_handler(self, etype, value, tb, tb_offset=None):
1889 print('*** Simple custom exception handler ***')
1925 print('*** Simple custom exception handler ***')
1890 print('Exception type :', etype)
1926 print('Exception type :', etype)
1891 print('Exception value:', value)
1927 print('Exception value:', value)
1892 print('Traceback :', tb)
1928 print('Traceback :', tb)
1893
1929
1894 def validate_stb(stb):
1930 def validate_stb(stb):
1895 """validate structured traceback return type
1931 """validate structured traceback return type
1896
1932
1897 return type of CustomTB *should* be a list of strings, but allow
1933 return type of CustomTB *should* be a list of strings, but allow
1898 single strings or None, which are harmless.
1934 single strings or None, which are harmless.
1899
1935
1900 This function will *always* return a list of strings,
1936 This function will *always* return a list of strings,
1901 and will raise a TypeError if stb is inappropriate.
1937 and will raise a TypeError if stb is inappropriate.
1902 """
1938 """
1903 msg = "CustomTB must return list of strings, not %r" % stb
1939 msg = "CustomTB must return list of strings, not %r" % stb
1904 if stb is None:
1940 if stb is None:
1905 return []
1941 return []
1906 elif isinstance(stb, str):
1942 elif isinstance(stb, str):
1907 return [stb]
1943 return [stb]
1908 elif not isinstance(stb, list):
1944 elif not isinstance(stb, list):
1909 raise TypeError(msg)
1945 raise TypeError(msg)
1910 # it's a list
1946 # it's a list
1911 for line in stb:
1947 for line in stb:
1912 # check every element
1948 # check every element
1913 if not isinstance(line, str):
1949 if not isinstance(line, str):
1914 raise TypeError(msg)
1950 raise TypeError(msg)
1915 return stb
1951 return stb
1916
1952
1917 if handler is None:
1953 if handler is None:
1918 wrapped = dummy_handler
1954 wrapped = dummy_handler
1919 else:
1955 else:
1920 def wrapped(self,etype,value,tb,tb_offset=None):
1956 def wrapped(self,etype,value,tb,tb_offset=None):
1921 """wrap CustomTB handler, to protect IPython from user code
1957 """wrap CustomTB handler, to protect IPython from user code
1922
1958
1923 This makes it harder (but not impossible) for custom exception
1959 This makes it harder (but not impossible) for custom exception
1924 handlers to crash IPython.
1960 handlers to crash IPython.
1925 """
1961 """
1926 try:
1962 try:
1927 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1963 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1928 return validate_stb(stb)
1964 return validate_stb(stb)
1929 except:
1965 except:
1930 # clear custom handler immediately
1966 # clear custom handler immediately
1931 self.set_custom_exc((), None)
1967 self.set_custom_exc((), None)
1932 print("Custom TB Handler failed, unregistering", file=sys.stderr)
1968 print("Custom TB Handler failed, unregistering", file=sys.stderr)
1933 # show the exception in handler first
1969 # show the exception in handler first
1934 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1970 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1935 print(self.InteractiveTB.stb2text(stb))
1971 print(self.InteractiveTB.stb2text(stb))
1936 print("The original exception:")
1972 print("The original exception:")
1937 stb = self.InteractiveTB.structured_traceback(
1973 stb = self.InteractiveTB.structured_traceback(
1938 (etype,value,tb), tb_offset=tb_offset
1974 (etype,value,tb), tb_offset=tb_offset
1939 )
1975 )
1940 return stb
1976 return stb
1941
1977
1942 self.CustomTB = types.MethodType(wrapped,self)
1978 self.CustomTB = types.MethodType(wrapped,self)
1943 self.custom_exceptions = exc_tuple
1979 self.custom_exceptions = exc_tuple
1944
1980
1945 def excepthook(self, etype, value, tb):
1981 def excepthook(self, etype, value, tb):
1946 """One more defense for GUI apps that call sys.excepthook.
1982 """One more defense for GUI apps that call sys.excepthook.
1947
1983
1948 GUI frameworks like wxPython trap exceptions and call
1984 GUI frameworks like wxPython trap exceptions and call
1949 sys.excepthook themselves. I guess this is a feature that
1985 sys.excepthook themselves. I guess this is a feature that
1950 enables them to keep running after exceptions that would
1986 enables them to keep running after exceptions that would
1951 otherwise kill their mainloop. This is a bother for IPython
1987 otherwise kill their mainloop. This is a bother for IPython
1952 which expects to catch all of the program exceptions with a try:
1988 which expects to catch all of the program exceptions with a try:
1953 except: statement.
1989 except: statement.
1954
1990
1955 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1991 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
1992 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
1993 IPython crashed. In order to work around this, we can disable the
1958 CrashHandler and replace it with this excepthook instead, which prints a
1994 CrashHandler and replace it with this excepthook instead, which prints a
1959 regular traceback using our InteractiveTB. In this fashion, apps which
1995 regular traceback using our InteractiveTB. In this fashion, apps which
1960 call sys.excepthook will generate a regular-looking exception from
1996 call sys.excepthook will generate a regular-looking exception from
1961 IPython, and the CrashHandler will only be triggered by real IPython
1997 IPython, and the CrashHandler will only be triggered by real IPython
1962 crashes.
1998 crashes.
1963
1999
1964 This hook should be used sparingly, only in places which are not likely
2000 This hook should be used sparingly, only in places which are not likely
1965 to be true IPython errors.
2001 to be true IPython errors.
1966 """
2002 """
1967 self.showtraceback((etype, value, tb), tb_offset=0)
2003 self.showtraceback((etype, value, tb), tb_offset=0)
1968
2004
1969 def _get_exc_info(self, exc_tuple=None):
2005 def _get_exc_info(self, exc_tuple=None):
1970 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
2006 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1971
2007
1972 Ensures sys.last_type,value,traceback hold the exc_info we found,
2008 Ensures sys.last_type,value,traceback hold the exc_info we found,
1973 from whichever source.
2009 from whichever source.
1974
2010
1975 raises ValueError if none of these contain any information
2011 raises ValueError if none of these contain any information
1976 """
2012 """
1977 if exc_tuple is None:
2013 if exc_tuple is None:
1978 etype, value, tb = sys.exc_info()
2014 etype, value, tb = sys.exc_info()
1979 else:
2015 else:
1980 etype, value, tb = exc_tuple
2016 etype, value, tb = exc_tuple
1981
2017
1982 if etype is None:
2018 if etype is None:
1983 if hasattr(sys, 'last_type'):
2019 if hasattr(sys, 'last_type'):
1984 etype, value, tb = sys.last_type, sys.last_value, \
2020 etype, value, tb = sys.last_type, sys.last_value, \
1985 sys.last_traceback
2021 sys.last_traceback
1986
2022
1987 if etype is None:
2023 if etype is None:
1988 raise ValueError("No exception to find")
2024 raise ValueError("No exception to find")
1989
2025
1990 # Now store the exception info in sys.last_type etc.
2026 # Now store the exception info in sys.last_type etc.
1991 # WARNING: these variables are somewhat deprecated and not
2027 # WARNING: these variables are somewhat deprecated and not
1992 # necessarily safe to use in a threaded environment, but tools
2028 # necessarily safe to use in a threaded environment, but tools
1993 # like pdb depend on their existence, so let's set them. If we
2029 # 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.
2030 # find problems in the field, we'll need to revisit their use.
1995 sys.last_type = etype
2031 sys.last_type = etype
1996 sys.last_value = value
2032 sys.last_value = value
1997 sys.last_traceback = tb
2033 sys.last_traceback = tb
1998
2034
1999 return etype, value, tb
2035 return etype, value, tb
2000
2036
2001 def show_usage_error(self, exc):
2037 def show_usage_error(self, exc):
2002 """Show a short message for UsageErrors
2038 """Show a short message for UsageErrors
2003
2039
2004 These are special exceptions that shouldn't show a traceback.
2040 These are special exceptions that shouldn't show a traceback.
2005 """
2041 """
2006 print("UsageError: %s" % exc, file=sys.stderr)
2042 print("UsageError: %s" % exc, file=sys.stderr)
2007
2043
2008 def get_exception_only(self, exc_tuple=None):
2044 def get_exception_only(self, exc_tuple=None):
2009 """
2045 """
2010 Return as a string (ending with a newline) the exception that
2046 Return as a string (ending with a newline) the exception that
2011 just occurred, without any traceback.
2047 just occurred, without any traceback.
2012 """
2048 """
2013 etype, value, tb = self._get_exc_info(exc_tuple)
2049 etype, value, tb = self._get_exc_info(exc_tuple)
2014 msg = traceback.format_exception_only(etype, value)
2050 msg = traceback.format_exception_only(etype, value)
2015 return ''.join(msg)
2051 return ''.join(msg)
2016
2052
2017 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
2053 def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None,
2018 exception_only=False, running_compiled_code=False):
2054 exception_only=False, running_compiled_code=False):
2019 """Display the exception that just occurred.
2055 """Display the exception that just occurred.
2020
2056
2021 If nothing is known about the exception, this is the method which
2057 If nothing is known about the exception, this is the method which
2022 should be used throughout the code for presenting user tracebacks,
2058 should be used throughout the code for presenting user tracebacks,
2023 rather than directly invoking the InteractiveTB object.
2059 rather than directly invoking the InteractiveTB object.
2024
2060
2025 A specific showsyntaxerror() also exists, but this method can take
2061 A specific showsyntaxerror() also exists, but this method can take
2026 care of calling it if needed, so unless you are explicitly catching a
2062 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
2063 SyntaxError exception, don't try to analyze the stack manually and
2028 simply call this method."""
2064 simply call this method."""
2029
2065
2030 try:
2066 try:
2031 try:
2067 try:
2032 etype, value, tb = self._get_exc_info(exc_tuple)
2068 etype, value, tb = self._get_exc_info(exc_tuple)
2033 except ValueError:
2069 except ValueError:
2034 print('No traceback available to show.', file=sys.stderr)
2070 print('No traceback available to show.', file=sys.stderr)
2035 return
2071 return
2036
2072
2037 if issubclass(etype, SyntaxError):
2073 if issubclass(etype, SyntaxError):
2038 # Though this won't be called by syntax errors in the input
2074 # Though this won't be called by syntax errors in the input
2039 # line, there may be SyntaxError cases with imported code.
2075 # line, there may be SyntaxError cases with imported code.
2040 self.showsyntaxerror(filename, running_compiled_code)
2076 self.showsyntaxerror(filename, running_compiled_code)
2041 elif etype is UsageError:
2077 elif etype is UsageError:
2042 self.show_usage_error(value)
2078 self.show_usage_error(value)
2043 else:
2079 else:
2044 if exception_only:
2080 if exception_only:
2045 stb = ['An exception has occurred, use %tb to see '
2081 stb = ['An exception has occurred, use %tb to see '
2046 'the full traceback.\n']
2082 'the full traceback.\n']
2047 stb.extend(self.InteractiveTB.get_exception_only(etype,
2083 stb.extend(self.InteractiveTB.get_exception_only(etype,
2048 value))
2084 value))
2049 else:
2085 else:
2050 try:
2086 try:
2051 # Exception classes can customise their traceback - we
2087 # Exception classes can customise their traceback - we
2052 # use this in IPython.parallel for exceptions occurring
2088 # use this in IPython.parallel for exceptions occurring
2053 # in the engines. This should return a list of strings.
2089 # in the engines. This should return a list of strings.
2054 if hasattr(value, "_render_traceback_"):
2090 if hasattr(value, "_render_traceback_"):
2055 stb = value._render_traceback_()
2091 stb = value._render_traceback_()
2056 else:
2092 else:
2057 stb = self.InteractiveTB.structured_traceback(
2093 stb = self.InteractiveTB.structured_traceback(
2058 etype, value, tb, tb_offset=tb_offset
2094 etype, value, tb, tb_offset=tb_offset
2059 )
2095 )
2060
2096
2061 except Exception:
2097 except Exception:
2062 print(
2098 print(
2063 "Unexpected exception formatting exception. Falling back to standard exception"
2099 "Unexpected exception formatting exception. Falling back to standard exception"
2064 )
2100 )
2065 traceback.print_exc()
2101 traceback.print_exc()
2066 return None
2102 return None
2067
2103
2068 self._showtraceback(etype, value, stb)
2104 self._showtraceback(etype, value, stb)
2069 if self.call_pdb:
2105 if self.call_pdb:
2070 # drop into debugger
2106 # drop into debugger
2071 self.debugger(force=True)
2107 self.debugger(force=True)
2072 return
2108 return
2073
2109
2074 # Actually show the traceback
2110 # Actually show the traceback
2075 self._showtraceback(etype, value, stb)
2111 self._showtraceback(etype, value, stb)
2076
2112
2077 except KeyboardInterrupt:
2113 except KeyboardInterrupt:
2078 print('\n' + self.get_exception_only(), file=sys.stderr)
2114 print('\n' + self.get_exception_only(), file=sys.stderr)
2079
2115
2080 def _showtraceback(self, etype, evalue, stb: str):
2116 def _showtraceback(self, etype, evalue, stb: str):
2081 """Actually show a traceback.
2117 """Actually show a traceback.
2082
2118
2083 Subclasses may override this method to put the traceback on a different
2119 Subclasses may override this method to put the traceback on a different
2084 place, like a side channel.
2120 place, like a side channel.
2085 """
2121 """
2086 val = self.InteractiveTB.stb2text(stb)
2122 val = self.InteractiveTB.stb2text(stb)
2087 try:
2123 try:
2088 print(val)
2124 print(val)
2089 except UnicodeEncodeError:
2125 except UnicodeEncodeError:
2090 print(val.encode("utf-8", "backslashreplace").decode())
2126 print(val.encode("utf-8", "backslashreplace").decode())
2091
2127
2092 def showsyntaxerror(self, filename=None, running_compiled_code=False):
2128 def showsyntaxerror(self, filename=None, running_compiled_code=False):
2093 """Display the syntax error that just occurred.
2129 """Display the syntax error that just occurred.
2094
2130
2095 This doesn't display a stack trace because there isn't one.
2131 This doesn't display a stack trace because there isn't one.
2096
2132
2097 If a filename is given, it is stuffed in the exception instead
2133 If a filename is given, it is stuffed in the exception instead
2098 of what was there before (because Python's parser always uses
2134 of what was there before (because Python's parser always uses
2099 "<string>" when reading from a string).
2135 "<string>" when reading from a string).
2100
2136
2101 If the syntax error occurred when running a compiled code (i.e. running_compile_code=True),
2137 If the syntax error occurred when running a compiled code (i.e. running_compile_code=True),
2102 longer stack trace will be displayed.
2138 longer stack trace will be displayed.
2103 """
2139 """
2104 etype, value, last_traceback = self._get_exc_info()
2140 etype, value, last_traceback = self._get_exc_info()
2105
2141
2106 if filename and issubclass(etype, SyntaxError):
2142 if filename and issubclass(etype, SyntaxError):
2107 try:
2143 try:
2108 value.filename = filename
2144 value.filename = filename
2109 except:
2145 except:
2110 # Not the format we expect; leave it alone
2146 # Not the format we expect; leave it alone
2111 pass
2147 pass
2112
2148
2113 # If the error occurred when executing compiled code, we should provide full stacktrace.
2149 # 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 []
2150 elist = traceback.extract_tb(last_traceback) if running_compiled_code else []
2115 stb = self.SyntaxTB.structured_traceback(etype, value, elist)
2151 stb = self.SyntaxTB.structured_traceback(etype, value, elist)
2116 self._showtraceback(etype, value, stb)
2152 self._showtraceback(etype, value, stb)
2117
2153
2118 # This is overridden in TerminalInteractiveShell to show a message about
2154 # This is overridden in TerminalInteractiveShell to show a message about
2119 # the %paste magic.
2155 # the %paste magic.
2120 def showindentationerror(self):
2156 def showindentationerror(self):
2121 """Called by _run_cell when there's an IndentationError in code entered
2157 """Called by _run_cell when there's an IndentationError in code entered
2122 at the prompt.
2158 at the prompt.
2123
2159
2124 This is overridden in TerminalInteractiveShell to show a message about
2160 This is overridden in TerminalInteractiveShell to show a message about
2125 the %paste magic."""
2161 the %paste magic."""
2126 self.showsyntaxerror()
2162 self.showsyntaxerror()
2127
2163
2128 @skip_doctest
2164 @skip_doctest
2129 def set_next_input(self, s, replace=False):
2165 def set_next_input(self, s, replace=False):
2130 """ Sets the 'default' input string for the next command line.
2166 """ Sets the 'default' input string for the next command line.
2131
2167
2132 Example::
2168 Example::
2133
2169
2134 In [1]: _ip.set_next_input("Hello Word")
2170 In [1]: _ip.set_next_input("Hello Word")
2135 In [2]: Hello Word_ # cursor is here
2171 In [2]: Hello Word_ # cursor is here
2136 """
2172 """
2137 self.rl_next_input = s
2173 self.rl_next_input = s
2138
2174
2139 def _indent_current_str(self):
2175 def _indent_current_str(self):
2140 """return the current level of indentation as a string"""
2176 """return the current level of indentation as a string"""
2141 return self.input_splitter.get_indent_spaces() * ' '
2177 return self.input_splitter.get_indent_spaces() * ' '
2142
2178
2143 #-------------------------------------------------------------------------
2179 #-------------------------------------------------------------------------
2144 # Things related to text completion
2180 # Things related to text completion
2145 #-------------------------------------------------------------------------
2181 #-------------------------------------------------------------------------
2146
2182
2147 def init_completer(self):
2183 def init_completer(self):
2148 """Initialize the completion machinery.
2184 """Initialize the completion machinery.
2149
2185
2150 This creates completion machinery that can be used by client code,
2186 This creates completion machinery that can be used by client code,
2151 either interactively in-process (typically triggered by the readline
2187 either interactively in-process (typically triggered by the readline
2152 library), programmatically (such as in test suites) or out-of-process
2188 library), programmatically (such as in test suites) or out-of-process
2153 (typically over the network by remote frontends).
2189 (typically over the network by remote frontends).
2154 """
2190 """
2155 from IPython.core.completer import IPCompleter
2191 from IPython.core.completer import IPCompleter
2156 from IPython.core.completerlib import (
2192 from IPython.core.completerlib import (
2157 cd_completer,
2193 cd_completer,
2158 magic_run_completer,
2194 magic_run_completer,
2159 module_completer,
2195 module_completer,
2160 reset_completer,
2196 reset_completer,
2161 )
2197 )
2162
2198
2163 self.Completer = IPCompleter(shell=self,
2199 self.Completer = IPCompleter(shell=self,
2164 namespace=self.user_ns,
2200 namespace=self.user_ns,
2165 global_namespace=self.user_global_ns,
2201 global_namespace=self.user_global_ns,
2166 parent=self,
2202 parent=self,
2167 )
2203 )
2168 self.configurables.append(self.Completer)
2204 self.configurables.append(self.Completer)
2169
2205
2170 # Add custom completers to the basic ones built into IPCompleter
2206 # Add custom completers to the basic ones built into IPCompleter
2171 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2207 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
2172 self.strdispatchers['complete_command'] = sdisp
2208 self.strdispatchers['complete_command'] = sdisp
2173 self.Completer.custom_completers = sdisp
2209 self.Completer.custom_completers = sdisp
2174
2210
2175 self.set_hook('complete_command', module_completer, str_key = 'import')
2211 self.set_hook('complete_command', module_completer, str_key = 'import')
2176 self.set_hook('complete_command', module_completer, str_key = 'from')
2212 self.set_hook('complete_command', module_completer, str_key = 'from')
2177 self.set_hook('complete_command', module_completer, str_key = '%aimport')
2213 self.set_hook('complete_command', module_completer, str_key = '%aimport')
2178 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2214 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
2179 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2215 self.set_hook('complete_command', cd_completer, str_key = '%cd')
2180 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2216 self.set_hook('complete_command', reset_completer, str_key = '%reset')
2181
2217
2182 @skip_doctest
2218 @skip_doctest
2183 def complete(self, text, line=None, cursor_pos=None):
2219 def complete(self, text, line=None, cursor_pos=None):
2184 """Return the completed text and a list of completions.
2220 """Return the completed text and a list of completions.
2185
2221
2186 Parameters
2222 Parameters
2187 ----------
2223 ----------
2188 text : string
2224 text : string
2189 A string of text to be completed on. It can be given as empty and
2225 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
2226 instead a line/position pair are given. In this case, the
2191 completer itself will split the line like readline does.
2227 completer itself will split the line like readline does.
2192 line : string, optional
2228 line : string, optional
2193 The complete line that text is part of.
2229 The complete line that text is part of.
2194 cursor_pos : int, optional
2230 cursor_pos : int, optional
2195 The position of the cursor on the input line.
2231 The position of the cursor on the input line.
2196
2232
2197 Returns
2233 Returns
2198 -------
2234 -------
2199 text : string
2235 text : string
2200 The actual text that was completed.
2236 The actual text that was completed.
2201 matches : list
2237 matches : list
2202 A sorted list with all possible completions.
2238 A sorted list with all possible completions.
2203
2239
2204 Notes
2240 Notes
2205 -----
2241 -----
2206 The optional arguments allow the completion to take more context into
2242 The optional arguments allow the completion to take more context into
2207 account, and are part of the low-level completion API.
2243 account, and are part of the low-level completion API.
2208
2244
2209 This is a wrapper around the completion mechanism, similar to what
2245 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
2246 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
2247 exposing it as a method, it can be used by other non-readline
2212 environments (such as GUIs) for text completion.
2248 environments (such as GUIs) for text completion.
2213
2249
2214 Examples
2250 Examples
2215 --------
2251 --------
2216 In [1]: x = 'hello'
2252 In [1]: x = 'hello'
2217
2253
2218 In [2]: _ip.complete('x.l')
2254 In [2]: _ip.complete('x.l')
2219 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2255 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2220 """
2256 """
2221
2257
2222 # Inject names into __builtin__ so we can complete on the added names.
2258 # Inject names into __builtin__ so we can complete on the added names.
2223 with self.builtin_trap:
2259 with self.builtin_trap:
2224 return self.Completer.complete(text, line, cursor_pos)
2260 return self.Completer.complete(text, line, cursor_pos)
2225
2261
2226 def set_custom_completer(self, completer, pos=0) -> None:
2262 def set_custom_completer(self, completer, pos=0) -> None:
2227 """Adds a new custom completer function.
2263 """Adds a new custom completer function.
2228
2264
2229 The position argument (defaults to 0) is the index in the completers
2265 The position argument (defaults to 0) is the index in the completers
2230 list where you want the completer to be inserted.
2266 list where you want the completer to be inserted.
2231
2267
2232 `completer` should have the following signature::
2268 `completer` should have the following signature::
2233
2269
2234 def completion(self: Completer, text: string) -> List[str]:
2270 def completion(self: Completer, text: string) -> List[str]:
2235 raise NotImplementedError
2271 raise NotImplementedError
2236
2272
2237 It will be bound to the current Completer instance and pass some text
2273 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.
2274 and return a list with current completions to suggest to the user.
2239 """
2275 """
2240
2276
2241 newcomp = types.MethodType(completer, self.Completer)
2277 newcomp = types.MethodType(completer, self.Completer)
2242 self.Completer.custom_matchers.insert(pos,newcomp)
2278 self.Completer.custom_matchers.insert(pos,newcomp)
2243
2279
2244 def set_completer_frame(self, frame=None):
2280 def set_completer_frame(self, frame=None):
2245 """Set the frame of the completer."""
2281 """Set the frame of the completer."""
2246 if frame:
2282 if frame:
2247 self.Completer.namespace = frame.f_locals
2283 self.Completer.namespace = frame.f_locals
2248 self.Completer.global_namespace = frame.f_globals
2284 self.Completer.global_namespace = frame.f_globals
2249 else:
2285 else:
2250 self.Completer.namespace = self.user_ns
2286 self.Completer.namespace = self.user_ns
2251 self.Completer.global_namespace = self.user_global_ns
2287 self.Completer.global_namespace = self.user_global_ns
2252
2288
2253 #-------------------------------------------------------------------------
2289 #-------------------------------------------------------------------------
2254 # Things related to magics
2290 # Things related to magics
2255 #-------------------------------------------------------------------------
2291 #-------------------------------------------------------------------------
2256
2292
2257 def init_magics(self):
2293 def init_magics(self):
2258 from IPython.core import magics as m
2294 from IPython.core import magics as m
2259 self.magics_manager = magic.MagicsManager(shell=self,
2295 self.magics_manager = magic.MagicsManager(shell=self,
2260 parent=self,
2296 parent=self,
2261 user_magics=m.UserMagics(self))
2297 user_magics=m.UserMagics(self))
2262 self.configurables.append(self.magics_manager)
2298 self.configurables.append(self.magics_manager)
2263
2299
2264 # Expose as public API from the magics manager
2300 # Expose as public API from the magics manager
2265 self.register_magics = self.magics_manager.register
2301 self.register_magics = self.magics_manager.register
2266
2302
2267 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2303 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2268 m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics,
2304 m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics,
2269 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2305 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2270 m.NamespaceMagics, m.OSMagics, m.PackagingMagics,
2306 m.NamespaceMagics, m.OSMagics, m.PackagingMagics,
2271 m.PylabMagics, m.ScriptMagics,
2307 m.PylabMagics, m.ScriptMagics,
2272 )
2308 )
2273 self.register_magics(m.AsyncMagics)
2309 self.register_magics(m.AsyncMagics)
2274
2310
2275 # Register Magic Aliases
2311 # Register Magic Aliases
2276 mman = self.magics_manager
2312 mman = self.magics_manager
2277 # FIXME: magic aliases should be defined by the Magics classes
2313 # FIXME: magic aliases should be defined by the Magics classes
2278 # or in MagicsManager, not here
2314 # or in MagicsManager, not here
2279 mman.register_alias('ed', 'edit')
2315 mman.register_alias('ed', 'edit')
2280 mman.register_alias('hist', 'history')
2316 mman.register_alias('hist', 'history')
2281 mman.register_alias('rep', 'recall')
2317 mman.register_alias('rep', 'recall')
2282 mman.register_alias('SVG', 'svg', 'cell')
2318 mman.register_alias('SVG', 'svg', 'cell')
2283 mman.register_alias('HTML', 'html', 'cell')
2319 mman.register_alias('HTML', 'html', 'cell')
2284 mman.register_alias('file', 'writefile', 'cell')
2320 mman.register_alias('file', 'writefile', 'cell')
2285
2321
2286 # FIXME: Move the color initialization to the DisplayHook, which
2322 # FIXME: Move the color initialization to the DisplayHook, which
2287 # should be split into a prompt manager and displayhook. We probably
2323 # should be split into a prompt manager and displayhook. We probably
2288 # even need a centralize colors management object.
2324 # even need a centralize colors management object.
2289 self.run_line_magic('colors', self.colors)
2325 self.run_line_magic('colors', self.colors)
2290
2326
2291 # Defined here so that it's included in the documentation
2327 # Defined here so that it's included in the documentation
2292 @functools.wraps(magic.MagicsManager.register_function)
2328 @functools.wraps(magic.MagicsManager.register_function)
2293 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2329 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2294 self.magics_manager.register_function(
2330 self.magics_manager.register_function(
2295 func, magic_kind=magic_kind, magic_name=magic_name
2331 func, magic_kind=magic_kind, magic_name=magic_name
2296 )
2332 )
2297
2333
2298 def _find_with_lazy_load(self, /, type_, magic_name: str):
2334 def _find_with_lazy_load(self, /, type_, magic_name: str):
2299 """
2335 """
2300 Try to find a magic potentially lazy-loading it.
2336 Try to find a magic potentially lazy-loading it.
2301
2337
2302 Parameters
2338 Parameters
2303 ----------
2339 ----------
2304
2340
2305 type_: "line"|"cell"
2341 type_: "line"|"cell"
2306 the type of magics we are trying to find/lazy load.
2342 the type of magics we are trying to find/lazy load.
2307 magic_name: str
2343 magic_name: str
2308 The name of the magic we are trying to find/lazy load
2344 The name of the magic we are trying to find/lazy load
2309
2345
2310
2346
2311 Note that this may have any side effects
2347 Note that this may have any side effects
2312 """
2348 """
2313 finder = {"line": self.find_line_magic, "cell": self.find_cell_magic}[type_]
2349 finder = {"line": self.find_line_magic, "cell": self.find_cell_magic}[type_]
2314 fn = finder(magic_name)
2350 fn = finder(magic_name)
2315 if fn is not None:
2351 if fn is not None:
2316 return fn
2352 return fn
2317 lazy = self.magics_manager.lazy_magics.get(magic_name)
2353 lazy = self.magics_manager.lazy_magics.get(magic_name)
2318 if lazy is None:
2354 if lazy is None:
2319 return None
2355 return None
2320
2356
2321 self.run_line_magic("load_ext", lazy)
2357 self.run_line_magic("load_ext", lazy)
2322 res = finder(magic_name)
2358 res = finder(magic_name)
2323 return res
2359 return res
2324
2360
2325 def run_line_magic(self, magic_name: str, line, _stack_depth=1):
2361 def run_line_magic(self, magic_name: str, line, _stack_depth=1):
2326 """Execute the given line magic.
2362 """Execute the given line magic.
2327
2363
2328 Parameters
2364 Parameters
2329 ----------
2365 ----------
2330 magic_name : str
2366 magic_name : str
2331 Name of the desired magic function, without '%' prefix.
2367 Name of the desired magic function, without '%' prefix.
2332 line : str
2368 line : str
2333 The rest of the input line as a single string.
2369 The rest of the input line as a single string.
2334 _stack_depth : int
2370 _stack_depth : int
2335 If run_line_magic() is called from magic() then _stack_depth=2.
2371 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()'
2372 This is added to ensure backward compatibility for use of 'get_ipython().magic()'
2337 """
2373 """
2338 fn = self._find_with_lazy_load("line", magic_name)
2374 fn = self._find_with_lazy_load("line", magic_name)
2339 if fn is None:
2375 if fn is None:
2340 lazy = self.magics_manager.lazy_magics.get(magic_name)
2376 lazy = self.magics_manager.lazy_magics.get(magic_name)
2341 if lazy:
2377 if lazy:
2342 self.run_line_magic("load_ext", lazy)
2378 self.run_line_magic("load_ext", lazy)
2343 fn = self.find_line_magic(magic_name)
2379 fn = self.find_line_magic(magic_name)
2344 if fn is None:
2380 if fn is None:
2345 cm = self.find_cell_magic(magic_name)
2381 cm = self.find_cell_magic(magic_name)
2346 etpl = "Line magic function `%%%s` not found%s."
2382 etpl = "Line magic function `%%%s` not found%s."
2347 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2383 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2348 'did you mean that instead?)' % magic_name )
2384 'did you mean that instead?)' % magic_name )
2349 raise UsageError(etpl % (magic_name, extra))
2385 raise UsageError(etpl % (magic_name, extra))
2350 else:
2386 else:
2351 # Note: this is the distance in the stack to the user's frame.
2387 # 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
2388 # This will need to be updated if the internal calling logic gets
2353 # refactored, or else we'll be expanding the wrong variables.
2389 # refactored, or else we'll be expanding the wrong variables.
2354
2390
2355 # Determine stack_depth depending on where run_line_magic() has been called
2391 # Determine stack_depth depending on where run_line_magic() has been called
2356 stack_depth = _stack_depth
2392 stack_depth = _stack_depth
2357 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2393 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2358 # magic has opted out of var_expand
2394 # magic has opted out of var_expand
2359 magic_arg_s = line
2395 magic_arg_s = line
2360 else:
2396 else:
2361 magic_arg_s = self.var_expand(line, stack_depth)
2397 magic_arg_s = self.var_expand(line, stack_depth)
2362 # Put magic args in a list so we can call with f(*a) syntax
2398 # Put magic args in a list so we can call with f(*a) syntax
2363 args = [magic_arg_s]
2399 args = [magic_arg_s]
2364 kwargs = {}
2400 kwargs = {}
2365 # Grab local namespace if we need it:
2401 # Grab local namespace if we need it:
2366 if getattr(fn, "needs_local_scope", False):
2402 if getattr(fn, "needs_local_scope", False):
2367 kwargs['local_ns'] = self.get_local_scope(stack_depth)
2403 kwargs['local_ns'] = self.get_local_scope(stack_depth)
2368 with self.builtin_trap:
2404 with self.builtin_trap:
2369 result = fn(*args, **kwargs)
2405 result = fn(*args, **kwargs)
2370
2406
2371 # The code below prevents the output from being displayed
2407 # The code below prevents the output from being displayed
2372 # when using magics with decodator @output_can_be_silenced
2408 # when using magics with decodator @output_can_be_silenced
2373 # when the last Python token in the expression is a ';'.
2409 # when the last Python token in the expression is a ';'.
2374 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
2410 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
2375 if DisplayHook.semicolon_at_end_of_expression(magic_arg_s):
2411 if DisplayHook.semicolon_at_end_of_expression(magic_arg_s):
2376 return None
2412 return None
2377
2413
2378 return result
2414 return result
2379
2415
2380 def get_local_scope(self, stack_depth):
2416 def get_local_scope(self, stack_depth):
2381 """Get local scope at given stack depth.
2417 """Get local scope at given stack depth.
2382
2418
2383 Parameters
2419 Parameters
2384 ----------
2420 ----------
2385 stack_depth : int
2421 stack_depth : int
2386 Depth relative to calling frame
2422 Depth relative to calling frame
2387 """
2423 """
2388 return sys._getframe(stack_depth + 1).f_locals
2424 return sys._getframe(stack_depth + 1).f_locals
2389
2425
2390 def run_cell_magic(self, magic_name, line, cell):
2426 def run_cell_magic(self, magic_name, line, cell):
2391 """Execute the given cell magic.
2427 """Execute the given cell magic.
2392
2428
2393 Parameters
2429 Parameters
2394 ----------
2430 ----------
2395 magic_name : str
2431 magic_name : str
2396 Name of the desired magic function, without '%' prefix.
2432 Name of the desired magic function, without '%' prefix.
2397 line : str
2433 line : str
2398 The rest of the first input line as a single string.
2434 The rest of the first input line as a single string.
2399 cell : str
2435 cell : str
2400 The body of the cell as a (possibly multiline) string.
2436 The body of the cell as a (possibly multiline) string.
2401 """
2437 """
2402 fn = self._find_with_lazy_load("cell", magic_name)
2438 fn = self._find_with_lazy_load("cell", magic_name)
2403 if fn is None:
2439 if fn is None:
2404 lm = self.find_line_magic(magic_name)
2440 lm = self.find_line_magic(magic_name)
2405 etpl = "Cell magic `%%{0}` not found{1}."
2441 etpl = "Cell magic `%%{0}` not found{1}."
2406 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2442 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2407 'did you mean that instead?)'.format(magic_name))
2443 'did you mean that instead?)'.format(magic_name))
2408 raise UsageError(etpl.format(magic_name, extra))
2444 raise UsageError(etpl.format(magic_name, extra))
2409 elif cell == '':
2445 elif cell == '':
2410 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2446 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:
2447 if self.find_line_magic(magic_name) is not None:
2412 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2448 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2413 raise UsageError(message)
2449 raise UsageError(message)
2414 else:
2450 else:
2415 # Note: this is the distance in the stack to the user's frame.
2451 # 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
2452 # This will need to be updated if the internal calling logic gets
2417 # refactored, or else we'll be expanding the wrong variables.
2453 # refactored, or else we'll be expanding the wrong variables.
2418 stack_depth = 2
2454 stack_depth = 2
2419 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2455 if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False):
2420 # magic has opted out of var_expand
2456 # magic has opted out of var_expand
2421 magic_arg_s = line
2457 magic_arg_s = line
2422 else:
2458 else:
2423 magic_arg_s = self.var_expand(line, stack_depth)
2459 magic_arg_s = self.var_expand(line, stack_depth)
2424 kwargs = {}
2460 kwargs = {}
2425 if getattr(fn, "needs_local_scope", False):
2461 if getattr(fn, "needs_local_scope", False):
2426 kwargs['local_ns'] = self.user_ns
2462 kwargs['local_ns'] = self.user_ns
2427
2463
2428 with self.builtin_trap:
2464 with self.builtin_trap:
2429 args = (magic_arg_s, cell)
2465 args = (magic_arg_s, cell)
2430 result = fn(*args, **kwargs)
2466 result = fn(*args, **kwargs)
2431
2467
2432 # The code below prevents the output from being displayed
2468 # The code below prevents the output from being displayed
2433 # when using magics with decodator @output_can_be_silenced
2469 # when using magics with decodator @output_can_be_silenced
2434 # when the last Python token in the expression is a ';'.
2470 # when the last Python token in the expression is a ';'.
2435 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
2471 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
2436 if DisplayHook.semicolon_at_end_of_expression(cell):
2472 if DisplayHook.semicolon_at_end_of_expression(cell):
2437 return None
2473 return None
2438
2474
2439 return result
2475 return result
2440
2476
2441 def find_line_magic(self, magic_name):
2477 def find_line_magic(self, magic_name):
2442 """Find and return a line magic by name.
2478 """Find and return a line magic by name.
2443
2479
2444 Returns None if the magic isn't found."""
2480 Returns None if the magic isn't found."""
2445 return self.magics_manager.magics['line'].get(magic_name)
2481 return self.magics_manager.magics['line'].get(magic_name)
2446
2482
2447 def find_cell_magic(self, magic_name):
2483 def find_cell_magic(self, magic_name):
2448 """Find and return a cell magic by name.
2484 """Find and return a cell magic by name.
2449
2485
2450 Returns None if the magic isn't found."""
2486 Returns None if the magic isn't found."""
2451 return self.magics_manager.magics['cell'].get(magic_name)
2487 return self.magics_manager.magics['cell'].get(magic_name)
2452
2488
2453 def find_magic(self, magic_name, magic_kind='line'):
2489 def find_magic(self, magic_name, magic_kind='line'):
2454 """Find and return a magic of the given type by name.
2490 """Find and return a magic of the given type by name.
2455
2491
2456 Returns None if the magic isn't found."""
2492 Returns None if the magic isn't found."""
2457 return self.magics_manager.magics[magic_kind].get(magic_name)
2493 return self.magics_manager.magics[magic_kind].get(magic_name)
2458
2494
2459 def magic(self, arg_s):
2495 def magic(self, arg_s):
2460 """
2496 """
2461 DEPRECATED
2497 DEPRECATED
2462
2498
2463 Deprecated since IPython 0.13 (warning added in
2499 Deprecated since IPython 0.13 (warning added in
2464 8.1), use run_line_magic(magic_name, parameter_s).
2500 8.1), use run_line_magic(magic_name, parameter_s).
2465
2501
2466 Call a magic function by name.
2502 Call a magic function by name.
2467
2503
2468 Input: a string containing the name of the magic function to call and
2504 Input: a string containing the name of the magic function to call and
2469 any additional arguments to be passed to the magic.
2505 any additional arguments to be passed to the magic.
2470
2506
2471 magic('name -opt foo bar') is equivalent to typing at the ipython
2507 magic('name -opt foo bar') is equivalent to typing at the ipython
2472 prompt:
2508 prompt:
2473
2509
2474 In[1]: %name -opt foo bar
2510 In[1]: %name -opt foo bar
2475
2511
2476 To call a magic without arguments, simply use magic('name').
2512 To call a magic without arguments, simply use magic('name').
2477
2513
2478 This provides a proper Python function to call IPython's magics in any
2514 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
2515 valid Python code you can type at the interpreter, including loops and
2480 compound statements.
2516 compound statements.
2481 """
2517 """
2482 warnings.warn(
2518 warnings.warn(
2483 "`magic(...)` is deprecated since IPython 0.13 (warning added in "
2519 "`magic(...)` is deprecated since IPython 0.13 (warning added in "
2484 "8.1), use run_line_magic(magic_name, parameter_s).",
2520 "8.1), use run_line_magic(magic_name, parameter_s).",
2485 DeprecationWarning,
2521 DeprecationWarning,
2486 stacklevel=2,
2522 stacklevel=2,
2487 )
2523 )
2488 # TODO: should we issue a loud deprecation warning here?
2524 # TODO: should we issue a loud deprecation warning here?
2489 magic_name, _, magic_arg_s = arg_s.partition(' ')
2525 magic_name, _, magic_arg_s = arg_s.partition(' ')
2490 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2526 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2491 return self.run_line_magic(magic_name, magic_arg_s, _stack_depth=2)
2527 return self.run_line_magic(magic_name, magic_arg_s, _stack_depth=2)
2492
2528
2493 #-------------------------------------------------------------------------
2529 #-------------------------------------------------------------------------
2494 # Things related to macros
2530 # Things related to macros
2495 #-------------------------------------------------------------------------
2531 #-------------------------------------------------------------------------
2496
2532
2497 def define_macro(self, name, themacro):
2533 def define_macro(self, name, themacro):
2498 """Define a new macro
2534 """Define a new macro
2499
2535
2500 Parameters
2536 Parameters
2501 ----------
2537 ----------
2502 name : str
2538 name : str
2503 The name of the macro.
2539 The name of the macro.
2504 themacro : str or Macro
2540 themacro : str or Macro
2505 The action to do upon invoking the macro. If a string, a new
2541 The action to do upon invoking the macro. If a string, a new
2506 Macro object is created by passing the string to it.
2542 Macro object is created by passing the string to it.
2507 """
2543 """
2508
2544
2509 from IPython.core import macro
2545 from IPython.core import macro
2510
2546
2511 if isinstance(themacro, str):
2547 if isinstance(themacro, str):
2512 themacro = macro.Macro(themacro)
2548 themacro = macro.Macro(themacro)
2513 if not isinstance(themacro, macro.Macro):
2549 if not isinstance(themacro, macro.Macro):
2514 raise ValueError('A macro must be a string or a Macro instance.')
2550 raise ValueError('A macro must be a string or a Macro instance.')
2515 self.user_ns[name] = themacro
2551 self.user_ns[name] = themacro
2516
2552
2517 #-------------------------------------------------------------------------
2553 #-------------------------------------------------------------------------
2518 # Things related to the running of system commands
2554 # Things related to the running of system commands
2519 #-------------------------------------------------------------------------
2555 #-------------------------------------------------------------------------
2520
2556
2521 def system_piped(self, cmd):
2557 def system_piped(self, cmd):
2522 """Call the given cmd in a subprocess, piping stdout/err
2558 """Call the given cmd in a subprocess, piping stdout/err
2523
2559
2524 Parameters
2560 Parameters
2525 ----------
2561 ----------
2526 cmd : str
2562 cmd : str
2527 Command to execute (can not end in '&', as background processes are
2563 Command to execute (can not end in '&', as background processes are
2528 not supported. Should not be a command that expects input
2564 not supported. Should not be a command that expects input
2529 other than simple text.
2565 other than simple text.
2530 """
2566 """
2531 if cmd.rstrip().endswith('&'):
2567 if cmd.rstrip().endswith('&'):
2532 # this is *far* from a rigorous test
2568 # this is *far* from a rigorous test
2533 # We do not support backgrounding processes because we either use
2569 # We do not support backgrounding processes because we either use
2534 # pexpect or pipes to read from. Users can always just call
2570 # pexpect or pipes to read from. Users can always just call
2535 # os.system() or use ip.system=ip.system_raw
2571 # os.system() or use ip.system=ip.system_raw
2536 # if they really want a background process.
2572 # if they really want a background process.
2537 raise OSError("Background processes not supported.")
2573 raise OSError("Background processes not supported.")
2538
2574
2539 # we explicitly do NOT return the subprocess status code, because
2575 # we explicitly do NOT return the subprocess status code, because
2540 # a non-None value would trigger :func:`sys.displayhook` calls.
2576 # a non-None value would trigger :func:`sys.displayhook` calls.
2541 # Instead, we store the exit_code in user_ns.
2577 # Instead, we store the exit_code in user_ns.
2542 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2578 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2543
2579
2544 def system_raw(self, cmd):
2580 def system_raw(self, cmd):
2545 """Call the given cmd in a subprocess using os.system on Windows or
2581 """Call the given cmd in a subprocess using os.system on Windows or
2546 subprocess.call using the system shell on other platforms.
2582 subprocess.call using the system shell on other platforms.
2547
2583
2548 Parameters
2584 Parameters
2549 ----------
2585 ----------
2550 cmd : str
2586 cmd : str
2551 Command to execute.
2587 Command to execute.
2552 """
2588 """
2553 cmd = self.var_expand(cmd, depth=1)
2589 cmd = self.var_expand(cmd, depth=1)
2554 # warn if there is an IPython magic alternative.
2590 # warn if there is an IPython magic alternative.
2555 main_cmd = cmd.split()[0]
2591 main_cmd = cmd.split()[0]
2556 has_magic_alternatives = ("pip", "conda", "cd")
2592 has_magic_alternatives = ("pip", "conda", "cd")
2557
2593
2558 if main_cmd in has_magic_alternatives:
2594 if main_cmd in has_magic_alternatives:
2559 warnings.warn(
2595 warnings.warn(
2560 (
2596 (
2561 "You executed the system command !{0} which may not work "
2597 "You executed the system command !{0} which may not work "
2562 "as expected. Try the IPython magic %{0} instead."
2598 "as expected. Try the IPython magic %{0} instead."
2563 ).format(main_cmd)
2599 ).format(main_cmd)
2564 )
2600 )
2565
2601
2566 # protect os.system from UNC paths on Windows, which it can't handle:
2602 # protect os.system from UNC paths on Windows, which it can't handle:
2567 if sys.platform == 'win32':
2603 if sys.platform == 'win32':
2568 from IPython.utils._process_win32 import AvoidUNCPath
2604 from IPython.utils._process_win32 import AvoidUNCPath
2569 with AvoidUNCPath() as path:
2605 with AvoidUNCPath() as path:
2570 if path is not None:
2606 if path is not None:
2571 cmd = '"pushd %s &&"%s' % (path, cmd)
2607 cmd = '"pushd %s &&"%s' % (path, cmd)
2572 try:
2608 try:
2573 ec = os.system(cmd)
2609 ec = os.system(cmd)
2574 except KeyboardInterrupt:
2610 except KeyboardInterrupt:
2575 print('\n' + self.get_exception_only(), file=sys.stderr)
2611 print('\n' + self.get_exception_only(), file=sys.stderr)
2576 ec = -2
2612 ec = -2
2577 else:
2613 else:
2578 # For posix the result of the subprocess.call() below is an exit
2614 # For posix the result of the subprocess.call() below is an exit
2579 # code, which by convention is zero for success, positive for
2615 # code, which by convention is zero for success, positive for
2580 # program failure. Exit codes above 128 are reserved for signals,
2616 # program failure. Exit codes above 128 are reserved for signals,
2581 # and the formula for converting a signal to an exit code is usually
2617 # and the formula for converting a signal to an exit code is usually
2582 # signal_number+128. To more easily differentiate between exit
2618 # signal_number+128. To more easily differentiate between exit
2583 # codes and signals, ipython uses negative numbers. For instance
2619 # codes and signals, ipython uses negative numbers. For instance
2584 # since control-c is signal 2 but exit code 130, ipython's
2620 # since control-c is signal 2 but exit code 130, ipython's
2585 # _exit_code variable will read -2. Note that some shells like
2621 # _exit_code variable will read -2. Note that some shells like
2586 # csh and fish don't follow sh/bash conventions for exit codes.
2622 # csh and fish don't follow sh/bash conventions for exit codes.
2587 executable = os.environ.get('SHELL', None)
2623 executable = os.environ.get('SHELL', None)
2588 try:
2624 try:
2589 # Use env shell instead of default /bin/sh
2625 # Use env shell instead of default /bin/sh
2590 ec = subprocess.call(cmd, shell=True, executable=executable)
2626 ec = subprocess.call(cmd, shell=True, executable=executable)
2591 except KeyboardInterrupt:
2627 except KeyboardInterrupt:
2592 # intercept control-C; a long traceback is not useful here
2628 # intercept control-C; a long traceback is not useful here
2593 print('\n' + self.get_exception_only(), file=sys.stderr)
2629 print('\n' + self.get_exception_only(), file=sys.stderr)
2594 ec = 130
2630 ec = 130
2595 if ec > 128:
2631 if ec > 128:
2596 ec = -(ec - 128)
2632 ec = -(ec - 128)
2597
2633
2598 # We explicitly do NOT return the subprocess status code, because
2634 # We explicitly do NOT return the subprocess status code, because
2599 # a non-None value would trigger :func:`sys.displayhook` calls.
2635 # a non-None value would trigger :func:`sys.displayhook` calls.
2600 # Instead, we store the exit_code in user_ns. Note the semantics
2636 # Instead, we store the exit_code in user_ns. Note the semantics
2601 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2637 # of _exit_code: for control-c, _exit_code == -signal.SIGNIT,
2602 # but raising SystemExit(_exit_code) will give status 254!
2638 # but raising SystemExit(_exit_code) will give status 254!
2603 self.user_ns['_exit_code'] = ec
2639 self.user_ns['_exit_code'] = ec
2604
2640
2605 # use piped system by default, because it is better behaved
2641 # use piped system by default, because it is better behaved
2606 system = system_piped
2642 system = system_piped
2607
2643
2608 def getoutput(self, cmd, split=True, depth=0):
2644 def getoutput(self, cmd, split=True, depth=0):
2609 """Get output (possibly including stderr) from a subprocess.
2645 """Get output (possibly including stderr) from a subprocess.
2610
2646
2611 Parameters
2647 Parameters
2612 ----------
2648 ----------
2613 cmd : str
2649 cmd : str
2614 Command to execute (can not end in '&', as background processes are
2650 Command to execute (can not end in '&', as background processes are
2615 not supported.
2651 not supported.
2616 split : bool, optional
2652 split : bool, optional
2617 If True, split the output into an IPython SList. Otherwise, an
2653 If True, split the output into an IPython SList. Otherwise, an
2618 IPython LSString is returned. These are objects similar to normal
2654 IPython LSString is returned. These are objects similar to normal
2619 lists and strings, with a few convenience attributes for easier
2655 lists and strings, with a few convenience attributes for easier
2620 manipulation of line-based output. You can use '?' on them for
2656 manipulation of line-based output. You can use '?' on them for
2621 details.
2657 details.
2622 depth : int, optional
2658 depth : int, optional
2623 How many frames above the caller are the local variables which should
2659 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
2660 be expanded in the command string? The default (0) assumes that the
2625 expansion variables are in the stack frame calling this function.
2661 expansion variables are in the stack frame calling this function.
2626 """
2662 """
2627 if cmd.rstrip().endswith('&'):
2663 if cmd.rstrip().endswith('&'):
2628 # this is *far* from a rigorous test
2664 # this is *far* from a rigorous test
2629 raise OSError("Background processes not supported.")
2665 raise OSError("Background processes not supported.")
2630 out = getoutput(self.var_expand(cmd, depth=depth+1))
2666 out = getoutput(self.var_expand(cmd, depth=depth+1))
2631 if split:
2667 if split:
2632 out = SList(out.splitlines())
2668 out = SList(out.splitlines())
2633 else:
2669 else:
2634 out = LSString(out)
2670 out = LSString(out)
2635 return out
2671 return out
2636
2672
2637 #-------------------------------------------------------------------------
2673 #-------------------------------------------------------------------------
2638 # Things related to aliases
2674 # Things related to aliases
2639 #-------------------------------------------------------------------------
2675 #-------------------------------------------------------------------------
2640
2676
2641 def init_alias(self):
2677 def init_alias(self):
2642 self.alias_manager = AliasManager(shell=self, parent=self)
2678 self.alias_manager = AliasManager(shell=self, parent=self)
2643 self.configurables.append(self.alias_manager)
2679 self.configurables.append(self.alias_manager)
2644
2680
2645 #-------------------------------------------------------------------------
2681 #-------------------------------------------------------------------------
2646 # Things related to extensions
2682 # Things related to extensions
2647 #-------------------------------------------------------------------------
2683 #-------------------------------------------------------------------------
2648
2684
2649 def init_extension_manager(self):
2685 def init_extension_manager(self):
2650 self.extension_manager = ExtensionManager(shell=self, parent=self)
2686 self.extension_manager = ExtensionManager(shell=self, parent=self)
2651 self.configurables.append(self.extension_manager)
2687 self.configurables.append(self.extension_manager)
2652
2688
2653 #-------------------------------------------------------------------------
2689 #-------------------------------------------------------------------------
2654 # Things related to payloads
2690 # Things related to payloads
2655 #-------------------------------------------------------------------------
2691 #-------------------------------------------------------------------------
2656
2692
2657 def init_payload(self):
2693 def init_payload(self):
2658 self.payload_manager = PayloadManager(parent=self)
2694 self.payload_manager = PayloadManager(parent=self)
2659 self.configurables.append(self.payload_manager)
2695 self.configurables.append(self.payload_manager)
2660
2696
2661 #-------------------------------------------------------------------------
2697 #-------------------------------------------------------------------------
2662 # Things related to the prefilter
2698 # Things related to the prefilter
2663 #-------------------------------------------------------------------------
2699 #-------------------------------------------------------------------------
2664
2700
2665 def init_prefilter(self):
2701 def init_prefilter(self):
2666 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2702 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2667 self.configurables.append(self.prefilter_manager)
2703 self.configurables.append(self.prefilter_manager)
2668 # Ultimately this will be refactored in the new interpreter code, but
2704 # Ultimately this will be refactored in the new interpreter code, but
2669 # for now, we should expose the main prefilter method (there's legacy
2705 # for now, we should expose the main prefilter method (there's legacy
2670 # code out there that may rely on this).
2706 # code out there that may rely on this).
2671 self.prefilter = self.prefilter_manager.prefilter_lines
2707 self.prefilter = self.prefilter_manager.prefilter_lines
2672
2708
2673 def auto_rewrite_input(self, cmd):
2709 def auto_rewrite_input(self, cmd):
2674 """Print to the screen the rewritten form of the user's command.
2710 """Print to the screen the rewritten form of the user's command.
2675
2711
2676 This shows visual feedback by rewriting input lines that cause
2712 This shows visual feedback by rewriting input lines that cause
2677 automatic calling to kick in, like::
2713 automatic calling to kick in, like::
2678
2714
2679 /f x
2715 /f x
2680
2716
2681 into::
2717 into::
2682
2718
2683 ------> f(x)
2719 ------> f(x)
2684
2720
2685 after the user's input prompt. This helps the user understand that the
2721 after the user's input prompt. This helps the user understand that the
2686 input line was transformed automatically by IPython.
2722 input line was transformed automatically by IPython.
2687 """
2723 """
2688 if not self.show_rewritten_input:
2724 if not self.show_rewritten_input:
2689 return
2725 return
2690
2726
2691 # This is overridden in TerminalInteractiveShell to use fancy prompts
2727 # This is overridden in TerminalInteractiveShell to use fancy prompts
2692 print("------> " + cmd)
2728 print("------> " + cmd)
2693
2729
2694 #-------------------------------------------------------------------------
2730 #-------------------------------------------------------------------------
2695 # Things related to extracting values/expressions from kernel and user_ns
2731 # Things related to extracting values/expressions from kernel and user_ns
2696 #-------------------------------------------------------------------------
2732 #-------------------------------------------------------------------------
2697
2733
2698 def _user_obj_error(self):
2734 def _user_obj_error(self):
2699 """return simple exception dict
2735 """return simple exception dict
2700
2736
2701 for use in user_expressions
2737 for use in user_expressions
2702 """
2738 """
2703
2739
2704 etype, evalue, tb = self._get_exc_info()
2740 etype, evalue, tb = self._get_exc_info()
2705 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2741 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2706
2742
2707 exc_info = {
2743 exc_info = {
2708 "status": "error",
2744 "status": "error",
2709 "traceback": stb,
2745 "traceback": stb,
2710 "ename": etype.__name__,
2746 "ename": etype.__name__,
2711 "evalue": py3compat.safe_unicode(evalue),
2747 "evalue": py3compat.safe_unicode(evalue),
2712 }
2748 }
2713
2749
2714 return exc_info
2750 return exc_info
2715
2751
2716 def _format_user_obj(self, obj):
2752 def _format_user_obj(self, obj):
2717 """format a user object to display dict
2753 """format a user object to display dict
2718
2754
2719 for use in user_expressions
2755 for use in user_expressions
2720 """
2756 """
2721
2757
2722 data, md = self.display_formatter.format(obj)
2758 data, md = self.display_formatter.format(obj)
2723 value = {
2759 value = {
2724 'status' : 'ok',
2760 'status' : 'ok',
2725 'data' : data,
2761 'data' : data,
2726 'metadata' : md,
2762 'metadata' : md,
2727 }
2763 }
2728 return value
2764 return value
2729
2765
2730 def user_expressions(self, expressions):
2766 def user_expressions(self, expressions):
2731 """Evaluate a dict of expressions in the user's namespace.
2767 """Evaluate a dict of expressions in the user's namespace.
2732
2768
2733 Parameters
2769 Parameters
2734 ----------
2770 ----------
2735 expressions : dict
2771 expressions : dict
2736 A dict with string keys and string values. The expression values
2772 A dict with string keys and string values. The expression values
2737 should be valid Python expressions, each of which will be evaluated
2773 should be valid Python expressions, each of which will be evaluated
2738 in the user namespace.
2774 in the user namespace.
2739
2775
2740 Returns
2776 Returns
2741 -------
2777 -------
2742 A dict, keyed like the input expressions dict, with the rich mime-typed
2778 A dict, keyed like the input expressions dict, with the rich mime-typed
2743 display_data of each value.
2779 display_data of each value.
2744 """
2780 """
2745 out = {}
2781 out = {}
2746 user_ns = self.user_ns
2782 user_ns = self.user_ns
2747 global_ns = self.user_global_ns
2783 global_ns = self.user_global_ns
2748
2784
2749 for key, expr in expressions.items():
2785 for key, expr in expressions.items():
2750 try:
2786 try:
2751 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2787 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2752 except:
2788 except:
2753 value = self._user_obj_error()
2789 value = self._user_obj_error()
2754 out[key] = value
2790 out[key] = value
2755 return out
2791 return out
2756
2792
2757 #-------------------------------------------------------------------------
2793 #-------------------------------------------------------------------------
2758 # Things related to the running of code
2794 # Things related to the running of code
2759 #-------------------------------------------------------------------------
2795 #-------------------------------------------------------------------------
2760
2796
2761 def ex(self, cmd):
2797 def ex(self, cmd):
2762 """Execute a normal python statement in user namespace."""
2798 """Execute a normal python statement in user namespace."""
2763 with self.builtin_trap:
2799 with self.builtin_trap:
2764 exec(cmd, self.user_global_ns, self.user_ns)
2800 exec(cmd, self.user_global_ns, self.user_ns)
2765
2801
2766 def ev(self, expr):
2802 def ev(self, expr):
2767 """Evaluate python expression expr in user namespace.
2803 """Evaluate python expression expr in user namespace.
2768
2804
2769 Returns the result of evaluation
2805 Returns the result of evaluation
2770 """
2806 """
2771 with self.builtin_trap:
2807 with self.builtin_trap:
2772 return eval(expr, self.user_global_ns, self.user_ns)
2808 return eval(expr, self.user_global_ns, self.user_ns)
2773
2809
2774 def safe_execfile(self, fname, *where, exit_ignore=False, raise_exceptions=False, shell_futures=False):
2810 def safe_execfile(self, fname, *where, exit_ignore=False, raise_exceptions=False, shell_futures=False):
2775 """A safe version of the builtin execfile().
2811 """A safe version of the builtin execfile().
2776
2812
2777 This version will never throw an exception, but instead print
2813 This version will never throw an exception, but instead print
2778 helpful error messages to the screen. This only works on pure
2814 helpful error messages to the screen. This only works on pure
2779 Python files with the .py extension.
2815 Python files with the .py extension.
2780
2816
2781 Parameters
2817 Parameters
2782 ----------
2818 ----------
2783 fname : string
2819 fname : string
2784 The name of the file to be executed.
2820 The name of the file to be executed.
2785 *where : tuple
2821 *where : tuple
2786 One or two namespaces, passed to execfile() as (globals,locals).
2822 One or two namespaces, passed to execfile() as (globals,locals).
2787 If only one is given, it is passed as both.
2823 If only one is given, it is passed as both.
2788 exit_ignore : bool (False)
2824 exit_ignore : bool (False)
2789 If True, then silence SystemExit for non-zero status (it is always
2825 If True, then silence SystemExit for non-zero status (it is always
2790 silenced for zero status, as it is so common).
2826 silenced for zero status, as it is so common).
2791 raise_exceptions : bool (False)
2827 raise_exceptions : bool (False)
2792 If True raise exceptions everywhere. Meant for testing.
2828 If True raise exceptions everywhere. Meant for testing.
2793 shell_futures : bool (False)
2829 shell_futures : bool (False)
2794 If True, the code will share future statements with the interactive
2830 If True, the code will share future statements with the interactive
2795 shell. It will both be affected by previous __future__ imports, and
2831 shell. It will both be affected by previous __future__ imports, and
2796 any __future__ imports in the code will affect the shell. If False,
2832 any __future__ imports in the code will affect the shell. If False,
2797 __future__ imports are not shared in either direction.
2833 __future__ imports are not shared in either direction.
2798
2834
2799 """
2835 """
2800 fname = Path(fname).expanduser().resolve()
2836 fname = Path(fname).expanduser().resolve()
2801
2837
2802 # Make sure we can open the file
2838 # Make sure we can open the file
2803 try:
2839 try:
2804 with fname.open("rb"):
2840 with fname.open("rb"):
2805 pass
2841 pass
2806 except:
2842 except:
2807 warn('Could not open file <%s> for safe execution.' % fname)
2843 warn('Could not open file <%s> for safe execution.' % fname)
2808 return
2844 return
2809
2845
2810 # Find things also in current directory. This is needed to mimic the
2846 # Find things also in current directory. This is needed to mimic the
2811 # behavior of running a script from the system command line, where
2847 # behavior of running a script from the system command line, where
2812 # Python inserts the script's directory into sys.path
2848 # Python inserts the script's directory into sys.path
2813 dname = str(fname.parent)
2849 dname = str(fname.parent)
2814
2850
2815 with prepended_to_syspath(dname), self.builtin_trap:
2851 with prepended_to_syspath(dname), self.builtin_trap:
2816 try:
2852 try:
2817 glob, loc = (where + (None, ))[:2]
2853 glob, loc = (where + (None, ))[:2]
2818 py3compat.execfile(
2854 py3compat.execfile(
2819 fname, glob, loc,
2855 fname, glob, loc,
2820 self.compile if shell_futures else None)
2856 self.compile if shell_futures else None)
2821 except SystemExit as status:
2857 except SystemExit as status:
2822 # If the call was made with 0 or None exit status (sys.exit(0)
2858 # 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
2859 # or sys.exit() ), don't bother showing a traceback, as both of
2824 # these are considered normal by the OS:
2860 # these are considered normal by the OS:
2825 # > python -c'import sys;sys.exit(0)'; echo $?
2861 # > python -c'import sys;sys.exit(0)'; echo $?
2826 # 0
2862 # 0
2827 # > python -c'import sys;sys.exit()'; echo $?
2863 # > python -c'import sys;sys.exit()'; echo $?
2828 # 0
2864 # 0
2829 # For other exit status, we show the exception unless
2865 # For other exit status, we show the exception unless
2830 # explicitly silenced, but only in short form.
2866 # explicitly silenced, but only in short form.
2831 if status.code:
2867 if status.code:
2832 if raise_exceptions:
2868 if raise_exceptions:
2833 raise
2869 raise
2834 if not exit_ignore:
2870 if not exit_ignore:
2835 self.showtraceback(exception_only=True)
2871 self.showtraceback(exception_only=True)
2836 except:
2872 except:
2837 if raise_exceptions:
2873 if raise_exceptions:
2838 raise
2874 raise
2839 # tb offset is 2 because we wrap execfile
2875 # tb offset is 2 because we wrap execfile
2840 self.showtraceback(tb_offset=2)
2876 self.showtraceback(tb_offset=2)
2841
2877
2842 def safe_execfile_ipy(self, fname, shell_futures=False, raise_exceptions=False):
2878 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.
2879 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2844
2880
2845 Parameters
2881 Parameters
2846 ----------
2882 ----------
2847 fname : str
2883 fname : str
2848 The name of the file to execute. The filename must have a
2884 The name of the file to execute. The filename must have a
2849 .ipy or .ipynb extension.
2885 .ipy or .ipynb extension.
2850 shell_futures : bool (False)
2886 shell_futures : bool (False)
2851 If True, the code will share future statements with the interactive
2887 If True, the code will share future statements with the interactive
2852 shell. It will both be affected by previous __future__ imports, and
2888 shell. It will both be affected by previous __future__ imports, and
2853 any __future__ imports in the code will affect the shell. If False,
2889 any __future__ imports in the code will affect the shell. If False,
2854 __future__ imports are not shared in either direction.
2890 __future__ imports are not shared in either direction.
2855 raise_exceptions : bool (False)
2891 raise_exceptions : bool (False)
2856 If True raise exceptions everywhere. Meant for testing.
2892 If True raise exceptions everywhere. Meant for testing.
2857 """
2893 """
2858 fname = Path(fname).expanduser().resolve()
2894 fname = Path(fname).expanduser().resolve()
2859
2895
2860 # Make sure we can open the file
2896 # Make sure we can open the file
2861 try:
2897 try:
2862 with fname.open("rb"):
2898 with fname.open("rb"):
2863 pass
2899 pass
2864 except:
2900 except:
2865 warn('Could not open file <%s> for safe execution.' % fname)
2901 warn('Could not open file <%s> for safe execution.' % fname)
2866 return
2902 return
2867
2903
2868 # Find things also in current directory. This is needed to mimic the
2904 # Find things also in current directory. This is needed to mimic the
2869 # behavior of running a script from the system command line, where
2905 # behavior of running a script from the system command line, where
2870 # Python inserts the script's directory into sys.path
2906 # Python inserts the script's directory into sys.path
2871 dname = str(fname.parent)
2907 dname = str(fname.parent)
2872
2908
2873 def get_cells():
2909 def get_cells():
2874 """generator for sequence of code blocks to run"""
2910 """generator for sequence of code blocks to run"""
2875 if fname.suffix == ".ipynb":
2911 if fname.suffix == ".ipynb":
2876 from nbformat import read
2912 from nbformat import read
2877 nb = read(fname, as_version=4)
2913 nb = read(fname, as_version=4)
2878 if not nb.cells:
2914 if not nb.cells:
2879 return
2915 return
2880 for cell in nb.cells:
2916 for cell in nb.cells:
2881 if cell.cell_type == 'code':
2917 if cell.cell_type == 'code':
2882 yield cell.source
2918 yield cell.source
2883 else:
2919 else:
2884 yield fname.read_text(encoding="utf-8")
2920 yield fname.read_text(encoding="utf-8")
2885
2921
2886 with prepended_to_syspath(dname):
2922 with prepended_to_syspath(dname):
2887 try:
2923 try:
2888 for cell in get_cells():
2924 for cell in get_cells():
2889 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2925 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2890 if raise_exceptions:
2926 if raise_exceptions:
2891 result.raise_error()
2927 result.raise_error()
2892 elif not result.success:
2928 elif not result.success:
2893 break
2929 break
2894 except:
2930 except:
2895 if raise_exceptions:
2931 if raise_exceptions:
2896 raise
2932 raise
2897 self.showtraceback()
2933 self.showtraceback()
2898 warn('Unknown failure executing file: <%s>' % fname)
2934 warn('Unknown failure executing file: <%s>' % fname)
2899
2935
2900 def safe_run_module(self, mod_name, where):
2936 def safe_run_module(self, mod_name, where):
2901 """A safe version of runpy.run_module().
2937 """A safe version of runpy.run_module().
2902
2938
2903 This version will never throw an exception, but instead print
2939 This version will never throw an exception, but instead print
2904 helpful error messages to the screen.
2940 helpful error messages to the screen.
2905
2941
2906 `SystemExit` exceptions with status code 0 or None are ignored.
2942 `SystemExit` exceptions with status code 0 or None are ignored.
2907
2943
2908 Parameters
2944 Parameters
2909 ----------
2945 ----------
2910 mod_name : string
2946 mod_name : string
2911 The name of the module to be executed.
2947 The name of the module to be executed.
2912 where : dict
2948 where : dict
2913 The globals namespace.
2949 The globals namespace.
2914 """
2950 """
2915 try:
2951 try:
2916 try:
2952 try:
2917 where.update(
2953 where.update(
2918 runpy.run_module(str(mod_name), run_name="__main__",
2954 runpy.run_module(str(mod_name), run_name="__main__",
2919 alter_sys=True)
2955 alter_sys=True)
2920 )
2956 )
2921 except SystemExit as status:
2957 except SystemExit as status:
2922 if status.code:
2958 if status.code:
2923 raise
2959 raise
2924 except:
2960 except:
2925 self.showtraceback()
2961 self.showtraceback()
2926 warn('Unknown failure executing module: <%s>' % mod_name)
2962 warn('Unknown failure executing module: <%s>' % mod_name)
2927
2963
2928 def run_cell(
2964 def run_cell(
2929 self,
2965 self,
2930 raw_cell,
2966 raw_cell,
2931 store_history=False,
2967 store_history=False,
2932 silent=False,
2968 silent=False,
2933 shell_futures=True,
2969 shell_futures=True,
2934 cell_id=None,
2970 cell_id=None,
2935 ):
2971 ):
2936 """Run a complete IPython cell.
2972 """Run a complete IPython cell.
2937
2973
2938 Parameters
2974 Parameters
2939 ----------
2975 ----------
2940 raw_cell : str
2976 raw_cell : str
2941 The code (including IPython code such as %magic functions) to run.
2977 The code (including IPython code such as %magic functions) to run.
2942 store_history : bool
2978 store_history : bool
2943 If True, the raw and translated cell will be stored in IPython's
2979 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
2980 history. For user code calling back into IPython's machinery, this
2945 should be set to False.
2981 should be set to False.
2946 silent : bool
2982 silent : bool
2947 If True, avoid side-effects, such as implicit displayhooks and
2983 If True, avoid side-effects, such as implicit displayhooks and
2948 and logging. silent=True forces store_history=False.
2984 and logging. silent=True forces store_history=False.
2949 shell_futures : bool
2985 shell_futures : bool
2950 If True, the code will share future statements with the interactive
2986 If True, the code will share future statements with the interactive
2951 shell. It will both be affected by previous __future__ imports, and
2987 shell. It will both be affected by previous __future__ imports, and
2952 any __future__ imports in the code will affect the shell. If False,
2988 any __future__ imports in the code will affect the shell. If False,
2953 __future__ imports are not shared in either direction.
2989 __future__ imports are not shared in either direction.
2954
2990
2955 Returns
2991 Returns
2956 -------
2992 -------
2957 result : :class:`ExecutionResult`
2993 result : :class:`ExecutionResult`
2958 """
2994 """
2959 result = None
2995 result = None
2960 try:
2996 try:
2961 result = self._run_cell(
2997 result = self._run_cell(
2962 raw_cell, store_history, silent, shell_futures, cell_id
2998 raw_cell, store_history, silent, shell_futures, cell_id
2963 )
2999 )
2964 finally:
3000 finally:
2965 self.events.trigger('post_execute')
3001 self.events.trigger('post_execute')
2966 if not silent:
3002 if not silent:
2967 self.events.trigger('post_run_cell', result)
3003 self.events.trigger('post_run_cell', result)
2968 return result
3004 return result
2969
3005
2970 def _run_cell(
3006 def _run_cell(
2971 self,
3007 self,
2972 raw_cell: str,
3008 raw_cell: str,
2973 store_history: bool,
3009 store_history: bool,
2974 silent: bool,
3010 silent: bool,
2975 shell_futures: bool,
3011 shell_futures: bool,
2976 cell_id: str,
3012 cell_id: str,
2977 ) -> ExecutionResult:
3013 ) -> ExecutionResult:
2978 """Internal method to run a complete IPython cell."""
3014 """Internal method to run a complete IPython cell."""
2979
3015
2980 # we need to avoid calling self.transform_cell multiple time on the same thing
3016 # we need to avoid calling self.transform_cell multiple time on the same thing
2981 # so we need to store some results:
3017 # so we need to store some results:
2982 preprocessing_exc_tuple = None
3018 preprocessing_exc_tuple = None
2983 try:
3019 try:
2984 transformed_cell = self.transform_cell(raw_cell)
3020 transformed_cell = self.transform_cell(raw_cell)
2985 except Exception:
3021 except Exception:
2986 transformed_cell = raw_cell
3022 transformed_cell = raw_cell
2987 preprocessing_exc_tuple = sys.exc_info()
3023 preprocessing_exc_tuple = sys.exc_info()
2988
3024
2989 assert transformed_cell is not None
3025 assert transformed_cell is not None
2990 coro = self.run_cell_async(
3026 coro = self.run_cell_async(
2991 raw_cell,
3027 raw_cell,
2992 store_history=store_history,
3028 store_history=store_history,
2993 silent=silent,
3029 silent=silent,
2994 shell_futures=shell_futures,
3030 shell_futures=shell_futures,
2995 transformed_cell=transformed_cell,
3031 transformed_cell=transformed_cell,
2996 preprocessing_exc_tuple=preprocessing_exc_tuple,
3032 preprocessing_exc_tuple=preprocessing_exc_tuple,
2997 cell_id=cell_id,
3033 cell_id=cell_id,
2998 )
3034 )
2999
3035
3000 # run_cell_async is async, but may not actually need an eventloop.
3036 # 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
3037 # 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
3038 # so that code can invoke eventloops (for example via the %run , and
3003 # `%paste` magic.
3039 # `%paste` magic.
3004 if self.trio_runner:
3040 if self.trio_runner:
3005 runner = self.trio_runner
3041 runner = self.trio_runner
3006 elif self.should_run_async(
3042 elif self.should_run_async(
3007 raw_cell,
3043 raw_cell,
3008 transformed_cell=transformed_cell,
3044 transformed_cell=transformed_cell,
3009 preprocessing_exc_tuple=preprocessing_exc_tuple,
3045 preprocessing_exc_tuple=preprocessing_exc_tuple,
3010 ):
3046 ):
3011 runner = self.loop_runner
3047 runner = self.loop_runner
3012 else:
3048 else:
3013 runner = _pseudo_sync_runner
3049 runner = _pseudo_sync_runner
3014
3050
3015 try:
3051 try:
3016 result = runner(coro)
3052 result = runner(coro)
3017 except BaseException as e:
3053 except BaseException as e:
3018 info = ExecutionInfo(
3054 info = ExecutionInfo(
3019 raw_cell, store_history, silent, shell_futures, cell_id
3055 raw_cell, store_history, silent, shell_futures, cell_id
3020 )
3056 )
3021 result = ExecutionResult(info)
3057 result = ExecutionResult(info)
3022 result.error_in_exec = e
3058 result.error_in_exec = e
3023 self.showtraceback(running_compiled_code=True)
3059 self.showtraceback(running_compiled_code=True)
3024 finally:
3060 finally:
3025 return result
3061 return result
3026
3062
3027 def should_run_async(
3063 def should_run_async(
3028 self, raw_cell: str, *, transformed_cell=None, preprocessing_exc_tuple=None
3064 self, raw_cell: str, *, transformed_cell=None, preprocessing_exc_tuple=None
3029 ) -> bool:
3065 ) -> bool:
3030 """Return whether a cell should be run asynchronously via a coroutine runner
3066 """Return whether a cell should be run asynchronously via a coroutine runner
3031
3067
3032 Parameters
3068 Parameters
3033 ----------
3069 ----------
3034 raw_cell : str
3070 raw_cell : str
3035 The code to be executed
3071 The code to be executed
3036
3072
3037 Returns
3073 Returns
3038 -------
3074 -------
3039 result: bool
3075 result: bool
3040 Whether the code needs to be run with a coroutine runner or not
3076 Whether the code needs to be run with a coroutine runner or not
3041 .. versionadded:: 7.0
3077 .. versionadded:: 7.0
3042 """
3078 """
3043 if not self.autoawait:
3079 if not self.autoawait:
3044 return False
3080 return False
3045 if preprocessing_exc_tuple is not None:
3081 if preprocessing_exc_tuple is not None:
3046 return False
3082 return False
3047 assert preprocessing_exc_tuple is None
3083 assert preprocessing_exc_tuple is None
3048 if transformed_cell is None:
3084 if transformed_cell is None:
3049 warnings.warn(
3085 warnings.warn(
3050 "`should_run_async` will not call `transform_cell`"
3086 "`should_run_async` will not call `transform_cell`"
3051 " automatically in the future. Please pass the result to"
3087 " automatically in the future. Please pass the result to"
3052 " `transformed_cell` argument and any exception that happen"
3088 " `transformed_cell` argument and any exception that happen"
3053 " during the"
3089 " during the"
3054 "transform in `preprocessing_exc_tuple` in"
3090 "transform in `preprocessing_exc_tuple` in"
3055 " IPython 7.17 and above.",
3091 " IPython 7.17 and above.",
3056 DeprecationWarning,
3092 DeprecationWarning,
3057 stacklevel=2,
3093 stacklevel=2,
3058 )
3094 )
3059 try:
3095 try:
3060 cell = self.transform_cell(raw_cell)
3096 cell = self.transform_cell(raw_cell)
3061 except Exception:
3097 except Exception:
3062 # any exception during transform will be raised
3098 # any exception during transform will be raised
3063 # prior to execution
3099 # prior to execution
3064 return False
3100 return False
3065 else:
3101 else:
3066 cell = transformed_cell
3102 cell = transformed_cell
3067 return _should_be_async(cell)
3103 return _should_be_async(cell)
3068
3104
3069 async def run_cell_async(
3105 async def run_cell_async(
3070 self,
3106 self,
3071 raw_cell: str,
3107 raw_cell: str,
3072 store_history=False,
3108 store_history=False,
3073 silent=False,
3109 silent=False,
3074 shell_futures=True,
3110 shell_futures=True,
3075 *,
3111 *,
3076 transformed_cell: Optional[str] = None,
3112 transformed_cell: Optional[str] = None,
3077 preprocessing_exc_tuple: Optional[Any] = None,
3113 preprocessing_exc_tuple: Optional[Any] = None,
3078 cell_id=None,
3114 cell_id=None,
3079 ) -> ExecutionResult:
3115 ) -> ExecutionResult:
3080 """Run a complete IPython cell asynchronously.
3116 """Run a complete IPython cell asynchronously.
3081
3117
3082 Parameters
3118 Parameters
3083 ----------
3119 ----------
3084 raw_cell : str
3120 raw_cell : str
3085 The code (including IPython code such as %magic functions) to run.
3121 The code (including IPython code such as %magic functions) to run.
3086 store_history : bool
3122 store_history : bool
3087 If True, the raw and translated cell will be stored in IPython's
3123 If True, the raw and translated cell will be stored in IPython's
3088 history. For user code calling back into IPython's machinery, this
3124 history. For user code calling back into IPython's machinery, this
3089 should be set to False.
3125 should be set to False.
3090 silent : bool
3126 silent : bool
3091 If True, avoid side-effects, such as implicit displayhooks and
3127 If True, avoid side-effects, such as implicit displayhooks and
3092 and logging. silent=True forces store_history=False.
3128 and logging. silent=True forces store_history=False.
3093 shell_futures : bool
3129 shell_futures : bool
3094 If True, the code will share future statements with the interactive
3130 If True, the code will share future statements with the interactive
3095 shell. It will both be affected by previous __future__ imports, and
3131 shell. It will both be affected by previous __future__ imports, and
3096 any __future__ imports in the code will affect the shell. If False,
3132 any __future__ imports in the code will affect the shell. If False,
3097 __future__ imports are not shared in either direction.
3133 __future__ imports are not shared in either direction.
3098 transformed_cell: str
3134 transformed_cell: str
3099 cell that was passed through transformers
3135 cell that was passed through transformers
3100 preprocessing_exc_tuple:
3136 preprocessing_exc_tuple:
3101 trace if the transformation failed.
3137 trace if the transformation failed.
3102
3138
3103 Returns
3139 Returns
3104 -------
3140 -------
3105 result : :class:`ExecutionResult`
3141 result : :class:`ExecutionResult`
3106
3142
3107 .. versionadded:: 7.0
3143 .. versionadded:: 7.0
3108 """
3144 """
3109 info = ExecutionInfo(raw_cell, store_history, silent, shell_futures, cell_id)
3145 info = ExecutionInfo(raw_cell, store_history, silent, shell_futures, cell_id)
3110 result = ExecutionResult(info)
3146 result = ExecutionResult(info)
3111
3147
3112 if (not raw_cell) or raw_cell.isspace():
3148 if (not raw_cell) or raw_cell.isspace():
3113 self.last_execution_succeeded = True
3149 self.last_execution_succeeded = True
3114 self.last_execution_result = result
3150 self.last_execution_result = result
3115 return result
3151 return result
3116
3152
3117 if silent:
3153 if silent:
3118 store_history = False
3154 store_history = False
3119
3155
3120 if store_history:
3156 if store_history:
3121 result.execution_count = self.execution_count
3157 result.execution_count = self.execution_count
3122
3158
3123 def error_before_exec(value):
3159 def error_before_exec(value):
3124 if store_history:
3160 if store_history:
3125 self.execution_count += 1
3161 self.execution_count += 1
3126 result.error_before_exec = value
3162 result.error_before_exec = value
3127 self.last_execution_succeeded = False
3163 self.last_execution_succeeded = False
3128 self.last_execution_result = result
3164 self.last_execution_result = result
3129 return result
3165 return result
3130
3166
3131 self.events.trigger('pre_execute')
3167 self.events.trigger('pre_execute')
3132 if not silent:
3168 if not silent:
3133 self.events.trigger('pre_run_cell', info)
3169 self.events.trigger('pre_run_cell', info)
3134
3170
3135 if transformed_cell is None:
3171 if transformed_cell is None:
3136 warnings.warn(
3172 warnings.warn(
3137 "`run_cell_async` will not call `transform_cell`"
3173 "`run_cell_async` will not call `transform_cell`"
3138 " automatically in the future. Please pass the result to"
3174 " automatically in the future. Please pass the result to"
3139 " `transformed_cell` argument and any exception that happen"
3175 " `transformed_cell` argument and any exception that happen"
3140 " during the"
3176 " during the"
3141 "transform in `preprocessing_exc_tuple` in"
3177 "transform in `preprocessing_exc_tuple` in"
3142 " IPython 7.17 and above.",
3178 " IPython 7.17 and above.",
3143 DeprecationWarning,
3179 DeprecationWarning,
3144 stacklevel=2,
3180 stacklevel=2,
3145 )
3181 )
3146 # If any of our input transformation (input_transformer_manager or
3182 # If any of our input transformation (input_transformer_manager or
3147 # prefilter_manager) raises an exception, we store it in this variable
3183 # prefilter_manager) raises an exception, we store it in this variable
3148 # so that we can display the error after logging the input and storing
3184 # so that we can display the error after logging the input and storing
3149 # it in the history.
3185 # it in the history.
3150 try:
3186 try:
3151 cell = self.transform_cell(raw_cell)
3187 cell = self.transform_cell(raw_cell)
3152 except Exception:
3188 except Exception:
3153 preprocessing_exc_tuple = sys.exc_info()
3189 preprocessing_exc_tuple = sys.exc_info()
3154 cell = raw_cell # cell has to exist so it can be stored/logged
3190 cell = raw_cell # cell has to exist so it can be stored/logged
3155 else:
3191 else:
3156 preprocessing_exc_tuple = None
3192 preprocessing_exc_tuple = None
3157 else:
3193 else:
3158 if preprocessing_exc_tuple is None:
3194 if preprocessing_exc_tuple is None:
3159 cell = transformed_cell
3195 cell = transformed_cell
3160 else:
3196 else:
3161 cell = raw_cell
3197 cell = raw_cell
3162
3198
3163 # Do NOT store paste/cpaste magic history
3199 # Do NOT store paste/cpaste magic history
3164 if "get_ipython().run_line_magic(" in cell and "paste" in cell:
3200 if "get_ipython().run_line_magic(" in cell and "paste" in cell:
3165 store_history = False
3201 store_history = False
3166
3202
3167 # Store raw and processed history
3203 # Store raw and processed history
3168 if store_history:
3204 if store_history:
3169 self.history_manager.store_inputs(self.execution_count, cell, raw_cell)
3205 self.history_manager.store_inputs(self.execution_count, cell, raw_cell)
3170 if not silent:
3206 if not silent:
3171 self.logger.log(cell, raw_cell)
3207 self.logger.log(cell, raw_cell)
3172
3208
3173 # Display the exception if input processing failed.
3209 # Display the exception if input processing failed.
3174 if preprocessing_exc_tuple is not None:
3210 if preprocessing_exc_tuple is not None:
3175 self.showtraceback(preprocessing_exc_tuple)
3211 self.showtraceback(preprocessing_exc_tuple)
3176 if store_history:
3212 if store_history:
3177 self.execution_count += 1
3213 self.execution_count += 1
3178 return error_before_exec(preprocessing_exc_tuple[1])
3214 return error_before_exec(preprocessing_exc_tuple[1])
3179
3215
3180 # Our own compiler remembers the __future__ environment. If we want to
3216 # Our own compiler remembers the __future__ environment. If we want to
3181 # run code with a separate __future__ environment, use the default
3217 # run code with a separate __future__ environment, use the default
3182 # compiler
3218 # compiler
3183 compiler = self.compile if shell_futures else self.compiler_class()
3219 compiler = self.compile if shell_futures else self.compiler_class()
3184
3220
3185 _run_async = False
3221 _run_async = False
3186
3222
3187 with self.builtin_trap:
3223 with self.builtin_trap:
3188 cell_name = compiler.cache(cell, self.execution_count, raw_code=raw_cell)
3224 cell_name = compiler.cache(cell, self.execution_count, raw_code=raw_cell)
3189
3225
3190 with self.display_trap:
3226 with self.display_trap:
3191 # Compile to bytecode
3227 # Compile to bytecode
3192 try:
3228 try:
3193 code_ast = compiler.ast_parse(cell, filename=cell_name)
3229 code_ast = compiler.ast_parse(cell, filename=cell_name)
3194 except self.custom_exceptions as e:
3230 except self.custom_exceptions as e:
3195 etype, value, tb = sys.exc_info()
3231 etype, value, tb = sys.exc_info()
3196 self.CustomTB(etype, value, tb)
3232 self.CustomTB(etype, value, tb)
3197 return error_before_exec(e)
3233 return error_before_exec(e)
3198 except IndentationError as e:
3234 except IndentationError as e:
3199 self.showindentationerror()
3235 self.showindentationerror()
3200 return error_before_exec(e)
3236 return error_before_exec(e)
3201 except (OverflowError, SyntaxError, ValueError, TypeError,
3237 except (OverflowError, SyntaxError, ValueError, TypeError,
3202 MemoryError) as e:
3238 MemoryError) as e:
3203 self.showsyntaxerror()
3239 self.showsyntaxerror()
3204 return error_before_exec(e)
3240 return error_before_exec(e)
3205
3241
3206 # Apply AST transformations
3242 # Apply AST transformations
3207 try:
3243 try:
3208 code_ast = self.transform_ast(code_ast)
3244 code_ast = self.transform_ast(code_ast)
3209 except InputRejected as e:
3245 except InputRejected as e:
3210 self.showtraceback()
3246 self.showtraceback()
3211 return error_before_exec(e)
3247 return error_before_exec(e)
3212
3248
3213 # Give the displayhook a reference to our ExecutionResult so it
3249 # Give the displayhook a reference to our ExecutionResult so it
3214 # can fill in the output value.
3250 # can fill in the output value.
3215 self.displayhook.exec_result = result
3251 self.displayhook.exec_result = result
3216
3252
3217 # Execute the user code
3253 # Execute the user code
3218 interactivity = "none" if silent else self.ast_node_interactivity
3254 interactivity = "none" if silent else self.ast_node_interactivity
3219
3255
3220
3256
3221 has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
3257 has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
3222 interactivity=interactivity, compiler=compiler, result=result)
3258 interactivity=interactivity, compiler=compiler, result=result)
3223
3259
3224 self.last_execution_succeeded = not has_raised
3260 self.last_execution_succeeded = not has_raised
3225 self.last_execution_result = result
3261 self.last_execution_result = result
3226
3262
3227 # Reset this so later displayed values do not modify the
3263 # Reset this so later displayed values do not modify the
3228 # ExecutionResult
3264 # ExecutionResult
3229 self.displayhook.exec_result = None
3265 self.displayhook.exec_result = None
3230
3266
3231 if store_history:
3267 if store_history:
3232 # Write output to the database. Does nothing unless
3268 # Write output to the database. Does nothing unless
3233 # history output logging is enabled.
3269 # history output logging is enabled.
3234 self.history_manager.store_output(self.execution_count)
3270 self.history_manager.store_output(self.execution_count)
3235 # Each cell is a *single* input, regardless of how many lines it has
3271 # Each cell is a *single* input, regardless of how many lines it has
3236 self.execution_count += 1
3272 self.execution_count += 1
3237
3273
3238 return result
3274 return result
3239
3275
3240 def transform_cell(self, raw_cell):
3276 def transform_cell(self, raw_cell):
3241 """Transform an input cell before parsing it.
3277 """Transform an input cell before parsing it.
3242
3278
3243 Static transformations, implemented in IPython.core.inputtransformer2,
3279 Static transformations, implemented in IPython.core.inputtransformer2,
3244 deal with things like ``%magic`` and ``!system`` commands.
3280 deal with things like ``%magic`` and ``!system`` commands.
3245 These run on all input.
3281 These run on all input.
3246 Dynamic transformations, for things like unescaped magics and the exit
3282 Dynamic transformations, for things like unescaped magics and the exit
3247 autocall, depend on the state of the interpreter.
3283 autocall, depend on the state of the interpreter.
3248 These only apply to single line inputs.
3284 These only apply to single line inputs.
3249
3285
3250 These string-based transformations are followed by AST transformations;
3286 These string-based transformations are followed by AST transformations;
3251 see :meth:`transform_ast`.
3287 see :meth:`transform_ast`.
3252 """
3288 """
3253 # Static input transformations
3289 # Static input transformations
3254 cell = self.input_transformer_manager.transform_cell(raw_cell)
3290 cell = self.input_transformer_manager.transform_cell(raw_cell)
3255
3291
3256 if len(cell.splitlines()) == 1:
3292 if len(cell.splitlines()) == 1:
3257 # Dynamic transformations - only applied for single line commands
3293 # Dynamic transformations - only applied for single line commands
3258 with self.builtin_trap:
3294 with self.builtin_trap:
3259 # use prefilter_lines to handle trailing newlines
3295 # use prefilter_lines to handle trailing newlines
3260 # restore trailing newline for ast.parse
3296 # restore trailing newline for ast.parse
3261 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
3297 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
3262
3298
3263 lines = cell.splitlines(keepends=True)
3299 lines = cell.splitlines(keepends=True)
3264 for transform in self.input_transformers_post:
3300 for transform in self.input_transformers_post:
3265 lines = transform(lines)
3301 lines = transform(lines)
3266 cell = ''.join(lines)
3302 cell = ''.join(lines)
3267
3303
3268 return cell
3304 return cell
3269
3305
3270 def transform_ast(self, node):
3306 def transform_ast(self, node):
3271 """Apply the AST transformations from self.ast_transformers
3307 """Apply the AST transformations from self.ast_transformers
3272
3308
3273 Parameters
3309 Parameters
3274 ----------
3310 ----------
3275 node : ast.Node
3311 node : ast.Node
3276 The root node to be transformed. Typically called with the ast.Module
3312 The root node to be transformed. Typically called with the ast.Module
3277 produced by parsing user input.
3313 produced by parsing user input.
3278
3314
3279 Returns
3315 Returns
3280 -------
3316 -------
3281 An ast.Node corresponding to the node it was called with. Note that it
3317 An ast.Node corresponding to the node it was called with. Note that it
3282 may also modify the passed object, so don't rely on references to the
3318 may also modify the passed object, so don't rely on references to the
3283 original AST.
3319 original AST.
3284 """
3320 """
3285 for transformer in self.ast_transformers:
3321 for transformer in self.ast_transformers:
3286 try:
3322 try:
3287 node = transformer.visit(node)
3323 node = transformer.visit(node)
3288 except InputRejected:
3324 except InputRejected:
3289 # User-supplied AST transformers can reject an input by raising
3325 # User-supplied AST transformers can reject an input by raising
3290 # an InputRejected. Short-circuit in this case so that we
3326 # an InputRejected. Short-circuit in this case so that we
3291 # don't unregister the transform.
3327 # don't unregister the transform.
3292 raise
3328 raise
3293 except Exception:
3329 except Exception:
3294 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
3330 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
3295 self.ast_transformers.remove(transformer)
3331 self.ast_transformers.remove(transformer)
3296
3332
3297 if self.ast_transformers:
3333 if self.ast_transformers:
3298 ast.fix_missing_locations(node)
3334 ast.fix_missing_locations(node)
3299 return node
3335 return node
3300
3336
3301 async def run_ast_nodes(
3337 async def run_ast_nodes(
3302 self,
3338 self,
3303 nodelist: ListType[stmt],
3339 nodelist: ListType[stmt],
3304 cell_name: str,
3340 cell_name: str,
3305 interactivity="last_expr",
3341 interactivity="last_expr",
3306 compiler=compile,
3342 compiler=compile,
3307 result=None,
3343 result=None,
3308 ):
3344 ):
3309 """Run a sequence of AST nodes. The execution mode depends on the
3345 """Run a sequence of AST nodes. The execution mode depends on the
3310 interactivity parameter.
3346 interactivity parameter.
3311
3347
3312 Parameters
3348 Parameters
3313 ----------
3349 ----------
3314 nodelist : list
3350 nodelist : list
3315 A sequence of AST nodes to run.
3351 A sequence of AST nodes to run.
3316 cell_name : str
3352 cell_name : str
3317 Will be passed to the compiler as the filename of the cell. Typically
3353 Will be passed to the compiler as the filename of the cell. Typically
3318 the value returned by ip.compile.cache(cell).
3354 the value returned by ip.compile.cache(cell).
3319 interactivity : str
3355 interactivity : str
3320 'all', 'last', 'last_expr' , 'last_expr_or_assign' or 'none',
3356 'all', 'last', 'last_expr' , 'last_expr_or_assign' or 'none',
3321 specifying which nodes should be run interactively (displaying output
3357 specifying which nodes should be run interactively (displaying output
3322 from expressions). 'last_expr' will run the last node interactively
3358 from expressions). 'last_expr' will run the last node interactively
3323 only if it is an expression (i.e. expressions in loops or other blocks
3359 only if it is an expression (i.e. expressions in loops or other blocks
3324 are not displayed) 'last_expr_or_assign' will run the last expression
3360 are not displayed) 'last_expr_or_assign' will run the last expression
3325 or the last assignment. Other values for this parameter will raise a
3361 or the last assignment. Other values for this parameter will raise a
3326 ValueError.
3362 ValueError.
3327
3363
3328 compiler : callable
3364 compiler : callable
3329 A function with the same interface as the built-in compile(), to turn
3365 A function with the same interface as the built-in compile(), to turn
3330 the AST nodes into code objects. Default is the built-in compile().
3366 the AST nodes into code objects. Default is the built-in compile().
3331 result : ExecutionResult, optional
3367 result : ExecutionResult, optional
3332 An object to store exceptions that occur during execution.
3368 An object to store exceptions that occur during execution.
3333
3369
3334 Returns
3370 Returns
3335 -------
3371 -------
3336 True if an exception occurred while running code, False if it finished
3372 True if an exception occurred while running code, False if it finished
3337 running.
3373 running.
3338 """
3374 """
3339 if not nodelist:
3375 if not nodelist:
3340 return
3376 return
3341
3377
3342
3378
3343 if interactivity == 'last_expr_or_assign':
3379 if interactivity == 'last_expr_or_assign':
3344 if isinstance(nodelist[-1], _assign_nodes):
3380 if isinstance(nodelist[-1], _assign_nodes):
3345 asg = nodelist[-1]
3381 asg = nodelist[-1]
3346 if isinstance(asg, ast.Assign) and len(asg.targets) == 1:
3382 if isinstance(asg, ast.Assign) and len(asg.targets) == 1:
3347 target = asg.targets[0]
3383 target = asg.targets[0]
3348 elif isinstance(asg, _single_targets_nodes):
3384 elif isinstance(asg, _single_targets_nodes):
3349 target = asg.target
3385 target = asg.target
3350 else:
3386 else:
3351 target = None
3387 target = None
3352 if isinstance(target, ast.Name):
3388 if isinstance(target, ast.Name):
3353 nnode = ast.Expr(ast.Name(target.id, ast.Load()))
3389 nnode = ast.Expr(ast.Name(target.id, ast.Load()))
3354 ast.fix_missing_locations(nnode)
3390 ast.fix_missing_locations(nnode)
3355 nodelist.append(nnode)
3391 nodelist.append(nnode)
3356 interactivity = 'last_expr'
3392 interactivity = 'last_expr'
3357
3393
3358 _async = False
3394 _async = False
3359 if interactivity == 'last_expr':
3395 if interactivity == 'last_expr':
3360 if isinstance(nodelist[-1], ast.Expr):
3396 if isinstance(nodelist[-1], ast.Expr):
3361 interactivity = "last"
3397 interactivity = "last"
3362 else:
3398 else:
3363 interactivity = "none"
3399 interactivity = "none"
3364
3400
3365 if interactivity == 'none':
3401 if interactivity == 'none':
3366 to_run_exec, to_run_interactive = nodelist, []
3402 to_run_exec, to_run_interactive = nodelist, []
3367 elif interactivity == 'last':
3403 elif interactivity == 'last':
3368 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
3404 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
3369 elif interactivity == 'all':
3405 elif interactivity == 'all':
3370 to_run_exec, to_run_interactive = [], nodelist
3406 to_run_exec, to_run_interactive = [], nodelist
3371 else:
3407 else:
3372 raise ValueError("Interactivity was %r" % interactivity)
3408 raise ValueError("Interactivity was %r" % interactivity)
3373
3409
3374 try:
3410 try:
3375
3411
3376 def compare(code):
3412 def compare(code):
3377 is_async = inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE
3413 is_async = inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE
3378 return is_async
3414 return is_async
3379
3415
3380 # refactor that to just change the mod constructor.
3416 # refactor that to just change the mod constructor.
3381 to_run = []
3417 to_run = []
3382 for node in to_run_exec:
3418 for node in to_run_exec:
3383 to_run.append((node, "exec"))
3419 to_run.append((node, "exec"))
3384
3420
3385 for node in to_run_interactive:
3421 for node in to_run_interactive:
3386 to_run.append((node, "single"))
3422 to_run.append((node, "single"))
3387
3423
3388 for node, mode in to_run:
3424 for node, mode in to_run:
3389 if mode == "exec":
3425 if mode == "exec":
3390 mod = Module([node], [])
3426 mod = Module([node], [])
3391 elif mode == "single":
3427 elif mode == "single":
3392 mod = ast.Interactive([node])
3428 mod = ast.Interactive([node])
3393 with compiler.extra_flags(
3429 with compiler.extra_flags(
3394 getattr(ast, "PyCF_ALLOW_TOP_LEVEL_AWAIT", 0x0)
3430 getattr(ast, "PyCF_ALLOW_TOP_LEVEL_AWAIT", 0x0)
3395 if self.autoawait
3431 if self.autoawait
3396 else 0x0
3432 else 0x0
3397 ):
3433 ):
3398 code = compiler(mod, cell_name, mode)
3434 code = compiler(mod, cell_name, mode)
3399 asy = compare(code)
3435 asy = compare(code)
3400 if await self.run_code(code, result, async_=asy):
3436 if await self.run_code(code, result, async_=asy):
3401 return True
3437 return True
3402
3438
3403 # Flush softspace
3439 # Flush softspace
3404 if softspace(sys.stdout, 0):
3440 if softspace(sys.stdout, 0):
3405 print()
3441 print()
3406
3442
3407 except:
3443 except:
3408 # It's possible to have exceptions raised here, typically by
3444 # It's possible to have exceptions raised here, typically by
3409 # compilation of odd code (such as a naked 'return' outside a
3445 # compilation of odd code (such as a naked 'return' outside a
3410 # function) that did parse but isn't valid. Typically the exception
3446 # function) that did parse but isn't valid. Typically the exception
3411 # is a SyntaxError, but it's safest just to catch anything and show
3447 # is a SyntaxError, but it's safest just to catch anything and show
3412 # the user a traceback.
3448 # the user a traceback.
3413
3449
3414 # We do only one try/except outside the loop to minimize the impact
3450 # We do only one try/except outside the loop to minimize the impact
3415 # on runtime, and also because if any node in the node list is
3451 # on runtime, and also because if any node in the node list is
3416 # broken, we should stop execution completely.
3452 # broken, we should stop execution completely.
3417 if result:
3453 if result:
3418 result.error_before_exec = sys.exc_info()[1]
3454 result.error_before_exec = sys.exc_info()[1]
3419 self.showtraceback()
3455 self.showtraceback()
3420 return True
3456 return True
3421
3457
3422 return False
3458 return False
3423
3459
3424 async def run_code(self, code_obj, result=None, *, async_=False):
3460 async def run_code(self, code_obj, result=None, *, async_=False):
3425 """Execute a code object.
3461 """Execute a code object.
3426
3462
3427 When an exception occurs, self.showtraceback() is called to display a
3463 When an exception occurs, self.showtraceback() is called to display a
3428 traceback.
3464 traceback.
3429
3465
3430 Parameters
3466 Parameters
3431 ----------
3467 ----------
3432 code_obj : code object
3468 code_obj : code object
3433 A compiled code object, to be executed
3469 A compiled code object, to be executed
3434 result : ExecutionResult, optional
3470 result : ExecutionResult, optional
3435 An object to store exceptions that occur during execution.
3471 An object to store exceptions that occur during execution.
3436 async_ : Bool (Experimental)
3472 async_ : Bool (Experimental)
3437 Attempt to run top-level asynchronous code in a default loop.
3473 Attempt to run top-level asynchronous code in a default loop.
3438
3474
3439 Returns
3475 Returns
3440 -------
3476 -------
3441 False : successful execution.
3477 False : successful execution.
3442 True : an error occurred.
3478 True : an error occurred.
3443 """
3479 """
3444 # special value to say that anything above is IPython and should be
3480 # special value to say that anything above is IPython and should be
3445 # hidden.
3481 # hidden.
3446 __tracebackhide__ = "__ipython_bottom__"
3482 __tracebackhide__ = "__ipython_bottom__"
3447 # Set our own excepthook in case the user code tries to call it
3483 # Set our own excepthook in case the user code tries to call it
3448 # directly, so that the IPython crash handler doesn't get triggered
3484 # directly, so that the IPython crash handler doesn't get triggered
3449 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3485 old_excepthook, sys.excepthook = sys.excepthook, self.excepthook
3450
3486
3451 # we save the original sys.excepthook in the instance, in case config
3487 # we save the original sys.excepthook in the instance, in case config
3452 # code (such as magics) needs access to it.
3488 # code (such as magics) needs access to it.
3453 self.sys_excepthook = old_excepthook
3489 self.sys_excepthook = old_excepthook
3454 outflag = True # happens in more places, so it's easier as default
3490 outflag = True # happens in more places, so it's easier as default
3455 try:
3491 try:
3456 try:
3492 try:
3457 if async_:
3493 if async_:
3458 await eval(code_obj, self.user_global_ns, self.user_ns)
3494 await eval(code_obj, self.user_global_ns, self.user_ns)
3459 else:
3495 else:
3460 exec(code_obj, self.user_global_ns, self.user_ns)
3496 exec(code_obj, self.user_global_ns, self.user_ns)
3461 finally:
3497 finally:
3462 # Reset our crash handler in place
3498 # Reset our crash handler in place
3463 sys.excepthook = old_excepthook
3499 sys.excepthook = old_excepthook
3464 except SystemExit as e:
3500 except SystemExit as e:
3465 if result is not None:
3501 if result is not None:
3466 result.error_in_exec = e
3502 result.error_in_exec = e
3467 self.showtraceback(exception_only=True)
3503 self.showtraceback(exception_only=True)
3468 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
3504 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
3469 except bdb.BdbQuit:
3505 except bdb.BdbQuit:
3470 etype, value, tb = sys.exc_info()
3506 etype, value, tb = sys.exc_info()
3471 if result is not None:
3507 if result is not None:
3472 result.error_in_exec = value
3508 result.error_in_exec = value
3473 # the BdbQuit stops here
3509 # the BdbQuit stops here
3474 except self.custom_exceptions:
3510 except self.custom_exceptions:
3475 etype, value, tb = sys.exc_info()
3511 etype, value, tb = sys.exc_info()
3476 if result is not None:
3512 if result is not None:
3477 result.error_in_exec = value
3513 result.error_in_exec = value
3478 self.CustomTB(etype, value, tb)
3514 self.CustomTB(etype, value, tb)
3479 except:
3515 except:
3480 if result is not None:
3516 if result is not None:
3481 result.error_in_exec = sys.exc_info()[1]
3517 result.error_in_exec = sys.exc_info()[1]
3482 self.showtraceback(running_compiled_code=True)
3518 self.showtraceback(running_compiled_code=True)
3483 else:
3519 else:
3484 outflag = False
3520 outflag = False
3485 return outflag
3521 return outflag
3486
3522
3487 # For backwards compatibility
3523 # For backwards compatibility
3488 runcode = run_code
3524 runcode = run_code
3489
3525
3490 def check_complete(self, code: str) -> Tuple[str, str]:
3526 def check_complete(self, code: str) -> Tuple[str, str]:
3491 """Return whether a block of code is ready to execute, or should be continued
3527 """Return whether a block of code is ready to execute, or should be continued
3492
3528
3493 Parameters
3529 Parameters
3494 ----------
3530 ----------
3495 code : string
3531 code : string
3496 Python input code, which can be multiline.
3532 Python input code, which can be multiline.
3497
3533
3498 Returns
3534 Returns
3499 -------
3535 -------
3500 status : str
3536 status : str
3501 One of 'complete', 'incomplete', or 'invalid' if source is not a
3537 One of 'complete', 'incomplete', or 'invalid' if source is not a
3502 prefix of valid code.
3538 prefix of valid code.
3503 indent : str
3539 indent : str
3504 When status is 'incomplete', this is some whitespace to insert on
3540 When status is 'incomplete', this is some whitespace to insert on
3505 the next line of the prompt.
3541 the next line of the prompt.
3506 """
3542 """
3507 status, nspaces = self.input_transformer_manager.check_complete(code)
3543 status, nspaces = self.input_transformer_manager.check_complete(code)
3508 return status, ' ' * (nspaces or 0)
3544 return status, ' ' * (nspaces or 0)
3509
3545
3510 #-------------------------------------------------------------------------
3546 #-------------------------------------------------------------------------
3511 # Things related to GUI support and pylab
3547 # Things related to GUI support and pylab
3512 #-------------------------------------------------------------------------
3548 #-------------------------------------------------------------------------
3513
3549
3514 active_eventloop = None
3550 active_eventloop = None
3515
3551
3516 def enable_gui(self, gui=None):
3552 def enable_gui(self, gui=None):
3517 raise NotImplementedError('Implement enable_gui in a subclass')
3553 raise NotImplementedError('Implement enable_gui in a subclass')
3518
3554
3519 def enable_matplotlib(self, gui=None):
3555 def enable_matplotlib(self, gui=None):
3520 """Enable interactive matplotlib and inline figure support.
3556 """Enable interactive matplotlib and inline figure support.
3521
3557
3522 This takes the following steps:
3558 This takes the following steps:
3523
3559
3524 1. select the appropriate eventloop and matplotlib backend
3560 1. select the appropriate eventloop and matplotlib backend
3525 2. set up matplotlib for interactive use with that backend
3561 2. set up matplotlib for interactive use with that backend
3526 3. configure formatters for inline figure display
3562 3. configure formatters for inline figure display
3527 4. enable the selected gui eventloop
3563 4. enable the selected gui eventloop
3528
3564
3529 Parameters
3565 Parameters
3530 ----------
3566 ----------
3531 gui : optional, string
3567 gui : optional, string
3532 If given, dictates the choice of matplotlib GUI backend to use
3568 If given, dictates the choice of matplotlib GUI backend to use
3533 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3569 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3534 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3570 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3535 matplotlib (as dictated by the matplotlib build-time options plus the
3571 matplotlib (as dictated by the matplotlib build-time options plus the
3536 user's matplotlibrc configuration file). Note that not all backends
3572 user's matplotlibrc configuration file). Note that not all backends
3537 make sense in all contexts, for example a terminal ipython can't
3573 make sense in all contexts, for example a terminal ipython can't
3538 display figures inline.
3574 display figures inline.
3539 """
3575 """
3540 from matplotlib_inline.backend_inline import configure_inline_support
3576 from matplotlib_inline.backend_inline import configure_inline_support
3541
3577
3542 from IPython.core import pylabtools as pt
3578 from IPython.core import pylabtools as pt
3543 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3579 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
3544
3580
3545 if gui != 'inline':
3581 if gui != 'inline':
3546 # If we have our first gui selection, store it
3582 # If we have our first gui selection, store it
3547 if self.pylab_gui_select is None:
3583 if self.pylab_gui_select is None:
3548 self.pylab_gui_select = gui
3584 self.pylab_gui_select = gui
3549 # Otherwise if they are different
3585 # Otherwise if they are different
3550 elif gui != self.pylab_gui_select:
3586 elif gui != self.pylab_gui_select:
3551 print('Warning: Cannot change to a different GUI toolkit: %s.'
3587 print('Warning: Cannot change to a different GUI toolkit: %s.'
3552 ' Using %s instead.' % (gui, self.pylab_gui_select))
3588 ' Using %s instead.' % (gui, self.pylab_gui_select))
3553 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3589 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
3554
3590
3555 pt.activate_matplotlib(backend)
3591 pt.activate_matplotlib(backend)
3556 configure_inline_support(self, backend)
3592 configure_inline_support(self, backend)
3557
3593
3558 # Now we must activate the gui pylab wants to use, and fix %run to take
3594 # Now we must activate the gui pylab wants to use, and fix %run to take
3559 # plot updates into account
3595 # plot updates into account
3560 self.enable_gui(gui)
3596 self.enable_gui(gui)
3561 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3597 self.magics_manager.registry['ExecutionMagics'].default_runner = \
3562 pt.mpl_runner(self.safe_execfile)
3598 pt.mpl_runner(self.safe_execfile)
3563
3599
3564 return gui, backend
3600 return gui, backend
3565
3601
3566 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3602 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
3567 """Activate pylab support at runtime.
3603 """Activate pylab support at runtime.
3568
3604
3569 This turns on support for matplotlib, preloads into the interactive
3605 This turns on support for matplotlib, preloads into the interactive
3570 namespace all of numpy and pylab, and configures IPython to correctly
3606 namespace all of numpy and pylab, and configures IPython to correctly
3571 interact with the GUI event loop. The GUI backend to be used can be
3607 interact with the GUI event loop. The GUI backend to be used can be
3572 optionally selected with the optional ``gui`` argument.
3608 optionally selected with the optional ``gui`` argument.
3573
3609
3574 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3610 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
3575
3611
3576 Parameters
3612 Parameters
3577 ----------
3613 ----------
3578 gui : optional, string
3614 gui : optional, string
3579 If given, dictates the choice of matplotlib GUI backend to use
3615 If given, dictates the choice of matplotlib GUI backend to use
3580 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3616 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
3581 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3617 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
3582 matplotlib (as dictated by the matplotlib build-time options plus the
3618 matplotlib (as dictated by the matplotlib build-time options plus the
3583 user's matplotlibrc configuration file). Note that not all backends
3619 user's matplotlibrc configuration file). Note that not all backends
3584 make sense in all contexts, for example a terminal ipython can't
3620 make sense in all contexts, for example a terminal ipython can't
3585 display figures inline.
3621 display figures inline.
3586 import_all : optional, bool, default: True
3622 import_all : optional, bool, default: True
3587 Whether to do `from numpy import *` and `from pylab import *`
3623 Whether to do `from numpy import *` and `from pylab import *`
3588 in addition to module imports.
3624 in addition to module imports.
3589 welcome_message : deprecated
3625 welcome_message : deprecated
3590 This argument is ignored, no welcome message will be displayed.
3626 This argument is ignored, no welcome message will be displayed.
3591 """
3627 """
3592 from IPython.core.pylabtools import import_pylab
3628 from IPython.core.pylabtools import import_pylab
3593
3629
3594 gui, backend = self.enable_matplotlib(gui)
3630 gui, backend = self.enable_matplotlib(gui)
3595
3631
3596 # We want to prevent the loading of pylab to pollute the user's
3632 # We want to prevent the loading of pylab to pollute the user's
3597 # namespace as shown by the %who* magics, so we execute the activation
3633 # namespace as shown by the %who* magics, so we execute the activation
3598 # code in an empty namespace, and we update *both* user_ns and
3634 # code in an empty namespace, and we update *both* user_ns and
3599 # user_ns_hidden with this information.
3635 # user_ns_hidden with this information.
3600 ns = {}
3636 ns = {}
3601 import_pylab(ns, import_all)
3637 import_pylab(ns, import_all)
3602 # warn about clobbered names
3638 # warn about clobbered names
3603 ignored = {"__builtins__"}
3639 ignored = {"__builtins__"}
3604 both = set(ns).intersection(self.user_ns).difference(ignored)
3640 both = set(ns).intersection(self.user_ns).difference(ignored)
3605 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3641 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
3606 self.user_ns.update(ns)
3642 self.user_ns.update(ns)
3607 self.user_ns_hidden.update(ns)
3643 self.user_ns_hidden.update(ns)
3608 return gui, backend, clobbered
3644 return gui, backend, clobbered
3609
3645
3610 #-------------------------------------------------------------------------
3646 #-------------------------------------------------------------------------
3611 # Utilities
3647 # Utilities
3612 #-------------------------------------------------------------------------
3648 #-------------------------------------------------------------------------
3613
3649
3614 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3650 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
3615 """Expand python variables in a string.
3651 """Expand python variables in a string.
3616
3652
3617 The depth argument indicates how many frames above the caller should
3653 The depth argument indicates how many frames above the caller should
3618 be walked to look for the local namespace where to expand variables.
3654 be walked to look for the local namespace where to expand variables.
3619
3655
3620 The global namespace for expansion is always the user's interactive
3656 The global namespace for expansion is always the user's interactive
3621 namespace.
3657 namespace.
3622 """
3658 """
3623 ns = self.user_ns.copy()
3659 ns = self.user_ns.copy()
3624 try:
3660 try:
3625 frame = sys._getframe(depth+1)
3661 frame = sys._getframe(depth+1)
3626 except ValueError:
3662 except ValueError:
3627 # This is thrown if there aren't that many frames on the stack,
3663 # This is thrown if there aren't that many frames on the stack,
3628 # e.g. if a script called run_line_magic() directly.
3664 # e.g. if a script called run_line_magic() directly.
3629 pass
3665 pass
3630 else:
3666 else:
3631 ns.update(frame.f_locals)
3667 ns.update(frame.f_locals)
3632
3668
3633 try:
3669 try:
3634 # We have to use .vformat() here, because 'self' is a valid and common
3670 # We have to use .vformat() here, because 'self' is a valid and common
3635 # name, and expanding **ns for .format() would make it collide with
3671 # name, and expanding **ns for .format() would make it collide with
3636 # the 'self' argument of the method.
3672 # the 'self' argument of the method.
3637 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3673 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3638 except Exception:
3674 except Exception:
3639 # if formatter couldn't format, just let it go untransformed
3675 # if formatter couldn't format, just let it go untransformed
3640 pass
3676 pass
3641 return cmd
3677 return cmd
3642
3678
3643 def mktempfile(self, data=None, prefix='ipython_edit_'):
3679 def mktempfile(self, data=None, prefix='ipython_edit_'):
3644 """Make a new tempfile and return its filename.
3680 """Make a new tempfile and return its filename.
3645
3681
3646 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3682 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3647 but it registers the created filename internally so ipython cleans it up
3683 but it registers the created filename internally so ipython cleans it up
3648 at exit time.
3684 at exit time.
3649
3685
3650 Optional inputs:
3686 Optional inputs:
3651
3687
3652 - data(None): if data is given, it gets written out to the temp file
3688 - data(None): if data is given, it gets written out to the temp file
3653 immediately, and the file is closed again."""
3689 immediately, and the file is closed again."""
3654
3690
3655 dir_path = Path(tempfile.mkdtemp(prefix=prefix))
3691 dir_path = Path(tempfile.mkdtemp(prefix=prefix))
3656 self.tempdirs.append(dir_path)
3692 self.tempdirs.append(dir_path)
3657
3693
3658 handle, filename = tempfile.mkstemp(".py", prefix, dir=str(dir_path))
3694 handle, filename = tempfile.mkstemp(".py", prefix, dir=str(dir_path))
3659 os.close(handle) # On Windows, there can only be one open handle on a file
3695 os.close(handle) # On Windows, there can only be one open handle on a file
3660
3696
3661 file_path = Path(filename)
3697 file_path = Path(filename)
3662 self.tempfiles.append(file_path)
3698 self.tempfiles.append(file_path)
3663
3699
3664 if data:
3700 if data:
3665 file_path.write_text(data, encoding="utf-8")
3701 file_path.write_text(data, encoding="utf-8")
3666 return filename
3702 return filename
3667
3703
3668 def ask_yes_no(self, prompt, default=None, interrupt=None):
3704 def ask_yes_no(self, prompt, default=None, interrupt=None):
3669 if self.quiet:
3705 if self.quiet:
3670 return True
3706 return True
3671 return ask_yes_no(prompt,default,interrupt)
3707 return ask_yes_no(prompt,default,interrupt)
3672
3708
3673 def show_usage(self):
3709 def show_usage(self):
3674 """Show a usage message"""
3710 """Show a usage message"""
3675 page.page(IPython.core.usage.interactive_usage)
3711 page.page(IPython.core.usage.interactive_usage)
3676
3712
3677 def extract_input_lines(self, range_str, raw=False):
3713 def extract_input_lines(self, range_str, raw=False):
3678 """Return as a string a set of input history slices.
3714 """Return as a string a set of input history slices.
3679
3715
3680 Parameters
3716 Parameters
3681 ----------
3717 ----------
3682 range_str : str
3718 range_str : str
3683 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3719 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3684 since this function is for use by magic functions which get their
3720 since this function is for use by magic functions which get their
3685 arguments as strings. The number before the / is the session
3721 arguments as strings. The number before the / is the session
3686 number: ~n goes n back from the current session.
3722 number: ~n goes n back from the current session.
3687
3723
3688 If empty string is given, returns history of current session
3724 If empty string is given, returns history of current session
3689 without the last input.
3725 without the last input.
3690
3726
3691 raw : bool, optional
3727 raw : bool, optional
3692 By default, the processed input is used. If this is true, the raw
3728 By default, the processed input is used. If this is true, the raw
3693 input history is used instead.
3729 input history is used instead.
3694
3730
3695 Notes
3731 Notes
3696 -----
3732 -----
3697 Slices can be described with two notations:
3733 Slices can be described with two notations:
3698
3734
3699 * ``N:M`` -> standard python form, means including items N...(M-1).
3735 * ``N:M`` -> standard python form, means including items N...(M-1).
3700 * ``N-M`` -> include items N..M (closed endpoint).
3736 * ``N-M`` -> include items N..M (closed endpoint).
3701 """
3737 """
3702 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3738 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3703 text = "\n".join(x for _, _, x in lines)
3739 text = "\n".join(x for _, _, x in lines)
3704
3740
3705 # Skip the last line, as it's probably the magic that called this
3741 # Skip the last line, as it's probably the magic that called this
3706 if not range_str:
3742 if not range_str:
3707 if "\n" not in text:
3743 if "\n" not in text:
3708 text = ""
3744 text = ""
3709 else:
3745 else:
3710 text = text[: text.rfind("\n")]
3746 text = text[: text.rfind("\n")]
3711
3747
3712 return text
3748 return text
3713
3749
3714 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3750 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
3715 """Get a code string from history, file, url, or a string or macro.
3751 """Get a code string from history, file, url, or a string or macro.
3716
3752
3717 This is mainly used by magic functions.
3753 This is mainly used by magic functions.
3718
3754
3719 Parameters
3755 Parameters
3720 ----------
3756 ----------
3721 target : str
3757 target : str
3722 A string specifying code to retrieve. This will be tried respectively
3758 A string specifying code to retrieve. This will be tried respectively
3723 as: ranges of input history (see %history for syntax), url,
3759 as: ranges of input history (see %history for syntax), url,
3724 corresponding .py file, filename, or an expression evaluating to a
3760 corresponding .py file, filename, or an expression evaluating to a
3725 string or Macro in the user namespace.
3761 string or Macro in the user namespace.
3726
3762
3727 If empty string is given, returns complete history of current
3763 If empty string is given, returns complete history of current
3728 session, without the last line.
3764 session, without the last line.
3729
3765
3730 raw : bool
3766 raw : bool
3731 If true (default), retrieve raw history. Has no effect on the other
3767 If true (default), retrieve raw history. Has no effect on the other
3732 retrieval mechanisms.
3768 retrieval mechanisms.
3733
3769
3734 py_only : bool (default False)
3770 py_only : bool (default False)
3735 Only try to fetch python code, do not try alternative methods to decode file
3771 Only try to fetch python code, do not try alternative methods to decode file
3736 if unicode fails.
3772 if unicode fails.
3737
3773
3738 Returns
3774 Returns
3739 -------
3775 -------
3740 A string of code.
3776 A string of code.
3741 ValueError is raised if nothing is found, and TypeError if it evaluates
3777 ValueError is raised if nothing is found, and TypeError if it evaluates
3742 to an object of another type. In each case, .args[0] is a printable
3778 to an object of another type. In each case, .args[0] is a printable
3743 message.
3779 message.
3744 """
3780 """
3745 code = self.extract_input_lines(target, raw=raw) # Grab history
3781 code = self.extract_input_lines(target, raw=raw) # Grab history
3746 if code:
3782 if code:
3747 return code
3783 return code
3748 try:
3784 try:
3749 if target.startswith(('http://', 'https://')):
3785 if target.startswith(('http://', 'https://')):
3750 return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
3786 return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
3751 except UnicodeDecodeError as e:
3787 except UnicodeDecodeError as e:
3752 if not py_only :
3788 if not py_only :
3753 # Deferred import
3789 # Deferred import
3754 from urllib.request import urlopen
3790 from urllib.request import urlopen
3755 response = urlopen(target)
3791 response = urlopen(target)
3756 return response.read().decode('latin1')
3792 return response.read().decode('latin1')
3757 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3793 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3758
3794
3759 potential_target = [target]
3795 potential_target = [target]
3760 try :
3796 try :
3761 potential_target.insert(0,get_py_filename(target))
3797 potential_target.insert(0,get_py_filename(target))
3762 except IOError:
3798 except IOError:
3763 pass
3799 pass
3764
3800
3765 for tgt in potential_target :
3801 for tgt in potential_target :
3766 if os.path.isfile(tgt): # Read file
3802 if os.path.isfile(tgt): # Read file
3767 try :
3803 try :
3768 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3804 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3769 except UnicodeDecodeError as e:
3805 except UnicodeDecodeError as e:
3770 if not py_only :
3806 if not py_only :
3771 with io_open(tgt,'r', encoding='latin1') as f :
3807 with io_open(tgt,'r', encoding='latin1') as f :
3772 return f.read()
3808 return f.read()
3773 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3809 raise ValueError(("'%s' seem to be unreadable.") % target) from e
3774 elif os.path.isdir(os.path.expanduser(tgt)):
3810 elif os.path.isdir(os.path.expanduser(tgt)):
3775 raise ValueError("'%s' is a directory, not a regular file." % target)
3811 raise ValueError("'%s' is a directory, not a regular file." % target)
3776
3812
3777 if search_ns:
3813 if search_ns:
3778 # Inspect namespace to load object source
3814 # Inspect namespace to load object source
3779 object_info = self.object_inspect(target, detail_level=1)
3815 object_info = self.object_inspect(target, detail_level=1)
3780 if object_info['found'] and object_info['source']:
3816 if object_info['found'] and object_info['source']:
3781 return object_info['source']
3817 return object_info['source']
3782
3818
3783 try: # User namespace
3819 try: # User namespace
3784 codeobj = eval(target, self.user_ns)
3820 codeobj = eval(target, self.user_ns)
3785 except Exception as e:
3821 except Exception as e:
3786 raise ValueError(("'%s' was not found in history, as a file, url, "
3822 raise ValueError(("'%s' was not found in history, as a file, url, "
3787 "nor in the user namespace.") % target) from e
3823 "nor in the user namespace.") % target) from e
3788
3824
3789 if isinstance(codeobj, str):
3825 if isinstance(codeobj, str):
3790 return codeobj
3826 return codeobj
3791 elif isinstance(codeobj, Macro):
3827 elif isinstance(codeobj, Macro):
3792 return codeobj.value
3828 return codeobj.value
3793
3829
3794 raise TypeError("%s is neither a string nor a macro." % target,
3830 raise TypeError("%s is neither a string nor a macro." % target,
3795 codeobj)
3831 codeobj)
3796
3832
3797 def _atexit_once(self):
3833 def _atexit_once(self):
3798 """
3834 """
3799 At exist operation that need to be called at most once.
3835 At exist operation that need to be called at most once.
3800 Second call to this function per instance will do nothing.
3836 Second call to this function per instance will do nothing.
3801 """
3837 """
3802
3838
3803 if not getattr(self, "_atexit_once_called", False):
3839 if not getattr(self, "_atexit_once_called", False):
3804 self._atexit_once_called = True
3840 self._atexit_once_called = True
3805 # Clear all user namespaces to release all references cleanly.
3841 # Clear all user namespaces to release all references cleanly.
3806 self.reset(new_session=False)
3842 self.reset(new_session=False)
3807 # Close the history session (this stores the end time and line count)
3843 # Close the history session (this stores the end time and line count)
3808 # this must be *before* the tempfile cleanup, in case of temporary
3844 # this must be *before* the tempfile cleanup, in case of temporary
3809 # history db
3845 # history db
3810 self.history_manager.end_session()
3846 self.history_manager.end_session()
3811 self.history_manager = None
3847 self.history_manager = None
3812
3848
3813 #-------------------------------------------------------------------------
3849 #-------------------------------------------------------------------------
3814 # Things related to IPython exiting
3850 # Things related to IPython exiting
3815 #-------------------------------------------------------------------------
3851 #-------------------------------------------------------------------------
3816 def atexit_operations(self):
3852 def atexit_operations(self):
3817 """This will be executed at the time of exit.
3853 """This will be executed at the time of exit.
3818
3854
3819 Cleanup operations and saving of persistent data that is done
3855 Cleanup operations and saving of persistent data that is done
3820 unconditionally by IPython should be performed here.
3856 unconditionally by IPython should be performed here.
3821
3857
3822 For things that may depend on startup flags or platform specifics (such
3858 For things that may depend on startup flags or platform specifics (such
3823 as having readline or not), register a separate atexit function in the
3859 as having readline or not), register a separate atexit function in the
3824 code that has the appropriate information, rather than trying to
3860 code that has the appropriate information, rather than trying to
3825 clutter
3861 clutter
3826 """
3862 """
3827 self._atexit_once()
3863 self._atexit_once()
3828
3864
3829 # Cleanup all tempfiles and folders left around
3865 # Cleanup all tempfiles and folders left around
3830 for tfile in self.tempfiles:
3866 for tfile in self.tempfiles:
3831 try:
3867 try:
3832 tfile.unlink()
3868 tfile.unlink()
3833 self.tempfiles.remove(tfile)
3869 self.tempfiles.remove(tfile)
3834 except FileNotFoundError:
3870 except FileNotFoundError:
3835 pass
3871 pass
3836 del self.tempfiles
3872 del self.tempfiles
3837 for tdir in self.tempdirs:
3873 for tdir in self.tempdirs:
3838 try:
3874 try:
3839 tdir.rmdir()
3875 tdir.rmdir()
3840 self.tempdirs.remove(tdir)
3876 self.tempdirs.remove(tdir)
3841 except FileNotFoundError:
3877 except FileNotFoundError:
3842 pass
3878 pass
3843 del self.tempdirs
3879 del self.tempdirs
3844
3880
3845 # Restore user's cursor
3881 # Restore user's cursor
3846 if hasattr(self, "editing_mode") and self.editing_mode == "vi":
3882 if hasattr(self, "editing_mode") and self.editing_mode == "vi":
3847 sys.stdout.write("\x1b[0 q")
3883 sys.stdout.write("\x1b[0 q")
3848 sys.stdout.flush()
3884 sys.stdout.flush()
3849
3885
3850 def cleanup(self):
3886 def cleanup(self):
3851 self.restore_sys_module_state()
3887 self.restore_sys_module_state()
3852
3888
3853
3889
3854 # Overridden in terminal subclass to change prompts
3890 # Overridden in terminal subclass to change prompts
3855 def switch_doctest_mode(self, mode):
3891 def switch_doctest_mode(self, mode):
3856 pass
3892 pass
3857
3893
3858
3894
3859 class InteractiveShellABC(metaclass=abc.ABCMeta):
3895 class InteractiveShellABC(metaclass=abc.ABCMeta):
3860 """An abstract base class for InteractiveShell."""
3896 """An abstract base class for InteractiveShell."""
3861
3897
3862 InteractiveShellABC.register(InteractiveShell)
3898 InteractiveShellABC.register(InteractiveShell)
@@ -1,1080 +1,1093 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tools for inspecting Python objects.
2 """Tools for inspecting Python objects.
3
3
4 Uses syntax highlighting for presenting the various information elements.
4 Uses syntax highlighting for presenting the various information elements.
5
5
6 Similar in spirit to the inspect module, but all calls take a name argument to
6 Similar in spirit to the inspect module, but all calls take a name argument to
7 reference the name under which an object is being read.
7 reference the name under which an object is being read.
8 """
8 """
9
9
10 # Copyright (c) IPython Development Team.
10 # Copyright (c) IPython Development Team.
11 # Distributed under the terms of the Modified BSD License.
11 # Distributed under the terms of the Modified BSD License.
12
12
13 __all__ = ['Inspector','InspectColors']
13 __all__ = ['Inspector','InspectColors']
14
14
15 # stdlib modules
15 # stdlib modules
16 import ast
16 import ast
17 import inspect
17 import inspect
18 from inspect import signature
18 from inspect import signature
19 import html
19 import html
20 import linecache
20 import linecache
21 import warnings
21 import warnings
22 import os
22 import os
23 from textwrap import dedent
23 from textwrap import dedent
24 import types
24 import types
25 import io as stdlib_io
25 import io as stdlib_io
26
26
27 from typing import Union
27 from typing import Union
28
28
29 # IPython's own
29 # IPython's own
30 from IPython.core import page
30 from IPython.core import page
31 from IPython.lib.pretty import pretty
31 from IPython.lib.pretty import pretty
32 from IPython.testing.skipdoctest import skip_doctest
32 from IPython.testing.skipdoctest import skip_doctest
33 from IPython.utils import PyColorize
33 from IPython.utils import PyColorize
34 from IPython.utils import openpy
34 from IPython.utils import openpy
35 from IPython.utils.dir2 import safe_hasattr
35 from IPython.utils.dir2 import safe_hasattr
36 from IPython.utils.path import compress_user
36 from IPython.utils.path import compress_user
37 from IPython.utils.text import indent
37 from IPython.utils.text import indent
38 from IPython.utils.wildcard import list_namespace
38 from IPython.utils.wildcard import list_namespace
39 from IPython.utils.wildcard import typestr2type
39 from IPython.utils.wildcard import typestr2type
40 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
40 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
41 from IPython.utils.py3compat import cast_unicode
41 from IPython.utils.py3compat import cast_unicode
42 from IPython.utils.colorable import Colorable
42 from IPython.utils.colorable import Colorable
43 from IPython.utils.decorators import undoc
43 from IPython.utils.decorators import undoc
44
44
45 from pygments import highlight
45 from pygments import highlight
46 from pygments.lexers import PythonLexer
46 from pygments.lexers import PythonLexer
47 from pygments.formatters import HtmlFormatter
47 from pygments.formatters import HtmlFormatter
48
48
49 from typing import Any
50 from dataclasses import dataclass
51
52
53 @dataclass
54 class OInfo:
55 ismagic: bool
56 isalias: bool
57 found: bool
58 namespace: str
59 parent: Any
60 obj: Any
61
49 def pylight(code):
62 def pylight(code):
50 return highlight(code, PythonLexer(), HtmlFormatter(noclasses=True))
63 return highlight(code, PythonLexer(), HtmlFormatter(noclasses=True))
51
64
52 # builtin docstrings to ignore
65 # builtin docstrings to ignore
53 _func_call_docstring = types.FunctionType.__call__.__doc__
66 _func_call_docstring = types.FunctionType.__call__.__doc__
54 _object_init_docstring = object.__init__.__doc__
67 _object_init_docstring = object.__init__.__doc__
55 _builtin_type_docstrings = {
68 _builtin_type_docstrings = {
56 inspect.getdoc(t) for t in (types.ModuleType, types.MethodType,
69 inspect.getdoc(t) for t in (types.ModuleType, types.MethodType,
57 types.FunctionType, property)
70 types.FunctionType, property)
58 }
71 }
59
72
60 _builtin_func_type = type(all)
73 _builtin_func_type = type(all)
61 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
74 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
62 #****************************************************************************
75 #****************************************************************************
63 # Builtin color schemes
76 # Builtin color schemes
64
77
65 Colors = TermColors # just a shorthand
78 Colors = TermColors # just a shorthand
66
79
67 InspectColors = PyColorize.ANSICodeColors
80 InspectColors = PyColorize.ANSICodeColors
68
81
69 #****************************************************************************
82 #****************************************************************************
70 # Auxiliary functions and objects
83 # Auxiliary functions and objects
71
84
72 # See the messaging spec for the definition of all these fields. This list
85 # See the messaging spec for the definition of all these fields. This list
73 # effectively defines the order of display
86 # effectively defines the order of display
74 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
87 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
75 'length', 'file', 'definition', 'docstring', 'source',
88 'length', 'file', 'definition', 'docstring', 'source',
76 'init_definition', 'class_docstring', 'init_docstring',
89 'init_definition', 'class_docstring', 'init_docstring',
77 'call_def', 'call_docstring',
90 'call_def', 'call_docstring',
78 # These won't be printed but will be used to determine how to
91 # These won't be printed but will be used to determine how to
79 # format the object
92 # format the object
80 'ismagic', 'isalias', 'isclass', 'found', 'name'
93 'ismagic', 'isalias', 'isclass', 'found', 'name'
81 ]
94 ]
82
95
83
96
84 def object_info(**kw):
97 def object_info(**kw):
85 """Make an object info dict with all fields present."""
98 """Make an object info dict with all fields present."""
86 infodict = {k:None for k in info_fields}
99 infodict = {k:None for k in info_fields}
87 infodict.update(kw)
100 infodict.update(kw)
88 return infodict
101 return infodict
89
102
90
103
91 def get_encoding(obj):
104 def get_encoding(obj):
92 """Get encoding for python source file defining obj
105 """Get encoding for python source file defining obj
93
106
94 Returns None if obj is not defined in a sourcefile.
107 Returns None if obj is not defined in a sourcefile.
95 """
108 """
96 ofile = find_file(obj)
109 ofile = find_file(obj)
97 # run contents of file through pager starting at line where the object
110 # run contents of file through pager starting at line where the object
98 # is defined, as long as the file isn't binary and is actually on the
111 # is defined, as long as the file isn't binary and is actually on the
99 # filesystem.
112 # filesystem.
100 if ofile is None:
113 if ofile is None:
101 return None
114 return None
102 elif ofile.endswith(('.so', '.dll', '.pyd')):
115 elif ofile.endswith(('.so', '.dll', '.pyd')):
103 return None
116 return None
104 elif not os.path.isfile(ofile):
117 elif not os.path.isfile(ofile):
105 return None
118 return None
106 else:
119 else:
107 # Print only text files, not extension binaries. Note that
120 # Print only text files, not extension binaries. Note that
108 # getsourcelines returns lineno with 1-offset and page() uses
121 # getsourcelines returns lineno with 1-offset and page() uses
109 # 0-offset, so we must adjust.
122 # 0-offset, so we must adjust.
110 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
123 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
111 encoding, lines = openpy.detect_encoding(buffer.readline)
124 encoding, lines = openpy.detect_encoding(buffer.readline)
112 return encoding
125 return encoding
113
126
114 def getdoc(obj) -> Union[str,None]:
127 def getdoc(obj) -> Union[str,None]:
115 """Stable wrapper around inspect.getdoc.
128 """Stable wrapper around inspect.getdoc.
116
129
117 This can't crash because of attribute problems.
130 This can't crash because of attribute problems.
118
131
119 It also attempts to call a getdoc() method on the given object. This
132 It also attempts to call a getdoc() method on the given object. This
120 allows objects which provide their docstrings via non-standard mechanisms
133 allows objects which provide their docstrings via non-standard mechanisms
121 (like Pyro proxies) to still be inspected by ipython's ? system.
134 (like Pyro proxies) to still be inspected by ipython's ? system.
122 """
135 """
123 # Allow objects to offer customized documentation via a getdoc method:
136 # Allow objects to offer customized documentation via a getdoc method:
124 try:
137 try:
125 ds = obj.getdoc()
138 ds = obj.getdoc()
126 except Exception:
139 except Exception:
127 pass
140 pass
128 else:
141 else:
129 if isinstance(ds, str):
142 if isinstance(ds, str):
130 return inspect.cleandoc(ds)
143 return inspect.cleandoc(ds)
131 docstr = inspect.getdoc(obj)
144 docstr = inspect.getdoc(obj)
132 return docstr
145 return docstr
133
146
134
147
135 def getsource(obj, oname='') -> Union[str,None]:
148 def getsource(obj, oname='') -> Union[str,None]:
136 """Wrapper around inspect.getsource.
149 """Wrapper around inspect.getsource.
137
150
138 This can be modified by other projects to provide customized source
151 This can be modified by other projects to provide customized source
139 extraction.
152 extraction.
140
153
141 Parameters
154 Parameters
142 ----------
155 ----------
143 obj : object
156 obj : object
144 an object whose source code we will attempt to extract
157 an object whose source code we will attempt to extract
145 oname : str
158 oname : str
146 (optional) a name under which the object is known
159 (optional) a name under which the object is known
147
160
148 Returns
161 Returns
149 -------
162 -------
150 src : unicode or None
163 src : unicode or None
151
164
152 """
165 """
153
166
154 if isinstance(obj, property):
167 if isinstance(obj, property):
155 sources = []
168 sources = []
156 for attrname in ['fget', 'fset', 'fdel']:
169 for attrname in ['fget', 'fset', 'fdel']:
157 fn = getattr(obj, attrname)
170 fn = getattr(obj, attrname)
158 if fn is not None:
171 if fn is not None:
159 encoding = get_encoding(fn)
172 encoding = get_encoding(fn)
160 oname_prefix = ('%s.' % oname) if oname else ''
173 oname_prefix = ('%s.' % oname) if oname else ''
161 sources.append(''.join(('# ', oname_prefix, attrname)))
174 sources.append(''.join(('# ', oname_prefix, attrname)))
162 if inspect.isfunction(fn):
175 if inspect.isfunction(fn):
163 sources.append(dedent(getsource(fn)))
176 sources.append(dedent(getsource(fn)))
164 else:
177 else:
165 # Default str/repr only prints function name,
178 # Default str/repr only prints function name,
166 # pretty.pretty prints module name too.
179 # pretty.pretty prints module name too.
167 sources.append(
180 sources.append(
168 '%s%s = %s\n' % (oname_prefix, attrname, pretty(fn))
181 '%s%s = %s\n' % (oname_prefix, attrname, pretty(fn))
169 )
182 )
170 if sources:
183 if sources:
171 return '\n'.join(sources)
184 return '\n'.join(sources)
172 else:
185 else:
173 return None
186 return None
174
187
175 else:
188 else:
176 # Get source for non-property objects.
189 # Get source for non-property objects.
177
190
178 obj = _get_wrapped(obj)
191 obj = _get_wrapped(obj)
179
192
180 try:
193 try:
181 src = inspect.getsource(obj)
194 src = inspect.getsource(obj)
182 except TypeError:
195 except TypeError:
183 # The object itself provided no meaningful source, try looking for
196 # The object itself provided no meaningful source, try looking for
184 # its class definition instead.
197 # its class definition instead.
185 try:
198 try:
186 src = inspect.getsource(obj.__class__)
199 src = inspect.getsource(obj.__class__)
187 except (OSError, TypeError):
200 except (OSError, TypeError):
188 return None
201 return None
189 except OSError:
202 except OSError:
190 return None
203 return None
191
204
192 return src
205 return src
193
206
194
207
195 def is_simple_callable(obj):
208 def is_simple_callable(obj):
196 """True if obj is a function ()"""
209 """True if obj is a function ()"""
197 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
210 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
198 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
211 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
199
212
200 @undoc
213 @undoc
201 def getargspec(obj):
214 def getargspec(obj):
202 """Wrapper around :func:`inspect.getfullargspec`
215 """Wrapper around :func:`inspect.getfullargspec`
203
216
204 In addition to functions and methods, this can also handle objects with a
217 In addition to functions and methods, this can also handle objects with a
205 ``__call__`` attribute.
218 ``__call__`` attribute.
206
219
207 DEPRECATED: Deprecated since 7.10. Do not use, will be removed.
220 DEPRECATED: Deprecated since 7.10. Do not use, will be removed.
208 """
221 """
209
222
210 warnings.warn('`getargspec` function is deprecated as of IPython 7.10'
223 warnings.warn('`getargspec` function is deprecated as of IPython 7.10'
211 'and will be removed in future versions.', DeprecationWarning, stacklevel=2)
224 'and will be removed in future versions.', DeprecationWarning, stacklevel=2)
212
225
213 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
226 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
214 obj = obj.__call__
227 obj = obj.__call__
215
228
216 return inspect.getfullargspec(obj)
229 return inspect.getfullargspec(obj)
217
230
218 @undoc
231 @undoc
219 def format_argspec(argspec):
232 def format_argspec(argspec):
220 """Format argspect, convenience wrapper around inspect's.
233 """Format argspect, convenience wrapper around inspect's.
221
234
222 This takes a dict instead of ordered arguments and calls
235 This takes a dict instead of ordered arguments and calls
223 inspect.format_argspec with the arguments in the necessary order.
236 inspect.format_argspec with the arguments in the necessary order.
224
237
225 DEPRECATED (since 7.10): Do not use; will be removed in future versions.
238 DEPRECATED (since 7.10): Do not use; will be removed in future versions.
226 """
239 """
227
240
228 warnings.warn('`format_argspec` function is deprecated as of IPython 7.10'
241 warnings.warn('`format_argspec` function is deprecated as of IPython 7.10'
229 'and will be removed in future versions.', DeprecationWarning, stacklevel=2)
242 'and will be removed in future versions.', DeprecationWarning, stacklevel=2)
230
243
231
244
232 return inspect.formatargspec(argspec['args'], argspec['varargs'],
245 return inspect.formatargspec(argspec['args'], argspec['varargs'],
233 argspec['varkw'], argspec['defaults'])
246 argspec['varkw'], argspec['defaults'])
234
247
235 @undoc
248 @undoc
236 def call_tip(oinfo, format_call=True):
249 def call_tip(oinfo, format_call=True):
237 """DEPRECATED since 6.0. Extract call tip data from an oinfo dict."""
250 """DEPRECATED since 6.0. Extract call tip data from an oinfo dict."""
238 warnings.warn(
251 warnings.warn(
239 "`call_tip` function is deprecated as of IPython 6.0"
252 "`call_tip` function is deprecated as of IPython 6.0"
240 "and will be removed in future versions.",
253 "and will be removed in future versions.",
241 DeprecationWarning,
254 DeprecationWarning,
242 stacklevel=2,
255 stacklevel=2,
243 )
256 )
244 # Get call definition
257 # Get call definition
245 argspec = oinfo.get('argspec')
258 argspec = oinfo.get('argspec')
246 if argspec is None:
259 if argspec is None:
247 call_line = None
260 call_line = None
248 else:
261 else:
249 # Callable objects will have 'self' as their first argument, prune
262 # Callable objects will have 'self' as their first argument, prune
250 # it out if it's there for clarity (since users do *not* pass an
263 # it out if it's there for clarity (since users do *not* pass an
251 # extra first argument explicitly).
264 # extra first argument explicitly).
252 try:
265 try:
253 has_self = argspec['args'][0] == 'self'
266 has_self = argspec['args'][0] == 'self'
254 except (KeyError, IndexError):
267 except (KeyError, IndexError):
255 pass
268 pass
256 else:
269 else:
257 if has_self:
270 if has_self:
258 argspec['args'] = argspec['args'][1:]
271 argspec['args'] = argspec['args'][1:]
259
272
260 call_line = oinfo['name']+format_argspec(argspec)
273 call_line = oinfo['name']+format_argspec(argspec)
261
274
262 # Now get docstring.
275 # Now get docstring.
263 # The priority is: call docstring, constructor docstring, main one.
276 # The priority is: call docstring, constructor docstring, main one.
264 doc = oinfo.get('call_docstring')
277 doc = oinfo.get('call_docstring')
265 if doc is None:
278 if doc is None:
266 doc = oinfo.get('init_docstring')
279 doc = oinfo.get('init_docstring')
267 if doc is None:
280 if doc is None:
268 doc = oinfo.get('docstring','')
281 doc = oinfo.get('docstring','')
269
282
270 return call_line, doc
283 return call_line, doc
271
284
272
285
273 def _get_wrapped(obj):
286 def _get_wrapped(obj):
274 """Get the original object if wrapped in one or more @decorators
287 """Get the original object if wrapped in one or more @decorators
275
288
276 Some objects automatically construct similar objects on any unrecognised
289 Some objects automatically construct similar objects on any unrecognised
277 attribute access (e.g. unittest.mock.call). To protect against infinite loops,
290 attribute access (e.g. unittest.mock.call). To protect against infinite loops,
278 this will arbitrarily cut off after 100 levels of obj.__wrapped__
291 this will arbitrarily cut off after 100 levels of obj.__wrapped__
279 attribute access. --TK, Jan 2016
292 attribute access. --TK, Jan 2016
280 """
293 """
281 orig_obj = obj
294 orig_obj = obj
282 i = 0
295 i = 0
283 while safe_hasattr(obj, '__wrapped__'):
296 while safe_hasattr(obj, '__wrapped__'):
284 obj = obj.__wrapped__
297 obj = obj.__wrapped__
285 i += 1
298 i += 1
286 if i > 100:
299 if i > 100:
287 # __wrapped__ is probably a lie, so return the thing we started with
300 # __wrapped__ is probably a lie, so return the thing we started with
288 return orig_obj
301 return orig_obj
289 return obj
302 return obj
290
303
291 def find_file(obj) -> str:
304 def find_file(obj) -> str:
292 """Find the absolute path to the file where an object was defined.
305 """Find the absolute path to the file where an object was defined.
293
306
294 This is essentially a robust wrapper around `inspect.getabsfile`.
307 This is essentially a robust wrapper around `inspect.getabsfile`.
295
308
296 Returns None if no file can be found.
309 Returns None if no file can be found.
297
310
298 Parameters
311 Parameters
299 ----------
312 ----------
300 obj : any Python object
313 obj : any Python object
301
314
302 Returns
315 Returns
303 -------
316 -------
304 fname : str
317 fname : str
305 The absolute path to the file where the object was defined.
318 The absolute path to the file where the object was defined.
306 """
319 """
307 obj = _get_wrapped(obj)
320 obj = _get_wrapped(obj)
308
321
309 fname = None
322 fname = None
310 try:
323 try:
311 fname = inspect.getabsfile(obj)
324 fname = inspect.getabsfile(obj)
312 except TypeError:
325 except TypeError:
313 # For an instance, the file that matters is where its class was
326 # For an instance, the file that matters is where its class was
314 # declared.
327 # declared.
315 try:
328 try:
316 fname = inspect.getabsfile(obj.__class__)
329 fname = inspect.getabsfile(obj.__class__)
317 except (OSError, TypeError):
330 except (OSError, TypeError):
318 # Can happen for builtins
331 # Can happen for builtins
319 pass
332 pass
320 except OSError:
333 except OSError:
321 pass
334 pass
322
335
323 return cast_unicode(fname)
336 return cast_unicode(fname)
324
337
325
338
326 def find_source_lines(obj):
339 def find_source_lines(obj):
327 """Find the line number in a file where an object was defined.
340 """Find the line number in a file where an object was defined.
328
341
329 This is essentially a robust wrapper around `inspect.getsourcelines`.
342 This is essentially a robust wrapper around `inspect.getsourcelines`.
330
343
331 Returns None if no file can be found.
344 Returns None if no file can be found.
332
345
333 Parameters
346 Parameters
334 ----------
347 ----------
335 obj : any Python object
348 obj : any Python object
336
349
337 Returns
350 Returns
338 -------
351 -------
339 lineno : int
352 lineno : int
340 The line number where the object definition starts.
353 The line number where the object definition starts.
341 """
354 """
342 obj = _get_wrapped(obj)
355 obj = _get_wrapped(obj)
343
356
344 try:
357 try:
345 lineno = inspect.getsourcelines(obj)[1]
358 lineno = inspect.getsourcelines(obj)[1]
346 except TypeError:
359 except TypeError:
347 # For instances, try the class object like getsource() does
360 # For instances, try the class object like getsource() does
348 try:
361 try:
349 lineno = inspect.getsourcelines(obj.__class__)[1]
362 lineno = inspect.getsourcelines(obj.__class__)[1]
350 except (OSError, TypeError):
363 except (OSError, TypeError):
351 return None
364 return None
352 except OSError:
365 except OSError:
353 return None
366 return None
354
367
355 return lineno
368 return lineno
356
369
357 class Inspector(Colorable):
370 class Inspector(Colorable):
358
371
359 def __init__(self, color_table=InspectColors,
372 def __init__(self, color_table=InspectColors,
360 code_color_table=PyColorize.ANSICodeColors,
373 code_color_table=PyColorize.ANSICodeColors,
361 scheme=None,
374 scheme=None,
362 str_detail_level=0,
375 str_detail_level=0,
363 parent=None, config=None):
376 parent=None, config=None):
364 super(Inspector, self).__init__(parent=parent, config=config)
377 super(Inspector, self).__init__(parent=parent, config=config)
365 self.color_table = color_table
378 self.color_table = color_table
366 self.parser = PyColorize.Parser(out='str', parent=self, style=scheme)
379 self.parser = PyColorize.Parser(out='str', parent=self, style=scheme)
367 self.format = self.parser.format
380 self.format = self.parser.format
368 self.str_detail_level = str_detail_level
381 self.str_detail_level = str_detail_level
369 self.set_active_scheme(scheme)
382 self.set_active_scheme(scheme)
370
383
371 def _getdef(self,obj,oname='') -> Union[str,None]:
384 def _getdef(self,obj,oname='') -> Union[str,None]:
372 """Return the call signature for any callable object.
385 """Return the call signature for any callable object.
373
386
374 If any exception is generated, None is returned instead and the
387 If any exception is generated, None is returned instead and the
375 exception is suppressed."""
388 exception is suppressed."""
376 try:
389 try:
377 return _render_signature(signature(obj), oname)
390 return _render_signature(signature(obj), oname)
378 except:
391 except:
379 return None
392 return None
380
393
381 def __head(self,h) -> str:
394 def __head(self,h) -> str:
382 """Return a header string with proper colors."""
395 """Return a header string with proper colors."""
383 return '%s%s%s' % (self.color_table.active_colors.header,h,
396 return '%s%s%s' % (self.color_table.active_colors.header,h,
384 self.color_table.active_colors.normal)
397 self.color_table.active_colors.normal)
385
398
386 def set_active_scheme(self, scheme):
399 def set_active_scheme(self, scheme):
387 if scheme is not None:
400 if scheme is not None:
388 self.color_table.set_active_scheme(scheme)
401 self.color_table.set_active_scheme(scheme)
389 self.parser.color_table.set_active_scheme(scheme)
402 self.parser.color_table.set_active_scheme(scheme)
390
403
391 def noinfo(self, msg, oname):
404 def noinfo(self, msg, oname):
392 """Generic message when no information is found."""
405 """Generic message when no information is found."""
393 print('No %s found' % msg, end=' ')
406 print('No %s found' % msg, end=' ')
394 if oname:
407 if oname:
395 print('for %s' % oname)
408 print('for %s' % oname)
396 else:
409 else:
397 print()
410 print()
398
411
399 def pdef(self, obj, oname=''):
412 def pdef(self, obj, oname=''):
400 """Print the call signature for any callable object.
413 """Print the call signature for any callable object.
401
414
402 If the object is a class, print the constructor information."""
415 If the object is a class, print the constructor information."""
403
416
404 if not callable(obj):
417 if not callable(obj):
405 print('Object is not callable.')
418 print('Object is not callable.')
406 return
419 return
407
420
408 header = ''
421 header = ''
409
422
410 if inspect.isclass(obj):
423 if inspect.isclass(obj):
411 header = self.__head('Class constructor information:\n')
424 header = self.__head('Class constructor information:\n')
412
425
413
426
414 output = self._getdef(obj,oname)
427 output = self._getdef(obj,oname)
415 if output is None:
428 if output is None:
416 self.noinfo('definition header',oname)
429 self.noinfo('definition header',oname)
417 else:
430 else:
418 print(header,self.format(output), end=' ')
431 print(header,self.format(output), end=' ')
419
432
420 # In Python 3, all classes are new-style, so they all have __init__.
433 # In Python 3, all classes are new-style, so they all have __init__.
421 @skip_doctest
434 @skip_doctest
422 def pdoc(self, obj, oname='', formatter=None):
435 def pdoc(self, obj, oname='', formatter=None):
423 """Print the docstring for any object.
436 """Print the docstring for any object.
424
437
425 Optional:
438 Optional:
426 -formatter: a function to run the docstring through for specially
439 -formatter: a function to run the docstring through for specially
427 formatted docstrings.
440 formatted docstrings.
428
441
429 Examples
442 Examples
430 --------
443 --------
431 In [1]: class NoInit:
444 In [1]: class NoInit:
432 ...: pass
445 ...: pass
433
446
434 In [2]: class NoDoc:
447 In [2]: class NoDoc:
435 ...: def __init__(self):
448 ...: def __init__(self):
436 ...: pass
449 ...: pass
437
450
438 In [3]: %pdoc NoDoc
451 In [3]: %pdoc NoDoc
439 No documentation found for NoDoc
452 No documentation found for NoDoc
440
453
441 In [4]: %pdoc NoInit
454 In [4]: %pdoc NoInit
442 No documentation found for NoInit
455 No documentation found for NoInit
443
456
444 In [5]: obj = NoInit()
457 In [5]: obj = NoInit()
445
458
446 In [6]: %pdoc obj
459 In [6]: %pdoc obj
447 No documentation found for obj
460 No documentation found for obj
448
461
449 In [5]: obj2 = NoDoc()
462 In [5]: obj2 = NoDoc()
450
463
451 In [6]: %pdoc obj2
464 In [6]: %pdoc obj2
452 No documentation found for obj2
465 No documentation found for obj2
453 """
466 """
454
467
455 head = self.__head # For convenience
468 head = self.__head # For convenience
456 lines = []
469 lines = []
457 ds = getdoc(obj)
470 ds = getdoc(obj)
458 if formatter:
471 if formatter:
459 ds = formatter(ds).get('plain/text', ds)
472 ds = formatter(ds).get('plain/text', ds)
460 if ds:
473 if ds:
461 lines.append(head("Class docstring:"))
474 lines.append(head("Class docstring:"))
462 lines.append(indent(ds))
475 lines.append(indent(ds))
463 if inspect.isclass(obj) and hasattr(obj, '__init__'):
476 if inspect.isclass(obj) and hasattr(obj, '__init__'):
464 init_ds = getdoc(obj.__init__)
477 init_ds = getdoc(obj.__init__)
465 if init_ds is not None:
478 if init_ds is not None:
466 lines.append(head("Init docstring:"))
479 lines.append(head("Init docstring:"))
467 lines.append(indent(init_ds))
480 lines.append(indent(init_ds))
468 elif hasattr(obj,'__call__'):
481 elif hasattr(obj,'__call__'):
469 call_ds = getdoc(obj.__call__)
482 call_ds = getdoc(obj.__call__)
470 if call_ds:
483 if call_ds:
471 lines.append(head("Call docstring:"))
484 lines.append(head("Call docstring:"))
472 lines.append(indent(call_ds))
485 lines.append(indent(call_ds))
473
486
474 if not lines:
487 if not lines:
475 self.noinfo('documentation',oname)
488 self.noinfo('documentation',oname)
476 else:
489 else:
477 page.page('\n'.join(lines))
490 page.page('\n'.join(lines))
478
491
479 def psource(self, obj, oname=''):
492 def psource(self, obj, oname=''):
480 """Print the source code for an object."""
493 """Print the source code for an object."""
481
494
482 # Flush the source cache because inspect can return out-of-date source
495 # Flush the source cache because inspect can return out-of-date source
483 linecache.checkcache()
496 linecache.checkcache()
484 try:
497 try:
485 src = getsource(obj, oname=oname)
498 src = getsource(obj, oname=oname)
486 except Exception:
499 except Exception:
487 src = None
500 src = None
488
501
489 if src is None:
502 if src is None:
490 self.noinfo('source', oname)
503 self.noinfo('source', oname)
491 else:
504 else:
492 page.page(self.format(src))
505 page.page(self.format(src))
493
506
494 def pfile(self, obj, oname=''):
507 def pfile(self, obj, oname=''):
495 """Show the whole file where an object was defined."""
508 """Show the whole file where an object was defined."""
496
509
497 lineno = find_source_lines(obj)
510 lineno = find_source_lines(obj)
498 if lineno is None:
511 if lineno is None:
499 self.noinfo('file', oname)
512 self.noinfo('file', oname)
500 return
513 return
501
514
502 ofile = find_file(obj)
515 ofile = find_file(obj)
503 # run contents of file through pager starting at line where the object
516 # run contents of file through pager starting at line where the object
504 # is defined, as long as the file isn't binary and is actually on the
517 # is defined, as long as the file isn't binary and is actually on the
505 # filesystem.
518 # filesystem.
506 if ofile.endswith(('.so', '.dll', '.pyd')):
519 if ofile.endswith(('.so', '.dll', '.pyd')):
507 print('File %r is binary, not printing.' % ofile)
520 print('File %r is binary, not printing.' % ofile)
508 elif not os.path.isfile(ofile):
521 elif not os.path.isfile(ofile):
509 print('File %r does not exist, not printing.' % ofile)
522 print('File %r does not exist, not printing.' % ofile)
510 else:
523 else:
511 # Print only text files, not extension binaries. Note that
524 # Print only text files, not extension binaries. Note that
512 # getsourcelines returns lineno with 1-offset and page() uses
525 # getsourcelines returns lineno with 1-offset and page() uses
513 # 0-offset, so we must adjust.
526 # 0-offset, so we must adjust.
514 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
527 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
515
528
516
529
517 def _mime_format(self, text:str, formatter=None) -> dict:
530 def _mime_format(self, text:str, formatter=None) -> dict:
518 """Return a mime bundle representation of the input text.
531 """Return a mime bundle representation of the input text.
519
532
520 - if `formatter` is None, the returned mime bundle has
533 - if `formatter` is None, the returned mime bundle has
521 a ``text/plain`` field, with the input text.
534 a ``text/plain`` field, with the input text.
522 a ``text/html`` field with a ``<pre>`` tag containing the input text.
535 a ``text/html`` field with a ``<pre>`` tag containing the input text.
523
536
524 - if ``formatter`` is not None, it must be a callable transforming the
537 - if ``formatter`` is not None, it must be a callable transforming the
525 input text into a mime bundle. Default values for ``text/plain`` and
538 input text into a mime bundle. Default values for ``text/plain`` and
526 ``text/html`` representations are the ones described above.
539 ``text/html`` representations are the ones described above.
527
540
528 Note:
541 Note:
529
542
530 Formatters returning strings are supported but this behavior is deprecated.
543 Formatters returning strings are supported but this behavior is deprecated.
531
544
532 """
545 """
533 defaults = {
546 defaults = {
534 "text/plain": text,
547 "text/plain": text,
535 "text/html": f"<pre>{html.escape(text)}</pre>",
548 "text/html": f"<pre>{html.escape(text)}</pre>",
536 }
549 }
537
550
538 if formatter is None:
551 if formatter is None:
539 return defaults
552 return defaults
540 else:
553 else:
541 formatted = formatter(text)
554 formatted = formatter(text)
542
555
543 if not isinstance(formatted, dict):
556 if not isinstance(formatted, dict):
544 # Handle the deprecated behavior of a formatter returning
557 # Handle the deprecated behavior of a formatter returning
545 # a string instead of a mime bundle.
558 # a string instead of a mime bundle.
546 return {"text/plain": formatted, "text/html": f"<pre>{formatted}</pre>"}
559 return {"text/plain": formatted, "text/html": f"<pre>{formatted}</pre>"}
547
560
548 else:
561 else:
549 return dict(defaults, **formatted)
562 return dict(defaults, **formatted)
550
563
551
564
552 def format_mime(self, bundle):
565 def format_mime(self, bundle):
553 """Format a mimebundle being created by _make_info_unformatted into a real mimebundle"""
566 """Format a mimebundle being created by _make_info_unformatted into a real mimebundle"""
554 # Format text/plain mimetype
567 # Format text/plain mimetype
555 if isinstance(bundle["text/plain"], (list, tuple)):
568 if isinstance(bundle["text/plain"], (list, tuple)):
556 # bundle['text/plain'] is a list of (head, formatted body) pairs
569 # bundle['text/plain'] is a list of (head, formatted body) pairs
557 lines = []
570 lines = []
558 _len = max(len(h) for h, _ in bundle["text/plain"])
571 _len = max(len(h) for h, _ in bundle["text/plain"])
559
572
560 for head, body in bundle["text/plain"]:
573 for head, body in bundle["text/plain"]:
561 body = body.strip("\n")
574 body = body.strip("\n")
562 delim = "\n" if "\n" in body else " "
575 delim = "\n" if "\n" in body else " "
563 lines.append(
576 lines.append(
564 f"{self.__head(head+':')}{(_len - len(head))*' '}{delim}{body}"
577 f"{self.__head(head+':')}{(_len - len(head))*' '}{delim}{body}"
565 )
578 )
566
579
567 bundle["text/plain"] = "\n".join(lines)
580 bundle["text/plain"] = "\n".join(lines)
568
581
569 # Format the text/html mimetype
582 # Format the text/html mimetype
570 if isinstance(bundle["text/html"], (list, tuple)):
583 if isinstance(bundle["text/html"], (list, tuple)):
571 # bundle['text/html'] is a list of (head, formatted body) pairs
584 # bundle['text/html'] is a list of (head, formatted body) pairs
572 bundle["text/html"] = "\n".join(
585 bundle["text/html"] = "\n".join(
573 (f"<h1>{head}</h1>\n{body}" for (head, body) in bundle["text/html"])
586 (f"<h1>{head}</h1>\n{body}" for (head, body) in bundle["text/html"])
574 )
587 )
575 return bundle
588 return bundle
576
589
577 def _append_info_field(
590 def _append_info_field(
578 self, bundle, title: str, key: str, info, omit_sections, formatter
591 self, bundle, title: str, key: str, info, omit_sections, formatter
579 ):
592 ):
580 """Append an info value to the unformatted mimebundle being constructed by _make_info_unformatted"""
593 """Append an info value to the unformatted mimebundle being constructed by _make_info_unformatted"""
581 if title in omit_sections or key in omit_sections:
594 if title in omit_sections or key in omit_sections:
582 return
595 return
583 field = info[key]
596 field = info[key]
584 if field is not None:
597 if field is not None:
585 formatted_field = self._mime_format(field, formatter)
598 formatted_field = self._mime_format(field, formatter)
586 bundle["text/plain"].append((title, formatted_field["text/plain"]))
599 bundle["text/plain"].append((title, formatted_field["text/plain"]))
587 bundle["text/html"].append((title, formatted_field["text/html"]))
600 bundle["text/html"].append((title, formatted_field["text/html"]))
588
601
589 def _make_info_unformatted(self, obj, info, formatter, detail_level, omit_sections):
602 def _make_info_unformatted(self, obj, info, formatter, detail_level, omit_sections):
590 """Assemble the mimebundle as unformatted lists of information"""
603 """Assemble the mimebundle as unformatted lists of information"""
591 bundle = {
604 bundle = {
592 "text/plain": [],
605 "text/plain": [],
593 "text/html": [],
606 "text/html": [],
594 }
607 }
595
608
596 # A convenience function to simplify calls below
609 # A convenience function to simplify calls below
597 def append_field(bundle, title: str, key: str, formatter=None):
610 def append_field(bundle, title: str, key: str, formatter=None):
598 self._append_info_field(
611 self._append_info_field(
599 bundle,
612 bundle,
600 title=title,
613 title=title,
601 key=key,
614 key=key,
602 info=info,
615 info=info,
603 omit_sections=omit_sections,
616 omit_sections=omit_sections,
604 formatter=formatter,
617 formatter=formatter,
605 )
618 )
606
619
607 def code_formatter(text):
620 def code_formatter(text):
608 return {
621 return {
609 'text/plain': self.format(text),
622 'text/plain': self.format(text),
610 'text/html': pylight(text)
623 'text/html': pylight(text)
611 }
624 }
612
625
613 if info["isalias"]:
626 if info["isalias"]:
614 append_field(bundle, "Repr", "string_form")
627 append_field(bundle, "Repr", "string_form")
615
628
616 elif info['ismagic']:
629 elif info['ismagic']:
617 if detail_level > 0:
630 if detail_level > 0:
618 append_field(bundle, "Source", "source", code_formatter)
631 append_field(bundle, "Source", "source", code_formatter)
619 else:
632 else:
620 append_field(bundle, "Docstring", "docstring", formatter)
633 append_field(bundle, "Docstring", "docstring", formatter)
621 append_field(bundle, "File", "file")
634 append_field(bundle, "File", "file")
622
635
623 elif info['isclass'] or is_simple_callable(obj):
636 elif info['isclass'] or is_simple_callable(obj):
624 # Functions, methods, classes
637 # Functions, methods, classes
625 append_field(bundle, "Signature", "definition", code_formatter)
638 append_field(bundle, "Signature", "definition", code_formatter)
626 append_field(bundle, "Init signature", "init_definition", code_formatter)
639 append_field(bundle, "Init signature", "init_definition", code_formatter)
627 append_field(bundle, "Docstring", "docstring", formatter)
640 append_field(bundle, "Docstring", "docstring", formatter)
628 if detail_level > 0 and info["source"]:
641 if detail_level > 0 and info["source"]:
629 append_field(bundle, "Source", "source", code_formatter)
642 append_field(bundle, "Source", "source", code_formatter)
630 else:
643 else:
631 append_field(bundle, "Init docstring", "init_docstring", formatter)
644 append_field(bundle, "Init docstring", "init_docstring", formatter)
632
645
633 append_field(bundle, "File", "file")
646 append_field(bundle, "File", "file")
634 append_field(bundle, "Type", "type_name")
647 append_field(bundle, "Type", "type_name")
635 append_field(bundle, "Subclasses", "subclasses")
648 append_field(bundle, "Subclasses", "subclasses")
636
649
637 else:
650 else:
638 # General Python objects
651 # General Python objects
639 append_field(bundle, "Signature", "definition", code_formatter)
652 append_field(bundle, "Signature", "definition", code_formatter)
640 append_field(bundle, "Call signature", "call_def", code_formatter)
653 append_field(bundle, "Call signature", "call_def", code_formatter)
641 append_field(bundle, "Type", "type_name")
654 append_field(bundle, "Type", "type_name")
642 append_field(bundle, "String form", "string_form")
655 append_field(bundle, "String form", "string_form")
643
656
644 # Namespace
657 # Namespace
645 if info["namespace"] != "Interactive":
658 if info["namespace"] != "Interactive":
646 append_field(bundle, "Namespace", "namespace")
659 append_field(bundle, "Namespace", "namespace")
647
660
648 append_field(bundle, "Length", "length")
661 append_field(bundle, "Length", "length")
649 append_field(bundle, "File", "file")
662 append_field(bundle, "File", "file")
650
663
651 # Source or docstring, depending on detail level and whether
664 # Source or docstring, depending on detail level and whether
652 # source found.
665 # source found.
653 if detail_level > 0 and info["source"]:
666 if detail_level > 0 and info["source"]:
654 append_field(bundle, "Source", "source", code_formatter)
667 append_field(bundle, "Source", "source", code_formatter)
655 else:
668 else:
656 append_field(bundle, "Docstring", "docstring", formatter)
669 append_field(bundle, "Docstring", "docstring", formatter)
657
670
658 append_field(bundle, "Class docstring", "class_docstring", formatter)
671 append_field(bundle, "Class docstring", "class_docstring", formatter)
659 append_field(bundle, "Init docstring", "init_docstring", formatter)
672 append_field(bundle, "Init docstring", "init_docstring", formatter)
660 append_field(bundle, "Call docstring", "call_docstring", formatter)
673 append_field(bundle, "Call docstring", "call_docstring", formatter)
661 return bundle
674 return bundle
662
675
663
676
664 def _get_info(
677 def _get_info(
665 self, obj, oname="", formatter=None, info=None, detail_level=0, omit_sections=()
678 self, obj, oname="", formatter=None, info=None, detail_level=0, omit_sections=()
666 ):
679 ):
667 """Retrieve an info dict and format it.
680 """Retrieve an info dict and format it.
668
681
669 Parameters
682 Parameters
670 ----------
683 ----------
671 obj : any
684 obj : any
672 Object to inspect and return info from
685 Object to inspect and return info from
673 oname : str (default: ''):
686 oname : str (default: ''):
674 Name of the variable pointing to `obj`.
687 Name of the variable pointing to `obj`.
675 formatter : callable
688 formatter : callable
676 info
689 info
677 already computed information
690 already computed information
678 detail_level : integer
691 detail_level : integer
679 Granularity of detail level, if set to 1, give more information.
692 Granularity of detail level, if set to 1, give more information.
680 omit_sections : container[str]
693 omit_sections : container[str]
681 Titles or keys to omit from output (can be set, tuple, etc., anything supporting `in`)
694 Titles or keys to omit from output (can be set, tuple, etc., anything supporting `in`)
682 """
695 """
683
696
684 info = self.info(obj, oname=oname, info=info, detail_level=detail_level)
697 info = self.info(obj, oname=oname, info=info, detail_level=detail_level)
685 bundle = self._make_info_unformatted(
698 bundle = self._make_info_unformatted(
686 obj, info, formatter, detail_level=detail_level, omit_sections=omit_sections
699 obj, info, formatter, detail_level=detail_level, omit_sections=omit_sections
687 )
700 )
688 return self.format_mime(bundle)
701 return self.format_mime(bundle)
689
702
690 def pinfo(
703 def pinfo(
691 self,
704 self,
692 obj,
705 obj,
693 oname="",
706 oname="",
694 formatter=None,
707 formatter=None,
695 info=None,
708 info=None,
696 detail_level=0,
709 detail_level=0,
697 enable_html_pager=True,
710 enable_html_pager=True,
698 omit_sections=(),
711 omit_sections=(),
699 ):
712 ):
700 """Show detailed information about an object.
713 """Show detailed information about an object.
701
714
702 Optional arguments:
715 Optional arguments:
703
716
704 - oname: name of the variable pointing to the object.
717 - oname: name of the variable pointing to the object.
705
718
706 - formatter: callable (optional)
719 - formatter: callable (optional)
707 A special formatter for docstrings.
720 A special formatter for docstrings.
708
721
709 The formatter is a callable that takes a string as an input
722 The formatter is a callable that takes a string as an input
710 and returns either a formatted string or a mime type bundle
723 and returns either a formatted string or a mime type bundle
711 in the form of a dictionary.
724 in the form of a dictionary.
712
725
713 Although the support of custom formatter returning a string
726 Although the support of custom formatter returning a string
714 instead of a mime type bundle is deprecated.
727 instead of a mime type bundle is deprecated.
715
728
716 - info: a structure with some information fields which may have been
729 - info: a structure with some information fields which may have been
717 precomputed already.
730 precomputed already.
718
731
719 - detail_level: if set to 1, more information is given.
732 - detail_level: if set to 1, more information is given.
720
733
721 - omit_sections: set of section keys and titles to omit
734 - omit_sections: set of section keys and titles to omit
722 """
735 """
723 info = self._get_info(
736 info = self._get_info(
724 obj, oname, formatter, info, detail_level, omit_sections=omit_sections
737 obj, oname, formatter, info, detail_level, omit_sections=omit_sections
725 )
738 )
726 if not enable_html_pager:
739 if not enable_html_pager:
727 del info['text/html']
740 del info['text/html']
728 page.page(info)
741 page.page(info)
729
742
730 def _info(self, obj, oname="", info=None, detail_level=0):
743 def _info(self, obj, oname="", info=None, detail_level=0):
731 """
744 """
732 Inspector.info() was likely improperly marked as deprecated
745 Inspector.info() was likely improperly marked as deprecated
733 while only a parameter was deprecated. We "un-deprecate" it.
746 while only a parameter was deprecated. We "un-deprecate" it.
734 """
747 """
735
748
736 warnings.warn(
749 warnings.warn(
737 "The `Inspector.info()` method has been un-deprecated as of 8.0 "
750 "The `Inspector.info()` method has been un-deprecated as of 8.0 "
738 "and the `formatter=` keyword removed. `Inspector._info` is now "
751 "and the `formatter=` keyword removed. `Inspector._info` is now "
739 "an alias, and you can just call `.info()` directly.",
752 "an alias, and you can just call `.info()` directly.",
740 DeprecationWarning,
753 DeprecationWarning,
741 stacklevel=2,
754 stacklevel=2,
742 )
755 )
743 return self.info(obj, oname=oname, info=info, detail_level=detail_level)
756 return self.info(obj, oname=oname, info=info, detail_level=detail_level)
744
757
745 def info(self, obj, oname="", info=None, detail_level=0) -> dict:
758 def info(self, obj, oname="", info=None, detail_level=0) -> dict:
746 """Compute a dict with detailed information about an object.
759 """Compute a dict with detailed information about an object.
747
760
748 Parameters
761 Parameters
749 ----------
762 ----------
750 obj : any
763 obj : any
751 An object to find information about
764 An object to find information about
752 oname : str (default: '')
765 oname : str (default: '')
753 Name of the variable pointing to `obj`.
766 Name of the variable pointing to `obj`.
754 info : (default: None)
767 info : (default: None)
755 A struct (dict like with attr access) with some information fields
768 A struct (dict like with attr access) with some information fields
756 which may have been precomputed already.
769 which may have been precomputed already.
757 detail_level : int (default:0)
770 detail_level : int (default:0)
758 If set to 1, more information is given.
771 If set to 1, more information is given.
759
772
760 Returns
773 Returns
761 -------
774 -------
762 An object info dict with known fields from `info_fields`. Keys are
775 An object info dict with known fields from `info_fields`. Keys are
763 strings, values are string or None.
776 strings, values are string or None.
764 """
777 """
765
778
766 if info is None:
779 if info is None:
767 ismagic = False
780 ismagic = False
768 isalias = False
781 isalias = False
769 ospace = ''
782 ospace = ''
770 else:
783 else:
771 ismagic = info.ismagic
784 ismagic = info.ismagic
772 isalias = info.isalias
785 isalias = info.isalias
773 ospace = info.namespace
786 ospace = info.namespace
774
787
775 # Get docstring, special-casing aliases:
788 # Get docstring, special-casing aliases:
776 if isalias:
789 if isalias:
777 if not callable(obj):
790 if not callable(obj):
778 try:
791 try:
779 ds = "Alias to the system command:\n %s" % obj[1]
792 ds = "Alias to the system command:\n %s" % obj[1]
780 except:
793 except:
781 ds = "Alias: " + str(obj)
794 ds = "Alias: " + str(obj)
782 else:
795 else:
783 ds = "Alias to " + str(obj)
796 ds = "Alias to " + str(obj)
784 if obj.__doc__:
797 if obj.__doc__:
785 ds += "\nDocstring:\n" + obj.__doc__
798 ds += "\nDocstring:\n" + obj.__doc__
786 else:
799 else:
787 ds = getdoc(obj)
800 ds = getdoc(obj)
788 if ds is None:
801 if ds is None:
789 ds = '<no docstring>'
802 ds = '<no docstring>'
790
803
791 # store output in a dict, we initialize it here and fill it as we go
804 # store output in a dict, we initialize it here and fill it as we go
792 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic, subclasses=None)
805 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic, subclasses=None)
793
806
794 string_max = 200 # max size of strings to show (snipped if longer)
807 string_max = 200 # max size of strings to show (snipped if longer)
795 shalf = int((string_max - 5) / 2)
808 shalf = int((string_max - 5) / 2)
796
809
797 if ismagic:
810 if ismagic:
798 out['type_name'] = 'Magic function'
811 out['type_name'] = 'Magic function'
799 elif isalias:
812 elif isalias:
800 out['type_name'] = 'System alias'
813 out['type_name'] = 'System alias'
801 else:
814 else:
802 out['type_name'] = type(obj).__name__
815 out['type_name'] = type(obj).__name__
803
816
804 try:
817 try:
805 bclass = obj.__class__
818 bclass = obj.__class__
806 out['base_class'] = str(bclass)
819 out['base_class'] = str(bclass)
807 except:
820 except:
808 pass
821 pass
809
822
810 # String form, but snip if too long in ? form (full in ??)
823 # String form, but snip if too long in ? form (full in ??)
811 if detail_level >= self.str_detail_level:
824 if detail_level >= self.str_detail_level:
812 try:
825 try:
813 ostr = str(obj)
826 ostr = str(obj)
814 str_head = 'string_form'
827 str_head = 'string_form'
815 if not detail_level and len(ostr)>string_max:
828 if not detail_level and len(ostr)>string_max:
816 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
829 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
817 ostr = ("\n" + " " * len(str_head.expandtabs())).\
830 ostr = ("\n" + " " * len(str_head.expandtabs())).\
818 join(q.strip() for q in ostr.split("\n"))
831 join(q.strip() for q in ostr.split("\n"))
819 out[str_head] = ostr
832 out[str_head] = ostr
820 except:
833 except:
821 pass
834 pass
822
835
823 if ospace:
836 if ospace:
824 out['namespace'] = ospace
837 out['namespace'] = ospace
825
838
826 # Length (for strings and lists)
839 # Length (for strings and lists)
827 try:
840 try:
828 out['length'] = str(len(obj))
841 out['length'] = str(len(obj))
829 except Exception:
842 except Exception:
830 pass
843 pass
831
844
832 # Filename where object was defined
845 # Filename where object was defined
833 binary_file = False
846 binary_file = False
834 fname = find_file(obj)
847 fname = find_file(obj)
835 if fname is None:
848 if fname is None:
836 # if anything goes wrong, we don't want to show source, so it's as
849 # if anything goes wrong, we don't want to show source, so it's as
837 # if the file was binary
850 # if the file was binary
838 binary_file = True
851 binary_file = True
839 else:
852 else:
840 if fname.endswith(('.so', '.dll', '.pyd')):
853 if fname.endswith(('.so', '.dll', '.pyd')):
841 binary_file = True
854 binary_file = True
842 elif fname.endswith('<string>'):
855 elif fname.endswith('<string>'):
843 fname = 'Dynamically generated function. No source code available.'
856 fname = 'Dynamically generated function. No source code available.'
844 out['file'] = compress_user(fname)
857 out['file'] = compress_user(fname)
845
858
846 # Original source code for a callable, class or property.
859 # Original source code for a callable, class or property.
847 if detail_level:
860 if detail_level:
848 # Flush the source cache because inspect can return out-of-date
861 # Flush the source cache because inspect can return out-of-date
849 # source
862 # source
850 linecache.checkcache()
863 linecache.checkcache()
851 try:
864 try:
852 if isinstance(obj, property) or not binary_file:
865 if isinstance(obj, property) or not binary_file:
853 src = getsource(obj, oname)
866 src = getsource(obj, oname)
854 if src is not None:
867 if src is not None:
855 src = src.rstrip()
868 src = src.rstrip()
856 out['source'] = src
869 out['source'] = src
857
870
858 except Exception:
871 except Exception:
859 pass
872 pass
860
873
861 # Add docstring only if no source is to be shown (avoid repetitions).
874 # Add docstring only if no source is to be shown (avoid repetitions).
862 if ds and not self._source_contains_docstring(out.get('source'), ds):
875 if ds and not self._source_contains_docstring(out.get('source'), ds):
863 out['docstring'] = ds
876 out['docstring'] = ds
864
877
865 # Constructor docstring for classes
878 # Constructor docstring for classes
866 if inspect.isclass(obj):
879 if inspect.isclass(obj):
867 out['isclass'] = True
880 out['isclass'] = True
868
881
869 # get the init signature:
882 # get the init signature:
870 try:
883 try:
871 init_def = self._getdef(obj, oname)
884 init_def = self._getdef(obj, oname)
872 except AttributeError:
885 except AttributeError:
873 init_def = None
886 init_def = None
874
887
875 # get the __init__ docstring
888 # get the __init__ docstring
876 try:
889 try:
877 obj_init = obj.__init__
890 obj_init = obj.__init__
878 except AttributeError:
891 except AttributeError:
879 init_ds = None
892 init_ds = None
880 else:
893 else:
881 if init_def is None:
894 if init_def is None:
882 # Get signature from init if top-level sig failed.
895 # Get signature from init if top-level sig failed.
883 # Can happen for built-in types (list, etc.).
896 # Can happen for built-in types (list, etc.).
884 try:
897 try:
885 init_def = self._getdef(obj_init, oname)
898 init_def = self._getdef(obj_init, oname)
886 except AttributeError:
899 except AttributeError:
887 pass
900 pass
888 init_ds = getdoc(obj_init)
901 init_ds = getdoc(obj_init)
889 # Skip Python's auto-generated docstrings
902 # Skip Python's auto-generated docstrings
890 if init_ds == _object_init_docstring:
903 if init_ds == _object_init_docstring:
891 init_ds = None
904 init_ds = None
892
905
893 if init_def:
906 if init_def:
894 out['init_definition'] = init_def
907 out['init_definition'] = init_def
895
908
896 if init_ds:
909 if init_ds:
897 out['init_docstring'] = init_ds
910 out['init_docstring'] = init_ds
898
911
899 names = [sub.__name__ for sub in type.__subclasses__(obj)]
912 names = [sub.__name__ for sub in type.__subclasses__(obj)]
900 if len(names) < 10:
913 if len(names) < 10:
901 all_names = ', '.join(names)
914 all_names = ', '.join(names)
902 else:
915 else:
903 all_names = ', '.join(names[:10]+['...'])
916 all_names = ', '.join(names[:10]+['...'])
904 out['subclasses'] = all_names
917 out['subclasses'] = all_names
905 # and class docstring for instances:
918 # and class docstring for instances:
906 else:
919 else:
907 # reconstruct the function definition and print it:
920 # reconstruct the function definition and print it:
908 defln = self._getdef(obj, oname)
921 defln = self._getdef(obj, oname)
909 if defln:
922 if defln:
910 out['definition'] = defln
923 out['definition'] = defln
911
924
912 # First, check whether the instance docstring is identical to the
925 # First, check whether the instance docstring is identical to the
913 # class one, and print it separately if they don't coincide. In
926 # class one, and print it separately if they don't coincide. In
914 # most cases they will, but it's nice to print all the info for
927 # most cases they will, but it's nice to print all the info for
915 # objects which use instance-customized docstrings.
928 # objects which use instance-customized docstrings.
916 if ds:
929 if ds:
917 try:
930 try:
918 cls = getattr(obj,'__class__')
931 cls = getattr(obj,'__class__')
919 except:
932 except:
920 class_ds = None
933 class_ds = None
921 else:
934 else:
922 class_ds = getdoc(cls)
935 class_ds = getdoc(cls)
923 # Skip Python's auto-generated docstrings
936 # Skip Python's auto-generated docstrings
924 if class_ds in _builtin_type_docstrings:
937 if class_ds in _builtin_type_docstrings:
925 class_ds = None
938 class_ds = None
926 if class_ds and ds != class_ds:
939 if class_ds and ds != class_ds:
927 out['class_docstring'] = class_ds
940 out['class_docstring'] = class_ds
928
941
929 # Next, try to show constructor docstrings
942 # Next, try to show constructor docstrings
930 try:
943 try:
931 init_ds = getdoc(obj.__init__)
944 init_ds = getdoc(obj.__init__)
932 # Skip Python's auto-generated docstrings
945 # Skip Python's auto-generated docstrings
933 if init_ds == _object_init_docstring:
946 if init_ds == _object_init_docstring:
934 init_ds = None
947 init_ds = None
935 except AttributeError:
948 except AttributeError:
936 init_ds = None
949 init_ds = None
937 if init_ds:
950 if init_ds:
938 out['init_docstring'] = init_ds
951 out['init_docstring'] = init_ds
939
952
940 # Call form docstring for callable instances
953 # Call form docstring for callable instances
941 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
954 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
942 call_def = self._getdef(obj.__call__, oname)
955 call_def = self._getdef(obj.__call__, oname)
943 if call_def and (call_def != out.get('definition')):
956 if call_def and (call_def != out.get('definition')):
944 # it may never be the case that call def and definition differ,
957 # it may never be the case that call def and definition differ,
945 # but don't include the same signature twice
958 # but don't include the same signature twice
946 out['call_def'] = call_def
959 out['call_def'] = call_def
947 call_ds = getdoc(obj.__call__)
960 call_ds = getdoc(obj.__call__)
948 # Skip Python's auto-generated docstrings
961 # Skip Python's auto-generated docstrings
949 if call_ds == _func_call_docstring:
962 if call_ds == _func_call_docstring:
950 call_ds = None
963 call_ds = None
951 if call_ds:
964 if call_ds:
952 out['call_docstring'] = call_ds
965 out['call_docstring'] = call_ds
953
966
954 return object_info(**out)
967 return object_info(**out)
955
968
956 @staticmethod
969 @staticmethod
957 def _source_contains_docstring(src, doc):
970 def _source_contains_docstring(src, doc):
958 """
971 """
959 Check whether the source *src* contains the docstring *doc*.
972 Check whether the source *src* contains the docstring *doc*.
960
973
961 This is is helper function to skip displaying the docstring if the
974 This is is helper function to skip displaying the docstring if the
962 source already contains it, avoiding repetition of information.
975 source already contains it, avoiding repetition of information.
963 """
976 """
964 try:
977 try:
965 def_node, = ast.parse(dedent(src)).body
978 def_node, = ast.parse(dedent(src)).body
966 return ast.get_docstring(def_node) == doc
979 return ast.get_docstring(def_node) == doc
967 except Exception:
980 except Exception:
968 # The source can become invalid or even non-existent (because it
981 # The source can become invalid or even non-existent (because it
969 # is re-fetched from the source file) so the above code fail in
982 # is re-fetched from the source file) so the above code fail in
970 # arbitrary ways.
983 # arbitrary ways.
971 return False
984 return False
972
985
973 def psearch(self,pattern,ns_table,ns_search=[],
986 def psearch(self,pattern,ns_table,ns_search=[],
974 ignore_case=False,show_all=False, *, list_types=False):
987 ignore_case=False,show_all=False, *, list_types=False):
975 """Search namespaces with wildcards for objects.
988 """Search namespaces with wildcards for objects.
976
989
977 Arguments:
990 Arguments:
978
991
979 - pattern: string containing shell-like wildcards to use in namespace
992 - pattern: string containing shell-like wildcards to use in namespace
980 searches and optionally a type specification to narrow the search to
993 searches and optionally a type specification to narrow the search to
981 objects of that type.
994 objects of that type.
982
995
983 - ns_table: dict of name->namespaces for search.
996 - ns_table: dict of name->namespaces for search.
984
997
985 Optional arguments:
998 Optional arguments:
986
999
987 - ns_search: list of namespace names to include in search.
1000 - ns_search: list of namespace names to include in search.
988
1001
989 - ignore_case(False): make the search case-insensitive.
1002 - ignore_case(False): make the search case-insensitive.
990
1003
991 - show_all(False): show all names, including those starting with
1004 - show_all(False): show all names, including those starting with
992 underscores.
1005 underscores.
993
1006
994 - list_types(False): list all available object types for object matching.
1007 - list_types(False): list all available object types for object matching.
995 """
1008 """
996 #print 'ps pattern:<%r>' % pattern # dbg
1009 #print 'ps pattern:<%r>' % pattern # dbg
997
1010
998 # defaults
1011 # defaults
999 type_pattern = 'all'
1012 type_pattern = 'all'
1000 filter = ''
1013 filter = ''
1001
1014
1002 # list all object types
1015 # list all object types
1003 if list_types:
1016 if list_types:
1004 page.page('\n'.join(sorted(typestr2type)))
1017 page.page('\n'.join(sorted(typestr2type)))
1005 return
1018 return
1006
1019
1007 cmds = pattern.split()
1020 cmds = pattern.split()
1008 len_cmds = len(cmds)
1021 len_cmds = len(cmds)
1009 if len_cmds == 1:
1022 if len_cmds == 1:
1010 # Only filter pattern given
1023 # Only filter pattern given
1011 filter = cmds[0]
1024 filter = cmds[0]
1012 elif len_cmds == 2:
1025 elif len_cmds == 2:
1013 # Both filter and type specified
1026 # Both filter and type specified
1014 filter,type_pattern = cmds
1027 filter,type_pattern = cmds
1015 else:
1028 else:
1016 raise ValueError('invalid argument string for psearch: <%s>' %
1029 raise ValueError('invalid argument string for psearch: <%s>' %
1017 pattern)
1030 pattern)
1018
1031
1019 # filter search namespaces
1032 # filter search namespaces
1020 for name in ns_search:
1033 for name in ns_search:
1021 if name not in ns_table:
1034 if name not in ns_table:
1022 raise ValueError('invalid namespace <%s>. Valid names: %s' %
1035 raise ValueError('invalid namespace <%s>. Valid names: %s' %
1023 (name,ns_table.keys()))
1036 (name,ns_table.keys()))
1024
1037
1025 #print 'type_pattern:',type_pattern # dbg
1038 #print 'type_pattern:',type_pattern # dbg
1026 search_result, namespaces_seen = set(), set()
1039 search_result, namespaces_seen = set(), set()
1027 for ns_name in ns_search:
1040 for ns_name in ns_search:
1028 ns = ns_table[ns_name]
1041 ns = ns_table[ns_name]
1029 # Normally, locals and globals are the same, so we just check one.
1042 # Normally, locals and globals are the same, so we just check one.
1030 if id(ns) in namespaces_seen:
1043 if id(ns) in namespaces_seen:
1031 continue
1044 continue
1032 namespaces_seen.add(id(ns))
1045 namespaces_seen.add(id(ns))
1033 tmp_res = list_namespace(ns, type_pattern, filter,
1046 tmp_res = list_namespace(ns, type_pattern, filter,
1034 ignore_case=ignore_case, show_all=show_all)
1047 ignore_case=ignore_case, show_all=show_all)
1035 search_result.update(tmp_res)
1048 search_result.update(tmp_res)
1036
1049
1037 page.page('\n'.join(sorted(search_result)))
1050 page.page('\n'.join(sorted(search_result)))
1038
1051
1039
1052
1040 def _render_signature(obj_signature, obj_name) -> str:
1053 def _render_signature(obj_signature, obj_name) -> str:
1041 """
1054 """
1042 This was mostly taken from inspect.Signature.__str__.
1055 This was mostly taken from inspect.Signature.__str__.
1043 Look there for the comments.
1056 Look there for the comments.
1044 The only change is to add linebreaks when this gets too long.
1057 The only change is to add linebreaks when this gets too long.
1045 """
1058 """
1046 result = []
1059 result = []
1047 pos_only = False
1060 pos_only = False
1048 kw_only = True
1061 kw_only = True
1049 for param in obj_signature.parameters.values():
1062 for param in obj_signature.parameters.values():
1050 if param.kind == inspect._POSITIONAL_ONLY:
1063 if param.kind == inspect._POSITIONAL_ONLY:
1051 pos_only = True
1064 pos_only = True
1052 elif pos_only:
1065 elif pos_only:
1053 result.append('/')
1066 result.append('/')
1054 pos_only = False
1067 pos_only = False
1055
1068
1056 if param.kind == inspect._VAR_POSITIONAL:
1069 if param.kind == inspect._VAR_POSITIONAL:
1057 kw_only = False
1070 kw_only = False
1058 elif param.kind == inspect._KEYWORD_ONLY and kw_only:
1071 elif param.kind == inspect._KEYWORD_ONLY and kw_only:
1059 result.append('*')
1072 result.append('*')
1060 kw_only = False
1073 kw_only = False
1061
1074
1062 result.append(str(param))
1075 result.append(str(param))
1063
1076
1064 if pos_only:
1077 if pos_only:
1065 result.append('/')
1078 result.append('/')
1066
1079
1067 # add up name, parameters, braces (2), and commas
1080 # add up name, parameters, braces (2), and commas
1068 if len(obj_name) + sum(len(r) + 2 for r in result) > 75:
1081 if len(obj_name) + sum(len(r) + 2 for r in result) > 75:
1069 # This doesn’t fit behind β€œSignature: ” in an inspect window.
1082 # This doesn’t fit behind β€œSignature: ” in an inspect window.
1070 rendered = '{}(\n{})'.format(obj_name, ''.join(
1083 rendered = '{}(\n{})'.format(obj_name, ''.join(
1071 ' {},\n'.format(r) for r in result)
1084 ' {},\n'.format(r) for r in result)
1072 )
1085 )
1073 else:
1086 else:
1074 rendered = '{}({})'.format(obj_name, ', '.join(result))
1087 rendered = '{}({})'.format(obj_name, ', '.join(result))
1075
1088
1076 if obj_signature.return_annotation is not inspect._empty:
1089 if obj_signature.return_annotation is not inspect._empty:
1077 anno = inspect.formatannotation(obj_signature.return_annotation)
1090 anno = inspect.formatannotation(obj_signature.return_annotation)
1078 rendered += ' -> {}'.format(anno)
1091 rendered += ' -> {}'.format(anno)
1079
1092
1080 return rendered
1093 return rendered
@@ -1,698 +1,700 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Prefiltering components.
3 Prefiltering components.
4
4
5 Prefilters transform user input before it is exec'd by Python. These
5 Prefilters transform user input before it is exec'd by Python. These
6 transforms are used to implement additional syntax such as !ls and %magic.
6 transforms are used to implement additional syntax such as !ls and %magic.
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 from keyword import iskeyword
12 from keyword import iskeyword
13 import re
13 import re
14
14
15 from .autocall import IPyAutocall
15 from .autocall import IPyAutocall
16 from traitlets.config.configurable import Configurable
16 from traitlets.config.configurable import Configurable
17 from .inputtransformer2 import (
17 from .inputtransformer2 import (
18 ESC_MAGIC,
18 ESC_MAGIC,
19 ESC_QUOTE,
19 ESC_QUOTE,
20 ESC_QUOTE2,
20 ESC_QUOTE2,
21 ESC_PAREN,
21 ESC_PAREN,
22 )
22 )
23 from .macro import Macro
23 from .macro import Macro
24 from .splitinput import LineInfo
24 from .splitinput import LineInfo
25
25
26 from traitlets import (
26 from traitlets import (
27 List, Integer, Unicode, Bool, Instance, CRegExp
27 List, Integer, Unicode, Bool, Instance, CRegExp
28 )
28 )
29
29
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31 # Global utilities, errors and constants
31 # Global utilities, errors and constants
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33
33
34
34
35 class PrefilterError(Exception):
35 class PrefilterError(Exception):
36 pass
36 pass
37
37
38
38
39 # RegExp to identify potential function names
39 # RegExp to identify potential function names
40 re_fun_name = re.compile(r'[^\W\d]([\w.]*) *$')
40 re_fun_name = re.compile(r'[^\W\d]([\w.]*) *$')
41
41
42 # RegExp to exclude strings with this start from autocalling. In
42 # RegExp to exclude strings with this start from autocalling. In
43 # particular, all binary operators should be excluded, so that if foo is
43 # particular, all binary operators should be excluded, so that if foo is
44 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
44 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
45 # characters '!=()' don't need to be checked for, as the checkPythonChars
45 # characters '!=()' don't need to be checked for, as the checkPythonChars
46 # routine explicitly does so, to catch direct calls and rebindings of
46 # routine explicitly does so, to catch direct calls and rebindings of
47 # existing names.
47 # existing names.
48
48
49 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
49 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
50 # it affects the rest of the group in square brackets.
50 # it affects the rest of the group in square brackets.
51 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
51 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
52 r'|^is |^not |^in |^and |^or ')
52 r'|^is |^not |^in |^and |^or ')
53
53
54 # try to catch also methods for stuff in lists/tuples/dicts: off
54 # try to catch also methods for stuff in lists/tuples/dicts: off
55 # (experimental). For this to work, the line_split regexp would need
55 # (experimental). For this to work, the line_split regexp would need
56 # to be modified so it wouldn't break things at '['. That line is
56 # to be modified so it wouldn't break things at '['. That line is
57 # nasty enough that I shouldn't change it until I can test it _well_.
57 # nasty enough that I shouldn't change it until I can test it _well_.
58 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
58 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
59
59
60
60
61 # Handler Check Utilities
61 # Handler Check Utilities
62 def is_shadowed(identifier, ip):
62 def is_shadowed(identifier, ip):
63 """Is the given identifier defined in one of the namespaces which shadow
63 """Is the given identifier defined in one of the namespaces which shadow
64 the alias and magic namespaces? Note that an identifier is different
64 the alias and magic namespaces? Note that an identifier is different
65 than ifun, because it can not contain a '.' character."""
65 than ifun, because it can not contain a '.' character."""
66 # This is much safer than calling ofind, which can change state
66 # This is much safer than calling ofind, which can change state
67 return (identifier in ip.user_ns \
67 return (identifier in ip.user_ns \
68 or identifier in ip.user_global_ns \
68 or identifier in ip.user_global_ns \
69 or identifier in ip.ns_table['builtin']\
69 or identifier in ip.ns_table['builtin']\
70 or iskeyword(identifier))
70 or iskeyword(identifier))
71
71
72
72
73 #-----------------------------------------------------------------------------
73 #-----------------------------------------------------------------------------
74 # Main Prefilter manager
74 # Main Prefilter manager
75 #-----------------------------------------------------------------------------
75 #-----------------------------------------------------------------------------
76
76
77
77
78 class PrefilterManager(Configurable):
78 class PrefilterManager(Configurable):
79 """Main prefilter component.
79 """Main prefilter component.
80
80
81 The IPython prefilter is run on all user input before it is run. The
81 The IPython prefilter is run on all user input before it is run. The
82 prefilter consumes lines of input and produces transformed lines of
82 prefilter consumes lines of input and produces transformed lines of
83 input.
83 input.
84
84
85 The implementation consists of two phases:
85 The implementation consists of two phases:
86
86
87 1. Transformers
87 1. Transformers
88 2. Checkers and handlers
88 2. Checkers and handlers
89
89
90 Over time, we plan on deprecating the checkers and handlers and doing
90 Over time, we plan on deprecating the checkers and handlers and doing
91 everything in the transformers.
91 everything in the transformers.
92
92
93 The transformers are instances of :class:`PrefilterTransformer` and have
93 The transformers are instances of :class:`PrefilterTransformer` and have
94 a single method :meth:`transform` that takes a line and returns a
94 a single method :meth:`transform` that takes a line and returns a
95 transformed line. The transformation can be accomplished using any
95 transformed line. The transformation can be accomplished using any
96 tool, but our current ones use regular expressions for speed.
96 tool, but our current ones use regular expressions for speed.
97
97
98 After all the transformers have been run, the line is fed to the checkers,
98 After all the transformers have been run, the line is fed to the checkers,
99 which are instances of :class:`PrefilterChecker`. The line is passed to
99 which are instances of :class:`PrefilterChecker`. The line is passed to
100 the :meth:`check` method, which either returns `None` or a
100 the :meth:`check` method, which either returns `None` or a
101 :class:`PrefilterHandler` instance. If `None` is returned, the other
101 :class:`PrefilterHandler` instance. If `None` is returned, the other
102 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
102 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
103 the line is passed to the :meth:`handle` method of the returned
103 the line is passed to the :meth:`handle` method of the returned
104 handler and no further checkers are tried.
104 handler and no further checkers are tried.
105
105
106 Both transformers and checkers have a `priority` attribute, that determines
106 Both transformers and checkers have a `priority` attribute, that determines
107 the order in which they are called. Smaller priorities are tried first.
107 the order in which they are called. Smaller priorities are tried first.
108
108
109 Both transformers and checkers also have `enabled` attribute, which is
109 Both transformers and checkers also have `enabled` attribute, which is
110 a boolean that determines if the instance is used.
110 a boolean that determines if the instance is used.
111
111
112 Users or developers can change the priority or enabled attribute of
112 Users or developers can change the priority or enabled attribute of
113 transformers or checkers, but they must call the :meth:`sort_checkers`
113 transformers or checkers, but they must call the :meth:`sort_checkers`
114 or :meth:`sort_transformers` method after changing the priority.
114 or :meth:`sort_transformers` method after changing the priority.
115 """
115 """
116
116
117 multi_line_specials = Bool(True).tag(config=True)
117 multi_line_specials = Bool(True).tag(config=True)
118 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
118 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
119
119
120 def __init__(self, shell=None, **kwargs):
120 def __init__(self, shell=None, **kwargs):
121 super(PrefilterManager, self).__init__(shell=shell, **kwargs)
121 super(PrefilterManager, self).__init__(shell=shell, **kwargs)
122 self.shell = shell
122 self.shell = shell
123 self._transformers = []
123 self._transformers = []
124 self.init_handlers()
124 self.init_handlers()
125 self.init_checkers()
125 self.init_checkers()
126
126
127 #-------------------------------------------------------------------------
127 #-------------------------------------------------------------------------
128 # API for managing transformers
128 # API for managing transformers
129 #-------------------------------------------------------------------------
129 #-------------------------------------------------------------------------
130
130
131 def sort_transformers(self):
131 def sort_transformers(self):
132 """Sort the transformers by priority.
132 """Sort the transformers by priority.
133
133
134 This must be called after the priority of a transformer is changed.
134 This must be called after the priority of a transformer is changed.
135 The :meth:`register_transformer` method calls this automatically.
135 The :meth:`register_transformer` method calls this automatically.
136 """
136 """
137 self._transformers.sort(key=lambda x: x.priority)
137 self._transformers.sort(key=lambda x: x.priority)
138
138
139 @property
139 @property
140 def transformers(self):
140 def transformers(self):
141 """Return a list of checkers, sorted by priority."""
141 """Return a list of checkers, sorted by priority."""
142 return self._transformers
142 return self._transformers
143
143
144 def register_transformer(self, transformer):
144 def register_transformer(self, transformer):
145 """Register a transformer instance."""
145 """Register a transformer instance."""
146 if transformer not in self._transformers:
146 if transformer not in self._transformers:
147 self._transformers.append(transformer)
147 self._transformers.append(transformer)
148 self.sort_transformers()
148 self.sort_transformers()
149
149
150 def unregister_transformer(self, transformer):
150 def unregister_transformer(self, transformer):
151 """Unregister a transformer instance."""
151 """Unregister a transformer instance."""
152 if transformer in self._transformers:
152 if transformer in self._transformers:
153 self._transformers.remove(transformer)
153 self._transformers.remove(transformer)
154
154
155 #-------------------------------------------------------------------------
155 #-------------------------------------------------------------------------
156 # API for managing checkers
156 # API for managing checkers
157 #-------------------------------------------------------------------------
157 #-------------------------------------------------------------------------
158
158
159 def init_checkers(self):
159 def init_checkers(self):
160 """Create the default checkers."""
160 """Create the default checkers."""
161 self._checkers = []
161 self._checkers = []
162 for checker in _default_checkers:
162 for checker in _default_checkers:
163 checker(
163 checker(
164 shell=self.shell, prefilter_manager=self, parent=self
164 shell=self.shell, prefilter_manager=self, parent=self
165 )
165 )
166
166
167 def sort_checkers(self):
167 def sort_checkers(self):
168 """Sort the checkers by priority.
168 """Sort the checkers by priority.
169
169
170 This must be called after the priority of a checker is changed.
170 This must be called after the priority of a checker is changed.
171 The :meth:`register_checker` method calls this automatically.
171 The :meth:`register_checker` method calls this automatically.
172 """
172 """
173 self._checkers.sort(key=lambda x: x.priority)
173 self._checkers.sort(key=lambda x: x.priority)
174
174
175 @property
175 @property
176 def checkers(self):
176 def checkers(self):
177 """Return a list of checkers, sorted by priority."""
177 """Return a list of checkers, sorted by priority."""
178 return self._checkers
178 return self._checkers
179
179
180 def register_checker(self, checker):
180 def register_checker(self, checker):
181 """Register a checker instance."""
181 """Register a checker instance."""
182 if checker not in self._checkers:
182 if checker not in self._checkers:
183 self._checkers.append(checker)
183 self._checkers.append(checker)
184 self.sort_checkers()
184 self.sort_checkers()
185
185
186 def unregister_checker(self, checker):
186 def unregister_checker(self, checker):
187 """Unregister a checker instance."""
187 """Unregister a checker instance."""
188 if checker in self._checkers:
188 if checker in self._checkers:
189 self._checkers.remove(checker)
189 self._checkers.remove(checker)
190
190
191 #-------------------------------------------------------------------------
191 #-------------------------------------------------------------------------
192 # API for managing handlers
192 # API for managing handlers
193 #-------------------------------------------------------------------------
193 #-------------------------------------------------------------------------
194
194
195 def init_handlers(self):
195 def init_handlers(self):
196 """Create the default handlers."""
196 """Create the default handlers."""
197 self._handlers = {}
197 self._handlers = {}
198 self._esc_handlers = {}
198 self._esc_handlers = {}
199 for handler in _default_handlers:
199 for handler in _default_handlers:
200 handler(
200 handler(
201 shell=self.shell, prefilter_manager=self, parent=self
201 shell=self.shell, prefilter_manager=self, parent=self
202 )
202 )
203
203
204 @property
204 @property
205 def handlers(self):
205 def handlers(self):
206 """Return a dict of all the handlers."""
206 """Return a dict of all the handlers."""
207 return self._handlers
207 return self._handlers
208
208
209 def register_handler(self, name, handler, esc_strings):
209 def register_handler(self, name, handler, esc_strings):
210 """Register a handler instance by name with esc_strings."""
210 """Register a handler instance by name with esc_strings."""
211 self._handlers[name] = handler
211 self._handlers[name] = handler
212 for esc_str in esc_strings:
212 for esc_str in esc_strings:
213 self._esc_handlers[esc_str] = handler
213 self._esc_handlers[esc_str] = handler
214
214
215 def unregister_handler(self, name, handler, esc_strings):
215 def unregister_handler(self, name, handler, esc_strings):
216 """Unregister a handler instance by name with esc_strings."""
216 """Unregister a handler instance by name with esc_strings."""
217 try:
217 try:
218 del self._handlers[name]
218 del self._handlers[name]
219 except KeyError:
219 except KeyError:
220 pass
220 pass
221 for esc_str in esc_strings:
221 for esc_str in esc_strings:
222 h = self._esc_handlers.get(esc_str)
222 h = self._esc_handlers.get(esc_str)
223 if h is handler:
223 if h is handler:
224 del self._esc_handlers[esc_str]
224 del self._esc_handlers[esc_str]
225
225
226 def get_handler_by_name(self, name):
226 def get_handler_by_name(self, name):
227 """Get a handler by its name."""
227 """Get a handler by its name."""
228 return self._handlers.get(name)
228 return self._handlers.get(name)
229
229
230 def get_handler_by_esc(self, esc_str):
230 def get_handler_by_esc(self, esc_str):
231 """Get a handler by its escape string."""
231 """Get a handler by its escape string."""
232 return self._esc_handlers.get(esc_str)
232 return self._esc_handlers.get(esc_str)
233
233
234 #-------------------------------------------------------------------------
234 #-------------------------------------------------------------------------
235 # Main prefiltering API
235 # Main prefiltering API
236 #-------------------------------------------------------------------------
236 #-------------------------------------------------------------------------
237
237
238 def prefilter_line_info(self, line_info):
238 def prefilter_line_info(self, line_info):
239 """Prefilter a line that has been converted to a LineInfo object.
239 """Prefilter a line that has been converted to a LineInfo object.
240
240
241 This implements the checker/handler part of the prefilter pipe.
241 This implements the checker/handler part of the prefilter pipe.
242 """
242 """
243 # print "prefilter_line_info: ", line_info
243 # print "prefilter_line_info: ", line_info
244 handler = self.find_handler(line_info)
244 handler = self.find_handler(line_info)
245 return handler.handle(line_info)
245 return handler.handle(line_info)
246
246
247 def find_handler(self, line_info):
247 def find_handler(self, line_info):
248 """Find a handler for the line_info by trying checkers."""
248 """Find a handler for the line_info by trying checkers."""
249 for checker in self.checkers:
249 for checker in self.checkers:
250 if checker.enabled:
250 if checker.enabled:
251 handler = checker.check(line_info)
251 handler = checker.check(line_info)
252 if handler:
252 if handler:
253 return handler
253 return handler
254 return self.get_handler_by_name('normal')
254 return self.get_handler_by_name('normal')
255
255
256 def transform_line(self, line, continue_prompt):
256 def transform_line(self, line, continue_prompt):
257 """Calls the enabled transformers in order of increasing priority."""
257 """Calls the enabled transformers in order of increasing priority."""
258 for transformer in self.transformers:
258 for transformer in self.transformers:
259 if transformer.enabled:
259 if transformer.enabled:
260 line = transformer.transform(line, continue_prompt)
260 line = transformer.transform(line, continue_prompt)
261 return line
261 return line
262
262
263 def prefilter_line(self, line, continue_prompt=False):
263 def prefilter_line(self, line, continue_prompt=False):
264 """Prefilter a single input line as text.
264 """Prefilter a single input line as text.
265
265
266 This method prefilters a single line of text by calling the
266 This method prefilters a single line of text by calling the
267 transformers and then the checkers/handlers.
267 transformers and then the checkers/handlers.
268 """
268 """
269
269
270 # print "prefilter_line: ", line, continue_prompt
270 # print "prefilter_line: ", line, continue_prompt
271 # All handlers *must* return a value, even if it's blank ('').
271 # All handlers *must* return a value, even if it's blank ('').
272
272
273 # save the line away in case we crash, so the post-mortem handler can
273 # save the line away in case we crash, so the post-mortem handler can
274 # record it
274 # record it
275 self.shell._last_input_line = line
275 self.shell._last_input_line = line
276
276
277 if not line:
277 if not line:
278 # Return immediately on purely empty lines, so that if the user
278 # Return immediately on purely empty lines, so that if the user
279 # previously typed some whitespace that started a continuation
279 # previously typed some whitespace that started a continuation
280 # prompt, he can break out of that loop with just an empty line.
280 # prompt, he can break out of that loop with just an empty line.
281 # This is how the default python prompt works.
281 # This is how the default python prompt works.
282 return ''
282 return ''
283
283
284 # At this point, we invoke our transformers.
284 # At this point, we invoke our transformers.
285 if not continue_prompt or (continue_prompt and self.multi_line_specials):
285 if not continue_prompt or (continue_prompt and self.multi_line_specials):
286 line = self.transform_line(line, continue_prompt)
286 line = self.transform_line(line, continue_prompt)
287
287
288 # Now we compute line_info for the checkers and handlers
288 # Now we compute line_info for the checkers and handlers
289 line_info = LineInfo(line, continue_prompt)
289 line_info = LineInfo(line, continue_prompt)
290
290
291 # the input history needs to track even empty lines
291 # the input history needs to track even empty lines
292 stripped = line.strip()
292 stripped = line.strip()
293
293
294 normal_handler = self.get_handler_by_name('normal')
294 normal_handler = self.get_handler_by_name('normal')
295 if not stripped:
295 if not stripped:
296 return normal_handler.handle(line_info)
296 return normal_handler.handle(line_info)
297
297
298 # special handlers are only allowed for single line statements
298 # special handlers are only allowed for single line statements
299 if continue_prompt and not self.multi_line_specials:
299 if continue_prompt and not self.multi_line_specials:
300 return normal_handler.handle(line_info)
300 return normal_handler.handle(line_info)
301
301
302 prefiltered = self.prefilter_line_info(line_info)
302 prefiltered = self.prefilter_line_info(line_info)
303 # print "prefiltered line: %r" % prefiltered
303 # print "prefiltered line: %r" % prefiltered
304 return prefiltered
304 return prefiltered
305
305
306 def prefilter_lines(self, lines, continue_prompt=False):
306 def prefilter_lines(self, lines, continue_prompt=False):
307 """Prefilter multiple input lines of text.
307 """Prefilter multiple input lines of text.
308
308
309 This is the main entry point for prefiltering multiple lines of
309 This is the main entry point for prefiltering multiple lines of
310 input. This simply calls :meth:`prefilter_line` for each line of
310 input. This simply calls :meth:`prefilter_line` for each line of
311 input.
311 input.
312
312
313 This covers cases where there are multiple lines in the user entry,
313 This covers cases where there are multiple lines in the user entry,
314 which is the case when the user goes back to a multiline history
314 which is the case when the user goes back to a multiline history
315 entry and presses enter.
315 entry and presses enter.
316 """
316 """
317 llines = lines.rstrip('\n').split('\n')
317 llines = lines.rstrip('\n').split('\n')
318 # We can get multiple lines in one shot, where multiline input 'blends'
318 # We can get multiple lines in one shot, where multiline input 'blends'
319 # into one line, in cases like recalling from the readline history
319 # into one line, in cases like recalling from the readline history
320 # buffer. We need to make sure that in such cases, we correctly
320 # buffer. We need to make sure that in such cases, we correctly
321 # communicate downstream which line is first and which are continuation
321 # communicate downstream which line is first and which are continuation
322 # ones.
322 # ones.
323 if len(llines) > 1:
323 if len(llines) > 1:
324 out = '\n'.join([self.prefilter_line(line, lnum>0)
324 out = '\n'.join([self.prefilter_line(line, lnum>0)
325 for lnum, line in enumerate(llines) ])
325 for lnum, line in enumerate(llines) ])
326 else:
326 else:
327 out = self.prefilter_line(llines[0], continue_prompt)
327 out = self.prefilter_line(llines[0], continue_prompt)
328
328
329 return out
329 return out
330
330
331 #-----------------------------------------------------------------------------
331 #-----------------------------------------------------------------------------
332 # Prefilter transformers
332 # Prefilter transformers
333 #-----------------------------------------------------------------------------
333 #-----------------------------------------------------------------------------
334
334
335
335
336 class PrefilterTransformer(Configurable):
336 class PrefilterTransformer(Configurable):
337 """Transform a line of user input."""
337 """Transform a line of user input."""
338
338
339 priority = Integer(100).tag(config=True)
339 priority = Integer(100).tag(config=True)
340 # Transformers don't currently use shell or prefilter_manager, but as we
340 # Transformers don't currently use shell or prefilter_manager, but as we
341 # move away from checkers and handlers, they will need them.
341 # move away from checkers and handlers, they will need them.
342 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
342 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
343 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
343 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
344 enabled = Bool(True).tag(config=True)
344 enabled = Bool(True).tag(config=True)
345
345
346 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
346 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
347 super(PrefilterTransformer, self).__init__(
347 super(PrefilterTransformer, self).__init__(
348 shell=shell, prefilter_manager=prefilter_manager, **kwargs
348 shell=shell, prefilter_manager=prefilter_manager, **kwargs
349 )
349 )
350 self.prefilter_manager.register_transformer(self)
350 self.prefilter_manager.register_transformer(self)
351
351
352 def transform(self, line, continue_prompt):
352 def transform(self, line, continue_prompt):
353 """Transform a line, returning the new one."""
353 """Transform a line, returning the new one."""
354 return None
354 return None
355
355
356 def __repr__(self):
356 def __repr__(self):
357 return "<%s(priority=%r, enabled=%r)>" % (
357 return "<%s(priority=%r, enabled=%r)>" % (
358 self.__class__.__name__, self.priority, self.enabled)
358 self.__class__.__name__, self.priority, self.enabled)
359
359
360
360
361 #-----------------------------------------------------------------------------
361 #-----------------------------------------------------------------------------
362 # Prefilter checkers
362 # Prefilter checkers
363 #-----------------------------------------------------------------------------
363 #-----------------------------------------------------------------------------
364
364
365
365
366 class PrefilterChecker(Configurable):
366 class PrefilterChecker(Configurable):
367 """Inspect an input line and return a handler for that line."""
367 """Inspect an input line and return a handler for that line."""
368
368
369 priority = Integer(100).tag(config=True)
369 priority = Integer(100).tag(config=True)
370 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
370 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
371 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
371 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
372 enabled = Bool(True).tag(config=True)
372 enabled = Bool(True).tag(config=True)
373
373
374 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
374 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
375 super(PrefilterChecker, self).__init__(
375 super(PrefilterChecker, self).__init__(
376 shell=shell, prefilter_manager=prefilter_manager, **kwargs
376 shell=shell, prefilter_manager=prefilter_manager, **kwargs
377 )
377 )
378 self.prefilter_manager.register_checker(self)
378 self.prefilter_manager.register_checker(self)
379
379
380 def check(self, line_info):
380 def check(self, line_info):
381 """Inspect line_info and return a handler instance or None."""
381 """Inspect line_info and return a handler instance or None."""
382 return None
382 return None
383
383
384 def __repr__(self):
384 def __repr__(self):
385 return "<%s(priority=%r, enabled=%r)>" % (
385 return "<%s(priority=%r, enabled=%r)>" % (
386 self.__class__.__name__, self.priority, self.enabled)
386 self.__class__.__name__, self.priority, self.enabled)
387
387
388
388
389 class EmacsChecker(PrefilterChecker):
389 class EmacsChecker(PrefilterChecker):
390
390
391 priority = Integer(100).tag(config=True)
391 priority = Integer(100).tag(config=True)
392 enabled = Bool(False).tag(config=True)
392 enabled = Bool(False).tag(config=True)
393
393
394 def check(self, line_info):
394 def check(self, line_info):
395 "Emacs ipython-mode tags certain input lines."
395 "Emacs ipython-mode tags certain input lines."
396 if line_info.line.endswith('# PYTHON-MODE'):
396 if line_info.line.endswith('# PYTHON-MODE'):
397 return self.prefilter_manager.get_handler_by_name('emacs')
397 return self.prefilter_manager.get_handler_by_name('emacs')
398 else:
398 else:
399 return None
399 return None
400
400
401
401
402 class MacroChecker(PrefilterChecker):
402 class MacroChecker(PrefilterChecker):
403
403
404 priority = Integer(250).tag(config=True)
404 priority = Integer(250).tag(config=True)
405
405
406 def check(self, line_info):
406 def check(self, line_info):
407 obj = self.shell.user_ns.get(line_info.ifun)
407 obj = self.shell.user_ns.get(line_info.ifun)
408 if isinstance(obj, Macro):
408 if isinstance(obj, Macro):
409 return self.prefilter_manager.get_handler_by_name('macro')
409 return self.prefilter_manager.get_handler_by_name('macro')
410 else:
410 else:
411 return None
411 return None
412
412
413
413
414 class IPyAutocallChecker(PrefilterChecker):
414 class IPyAutocallChecker(PrefilterChecker):
415
415
416 priority = Integer(300).tag(config=True)
416 priority = Integer(300).tag(config=True)
417
417
418 def check(self, line_info):
418 def check(self, line_info):
419 "Instances of IPyAutocall in user_ns get autocalled immediately"
419 "Instances of IPyAutocall in user_ns get autocalled immediately"
420 obj = self.shell.user_ns.get(line_info.ifun, None)
420 obj = self.shell.user_ns.get(line_info.ifun, None)
421 if isinstance(obj, IPyAutocall):
421 if isinstance(obj, IPyAutocall):
422 obj.set_ip(self.shell)
422 obj.set_ip(self.shell)
423 return self.prefilter_manager.get_handler_by_name('auto')
423 return self.prefilter_manager.get_handler_by_name('auto')
424 else:
424 else:
425 return None
425 return None
426
426
427
427
428 class AssignmentChecker(PrefilterChecker):
428 class AssignmentChecker(PrefilterChecker):
429
429
430 priority = Integer(600).tag(config=True)
430 priority = Integer(600).tag(config=True)
431
431
432 def check(self, line_info):
432 def check(self, line_info):
433 """Check to see if user is assigning to a var for the first time, in
433 """Check to see if user is assigning to a var for the first time, in
434 which case we want to avoid any sort of automagic / autocall games.
434 which case we want to avoid any sort of automagic / autocall games.
435
435
436 This allows users to assign to either alias or magic names true python
436 This allows users to assign to either alias or magic names true python
437 variables (the magic/alias systems always take second seat to true
437 variables (the magic/alias systems always take second seat to true
438 python code). E.g. ls='hi', or ls,that=1,2"""
438 python code). E.g. ls='hi', or ls,that=1,2"""
439 if line_info.the_rest:
439 if line_info.the_rest:
440 if line_info.the_rest[0] in '=,':
440 if line_info.the_rest[0] in '=,':
441 return self.prefilter_manager.get_handler_by_name('normal')
441 return self.prefilter_manager.get_handler_by_name('normal')
442 else:
442 else:
443 return None
443 return None
444
444
445
445
446 class AutoMagicChecker(PrefilterChecker):
446 class AutoMagicChecker(PrefilterChecker):
447
447
448 priority = Integer(700).tag(config=True)
448 priority = Integer(700).tag(config=True)
449
449
450 def check(self, line_info):
450 def check(self, line_info):
451 """If the ifun is magic, and automagic is on, run it. Note: normal,
451 """If the ifun is magic, and automagic is on, run it. Note: normal,
452 non-auto magic would already have been triggered via '%' in
452 non-auto magic would already have been triggered via '%' in
453 check_esc_chars. This just checks for automagic. Also, before
453 check_esc_chars. This just checks for automagic. Also, before
454 triggering the magic handler, make sure that there is nothing in the
454 triggering the magic handler, make sure that there is nothing in the
455 user namespace which could shadow it."""
455 user namespace which could shadow it."""
456 if not self.shell.automagic or not self.shell.find_magic(line_info.ifun):
456 if not self.shell.automagic or not self.shell.find_magic(line_info.ifun):
457 return None
457 return None
458
458
459 # We have a likely magic method. Make sure we should actually call it.
459 # We have a likely magic method. Make sure we should actually call it.
460 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
460 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
461 return None
461 return None
462
462
463 head = line_info.ifun.split('.',1)[0]
463 head = line_info.ifun.split('.',1)[0]
464 if is_shadowed(head, self.shell):
464 if is_shadowed(head, self.shell):
465 return None
465 return None
466
466
467 return self.prefilter_manager.get_handler_by_name('magic')
467 return self.prefilter_manager.get_handler_by_name('magic')
468
468
469
469
470 class PythonOpsChecker(PrefilterChecker):
470 class PythonOpsChecker(PrefilterChecker):
471
471
472 priority = Integer(900).tag(config=True)
472 priority = Integer(900).tag(config=True)
473
473
474 def check(self, line_info):
474 def check(self, line_info):
475 """If the 'rest' of the line begins with a function call or pretty much
475 """If the 'rest' of the line begins with a function call or pretty much
476 any python operator, we should simply execute the line (regardless of
476 any python operator, we should simply execute the line (regardless of
477 whether or not there's a possible autocall expansion). This avoids
477 whether or not there's a possible autocall expansion). This avoids
478 spurious (and very confusing) geattr() accesses."""
478 spurious (and very confusing) geattr() accesses."""
479 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
479 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
480 return self.prefilter_manager.get_handler_by_name('normal')
480 return self.prefilter_manager.get_handler_by_name('normal')
481 else:
481 else:
482 return None
482 return None
483
483
484
484
485 class AutocallChecker(PrefilterChecker):
485 class AutocallChecker(PrefilterChecker):
486
486
487 priority = Integer(1000).tag(config=True)
487 priority = Integer(1000).tag(config=True)
488
488
489 function_name_regexp = CRegExp(re_fun_name,
489 function_name_regexp = CRegExp(re_fun_name,
490 help="RegExp to identify potential function names."
490 help="RegExp to identify potential function names."
491 ).tag(config=True)
491 ).tag(config=True)
492 exclude_regexp = CRegExp(re_exclude_auto,
492 exclude_regexp = CRegExp(re_exclude_auto,
493 help="RegExp to exclude strings with this start from autocalling."
493 help="RegExp to exclude strings with this start from autocalling."
494 ).tag(config=True)
494 ).tag(config=True)
495
495
496 def check(self, line_info):
496 def check(self, line_info):
497 "Check if the initial word/function is callable and autocall is on."
497 "Check if the initial word/function is callable and autocall is on."
498 if not self.shell.autocall:
498 if not self.shell.autocall:
499 return None
499 return None
500
500
501 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
501 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
502 if not oinfo['found']:
502 if not oinfo.found:
503 return None
503 return None
504
504
505 ignored_funs = ['b', 'f', 'r', 'u', 'br', 'rb', 'fr', 'rf']
505 ignored_funs = ['b', 'f', 'r', 'u', 'br', 'rb', 'fr', 'rf']
506 ifun = line_info.ifun
506 ifun = line_info.ifun
507 line = line_info.line
507 line = line_info.line
508 if ifun.lower() in ignored_funs and (line.startswith(ifun + "'") or line.startswith(ifun + '"')):
508 if ifun.lower() in ignored_funs and (line.startswith(ifun + "'") or line.startswith(ifun + '"')):
509 return None
509 return None
510
510
511 if callable(oinfo['obj']) \
511 if (
512 and (not self.exclude_regexp.match(line_info.the_rest)) \
512 callable(oinfo.obj)
513 and self.function_name_regexp.match(line_info.ifun):
513 and (not self.exclude_regexp.match(line_info.the_rest))
514 return self.prefilter_manager.get_handler_by_name('auto')
514 and self.function_name_regexp.match(line_info.ifun)
515 ):
516 return self.prefilter_manager.get_handler_by_name("auto")
515 else:
517 else:
516 return None
518 return None
517
519
518
520
519 #-----------------------------------------------------------------------------
521 #-----------------------------------------------------------------------------
520 # Prefilter handlers
522 # Prefilter handlers
521 #-----------------------------------------------------------------------------
523 #-----------------------------------------------------------------------------
522
524
523
525
524 class PrefilterHandler(Configurable):
526 class PrefilterHandler(Configurable):
525
527
526 handler_name = Unicode('normal')
528 handler_name = Unicode('normal')
527 esc_strings = List([])
529 esc_strings = List([])
528 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
530 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
529 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
531 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
530
532
531 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
533 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
532 super(PrefilterHandler, self).__init__(
534 super(PrefilterHandler, self).__init__(
533 shell=shell, prefilter_manager=prefilter_manager, **kwargs
535 shell=shell, prefilter_manager=prefilter_manager, **kwargs
534 )
536 )
535 self.prefilter_manager.register_handler(
537 self.prefilter_manager.register_handler(
536 self.handler_name,
538 self.handler_name,
537 self,
539 self,
538 self.esc_strings
540 self.esc_strings
539 )
541 )
540
542
541 def handle(self, line_info):
543 def handle(self, line_info):
542 # print "normal: ", line_info
544 # print "normal: ", line_info
543 """Handle normal input lines. Use as a template for handlers."""
545 """Handle normal input lines. Use as a template for handlers."""
544
546
545 # With autoindent on, we need some way to exit the input loop, and I
547 # With autoindent on, we need some way to exit the input loop, and I
546 # don't want to force the user to have to backspace all the way to
548 # don't want to force the user to have to backspace all the way to
547 # clear the line. The rule will be in this case, that either two
549 # clear the line. The rule will be in this case, that either two
548 # lines of pure whitespace in a row, or a line of pure whitespace but
550 # lines of pure whitespace in a row, or a line of pure whitespace but
549 # of a size different to the indent level, will exit the input loop.
551 # of a size different to the indent level, will exit the input loop.
550 line = line_info.line
552 line = line_info.line
551 continue_prompt = line_info.continue_prompt
553 continue_prompt = line_info.continue_prompt
552
554
553 if (continue_prompt and
555 if (continue_prompt and
554 self.shell.autoindent and
556 self.shell.autoindent and
555 line.isspace() and
557 line.isspace() and
556 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
558 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
557 line = ''
559 line = ''
558
560
559 return line
561 return line
560
562
561 def __str__(self):
563 def __str__(self):
562 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
564 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
563
565
564
566
565 class MacroHandler(PrefilterHandler):
567 class MacroHandler(PrefilterHandler):
566 handler_name = Unicode("macro")
568 handler_name = Unicode("macro")
567
569
568 def handle(self, line_info):
570 def handle(self, line_info):
569 obj = self.shell.user_ns.get(line_info.ifun)
571 obj = self.shell.user_ns.get(line_info.ifun)
570 pre_space = line_info.pre_whitespace
572 pre_space = line_info.pre_whitespace
571 line_sep = "\n" + pre_space
573 line_sep = "\n" + pre_space
572 return pre_space + line_sep.join(obj.value.splitlines())
574 return pre_space + line_sep.join(obj.value.splitlines())
573
575
574
576
575 class MagicHandler(PrefilterHandler):
577 class MagicHandler(PrefilterHandler):
576
578
577 handler_name = Unicode('magic')
579 handler_name = Unicode('magic')
578 esc_strings = List([ESC_MAGIC])
580 esc_strings = List([ESC_MAGIC])
579
581
580 def handle(self, line_info):
582 def handle(self, line_info):
581 """Execute magic functions."""
583 """Execute magic functions."""
582 ifun = line_info.ifun
584 ifun = line_info.ifun
583 the_rest = line_info.the_rest
585 the_rest = line_info.the_rest
584 #Prepare arguments for get_ipython().run_line_magic(magic_name, magic_args)
586 #Prepare arguments for get_ipython().run_line_magic(magic_name, magic_args)
585 t_arg_s = ifun + " " + the_rest
587 t_arg_s = ifun + " " + the_rest
586 t_magic_name, _, t_magic_arg_s = t_arg_s.partition(' ')
588 t_magic_name, _, t_magic_arg_s = t_arg_s.partition(' ')
587 t_magic_name = t_magic_name.lstrip(ESC_MAGIC)
589 t_magic_name = t_magic_name.lstrip(ESC_MAGIC)
588 cmd = '%sget_ipython().run_line_magic(%r, %r)' % (line_info.pre_whitespace, t_magic_name, t_magic_arg_s)
590 cmd = '%sget_ipython().run_line_magic(%r, %r)' % (line_info.pre_whitespace, t_magic_name, t_magic_arg_s)
589 return cmd
591 return cmd
590
592
591
593
592 class AutoHandler(PrefilterHandler):
594 class AutoHandler(PrefilterHandler):
593
595
594 handler_name = Unicode('auto')
596 handler_name = Unicode('auto')
595 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
597 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
596
598
597 def handle(self, line_info):
599 def handle(self, line_info):
598 """Handle lines which can be auto-executed, quoting if requested."""
600 """Handle lines which can be auto-executed, quoting if requested."""
599 line = line_info.line
601 line = line_info.line
600 ifun = line_info.ifun
602 ifun = line_info.ifun
601 the_rest = line_info.the_rest
603 the_rest = line_info.the_rest
602 esc = line_info.esc
604 esc = line_info.esc
603 continue_prompt = line_info.continue_prompt
605 continue_prompt = line_info.continue_prompt
604 obj = line_info.ofind(self.shell)['obj']
606 obj = line_info.ofind(self.shell).obj
605
607
606 # This should only be active for single-line input!
608 # This should only be active for single-line input!
607 if continue_prompt:
609 if continue_prompt:
608 return line
610 return line
609
611
610 force_auto = isinstance(obj, IPyAutocall)
612 force_auto = isinstance(obj, IPyAutocall)
611
613
612 # User objects sometimes raise exceptions on attribute access other
614 # User objects sometimes raise exceptions on attribute access other
613 # than AttributeError (we've seen it in the past), so it's safest to be
615 # than AttributeError (we've seen it in the past), so it's safest to be
614 # ultra-conservative here and catch all.
616 # ultra-conservative here and catch all.
615 try:
617 try:
616 auto_rewrite = obj.rewrite
618 auto_rewrite = obj.rewrite
617 except Exception:
619 except Exception:
618 auto_rewrite = True
620 auto_rewrite = True
619
621
620 if esc == ESC_QUOTE:
622 if esc == ESC_QUOTE:
621 # Auto-quote splitting on whitespace
623 # Auto-quote splitting on whitespace
622 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
624 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
623 elif esc == ESC_QUOTE2:
625 elif esc == ESC_QUOTE2:
624 # Auto-quote whole string
626 # Auto-quote whole string
625 newcmd = '%s("%s")' % (ifun,the_rest)
627 newcmd = '%s("%s")' % (ifun,the_rest)
626 elif esc == ESC_PAREN:
628 elif esc == ESC_PAREN:
627 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
629 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
628 else:
630 else:
629 # Auto-paren.
631 # Auto-paren.
630 if force_auto:
632 if force_auto:
631 # Don't rewrite if it is already a call.
633 # Don't rewrite if it is already a call.
632 do_rewrite = not the_rest.startswith('(')
634 do_rewrite = not the_rest.startswith('(')
633 else:
635 else:
634 if not the_rest:
636 if not the_rest:
635 # We only apply it to argument-less calls if the autocall
637 # We only apply it to argument-less calls if the autocall
636 # parameter is set to 2.
638 # parameter is set to 2.
637 do_rewrite = (self.shell.autocall >= 2)
639 do_rewrite = (self.shell.autocall >= 2)
638 elif the_rest.startswith('[') and hasattr(obj, '__getitem__'):
640 elif the_rest.startswith('[') and hasattr(obj, '__getitem__'):
639 # Don't autocall in this case: item access for an object
641 # Don't autocall in this case: item access for an object
640 # which is BOTH callable and implements __getitem__.
642 # which is BOTH callable and implements __getitem__.
641 do_rewrite = False
643 do_rewrite = False
642 else:
644 else:
643 do_rewrite = True
645 do_rewrite = True
644
646
645 # Figure out the rewritten command
647 # Figure out the rewritten command
646 if do_rewrite:
648 if do_rewrite:
647 if the_rest.endswith(';'):
649 if the_rest.endswith(';'):
648 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
650 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
649 else:
651 else:
650 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
652 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
651 else:
653 else:
652 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
654 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
653 return normal_handler.handle(line_info)
655 return normal_handler.handle(line_info)
654
656
655 # Display the rewritten call
657 # Display the rewritten call
656 if auto_rewrite:
658 if auto_rewrite:
657 self.shell.auto_rewrite_input(newcmd)
659 self.shell.auto_rewrite_input(newcmd)
658
660
659 return newcmd
661 return newcmd
660
662
661
663
662 class EmacsHandler(PrefilterHandler):
664 class EmacsHandler(PrefilterHandler):
663
665
664 handler_name = Unicode('emacs')
666 handler_name = Unicode('emacs')
665 esc_strings = List([])
667 esc_strings = List([])
666
668
667 def handle(self, line_info):
669 def handle(self, line_info):
668 """Handle input lines marked by python-mode."""
670 """Handle input lines marked by python-mode."""
669
671
670 # Currently, nothing is done. Later more functionality can be added
672 # Currently, nothing is done. Later more functionality can be added
671 # here if needed.
673 # here if needed.
672
674
673 # The input cache shouldn't be updated
675 # The input cache shouldn't be updated
674 return line_info.line
676 return line_info.line
675
677
676
678
677 #-----------------------------------------------------------------------------
679 #-----------------------------------------------------------------------------
678 # Defaults
680 # Defaults
679 #-----------------------------------------------------------------------------
681 #-----------------------------------------------------------------------------
680
682
681
683
682 _default_checkers = [
684 _default_checkers = [
683 EmacsChecker,
685 EmacsChecker,
684 MacroChecker,
686 MacroChecker,
685 IPyAutocallChecker,
687 IPyAutocallChecker,
686 AssignmentChecker,
688 AssignmentChecker,
687 AutoMagicChecker,
689 AutoMagicChecker,
688 PythonOpsChecker,
690 PythonOpsChecker,
689 AutocallChecker
691 AutocallChecker
690 ]
692 ]
691
693
692 _default_handlers = [
694 _default_handlers = [
693 PrefilterHandler,
695 PrefilterHandler,
694 MacroHandler,
696 MacroHandler,
695 MagicHandler,
697 MagicHandler,
696 AutoHandler,
698 AutoHandler,
697 EmacsHandler
699 EmacsHandler
698 ]
700 ]
@@ -1,137 +1,138 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Simple utility for splitting user input. This is used by both inputsplitter and
3 Simple utility for splitting user input. This is used by both inputsplitter and
4 prefilter.
4 prefilter.
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez
9 * Fernando Perez
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2011 The IPython Development Team
13 # Copyright (C) 2008-2011 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import re
23 import re
24 import sys
24 import sys
25
25
26 from IPython.utils import py3compat
26 from IPython.utils import py3compat
27 from IPython.utils.encoding import get_stream_enc
27 from IPython.utils.encoding import get_stream_enc
28 from IPython.core.oinspect import OInfo
28
29
29 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
30 # Main function
31 # Main function
31 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
32
33
33 # RegExp for splitting line contents into pre-char//first word-method//rest.
34 # RegExp for splitting line contents into pre-char//first word-method//rest.
34 # For clarity, each group in on one line.
35 # For clarity, each group in on one line.
35
36
36 # WARNING: update the regexp if the escapes in interactiveshell are changed, as
37 # WARNING: update the regexp if the escapes in interactiveshell are changed, as
37 # they are hardwired in.
38 # they are hardwired in.
38
39
39 # Although it's not solely driven by the regex, note that:
40 # Although it's not solely driven by the regex, note that:
40 # ,;/% only trigger if they are the first character on the line
41 # ,;/% only trigger if they are the first character on the line
41 # ! and !! trigger if they are first char(s) *or* follow an indent
42 # ! and !! trigger if they are first char(s) *or* follow an indent
42 # ? triggers as first or last char.
43 # ? triggers as first or last char.
43
44
44 line_split = re.compile(r"""
45 line_split = re.compile(r"""
45 ^(\s*) # any leading space
46 ^(\s*) # any leading space
46 ([,;/%]|!!?|\?\??)? # escape character or characters
47 ([,;/%]|!!?|\?\??)? # escape character or characters
47 \s*(%{0,2}[\w\.\*]*) # function/method, possibly with leading %
48 \s*(%{0,2}[\w\.\*]*) # function/method, possibly with leading %
48 # to correctly treat things like '?%magic'
49 # to correctly treat things like '?%magic'
49 (.*?$|$) # rest of line
50 (.*?$|$) # rest of line
50 """, re.VERBOSE)
51 """, re.VERBOSE)
51
52
52
53
53 def split_user_input(line, pattern=None):
54 def split_user_input(line, pattern=None):
54 """Split user input into initial whitespace, escape character, function part
55 """Split user input into initial whitespace, escape character, function part
55 and the rest.
56 and the rest.
56 """
57 """
57 # We need to ensure that the rest of this routine deals only with unicode
58 # We need to ensure that the rest of this routine deals only with unicode
58 encoding = get_stream_enc(sys.stdin, 'utf-8')
59 encoding = get_stream_enc(sys.stdin, 'utf-8')
59 line = py3compat.cast_unicode(line, encoding)
60 line = py3compat.cast_unicode(line, encoding)
60
61
61 if pattern is None:
62 if pattern is None:
62 pattern = line_split
63 pattern = line_split
63 match = pattern.match(line)
64 match = pattern.match(line)
64 if not match:
65 if not match:
65 # print "match failed for line '%s'" % line
66 # print "match failed for line '%s'" % line
66 try:
67 try:
67 ifun, the_rest = line.split(None,1)
68 ifun, the_rest = line.split(None,1)
68 except ValueError:
69 except ValueError:
69 # print "split failed for line '%s'" % line
70 # print "split failed for line '%s'" % line
70 ifun, the_rest = line, u''
71 ifun, the_rest = line, u''
71 pre = re.match(r'^(\s*)(.*)',line).groups()[0]
72 pre = re.match(r'^(\s*)(.*)',line).groups()[0]
72 esc = ""
73 esc = ""
73 else:
74 else:
74 pre, esc, ifun, the_rest = match.groups()
75 pre, esc, ifun, the_rest = match.groups()
75
76
76 #print 'line:<%s>' % line # dbg
77 #print 'line:<%s>' % line # dbg
77 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg
78 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg
78 return pre, esc or '', ifun.strip(), the_rest.lstrip()
79 return pre, esc or '', ifun.strip(), the_rest.lstrip()
79
80
80
81
81 class LineInfo(object):
82 class LineInfo(object):
82 """A single line of input and associated info.
83 """A single line of input and associated info.
83
84
84 Includes the following as properties:
85 Includes the following as properties:
85
86
86 line
87 line
87 The original, raw line
88 The original, raw line
88
89
89 continue_prompt
90 continue_prompt
90 Is this line a continuation in a sequence of multiline input?
91 Is this line a continuation in a sequence of multiline input?
91
92
92 pre
93 pre
93 Any leading whitespace.
94 Any leading whitespace.
94
95
95 esc
96 esc
96 The escape character(s) in pre or the empty string if there isn't one.
97 The escape character(s) in pre or the empty string if there isn't one.
97 Note that '!!' and '??' are possible values for esc. Otherwise it will
98 Note that '!!' and '??' are possible values for esc. Otherwise it will
98 always be a single character.
99 always be a single character.
99
100
100 ifun
101 ifun
101 The 'function part', which is basically the maximal initial sequence
102 The 'function part', which is basically the maximal initial sequence
102 of valid python identifiers and the '.' character. This is what is
103 of valid python identifiers and the '.' character. This is what is
103 checked for alias and magic transformations, used for auto-calling,
104 checked for alias and magic transformations, used for auto-calling,
104 etc. In contrast to Python identifiers, it may start with "%" and contain
105 etc. In contrast to Python identifiers, it may start with "%" and contain
105 "*".
106 "*".
106
107
107 the_rest
108 the_rest
108 Everything else on the line.
109 Everything else on the line.
109 """
110 """
110 def __init__(self, line, continue_prompt=False):
111 def __init__(self, line, continue_prompt=False):
111 self.line = line
112 self.line = line
112 self.continue_prompt = continue_prompt
113 self.continue_prompt = continue_prompt
113 self.pre, self.esc, self.ifun, self.the_rest = split_user_input(line)
114 self.pre, self.esc, self.ifun, self.the_rest = split_user_input(line)
114
115
115 self.pre_char = self.pre.strip()
116 self.pre_char = self.pre.strip()
116 if self.pre_char:
117 if self.pre_char:
117 self.pre_whitespace = '' # No whitespace allowed before esc chars
118 self.pre_whitespace = '' # No whitespace allowed before esc chars
118 else:
119 else:
119 self.pre_whitespace = self.pre
120 self.pre_whitespace = self.pre
120
121
121 def ofind(self, ip):
122 def ofind(self, ip) -> OInfo:
122 """Do a full, attribute-walking lookup of the ifun in the various
123 """Do a full, attribute-walking lookup of the ifun in the various
123 namespaces for the given IPython InteractiveShell instance.
124 namespaces for the given IPython InteractiveShell instance.
124
125
125 Return a dict with keys: {found, obj, ospace, ismagic}
126 Return a dict with keys: {found, obj, ospace, ismagic}
126
127
127 Note: can cause state changes because of calling getattr, but should
128 Note: can cause state changes because of calling getattr, but should
128 only be run if autocall is on and if the line hasn't matched any
129 only be run if autocall is on and if the line hasn't matched any
129 other, less dangerous handlers.
130 other, less dangerous handlers.
130
131
131 Does cache the results of the call, so can be called multiple times
132 Does cache the results of the call, so can be called multiple times
132 without worrying about *further* damaging state.
133 without worrying about *further* damaging state.
133 """
134 """
134 return ip._ofind(self.ifun)
135 return ip._ofind(self.ifun)
135
136
136 def __str__(self):
137 def __str__(self):
137 return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest)
138 return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest)
@@ -1,193 +1,193 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for completerlib.
2 """Tests for completerlib.
3
3
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Imports
7 # Imports
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9
9
10 import os
10 import os
11 import shutil
11 import shutil
12 import sys
12 import sys
13 import tempfile
13 import tempfile
14 import unittest
14 import unittest
15 from os.path import join
15 from os.path import join
16
16
17 from tempfile import TemporaryDirectory
17 from tempfile import TemporaryDirectory
18
18
19 from IPython.core.completerlib import magic_run_completer, module_completion, try_import
19 from IPython.core.completerlib import magic_run_completer, module_completion, try_import
20 from IPython.testing.decorators import onlyif_unicode_paths
20 from IPython.testing.decorators import onlyif_unicode_paths
21
21
22
22
23 class MockEvent(object):
23 class MockEvent(object):
24 def __init__(self, line):
24 def __init__(self, line):
25 self.line = line
25 self.line = line
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Test functions begin
28 # Test functions begin
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 class Test_magic_run_completer(unittest.TestCase):
30 class Test_magic_run_completer(unittest.TestCase):
31 files = [u"aao.py", u"a.py", u"b.py", u"aao.txt"]
31 files = [u"aao.py", u"a.py", u"b.py", u"aao.txt"]
32 dirs = [u"adir/", "bdir/"]
32 dirs = [u"adir/", "bdir/"]
33
33
34 def setUp(self):
34 def setUp(self):
35 self.BASETESTDIR = tempfile.mkdtemp()
35 self.BASETESTDIR = tempfile.mkdtemp()
36 for fil in self.files:
36 for fil in self.files:
37 with open(join(self.BASETESTDIR, fil), "w", encoding="utf-8") as sfile:
37 with open(join(self.BASETESTDIR, fil), "w", encoding="utf-8") as sfile:
38 sfile.write("pass\n")
38 sfile.write("pass\n")
39 for d in self.dirs:
39 for d in self.dirs:
40 os.mkdir(join(self.BASETESTDIR, d))
40 os.mkdir(join(self.BASETESTDIR, d))
41
41
42 self.oldpath = os.getcwd()
42 self.oldpath = os.getcwd()
43 os.chdir(self.BASETESTDIR)
43 os.chdir(self.BASETESTDIR)
44
44
45 def tearDown(self):
45 def tearDown(self):
46 os.chdir(self.oldpath)
46 os.chdir(self.oldpath)
47 shutil.rmtree(self.BASETESTDIR)
47 shutil.rmtree(self.BASETESTDIR)
48
48
49 def test_1(self):
49 def test_1(self):
50 """Test magic_run_completer, should match two alternatives
50 """Test magic_run_completer, should match two alternatives
51 """
51 """
52 event = MockEvent(u"%run a")
52 event = MockEvent(u"%run a")
53 mockself = None
53 mockself = None
54 match = set(magic_run_completer(mockself, event))
54 match = set(magic_run_completer(mockself, event))
55 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
55 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
56
56
57 def test_2(self):
57 def test_2(self):
58 """Test magic_run_completer, should match one alternative
58 """Test magic_run_completer, should match one alternative
59 """
59 """
60 event = MockEvent(u"%run aa")
60 event = MockEvent(u"%run aa")
61 mockself = None
61 mockself = None
62 match = set(magic_run_completer(mockself, event))
62 match = set(magic_run_completer(mockself, event))
63 self.assertEqual(match, {u"aao.py"})
63 self.assertEqual(match, {u"aao.py"})
64
64
65 def test_3(self):
65 def test_3(self):
66 """Test magic_run_completer with unterminated " """
66 """Test magic_run_completer with unterminated " """
67 event = MockEvent(u'%run "a')
67 event = MockEvent(u'%run "a')
68 mockself = None
68 mockself = None
69 match = set(magic_run_completer(mockself, event))
69 match = set(magic_run_completer(mockself, event))
70 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
70 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
71
71
72 def test_completion_more_args(self):
72 def test_completion_more_args(self):
73 event = MockEvent(u'%run a.py ')
73 event = MockEvent(u'%run a.py ')
74 match = set(magic_run_completer(None, event))
74 match = set(magic_run_completer(None, event))
75 self.assertEqual(match, set(self.files + self.dirs))
75 self.assertEqual(match, set(self.files + self.dirs))
76
76
77 def test_completion_in_dir(self):
77 def test_completion_in_dir(self):
78 # Github issue #3459
78 # Github issue #3459
79 event = MockEvent(u'%run a.py {}'.format(join(self.BASETESTDIR, 'a')))
79 event = MockEvent(u'%run a.py {}'.format(join(self.BASETESTDIR, 'a')))
80 print(repr(event.line))
80 print(repr(event.line))
81 match = set(magic_run_completer(None, event))
81 match = set(magic_run_completer(None, event))
82 # We specifically use replace here rather than normpath, because
82 # We specifically use replace here rather than normpath, because
83 # at one point there were duplicates 'adir' and 'adir/', and normpath
83 # at one point there were duplicates 'adir' and 'adir/', and normpath
84 # would hide the failure for that.
84 # would hide the failure for that.
85 self.assertEqual(match, {join(self.BASETESTDIR, f).replace('\\','/')
85 self.assertEqual(match, {join(self.BASETESTDIR, f).replace('\\','/')
86 for f in (u'a.py', u'aao.py', u'aao.txt', u'adir/')})
86 for f in (u'a.py', u'aao.py', u'aao.txt', u'adir/')})
87
87
88 class Test_magic_run_completer_nonascii(unittest.TestCase):
88 class Test_magic_run_completer_nonascii(unittest.TestCase):
89 @onlyif_unicode_paths
89 @onlyif_unicode_paths
90 def setUp(self):
90 def setUp(self):
91 self.BASETESTDIR = tempfile.mkdtemp()
91 self.BASETESTDIR = tempfile.mkdtemp()
92 for fil in [u"aaΓΈ.py", u"a.py", u"b.py"]:
92 for fil in [u"aaΓΈ.py", u"a.py", u"b.py"]:
93 with open(join(self.BASETESTDIR, fil), "w", encoding="utf-8") as sfile:
93 with open(join(self.BASETESTDIR, fil), "w", encoding="utf-8") as sfile:
94 sfile.write("pass\n")
94 sfile.write("pass\n")
95 self.oldpath = os.getcwd()
95 self.oldpath = os.getcwd()
96 os.chdir(self.BASETESTDIR)
96 os.chdir(self.BASETESTDIR)
97
97
98 def tearDown(self):
98 def tearDown(self):
99 os.chdir(self.oldpath)
99 os.chdir(self.oldpath)
100 shutil.rmtree(self.BASETESTDIR)
100 shutil.rmtree(self.BASETESTDIR)
101
101
102 @onlyif_unicode_paths
102 @onlyif_unicode_paths
103 def test_1(self):
103 def test_1(self):
104 """Test magic_run_completer, should match two alternatives
104 """Test magic_run_completer, should match two alternatives
105 """
105 """
106 event = MockEvent(u"%run a")
106 event = MockEvent(u"%run a")
107 mockself = None
107 mockself = None
108 match = set(magic_run_completer(mockself, event))
108 match = set(magic_run_completer(mockself, event))
109 self.assertEqual(match, {u"a.py", u"aaΓΈ.py"})
109 self.assertEqual(match, {u"a.py", u"aaΓΈ.py"})
110
110
111 @onlyif_unicode_paths
111 @onlyif_unicode_paths
112 def test_2(self):
112 def test_2(self):
113 """Test magic_run_completer, should match one alternative
113 """Test magic_run_completer, should match one alternative
114 """
114 """
115 event = MockEvent(u"%run aa")
115 event = MockEvent(u"%run aa")
116 mockself = None
116 mockself = None
117 match = set(magic_run_completer(mockself, event))
117 match = set(magic_run_completer(mockself, event))
118 self.assertEqual(match, {u"aaΓΈ.py"})
118 self.assertEqual(match, {u"aaΓΈ.py"})
119
119
120 @onlyif_unicode_paths
120 @onlyif_unicode_paths
121 def test_3(self):
121 def test_3(self):
122 """Test magic_run_completer with unterminated " """
122 """Test magic_run_completer with unterminated " """
123 event = MockEvent(u'%run "a')
123 event = MockEvent(u'%run "a')
124 mockself = None
124 mockself = None
125 match = set(magic_run_completer(mockself, event))
125 match = set(magic_run_completer(mockself, event))
126 self.assertEqual(match, {u"a.py", u"aaΓΈ.py"})
126 self.assertEqual(match, {u"a.py", u"aaΓΈ.py"})
127
127
128 # module_completer:
128 # module_completer:
129
129
130 def test_import_invalid_module():
130 def test_import_invalid_module():
131 """Testing of issue https://github.com/ipython/ipython/issues/1107"""
131 """Testing of issue https://github.com/ipython/ipython/issues/1107"""
132 invalid_module_names = {'foo-bar', 'foo:bar', '10foo'}
132 invalid_module_names = {'foo-bar', 'foo:bar', '10foo'}
133 valid_module_names = {'foobar'}
133 valid_module_names = {'foobar'}
134 with TemporaryDirectory() as tmpdir:
134 with TemporaryDirectory() as tmpdir:
135 sys.path.insert( 0, tmpdir )
135 sys.path.insert( 0, tmpdir )
136 for name in invalid_module_names | valid_module_names:
136 for name in invalid_module_names | valid_module_names:
137 filename = os.path.join(tmpdir, name + ".py")
137 filename = os.path.join(tmpdir, name + ".py")
138 open(filename, "w", encoding="utf-8").close()
138 open(filename, "w", encoding="utf-8").close()
139
139
140 s = set( module_completion('import foo') )
140 s = set( module_completion('import foo') )
141 intersection = s.intersection(invalid_module_names)
141 intersection = s.intersection(invalid_module_names)
142 assert intersection == set()
142 assert intersection == set()
143
143
144 assert valid_module_names.issubset(s), valid_module_names.intersection(s)
144 assert valid_module_names.issubset(s), valid_module_names.intersection(s)
145
145
146
146
147 def test_bad_module_all():
147 def test_bad_module_all():
148 """Test module with invalid __all__
148 """Test module with invalid __all__
149
149
150 https://github.com/ipython/ipython/issues/9678
150 https://github.com/ipython/ipython/issues/9678
151 """
151 """
152 testsdir = os.path.dirname(__file__)
152 testsdir = os.path.dirname(__file__)
153 sys.path.insert(0, testsdir)
153 sys.path.insert(0, testsdir)
154 try:
154 try:
155 results = module_completion("from bad_all import ")
155 results = module_completion("from bad_all import ")
156 assert "puppies" in results
156 assert "puppies" in results
157 for r in results:
157 for r in results:
158 assert isinstance(r, str)
158 assert isinstance(r, str)
159
159
160 # bad_all doesn't contain submodules, but this completion
160 # bad_all doesn't contain submodules, but this completion
161 # should finish without raising an exception:
161 # should finish without raising an exception:
162 results = module_completion("import bad_all.")
162 results = module_completion("import bad_all.")
163 assert results == []
163 assert results == []
164 finally:
164 finally:
165 sys.path.remove(testsdir)
165 sys.path.remove(testsdir)
166
166
167
167
168 def test_module_without_init():
168 def test_module_without_init():
169 """
169 """
170 Test module without __init__.py.
170 Test module without __init__.py.
171
171
172 https://github.com/ipython/ipython/issues/11226
172 https://github.com/ipython/ipython/issues/11226
173 """
173 """
174 fake_module_name = "foo"
174 fake_module_name = "foo"
175 with TemporaryDirectory() as tmpdir:
175 with TemporaryDirectory() as tmpdir:
176 sys.path.insert(0, tmpdir)
176 sys.path.insert(0, tmpdir)
177 try:
177 try:
178 os.makedirs(os.path.join(tmpdir, fake_module_name))
178 os.makedirs(os.path.join(tmpdir, fake_module_name))
179 s = try_import(mod=fake_module_name)
179 s = try_import(mod=fake_module_name)
180 assert s == []
180 assert s == [], f"for module {fake_module_name}"
181 finally:
181 finally:
182 sys.path.remove(tmpdir)
182 sys.path.remove(tmpdir)
183
183
184
184
185 def test_valid_exported_submodules():
185 def test_valid_exported_submodules():
186 """
186 """
187 Test checking exported (__all__) objects are submodules
187 Test checking exported (__all__) objects are submodules
188 """
188 """
189 results = module_completion("import os.pa")
189 results = module_completion("import os.pa")
190 # ensure we get a valid submodule:
190 # ensure we get a valid submodule:
191 assert "os.path" in results
191 assert "os.path" in results
192 # ensure we don't get objects that aren't submodules:
192 # ensure we don't get objects that aren't submodules:
193 assert "os.pathconf" not in results
193 assert "os.pathconf" not in results
@@ -1,1175 +1,1200 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.core.oinspect import OInfo
28 from IPython.testing.decorators import (
29 from IPython.testing.decorators import (
29 skipif, skip_win32, onlyif_unicode_paths, onlyif_cmds_exist,
30 skipif, skip_win32, onlyif_unicode_paths, onlyif_cmds_exist,
30 )
31 )
31 from IPython.testing import tools as tt
32 from IPython.testing import tools as tt
32 from IPython.utils.process import find_cmd
33 from IPython.utils.process import find_cmd
33
34
34 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
35 # Globals
36 # Globals
36 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
37 # This is used by every single test, no point repeating it ad nauseam
38 # This is used by every single test, no point repeating it ad nauseam
38
39
39 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
40 # Tests
41 # Tests
41 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
42
43
43 class DerivedInterrupt(KeyboardInterrupt):
44 class DerivedInterrupt(KeyboardInterrupt):
44 pass
45 pass
45
46
46 class InteractiveShellTestCase(unittest.TestCase):
47 class InteractiveShellTestCase(unittest.TestCase):
47 def test_naked_string_cells(self):
48 def test_naked_string_cells(self):
48 """Test that cells with only naked strings are fully executed"""
49 """Test that cells with only naked strings are fully executed"""
49 # First, single-line inputs
50 # First, single-line inputs
50 ip.run_cell('"a"\n')
51 ip.run_cell('"a"\n')
51 self.assertEqual(ip.user_ns['_'], 'a')
52 self.assertEqual(ip.user_ns['_'], 'a')
52 # And also multi-line cells
53 # And also multi-line cells
53 ip.run_cell('"""a\nb"""\n')
54 ip.run_cell('"""a\nb"""\n')
54 self.assertEqual(ip.user_ns['_'], 'a\nb')
55 self.assertEqual(ip.user_ns['_'], 'a\nb')
55
56
56 def test_run_empty_cell(self):
57 def test_run_empty_cell(self):
57 """Just make sure we don't get a horrible error with a blank
58 """Just make sure we don't get a horrible error with a blank
58 cell of input. Yes, I did overlook that."""
59 cell of input. Yes, I did overlook that."""
59 old_xc = ip.execution_count
60 old_xc = ip.execution_count
60 res = ip.run_cell('')
61 res = ip.run_cell('')
61 self.assertEqual(ip.execution_count, old_xc)
62 self.assertEqual(ip.execution_count, old_xc)
62 self.assertEqual(res.execution_count, None)
63 self.assertEqual(res.execution_count, None)
63
64
64 def test_run_cell_multiline(self):
65 def test_run_cell_multiline(self):
65 """Multi-block, multi-line cells must execute correctly.
66 """Multi-block, multi-line cells must execute correctly.
66 """
67 """
67 src = '\n'.join(["x=1",
68 src = '\n'.join(["x=1",
68 "y=2",
69 "y=2",
69 "if 1:",
70 "if 1:",
70 " x += 1",
71 " x += 1",
71 " y += 1",])
72 " y += 1",])
72 res = ip.run_cell(src)
73 res = ip.run_cell(src)
73 self.assertEqual(ip.user_ns['x'], 2)
74 self.assertEqual(ip.user_ns['x'], 2)
74 self.assertEqual(ip.user_ns['y'], 3)
75 self.assertEqual(ip.user_ns['y'], 3)
75 self.assertEqual(res.success, True)
76 self.assertEqual(res.success, True)
76 self.assertEqual(res.result, None)
77 self.assertEqual(res.result, None)
77
78
78 def test_multiline_string_cells(self):
79 def test_multiline_string_cells(self):
79 "Code sprinkled with multiline strings should execute (GH-306)"
80 "Code sprinkled with multiline strings should execute (GH-306)"
80 ip.run_cell('tmp=0')
81 ip.run_cell('tmp=0')
81 self.assertEqual(ip.user_ns['tmp'], 0)
82 self.assertEqual(ip.user_ns['tmp'], 0)
82 res = ip.run_cell('tmp=1;"""a\nb"""\n')
83 res = ip.run_cell('tmp=1;"""a\nb"""\n')
83 self.assertEqual(ip.user_ns['tmp'], 1)
84 self.assertEqual(ip.user_ns['tmp'], 1)
84 self.assertEqual(res.success, True)
85 self.assertEqual(res.success, True)
85 self.assertEqual(res.result, "a\nb")
86 self.assertEqual(res.result, "a\nb")
86
87
87 def test_dont_cache_with_semicolon(self):
88 def test_dont_cache_with_semicolon(self):
88 "Ending a line with semicolon should not cache the returned object (GH-307)"
89 "Ending a line with semicolon should not cache the returned object (GH-307)"
89 oldlen = len(ip.user_ns['Out'])
90 oldlen = len(ip.user_ns['Out'])
90 for cell in ['1;', '1;1;']:
91 for cell in ['1;', '1;1;']:
91 res = ip.run_cell(cell, store_history=True)
92 res = ip.run_cell(cell, store_history=True)
92 newlen = len(ip.user_ns['Out'])
93 newlen = len(ip.user_ns['Out'])
93 self.assertEqual(oldlen, newlen)
94 self.assertEqual(oldlen, newlen)
94 self.assertIsNone(res.result)
95 self.assertIsNone(res.result)
95 i = 0
96 i = 0
96 #also test the default caching behavior
97 #also test the default caching behavior
97 for cell in ['1', '1;1']:
98 for cell in ['1', '1;1']:
98 ip.run_cell(cell, store_history=True)
99 ip.run_cell(cell, store_history=True)
99 newlen = len(ip.user_ns['Out'])
100 newlen = len(ip.user_ns['Out'])
100 i += 1
101 i += 1
101 self.assertEqual(oldlen+i, newlen)
102 self.assertEqual(oldlen+i, newlen)
102
103
103 def test_syntax_error(self):
104 def test_syntax_error(self):
104 res = ip.run_cell("raise = 3")
105 res = ip.run_cell("raise = 3")
105 self.assertIsInstance(res.error_before_exec, SyntaxError)
106 self.assertIsInstance(res.error_before_exec, SyntaxError)
106
107
107 def test_open_standard_input_stream(self):
108 def test_open_standard_input_stream(self):
108 res = ip.run_cell("open(0)")
109 res = ip.run_cell("open(0)")
109 self.assertIsInstance(res.error_in_exec, ValueError)
110 self.assertIsInstance(res.error_in_exec, ValueError)
110
111
111 def test_open_standard_output_stream(self):
112 def test_open_standard_output_stream(self):
112 res = ip.run_cell("open(1)")
113 res = ip.run_cell("open(1)")
113 self.assertIsInstance(res.error_in_exec, ValueError)
114 self.assertIsInstance(res.error_in_exec, ValueError)
114
115
115 def test_open_standard_error_stream(self):
116 def test_open_standard_error_stream(self):
116 res = ip.run_cell("open(2)")
117 res = ip.run_cell("open(2)")
117 self.assertIsInstance(res.error_in_exec, ValueError)
118 self.assertIsInstance(res.error_in_exec, ValueError)
118
119
119 def test_In_variable(self):
120 def test_In_variable(self):
120 "Verify that In variable grows with user input (GH-284)"
121 "Verify that In variable grows with user input (GH-284)"
121 oldlen = len(ip.user_ns['In'])
122 oldlen = len(ip.user_ns['In'])
122 ip.run_cell('1;', store_history=True)
123 ip.run_cell('1;', store_history=True)
123 newlen = len(ip.user_ns['In'])
124 newlen = len(ip.user_ns['In'])
124 self.assertEqual(oldlen+1, newlen)
125 self.assertEqual(oldlen+1, newlen)
125 self.assertEqual(ip.user_ns['In'][-1],'1;')
126 self.assertEqual(ip.user_ns['In'][-1],'1;')
126
127
127 def test_magic_names_in_string(self):
128 def test_magic_names_in_string(self):
128 ip.run_cell('a = """\n%exit\n"""')
129 ip.run_cell('a = """\n%exit\n"""')
129 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
130 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
130
131
131 def test_trailing_newline(self):
132 def test_trailing_newline(self):
132 """test that running !(command) does not raise a SyntaxError"""
133 """test that running !(command) does not raise a SyntaxError"""
133 ip.run_cell('!(true)\n', False)
134 ip.run_cell('!(true)\n', False)
134 ip.run_cell('!(true)\n\n\n', False)
135 ip.run_cell('!(true)\n\n\n', False)
135
136
136 def test_gh_597(self):
137 def test_gh_597(self):
137 """Pretty-printing lists of objects with non-ascii reprs may cause
138 """Pretty-printing lists of objects with non-ascii reprs may cause
138 problems."""
139 problems."""
139 class Spam(object):
140 class Spam(object):
140 def __repr__(self):
141 def __repr__(self):
141 return "\xe9"*50
142 return "\xe9"*50
142 import IPython.core.formatters
143 import IPython.core.formatters
143 f = IPython.core.formatters.PlainTextFormatter()
144 f = IPython.core.formatters.PlainTextFormatter()
144 f([Spam(),Spam()])
145 f([Spam(),Spam()])
145
146
146
147
147 def test_future_flags(self):
148 def test_future_flags(self):
148 """Check that future flags are used for parsing code (gh-777)"""
149 """Check that future flags are used for parsing code (gh-777)"""
149 ip.run_cell('from __future__ import barry_as_FLUFL')
150 ip.run_cell('from __future__ import barry_as_FLUFL')
150 try:
151 try:
151 ip.run_cell('prfunc_return_val = 1 <> 2')
152 ip.run_cell('prfunc_return_val = 1 <> 2')
152 assert 'prfunc_return_val' in ip.user_ns
153 assert 'prfunc_return_val' in ip.user_ns
153 finally:
154 finally:
154 # Reset compiler flags so we don't mess up other tests.
155 # Reset compiler flags so we don't mess up other tests.
155 ip.compile.reset_compiler_flags()
156 ip.compile.reset_compiler_flags()
156
157
157 def test_can_pickle(self):
158 def test_can_pickle(self):
158 "Can we pickle objects defined interactively (GH-29)"
159 "Can we pickle objects defined interactively (GH-29)"
159 ip = get_ipython()
160 ip = get_ipython()
160 ip.reset()
161 ip.reset()
161 ip.run_cell(("class Mylist(list):\n"
162 ip.run_cell(("class Mylist(list):\n"
162 " def __init__(self,x=[]):\n"
163 " def __init__(self,x=[]):\n"
163 " list.__init__(self,x)"))
164 " list.__init__(self,x)"))
164 ip.run_cell("w=Mylist([1,2,3])")
165 ip.run_cell("w=Mylist([1,2,3])")
165
166
166 from pickle import dumps
167 from pickle import dumps
167
168
168 # We need to swap in our main module - this is only necessary
169 # We need to swap in our main module - this is only necessary
169 # inside the test framework, because IPython puts the interactive module
170 # inside the test framework, because IPython puts the interactive module
170 # in place (but the test framework undoes this).
171 # in place (but the test framework undoes this).
171 _main = sys.modules['__main__']
172 _main = sys.modules['__main__']
172 sys.modules['__main__'] = ip.user_module
173 sys.modules['__main__'] = ip.user_module
173 try:
174 try:
174 res = dumps(ip.user_ns["w"])
175 res = dumps(ip.user_ns["w"])
175 finally:
176 finally:
176 sys.modules['__main__'] = _main
177 sys.modules['__main__'] = _main
177 self.assertTrue(isinstance(res, bytes))
178 self.assertTrue(isinstance(res, bytes))
178
179
179 def test_global_ns(self):
180 def test_global_ns(self):
180 "Code in functions must be able to access variables outside them."
181 "Code in functions must be able to access variables outside them."
181 ip = get_ipython()
182 ip = get_ipython()
182 ip.run_cell("a = 10")
183 ip.run_cell("a = 10")
183 ip.run_cell(("def f(x):\n"
184 ip.run_cell(("def f(x):\n"
184 " return x + a"))
185 " return x + a"))
185 ip.run_cell("b = f(12)")
186 ip.run_cell("b = f(12)")
186 self.assertEqual(ip.user_ns["b"], 22)
187 self.assertEqual(ip.user_ns["b"], 22)
187
188
188 def test_bad_custom_tb(self):
189 def test_bad_custom_tb(self):
189 """Check that InteractiveShell is protected from bad custom exception handlers"""
190 """Check that InteractiveShell is protected from bad custom exception handlers"""
190 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
191 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
191 self.assertEqual(ip.custom_exceptions, (IOError,))
192 self.assertEqual(ip.custom_exceptions, (IOError,))
192 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
193 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
193 ip.run_cell(u'raise IOError("foo")')
194 ip.run_cell(u'raise IOError("foo")')
194 self.assertEqual(ip.custom_exceptions, ())
195 self.assertEqual(ip.custom_exceptions, ())
195
196
196 def test_bad_custom_tb_return(self):
197 def test_bad_custom_tb_return(self):
197 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
198 """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)
199 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
199 self.assertEqual(ip.custom_exceptions, (NameError,))
200 self.assertEqual(ip.custom_exceptions, (NameError,))
200 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
201 with tt.AssertPrints("Custom TB Handler failed", channel='stderr'):
201 ip.run_cell(u'a=abracadabra')
202 ip.run_cell(u'a=abracadabra')
202 self.assertEqual(ip.custom_exceptions, ())
203 self.assertEqual(ip.custom_exceptions, ())
203
204
204 def test_drop_by_id(self):
205 def test_drop_by_id(self):
205 myvars = {"a":object(), "b":object(), "c": object()}
206 myvars = {"a":object(), "b":object(), "c": object()}
206 ip.push(myvars, interactive=False)
207 ip.push(myvars, interactive=False)
207 for name in myvars:
208 for name in myvars:
208 assert name in ip.user_ns, name
209 assert name in ip.user_ns, name
209 assert name in ip.user_ns_hidden, name
210 assert name in ip.user_ns_hidden, name
210 ip.user_ns['b'] = 12
211 ip.user_ns['b'] = 12
211 ip.drop_by_id(myvars)
212 ip.drop_by_id(myvars)
212 for name in ["a", "c"]:
213 for name in ["a", "c"]:
213 assert name not in ip.user_ns, name
214 assert name not in ip.user_ns, name
214 assert name not in ip.user_ns_hidden, name
215 assert name not in ip.user_ns_hidden, name
215 assert ip.user_ns['b'] == 12
216 assert ip.user_ns['b'] == 12
216 ip.reset()
217 ip.reset()
217
218
218 def test_var_expand(self):
219 def test_var_expand(self):
219 ip.user_ns['f'] = u'Ca\xf1o'
220 ip.user_ns['f'] = u'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}'), u'echo Ca\xf1o')
222 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
223 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')
224 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
224
225
225 self.assertEqual(ip.var_expand(u"grep x | awk '{print $1}'"), u"grep x | awk '{print $1}'")
226 self.assertEqual(ip.var_expand(u"grep x | awk '{print $1}'"), u"grep x | awk '{print $1}'")
226
227
227 ip.user_ns['f'] = b'Ca\xc3\xb1o'
228 ip.user_ns['f'] = b'Ca\xc3\xb1o'
228 # This should not raise any exception:
229 # This should not raise any exception:
229 ip.var_expand(u'echo $f')
230 ip.var_expand(u'echo $f')
230
231
231 def test_var_expand_local(self):
232 def test_var_expand_local(self):
232 """Test local variable expansion in !system and %magic calls"""
233 """Test local variable expansion in !system and %magic calls"""
233 # !system
234 # !system
234 ip.run_cell(
235 ip.run_cell(
235 "def test():\n"
236 "def test():\n"
236 ' lvar = "ttt"\n'
237 ' lvar = "ttt"\n'
237 " ret = !echo {lvar}\n"
238 " ret = !echo {lvar}\n"
238 " return ret[0]\n"
239 " return ret[0]\n"
239 )
240 )
240 res = ip.user_ns["test"]()
241 res = ip.user_ns["test"]()
241 self.assertIn("ttt", res)
242 self.assertIn("ttt", res)
242
243
243 # %magic
244 # %magic
244 ip.run_cell(
245 ip.run_cell(
245 "def makemacro():\n"
246 "def makemacro():\n"
246 ' macroname = "macro_var_expand_locals"\n'
247 ' macroname = "macro_var_expand_locals"\n'
247 " %macro {macroname} codestr\n"
248 " %macro {macroname} codestr\n"
248 )
249 )
249 ip.user_ns["codestr"] = "str(12)"
250 ip.user_ns["codestr"] = "str(12)"
250 ip.run_cell("makemacro()")
251 ip.run_cell("makemacro()")
251 self.assertIn("macro_var_expand_locals", ip.user_ns)
252 self.assertIn("macro_var_expand_locals", ip.user_ns)
252
253
253 def test_var_expand_self(self):
254 def test_var_expand_self(self):
254 """Test variable expansion with the name 'self', which was failing.
255 """Test variable expansion with the name 'self', which was failing.
255
256
256 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
257 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
257 """
258 """
258 ip.run_cell(
259 ip.run_cell(
259 "class cTest:\n"
260 "class cTest:\n"
260 ' classvar="see me"\n'
261 ' classvar="see me"\n'
261 " def test(self):\n"
262 " def test(self):\n"
262 " res = !echo Variable: {self.classvar}\n"
263 " res = !echo Variable: {self.classvar}\n"
263 " return res[0]\n"
264 " return res[0]\n"
264 )
265 )
265 self.assertIn("see me", ip.user_ns["cTest"]().test())
266 self.assertIn("see me", ip.user_ns["cTest"]().test())
266
267
267 def test_bad_var_expand(self):
268 def test_bad_var_expand(self):
268 """var_expand on invalid formats shouldn't raise"""
269 """var_expand on invalid formats shouldn't raise"""
269 # SyntaxError
270 # SyntaxError
270 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
271 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
271 # NameError
272 # NameError
272 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
273 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
273 # ZeroDivisionError
274 # ZeroDivisionError
274 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
275 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
275
276
276 def test_silent_postexec(self):
277 def test_silent_postexec(self):
277 """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks"""
278 """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks"""
278 pre_explicit = mock.Mock()
279 pre_explicit = mock.Mock()
279 pre_always = mock.Mock()
280 pre_always = mock.Mock()
280 post_explicit = mock.Mock()
281 post_explicit = mock.Mock()
281 post_always = mock.Mock()
282 post_always = mock.Mock()
282 all_mocks = [pre_explicit, pre_always, post_explicit, post_always]
283 all_mocks = [pre_explicit, pre_always, post_explicit, post_always]
283
284
284 ip.events.register('pre_run_cell', pre_explicit)
285 ip.events.register('pre_run_cell', pre_explicit)
285 ip.events.register('pre_execute', pre_always)
286 ip.events.register('pre_execute', pre_always)
286 ip.events.register('post_run_cell', post_explicit)
287 ip.events.register('post_run_cell', post_explicit)
287 ip.events.register('post_execute', post_always)
288 ip.events.register('post_execute', post_always)
288
289
289 try:
290 try:
290 ip.run_cell("1", silent=True)
291 ip.run_cell("1", silent=True)
291 assert pre_always.called
292 assert pre_always.called
292 assert not pre_explicit.called
293 assert not pre_explicit.called
293 assert post_always.called
294 assert post_always.called
294 assert not post_explicit.called
295 assert not post_explicit.called
295 # double-check that non-silent exec did what we expected
296 # double-check that non-silent exec did what we expected
296 # silent to avoid
297 # silent to avoid
297 ip.run_cell("1")
298 ip.run_cell("1")
298 assert pre_explicit.called
299 assert pre_explicit.called
299 assert post_explicit.called
300 assert post_explicit.called
300 info, = pre_explicit.call_args[0]
301 info, = pre_explicit.call_args[0]
301 result, = post_explicit.call_args[0]
302 result, = post_explicit.call_args[0]
302 self.assertEqual(info, result.info)
303 self.assertEqual(info, result.info)
303 # check that post hooks are always called
304 # check that post hooks are always called
304 [m.reset_mock() for m in all_mocks]
305 [m.reset_mock() for m in all_mocks]
305 ip.run_cell("syntax error")
306 ip.run_cell("syntax error")
306 assert pre_always.called
307 assert pre_always.called
307 assert pre_explicit.called
308 assert pre_explicit.called
308 assert post_always.called
309 assert post_always.called
309 assert post_explicit.called
310 assert post_explicit.called
310 info, = pre_explicit.call_args[0]
311 info, = pre_explicit.call_args[0]
311 result, = post_explicit.call_args[0]
312 result, = post_explicit.call_args[0]
312 self.assertEqual(info, result.info)
313 self.assertEqual(info, result.info)
313 finally:
314 finally:
314 # remove post-exec
315 # remove post-exec
315 ip.events.unregister('pre_run_cell', pre_explicit)
316 ip.events.unregister('pre_run_cell', pre_explicit)
316 ip.events.unregister('pre_execute', pre_always)
317 ip.events.unregister('pre_execute', pre_always)
317 ip.events.unregister('post_run_cell', post_explicit)
318 ip.events.unregister('post_run_cell', post_explicit)
318 ip.events.unregister('post_execute', post_always)
319 ip.events.unregister('post_execute', post_always)
319
320
320 def test_silent_noadvance(self):
321 def test_silent_noadvance(self):
321 """run_cell(silent=True) doesn't advance execution_count"""
322 """run_cell(silent=True) doesn't advance execution_count"""
322 ec = ip.execution_count
323 ec = ip.execution_count
323 # silent should force store_history=False
324 # silent should force store_history=False
324 ip.run_cell("1", store_history=True, silent=True)
325 ip.run_cell("1", store_history=True, silent=True)
325
326
326 self.assertEqual(ec, ip.execution_count)
327 self.assertEqual(ec, ip.execution_count)
327 # double-check that non-silent exec did what we expected
328 # double-check that non-silent exec did what we expected
328 # silent to avoid
329 # silent to avoid
329 ip.run_cell("1", store_history=True)
330 ip.run_cell("1", store_history=True)
330 self.assertEqual(ec+1, ip.execution_count)
331 self.assertEqual(ec+1, ip.execution_count)
331
332
332 def test_silent_nodisplayhook(self):
333 def test_silent_nodisplayhook(self):
333 """run_cell(silent=True) doesn't trigger displayhook"""
334 """run_cell(silent=True) doesn't trigger displayhook"""
334 d = dict(called=False)
335 d = dict(called=False)
335
336
336 trap = ip.display_trap
337 trap = ip.display_trap
337 save_hook = trap.hook
338 save_hook = trap.hook
338
339
339 def failing_hook(*args, **kwargs):
340 def failing_hook(*args, **kwargs):
340 d['called'] = True
341 d['called'] = True
341
342
342 try:
343 try:
343 trap.hook = failing_hook
344 trap.hook = failing_hook
344 res = ip.run_cell("1", silent=True)
345 res = ip.run_cell("1", silent=True)
345 self.assertFalse(d['called'])
346 self.assertFalse(d['called'])
346 self.assertIsNone(res.result)
347 self.assertIsNone(res.result)
347 # double-check that non-silent exec did what we expected
348 # double-check that non-silent exec did what we expected
348 # silent to avoid
349 # silent to avoid
349 ip.run_cell("1")
350 ip.run_cell("1")
350 self.assertTrue(d['called'])
351 self.assertTrue(d['called'])
351 finally:
352 finally:
352 trap.hook = save_hook
353 trap.hook = save_hook
353
354
354 def test_ofind_line_magic(self):
355 def test_ofind_line_magic(self):
355 from IPython.core.magic import register_line_magic
356 from IPython.core.magic import register_line_magic
356
357
357 @register_line_magic
358 @register_line_magic
358 def lmagic(line):
359 def lmagic(line):
359 "A line magic"
360 "A line magic"
360
361
361 # Get info on line magic
362 # Get info on line magic
362 lfind = ip._ofind("lmagic")
363 lfind = ip._ofind("lmagic")
363 info = dict(
364 info = OInfo(
364 found=True,
365 found=True,
365 isalias=False,
366 isalias=False,
366 ismagic=True,
367 ismagic=True,
367 namespace="IPython internal",
368 namespace="IPython internal",
368 obj=lmagic,
369 obj=lmagic,
369 parent=None,
370 parent=None,
370 )
371 )
371 self.assertEqual(lfind, info)
372 self.assertEqual(lfind, info)
372
373
373 def test_ofind_cell_magic(self):
374 def test_ofind_cell_magic(self):
374 from IPython.core.magic import register_cell_magic
375 from IPython.core.magic import register_cell_magic
375
376
376 @register_cell_magic
377 @register_cell_magic
377 def cmagic(line, cell):
378 def cmagic(line, cell):
378 "A cell magic"
379 "A cell magic"
379
380
380 # Get info on cell magic
381 # Get info on cell magic
381 find = ip._ofind("cmagic")
382 find = ip._ofind("cmagic")
382 info = dict(
383 info = OInfo(
383 found=True,
384 found=True,
384 isalias=False,
385 isalias=False,
385 ismagic=True,
386 ismagic=True,
386 namespace="IPython internal",
387 namespace="IPython internal",
387 obj=cmagic,
388 obj=cmagic,
388 parent=None,
389 parent=None,
389 )
390 )
390 self.assertEqual(find, info)
391 self.assertEqual(find, info)
391
392
392 def test_ofind_property_with_error(self):
393 def test_ofind_property_with_error(self):
393 class A(object):
394 class A(object):
394 @property
395 @property
395 def foo(self):
396 def foo(self):
396 raise NotImplementedError() # pragma: no cover
397 raise NotImplementedError() # pragma: no cover
397
398
398 a = A()
399 a = A()
399
400
400 found = ip._ofind('a.foo', [('locals', locals())])
401 found = ip._ofind("a.foo", [("locals", locals())])
401 info = dict(found=True, isalias=False, ismagic=False,
402 info = OInfo(
402 namespace='locals', obj=A.foo, parent=a)
403 found=True,
404 isalias=False,
405 ismagic=False,
406 namespace="locals",
407 obj=A.foo,
408 parent=a,
409 )
403 self.assertEqual(found, info)
410 self.assertEqual(found, info)
404
411
405 def test_ofind_multiple_attribute_lookups(self):
412 def test_ofind_multiple_attribute_lookups(self):
406 class A(object):
413 class A(object):
407 @property
414 @property
408 def foo(self):
415 def foo(self):
409 raise NotImplementedError() # pragma: no cover
416 raise NotImplementedError() # pragma: no cover
410
417
411 a = A()
418 a = A()
412 a.a = A()
419 a.a = A()
413 a.a.a = A()
420 a.a.a = A()
414
421
415 found = ip._ofind('a.a.a.foo', [('locals', locals())])
422 found = ip._ofind("a.a.a.foo", [("locals", locals())])
416 info = dict(found=True, isalias=False, ismagic=False,
423 info = OInfo(
417 namespace='locals', obj=A.foo, parent=a.a.a)
424 found=True,
425 isalias=False,
426 ismagic=False,
427 namespace="locals",
428 obj=A.foo,
429 parent=a.a.a,
430 )
418 self.assertEqual(found, info)
431 self.assertEqual(found, info)
419
432
420 def test_ofind_slotted_attributes(self):
433 def test_ofind_slotted_attributes(self):
421 class A(object):
434 class A(object):
422 __slots__ = ['foo']
435 __slots__ = ['foo']
423 def __init__(self):
436 def __init__(self):
424 self.foo = 'bar'
437 self.foo = 'bar'
425
438
426 a = A()
439 a = A()
427 found = ip._ofind('a.foo', [('locals', locals())])
440 found = ip._ofind("a.foo", [("locals", locals())])
428 info = dict(found=True, isalias=False, ismagic=False,
441 info = OInfo(
429 namespace='locals', obj=a.foo, parent=a)
442 found=True,
443 isalias=False,
444 ismagic=False,
445 namespace="locals",
446 obj=a.foo,
447 parent=a,
448 )
430 self.assertEqual(found, info)
449 self.assertEqual(found, info)
431
450
432 found = ip._ofind('a.bar', [('locals', locals())])
451 found = ip._ofind("a.bar", [("locals", locals())])
433 info = dict(found=False, isalias=False, ismagic=False,
452 info = OInfo(
434 namespace=None, obj=None, parent=a)
453 found=False,
454 isalias=False,
455 ismagic=False,
456 namespace=None,
457 obj=None,
458 parent=a,
459 )
435 self.assertEqual(found, info)
460 self.assertEqual(found, info)
436
461
437 def test_ofind_prefers_property_to_instance_level_attribute(self):
462 def test_ofind_prefers_property_to_instance_level_attribute(self):
438 class A(object):
463 class A(object):
439 @property
464 @property
440 def foo(self):
465 def foo(self):
441 return 'bar'
466 return 'bar'
442 a = A()
467 a = A()
443 a.__dict__["foo"] = "baz"
468 a.__dict__["foo"] = "baz"
444 self.assertEqual(a.foo, "bar")
469 self.assertEqual(a.foo, "bar")
445 found = ip._ofind("a.foo", [("locals", locals())])
470 found = ip._ofind("a.foo", [("locals", locals())])
446 self.assertIs(found["obj"], A.foo)
471 self.assertIs(found.obj, A.foo)
447
472
448 def test_custom_syntaxerror_exception(self):
473 def test_custom_syntaxerror_exception(self):
449 called = []
474 called = []
450 def my_handler(shell, etype, value, tb, tb_offset=None):
475 def my_handler(shell, etype, value, tb, tb_offset=None):
451 called.append(etype)
476 called.append(etype)
452 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
477 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
453
478
454 ip.set_custom_exc((SyntaxError,), my_handler)
479 ip.set_custom_exc((SyntaxError,), my_handler)
455 try:
480 try:
456 ip.run_cell("1f")
481 ip.run_cell("1f")
457 # Check that this was called, and only once.
482 # Check that this was called, and only once.
458 self.assertEqual(called, [SyntaxError])
483 self.assertEqual(called, [SyntaxError])
459 finally:
484 finally:
460 # Reset the custom exception hook
485 # Reset the custom exception hook
461 ip.set_custom_exc((), None)
486 ip.set_custom_exc((), None)
462
487
463 def test_custom_exception(self):
488 def test_custom_exception(self):
464 called = []
489 called = []
465 def my_handler(shell, etype, value, tb, tb_offset=None):
490 def my_handler(shell, etype, value, tb, tb_offset=None):
466 called.append(etype)
491 called.append(etype)
467 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
492 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
468
493
469 ip.set_custom_exc((ValueError,), my_handler)
494 ip.set_custom_exc((ValueError,), my_handler)
470 try:
495 try:
471 res = ip.run_cell("raise ValueError('test')")
496 res = ip.run_cell("raise ValueError('test')")
472 # Check that this was called, and only once.
497 # Check that this was called, and only once.
473 self.assertEqual(called, [ValueError])
498 self.assertEqual(called, [ValueError])
474 # Check that the error is on the result object
499 # Check that the error is on the result object
475 self.assertIsInstance(res.error_in_exec, ValueError)
500 self.assertIsInstance(res.error_in_exec, ValueError)
476 finally:
501 finally:
477 # Reset the custom exception hook
502 # Reset the custom exception hook
478 ip.set_custom_exc((), None)
503 ip.set_custom_exc((), None)
479
504
480 @mock.patch("builtins.print")
505 @mock.patch("builtins.print")
481 def test_showtraceback_with_surrogates(self, mocked_print):
506 def test_showtraceback_with_surrogates(self, mocked_print):
482 values = []
507 values = []
483
508
484 def mock_print_func(value, sep=" ", end="\n", file=sys.stdout, flush=False):
509 def mock_print_func(value, sep=" ", end="\n", file=sys.stdout, flush=False):
485 values.append(value)
510 values.append(value)
486 if value == chr(0xD8FF):
511 if value == chr(0xD8FF):
487 raise UnicodeEncodeError("utf-8", chr(0xD8FF), 0, 1, "")
512 raise UnicodeEncodeError("utf-8", chr(0xD8FF), 0, 1, "")
488
513
489 # mock builtins.print
514 # mock builtins.print
490 mocked_print.side_effect = mock_print_func
515 mocked_print.side_effect = mock_print_func
491
516
492 # ip._showtraceback() is replaced in globalipapp.py.
517 # ip._showtraceback() is replaced in globalipapp.py.
493 # Call original method to test.
518 # Call original method to test.
494 interactiveshell.InteractiveShell._showtraceback(ip, None, None, chr(0xD8FF))
519 interactiveshell.InteractiveShell._showtraceback(ip, None, None, chr(0xD8FF))
495
520
496 self.assertEqual(mocked_print.call_count, 2)
521 self.assertEqual(mocked_print.call_count, 2)
497 self.assertEqual(values, [chr(0xD8FF), "\\ud8ff"])
522 self.assertEqual(values, [chr(0xD8FF), "\\ud8ff"])
498
523
499 def test_mktempfile(self):
524 def test_mktempfile(self):
500 filename = ip.mktempfile()
525 filename = ip.mktempfile()
501 # Check that we can open the file again on Windows
526 # Check that we can open the file again on Windows
502 with open(filename, "w", encoding="utf-8") as f:
527 with open(filename, "w", encoding="utf-8") as f:
503 f.write("abc")
528 f.write("abc")
504
529
505 filename = ip.mktempfile(data="blah")
530 filename = ip.mktempfile(data="blah")
506 with open(filename, "r", encoding="utf-8") as f:
531 with open(filename, "r", encoding="utf-8") as f:
507 self.assertEqual(f.read(), "blah")
532 self.assertEqual(f.read(), "blah")
508
533
509 def test_new_main_mod(self):
534 def test_new_main_mod(self):
510 # Smoketest to check that this accepts a unicode module name
535 # Smoketest to check that this accepts a unicode module name
511 name = u'jiefmw'
536 name = u'jiefmw'
512 mod = ip.new_main_mod(u'%s.py' % name, name)
537 mod = ip.new_main_mod(u'%s.py' % name, name)
513 self.assertEqual(mod.__name__, name)
538 self.assertEqual(mod.__name__, name)
514
539
515 def test_get_exception_only(self):
540 def test_get_exception_only(self):
516 try:
541 try:
517 raise KeyboardInterrupt
542 raise KeyboardInterrupt
518 except KeyboardInterrupt:
543 except KeyboardInterrupt:
519 msg = ip.get_exception_only()
544 msg = ip.get_exception_only()
520 self.assertEqual(msg, 'KeyboardInterrupt\n')
545 self.assertEqual(msg, 'KeyboardInterrupt\n')
521
546
522 try:
547 try:
523 raise DerivedInterrupt("foo")
548 raise DerivedInterrupt("foo")
524 except KeyboardInterrupt:
549 except KeyboardInterrupt:
525 msg = ip.get_exception_only()
550 msg = ip.get_exception_only()
526 self.assertEqual(msg, 'IPython.core.tests.test_interactiveshell.DerivedInterrupt: foo\n')
551 self.assertEqual(msg, 'IPython.core.tests.test_interactiveshell.DerivedInterrupt: foo\n')
527
552
528 def test_inspect_text(self):
553 def test_inspect_text(self):
529 ip.run_cell('a = 5')
554 ip.run_cell('a = 5')
530 text = ip.object_inspect_text('a')
555 text = ip.object_inspect_text('a')
531 self.assertIsInstance(text, str)
556 self.assertIsInstance(text, str)
532
557
533 def test_last_execution_result(self):
558 def test_last_execution_result(self):
534 """ Check that last execution result gets set correctly (GH-10702) """
559 """ Check that last execution result gets set correctly (GH-10702) """
535 result = ip.run_cell('a = 5; a')
560 result = ip.run_cell('a = 5; a')
536 self.assertTrue(ip.last_execution_succeeded)
561 self.assertTrue(ip.last_execution_succeeded)
537 self.assertEqual(ip.last_execution_result.result, 5)
562 self.assertEqual(ip.last_execution_result.result, 5)
538
563
539 result = ip.run_cell('a = x_invalid_id_x')
564 result = ip.run_cell('a = x_invalid_id_x')
540 self.assertFalse(ip.last_execution_succeeded)
565 self.assertFalse(ip.last_execution_succeeded)
541 self.assertFalse(ip.last_execution_result.success)
566 self.assertFalse(ip.last_execution_result.success)
542 self.assertIsInstance(ip.last_execution_result.error_in_exec, NameError)
567 self.assertIsInstance(ip.last_execution_result.error_in_exec, NameError)
543
568
544 def test_reset_aliasing(self):
569 def test_reset_aliasing(self):
545 """ Check that standard posix aliases work after %reset. """
570 """ Check that standard posix aliases work after %reset. """
546 if os.name != 'posix':
571 if os.name != 'posix':
547 return
572 return
548
573
549 ip.reset()
574 ip.reset()
550 for cmd in ('clear', 'more', 'less', 'man'):
575 for cmd in ('clear', 'more', 'less', 'man'):
551 res = ip.run_cell('%' + cmd)
576 res = ip.run_cell('%' + cmd)
552 self.assertEqual(res.success, True)
577 self.assertEqual(res.success, True)
553
578
554
579
555 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
580 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
556
581
557 @onlyif_unicode_paths
582 @onlyif_unicode_paths
558 def setUp(self):
583 def setUp(self):
559 self.BASETESTDIR = tempfile.mkdtemp()
584 self.BASETESTDIR = tempfile.mkdtemp()
560 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
585 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
561 os.mkdir(self.TESTDIR)
586 os.mkdir(self.TESTDIR)
562 with open(
587 with open(
563 join(self.TESTDIR, "Γ₯Àâtestscript.py"), "w", encoding="utf-8"
588 join(self.TESTDIR, "Γ₯Àâtestscript.py"), "w", encoding="utf-8"
564 ) as sfile:
589 ) as sfile:
565 sfile.write("pass\n")
590 sfile.write("pass\n")
566 self.oldpath = os.getcwd()
591 self.oldpath = os.getcwd()
567 os.chdir(self.TESTDIR)
592 os.chdir(self.TESTDIR)
568 self.fname = u"Γ₯Àâtestscript.py"
593 self.fname = u"Γ₯Àâtestscript.py"
569
594
570 def tearDown(self):
595 def tearDown(self):
571 os.chdir(self.oldpath)
596 os.chdir(self.oldpath)
572 shutil.rmtree(self.BASETESTDIR)
597 shutil.rmtree(self.BASETESTDIR)
573
598
574 @onlyif_unicode_paths
599 @onlyif_unicode_paths
575 def test_1(self):
600 def test_1(self):
576 """Test safe_execfile with non-ascii path
601 """Test safe_execfile with non-ascii path
577 """
602 """
578 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
603 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
579
604
580 class ExitCodeChecks(tt.TempFileMixin):
605 class ExitCodeChecks(tt.TempFileMixin):
581
606
582 def setUp(self):
607 def setUp(self):
583 self.system = ip.system_raw
608 self.system = ip.system_raw
584
609
585 def test_exit_code_ok(self):
610 def test_exit_code_ok(self):
586 self.system('exit 0')
611 self.system('exit 0')
587 self.assertEqual(ip.user_ns['_exit_code'], 0)
612 self.assertEqual(ip.user_ns['_exit_code'], 0)
588
613
589 def test_exit_code_error(self):
614 def test_exit_code_error(self):
590 self.system('exit 1')
615 self.system('exit 1')
591 self.assertEqual(ip.user_ns['_exit_code'], 1)
616 self.assertEqual(ip.user_ns['_exit_code'], 1)
592
617
593 @skipif(not hasattr(signal, 'SIGALRM'))
618 @skipif(not hasattr(signal, 'SIGALRM'))
594 def test_exit_code_signal(self):
619 def test_exit_code_signal(self):
595 self.mktmp("import signal, time\n"
620 self.mktmp("import signal, time\n"
596 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
621 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
597 "time.sleep(1)\n")
622 "time.sleep(1)\n")
598 self.system("%s %s" % (sys.executable, self.fname))
623 self.system("%s %s" % (sys.executable, self.fname))
599 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
624 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
600
625
601 @onlyif_cmds_exist("csh")
626 @onlyif_cmds_exist("csh")
602 def test_exit_code_signal_csh(self): # pragma: no cover
627 def test_exit_code_signal_csh(self): # pragma: no cover
603 SHELL = os.environ.get("SHELL", None)
628 SHELL = os.environ.get("SHELL", None)
604 os.environ["SHELL"] = find_cmd("csh")
629 os.environ["SHELL"] = find_cmd("csh")
605 try:
630 try:
606 self.test_exit_code_signal()
631 self.test_exit_code_signal()
607 finally:
632 finally:
608 if SHELL is not None:
633 if SHELL is not None:
609 os.environ['SHELL'] = SHELL
634 os.environ['SHELL'] = SHELL
610 else:
635 else:
611 del os.environ['SHELL']
636 del os.environ['SHELL']
612
637
613
638
614 class TestSystemRaw(ExitCodeChecks):
639 class TestSystemRaw(ExitCodeChecks):
615
640
616 def setUp(self):
641 def setUp(self):
617 super().setUp()
642 super().setUp()
618 self.system = ip.system_raw
643 self.system = ip.system_raw
619
644
620 @onlyif_unicode_paths
645 @onlyif_unicode_paths
621 def test_1(self):
646 def test_1(self):
622 """Test system_raw with non-ascii cmd
647 """Test system_raw with non-ascii cmd
623 """
648 """
624 cmd = u'''python -c "'Γ₯Àâ'" '''
649 cmd = u'''python -c "'Γ₯Àâ'" '''
625 ip.system_raw(cmd)
650 ip.system_raw(cmd)
626
651
627 @mock.patch('subprocess.call', side_effect=KeyboardInterrupt)
652 @mock.patch('subprocess.call', side_effect=KeyboardInterrupt)
628 @mock.patch('os.system', side_effect=KeyboardInterrupt)
653 @mock.patch('os.system', side_effect=KeyboardInterrupt)
629 def test_control_c(self, *mocks):
654 def test_control_c(self, *mocks):
630 try:
655 try:
631 self.system("sleep 1 # wont happen")
656 self.system("sleep 1 # wont happen")
632 except KeyboardInterrupt: # pragma: no cove
657 except KeyboardInterrupt: # pragma: no cove
633 self.fail(
658 self.fail(
634 "system call should intercept "
659 "system call should intercept "
635 "keyboard interrupt from subprocess.call"
660 "keyboard interrupt from subprocess.call"
636 )
661 )
637 self.assertEqual(ip.user_ns["_exit_code"], -signal.SIGINT)
662 self.assertEqual(ip.user_ns["_exit_code"], -signal.SIGINT)
638
663
639
664
640 @pytest.mark.parametrize("magic_cmd", ["pip", "conda", "cd"])
665 @pytest.mark.parametrize("magic_cmd", ["pip", "conda", "cd"])
641 def test_magic_warnings(magic_cmd):
666 def test_magic_warnings(magic_cmd):
642 if sys.platform == "win32":
667 if sys.platform == "win32":
643 to_mock = "os.system"
668 to_mock = "os.system"
644 expected_arg, expected_kwargs = magic_cmd, dict()
669 expected_arg, expected_kwargs = magic_cmd, dict()
645 else:
670 else:
646 to_mock = "subprocess.call"
671 to_mock = "subprocess.call"
647 expected_arg, expected_kwargs = magic_cmd, dict(
672 expected_arg, expected_kwargs = magic_cmd, dict(
648 shell=True, executable=os.environ.get("SHELL", None)
673 shell=True, executable=os.environ.get("SHELL", None)
649 )
674 )
650
675
651 with mock.patch(to_mock, return_value=0) as mock_sub:
676 with mock.patch(to_mock, return_value=0) as mock_sub:
652 with pytest.warns(Warning, match=r"You executed the system command"):
677 with pytest.warns(Warning, match=r"You executed the system command"):
653 ip.system_raw(magic_cmd)
678 ip.system_raw(magic_cmd)
654 mock_sub.assert_called_once_with(expected_arg, **expected_kwargs)
679 mock_sub.assert_called_once_with(expected_arg, **expected_kwargs)
655
680
656
681
657 # TODO: Exit codes are currently ignored on Windows.
682 # TODO: Exit codes are currently ignored on Windows.
658 class TestSystemPipedExitCode(ExitCodeChecks):
683 class TestSystemPipedExitCode(ExitCodeChecks):
659
684
660 def setUp(self):
685 def setUp(self):
661 super().setUp()
686 super().setUp()
662 self.system = ip.system_piped
687 self.system = ip.system_piped
663
688
664 @skip_win32
689 @skip_win32
665 def test_exit_code_ok(self):
690 def test_exit_code_ok(self):
666 ExitCodeChecks.test_exit_code_ok(self)
691 ExitCodeChecks.test_exit_code_ok(self)
667
692
668 @skip_win32
693 @skip_win32
669 def test_exit_code_error(self):
694 def test_exit_code_error(self):
670 ExitCodeChecks.test_exit_code_error(self)
695 ExitCodeChecks.test_exit_code_error(self)
671
696
672 @skip_win32
697 @skip_win32
673 def test_exit_code_signal(self):
698 def test_exit_code_signal(self):
674 ExitCodeChecks.test_exit_code_signal(self)
699 ExitCodeChecks.test_exit_code_signal(self)
675
700
676 class TestModules(tt.TempFileMixin):
701 class TestModules(tt.TempFileMixin):
677 def test_extraneous_loads(self):
702 def test_extraneous_loads(self):
678 """Test we're not loading modules on startup that we shouldn't.
703 """Test we're not loading modules on startup that we shouldn't.
679 """
704 """
680 self.mktmp("import sys\n"
705 self.mktmp("import sys\n"
681 "print('numpy' in sys.modules)\n"
706 "print('numpy' in sys.modules)\n"
682 "print('ipyparallel' in sys.modules)\n"
707 "print('ipyparallel' in sys.modules)\n"
683 "print('ipykernel' in sys.modules)\n"
708 "print('ipykernel' in sys.modules)\n"
684 )
709 )
685 out = "False\nFalse\nFalse\n"
710 out = "False\nFalse\nFalse\n"
686 tt.ipexec_validate(self.fname, out)
711 tt.ipexec_validate(self.fname, out)
687
712
688 class Negator(ast.NodeTransformer):
713 class Negator(ast.NodeTransformer):
689 """Negates all number literals in an AST."""
714 """Negates all number literals in an AST."""
690
715
691 # for python 3.7 and earlier
716 # for python 3.7 and earlier
692 def visit_Num(self, node):
717 def visit_Num(self, node):
693 node.n = -node.n
718 node.n = -node.n
694 return node
719 return node
695
720
696 # for python 3.8+
721 # for python 3.8+
697 def visit_Constant(self, node):
722 def visit_Constant(self, node):
698 if isinstance(node.value, int):
723 if isinstance(node.value, int):
699 return self.visit_Num(node)
724 return self.visit_Num(node)
700 return node
725 return node
701
726
702 class TestAstTransform(unittest.TestCase):
727 class TestAstTransform(unittest.TestCase):
703 def setUp(self):
728 def setUp(self):
704 self.negator = Negator()
729 self.negator = Negator()
705 ip.ast_transformers.append(self.negator)
730 ip.ast_transformers.append(self.negator)
706
731
707 def tearDown(self):
732 def tearDown(self):
708 ip.ast_transformers.remove(self.negator)
733 ip.ast_transformers.remove(self.negator)
709
734
710 def test_non_int_const(self):
735 def test_non_int_const(self):
711 with tt.AssertPrints("hello"):
736 with tt.AssertPrints("hello"):
712 ip.run_cell('print("hello")')
737 ip.run_cell('print("hello")')
713
738
714 def test_run_cell(self):
739 def test_run_cell(self):
715 with tt.AssertPrints("-34"):
740 with tt.AssertPrints("-34"):
716 ip.run_cell("print(12 + 22)")
741 ip.run_cell("print(12 + 22)")
717
742
718 # A named reference to a number shouldn't be transformed.
743 # A named reference to a number shouldn't be transformed.
719 ip.user_ns["n"] = 55
744 ip.user_ns["n"] = 55
720 with tt.AssertNotPrints("-55"):
745 with tt.AssertNotPrints("-55"):
721 ip.run_cell("print(n)")
746 ip.run_cell("print(n)")
722
747
723 def test_timeit(self):
748 def test_timeit(self):
724 called = set()
749 called = set()
725 def f(x):
750 def f(x):
726 called.add(x)
751 called.add(x)
727 ip.push({'f':f})
752 ip.push({'f':f})
728
753
729 with tt.AssertPrints("std. dev. of"):
754 with tt.AssertPrints("std. dev. of"):
730 ip.run_line_magic("timeit", "-n1 f(1)")
755 ip.run_line_magic("timeit", "-n1 f(1)")
731 self.assertEqual(called, {-1})
756 self.assertEqual(called, {-1})
732 called.clear()
757 called.clear()
733
758
734 with tt.AssertPrints("std. dev. of"):
759 with tt.AssertPrints("std. dev. of"):
735 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
760 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
736 self.assertEqual(called, {-2, -3})
761 self.assertEqual(called, {-2, -3})
737
762
738 def test_time(self):
763 def test_time(self):
739 called = []
764 called = []
740 def f(x):
765 def f(x):
741 called.append(x)
766 called.append(x)
742 ip.push({'f':f})
767 ip.push({'f':f})
743
768
744 # Test with an expression
769 # Test with an expression
745 with tt.AssertPrints("Wall time: "):
770 with tt.AssertPrints("Wall time: "):
746 ip.run_line_magic("time", "f(5+9)")
771 ip.run_line_magic("time", "f(5+9)")
747 self.assertEqual(called, [-14])
772 self.assertEqual(called, [-14])
748 called[:] = []
773 called[:] = []
749
774
750 # Test with a statement (different code path)
775 # Test with a statement (different code path)
751 with tt.AssertPrints("Wall time: "):
776 with tt.AssertPrints("Wall time: "):
752 ip.run_line_magic("time", "a = f(-3 + -2)")
777 ip.run_line_magic("time", "a = f(-3 + -2)")
753 self.assertEqual(called, [5])
778 self.assertEqual(called, [5])
754
779
755 def test_macro(self):
780 def test_macro(self):
756 ip.push({'a':10})
781 ip.push({'a':10})
757 # The AST transformation makes this do a+=-1
782 # The AST transformation makes this do a+=-1
758 ip.define_macro("amacro", "a+=1\nprint(a)")
783 ip.define_macro("amacro", "a+=1\nprint(a)")
759
784
760 with tt.AssertPrints("9"):
785 with tt.AssertPrints("9"):
761 ip.run_cell("amacro")
786 ip.run_cell("amacro")
762 with tt.AssertPrints("8"):
787 with tt.AssertPrints("8"):
763 ip.run_cell("amacro")
788 ip.run_cell("amacro")
764
789
765 class TestMiscTransform(unittest.TestCase):
790 class TestMiscTransform(unittest.TestCase):
766
791
767
792
768 def test_transform_only_once(self):
793 def test_transform_only_once(self):
769 cleanup = 0
794 cleanup = 0
770 line_t = 0
795 line_t = 0
771 def count_cleanup(lines):
796 def count_cleanup(lines):
772 nonlocal cleanup
797 nonlocal cleanup
773 cleanup += 1
798 cleanup += 1
774 return lines
799 return lines
775
800
776 def count_line_t(lines):
801 def count_line_t(lines):
777 nonlocal line_t
802 nonlocal line_t
778 line_t += 1
803 line_t += 1
779 return lines
804 return lines
780
805
781 ip.input_transformer_manager.cleanup_transforms.append(count_cleanup)
806 ip.input_transformer_manager.cleanup_transforms.append(count_cleanup)
782 ip.input_transformer_manager.line_transforms.append(count_line_t)
807 ip.input_transformer_manager.line_transforms.append(count_line_t)
783
808
784 ip.run_cell('1')
809 ip.run_cell('1')
785
810
786 assert cleanup == 1
811 assert cleanup == 1
787 assert line_t == 1
812 assert line_t == 1
788
813
789 class IntegerWrapper(ast.NodeTransformer):
814 class IntegerWrapper(ast.NodeTransformer):
790 """Wraps all integers in a call to Integer()"""
815 """Wraps all integers in a call to Integer()"""
791
816
792 # for Python 3.7 and earlier
817 # for Python 3.7 and earlier
793
818
794 # for Python 3.7 and earlier
819 # for Python 3.7 and earlier
795 def visit_Num(self, node):
820 def visit_Num(self, node):
796 if isinstance(node.n, int):
821 if isinstance(node.n, int):
797 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
822 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
798 args=[node], keywords=[])
823 args=[node], keywords=[])
799 return node
824 return node
800
825
801 # For Python 3.8+
826 # For Python 3.8+
802 def visit_Constant(self, node):
827 def visit_Constant(self, node):
803 if isinstance(node.value, int):
828 if isinstance(node.value, int):
804 return self.visit_Num(node)
829 return self.visit_Num(node)
805 return node
830 return node
806
831
807
832
808 class TestAstTransform2(unittest.TestCase):
833 class TestAstTransform2(unittest.TestCase):
809 def setUp(self):
834 def setUp(self):
810 self.intwrapper = IntegerWrapper()
835 self.intwrapper = IntegerWrapper()
811 ip.ast_transformers.append(self.intwrapper)
836 ip.ast_transformers.append(self.intwrapper)
812
837
813 self.calls = []
838 self.calls = []
814 def Integer(*args):
839 def Integer(*args):
815 self.calls.append(args)
840 self.calls.append(args)
816 return args
841 return args
817 ip.push({"Integer": Integer})
842 ip.push({"Integer": Integer})
818
843
819 def tearDown(self):
844 def tearDown(self):
820 ip.ast_transformers.remove(self.intwrapper)
845 ip.ast_transformers.remove(self.intwrapper)
821 del ip.user_ns['Integer']
846 del ip.user_ns['Integer']
822
847
823 def test_run_cell(self):
848 def test_run_cell(self):
824 ip.run_cell("n = 2")
849 ip.run_cell("n = 2")
825 self.assertEqual(self.calls, [(2,)])
850 self.assertEqual(self.calls, [(2,)])
826
851
827 # This shouldn't throw an error
852 # This shouldn't throw an error
828 ip.run_cell("o = 2.0")
853 ip.run_cell("o = 2.0")
829 self.assertEqual(ip.user_ns['o'], 2.0)
854 self.assertEqual(ip.user_ns['o'], 2.0)
830
855
831 def test_run_cell_non_int(self):
856 def test_run_cell_non_int(self):
832 ip.run_cell("n = 'a'")
857 ip.run_cell("n = 'a'")
833 assert self.calls == []
858 assert self.calls == []
834
859
835 def test_timeit(self):
860 def test_timeit(self):
836 called = set()
861 called = set()
837 def f(x):
862 def f(x):
838 called.add(x)
863 called.add(x)
839 ip.push({'f':f})
864 ip.push({'f':f})
840
865
841 with tt.AssertPrints("std. dev. of"):
866 with tt.AssertPrints("std. dev. of"):
842 ip.run_line_magic("timeit", "-n1 f(1)")
867 ip.run_line_magic("timeit", "-n1 f(1)")
843 self.assertEqual(called, {(1,)})
868 self.assertEqual(called, {(1,)})
844 called.clear()
869 called.clear()
845
870
846 with tt.AssertPrints("std. dev. of"):
871 with tt.AssertPrints("std. dev. of"):
847 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
872 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
848 self.assertEqual(called, {(2,), (3,)})
873 self.assertEqual(called, {(2,), (3,)})
849
874
850 class ErrorTransformer(ast.NodeTransformer):
875 class ErrorTransformer(ast.NodeTransformer):
851 """Throws an error when it sees a number."""
876 """Throws an error when it sees a number."""
852
877
853 def visit_Constant(self, node):
878 def visit_Constant(self, node):
854 if isinstance(node.value, int):
879 if isinstance(node.value, int):
855 raise ValueError("test")
880 raise ValueError("test")
856 return node
881 return node
857
882
858
883
859 class TestAstTransformError(unittest.TestCase):
884 class TestAstTransformError(unittest.TestCase):
860 def test_unregistering(self):
885 def test_unregistering(self):
861 err_transformer = ErrorTransformer()
886 err_transformer = ErrorTransformer()
862 ip.ast_transformers.append(err_transformer)
887 ip.ast_transformers.append(err_transformer)
863
888
864 with self.assertWarnsRegex(UserWarning, "It will be unregistered"):
889 with self.assertWarnsRegex(UserWarning, "It will be unregistered"):
865 ip.run_cell("1 + 2")
890 ip.run_cell("1 + 2")
866
891
867 # This should have been removed.
892 # This should have been removed.
868 self.assertNotIn(err_transformer, ip.ast_transformers)
893 self.assertNotIn(err_transformer, ip.ast_transformers)
869
894
870
895
871 class StringRejector(ast.NodeTransformer):
896 class StringRejector(ast.NodeTransformer):
872 """Throws an InputRejected when it sees a string literal.
897 """Throws an InputRejected when it sees a string literal.
873
898
874 Used to verify that NodeTransformers can signal that a piece of code should
899 Used to verify that NodeTransformers can signal that a piece of code should
875 not be executed by throwing an InputRejected.
900 not be executed by throwing an InputRejected.
876 """
901 """
877
902
878 # 3.8 only
903 # 3.8 only
879 def visit_Constant(self, node):
904 def visit_Constant(self, node):
880 if isinstance(node.value, str):
905 if isinstance(node.value, str):
881 raise InputRejected("test")
906 raise InputRejected("test")
882 return node
907 return node
883
908
884
909
885 class TestAstTransformInputRejection(unittest.TestCase):
910 class TestAstTransformInputRejection(unittest.TestCase):
886
911
887 def setUp(self):
912 def setUp(self):
888 self.transformer = StringRejector()
913 self.transformer = StringRejector()
889 ip.ast_transformers.append(self.transformer)
914 ip.ast_transformers.append(self.transformer)
890
915
891 def tearDown(self):
916 def tearDown(self):
892 ip.ast_transformers.remove(self.transformer)
917 ip.ast_transformers.remove(self.transformer)
893
918
894 def test_input_rejection(self):
919 def test_input_rejection(self):
895 """Check that NodeTransformers can reject input."""
920 """Check that NodeTransformers can reject input."""
896
921
897 expect_exception_tb = tt.AssertPrints("InputRejected: test")
922 expect_exception_tb = tt.AssertPrints("InputRejected: test")
898 expect_no_cell_output = tt.AssertNotPrints("'unsafe'", suppress=False)
923 expect_no_cell_output = tt.AssertNotPrints("'unsafe'", suppress=False)
899
924
900 # Run the same check twice to verify that the transformer is not
925 # Run the same check twice to verify that the transformer is not
901 # disabled after raising.
926 # disabled after raising.
902 with expect_exception_tb, expect_no_cell_output:
927 with expect_exception_tb, expect_no_cell_output:
903 ip.run_cell("'unsafe'")
928 ip.run_cell("'unsafe'")
904
929
905 with expect_exception_tb, expect_no_cell_output:
930 with expect_exception_tb, expect_no_cell_output:
906 res = ip.run_cell("'unsafe'")
931 res = ip.run_cell("'unsafe'")
907
932
908 self.assertIsInstance(res.error_before_exec, InputRejected)
933 self.assertIsInstance(res.error_before_exec, InputRejected)
909
934
910 def test__IPYTHON__():
935 def test__IPYTHON__():
911 # This shouldn't raise a NameError, that's all
936 # This shouldn't raise a NameError, that's all
912 __IPYTHON__
937 __IPYTHON__
913
938
914
939
915 class DummyRepr(object):
940 class DummyRepr(object):
916 def __repr__(self):
941 def __repr__(self):
917 return "DummyRepr"
942 return "DummyRepr"
918
943
919 def _repr_html_(self):
944 def _repr_html_(self):
920 return "<b>dummy</b>"
945 return "<b>dummy</b>"
921
946
922 def _repr_javascript_(self):
947 def _repr_javascript_(self):
923 return "console.log('hi');", {'key': 'value'}
948 return "console.log('hi');", {'key': 'value'}
924
949
925
950
926 def test_user_variables():
951 def test_user_variables():
927 # enable all formatters
952 # enable all formatters
928 ip.display_formatter.active_types = ip.display_formatter.format_types
953 ip.display_formatter.active_types = ip.display_formatter.format_types
929
954
930 ip.user_ns['dummy'] = d = DummyRepr()
955 ip.user_ns['dummy'] = d = DummyRepr()
931 keys = {'dummy', 'doesnotexist'}
956 keys = {'dummy', 'doesnotexist'}
932 r = ip.user_expressions({ key:key for key in keys})
957 r = ip.user_expressions({ key:key for key in keys})
933
958
934 assert keys == set(r.keys())
959 assert keys == set(r.keys())
935 dummy = r["dummy"]
960 dummy = r["dummy"]
936 assert {"status", "data", "metadata"} == set(dummy.keys())
961 assert {"status", "data", "metadata"} == set(dummy.keys())
937 assert dummy["status"] == "ok"
962 assert dummy["status"] == "ok"
938 data = dummy["data"]
963 data = dummy["data"]
939 metadata = dummy["metadata"]
964 metadata = dummy["metadata"]
940 assert data.get("text/html") == d._repr_html_()
965 assert data.get("text/html") == d._repr_html_()
941 js, jsmd = d._repr_javascript_()
966 js, jsmd = d._repr_javascript_()
942 assert data.get("application/javascript") == js
967 assert data.get("application/javascript") == js
943 assert metadata.get("application/javascript") == jsmd
968 assert metadata.get("application/javascript") == jsmd
944
969
945 dne = r["doesnotexist"]
970 dne = r["doesnotexist"]
946 assert dne["status"] == "error"
971 assert dne["status"] == "error"
947 assert dne["ename"] == "NameError"
972 assert dne["ename"] == "NameError"
948
973
949 # back to text only
974 # back to text only
950 ip.display_formatter.active_types = ['text/plain']
975 ip.display_formatter.active_types = ['text/plain']
951
976
952 def test_user_expression():
977 def test_user_expression():
953 # enable all formatters
978 # enable all formatters
954 ip.display_formatter.active_types = ip.display_formatter.format_types
979 ip.display_formatter.active_types = ip.display_formatter.format_types
955 query = {
980 query = {
956 'a' : '1 + 2',
981 'a' : '1 + 2',
957 'b' : '1/0',
982 'b' : '1/0',
958 }
983 }
959 r = ip.user_expressions(query)
984 r = ip.user_expressions(query)
960 import pprint
985 import pprint
961 pprint.pprint(r)
986 pprint.pprint(r)
962 assert set(r.keys()) == set(query.keys())
987 assert set(r.keys()) == set(query.keys())
963 a = r["a"]
988 a = r["a"]
964 assert {"status", "data", "metadata"} == set(a.keys())
989 assert {"status", "data", "metadata"} == set(a.keys())
965 assert a["status"] == "ok"
990 assert a["status"] == "ok"
966 data = a["data"]
991 data = a["data"]
967 metadata = a["metadata"]
992 metadata = a["metadata"]
968 assert data.get("text/plain") == "3"
993 assert data.get("text/plain") == "3"
969
994
970 b = r["b"]
995 b = r["b"]
971 assert b["status"] == "error"
996 assert b["status"] == "error"
972 assert b["ename"] == "ZeroDivisionError"
997 assert b["ename"] == "ZeroDivisionError"
973
998
974 # back to text only
999 # back to text only
975 ip.display_formatter.active_types = ['text/plain']
1000 ip.display_formatter.active_types = ['text/plain']
976
1001
977
1002
978 class TestSyntaxErrorTransformer(unittest.TestCase):
1003 class TestSyntaxErrorTransformer(unittest.TestCase):
979 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
1004 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
980
1005
981 @staticmethod
1006 @staticmethod
982 def transformer(lines):
1007 def transformer(lines):
983 for line in lines:
1008 for line in lines:
984 pos = line.find('syntaxerror')
1009 pos = line.find('syntaxerror')
985 if pos >= 0:
1010 if pos >= 0:
986 e = SyntaxError('input contains "syntaxerror"')
1011 e = SyntaxError('input contains "syntaxerror"')
987 e.text = line
1012 e.text = line
988 e.offset = pos + 1
1013 e.offset = pos + 1
989 raise e
1014 raise e
990 return lines
1015 return lines
991
1016
992 def setUp(self):
1017 def setUp(self):
993 ip.input_transformers_post.append(self.transformer)
1018 ip.input_transformers_post.append(self.transformer)
994
1019
995 def tearDown(self):
1020 def tearDown(self):
996 ip.input_transformers_post.remove(self.transformer)
1021 ip.input_transformers_post.remove(self.transformer)
997
1022
998 def test_syntaxerror_input_transformer(self):
1023 def test_syntaxerror_input_transformer(self):
999 with tt.AssertPrints('1234'):
1024 with tt.AssertPrints('1234'):
1000 ip.run_cell('1234')
1025 ip.run_cell('1234')
1001 with tt.AssertPrints('SyntaxError: invalid syntax'):
1026 with tt.AssertPrints('SyntaxError: invalid syntax'):
1002 ip.run_cell('1 2 3') # plain python syntax error
1027 ip.run_cell('1 2 3') # plain python syntax error
1003 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
1028 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
1004 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
1029 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
1005 with tt.AssertPrints('3456'):
1030 with tt.AssertPrints('3456'):
1006 ip.run_cell('3456')
1031 ip.run_cell('3456')
1007
1032
1008
1033
1009 class TestWarningSuppression(unittest.TestCase):
1034 class TestWarningSuppression(unittest.TestCase):
1010 def test_warning_suppression(self):
1035 def test_warning_suppression(self):
1011 ip.run_cell("import warnings")
1036 ip.run_cell("import warnings")
1012 try:
1037 try:
1013 with self.assertWarnsRegex(UserWarning, "asdf"):
1038 with self.assertWarnsRegex(UserWarning, "asdf"):
1014 ip.run_cell("warnings.warn('asdf')")
1039 ip.run_cell("warnings.warn('asdf')")
1015 # Here's the real test -- if we run that again, we should get the
1040 # 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
1041 # warning again. Traditionally, each warning was only issued once per
1017 # IPython session (approximately), even if the user typed in new and
1042 # IPython session (approximately), even if the user typed in new and
1018 # different code that should have also triggered the warning, leading
1043 # different code that should have also triggered the warning, leading
1019 # to much confusion.
1044 # to much confusion.
1020 with self.assertWarnsRegex(UserWarning, "asdf"):
1045 with self.assertWarnsRegex(UserWarning, "asdf"):
1021 ip.run_cell("warnings.warn('asdf')")
1046 ip.run_cell("warnings.warn('asdf')")
1022 finally:
1047 finally:
1023 ip.run_cell("del warnings")
1048 ip.run_cell("del warnings")
1024
1049
1025
1050
1026 def test_deprecation_warning(self):
1051 def test_deprecation_warning(self):
1027 ip.run_cell("""
1052 ip.run_cell("""
1028 import warnings
1053 import warnings
1029 def wrn():
1054 def wrn():
1030 warnings.warn(
1055 warnings.warn(
1031 "I AM A WARNING",
1056 "I AM A WARNING",
1032 DeprecationWarning
1057 DeprecationWarning
1033 )
1058 )
1034 """)
1059 """)
1035 try:
1060 try:
1036 with self.assertWarnsRegex(DeprecationWarning, "I AM A WARNING"):
1061 with self.assertWarnsRegex(DeprecationWarning, "I AM A WARNING"):
1037 ip.run_cell("wrn()")
1062 ip.run_cell("wrn()")
1038 finally:
1063 finally:
1039 ip.run_cell("del warnings")
1064 ip.run_cell("del warnings")
1040 ip.run_cell("del wrn")
1065 ip.run_cell("del wrn")
1041
1066
1042
1067
1043 class TestImportNoDeprecate(tt.TempFileMixin):
1068 class TestImportNoDeprecate(tt.TempFileMixin):
1044
1069
1045 def setUp(self):
1070 def setUp(self):
1046 """Make a valid python temp file."""
1071 """Make a valid python temp file."""
1047 self.mktmp("""
1072 self.mktmp("""
1048 import warnings
1073 import warnings
1049 def wrn():
1074 def wrn():
1050 warnings.warn(
1075 warnings.warn(
1051 "I AM A WARNING",
1076 "I AM A WARNING",
1052 DeprecationWarning
1077 DeprecationWarning
1053 )
1078 )
1054 """)
1079 """)
1055 super().setUp()
1080 super().setUp()
1056
1081
1057 def test_no_dep(self):
1082 def test_no_dep(self):
1058 """
1083 """
1059 No deprecation warning should be raised from imported functions
1084 No deprecation warning should be raised from imported functions
1060 """
1085 """
1061 ip.run_cell("from {} import wrn".format(self.fname))
1086 ip.run_cell("from {} import wrn".format(self.fname))
1062
1087
1063 with tt.AssertNotPrints("I AM A WARNING"):
1088 with tt.AssertNotPrints("I AM A WARNING"):
1064 ip.run_cell("wrn()")
1089 ip.run_cell("wrn()")
1065 ip.run_cell("del wrn")
1090 ip.run_cell("del wrn")
1066
1091
1067
1092
1068 def test_custom_exc_count():
1093 def test_custom_exc_count():
1069 hook = mock.Mock(return_value=None)
1094 hook = mock.Mock(return_value=None)
1070 ip.set_custom_exc((SyntaxError,), hook)
1095 ip.set_custom_exc((SyntaxError,), hook)
1071 before = ip.execution_count
1096 before = ip.execution_count
1072 ip.run_cell("def foo()", store_history=True)
1097 ip.run_cell("def foo()", store_history=True)
1073 # restore default excepthook
1098 # restore default excepthook
1074 ip.set_custom_exc((), None)
1099 ip.set_custom_exc((), None)
1075 assert hook.call_count == 1
1100 assert hook.call_count == 1
1076 assert ip.execution_count == before + 1
1101 assert ip.execution_count == before + 1
1077
1102
1078
1103
1079 def test_run_cell_async():
1104 def test_run_cell_async():
1080 ip.run_cell("import asyncio")
1105 ip.run_cell("import asyncio")
1081 coro = ip.run_cell_async("await asyncio.sleep(0.01)\n5")
1106 coro = ip.run_cell_async("await asyncio.sleep(0.01)\n5")
1082 assert asyncio.iscoroutine(coro)
1107 assert asyncio.iscoroutine(coro)
1083 loop = asyncio.new_event_loop()
1108 loop = asyncio.new_event_loop()
1084 result = loop.run_until_complete(coro)
1109 result = loop.run_until_complete(coro)
1085 assert isinstance(result, interactiveshell.ExecutionResult)
1110 assert isinstance(result, interactiveshell.ExecutionResult)
1086 assert result.result == 5
1111 assert result.result == 5
1087
1112
1088
1113
1089 def test_run_cell_await():
1114 def test_run_cell_await():
1090 ip.run_cell("import asyncio")
1115 ip.run_cell("import asyncio")
1091 result = ip.run_cell("await asyncio.sleep(0.01); 10")
1116 result = ip.run_cell("await asyncio.sleep(0.01); 10")
1092 assert ip.user_ns["_"] == 10
1117 assert ip.user_ns["_"] == 10
1093
1118
1094
1119
1095 def test_run_cell_asyncio_run():
1120 def test_run_cell_asyncio_run():
1096 ip.run_cell("import asyncio")
1121 ip.run_cell("import asyncio")
1097 result = ip.run_cell("await asyncio.sleep(0.01); 1")
1122 result = ip.run_cell("await asyncio.sleep(0.01); 1")
1098 assert ip.user_ns["_"] == 1
1123 assert ip.user_ns["_"] == 1
1099 result = ip.run_cell("asyncio.run(asyncio.sleep(0.01)); 2")
1124 result = ip.run_cell("asyncio.run(asyncio.sleep(0.01)); 2")
1100 assert ip.user_ns["_"] == 2
1125 assert ip.user_ns["_"] == 2
1101 result = ip.run_cell("await asyncio.sleep(0.01); 3")
1126 result = ip.run_cell("await asyncio.sleep(0.01); 3")
1102 assert ip.user_ns["_"] == 3
1127 assert ip.user_ns["_"] == 3
1103
1128
1104
1129
1105 def test_should_run_async():
1130 def test_should_run_async():
1106 assert not ip.should_run_async("a = 5", transformed_cell="a = 5")
1131 assert not ip.should_run_async("a = 5", transformed_cell="a = 5")
1107 assert ip.should_run_async("await x", transformed_cell="await x")
1132 assert ip.should_run_async("await x", transformed_cell="await x")
1108 assert ip.should_run_async(
1133 assert ip.should_run_async(
1109 "import asyncio; await asyncio.sleep(1)",
1134 "import asyncio; await asyncio.sleep(1)",
1110 transformed_cell="import asyncio; await asyncio.sleep(1)",
1135 transformed_cell="import asyncio; await asyncio.sleep(1)",
1111 )
1136 )
1112
1137
1113
1138
1114 def test_set_custom_completer():
1139 def test_set_custom_completer():
1115 num_completers = len(ip.Completer.matchers)
1140 num_completers = len(ip.Completer.matchers)
1116
1141
1117 def foo(*args, **kwargs):
1142 def foo(*args, **kwargs):
1118 return "I'm a completer!"
1143 return "I'm a completer!"
1119
1144
1120 ip.set_custom_completer(foo, 0)
1145 ip.set_custom_completer(foo, 0)
1121
1146
1122 # check that we've really added a new completer
1147 # check that we've really added a new completer
1123 assert len(ip.Completer.matchers) == num_completers + 1
1148 assert len(ip.Completer.matchers) == num_completers + 1
1124
1149
1125 # check that the first completer is the function we defined
1150 # check that the first completer is the function we defined
1126 assert ip.Completer.matchers[0]() == "I'm a completer!"
1151 assert ip.Completer.matchers[0]() == "I'm a completer!"
1127
1152
1128 # clean up
1153 # clean up
1129 ip.Completer.custom_matchers.pop()
1154 ip.Completer.custom_matchers.pop()
1130
1155
1131
1156
1132 class TestShowTracebackAttack(unittest.TestCase):
1157 class TestShowTracebackAttack(unittest.TestCase):
1133 """Test that the interactive shell is resilient against the client attack of
1158 """Test that the interactive shell is resilient against the client attack of
1134 manipulating the showtracebacks method. These attacks shouldn't result in an
1159 manipulating the showtracebacks method. These attacks shouldn't result in an
1135 unhandled exception in the kernel."""
1160 unhandled exception in the kernel."""
1136
1161
1137 def setUp(self):
1162 def setUp(self):
1138 self.orig_showtraceback = interactiveshell.InteractiveShell.showtraceback
1163 self.orig_showtraceback = interactiveshell.InteractiveShell.showtraceback
1139
1164
1140 def tearDown(self):
1165 def tearDown(self):
1141 interactiveshell.InteractiveShell.showtraceback = self.orig_showtraceback
1166 interactiveshell.InteractiveShell.showtraceback = self.orig_showtraceback
1142
1167
1143 def test_set_show_tracebacks_none(self):
1168 def test_set_show_tracebacks_none(self):
1144 """Test the case of the client setting showtracebacks to None"""
1169 """Test the case of the client setting showtracebacks to None"""
1145
1170
1146 result = ip.run_cell(
1171 result = ip.run_cell(
1147 """
1172 """
1148 import IPython.core.interactiveshell
1173 import IPython.core.interactiveshell
1149 IPython.core.interactiveshell.InteractiveShell.showtraceback = None
1174 IPython.core.interactiveshell.InteractiveShell.showtraceback = None
1150
1175
1151 assert False, "This should not raise an exception"
1176 assert False, "This should not raise an exception"
1152 """
1177 """
1153 )
1178 )
1154 print(result)
1179 print(result)
1155
1180
1156 assert result.result is None
1181 assert result.result is None
1157 assert isinstance(result.error_in_exec, TypeError)
1182 assert isinstance(result.error_in_exec, TypeError)
1158 assert str(result.error_in_exec) == "'NoneType' object is not callable"
1183 assert str(result.error_in_exec) == "'NoneType' object is not callable"
1159
1184
1160 def test_set_show_tracebacks_noop(self):
1185 def test_set_show_tracebacks_noop(self):
1161 """Test the case of the client setting showtracebacks to a no op lambda"""
1186 """Test the case of the client setting showtracebacks to a no op lambda"""
1162
1187
1163 result = ip.run_cell(
1188 result = ip.run_cell(
1164 """
1189 """
1165 import IPython.core.interactiveshell
1190 import IPython.core.interactiveshell
1166 IPython.core.interactiveshell.InteractiveShell.showtraceback = lambda *args, **kwargs: None
1191 IPython.core.interactiveshell.InteractiveShell.showtraceback = lambda *args, **kwargs: None
1167
1192
1168 assert False, "This should not raise an exception"
1193 assert False, "This should not raise an exception"
1169 """
1194 """
1170 )
1195 )
1171 print(result)
1196 print(result)
1172
1197
1173 assert result.result is None
1198 assert result.result is None
1174 assert isinstance(result.error_in_exec, AssertionError)
1199 assert isinstance(result.error_in_exec, AssertionError)
1175 assert str(result.error_in_exec) == "This should not raise an exception"
1200 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