##// END OF EJS Templates
Merge pull request #5188 from takluyver/callbacks...
Min RK -
r15667:4c8ff1de merge
parent child Browse files
Show More
@@ -0,0 +1,139 b''
1 """Infrastructure for registering and firing callbacks on application events.
2
3 Unlike :mod:`IPython.core.hooks`, which lets end users set single functions to
4 be called at specific times, or a collection of alternative methods to try,
5 callbacks are designed to be used by extension authors. A number of callbacks
6 can be registered for the same event without needing to be aware of one another.
7
8 The functions defined in this module are no-ops indicating the names of available
9 events and the arguments which will be passed to them.
10
11 .. note::
12
13 This API is experimental in IPython 2.0, and may be revised in future versions.
14 """
15 from __future__ import print_function
16
17 class EventManager(object):
18 """Manage a collection of events and a sequence of callbacks for each.
19
20 This is attached to :class:`~IPython.core.interactiveshell.InteractiveShell`
21 instances as an ``events`` attribute.
22
23 .. note::
24
25 This API is experimental in IPython 2.0, and may be revised in future versions.
26 """
27 def __init__(self, shell, available_events):
28 """Initialise the :class:`CallbackManager`.
29
30 Parameters
31 ----------
32 shell
33 The :class:`~IPython.core.interactiveshell.InteractiveShell` instance
34 available_callbacks
35 An iterable of names for callback events.
36 """
37 self.shell = shell
38 self.callbacks = {n:[] for n in available_events}
39
40 def register(self, event, function):
41 """Register a new event callback
42
43 Parameters
44 ----------
45 event : str
46 The event for which to register this callback.
47 function : callable
48 A function to be called on the given event. It should take the same
49 parameters as the appropriate callback prototype.
50
51 Raises
52 ------
53 TypeError
54 If ``function`` is not callable.
55 KeyError
56 If ``event`` is not one of the known events.
57 """
58 if not callable(function):
59 raise TypeError('Need a callable, got %r' % function)
60 self.callbacks[event].append(function)
61
62 def unregister(self, event, function):
63 """Remove a callback from the given event."""
64 self.callbacks[event].remove(function)
65
66 def reset(self, event):
67 """Clear all callbacks for the given event."""
68 self.callbacks[event] = []
69
70 def reset_all(self):
71 """Clear all callbacks for all events."""
72 self.callbacks = {n:[] for n in self.callbacks}
73
74 def trigger(self, event, *args, **kwargs):
75 """Call callbacks for ``event``.
76
77 Any additional arguments are passed to all callbacks registered for this
78 event. Exceptions raised by callbacks are caught, and a message printed.
79 """
80 for func in self.callbacks[event]:
81 try:
82 func(*args, **kwargs)
83 except Exception:
84 print("Error in callback {} (for {}):".format(func, event))
85 self.shell.showtraceback()
86
87 # event_name -> prototype mapping
88 available_events = {}
89
90 def _define_event(callback_proto):
91 available_events[callback_proto.__name__] = callback_proto
92 return callback_proto
93
94 # ------------------------------------------------------------------------------
95 # Callback prototypes
96 #
97 # No-op functions which describe the names of available events and the
98 # signatures of callbacks for those events.
99 # ------------------------------------------------------------------------------
100
101 @_define_event
102 def pre_execute():
103 """Fires before code is executed in response to user/frontend action.
104
105 This includes comm and widget messages and silent execution, as well as user
106 code cells."""
107 pass
108
109 @_define_event
110 def pre_run_cell():
111 """Fires before user-entered code runs."""
112 pass
113
114 @_define_event
115 def post_execute():
116 """Fires after code is executed in response to user/frontend action.
117
118 This includes comm and widget messages and silent execution, as well as user
119 code cells."""
120 pass
121
122 @_define_event
123 def post_run_cell():
124 """Fires after user-entered code runs."""
125 pass
126
127 @_define_event
128 def shell_initialized(ip):
129 """Fires after initialisation of :class:`~IPython.core.interactiveshell.InteractiveShell`.
130
131 This is before extensions and startup scripts are loaded, so it can only be
132 set by subclassing.
133
134 Parameters
135 ----------
136 ip : :class:`~IPython.core.interactiveshell.InteractiveShell`
137 The newly initialised shell.
138 """
139 pass
@@ -0,0 +1,46 b''
1 import unittest
2 try: # Python 3.3 +
3 from unittest.mock import Mock
4 except ImportError:
5 from mock import Mock
6
7 from IPython.core import events
8 import IPython.testing.tools as tt
9
10 def ping_received():
11 pass
12
13 class CallbackTests(unittest.TestCase):
14 def setUp(self):
15 self.em = events.EventManager(get_ipython(), {'ping_received': ping_received})
16
17 def test_register_unregister(self):
18 cb = Mock()
19
20 self.em.register('ping_received', cb)
21 self.em.trigger('ping_received')
22 self.assertEqual(cb.call_count, 1)
23
24 self.em.unregister('ping_received', cb)
25 self.em.trigger('ping_received')
26 self.assertEqual(cb.call_count, 1)
27
28 def test_reset(self):
29 cb = Mock()
30 self.em.register('ping_received', cb)
31 self.em.reset('ping_received')
32 self.em.trigger('ping_received')
33 assert not cb.called
34
35 def test_reset_all(self):
36 cb = Mock()
37 self.em.register('ping_received', cb)
38 self.em.reset_all()
39 self.em.trigger('ping_received')
40 assert not cb.called
41
42 def test_cb_error(self):
43 cb = Mock(side_effect=ValueError)
44 self.em.register('ping_received', cb)
45 with tt.AssertPrints("Error in callback"):
46 self.em.trigger('ping_received') No newline at end of file
@@ -0,0 +1,42 b''
1 =====================
2 Registering callbacks
3 =====================
4
5 Extension code can register callbacks functions which will be called on specific
6 events within the IPython code. You can see the current list of available
7 callbacks, and the parameters that will be passed with each, in the callback
8 prototype functions defined in :mod:`IPython.core.callbacks`.
9
10 To register callbacks, use :meth:`IPython.core.events.EventManager.register`.
11 For example::
12
13 class VarWatcher(object):
14 def __init__(self, ip):
15 self.shell = ip
16 self.last_x = None
17
18 def pre_execute(self):
19 self.last_x = self.shell.user_ns.get('x', None)
20
21 def post_execute(self):
22 if self.shell.user_ns.get('x', None) != self.last_x:
23 print("x changed!")
24
25 def load_ipython_extension(ip):
26 vw = VarWatcher(ip)
27 ip.events.register('pre_execute', vw.pre_execute)
28 ip.events.register('post_execute', vw.post_execute)
29
30 .. note::
31
32 This API is experimental in IPython 2.0, and may be revised in future versions.
33
34 .. seealso::
35
36 Module :mod:`IPython.core.hooks`
37 The older 'hooks' system allows end users to customise some parts of
38 IPython's behaviour.
39
40 :doc:`inputtransforms`
41 By registering input transformers that don't change code, you can monitor
42 what is being executed.
@@ -0,0 +1,1 b''
1 * A new callback system has been introduced. For details, see :doc:`/config/callbacks`.
@@ -1,18 +1,18 b''
1 1 # http://travis-ci.org/#!/ipython/ipython
2 2 language: python
3 3 python:
4 4 - 2.7
5 5 - 3.3
6 6 before_install:
7 7 # workaround for https://github.com/travis-ci/travis-cookbooks/issues/155
8 8 - sudo rm -rf /dev/shm && sudo ln -s /run/shm /dev/shm
9 9 - easy_install -q pyzmq
10 - pip install jinja2 sphinx pygments tornado requests
10 - pip install jinja2 sphinx pygments tornado requests mock
11 11 # Pierre Carrier's PPA for PhantomJS and CasperJS
12 12 - sudo add-apt-repository -y ppa:pcarrier/ppa
13 13 - sudo apt-get update
14 14 - sudo apt-get install pandoc casperjs nodejs
15 15 install:
16 16 - python setup.py install -q
17 17 script:
18 18 - cd /tmp && iptest
@@ -1,209 +1,214 b''
1 1 """Hooks for IPython.
2 2
3 3 In Python, it is possible to overwrite any method of any object if you really
4 4 want to. But IPython exposes a few 'hooks', methods which are *designed* to
5 5 be overwritten by users for customization purposes. This module defines the
6 6 default versions of all such hooks, which get used by IPython if not
7 7 overridden by the user.
8 8
9 9 Hooks are simple functions, but they should be declared with ``self`` as their
10 10 first argument, because when activated they are registered into IPython as
11 11 instance methods. The self argument will be the IPython running instance
12 12 itself, so hooks have full access to the entire IPython object.
13 13
14 14 If you wish to define a new hook and activate it, you can make an :doc:`extension
15 15 </config/extensions/index>` or a :ref:`startup script <startup_files>`. For
16 16 example, you could use a startup file like this::
17 17
18 18 import os
19 19
20 20 def calljed(self,filename, linenum):
21 21 "My editor hook calls the jed editor directly."
22 22 print "Calling my own editor, jed ..."
23 23 if os.system('jed +%d %s' % (linenum,filename)) != 0:
24 24 raise TryNext()
25 25
26 26 def load_ipython_extension(ip):
27 27 ip.set_hook('editor', calljed)
28 28
29 29 """
30 30
31 31 #*****************************************************************************
32 32 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
33 33 #
34 34 # Distributed under the terms of the BSD License. The full license is in
35 35 # the file COPYING, distributed as part of this software.
36 36 #*****************************************************************************
37 37
38 38 import os
39 39 import subprocess
40 40 import sys
41 41
42 42 from IPython.core.error import TryNext
43 43
44 44 # List here all the default hooks. For now it's just the editor functions
45 45 # but over time we'll move here all the public API for user-accessible things.
46 46
47 47 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor',
48 48 'shutdown_hook', 'late_startup_hook',
49 49 'show_in_pager','pre_prompt_hook',
50 50 'pre_run_code_hook', 'clipboard_get']
51 51
52 deprecated = {'pre_run_code_hook': "a callback for the 'pre_execute' or 'pre_run_cell' event",
53 'late_startup_hook': "a callback for the 'shell_initialized' event",
54 'shutdown_hook': "the atexit module",
55 }
56
52 57 def editor(self, filename, linenum=None, wait=True):
53 58 """Open the default editor at the given filename and linenumber.
54 59
55 60 This is IPython's default editor hook, you can use it as an example to
56 61 write your own modified one. To set your own editor function as the
57 62 new editor hook, call ip.set_hook('editor',yourfunc)."""
58 63
59 64 # IPython configures a default editor at startup by reading $EDITOR from
60 65 # the environment, and falling back on vi (unix) or notepad (win32).
61 66 editor = self.editor
62 67
63 68 # marker for at which line to open the file (for existing objects)
64 69 if linenum is None or editor=='notepad':
65 70 linemark = ''
66 71 else:
67 72 linemark = '+%d' % int(linenum)
68 73
69 74 # Enclose in quotes if necessary and legal
70 75 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
71 76 editor = '"%s"' % editor
72 77
73 78 # Call the actual editor
74 79 proc = subprocess.Popen('%s %s %s' % (editor, linemark, filename),
75 80 shell=True)
76 81 if wait and proc.wait() != 0:
77 82 raise TryNext()
78 83
79 84 import tempfile
80 85 def fix_error_editor(self,filename,linenum,column,msg):
81 86 """Open the editor at the given filename, linenumber, column and
82 87 show an error message. This is used for correcting syntax errors.
83 88 The current implementation only has special support for the VIM editor,
84 89 and falls back on the 'editor' hook if VIM is not used.
85 90
86 91 Call ip.set_hook('fix_error_editor',youfunc) to use your own function,
87 92 """
88 93 def vim_quickfix_file():
89 94 t = tempfile.NamedTemporaryFile()
90 95 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
91 96 t.flush()
92 97 return t
93 98 if os.path.basename(self.editor) != 'vim':
94 99 self.hooks.editor(filename,linenum)
95 100 return
96 101 t = vim_quickfix_file()
97 102 try:
98 103 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
99 104 raise TryNext()
100 105 finally:
101 106 t.close()
102 107
103 108
104 109 def synchronize_with_editor(self, filename, linenum, column):
105 110 pass
106 111
107 112
108 113 class CommandChainDispatcher:
109 114 """ Dispatch calls to a chain of commands until some func can handle it
110 115
111 116 Usage: instantiate, execute "add" to add commands (with optional
112 117 priority), execute normally via f() calling mechanism.
113 118
114 119 """
115 120 def __init__(self,commands=None):
116 121 if commands is None:
117 122 self.chain = []
118 123 else:
119 124 self.chain = commands
120 125
121 126
122 127 def __call__(self,*args, **kw):
123 128 """ Command chain is called just like normal func.
124 129
125 130 This will call all funcs in chain with the same args as were given to
126 131 this function, and return the result of first func that didn't raise
127 132 TryNext"""
128 133 last_exc = TryNext()
129 134 for prio,cmd in self.chain:
130 135 #print "prio",prio,"cmd",cmd #dbg
131 136 try:
132 137 return cmd(*args, **kw)
133 138 except TryNext as exc:
134 139 last_exc = exc
135 140 # if no function will accept it, raise TryNext up to the caller
136 141 raise last_exc
137 142
138 143 def __str__(self):
139 144 return str(self.chain)
140 145
141 146 def add(self, func, priority=0):
142 147 """ Add a func to the cmd chain with given priority """
143 148 self.chain.append((priority, func))
144 149 self.chain.sort(key=lambda x: x[0])
145 150
146 151 def __iter__(self):
147 152 """ Return all objects in chain.
148 153
149 154 Handy if the objects are not callable.
150 155 """
151 156 return iter(self.chain)
152 157
153 158
154 159 def shutdown_hook(self):
155 160 """ default shutdown hook
156 161
157 162 Typically, shotdown hooks should raise TryNext so all shutdown ops are done
158 163 """
159 164
160 165 #print "default shutdown hook ok" # dbg
161 166 return
162 167
163 168
164 169 def late_startup_hook(self):
165 170 """ Executed after ipython has been constructed and configured
166 171
167 172 """
168 173 #print "default startup hook ok" # dbg
169 174
170 175
171 176 def show_in_pager(self,s):
172 177 """ Run a string through pager """
173 178 # raising TryNext here will use the default paging functionality
174 179 raise TryNext
175 180
176 181
177 182 def pre_prompt_hook(self):
178 183 """ Run before displaying the next prompt
179 184
180 185 Use this e.g. to display output from asynchronous operations (in order
181 186 to not mess up text entry)
182 187 """
183 188
184 189 return None
185 190
186 191
187 192 def pre_run_code_hook(self):
188 193 """ Executed before running the (prefiltered) code in IPython """
189 194 return None
190 195
191 196
192 197 def clipboard_get(self):
193 198 """ Get text from the clipboard.
194 199 """
195 200 from IPython.lib.clipboard import (
196 201 osx_clipboard_get, tkinter_clipboard_get,
197 202 win32_clipboard_get
198 203 )
199 204 if sys.platform == 'win32':
200 205 chain = [win32_clipboard_get, tkinter_clipboard_get]
201 206 elif sys.platform == 'darwin':
202 207 chain = [osx_clipboard_get, tkinter_clipboard_get]
203 208 else:
204 209 chain = [tkinter_clipboard_get]
205 210 dispatcher = CommandChainDispatcher()
206 211 for func in chain:
207 212 dispatcher.add(func)
208 213 text = dispatcher()
209 214 return text
@@ -1,3213 +1,3217 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Main IPython class."""
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 from __future__ import absolute_import
18 18 from __future__ import print_function
19 19
20 20 import __future__
21 21 import abc
22 22 import ast
23 23 import atexit
24 24 import functools
25 25 import os
26 26 import re
27 27 import runpy
28 28 import sys
29 29 import tempfile
30 30 import types
31 31 import subprocess
32 32 from io import open as io_open
33 33
34 34 from IPython.config.configurable import SingletonConfigurable
35 35 from IPython.core import debugger, oinspect
36 36 from IPython.core import magic
37 37 from IPython.core import page
38 38 from IPython.core import prefilter
39 39 from IPython.core import shadowns
40 40 from IPython.core import ultratb
41 41 from IPython.core.alias import AliasManager, AliasError
42 42 from IPython.core.autocall import ExitAutocall
43 43 from IPython.core.builtin_trap import BuiltinTrap
44 from IPython.core.events import EventManager, available_events
44 45 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
45 46 from IPython.core.display_trap import DisplayTrap
46 47 from IPython.core.displayhook import DisplayHook
47 48 from IPython.core.displaypub import DisplayPublisher
48 49 from IPython.core.error import UsageError
49 50 from IPython.core.extensions import ExtensionManager
50 51 from IPython.core.formatters import DisplayFormatter
51 52 from IPython.core.history import HistoryManager
52 53 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC, ESC_MAGIC2
53 54 from IPython.core.logger import Logger
54 55 from IPython.core.macro import Macro
55 56 from IPython.core.payload import PayloadManager
56 57 from IPython.core.prefilter import PrefilterManager
57 58 from IPython.core.profiledir import ProfileDir
58 59 from IPython.core.prompts import PromptManager
59 60 from IPython.lib.latextools import LaTeXTool
60 61 from IPython.testing.skipdoctest import skip_doctest
61 62 from IPython.utils import PyColorize
62 63 from IPython.utils import io
63 64 from IPython.utils import py3compat
64 65 from IPython.utils import openpy
65 66 from IPython.utils.decorators import undoc
66 67 from IPython.utils.io import ask_yes_no
67 68 from IPython.utils.ipstruct import Struct
68 69 from IPython.utils.path import get_home_dir, get_ipython_dir, get_py_filename, unquote_filename
69 70 from IPython.utils.pickleshare import PickleShareDB
70 71 from IPython.utils.process import system, getoutput
71 72 from IPython.utils.py3compat import (builtin_mod, unicode_type, string_types,
72 73 with_metaclass, iteritems)
73 74 from IPython.utils.strdispatch import StrDispatch
74 75 from IPython.utils.syspathcontext import prepended_to_syspath
75 76 from IPython.utils.text import (format_screen, LSString, SList,
76 77 DollarFormatter)
77 78 from IPython.utils.traitlets import (Integer, CBool, CaselessStrEnum, Enum,
78 79 List, Unicode, Instance, Type)
79 80 from IPython.utils.warn import warn, error
80 81 import IPython.core.hooks
81 82
82 83 #-----------------------------------------------------------------------------
83 84 # Globals
84 85 #-----------------------------------------------------------------------------
85 86
86 87 # compiled regexps for autoindent management
87 88 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
88 89
89 90 #-----------------------------------------------------------------------------
90 91 # Utilities
91 92 #-----------------------------------------------------------------------------
92 93
93 94 @undoc
94 95 def softspace(file, newvalue):
95 96 """Copied from code.py, to remove the dependency"""
96 97
97 98 oldvalue = 0
98 99 try:
99 100 oldvalue = file.softspace
100 101 except AttributeError:
101 102 pass
102 103 try:
103 104 file.softspace = newvalue
104 105 except (AttributeError, TypeError):
105 106 # "attribute-less object" or "read-only attributes"
106 107 pass
107 108 return oldvalue
108 109
109 110 @undoc
110 111 def no_op(*a, **kw): pass
111 112
112 113 @undoc
113 114 class NoOpContext(object):
114 115 def __enter__(self): pass
115 116 def __exit__(self, type, value, traceback): pass
116 117 no_op_context = NoOpContext()
117 118
118 119 class SpaceInInput(Exception): pass
119 120
120 121 @undoc
121 122 class Bunch: pass
122 123
123 124
124 125 def get_default_colors():
125 126 if sys.platform=='darwin':
126 127 return "LightBG"
127 128 elif os.name=='nt':
128 129 return 'Linux'
129 130 else:
130 131 return 'Linux'
131 132
132 133
133 134 class SeparateUnicode(Unicode):
134 135 r"""A Unicode subclass to validate separate_in, separate_out, etc.
135 136
136 137 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
137 138 """
138 139
139 140 def validate(self, obj, value):
140 141 if value == '0': value = ''
141 142 value = value.replace('\\n','\n')
142 143 return super(SeparateUnicode, self).validate(obj, value)
143 144
144 145
145 146 class ReadlineNoRecord(object):
146 147 """Context manager to execute some code, then reload readline history
147 148 so that interactive input to the code doesn't appear when pressing up."""
148 149 def __init__(self, shell):
149 150 self.shell = shell
150 151 self._nested_level = 0
151 152
152 153 def __enter__(self):
153 154 if self._nested_level == 0:
154 155 try:
155 156 self.orig_length = self.current_length()
156 157 self.readline_tail = self.get_readline_tail()
157 158 except (AttributeError, IndexError): # Can fail with pyreadline
158 159 self.orig_length, self.readline_tail = 999999, []
159 160 self._nested_level += 1
160 161
161 162 def __exit__(self, type, value, traceback):
162 163 self._nested_level -= 1
163 164 if self._nested_level == 0:
164 165 # Try clipping the end if it's got longer
165 166 try:
166 167 e = self.current_length() - self.orig_length
167 168 if e > 0:
168 169 for _ in range(e):
169 170 self.shell.readline.remove_history_item(self.orig_length)
170 171
171 172 # If it still doesn't match, just reload readline history.
172 173 if self.current_length() != self.orig_length \
173 174 or self.get_readline_tail() != self.readline_tail:
174 175 self.shell.refill_readline_hist()
175 176 except (AttributeError, IndexError):
176 177 pass
177 178 # Returning False will cause exceptions to propagate
178 179 return False
179 180
180 181 def current_length(self):
181 182 return self.shell.readline.get_current_history_length()
182 183
183 184 def get_readline_tail(self, n=10):
184 185 """Get the last n items in readline history."""
185 186 end = self.shell.readline.get_current_history_length() + 1
186 187 start = max(end-n, 1)
187 188 ghi = self.shell.readline.get_history_item
188 189 return [ghi(x) for x in range(start, end)]
189 190
190 191
191 192 @undoc
192 193 class DummyMod(object):
193 194 """A dummy module used for IPython's interactive module when
194 195 a namespace must be assigned to the module's __dict__."""
195 196 pass
196 197
197 198 #-----------------------------------------------------------------------------
198 199 # Main IPython class
199 200 #-----------------------------------------------------------------------------
200 201
201 202 class InteractiveShell(SingletonConfigurable):
202 203 """An enhanced, interactive shell for Python."""
203 204
204 205 _instance = None
205 206
206 207 ast_transformers = List([], config=True, help=
207 208 """
208 209 A list of ast.NodeTransformer subclass instances, which will be applied
209 210 to user input before code is run.
210 211 """
211 212 )
212 213
213 214 autocall = Enum((0,1,2), default_value=0, config=True, help=
214 215 """
215 216 Make IPython automatically call any callable object even if you didn't
216 217 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
217 218 automatically. The value can be '0' to disable the feature, '1' for
218 219 'smart' autocall, where it is not applied if there are no more
219 220 arguments on the line, and '2' for 'full' autocall, where all callable
220 221 objects are automatically called (even if no arguments are present).
221 222 """
222 223 )
223 224 # TODO: remove all autoindent logic and put into frontends.
224 225 # We can't do this yet because even runlines uses the autoindent.
225 226 autoindent = CBool(True, config=True, help=
226 227 """
227 228 Autoindent IPython code entered interactively.
228 229 """
229 230 )
230 231 automagic = CBool(True, config=True, help=
231 232 """
232 233 Enable magic commands to be called without the leading %.
233 234 """
234 235 )
235 236 cache_size = Integer(1000, config=True, help=
236 237 """
237 238 Set the size of the output cache. The default is 1000, you can
238 239 change it permanently in your config file. Setting it to 0 completely
239 240 disables the caching system, and the minimum value accepted is 20 (if
240 241 you provide a value less than 20, it is reset to 0 and a warning is
241 242 issued). This limit is defined because otherwise you'll spend more
242 243 time re-flushing a too small cache than working
243 244 """
244 245 )
245 246 color_info = CBool(True, config=True, help=
246 247 """
247 248 Use colors for displaying information about objects. Because this
248 249 information is passed through a pager (like 'less'), and some pagers
249 250 get confused with color codes, this capability can be turned off.
250 251 """
251 252 )
252 253 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
253 254 default_value=get_default_colors(), config=True,
254 255 help="Set the color scheme (NoColor, Linux, or LightBG)."
255 256 )
256 257 colors_force = CBool(False, help=
257 258 """
258 259 Force use of ANSI color codes, regardless of OS and readline
259 260 availability.
260 261 """
261 262 # FIXME: This is essentially a hack to allow ZMQShell to show colors
262 263 # without readline on Win32. When the ZMQ formatting system is
263 264 # refactored, this should be removed.
264 265 )
265 266 debug = CBool(False, config=True)
266 267 deep_reload = CBool(False, config=True, help=
267 268 """
268 269 Enable deep (recursive) reloading by default. IPython can use the
269 270 deep_reload module which reloads changes in modules recursively (it
270 271 replaces the reload() function, so you don't need to change anything to
271 272 use it). deep_reload() forces a full reload of modules whose code may
272 273 have changed, which the default reload() function does not. When
273 274 deep_reload is off, IPython will use the normal reload(), but
274 275 deep_reload will still be available as dreload().
275 276 """
276 277 )
277 278 disable_failing_post_execute = CBool(False, config=True,
278 279 help="Don't call post-execute functions that have failed in the past."
279 280 )
280 281 display_formatter = Instance(DisplayFormatter)
281 282 displayhook_class = Type(DisplayHook)
282 283 display_pub_class = Type(DisplayPublisher)
283 284 data_pub_class = None
284 285
285 286 exit_now = CBool(False)
286 287 exiter = Instance(ExitAutocall)
287 288 def _exiter_default(self):
288 289 return ExitAutocall(self)
289 290 # Monotonically increasing execution counter
290 291 execution_count = Integer(1)
291 292 filename = Unicode("<ipython console>")
292 293 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
293 294
294 295 # Input splitter, to transform input line by line and detect when a block
295 296 # is ready to be executed.
296 297 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
297 298 (), {'line_input_checker': True})
298 299
299 300 # This InputSplitter instance is used to transform completed cells before
300 301 # running them. It allows cell magics to contain blank lines.
301 302 input_transformer_manager = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
302 303 (), {'line_input_checker': False})
303 304
304 305 logstart = CBool(False, config=True, help=
305 306 """
306 307 Start logging to the default log file.
307 308 """
308 309 )
309 310 logfile = Unicode('', config=True, help=
310 311 """
311 312 The name of the logfile to use.
312 313 """
313 314 )
314 315 logappend = Unicode('', config=True, help=
315 316 """
316 317 Start logging to the given file in append mode.
317 318 """
318 319 )
319 320 object_info_string_level = Enum((0,1,2), default_value=0,
320 321 config=True)
321 322 pdb = CBool(False, config=True, help=
322 323 """
323 324 Automatically call the pdb debugger after every exception.
324 325 """
325 326 )
326 327 multiline_history = CBool(sys.platform != 'win32', config=True,
327 328 help="Save multi-line entries as one entry in readline history"
328 329 )
329 330
330 331 # deprecated prompt traits:
331 332
332 333 prompt_in1 = Unicode('In [\\#]: ', config=True,
333 334 help="Deprecated, use PromptManager.in_template")
334 335 prompt_in2 = Unicode(' .\\D.: ', config=True,
335 336 help="Deprecated, use PromptManager.in2_template")
336 337 prompt_out = Unicode('Out[\\#]: ', config=True,
337 338 help="Deprecated, use PromptManager.out_template")
338 339 prompts_pad_left = CBool(True, config=True,
339 340 help="Deprecated, use PromptManager.justify")
340 341
341 342 def _prompt_trait_changed(self, name, old, new):
342 343 table = {
343 344 'prompt_in1' : 'in_template',
344 345 'prompt_in2' : 'in2_template',
345 346 'prompt_out' : 'out_template',
346 347 'prompts_pad_left' : 'justify',
347 348 }
348 349 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}".format(
349 350 name=name, newname=table[name])
350 351 )
351 352 # protect against weird cases where self.config may not exist:
352 353 if self.config is not None:
353 354 # propagate to corresponding PromptManager trait
354 355 setattr(self.config.PromptManager, table[name], new)
355 356
356 357 _prompt_in1_changed = _prompt_trait_changed
357 358 _prompt_in2_changed = _prompt_trait_changed
358 359 _prompt_out_changed = _prompt_trait_changed
359 360 _prompt_pad_left_changed = _prompt_trait_changed
360 361
361 362 show_rewritten_input = CBool(True, config=True,
362 363 help="Show rewritten input, e.g. for autocall."
363 364 )
364 365
365 366 quiet = CBool(False, config=True)
366 367
367 368 history_length = Integer(10000, config=True)
368 369
369 370 # The readline stuff will eventually be moved to the terminal subclass
370 371 # but for now, we can't do that as readline is welded in everywhere.
371 372 readline_use = CBool(True, config=True)
372 373 readline_remove_delims = Unicode('-/~', config=True)
373 374 readline_delims = Unicode() # set by init_readline()
374 375 # don't use \M- bindings by default, because they
375 376 # conflict with 8-bit encodings. See gh-58,gh-88
376 377 readline_parse_and_bind = List([
377 378 'tab: complete',
378 379 '"\C-l": clear-screen',
379 380 'set show-all-if-ambiguous on',
380 381 '"\C-o": tab-insert',
381 382 '"\C-r": reverse-search-history',
382 383 '"\C-s": forward-search-history',
383 384 '"\C-p": history-search-backward',
384 385 '"\C-n": history-search-forward',
385 386 '"\e[A": history-search-backward',
386 387 '"\e[B": history-search-forward',
387 388 '"\C-k": kill-line',
388 389 '"\C-u": unix-line-discard',
389 390 ], allow_none=False, config=True)
390 391
391 392 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none'],
392 393 default_value='last_expr', config=True,
393 394 help="""
394 395 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
395 396 run interactively (displaying output from expressions).""")
396 397
397 398 # TODO: this part of prompt management should be moved to the frontends.
398 399 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
399 400 separate_in = SeparateUnicode('\n', config=True)
400 401 separate_out = SeparateUnicode('', config=True)
401 402 separate_out2 = SeparateUnicode('', config=True)
402 403 wildcards_case_sensitive = CBool(True, config=True)
403 404 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
404 405 default_value='Context', config=True)
405 406
406 407 # Subcomponents of InteractiveShell
407 408 alias_manager = Instance('IPython.core.alias.AliasManager')
408 409 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
409 410 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
410 411 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
411 412 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
412 413 payload_manager = Instance('IPython.core.payload.PayloadManager')
413 414 history_manager = Instance('IPython.core.history.HistoryManager')
414 415 magics_manager = Instance('IPython.core.magic.MagicsManager')
415 416
416 417 profile_dir = Instance('IPython.core.application.ProfileDir')
417 418 @property
418 419 def profile(self):
419 420 if self.profile_dir is not None:
420 421 name = os.path.basename(self.profile_dir.location)
421 422 return name.replace('profile_','')
422 423
423 424
424 425 # Private interface
425 426 _post_execute = Instance(dict)
426 427
427 428 # Tracks any GUI loop loaded for pylab
428 429 pylab_gui_select = None
429 430
430 431 def __init__(self, ipython_dir=None, profile_dir=None,
431 432 user_module=None, user_ns=None,
432 433 custom_exceptions=((), None), **kwargs):
433 434
434 435 # This is where traits with a config_key argument are updated
435 436 # from the values on config.
436 437 super(InteractiveShell, self).__init__(**kwargs)
437 438 self.configurables = [self]
438 439
439 440 # These are relatively independent and stateless
440 441 self.init_ipython_dir(ipython_dir)
441 442 self.init_profile_dir(profile_dir)
442 443 self.init_instance_attrs()
443 444 self.init_environment()
444 445
445 446 # Check if we're in a virtualenv, and set up sys.path.
446 447 self.init_virtualenv()
447 448
448 449 # Create namespaces (user_ns, user_global_ns, etc.)
449 450 self.init_create_namespaces(user_module, user_ns)
450 451 # This has to be done after init_create_namespaces because it uses
451 452 # something in self.user_ns, but before init_sys_modules, which
452 453 # is the first thing to modify sys.
453 454 # TODO: When we override sys.stdout and sys.stderr before this class
454 455 # is created, we are saving the overridden ones here. Not sure if this
455 456 # is what we want to do.
456 457 self.save_sys_module_state()
457 458 self.init_sys_modules()
458 459
459 460 # While we're trying to have each part of the code directly access what
460 461 # it needs without keeping redundant references to objects, we have too
461 462 # much legacy code that expects ip.db to exist.
462 463 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
463 464
464 465 self.init_history()
465 466 self.init_encoding()
466 467 self.init_prefilter()
467 468
468 469 self.init_syntax_highlighting()
469 470 self.init_hooks()
471 self.init_events()
470 472 self.init_pushd_popd_magic()
471 473 # self.init_traceback_handlers use to be here, but we moved it below
472 474 # because it and init_io have to come after init_readline.
473 475 self.init_user_ns()
474 476 self.init_logger()
475 477 self.init_builtins()
476 478
477 479 # The following was in post_config_initialization
478 480 self.init_inspector()
479 481 # init_readline() must come before init_io(), because init_io uses
480 482 # readline related things.
481 483 self.init_readline()
482 484 # We save this here in case user code replaces raw_input, but it needs
483 485 # to be after init_readline(), because PyPy's readline works by replacing
484 486 # raw_input.
485 487 if py3compat.PY3:
486 488 self.raw_input_original = input
487 489 else:
488 490 self.raw_input_original = raw_input
489 491 # init_completer must come after init_readline, because it needs to
490 492 # know whether readline is present or not system-wide to configure the
491 493 # completers, since the completion machinery can now operate
492 494 # independently of readline (e.g. over the network)
493 495 self.init_completer()
494 496 # TODO: init_io() needs to happen before init_traceback handlers
495 497 # because the traceback handlers hardcode the stdout/stderr streams.
496 498 # This logic in in debugger.Pdb and should eventually be changed.
497 499 self.init_io()
498 500 self.init_traceback_handlers(custom_exceptions)
499 501 self.init_prompts()
500 502 self.init_display_formatter()
501 503 self.init_display_pub()
502 504 self.init_data_pub()
503 505 self.init_displayhook()
504 506 self.init_latextool()
505 507 self.init_magics()
506 508 self.init_alias()
507 509 self.init_logstart()
508 510 self.init_pdb()
509 511 self.init_extension_manager()
510 512 self.init_payload()
511 513 self.init_comms()
512 514 self.hooks.late_startup_hook()
515 self.events.trigger('shell_initialized', self)
513 516 atexit.register(self.atexit_operations)
514 517
515 518 def get_ipython(self):
516 519 """Return the currently running IPython instance."""
517 520 return self
518 521
519 522 #-------------------------------------------------------------------------
520 523 # Trait changed handlers
521 524 #-------------------------------------------------------------------------
522 525
523 526 def _ipython_dir_changed(self, name, new):
524 527 if not os.path.isdir(new):
525 528 os.makedirs(new, mode = 0o777)
526 529
527 530 def set_autoindent(self,value=None):
528 531 """Set the autoindent flag, checking for readline support.
529 532
530 533 If called with no arguments, it acts as a toggle."""
531 534
532 535 if value != 0 and not self.has_readline:
533 536 if os.name == 'posix':
534 537 warn("The auto-indent feature requires the readline library")
535 538 self.autoindent = 0
536 539 return
537 540 if value is None:
538 541 self.autoindent = not self.autoindent
539 542 else:
540 543 self.autoindent = value
541 544
542 545 #-------------------------------------------------------------------------
543 546 # init_* methods called by __init__
544 547 #-------------------------------------------------------------------------
545 548
546 549 def init_ipython_dir(self, ipython_dir):
547 550 if ipython_dir is not None:
548 551 self.ipython_dir = ipython_dir
549 552 return
550 553
551 554 self.ipython_dir = get_ipython_dir()
552 555
553 556 def init_profile_dir(self, profile_dir):
554 557 if profile_dir is not None:
555 558 self.profile_dir = profile_dir
556 559 return
557 560 self.profile_dir =\
558 561 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
559 562
560 563 def init_instance_attrs(self):
561 564 self.more = False
562 565
563 566 # command compiler
564 567 self.compile = CachingCompiler()
565 568
566 569 # Make an empty namespace, which extension writers can rely on both
567 570 # existing and NEVER being used by ipython itself. This gives them a
568 571 # convenient location for storing additional information and state
569 572 # their extensions may require, without fear of collisions with other
570 573 # ipython names that may develop later.
571 574 self.meta = Struct()
572 575
573 576 # Temporary files used for various purposes. Deleted at exit.
574 577 self.tempfiles = []
575 578 self.tempdirs = []
576 579
577 580 # Keep track of readline usage (later set by init_readline)
578 581 self.has_readline = False
579 582
580 583 # keep track of where we started running (mainly for crash post-mortem)
581 584 # This is not being used anywhere currently.
582 585 self.starting_dir = py3compat.getcwd()
583 586
584 587 # Indentation management
585 588 self.indent_current_nsp = 0
586 589
587 590 # Dict to track post-execution functions that have been registered
588 591 self._post_execute = {}
589 592
590 593 def init_environment(self):
591 594 """Any changes we need to make to the user's environment."""
592 595 pass
593 596
594 597 def init_encoding(self):
595 598 # Get system encoding at startup time. Certain terminals (like Emacs
596 599 # under Win32 have it set to None, and we need to have a known valid
597 600 # encoding to use in the raw_input() method
598 601 try:
599 602 self.stdin_encoding = sys.stdin.encoding or 'ascii'
600 603 except AttributeError:
601 604 self.stdin_encoding = 'ascii'
602 605
603 606 def init_syntax_highlighting(self):
604 607 # Python source parser/formatter for syntax highlighting
605 608 pyformat = PyColorize.Parser().format
606 609 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
607 610
608 611 def init_pushd_popd_magic(self):
609 612 # for pushd/popd management
610 613 self.home_dir = get_home_dir()
611 614
612 615 self.dir_stack = []
613 616
614 617 def init_logger(self):
615 618 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
616 619 logmode='rotate')
617 620
618 621 def init_logstart(self):
619 622 """Initialize logging in case it was requested at the command line.
620 623 """
621 624 if self.logappend:
622 625 self.magic('logstart %s append' % self.logappend)
623 626 elif self.logfile:
624 627 self.magic('logstart %s' % self.logfile)
625 628 elif self.logstart:
626 629 self.magic('logstart')
627 630
628 631 def init_builtins(self):
629 632 # A single, static flag that we set to True. Its presence indicates
630 633 # that an IPython shell has been created, and we make no attempts at
631 634 # removing on exit or representing the existence of more than one
632 635 # IPython at a time.
633 636 builtin_mod.__dict__['__IPYTHON__'] = True
634 637
635 638 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
636 639 # manage on enter/exit, but with all our shells it's virtually
637 640 # impossible to get all the cases right. We're leaving the name in for
638 641 # those who adapted their codes to check for this flag, but will
639 642 # eventually remove it after a few more releases.
640 643 builtin_mod.__dict__['__IPYTHON__active'] = \
641 644 'Deprecated, check for __IPYTHON__'
642 645
643 646 self.builtin_trap = BuiltinTrap(shell=self)
644 647
645 648 def init_inspector(self):
646 649 # Object inspector
647 650 self.inspector = oinspect.Inspector(oinspect.InspectColors,
648 651 PyColorize.ANSICodeColors,
649 652 'NoColor',
650 653 self.object_info_string_level)
651 654
652 655 def init_io(self):
653 656 # This will just use sys.stdout and sys.stderr. If you want to
654 657 # override sys.stdout and sys.stderr themselves, you need to do that
655 658 # *before* instantiating this class, because io holds onto
656 659 # references to the underlying streams.
657 660 if (sys.platform == 'win32' or sys.platform == 'cli') and self.has_readline:
658 661 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
659 662 else:
660 663 io.stdout = io.IOStream(sys.stdout)
661 664 io.stderr = io.IOStream(sys.stderr)
662 665
663 666 def init_prompts(self):
664 667 self.prompt_manager = PromptManager(shell=self, parent=self)
665 668 self.configurables.append(self.prompt_manager)
666 669 # Set system prompts, so that scripts can decide if they are running
667 670 # interactively.
668 671 sys.ps1 = 'In : '
669 672 sys.ps2 = '...: '
670 673 sys.ps3 = 'Out: '
671 674
672 675 def init_display_formatter(self):
673 676 self.display_formatter = DisplayFormatter(parent=self)
674 677 self.configurables.append(self.display_formatter)
675 678
676 679 def init_display_pub(self):
677 680 self.display_pub = self.display_pub_class(parent=self)
678 681 self.configurables.append(self.display_pub)
679 682
680 683 def init_data_pub(self):
681 684 if not self.data_pub_class:
682 685 self.data_pub = None
683 686 return
684 687 self.data_pub = self.data_pub_class(parent=self)
685 688 self.configurables.append(self.data_pub)
686 689
687 690 def init_displayhook(self):
688 691 # Initialize displayhook, set in/out prompts and printing system
689 692 self.displayhook = self.displayhook_class(
690 693 parent=self,
691 694 shell=self,
692 695 cache_size=self.cache_size,
693 696 )
694 697 self.configurables.append(self.displayhook)
695 698 # This is a context manager that installs/revmoes the displayhook at
696 699 # the appropriate time.
697 700 self.display_trap = DisplayTrap(hook=self.displayhook)
698 701
699 702 def init_latextool(self):
700 703 """Configure LaTeXTool."""
701 704 cfg = LaTeXTool.instance(parent=self)
702 705 if cfg not in self.configurables:
703 706 self.configurables.append(cfg)
704 707
705 708 def init_virtualenv(self):
706 709 """Add a virtualenv to sys.path so the user can import modules from it.
707 710 This isn't perfect: it doesn't use the Python interpreter with which the
708 711 virtualenv was built, and it ignores the --no-site-packages option. A
709 712 warning will appear suggesting the user installs IPython in the
710 713 virtualenv, but for many cases, it probably works well enough.
711 714
712 715 Adapted from code snippets online.
713 716
714 717 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
715 718 """
716 719 if 'VIRTUAL_ENV' not in os.environ:
717 720 # Not in a virtualenv
718 721 return
719 722
720 723 # venv detection:
721 724 # stdlib venv may symlink sys.executable, so we can't use realpath.
722 725 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
723 726 # So we just check every item in the symlink tree (generally <= 3)
724 727 p = sys.executable
725 728 paths = [p]
726 729 while os.path.islink(p):
727 730 p = os.path.join(os.path.dirname(p), os.readlink(p))
728 731 paths.append(p)
729 732 if any(p.startswith(os.environ['VIRTUAL_ENV']) for p in paths):
730 733 # Running properly in the virtualenv, don't need to do anything
731 734 return
732 735
733 736 warn("Attempting to work in a virtualenv. If you encounter problems, please "
734 737 "install IPython inside the virtualenv.")
735 738 if sys.platform == "win32":
736 739 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
737 740 else:
738 741 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
739 742 'python%d.%d' % sys.version_info[:2], 'site-packages')
740 743
741 744 import site
742 745 sys.path.insert(0, virtual_env)
743 746 site.addsitedir(virtual_env)
744 747
745 748 #-------------------------------------------------------------------------
746 749 # Things related to injections into the sys module
747 750 #-------------------------------------------------------------------------
748 751
749 752 def save_sys_module_state(self):
750 753 """Save the state of hooks in the sys module.
751 754
752 755 This has to be called after self.user_module is created.
753 756 """
754 757 self._orig_sys_module_state = {}
755 758 self._orig_sys_module_state['stdin'] = sys.stdin
756 759 self._orig_sys_module_state['stdout'] = sys.stdout
757 760 self._orig_sys_module_state['stderr'] = sys.stderr
758 761 self._orig_sys_module_state['excepthook'] = sys.excepthook
759 762 self._orig_sys_modules_main_name = self.user_module.__name__
760 763 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
761 764
762 765 def restore_sys_module_state(self):
763 766 """Restore the state of the sys module."""
764 767 try:
765 768 for k, v in iteritems(self._orig_sys_module_state):
766 769 setattr(sys, k, v)
767 770 except AttributeError:
768 771 pass
769 772 # Reset what what done in self.init_sys_modules
770 773 if self._orig_sys_modules_main_mod is not None:
771 774 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
772 775
773 776 #-------------------------------------------------------------------------
774 777 # Things related to hooks
775 778 #-------------------------------------------------------------------------
776 779
777 780 def init_hooks(self):
778 781 # hooks holds pointers used for user-side customizations
779 782 self.hooks = Struct()
780 783
781 784 self.strdispatchers = {}
782 785
783 786 # Set all default hooks, defined in the IPython.hooks module.
784 787 hooks = IPython.core.hooks
785 788 for hook_name in hooks.__all__:
786 789 # default hooks have priority 100, i.e. low; user hooks should have
787 790 # 0-100 priority
788 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
791 self.set_hook(hook_name,getattr(hooks,hook_name), 100, _warn_deprecated=False)
789 792
790 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
793 def set_hook(self,name,hook, priority=50, str_key=None, re_key=None,
794 _warn_deprecated=True):
791 795 """set_hook(name,hook) -> sets an internal IPython hook.
792 796
793 797 IPython exposes some of its internal API as user-modifiable hooks. By
794 798 adding your function to one of these hooks, you can modify IPython's
795 799 behavior to call at runtime your own routines."""
796 800
797 801 # At some point in the future, this should validate the hook before it
798 802 # accepts it. Probably at least check that the hook takes the number
799 803 # of args it's supposed to.
800 804
801 805 f = types.MethodType(hook,self)
802 806
803 807 # check if the hook is for strdispatcher first
804 808 if str_key is not None:
805 809 sdp = self.strdispatchers.get(name, StrDispatch())
806 810 sdp.add_s(str_key, f, priority )
807 811 self.strdispatchers[name] = sdp
808 812 return
809 813 if re_key is not None:
810 814 sdp = self.strdispatchers.get(name, StrDispatch())
811 815 sdp.add_re(re.compile(re_key), f, priority )
812 816 self.strdispatchers[name] = sdp
813 817 return
814 818
815 819 dp = getattr(self.hooks, name, None)
816 820 if name not in IPython.core.hooks.__all__:
817 821 print("Warning! Hook '%s' is not one of %s" % \
818 822 (name, IPython.core.hooks.__all__ ))
823
824 if _warn_deprecated and (name in IPython.core.hooks.deprecated):
825 alternative = IPython.core.hooks.deprecated[name]
826 warn("Hook {} is deprecated. Use {} instead.".format(name, alternative))
827
819 828 if not dp:
820 829 dp = IPython.core.hooks.CommandChainDispatcher()
821 830
822 831 try:
823 832 dp.add(f,priority)
824 833 except AttributeError:
825 834 # it was not commandchain, plain old func - replace
826 835 dp = f
827 836
828 837 setattr(self.hooks,name, dp)
829 838
839 #-------------------------------------------------------------------------
840 # Things related to events
841 #-------------------------------------------------------------------------
842
843 def init_events(self):
844 self.events = EventManager(self, available_events)
845
830 846 def register_post_execute(self, func):
831 """Register a function for calling after code execution.
847 """DEPRECATED: Use ip.events.register('post_run_cell', func)
848
849 Register a function for calling after code execution.
832 850 """
833 if not callable(func):
834 raise ValueError('argument %s must be callable' % func)
835 self._post_execute[func] = True
851 warn("ip.register_post_execute is deprecated, use "
852 "ip.events.register('post_run_cell', func) instead.")
853 self.events.register('post_run_cell', func)
836 854
837 855 #-------------------------------------------------------------------------
838 856 # Things related to the "main" module
839 857 #-------------------------------------------------------------------------
840 858
841 859 def new_main_mod(self, filename, modname):
842 860 """Return a new 'main' module object for user code execution.
843 861
844 862 ``filename`` should be the path of the script which will be run in the
845 863 module. Requests with the same filename will get the same module, with
846 864 its namespace cleared.
847 865
848 866 ``modname`` should be the module name - normally either '__main__' or
849 867 the basename of the file without the extension.
850 868
851 869 When scripts are executed via %run, we must keep a reference to their
852 870 __main__ module around so that Python doesn't
853 871 clear it, rendering references to module globals useless.
854 872
855 873 This method keeps said reference in a private dict, keyed by the
856 874 absolute path of the script. This way, for multiple executions of the
857 875 same script we only keep one copy of the namespace (the last one),
858 876 thus preventing memory leaks from old references while allowing the
859 877 objects from the last execution to be accessible.
860 878 """
861 879 filename = os.path.abspath(filename)
862 880 try:
863 881 main_mod = self._main_mod_cache[filename]
864 882 except KeyError:
865 883 main_mod = self._main_mod_cache[filename] = types.ModuleType(modname,
866 884 doc="Module created for script run in IPython")
867 885 else:
868 886 main_mod.__dict__.clear()
869 887 main_mod.__name__ = modname
870 888
871 889 main_mod.__file__ = filename
872 890 # It seems pydoc (and perhaps others) needs any module instance to
873 891 # implement a __nonzero__ method
874 892 main_mod.__nonzero__ = lambda : True
875 893
876 894 return main_mod
877 895
878 896 def clear_main_mod_cache(self):
879 897 """Clear the cache of main modules.
880 898
881 899 Mainly for use by utilities like %reset.
882 900
883 901 Examples
884 902 --------
885 903
886 904 In [15]: import IPython
887 905
888 906 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
889 907
890 908 In [17]: len(_ip._main_mod_cache) > 0
891 909 Out[17]: True
892 910
893 911 In [18]: _ip.clear_main_mod_cache()
894 912
895 913 In [19]: len(_ip._main_mod_cache) == 0
896 914 Out[19]: True
897 915 """
898 916 self._main_mod_cache.clear()
899 917
900 918 #-------------------------------------------------------------------------
901 919 # Things related to debugging
902 920 #-------------------------------------------------------------------------
903 921
904 922 def init_pdb(self):
905 923 # Set calling of pdb on exceptions
906 924 # self.call_pdb is a property
907 925 self.call_pdb = self.pdb
908 926
909 927 def _get_call_pdb(self):
910 928 return self._call_pdb
911 929
912 930 def _set_call_pdb(self,val):
913 931
914 932 if val not in (0,1,False,True):
915 933 raise ValueError('new call_pdb value must be boolean')
916 934
917 935 # store value in instance
918 936 self._call_pdb = val
919 937
920 938 # notify the actual exception handlers
921 939 self.InteractiveTB.call_pdb = val
922 940
923 941 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
924 942 'Control auto-activation of pdb at exceptions')
925 943
926 944 def debugger(self,force=False):
927 945 """Call the pydb/pdb debugger.
928 946
929 947 Keywords:
930 948
931 949 - force(False): by default, this routine checks the instance call_pdb
932 950 flag and does not actually invoke the debugger if the flag is false.
933 951 The 'force' option forces the debugger to activate even if the flag
934 952 is false.
935 953 """
936 954
937 955 if not (force or self.call_pdb):
938 956 return
939 957
940 958 if not hasattr(sys,'last_traceback'):
941 959 error('No traceback has been produced, nothing to debug.')
942 960 return
943 961
944 962 # use pydb if available
945 963 if debugger.has_pydb:
946 964 from pydb import pm
947 965 else:
948 966 # fallback to our internal debugger
949 967 pm = lambda : self.InteractiveTB.debugger(force=True)
950 968
951 969 with self.readline_no_record:
952 970 pm()
953 971
954 972 #-------------------------------------------------------------------------
955 973 # Things related to IPython's various namespaces
956 974 #-------------------------------------------------------------------------
957 975 default_user_namespaces = True
958 976
959 977 def init_create_namespaces(self, user_module=None, user_ns=None):
960 978 # Create the namespace where the user will operate. user_ns is
961 979 # normally the only one used, and it is passed to the exec calls as
962 980 # the locals argument. But we do carry a user_global_ns namespace
963 981 # given as the exec 'globals' argument, This is useful in embedding
964 982 # situations where the ipython shell opens in a context where the
965 983 # distinction between locals and globals is meaningful. For
966 984 # non-embedded contexts, it is just the same object as the user_ns dict.
967 985
968 986 # FIXME. For some strange reason, __builtins__ is showing up at user
969 987 # level as a dict instead of a module. This is a manual fix, but I
970 988 # should really track down where the problem is coming from. Alex
971 989 # Schmolck reported this problem first.
972 990
973 991 # A useful post by Alex Martelli on this topic:
974 992 # Re: inconsistent value from __builtins__
975 993 # Von: Alex Martelli <aleaxit@yahoo.com>
976 994 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
977 995 # Gruppen: comp.lang.python
978 996
979 997 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
980 998 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
981 999 # > <type 'dict'>
982 1000 # > >>> print type(__builtins__)
983 1001 # > <type 'module'>
984 1002 # > Is this difference in return value intentional?
985 1003
986 1004 # Well, it's documented that '__builtins__' can be either a dictionary
987 1005 # or a module, and it's been that way for a long time. Whether it's
988 1006 # intentional (or sensible), I don't know. In any case, the idea is
989 1007 # that if you need to access the built-in namespace directly, you
990 1008 # should start with "import __builtin__" (note, no 's') which will
991 1009 # definitely give you a module. Yeah, it's somewhat confusing:-(.
992 1010
993 1011 # These routines return a properly built module and dict as needed by
994 1012 # the rest of the code, and can also be used by extension writers to
995 1013 # generate properly initialized namespaces.
996 1014 if (user_ns is not None) or (user_module is not None):
997 1015 self.default_user_namespaces = False
998 1016 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
999 1017
1000 1018 # A record of hidden variables we have added to the user namespace, so
1001 1019 # we can list later only variables defined in actual interactive use.
1002 1020 self.user_ns_hidden = {}
1003 1021
1004 1022 # Now that FakeModule produces a real module, we've run into a nasty
1005 1023 # problem: after script execution (via %run), the module where the user
1006 1024 # code ran is deleted. Now that this object is a true module (needed
1007 1025 # so docetst and other tools work correctly), the Python module
1008 1026 # teardown mechanism runs over it, and sets to None every variable
1009 1027 # present in that module. Top-level references to objects from the
1010 1028 # script survive, because the user_ns is updated with them. However,
1011 1029 # calling functions defined in the script that use other things from
1012 1030 # the script will fail, because the function's closure had references
1013 1031 # to the original objects, which are now all None. So we must protect
1014 1032 # these modules from deletion by keeping a cache.
1015 1033 #
1016 1034 # To avoid keeping stale modules around (we only need the one from the
1017 1035 # last run), we use a dict keyed with the full path to the script, so
1018 1036 # only the last version of the module is held in the cache. Note,
1019 1037 # however, that we must cache the module *namespace contents* (their
1020 1038 # __dict__). Because if we try to cache the actual modules, old ones
1021 1039 # (uncached) could be destroyed while still holding references (such as
1022 1040 # those held by GUI objects that tend to be long-lived)>
1023 1041 #
1024 1042 # The %reset command will flush this cache. See the cache_main_mod()
1025 1043 # and clear_main_mod_cache() methods for details on use.
1026 1044
1027 1045 # This is the cache used for 'main' namespaces
1028 1046 self._main_mod_cache = {}
1029 1047
1030 1048 # A table holding all the namespaces IPython deals with, so that
1031 1049 # introspection facilities can search easily.
1032 1050 self.ns_table = {'user_global':self.user_module.__dict__,
1033 1051 'user_local':self.user_ns,
1034 1052 'builtin':builtin_mod.__dict__
1035 1053 }
1036 1054
1037 1055 @property
1038 1056 def user_global_ns(self):
1039 1057 return self.user_module.__dict__
1040 1058
1041 1059 def prepare_user_module(self, user_module=None, user_ns=None):
1042 1060 """Prepare the module and namespace in which user code will be run.
1043 1061
1044 1062 When IPython is started normally, both parameters are None: a new module
1045 1063 is created automatically, and its __dict__ used as the namespace.
1046 1064
1047 1065 If only user_module is provided, its __dict__ is used as the namespace.
1048 1066 If only user_ns is provided, a dummy module is created, and user_ns
1049 1067 becomes the global namespace. If both are provided (as they may be
1050 1068 when embedding), user_ns is the local namespace, and user_module
1051 1069 provides the global namespace.
1052 1070
1053 1071 Parameters
1054 1072 ----------
1055 1073 user_module : module, optional
1056 1074 The current user module in which IPython is being run. If None,
1057 1075 a clean module will be created.
1058 1076 user_ns : dict, optional
1059 1077 A namespace in which to run interactive commands.
1060 1078
1061 1079 Returns
1062 1080 -------
1063 1081 A tuple of user_module and user_ns, each properly initialised.
1064 1082 """
1065 1083 if user_module is None and user_ns is not None:
1066 1084 user_ns.setdefault("__name__", "__main__")
1067 1085 user_module = DummyMod()
1068 1086 user_module.__dict__ = user_ns
1069 1087
1070 1088 if user_module is None:
1071 1089 user_module = types.ModuleType("__main__",
1072 1090 doc="Automatically created module for IPython interactive environment")
1073 1091
1074 1092 # We must ensure that __builtin__ (without the final 's') is always
1075 1093 # available and pointing to the __builtin__ *module*. For more details:
1076 1094 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1077 1095 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1078 1096 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1079 1097
1080 1098 if user_ns is None:
1081 1099 user_ns = user_module.__dict__
1082 1100
1083 1101 return user_module, user_ns
1084 1102
1085 1103 def init_sys_modules(self):
1086 1104 # We need to insert into sys.modules something that looks like a
1087 1105 # module but which accesses the IPython namespace, for shelve and
1088 1106 # pickle to work interactively. Normally they rely on getting
1089 1107 # everything out of __main__, but for embedding purposes each IPython
1090 1108 # instance has its own private namespace, so we can't go shoving
1091 1109 # everything into __main__.
1092 1110
1093 1111 # note, however, that we should only do this for non-embedded
1094 1112 # ipythons, which really mimic the __main__.__dict__ with their own
1095 1113 # namespace. Embedded instances, on the other hand, should not do
1096 1114 # this because they need to manage the user local/global namespaces
1097 1115 # only, but they live within a 'normal' __main__ (meaning, they
1098 1116 # shouldn't overtake the execution environment of the script they're
1099 1117 # embedded in).
1100 1118
1101 1119 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1102 1120 main_name = self.user_module.__name__
1103 1121 sys.modules[main_name] = self.user_module
1104 1122
1105 1123 def init_user_ns(self):
1106 1124 """Initialize all user-visible namespaces to their minimum defaults.
1107 1125
1108 1126 Certain history lists are also initialized here, as they effectively
1109 1127 act as user namespaces.
1110 1128
1111 1129 Notes
1112 1130 -----
1113 1131 All data structures here are only filled in, they are NOT reset by this
1114 1132 method. If they were not empty before, data will simply be added to
1115 1133 therm.
1116 1134 """
1117 1135 # This function works in two parts: first we put a few things in
1118 1136 # user_ns, and we sync that contents into user_ns_hidden so that these
1119 1137 # initial variables aren't shown by %who. After the sync, we add the
1120 1138 # rest of what we *do* want the user to see with %who even on a new
1121 1139 # session (probably nothing, so theye really only see their own stuff)
1122 1140
1123 1141 # The user dict must *always* have a __builtin__ reference to the
1124 1142 # Python standard __builtin__ namespace, which must be imported.
1125 1143 # This is so that certain operations in prompt evaluation can be
1126 1144 # reliably executed with builtins. Note that we can NOT use
1127 1145 # __builtins__ (note the 's'), because that can either be a dict or a
1128 1146 # module, and can even mutate at runtime, depending on the context
1129 1147 # (Python makes no guarantees on it). In contrast, __builtin__ is
1130 1148 # always a module object, though it must be explicitly imported.
1131 1149
1132 1150 # For more details:
1133 1151 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1134 1152 ns = dict()
1135 1153
1136 1154 # make global variables for user access to the histories
1137 1155 ns['_ih'] = self.history_manager.input_hist_parsed
1138 1156 ns['_oh'] = self.history_manager.output_hist
1139 1157 ns['_dh'] = self.history_manager.dir_hist
1140 1158
1141 1159 ns['_sh'] = shadowns
1142 1160
1143 1161 # user aliases to input and output histories. These shouldn't show up
1144 1162 # in %who, as they can have very large reprs.
1145 1163 ns['In'] = self.history_manager.input_hist_parsed
1146 1164 ns['Out'] = self.history_manager.output_hist
1147 1165
1148 1166 # Store myself as the public api!!!
1149 1167 ns['get_ipython'] = self.get_ipython
1150 1168
1151 1169 ns['exit'] = self.exiter
1152 1170 ns['quit'] = self.exiter
1153 1171
1154 1172 # Sync what we've added so far to user_ns_hidden so these aren't seen
1155 1173 # by %who
1156 1174 self.user_ns_hidden.update(ns)
1157 1175
1158 1176 # Anything put into ns now would show up in %who. Think twice before
1159 1177 # putting anything here, as we really want %who to show the user their
1160 1178 # stuff, not our variables.
1161 1179
1162 1180 # Finally, update the real user's namespace
1163 1181 self.user_ns.update(ns)
1164 1182
1165 1183 @property
1166 1184 def all_ns_refs(self):
1167 1185 """Get a list of references to all the namespace dictionaries in which
1168 1186 IPython might store a user-created object.
1169 1187
1170 1188 Note that this does not include the displayhook, which also caches
1171 1189 objects from the output."""
1172 1190 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1173 1191 [m.__dict__ for m in self._main_mod_cache.values()]
1174 1192
1175 1193 def reset(self, new_session=True):
1176 1194 """Clear all internal namespaces, and attempt to release references to
1177 1195 user objects.
1178 1196
1179 1197 If new_session is True, a new history session will be opened.
1180 1198 """
1181 1199 # Clear histories
1182 1200 self.history_manager.reset(new_session)
1183 1201 # Reset counter used to index all histories
1184 1202 if new_session:
1185 1203 self.execution_count = 1
1186 1204
1187 1205 # Flush cached output items
1188 1206 if self.displayhook.do_full_cache:
1189 1207 self.displayhook.flush()
1190 1208
1191 1209 # The main execution namespaces must be cleared very carefully,
1192 1210 # skipping the deletion of the builtin-related keys, because doing so
1193 1211 # would cause errors in many object's __del__ methods.
1194 1212 if self.user_ns is not self.user_global_ns:
1195 1213 self.user_ns.clear()
1196 1214 ns = self.user_global_ns
1197 1215 drop_keys = set(ns.keys())
1198 1216 drop_keys.discard('__builtin__')
1199 1217 drop_keys.discard('__builtins__')
1200 1218 drop_keys.discard('__name__')
1201 1219 for k in drop_keys:
1202 1220 del ns[k]
1203 1221
1204 1222 self.user_ns_hidden.clear()
1205 1223
1206 1224 # Restore the user namespaces to minimal usability
1207 1225 self.init_user_ns()
1208 1226
1209 1227 # Restore the default and user aliases
1210 1228 self.alias_manager.clear_aliases()
1211 1229 self.alias_manager.init_aliases()
1212 1230
1213 1231 # Flush the private list of module references kept for script
1214 1232 # execution protection
1215 1233 self.clear_main_mod_cache()
1216 1234
1217 1235 def del_var(self, varname, by_name=False):
1218 1236 """Delete a variable from the various namespaces, so that, as
1219 1237 far as possible, we're not keeping any hidden references to it.
1220 1238
1221 1239 Parameters
1222 1240 ----------
1223 1241 varname : str
1224 1242 The name of the variable to delete.
1225 1243 by_name : bool
1226 1244 If True, delete variables with the given name in each
1227 1245 namespace. If False (default), find the variable in the user
1228 1246 namespace, and delete references to it.
1229 1247 """
1230 1248 if varname in ('__builtin__', '__builtins__'):
1231 1249 raise ValueError("Refusing to delete %s" % varname)
1232 1250
1233 1251 ns_refs = self.all_ns_refs
1234 1252
1235 1253 if by_name: # Delete by name
1236 1254 for ns in ns_refs:
1237 1255 try:
1238 1256 del ns[varname]
1239 1257 except KeyError:
1240 1258 pass
1241 1259 else: # Delete by object
1242 1260 try:
1243 1261 obj = self.user_ns[varname]
1244 1262 except KeyError:
1245 1263 raise NameError("name '%s' is not defined" % varname)
1246 1264 # Also check in output history
1247 1265 ns_refs.append(self.history_manager.output_hist)
1248 1266 for ns in ns_refs:
1249 1267 to_delete = [n for n, o in iteritems(ns) if o is obj]
1250 1268 for name in to_delete:
1251 1269 del ns[name]
1252 1270
1253 1271 # displayhook keeps extra references, but not in a dictionary
1254 1272 for name in ('_', '__', '___'):
1255 1273 if getattr(self.displayhook, name) is obj:
1256 1274 setattr(self.displayhook, name, None)
1257 1275
1258 1276 def reset_selective(self, regex=None):
1259 1277 """Clear selective variables from internal namespaces based on a
1260 1278 specified regular expression.
1261 1279
1262 1280 Parameters
1263 1281 ----------
1264 1282 regex : string or compiled pattern, optional
1265 1283 A regular expression pattern that will be used in searching
1266 1284 variable names in the users namespaces.
1267 1285 """
1268 1286 if regex is not None:
1269 1287 try:
1270 1288 m = re.compile(regex)
1271 1289 except TypeError:
1272 1290 raise TypeError('regex must be a string or compiled pattern')
1273 1291 # Search for keys in each namespace that match the given regex
1274 1292 # If a match is found, delete the key/value pair.
1275 1293 for ns in self.all_ns_refs:
1276 1294 for var in ns:
1277 1295 if m.search(var):
1278 1296 del ns[var]
1279 1297
1280 1298 def push(self, variables, interactive=True):
1281 1299 """Inject a group of variables into the IPython user namespace.
1282 1300
1283 1301 Parameters
1284 1302 ----------
1285 1303 variables : dict, str or list/tuple of str
1286 1304 The variables to inject into the user's namespace. If a dict, a
1287 1305 simple update is done. If a str, the string is assumed to have
1288 1306 variable names separated by spaces. A list/tuple of str can also
1289 1307 be used to give the variable names. If just the variable names are
1290 1308 give (list/tuple/str) then the variable values looked up in the
1291 1309 callers frame.
1292 1310 interactive : bool
1293 1311 If True (default), the variables will be listed with the ``who``
1294 1312 magic.
1295 1313 """
1296 1314 vdict = None
1297 1315
1298 1316 # We need a dict of name/value pairs to do namespace updates.
1299 1317 if isinstance(variables, dict):
1300 1318 vdict = variables
1301 1319 elif isinstance(variables, string_types+(list, tuple)):
1302 1320 if isinstance(variables, string_types):
1303 1321 vlist = variables.split()
1304 1322 else:
1305 1323 vlist = variables
1306 1324 vdict = {}
1307 1325 cf = sys._getframe(1)
1308 1326 for name in vlist:
1309 1327 try:
1310 1328 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1311 1329 except:
1312 1330 print('Could not get variable %s from %s' %
1313 1331 (name,cf.f_code.co_name))
1314 1332 else:
1315 1333 raise ValueError('variables must be a dict/str/list/tuple')
1316 1334
1317 1335 # Propagate variables to user namespace
1318 1336 self.user_ns.update(vdict)
1319 1337
1320 1338 # And configure interactive visibility
1321 1339 user_ns_hidden = self.user_ns_hidden
1322 1340 if interactive:
1323 1341 for name in vdict:
1324 1342 user_ns_hidden.pop(name, None)
1325 1343 else:
1326 1344 user_ns_hidden.update(vdict)
1327 1345
1328 1346 def drop_by_id(self, variables):
1329 1347 """Remove a dict of variables from the user namespace, if they are the
1330 1348 same as the values in the dictionary.
1331 1349
1332 1350 This is intended for use by extensions: variables that they've added can
1333 1351 be taken back out if they are unloaded, without removing any that the
1334 1352 user has overwritten.
1335 1353
1336 1354 Parameters
1337 1355 ----------
1338 1356 variables : dict
1339 1357 A dictionary mapping object names (as strings) to the objects.
1340 1358 """
1341 1359 for name, obj in iteritems(variables):
1342 1360 if name in self.user_ns and self.user_ns[name] is obj:
1343 1361 del self.user_ns[name]
1344 1362 self.user_ns_hidden.pop(name, None)
1345 1363
1346 1364 #-------------------------------------------------------------------------
1347 1365 # Things related to object introspection
1348 1366 #-------------------------------------------------------------------------
1349 1367
1350 1368 def _ofind(self, oname, namespaces=None):
1351 1369 """Find an object in the available namespaces.
1352 1370
1353 1371 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1354 1372
1355 1373 Has special code to detect magic functions.
1356 1374 """
1357 1375 oname = oname.strip()
1358 1376 #print '1- oname: <%r>' % oname # dbg
1359 1377 if not oname.startswith(ESC_MAGIC) and \
1360 1378 not oname.startswith(ESC_MAGIC2) and \
1361 1379 not py3compat.isidentifier(oname, dotted=True):
1362 1380 return dict(found=False)
1363 1381
1364 1382 alias_ns = None
1365 1383 if namespaces is None:
1366 1384 # Namespaces to search in:
1367 1385 # Put them in a list. The order is important so that we
1368 1386 # find things in the same order that Python finds them.
1369 1387 namespaces = [ ('Interactive', self.user_ns),
1370 1388 ('Interactive (global)', self.user_global_ns),
1371 1389 ('Python builtin', builtin_mod.__dict__),
1372 1390 ]
1373 1391
1374 1392 # initialize results to 'null'
1375 1393 found = False; obj = None; ospace = None; ds = None;
1376 1394 ismagic = False; isalias = False; parent = None
1377 1395
1378 1396 # We need to special-case 'print', which as of python2.6 registers as a
1379 1397 # function but should only be treated as one if print_function was
1380 1398 # loaded with a future import. In this case, just bail.
1381 1399 if (oname == 'print' and not py3compat.PY3 and not \
1382 1400 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1383 1401 return {'found':found, 'obj':obj, 'namespace':ospace,
1384 1402 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1385 1403
1386 1404 # Look for the given name by splitting it in parts. If the head is
1387 1405 # found, then we look for all the remaining parts as members, and only
1388 1406 # declare success if we can find them all.
1389 1407 oname_parts = oname.split('.')
1390 1408 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1391 1409 for nsname,ns in namespaces:
1392 1410 try:
1393 1411 obj = ns[oname_head]
1394 1412 except KeyError:
1395 1413 continue
1396 1414 else:
1397 1415 #print 'oname_rest:', oname_rest # dbg
1398 1416 for part in oname_rest:
1399 1417 try:
1400 1418 parent = obj
1401 1419 obj = getattr(obj,part)
1402 1420 except:
1403 1421 # Blanket except b/c some badly implemented objects
1404 1422 # allow __getattr__ to raise exceptions other than
1405 1423 # AttributeError, which then crashes IPython.
1406 1424 break
1407 1425 else:
1408 1426 # If we finish the for loop (no break), we got all members
1409 1427 found = True
1410 1428 ospace = nsname
1411 1429 break # namespace loop
1412 1430
1413 1431 # Try to see if it's magic
1414 1432 if not found:
1415 1433 obj = None
1416 1434 if oname.startswith(ESC_MAGIC2):
1417 1435 oname = oname.lstrip(ESC_MAGIC2)
1418 1436 obj = self.find_cell_magic(oname)
1419 1437 elif oname.startswith(ESC_MAGIC):
1420 1438 oname = oname.lstrip(ESC_MAGIC)
1421 1439 obj = self.find_line_magic(oname)
1422 1440 else:
1423 1441 # search without prefix, so run? will find %run?
1424 1442 obj = self.find_line_magic(oname)
1425 1443 if obj is None:
1426 1444 obj = self.find_cell_magic(oname)
1427 1445 if obj is not None:
1428 1446 found = True
1429 1447 ospace = 'IPython internal'
1430 1448 ismagic = True
1431 1449
1432 1450 # Last try: special-case some literals like '', [], {}, etc:
1433 1451 if not found and oname_head in ["''",'""','[]','{}','()']:
1434 1452 obj = eval(oname_head)
1435 1453 found = True
1436 1454 ospace = 'Interactive'
1437 1455
1438 1456 return {'found':found, 'obj':obj, 'namespace':ospace,
1439 1457 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1440 1458
1441 1459 def _ofind_property(self, oname, info):
1442 1460 """Second part of object finding, to look for property details."""
1443 1461 if info.found:
1444 1462 # Get the docstring of the class property if it exists.
1445 1463 path = oname.split('.')
1446 1464 root = '.'.join(path[:-1])
1447 1465 if info.parent is not None:
1448 1466 try:
1449 1467 target = getattr(info.parent, '__class__')
1450 1468 # The object belongs to a class instance.
1451 1469 try:
1452 1470 target = getattr(target, path[-1])
1453 1471 # The class defines the object.
1454 1472 if isinstance(target, property):
1455 1473 oname = root + '.__class__.' + path[-1]
1456 1474 info = Struct(self._ofind(oname))
1457 1475 except AttributeError: pass
1458 1476 except AttributeError: pass
1459 1477
1460 1478 # We return either the new info or the unmodified input if the object
1461 1479 # hadn't been found
1462 1480 return info
1463 1481
1464 1482 def _object_find(self, oname, namespaces=None):
1465 1483 """Find an object and return a struct with info about it."""
1466 1484 inf = Struct(self._ofind(oname, namespaces))
1467 1485 return Struct(self._ofind_property(oname, inf))
1468 1486
1469 1487 def _inspect(self, meth, oname, namespaces=None, **kw):
1470 1488 """Generic interface to the inspector system.
1471 1489
1472 1490 This function is meant to be called by pdef, pdoc & friends."""
1473 1491 info = self._object_find(oname, namespaces)
1474 1492 if info.found:
1475 1493 pmethod = getattr(self.inspector, meth)
1476 1494 formatter = format_screen if info.ismagic else None
1477 1495 if meth == 'pdoc':
1478 1496 pmethod(info.obj, oname, formatter)
1479 1497 elif meth == 'pinfo':
1480 1498 pmethod(info.obj, oname, formatter, info, **kw)
1481 1499 else:
1482 1500 pmethod(info.obj, oname)
1483 1501 else:
1484 1502 print('Object `%s` not found.' % oname)
1485 1503 return 'not found' # so callers can take other action
1486 1504
1487 1505 def object_inspect(self, oname, detail_level=0):
1488 1506 with self.builtin_trap:
1489 1507 info = self._object_find(oname)
1490 1508 if info.found:
1491 1509 return self.inspector.info(info.obj, oname, info=info,
1492 1510 detail_level=detail_level
1493 1511 )
1494 1512 else:
1495 1513 return oinspect.object_info(name=oname, found=False)
1496 1514
1497 1515 #-------------------------------------------------------------------------
1498 1516 # Things related to history management
1499 1517 #-------------------------------------------------------------------------
1500 1518
1501 1519 def init_history(self):
1502 1520 """Sets up the command history, and starts regular autosaves."""
1503 1521 self.history_manager = HistoryManager(shell=self, parent=self)
1504 1522 self.configurables.append(self.history_manager)
1505 1523
1506 1524 #-------------------------------------------------------------------------
1507 1525 # Things related to exception handling and tracebacks (not debugging)
1508 1526 #-------------------------------------------------------------------------
1509 1527
1510 1528 def init_traceback_handlers(self, custom_exceptions):
1511 1529 # Syntax error handler.
1512 1530 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1513 1531
1514 1532 # The interactive one is initialized with an offset, meaning we always
1515 1533 # want to remove the topmost item in the traceback, which is our own
1516 1534 # internal code. Valid modes: ['Plain','Context','Verbose']
1517 1535 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1518 1536 color_scheme='NoColor',
1519 1537 tb_offset = 1,
1520 1538 check_cache=check_linecache_ipython)
1521 1539
1522 1540 # The instance will store a pointer to the system-wide exception hook,
1523 1541 # so that runtime code (such as magics) can access it. This is because
1524 1542 # during the read-eval loop, it may get temporarily overwritten.
1525 1543 self.sys_excepthook = sys.excepthook
1526 1544
1527 1545 # and add any custom exception handlers the user may have specified
1528 1546 self.set_custom_exc(*custom_exceptions)
1529 1547
1530 1548 # Set the exception mode
1531 1549 self.InteractiveTB.set_mode(mode=self.xmode)
1532 1550
1533 1551 def set_custom_exc(self, exc_tuple, handler):
1534 1552 """set_custom_exc(exc_tuple,handler)
1535 1553
1536 1554 Set a custom exception handler, which will be called if any of the
1537 1555 exceptions in exc_tuple occur in the mainloop (specifically, in the
1538 1556 run_code() method).
1539 1557
1540 1558 Parameters
1541 1559 ----------
1542 1560
1543 1561 exc_tuple : tuple of exception classes
1544 1562 A *tuple* of exception classes, for which to call the defined
1545 1563 handler. It is very important that you use a tuple, and NOT A
1546 1564 LIST here, because of the way Python's except statement works. If
1547 1565 you only want to trap a single exception, use a singleton tuple::
1548 1566
1549 1567 exc_tuple == (MyCustomException,)
1550 1568
1551 1569 handler : callable
1552 1570 handler must have the following signature::
1553 1571
1554 1572 def my_handler(self, etype, value, tb, tb_offset=None):
1555 1573 ...
1556 1574 return structured_traceback
1557 1575
1558 1576 Your handler must return a structured traceback (a list of strings),
1559 1577 or None.
1560 1578
1561 1579 This will be made into an instance method (via types.MethodType)
1562 1580 of IPython itself, and it will be called if any of the exceptions
1563 1581 listed in the exc_tuple are caught. If the handler is None, an
1564 1582 internal basic one is used, which just prints basic info.
1565 1583
1566 1584 To protect IPython from crashes, if your handler ever raises an
1567 1585 exception or returns an invalid result, it will be immediately
1568 1586 disabled.
1569 1587
1570 1588 WARNING: by putting in your own exception handler into IPython's main
1571 1589 execution loop, you run a very good chance of nasty crashes. This
1572 1590 facility should only be used if you really know what you are doing."""
1573 1591
1574 1592 assert type(exc_tuple)==type(()) , \
1575 1593 "The custom exceptions must be given AS A TUPLE."
1576 1594
1577 1595 def dummy_handler(self,etype,value,tb,tb_offset=None):
1578 1596 print('*** Simple custom exception handler ***')
1579 1597 print('Exception type :',etype)
1580 1598 print('Exception value:',value)
1581 1599 print('Traceback :',tb)
1582 1600 #print 'Source code :','\n'.join(self.buffer)
1583 1601
1584 1602 def validate_stb(stb):
1585 1603 """validate structured traceback return type
1586 1604
1587 1605 return type of CustomTB *should* be a list of strings, but allow
1588 1606 single strings or None, which are harmless.
1589 1607
1590 1608 This function will *always* return a list of strings,
1591 1609 and will raise a TypeError if stb is inappropriate.
1592 1610 """
1593 1611 msg = "CustomTB must return list of strings, not %r" % stb
1594 1612 if stb is None:
1595 1613 return []
1596 1614 elif isinstance(stb, string_types):
1597 1615 return [stb]
1598 1616 elif not isinstance(stb, list):
1599 1617 raise TypeError(msg)
1600 1618 # it's a list
1601 1619 for line in stb:
1602 1620 # check every element
1603 1621 if not isinstance(line, string_types):
1604 1622 raise TypeError(msg)
1605 1623 return stb
1606 1624
1607 1625 if handler is None:
1608 1626 wrapped = dummy_handler
1609 1627 else:
1610 1628 def wrapped(self,etype,value,tb,tb_offset=None):
1611 1629 """wrap CustomTB handler, to protect IPython from user code
1612 1630
1613 1631 This makes it harder (but not impossible) for custom exception
1614 1632 handlers to crash IPython.
1615 1633 """
1616 1634 try:
1617 1635 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1618 1636 return validate_stb(stb)
1619 1637 except:
1620 1638 # clear custom handler immediately
1621 1639 self.set_custom_exc((), None)
1622 1640 print("Custom TB Handler failed, unregistering", file=io.stderr)
1623 1641 # show the exception in handler first
1624 1642 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1625 1643 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1626 1644 print("The original exception:", file=io.stdout)
1627 1645 stb = self.InteractiveTB.structured_traceback(
1628 1646 (etype,value,tb), tb_offset=tb_offset
1629 1647 )
1630 1648 return stb
1631 1649
1632 1650 self.CustomTB = types.MethodType(wrapped,self)
1633 1651 self.custom_exceptions = exc_tuple
1634 1652
1635 1653 def excepthook(self, etype, value, tb):
1636 1654 """One more defense for GUI apps that call sys.excepthook.
1637 1655
1638 1656 GUI frameworks like wxPython trap exceptions and call
1639 1657 sys.excepthook themselves. I guess this is a feature that
1640 1658 enables them to keep running after exceptions that would
1641 1659 otherwise kill their mainloop. This is a bother for IPython
1642 1660 which excepts to catch all of the program exceptions with a try:
1643 1661 except: statement.
1644 1662
1645 1663 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1646 1664 any app directly invokes sys.excepthook, it will look to the user like
1647 1665 IPython crashed. In order to work around this, we can disable the
1648 1666 CrashHandler and replace it with this excepthook instead, which prints a
1649 1667 regular traceback using our InteractiveTB. In this fashion, apps which
1650 1668 call sys.excepthook will generate a regular-looking exception from
1651 1669 IPython, and the CrashHandler will only be triggered by real IPython
1652 1670 crashes.
1653 1671
1654 1672 This hook should be used sparingly, only in places which are not likely
1655 1673 to be true IPython errors.
1656 1674 """
1657 1675 self.showtraceback((etype,value,tb),tb_offset=0)
1658 1676
1659 1677 def _get_exc_info(self, exc_tuple=None):
1660 1678 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1661 1679
1662 1680 Ensures sys.last_type,value,traceback hold the exc_info we found,
1663 1681 from whichever source.
1664 1682
1665 1683 raises ValueError if none of these contain any information
1666 1684 """
1667 1685 if exc_tuple is None:
1668 1686 etype, value, tb = sys.exc_info()
1669 1687 else:
1670 1688 etype, value, tb = exc_tuple
1671 1689
1672 1690 if etype is None:
1673 1691 if hasattr(sys, 'last_type'):
1674 1692 etype, value, tb = sys.last_type, sys.last_value, \
1675 1693 sys.last_traceback
1676 1694
1677 1695 if etype is None:
1678 1696 raise ValueError("No exception to find")
1679 1697
1680 1698 # Now store the exception info in sys.last_type etc.
1681 1699 # WARNING: these variables are somewhat deprecated and not
1682 1700 # necessarily safe to use in a threaded environment, but tools
1683 1701 # like pdb depend on their existence, so let's set them. If we
1684 1702 # find problems in the field, we'll need to revisit their use.
1685 1703 sys.last_type = etype
1686 1704 sys.last_value = value
1687 1705 sys.last_traceback = tb
1688 1706
1689 1707 return etype, value, tb
1690 1708
1691 1709 def show_usage_error(self, exc):
1692 1710 """Show a short message for UsageErrors
1693 1711
1694 1712 These are special exceptions that shouldn't show a traceback.
1695 1713 """
1696 1714 self.write_err("UsageError: %s" % exc)
1697 1715
1698 1716 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1699 1717 exception_only=False):
1700 1718 """Display the exception that just occurred.
1701 1719
1702 1720 If nothing is known about the exception, this is the method which
1703 1721 should be used throughout the code for presenting user tracebacks,
1704 1722 rather than directly invoking the InteractiveTB object.
1705 1723
1706 1724 A specific showsyntaxerror() also exists, but this method can take
1707 1725 care of calling it if needed, so unless you are explicitly catching a
1708 1726 SyntaxError exception, don't try to analyze the stack manually and
1709 1727 simply call this method."""
1710 1728
1711 1729 try:
1712 1730 try:
1713 1731 etype, value, tb = self._get_exc_info(exc_tuple)
1714 1732 except ValueError:
1715 1733 self.write_err('No traceback available to show.\n')
1716 1734 return
1717 1735
1718 1736 if issubclass(etype, SyntaxError):
1719 1737 # Though this won't be called by syntax errors in the input
1720 1738 # line, there may be SyntaxError cases with imported code.
1721 1739 self.showsyntaxerror(filename)
1722 1740 elif etype is UsageError:
1723 1741 self.show_usage_error(value)
1724 1742 else:
1725 1743 if exception_only:
1726 1744 stb = ['An exception has occurred, use %tb to see '
1727 1745 'the full traceback.\n']
1728 1746 stb.extend(self.InteractiveTB.get_exception_only(etype,
1729 1747 value))
1730 1748 else:
1731 1749 try:
1732 1750 # Exception classes can customise their traceback - we
1733 1751 # use this in IPython.parallel for exceptions occurring
1734 1752 # in the engines. This should return a list of strings.
1735 1753 stb = value._render_traceback_()
1736 1754 except Exception:
1737 1755 stb = self.InteractiveTB.structured_traceback(etype,
1738 1756 value, tb, tb_offset=tb_offset)
1739 1757
1740 1758 self._showtraceback(etype, value, stb)
1741 1759 if self.call_pdb:
1742 1760 # drop into debugger
1743 1761 self.debugger(force=True)
1744 1762 return
1745 1763
1746 1764 # Actually show the traceback
1747 1765 self._showtraceback(etype, value, stb)
1748 1766
1749 1767 except KeyboardInterrupt:
1750 1768 self.write_err("\nKeyboardInterrupt\n")
1751 1769
1752 1770 def _showtraceback(self, etype, evalue, stb):
1753 1771 """Actually show a traceback.
1754 1772
1755 1773 Subclasses may override this method to put the traceback on a different
1756 1774 place, like a side channel.
1757 1775 """
1758 1776 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1759 1777
1760 1778 def showsyntaxerror(self, filename=None):
1761 1779 """Display the syntax error that just occurred.
1762 1780
1763 1781 This doesn't display a stack trace because there isn't one.
1764 1782
1765 1783 If a filename is given, it is stuffed in the exception instead
1766 1784 of what was there before (because Python's parser always uses
1767 1785 "<string>" when reading from a string).
1768 1786 """
1769 1787 etype, value, last_traceback = self._get_exc_info()
1770 1788
1771 1789 if filename and issubclass(etype, SyntaxError):
1772 1790 try:
1773 1791 value.filename = filename
1774 1792 except:
1775 1793 # Not the format we expect; leave it alone
1776 1794 pass
1777 1795
1778 1796 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1779 1797 self._showtraceback(etype, value, stb)
1780 1798
1781 1799 # This is overridden in TerminalInteractiveShell to show a message about
1782 1800 # the %paste magic.
1783 1801 def showindentationerror(self):
1784 1802 """Called by run_cell when there's an IndentationError in code entered
1785 1803 at the prompt.
1786 1804
1787 1805 This is overridden in TerminalInteractiveShell to show a message about
1788 1806 the %paste magic."""
1789 1807 self.showsyntaxerror()
1790 1808
1791 1809 #-------------------------------------------------------------------------
1792 1810 # Things related to readline
1793 1811 #-------------------------------------------------------------------------
1794 1812
1795 1813 def init_readline(self):
1796 1814 """Command history completion/saving/reloading."""
1797 1815
1798 1816 if self.readline_use:
1799 1817 import IPython.utils.rlineimpl as readline
1800 1818
1801 1819 self.rl_next_input = None
1802 1820 self.rl_do_indent = False
1803 1821
1804 1822 if not self.readline_use or not readline.have_readline:
1805 1823 self.has_readline = False
1806 1824 self.readline = None
1807 1825 # Set a number of methods that depend on readline to be no-op
1808 1826 self.readline_no_record = no_op_context
1809 1827 self.set_readline_completer = no_op
1810 1828 self.set_custom_completer = no_op
1811 1829 if self.readline_use:
1812 1830 warn('Readline services not available or not loaded.')
1813 1831 else:
1814 1832 self.has_readline = True
1815 1833 self.readline = readline
1816 1834 sys.modules['readline'] = readline
1817 1835
1818 1836 # Platform-specific configuration
1819 1837 if os.name == 'nt':
1820 1838 # FIXME - check with Frederick to see if we can harmonize
1821 1839 # naming conventions with pyreadline to avoid this
1822 1840 # platform-dependent check
1823 1841 self.readline_startup_hook = readline.set_pre_input_hook
1824 1842 else:
1825 1843 self.readline_startup_hook = readline.set_startup_hook
1826 1844
1827 1845 # Load user's initrc file (readline config)
1828 1846 # Or if libedit is used, load editrc.
1829 1847 inputrc_name = os.environ.get('INPUTRC')
1830 1848 if inputrc_name is None:
1831 1849 inputrc_name = '.inputrc'
1832 1850 if readline.uses_libedit:
1833 1851 inputrc_name = '.editrc'
1834 1852 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1835 1853 if os.path.isfile(inputrc_name):
1836 1854 try:
1837 1855 readline.read_init_file(inputrc_name)
1838 1856 except:
1839 1857 warn('Problems reading readline initialization file <%s>'
1840 1858 % inputrc_name)
1841 1859
1842 1860 # Configure readline according to user's prefs
1843 1861 # This is only done if GNU readline is being used. If libedit
1844 1862 # is being used (as on Leopard) the readline config is
1845 1863 # not run as the syntax for libedit is different.
1846 1864 if not readline.uses_libedit:
1847 1865 for rlcommand in self.readline_parse_and_bind:
1848 1866 #print "loading rl:",rlcommand # dbg
1849 1867 readline.parse_and_bind(rlcommand)
1850 1868
1851 1869 # Remove some chars from the delimiters list. If we encounter
1852 1870 # unicode chars, discard them.
1853 1871 delims = readline.get_completer_delims()
1854 1872 if not py3compat.PY3:
1855 1873 delims = delims.encode("ascii", "ignore")
1856 1874 for d in self.readline_remove_delims:
1857 1875 delims = delims.replace(d, "")
1858 1876 delims = delims.replace(ESC_MAGIC, '')
1859 1877 readline.set_completer_delims(delims)
1860 1878 # Store these so we can restore them if something like rpy2 modifies
1861 1879 # them.
1862 1880 self.readline_delims = delims
1863 1881 # otherwise we end up with a monster history after a while:
1864 1882 readline.set_history_length(self.history_length)
1865 1883
1866 1884 self.refill_readline_hist()
1867 1885 self.readline_no_record = ReadlineNoRecord(self)
1868 1886
1869 1887 # Configure auto-indent for all platforms
1870 1888 self.set_autoindent(self.autoindent)
1871 1889
1872 1890 def refill_readline_hist(self):
1873 1891 # Load the last 1000 lines from history
1874 1892 self.readline.clear_history()
1875 1893 stdin_encoding = sys.stdin.encoding or "utf-8"
1876 1894 last_cell = u""
1877 1895 for _, _, cell in self.history_manager.get_tail(1000,
1878 1896 include_latest=True):
1879 1897 # Ignore blank lines and consecutive duplicates
1880 1898 cell = cell.rstrip()
1881 1899 if cell and (cell != last_cell):
1882 1900 try:
1883 1901 if self.multiline_history:
1884 1902 self.readline.add_history(py3compat.unicode_to_str(cell,
1885 1903 stdin_encoding))
1886 1904 else:
1887 1905 for line in cell.splitlines():
1888 1906 self.readline.add_history(py3compat.unicode_to_str(line,
1889 1907 stdin_encoding))
1890 1908 last_cell = cell
1891 1909
1892 1910 except TypeError:
1893 1911 # The history DB can get corrupted so it returns strings
1894 1912 # containing null bytes, which readline objects to.
1895 1913 continue
1896 1914
1897 1915 @skip_doctest
1898 1916 def set_next_input(self, s):
1899 1917 """ Sets the 'default' input string for the next command line.
1900 1918
1901 1919 Requires readline.
1902 1920
1903 1921 Example::
1904 1922
1905 1923 In [1]: _ip.set_next_input("Hello Word")
1906 1924 In [2]: Hello Word_ # cursor is here
1907 1925 """
1908 1926 self.rl_next_input = py3compat.cast_bytes_py2(s)
1909 1927
1910 1928 # Maybe move this to the terminal subclass?
1911 1929 def pre_readline(self):
1912 1930 """readline hook to be used at the start of each line.
1913 1931
1914 1932 Currently it handles auto-indent only."""
1915 1933
1916 1934 if self.rl_do_indent:
1917 1935 self.readline.insert_text(self._indent_current_str())
1918 1936 if self.rl_next_input is not None:
1919 1937 self.readline.insert_text(self.rl_next_input)
1920 1938 self.rl_next_input = None
1921 1939
1922 1940 def _indent_current_str(self):
1923 1941 """return the current level of indentation as a string"""
1924 1942 return self.input_splitter.indent_spaces * ' '
1925 1943
1926 1944 #-------------------------------------------------------------------------
1927 1945 # Things related to text completion
1928 1946 #-------------------------------------------------------------------------
1929 1947
1930 1948 def init_completer(self):
1931 1949 """Initialize the completion machinery.
1932 1950
1933 1951 This creates completion machinery that can be used by client code,
1934 1952 either interactively in-process (typically triggered by the readline
1935 1953 library), programatically (such as in test suites) or out-of-prcess
1936 1954 (typically over the network by remote frontends).
1937 1955 """
1938 1956 from IPython.core.completer import IPCompleter
1939 1957 from IPython.core.completerlib import (module_completer,
1940 1958 magic_run_completer, cd_completer, reset_completer)
1941 1959
1942 1960 self.Completer = IPCompleter(shell=self,
1943 1961 namespace=self.user_ns,
1944 1962 global_namespace=self.user_global_ns,
1945 1963 use_readline=self.has_readline,
1946 1964 parent=self,
1947 1965 )
1948 1966 self.configurables.append(self.Completer)
1949 1967
1950 1968 # Add custom completers to the basic ones built into IPCompleter
1951 1969 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1952 1970 self.strdispatchers['complete_command'] = sdisp
1953 1971 self.Completer.custom_completers = sdisp
1954 1972
1955 1973 self.set_hook('complete_command', module_completer, str_key = 'import')
1956 1974 self.set_hook('complete_command', module_completer, str_key = 'from')
1957 1975 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
1958 1976 self.set_hook('complete_command', cd_completer, str_key = '%cd')
1959 1977 self.set_hook('complete_command', reset_completer, str_key = '%reset')
1960 1978
1961 1979 # Only configure readline if we truly are using readline. IPython can
1962 1980 # do tab-completion over the network, in GUIs, etc, where readline
1963 1981 # itself may be absent
1964 1982 if self.has_readline:
1965 1983 self.set_readline_completer()
1966 1984
1967 1985 def complete(self, text, line=None, cursor_pos=None):
1968 1986 """Return the completed text and a list of completions.
1969 1987
1970 1988 Parameters
1971 1989 ----------
1972 1990
1973 1991 text : string
1974 1992 A string of text to be completed on. It can be given as empty and
1975 1993 instead a line/position pair are given. In this case, the
1976 1994 completer itself will split the line like readline does.
1977 1995
1978 1996 line : string, optional
1979 1997 The complete line that text is part of.
1980 1998
1981 1999 cursor_pos : int, optional
1982 2000 The position of the cursor on the input line.
1983 2001
1984 2002 Returns
1985 2003 -------
1986 2004 text : string
1987 2005 The actual text that was completed.
1988 2006
1989 2007 matches : list
1990 2008 A sorted list with all possible completions.
1991 2009
1992 2010 The optional arguments allow the completion to take more context into
1993 2011 account, and are part of the low-level completion API.
1994 2012
1995 2013 This is a wrapper around the completion mechanism, similar to what
1996 2014 readline does at the command line when the TAB key is hit. By
1997 2015 exposing it as a method, it can be used by other non-readline
1998 2016 environments (such as GUIs) for text completion.
1999 2017
2000 2018 Simple usage example:
2001 2019
2002 2020 In [1]: x = 'hello'
2003 2021
2004 2022 In [2]: _ip.complete('x.l')
2005 2023 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2006 2024 """
2007 2025
2008 2026 # Inject names into __builtin__ so we can complete on the added names.
2009 2027 with self.builtin_trap:
2010 2028 return self.Completer.complete(text, line, cursor_pos)
2011 2029
2012 2030 def set_custom_completer(self, completer, pos=0):
2013 2031 """Adds a new custom completer function.
2014 2032
2015 2033 The position argument (defaults to 0) is the index in the completers
2016 2034 list where you want the completer to be inserted."""
2017 2035
2018 2036 newcomp = types.MethodType(completer,self.Completer)
2019 2037 self.Completer.matchers.insert(pos,newcomp)
2020 2038
2021 2039 def set_readline_completer(self):
2022 2040 """Reset readline's completer to be our own."""
2023 2041 self.readline.set_completer(self.Completer.rlcomplete)
2024 2042
2025 2043 def set_completer_frame(self, frame=None):
2026 2044 """Set the frame of the completer."""
2027 2045 if frame:
2028 2046 self.Completer.namespace = frame.f_locals
2029 2047 self.Completer.global_namespace = frame.f_globals
2030 2048 else:
2031 2049 self.Completer.namespace = self.user_ns
2032 2050 self.Completer.global_namespace = self.user_global_ns
2033 2051
2034 2052 #-------------------------------------------------------------------------
2035 2053 # Things related to magics
2036 2054 #-------------------------------------------------------------------------
2037 2055
2038 2056 def init_magics(self):
2039 2057 from IPython.core import magics as m
2040 2058 self.magics_manager = magic.MagicsManager(shell=self,
2041 2059 parent=self,
2042 2060 user_magics=m.UserMagics(self))
2043 2061 self.configurables.append(self.magics_manager)
2044 2062
2045 2063 # Expose as public API from the magics manager
2046 2064 self.register_magics = self.magics_manager.register
2047 2065 self.define_magic = self.magics_manager.define_magic
2048 2066
2049 2067 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2050 2068 m.ConfigMagics, m.DeprecatedMagics, m.DisplayMagics, m.ExecutionMagics,
2051 2069 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2052 2070 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2053 2071 )
2054 2072
2055 2073 # Register Magic Aliases
2056 2074 mman = self.magics_manager
2057 2075 # FIXME: magic aliases should be defined by the Magics classes
2058 2076 # or in MagicsManager, not here
2059 2077 mman.register_alias('ed', 'edit')
2060 2078 mman.register_alias('hist', 'history')
2061 2079 mman.register_alias('rep', 'recall')
2062 2080 mman.register_alias('SVG', 'svg', 'cell')
2063 2081 mman.register_alias('HTML', 'html', 'cell')
2064 2082 mman.register_alias('file', 'writefile', 'cell')
2065 2083
2066 2084 # FIXME: Move the color initialization to the DisplayHook, which
2067 2085 # should be split into a prompt manager and displayhook. We probably
2068 2086 # even need a centralize colors management object.
2069 2087 self.magic('colors %s' % self.colors)
2070 2088
2071 2089 # Defined here so that it's included in the documentation
2072 2090 @functools.wraps(magic.MagicsManager.register_function)
2073 2091 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2074 2092 self.magics_manager.register_function(func,
2075 2093 magic_kind=magic_kind, magic_name=magic_name)
2076 2094
2077 2095 def run_line_magic(self, magic_name, line):
2078 2096 """Execute the given line magic.
2079 2097
2080 2098 Parameters
2081 2099 ----------
2082 2100 magic_name : str
2083 2101 Name of the desired magic function, without '%' prefix.
2084 2102
2085 2103 line : str
2086 2104 The rest of the input line as a single string.
2087 2105 """
2088 2106 fn = self.find_line_magic(magic_name)
2089 2107 if fn is None:
2090 2108 cm = self.find_cell_magic(magic_name)
2091 2109 etpl = "Line magic function `%%%s` not found%s."
2092 2110 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2093 2111 'did you mean that instead?)' % magic_name )
2094 2112 error(etpl % (magic_name, extra))
2095 2113 else:
2096 2114 # Note: this is the distance in the stack to the user's frame.
2097 2115 # This will need to be updated if the internal calling logic gets
2098 2116 # refactored, or else we'll be expanding the wrong variables.
2099 2117 stack_depth = 2
2100 2118 magic_arg_s = self.var_expand(line, stack_depth)
2101 2119 # Put magic args in a list so we can call with f(*a) syntax
2102 2120 args = [magic_arg_s]
2103 2121 kwargs = {}
2104 2122 # Grab local namespace if we need it:
2105 2123 if getattr(fn, "needs_local_scope", False):
2106 2124 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2107 2125 with self.builtin_trap:
2108 2126 result = fn(*args,**kwargs)
2109 2127 return result
2110 2128
2111 2129 def run_cell_magic(self, magic_name, line, cell):
2112 2130 """Execute the given cell magic.
2113 2131
2114 2132 Parameters
2115 2133 ----------
2116 2134 magic_name : str
2117 2135 Name of the desired magic function, without '%' prefix.
2118 2136
2119 2137 line : str
2120 2138 The rest of the first input line as a single string.
2121 2139
2122 2140 cell : str
2123 2141 The body of the cell as a (possibly multiline) string.
2124 2142 """
2125 2143 fn = self.find_cell_magic(magic_name)
2126 2144 if fn is None:
2127 2145 lm = self.find_line_magic(magic_name)
2128 2146 etpl = "Cell magic `%%{0}` not found{1}."
2129 2147 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2130 2148 'did you mean that instead?)'.format(magic_name))
2131 2149 error(etpl.format(magic_name, extra))
2132 2150 elif cell == '':
2133 2151 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2134 2152 if self.find_line_magic(magic_name) is not None:
2135 2153 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2136 2154 raise UsageError(message)
2137 2155 else:
2138 2156 # Note: this is the distance in the stack to the user's frame.
2139 2157 # This will need to be updated if the internal calling logic gets
2140 2158 # refactored, or else we'll be expanding the wrong variables.
2141 2159 stack_depth = 2
2142 2160 magic_arg_s = self.var_expand(line, stack_depth)
2143 2161 with self.builtin_trap:
2144 2162 result = fn(magic_arg_s, cell)
2145 2163 return result
2146 2164
2147 2165 def find_line_magic(self, magic_name):
2148 2166 """Find and return a line magic by name.
2149 2167
2150 2168 Returns None if the magic isn't found."""
2151 2169 return self.magics_manager.magics['line'].get(magic_name)
2152 2170
2153 2171 def find_cell_magic(self, magic_name):
2154 2172 """Find and return a cell magic by name.
2155 2173
2156 2174 Returns None if the magic isn't found."""
2157 2175 return self.magics_manager.magics['cell'].get(magic_name)
2158 2176
2159 2177 def find_magic(self, magic_name, magic_kind='line'):
2160 2178 """Find and return a magic of the given type by name.
2161 2179
2162 2180 Returns None if the magic isn't found."""
2163 2181 return self.magics_manager.magics[magic_kind].get(magic_name)
2164 2182
2165 2183 def magic(self, arg_s):
2166 2184 """DEPRECATED. Use run_line_magic() instead.
2167 2185
2168 2186 Call a magic function by name.
2169 2187
2170 2188 Input: a string containing the name of the magic function to call and
2171 2189 any additional arguments to be passed to the magic.
2172 2190
2173 2191 magic('name -opt foo bar') is equivalent to typing at the ipython
2174 2192 prompt:
2175 2193
2176 2194 In[1]: %name -opt foo bar
2177 2195
2178 2196 To call a magic without arguments, simply use magic('name').
2179 2197
2180 2198 This provides a proper Python function to call IPython's magics in any
2181 2199 valid Python code you can type at the interpreter, including loops and
2182 2200 compound statements.
2183 2201 """
2184 2202 # TODO: should we issue a loud deprecation warning here?
2185 2203 magic_name, _, magic_arg_s = arg_s.partition(' ')
2186 2204 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2187 2205 return self.run_line_magic(magic_name, magic_arg_s)
2188 2206
2189 2207 #-------------------------------------------------------------------------
2190 2208 # Things related to macros
2191 2209 #-------------------------------------------------------------------------
2192 2210
2193 2211 def define_macro(self, name, themacro):
2194 2212 """Define a new macro
2195 2213
2196 2214 Parameters
2197 2215 ----------
2198 2216 name : str
2199 2217 The name of the macro.
2200 2218 themacro : str or Macro
2201 2219 The action to do upon invoking the macro. If a string, a new
2202 2220 Macro object is created by passing the string to it.
2203 2221 """
2204 2222
2205 2223 from IPython.core import macro
2206 2224
2207 2225 if isinstance(themacro, string_types):
2208 2226 themacro = macro.Macro(themacro)
2209 2227 if not isinstance(themacro, macro.Macro):
2210 2228 raise ValueError('A macro must be a string or a Macro instance.')
2211 2229 self.user_ns[name] = themacro
2212 2230
2213 2231 #-------------------------------------------------------------------------
2214 2232 # Things related to the running of system commands
2215 2233 #-------------------------------------------------------------------------
2216 2234
2217 2235 def system_piped(self, cmd):
2218 2236 """Call the given cmd in a subprocess, piping stdout/err
2219 2237
2220 2238 Parameters
2221 2239 ----------
2222 2240 cmd : str
2223 2241 Command to execute (can not end in '&', as background processes are
2224 2242 not supported. Should not be a command that expects input
2225 2243 other than simple text.
2226 2244 """
2227 2245 if cmd.rstrip().endswith('&'):
2228 2246 # this is *far* from a rigorous test
2229 2247 # We do not support backgrounding processes because we either use
2230 2248 # pexpect or pipes to read from. Users can always just call
2231 2249 # os.system() or use ip.system=ip.system_raw
2232 2250 # if they really want a background process.
2233 2251 raise OSError("Background processes not supported.")
2234 2252
2235 2253 # we explicitly do NOT return the subprocess status code, because
2236 2254 # a non-None value would trigger :func:`sys.displayhook` calls.
2237 2255 # Instead, we store the exit_code in user_ns.
2238 2256 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2239 2257
2240 2258 def system_raw(self, cmd):
2241 2259 """Call the given cmd in a subprocess using os.system on Windows or
2242 2260 subprocess.call using the system shell on other platforms.
2243 2261
2244 2262 Parameters
2245 2263 ----------
2246 2264 cmd : str
2247 2265 Command to execute.
2248 2266 """
2249 2267 cmd = self.var_expand(cmd, depth=1)
2250 2268 # protect os.system from UNC paths on Windows, which it can't handle:
2251 2269 if sys.platform == 'win32':
2252 2270 from IPython.utils._process_win32 import AvoidUNCPath
2253 2271 with AvoidUNCPath() as path:
2254 2272 if path is not None:
2255 2273 cmd = '"pushd %s &&"%s' % (path, cmd)
2256 2274 cmd = py3compat.unicode_to_str(cmd)
2257 2275 ec = os.system(cmd)
2258 2276 else:
2259 2277 cmd = py3compat.unicode_to_str(cmd)
2260 2278 # Call the cmd using the OS shell, instead of the default /bin/sh, if set.
2261 2279 ec = subprocess.call(cmd, shell=True, executable=os.environ.get('SHELL', None))
2262 2280 # exit code is positive for program failure, or negative for
2263 2281 # terminating signal number.
2264 2282
2265 2283 # We explicitly do NOT return the subprocess status code, because
2266 2284 # a non-None value would trigger :func:`sys.displayhook` calls.
2267 2285 # Instead, we store the exit_code in user_ns.
2268 2286 self.user_ns['_exit_code'] = ec
2269 2287
2270 2288 # use piped system by default, because it is better behaved
2271 2289 system = system_piped
2272 2290
2273 2291 def getoutput(self, cmd, split=True, depth=0):
2274 2292 """Get output (possibly including stderr) from a subprocess.
2275 2293
2276 2294 Parameters
2277 2295 ----------
2278 2296 cmd : str
2279 2297 Command to execute (can not end in '&', as background processes are
2280 2298 not supported.
2281 2299 split : bool, optional
2282 2300 If True, split the output into an IPython SList. Otherwise, an
2283 2301 IPython LSString is returned. These are objects similar to normal
2284 2302 lists and strings, with a few convenience attributes for easier
2285 2303 manipulation of line-based output. You can use '?' on them for
2286 2304 details.
2287 2305 depth : int, optional
2288 2306 How many frames above the caller are the local variables which should
2289 2307 be expanded in the command string? The default (0) assumes that the
2290 2308 expansion variables are in the stack frame calling this function.
2291 2309 """
2292 2310 if cmd.rstrip().endswith('&'):
2293 2311 # this is *far* from a rigorous test
2294 2312 raise OSError("Background processes not supported.")
2295 2313 out = getoutput(self.var_expand(cmd, depth=depth+1))
2296 2314 if split:
2297 2315 out = SList(out.splitlines())
2298 2316 else:
2299 2317 out = LSString(out)
2300 2318 return out
2301 2319
2302 2320 #-------------------------------------------------------------------------
2303 2321 # Things related to aliases
2304 2322 #-------------------------------------------------------------------------
2305 2323
2306 2324 def init_alias(self):
2307 2325 self.alias_manager = AliasManager(shell=self, parent=self)
2308 2326 self.configurables.append(self.alias_manager)
2309 2327
2310 2328 #-------------------------------------------------------------------------
2311 2329 # Things related to extensions
2312 2330 #-------------------------------------------------------------------------
2313 2331
2314 2332 def init_extension_manager(self):
2315 2333 self.extension_manager = ExtensionManager(shell=self, parent=self)
2316 2334 self.configurables.append(self.extension_manager)
2317 2335
2318 2336 #-------------------------------------------------------------------------
2319 2337 # Things related to payloads
2320 2338 #-------------------------------------------------------------------------
2321 2339
2322 2340 def init_payload(self):
2323 2341 self.payload_manager = PayloadManager(parent=self)
2324 2342 self.configurables.append(self.payload_manager)
2325 2343
2326 2344 #-------------------------------------------------------------------------
2327 2345 # Things related to widgets
2328 2346 #-------------------------------------------------------------------------
2329 2347
2330 2348 def init_comms(self):
2331 2349 # not implemented in the base class
2332 2350 pass
2333 2351
2334 2352 #-------------------------------------------------------------------------
2335 2353 # Things related to the prefilter
2336 2354 #-------------------------------------------------------------------------
2337 2355
2338 2356 def init_prefilter(self):
2339 2357 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2340 2358 self.configurables.append(self.prefilter_manager)
2341 2359 # Ultimately this will be refactored in the new interpreter code, but
2342 2360 # for now, we should expose the main prefilter method (there's legacy
2343 2361 # code out there that may rely on this).
2344 2362 self.prefilter = self.prefilter_manager.prefilter_lines
2345 2363
2346 2364 def auto_rewrite_input(self, cmd):
2347 2365 """Print to the screen the rewritten form of the user's command.
2348 2366
2349 2367 This shows visual feedback by rewriting input lines that cause
2350 2368 automatic calling to kick in, like::
2351 2369
2352 2370 /f x
2353 2371
2354 2372 into::
2355 2373
2356 2374 ------> f(x)
2357 2375
2358 2376 after the user's input prompt. This helps the user understand that the
2359 2377 input line was transformed automatically by IPython.
2360 2378 """
2361 2379 if not self.show_rewritten_input:
2362 2380 return
2363 2381
2364 2382 rw = self.prompt_manager.render('rewrite') + cmd
2365 2383
2366 2384 try:
2367 2385 # plain ascii works better w/ pyreadline, on some machines, so
2368 2386 # we use it and only print uncolored rewrite if we have unicode
2369 2387 rw = str(rw)
2370 2388 print(rw, file=io.stdout)
2371 2389 except UnicodeEncodeError:
2372 2390 print("------> " + cmd)
2373 2391
2374 2392 #-------------------------------------------------------------------------
2375 2393 # Things related to extracting values/expressions from kernel and user_ns
2376 2394 #-------------------------------------------------------------------------
2377 2395
2378 2396 def _user_obj_error(self):
2379 2397 """return simple exception dict
2380 2398
2381 2399 for use in user_variables / expressions
2382 2400 """
2383 2401
2384 2402 etype, evalue, tb = self._get_exc_info()
2385 2403 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2386 2404
2387 2405 exc_info = {
2388 2406 u'status' : 'error',
2389 2407 u'traceback' : stb,
2390 2408 u'ename' : unicode_type(etype.__name__),
2391 2409 u'evalue' : py3compat.safe_unicode(evalue),
2392 2410 }
2393 2411
2394 2412 return exc_info
2395 2413
2396 2414 def _format_user_obj(self, obj):
2397 2415 """format a user object to display dict
2398 2416
2399 2417 for use in user_expressions / variables
2400 2418 """
2401 2419
2402 2420 data, md = self.display_formatter.format(obj)
2403 2421 value = {
2404 2422 'status' : 'ok',
2405 2423 'data' : data,
2406 2424 'metadata' : md,
2407 2425 }
2408 2426 return value
2409 2427
2410 2428 def user_variables(self, names):
2411 2429 """Get a list of variable names from the user's namespace.
2412 2430
2413 2431 Parameters
2414 2432 ----------
2415 2433 names : list of strings
2416 2434 A list of names of variables to be read from the user namespace.
2417 2435
2418 2436 Returns
2419 2437 -------
2420 2438 A dict, keyed by the input names and with the rich mime-type repr(s) of each value.
2421 2439 Each element will be a sub-dict of the same form as a display_data message.
2422 2440 """
2423 2441 out = {}
2424 2442 user_ns = self.user_ns
2425 2443
2426 2444 for varname in names:
2427 2445 try:
2428 2446 value = self._format_user_obj(user_ns[varname])
2429 2447 except:
2430 2448 value = self._user_obj_error()
2431 2449 out[varname] = value
2432 2450 return out
2433 2451
2434 2452 def user_expressions(self, expressions):
2435 2453 """Evaluate a dict of expressions in the user's namespace.
2436 2454
2437 2455 Parameters
2438 2456 ----------
2439 2457 expressions : dict
2440 2458 A dict with string keys and string values. The expression values
2441 2459 should be valid Python expressions, each of which will be evaluated
2442 2460 in the user namespace.
2443 2461
2444 2462 Returns
2445 2463 -------
2446 2464 A dict, keyed like the input expressions dict, with the rich mime-typed
2447 2465 display_data of each value.
2448 2466 """
2449 2467 out = {}
2450 2468 user_ns = self.user_ns
2451 2469 global_ns = self.user_global_ns
2452 2470
2453 2471 for key, expr in iteritems(expressions):
2454 2472 try:
2455 2473 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2456 2474 except:
2457 2475 value = self._user_obj_error()
2458 2476 out[key] = value
2459 2477 return out
2460 2478
2461 2479 #-------------------------------------------------------------------------
2462 2480 # Things related to the running of code
2463 2481 #-------------------------------------------------------------------------
2464 2482
2465 2483 def ex(self, cmd):
2466 2484 """Execute a normal python statement in user namespace."""
2467 2485 with self.builtin_trap:
2468 2486 exec(cmd, self.user_global_ns, self.user_ns)
2469 2487
2470 2488 def ev(self, expr):
2471 2489 """Evaluate python expression expr in user namespace.
2472 2490
2473 2491 Returns the result of evaluation
2474 2492 """
2475 2493 with self.builtin_trap:
2476 2494 return eval(expr, self.user_global_ns, self.user_ns)
2477 2495
2478 2496 def safe_execfile(self, fname, *where, **kw):
2479 2497 """A safe version of the builtin execfile().
2480 2498
2481 2499 This version will never throw an exception, but instead print
2482 2500 helpful error messages to the screen. This only works on pure
2483 2501 Python files with the .py extension.
2484 2502
2485 2503 Parameters
2486 2504 ----------
2487 2505 fname : string
2488 2506 The name of the file to be executed.
2489 2507 where : tuple
2490 2508 One or two namespaces, passed to execfile() as (globals,locals).
2491 2509 If only one is given, it is passed as both.
2492 2510 exit_ignore : bool (False)
2493 2511 If True, then silence SystemExit for non-zero status (it is always
2494 2512 silenced for zero status, as it is so common).
2495 2513 raise_exceptions : bool (False)
2496 2514 If True raise exceptions everywhere. Meant for testing.
2497 2515
2498 2516 """
2499 2517 kw.setdefault('exit_ignore', False)
2500 2518 kw.setdefault('raise_exceptions', False)
2501 2519
2502 2520 fname = os.path.abspath(os.path.expanduser(fname))
2503 2521
2504 2522 # Make sure we can open the file
2505 2523 try:
2506 2524 with open(fname) as thefile:
2507 2525 pass
2508 2526 except:
2509 2527 warn('Could not open file <%s> for safe execution.' % fname)
2510 2528 return
2511 2529
2512 2530 # Find things also in current directory. This is needed to mimic the
2513 2531 # behavior of running a script from the system command line, where
2514 2532 # Python inserts the script's directory into sys.path
2515 2533 dname = os.path.dirname(fname)
2516 2534
2517 2535 with prepended_to_syspath(dname):
2518 2536 try:
2519 2537 py3compat.execfile(fname,*where)
2520 2538 except SystemExit as status:
2521 2539 # If the call was made with 0 or None exit status (sys.exit(0)
2522 2540 # or sys.exit() ), don't bother showing a traceback, as both of
2523 2541 # these are considered normal by the OS:
2524 2542 # > python -c'import sys;sys.exit(0)'; echo $?
2525 2543 # 0
2526 2544 # > python -c'import sys;sys.exit()'; echo $?
2527 2545 # 0
2528 2546 # For other exit status, we show the exception unless
2529 2547 # explicitly silenced, but only in short form.
2530 2548 if kw['raise_exceptions']:
2531 2549 raise
2532 2550 if status.code and not kw['exit_ignore']:
2533 2551 self.showtraceback(exception_only=True)
2534 2552 except:
2535 2553 if kw['raise_exceptions']:
2536 2554 raise
2537 2555 # tb offset is 2 because we wrap execfile
2538 2556 self.showtraceback(tb_offset=2)
2539 2557
2540 2558 def safe_execfile_ipy(self, fname):
2541 2559 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2542 2560
2543 2561 Parameters
2544 2562 ----------
2545 2563 fname : str
2546 2564 The name of the file to execute. The filename must have a
2547 2565 .ipy or .ipynb extension.
2548 2566 """
2549 2567 fname = os.path.abspath(os.path.expanduser(fname))
2550 2568
2551 2569 # Make sure we can open the file
2552 2570 try:
2553 2571 with open(fname) as thefile:
2554 2572 pass
2555 2573 except:
2556 2574 warn('Could not open file <%s> for safe execution.' % fname)
2557 2575 return
2558 2576
2559 2577 # Find things also in current directory. This is needed to mimic the
2560 2578 # behavior of running a script from the system command line, where
2561 2579 # Python inserts the script's directory into sys.path
2562 2580 dname = os.path.dirname(fname)
2563 2581
2564 2582 def get_cells():
2565 2583 """generator for sequence of code blocks to run"""
2566 2584 if fname.endswith('.ipynb'):
2567 2585 from IPython.nbformat import current
2568 2586 with open(fname) as f:
2569 2587 nb = current.read(f, 'json')
2570 2588 if not nb.worksheets:
2571 2589 return
2572 2590 for cell in nb.worksheets[0].cells:
2573 2591 if cell.cell_type == 'code':
2574 2592 yield cell.input
2575 2593 else:
2576 2594 with open(fname) as f:
2577 2595 yield f.read()
2578 2596
2579 2597 with prepended_to_syspath(dname):
2580 2598 try:
2581 2599 for cell in get_cells():
2582 2600 # self.run_cell currently captures all exceptions
2583 2601 # raised in user code. It would be nice if there were
2584 2602 # versions of run_cell that did raise, so
2585 2603 # we could catch the errors.
2586 2604 self.run_cell(cell, store_history=False, shell_futures=False)
2587 2605 except:
2588 2606 self.showtraceback()
2589 2607 warn('Unknown failure executing file: <%s>' % fname)
2590 2608
2591 2609 def safe_run_module(self, mod_name, where):
2592 2610 """A safe version of runpy.run_module().
2593 2611
2594 2612 This version will never throw an exception, but instead print
2595 2613 helpful error messages to the screen.
2596 2614
2597 2615 `SystemExit` exceptions with status code 0 or None are ignored.
2598 2616
2599 2617 Parameters
2600 2618 ----------
2601 2619 mod_name : string
2602 2620 The name of the module to be executed.
2603 2621 where : dict
2604 2622 The globals namespace.
2605 2623 """
2606 2624 try:
2607 2625 try:
2608 2626 where.update(
2609 2627 runpy.run_module(str(mod_name), run_name="__main__",
2610 2628 alter_sys=True)
2611 2629 )
2612 2630 except SystemExit as status:
2613 2631 if status.code:
2614 2632 raise
2615 2633 except:
2616 2634 self.showtraceback()
2617 2635 warn('Unknown failure executing module: <%s>' % mod_name)
2618 2636
2619 2637 def _run_cached_cell_magic(self, magic_name, line):
2620 2638 """Special method to call a cell magic with the data stored in self.
2621 2639 """
2622 2640 cell = self._current_cell_magic_body
2623 2641 self._current_cell_magic_body = None
2624 2642 return self.run_cell_magic(magic_name, line, cell)
2625 2643
2626 2644 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2627 2645 """Run a complete IPython cell.
2628 2646
2629 2647 Parameters
2630 2648 ----------
2631 2649 raw_cell : str
2632 2650 The code (including IPython code such as %magic functions) to run.
2633 2651 store_history : bool
2634 2652 If True, the raw and translated cell will be stored in IPython's
2635 2653 history. For user code calling back into IPython's machinery, this
2636 2654 should be set to False.
2637 2655 silent : bool
2638 2656 If True, avoid side-effects, such as implicit displayhooks and
2639 2657 and logging. silent=True forces store_history=False.
2640 2658 shell_futures : bool
2641 2659 If True, the code will share future statements with the interactive
2642 2660 shell. It will both be affected by previous __future__ imports, and
2643 2661 any __future__ imports in the code will affect the shell. If False,
2644 2662 __future__ imports are not shared in either direction.
2645 2663 """
2646 2664 if (not raw_cell) or raw_cell.isspace():
2647 2665 return
2648 2666
2649 2667 if silent:
2650 2668 store_history = False
2651 2669
2670 self.events.trigger('pre_execute')
2671 if not silent:
2672 self.events.trigger('pre_run_cell')
2673
2652 2674 # If any of our input transformation (input_transformer_manager or
2653 2675 # prefilter_manager) raises an exception, we store it in this variable
2654 2676 # so that we can display the error after logging the input and storing
2655 2677 # it in the history.
2656 2678 preprocessing_exc_tuple = None
2657 2679 try:
2658 2680 # Static input transformations
2659 2681 cell = self.input_transformer_manager.transform_cell(raw_cell)
2660 2682 except SyntaxError:
2661 2683 preprocessing_exc_tuple = sys.exc_info()
2662 2684 cell = raw_cell # cell has to exist so it can be stored/logged
2663 2685 else:
2664 2686 if len(cell.splitlines()) == 1:
2665 2687 # Dynamic transformations - only applied for single line commands
2666 2688 with self.builtin_trap:
2667 2689 try:
2668 2690 # use prefilter_lines to handle trailing newlines
2669 2691 # restore trailing newline for ast.parse
2670 2692 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2671 2693 except Exception:
2672 2694 # don't allow prefilter errors to crash IPython
2673 2695 preprocessing_exc_tuple = sys.exc_info()
2674 2696
2675 2697 # Store raw and processed history
2676 2698 if store_history:
2677 2699 self.history_manager.store_inputs(self.execution_count,
2678 2700 cell, raw_cell)
2679 2701 if not silent:
2680 2702 self.logger.log(cell, raw_cell)
2681 2703
2682 2704 # Display the exception if input processing failed.
2683 2705 if preprocessing_exc_tuple is not None:
2684 2706 self.showtraceback(preprocessing_exc_tuple)
2685 2707 if store_history:
2686 2708 self.execution_count += 1
2687 2709 return
2688 2710
2689 2711 # Our own compiler remembers the __future__ environment. If we want to
2690 2712 # run code with a separate __future__ environment, use the default
2691 2713 # compiler
2692 2714 compiler = self.compile if shell_futures else CachingCompiler()
2693 2715
2694 2716 with self.builtin_trap:
2695 2717 cell_name = self.compile.cache(cell, self.execution_count)
2696 2718
2697 2719 with self.display_trap:
2698 2720 # Compile to bytecode
2699 2721 try:
2700 2722 code_ast = compiler.ast_parse(cell, filename=cell_name)
2701 2723 except IndentationError:
2702 2724 self.showindentationerror()
2703 2725 if store_history:
2704 2726 self.execution_count += 1
2705 2727 return None
2706 2728 except (OverflowError, SyntaxError, ValueError, TypeError,
2707 2729 MemoryError):
2708 2730 self.showsyntaxerror()
2709 2731 if store_history:
2710 2732 self.execution_count += 1
2711 2733 return None
2712 2734
2713 2735 # Apply AST transformations
2714 2736 code_ast = self.transform_ast(code_ast)
2715 2737
2716 2738 # Execute the user code
2717 2739 interactivity = "none" if silent else self.ast_node_interactivity
2718 2740 self.run_ast_nodes(code_ast.body, cell_name,
2719 2741 interactivity=interactivity, compiler=compiler)
2720 2742
2721 # Execute any registered post-execution functions.
2722 # unless we are silent
2723 post_exec = [] if silent else iteritems(self._post_execute)
2724
2725 for func, status in post_exec:
2726 if self.disable_failing_post_execute and not status:
2727 continue
2728 try:
2729 func()
2730 except KeyboardInterrupt:
2731 print("\nKeyboardInterrupt", file=io.stderr)
2732 except Exception:
2733 # register as failing:
2734 self._post_execute[func] = False
2735 self.showtraceback()
2736 print('\n'.join([
2737 "post-execution function %r produced an error." % func,
2738 "If this problem persists, you can disable failing post-exec functions with:",
2739 "",
2740 " get_ipython().disable_failing_post_execute = True"
2741 ]), file=io.stderr)
2743 self.events.trigger('post_execute')
2744 if not silent:
2745 self.events.trigger('post_run_cell')
2742 2746
2743 2747 if store_history:
2744 2748 # Write output to the database. Does nothing unless
2745 2749 # history output logging is enabled.
2746 2750 self.history_manager.store_output(self.execution_count)
2747 2751 # Each cell is a *single* input, regardless of how many lines it has
2748 2752 self.execution_count += 1
2749 2753
2750 2754 def transform_ast(self, node):
2751 2755 """Apply the AST transformations from self.ast_transformers
2752 2756
2753 2757 Parameters
2754 2758 ----------
2755 2759 node : ast.Node
2756 2760 The root node to be transformed. Typically called with the ast.Module
2757 2761 produced by parsing user input.
2758 2762
2759 2763 Returns
2760 2764 -------
2761 2765 An ast.Node corresponding to the node it was called with. Note that it
2762 2766 may also modify the passed object, so don't rely on references to the
2763 2767 original AST.
2764 2768 """
2765 2769 for transformer in self.ast_transformers:
2766 2770 try:
2767 2771 node = transformer.visit(node)
2768 2772 except Exception:
2769 2773 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
2770 2774 self.ast_transformers.remove(transformer)
2771 2775
2772 2776 if self.ast_transformers:
2773 2777 ast.fix_missing_locations(node)
2774 2778 return node
2775 2779
2776 2780
2777 2781 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr',
2778 2782 compiler=compile):
2779 2783 """Run a sequence of AST nodes. The execution mode depends on the
2780 2784 interactivity parameter.
2781 2785
2782 2786 Parameters
2783 2787 ----------
2784 2788 nodelist : list
2785 2789 A sequence of AST nodes to run.
2786 2790 cell_name : str
2787 2791 Will be passed to the compiler as the filename of the cell. Typically
2788 2792 the value returned by ip.compile.cache(cell).
2789 2793 interactivity : str
2790 2794 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2791 2795 run interactively (displaying output from expressions). 'last_expr'
2792 2796 will run the last node interactively only if it is an expression (i.e.
2793 2797 expressions in loops or other blocks are not displayed. Other values
2794 2798 for this parameter will raise a ValueError.
2795 2799 compiler : callable
2796 2800 A function with the same interface as the built-in compile(), to turn
2797 2801 the AST nodes into code objects. Default is the built-in compile().
2798 2802 """
2799 2803 if not nodelist:
2800 2804 return
2801 2805
2802 2806 if interactivity == 'last_expr':
2803 2807 if isinstance(nodelist[-1], ast.Expr):
2804 2808 interactivity = "last"
2805 2809 else:
2806 2810 interactivity = "none"
2807 2811
2808 2812 if interactivity == 'none':
2809 2813 to_run_exec, to_run_interactive = nodelist, []
2810 2814 elif interactivity == 'last':
2811 2815 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2812 2816 elif interactivity == 'all':
2813 2817 to_run_exec, to_run_interactive = [], nodelist
2814 2818 else:
2815 2819 raise ValueError("Interactivity was %r" % interactivity)
2816 2820
2817 2821 exec_count = self.execution_count
2818 2822
2819 2823 try:
2820 2824 for i, node in enumerate(to_run_exec):
2821 2825 mod = ast.Module([node])
2822 2826 code = compiler(mod, cell_name, "exec")
2823 2827 if self.run_code(code):
2824 2828 return True
2825 2829
2826 2830 for i, node in enumerate(to_run_interactive):
2827 2831 mod = ast.Interactive([node])
2828 2832 code = compiler(mod, cell_name, "single")
2829 2833 if self.run_code(code):
2830 2834 return True
2831 2835
2832 2836 # Flush softspace
2833 2837 if softspace(sys.stdout, 0):
2834 2838 print()
2835 2839
2836 2840 except:
2837 2841 # It's possible to have exceptions raised here, typically by
2838 2842 # compilation of odd code (such as a naked 'return' outside a
2839 2843 # function) that did parse but isn't valid. Typically the exception
2840 2844 # is a SyntaxError, but it's safest just to catch anything and show
2841 2845 # the user a traceback.
2842 2846
2843 2847 # We do only one try/except outside the loop to minimize the impact
2844 2848 # on runtime, and also because if any node in the node list is
2845 2849 # broken, we should stop execution completely.
2846 2850 self.showtraceback()
2847 2851
2848 2852 return False
2849 2853
2850 2854 def run_code(self, code_obj):
2851 2855 """Execute a code object.
2852 2856
2853 2857 When an exception occurs, self.showtraceback() is called to display a
2854 2858 traceback.
2855 2859
2856 2860 Parameters
2857 2861 ----------
2858 2862 code_obj : code object
2859 2863 A compiled code object, to be executed
2860 2864
2861 2865 Returns
2862 2866 -------
2863 2867 False : successful execution.
2864 2868 True : an error occurred.
2865 2869 """
2866 2870
2867 2871 # Set our own excepthook in case the user code tries to call it
2868 2872 # directly, so that the IPython crash handler doesn't get triggered
2869 2873 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2870 2874
2871 2875 # we save the original sys.excepthook in the instance, in case config
2872 2876 # code (such as magics) needs access to it.
2873 2877 self.sys_excepthook = old_excepthook
2874 2878 outflag = 1 # happens in more places, so it's easier as default
2875 2879 try:
2876 2880 try:
2877 2881 self.hooks.pre_run_code_hook()
2878 2882 #rprint('Running code', repr(code_obj)) # dbg
2879 2883 exec(code_obj, self.user_global_ns, self.user_ns)
2880 2884 finally:
2881 2885 # Reset our crash handler in place
2882 2886 sys.excepthook = old_excepthook
2883 2887 except SystemExit:
2884 2888 self.showtraceback(exception_only=True)
2885 2889 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
2886 2890 except self.custom_exceptions:
2887 2891 etype,value,tb = sys.exc_info()
2888 2892 self.CustomTB(etype,value,tb)
2889 2893 except:
2890 2894 self.showtraceback()
2891 2895 else:
2892 2896 outflag = 0
2893 2897 return outflag
2894 2898
2895 2899 # For backwards compatibility
2896 2900 runcode = run_code
2897 2901
2898 2902 #-------------------------------------------------------------------------
2899 2903 # Things related to GUI support and pylab
2900 2904 #-------------------------------------------------------------------------
2901 2905
2902 2906 def enable_gui(self, gui=None):
2903 2907 raise NotImplementedError('Implement enable_gui in a subclass')
2904 2908
2905 2909 def enable_matplotlib(self, gui=None):
2906 2910 """Enable interactive matplotlib and inline figure support.
2907 2911
2908 2912 This takes the following steps:
2909 2913
2910 2914 1. select the appropriate eventloop and matplotlib backend
2911 2915 2. set up matplotlib for interactive use with that backend
2912 2916 3. configure formatters for inline figure display
2913 2917 4. enable the selected gui eventloop
2914 2918
2915 2919 Parameters
2916 2920 ----------
2917 2921 gui : optional, string
2918 2922 If given, dictates the choice of matplotlib GUI backend to use
2919 2923 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2920 2924 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2921 2925 matplotlib (as dictated by the matplotlib build-time options plus the
2922 2926 user's matplotlibrc configuration file). Note that not all backends
2923 2927 make sense in all contexts, for example a terminal ipython can't
2924 2928 display figures inline.
2925 2929 """
2926 2930 from IPython.core import pylabtools as pt
2927 2931 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
2928 2932
2929 2933 if gui != 'inline':
2930 2934 # If we have our first gui selection, store it
2931 2935 if self.pylab_gui_select is None:
2932 2936 self.pylab_gui_select = gui
2933 2937 # Otherwise if they are different
2934 2938 elif gui != self.pylab_gui_select:
2935 2939 print ('Warning: Cannot change to a different GUI toolkit: %s.'
2936 2940 ' Using %s instead.' % (gui, self.pylab_gui_select))
2937 2941 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
2938 2942
2939 2943 pt.activate_matplotlib(backend)
2940 2944 pt.configure_inline_support(self, backend)
2941 2945
2942 2946 # Now we must activate the gui pylab wants to use, and fix %run to take
2943 2947 # plot updates into account
2944 2948 self.enable_gui(gui)
2945 2949 self.magics_manager.registry['ExecutionMagics'].default_runner = \
2946 2950 pt.mpl_runner(self.safe_execfile)
2947 2951
2948 2952 return gui, backend
2949 2953
2950 2954 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
2951 2955 """Activate pylab support at runtime.
2952 2956
2953 2957 This turns on support for matplotlib, preloads into the interactive
2954 2958 namespace all of numpy and pylab, and configures IPython to correctly
2955 2959 interact with the GUI event loop. The GUI backend to be used can be
2956 2960 optionally selected with the optional ``gui`` argument.
2957 2961
2958 2962 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
2959 2963
2960 2964 Parameters
2961 2965 ----------
2962 2966 gui : optional, string
2963 2967 If given, dictates the choice of matplotlib GUI backend to use
2964 2968 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2965 2969 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2966 2970 matplotlib (as dictated by the matplotlib build-time options plus the
2967 2971 user's matplotlibrc configuration file). Note that not all backends
2968 2972 make sense in all contexts, for example a terminal ipython can't
2969 2973 display figures inline.
2970 2974 import_all : optional, bool, default: True
2971 2975 Whether to do `from numpy import *` and `from pylab import *`
2972 2976 in addition to module imports.
2973 2977 welcome_message : deprecated
2974 2978 This argument is ignored, no welcome message will be displayed.
2975 2979 """
2976 2980 from IPython.core.pylabtools import import_pylab
2977 2981
2978 2982 gui, backend = self.enable_matplotlib(gui)
2979 2983
2980 2984 # We want to prevent the loading of pylab to pollute the user's
2981 2985 # namespace as shown by the %who* magics, so we execute the activation
2982 2986 # code in an empty namespace, and we update *both* user_ns and
2983 2987 # user_ns_hidden with this information.
2984 2988 ns = {}
2985 2989 import_pylab(ns, import_all)
2986 2990 # warn about clobbered names
2987 2991 ignored = set(["__builtins__"])
2988 2992 both = set(ns).intersection(self.user_ns).difference(ignored)
2989 2993 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
2990 2994 self.user_ns.update(ns)
2991 2995 self.user_ns_hidden.update(ns)
2992 2996 return gui, backend, clobbered
2993 2997
2994 2998 #-------------------------------------------------------------------------
2995 2999 # Utilities
2996 3000 #-------------------------------------------------------------------------
2997 3001
2998 3002 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
2999 3003 """Expand python variables in a string.
3000 3004
3001 3005 The depth argument indicates how many frames above the caller should
3002 3006 be walked to look for the local namespace where to expand variables.
3003 3007
3004 3008 The global namespace for expansion is always the user's interactive
3005 3009 namespace.
3006 3010 """
3007 3011 ns = self.user_ns.copy()
3008 3012 ns.update(sys._getframe(depth+1).f_locals)
3009 3013 try:
3010 3014 # We have to use .vformat() here, because 'self' is a valid and common
3011 3015 # name, and expanding **ns for .format() would make it collide with
3012 3016 # the 'self' argument of the method.
3013 3017 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3014 3018 except Exception:
3015 3019 # if formatter couldn't format, just let it go untransformed
3016 3020 pass
3017 3021 return cmd
3018 3022
3019 3023 def mktempfile(self, data=None, prefix='ipython_edit_'):
3020 3024 """Make a new tempfile and return its filename.
3021 3025
3022 3026 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3023 3027 but it registers the created filename internally so ipython cleans it up
3024 3028 at exit time.
3025 3029
3026 3030 Optional inputs:
3027 3031
3028 3032 - data(None): if data is given, it gets written out to the temp file
3029 3033 immediately, and the file is closed again."""
3030 3034
3031 3035 dirname = tempfile.mkdtemp(prefix=prefix)
3032 3036 self.tempdirs.append(dirname)
3033 3037
3034 3038 handle, filename = tempfile.mkstemp('.py', prefix, dir=dirname)
3035 3039 self.tempfiles.append(filename)
3036 3040
3037 3041 if data:
3038 3042 tmp_file = open(filename,'w')
3039 3043 tmp_file.write(data)
3040 3044 tmp_file.close()
3041 3045 return filename
3042 3046
3043 3047 # TODO: This should be removed when Term is refactored.
3044 3048 def write(self,data):
3045 3049 """Write a string to the default output"""
3046 3050 io.stdout.write(data)
3047 3051
3048 3052 # TODO: This should be removed when Term is refactored.
3049 3053 def write_err(self,data):
3050 3054 """Write a string to the default error output"""
3051 3055 io.stderr.write(data)
3052 3056
3053 3057 def ask_yes_no(self, prompt, default=None):
3054 3058 if self.quiet:
3055 3059 return True
3056 3060 return ask_yes_no(prompt,default)
3057 3061
3058 3062 def show_usage(self):
3059 3063 """Show a usage message"""
3060 3064 page.page(IPython.core.usage.interactive_usage)
3061 3065
3062 3066 def extract_input_lines(self, range_str, raw=False):
3063 3067 """Return as a string a set of input history slices.
3064 3068
3065 3069 Parameters
3066 3070 ----------
3067 3071 range_str : string
3068 3072 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3069 3073 since this function is for use by magic functions which get their
3070 3074 arguments as strings. The number before the / is the session
3071 3075 number: ~n goes n back from the current session.
3072 3076
3073 3077 raw : bool, optional
3074 3078 By default, the processed input is used. If this is true, the raw
3075 3079 input history is used instead.
3076 3080
3077 3081 Notes
3078 3082 -----
3079 3083
3080 3084 Slices can be described with two notations:
3081 3085
3082 3086 * ``N:M`` -> standard python form, means including items N...(M-1).
3083 3087 * ``N-M`` -> include items N..M (closed endpoint).
3084 3088 """
3085 3089 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3086 3090 return "\n".join(x for _, _, x in lines)
3087 3091
3088 3092 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True):
3089 3093 """Get a code string from history, file, url, or a string or macro.
3090 3094
3091 3095 This is mainly used by magic functions.
3092 3096
3093 3097 Parameters
3094 3098 ----------
3095 3099
3096 3100 target : str
3097 3101
3098 3102 A string specifying code to retrieve. This will be tried respectively
3099 3103 as: ranges of input history (see %history for syntax), url,
3100 3104 correspnding .py file, filename, or an expression evaluating to a
3101 3105 string or Macro in the user namespace.
3102 3106
3103 3107 raw : bool
3104 3108 If true (default), retrieve raw history. Has no effect on the other
3105 3109 retrieval mechanisms.
3106 3110
3107 3111 py_only : bool (default False)
3108 3112 Only try to fetch python code, do not try alternative methods to decode file
3109 3113 if unicode fails.
3110 3114
3111 3115 Returns
3112 3116 -------
3113 3117 A string of code.
3114 3118
3115 3119 ValueError is raised if nothing is found, and TypeError if it evaluates
3116 3120 to an object of another type. In each case, .args[0] is a printable
3117 3121 message.
3118 3122 """
3119 3123 code = self.extract_input_lines(target, raw=raw) # Grab history
3120 3124 if code:
3121 3125 return code
3122 3126 utarget = unquote_filename(target)
3123 3127 try:
3124 3128 if utarget.startswith(('http://', 'https://')):
3125 3129 return openpy.read_py_url(utarget, skip_encoding_cookie=skip_encoding_cookie)
3126 3130 except UnicodeDecodeError:
3127 3131 if not py_only :
3128 3132 # Deferred import
3129 3133 try:
3130 3134 from urllib.request import urlopen # Py3
3131 3135 except ImportError:
3132 3136 from urllib import urlopen
3133 3137 response = urlopen(target)
3134 3138 return response.read().decode('latin1')
3135 3139 raise ValueError(("'%s' seem to be unreadable.") % utarget)
3136 3140
3137 3141 potential_target = [target]
3138 3142 try :
3139 3143 potential_target.insert(0,get_py_filename(target))
3140 3144 except IOError:
3141 3145 pass
3142 3146
3143 3147 for tgt in potential_target :
3144 3148 if os.path.isfile(tgt): # Read file
3145 3149 try :
3146 3150 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3147 3151 except UnicodeDecodeError :
3148 3152 if not py_only :
3149 3153 with io_open(tgt,'r', encoding='latin1') as f :
3150 3154 return f.read()
3151 3155 raise ValueError(("'%s' seem to be unreadable.") % target)
3152 3156 elif os.path.isdir(os.path.expanduser(tgt)):
3153 3157 raise ValueError("'%s' is a directory, not a regular file." % target)
3154 3158
3155 3159 try: # User namespace
3156 3160 codeobj = eval(target, self.user_ns)
3157 3161 except Exception:
3158 3162 raise ValueError(("'%s' was not found in history, as a file, url, "
3159 3163 "nor in the user namespace.") % target)
3160 3164 if isinstance(codeobj, string_types):
3161 3165 return codeobj
3162 3166 elif isinstance(codeobj, Macro):
3163 3167 return codeobj.value
3164 3168
3165 3169 raise TypeError("%s is neither a string nor a macro." % target,
3166 3170 codeobj)
3167 3171
3168 3172 #-------------------------------------------------------------------------
3169 3173 # Things related to IPython exiting
3170 3174 #-------------------------------------------------------------------------
3171 3175 def atexit_operations(self):
3172 3176 """This will be executed at the time of exit.
3173 3177
3174 3178 Cleanup operations and saving of persistent data that is done
3175 3179 unconditionally by IPython should be performed here.
3176 3180
3177 3181 For things that may depend on startup flags or platform specifics (such
3178 3182 as having readline or not), register a separate atexit function in the
3179 3183 code that has the appropriate information, rather than trying to
3180 3184 clutter
3181 3185 """
3182 3186 # Close the history session (this stores the end time and line count)
3183 3187 # this must be *before* the tempfile cleanup, in case of temporary
3184 3188 # history db
3185 3189 self.history_manager.end_session()
3186 3190
3187 3191 # Cleanup all tempfiles and folders left around
3188 3192 for tfile in self.tempfiles:
3189 3193 try:
3190 3194 os.unlink(tfile)
3191 3195 except OSError:
3192 3196 pass
3193 3197
3194 3198 for tdir in self.tempdirs:
3195 3199 try:
3196 3200 os.rmdir(tdir)
3197 3201 except OSError:
3198 3202 pass
3199 3203
3200 3204 # Clear all user namespaces to release all references cleanly.
3201 3205 self.reset(new_session=False)
3202 3206
3203 3207 # Run user hooks
3204 3208 self.hooks.shutdown_hook()
3205 3209
3206 3210 def cleanup(self):
3207 3211 self.restore_sys_module_state()
3208 3212
3209 3213
3210 3214 class InteractiveShellABC(with_metaclass(abc.ABCMeta, object)):
3211 3215 """An abstract base class for InteractiveShell."""
3212 3216
3213 3217 InteractiveShellABC.register(InteractiveShell)
@@ -1,374 +1,376 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Pylab (matplotlib) support utilities.
3 3
4 4 Authors
5 5 -------
6 6
7 7 * Fernando Perez.
8 8 * Brian Granger
9 9 """
10 10 from __future__ import print_function
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2009 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import sys
24 24 from io import BytesIO
25 25
26 26 from IPython.core.display import _pngxy
27 27 from IPython.utils.decorators import flag_calls
28 28 from IPython.utils import py3compat
29 29
30 30 # If user specifies a GUI, that dictates the backend, otherwise we read the
31 31 # user's mpl default from the mpl rc structure
32 32 backends = {'tk': 'TkAgg',
33 33 'gtk': 'GTKAgg',
34 34 'gtk3': 'GTK3Agg',
35 35 'wx': 'WXAgg',
36 36 'qt': 'Qt4Agg', # qt3 not supported
37 37 'qt4': 'Qt4Agg',
38 38 'osx': 'MacOSX',
39 39 'inline' : 'module://IPython.kernel.zmq.pylab.backend_inline'}
40 40
41 41 # We also need a reverse backends2guis mapping that will properly choose which
42 42 # GUI support to activate based on the desired matplotlib backend. For the
43 43 # most part it's just a reverse of the above dict, but we also need to add a
44 44 # few others that map to the same GUI manually:
45 45 backend2gui = dict(zip(backends.values(), backends.keys()))
46 46 # Our tests expect backend2gui to just return 'qt'
47 47 backend2gui['Qt4Agg'] = 'qt'
48 48 # In the reverse mapping, there are a few extra valid matplotlib backends that
49 49 # map to the same GUI support
50 50 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
51 51 backend2gui['GTK3Cairo'] = 'gtk3'
52 52 backend2gui['WX'] = 'wx'
53 53 backend2gui['CocoaAgg'] = 'osx'
54 54
55 55 #-----------------------------------------------------------------------------
56 56 # Matplotlib utilities
57 57 #-----------------------------------------------------------------------------
58 58
59 59
60 60 def getfigs(*fig_nums):
61 61 """Get a list of matplotlib figures by figure numbers.
62 62
63 63 If no arguments are given, all available figures are returned. If the
64 64 argument list contains references to invalid figures, a warning is printed
65 65 but the function continues pasting further figures.
66 66
67 67 Parameters
68 68 ----------
69 69 figs : tuple
70 70 A tuple of ints giving the figure numbers of the figures to return.
71 71 """
72 72 from matplotlib._pylab_helpers import Gcf
73 73 if not fig_nums:
74 74 fig_managers = Gcf.get_all_fig_managers()
75 75 return [fm.canvas.figure for fm in fig_managers]
76 76 else:
77 77 figs = []
78 78 for num in fig_nums:
79 79 f = Gcf.figs.get(num)
80 80 if f is None:
81 81 print('Warning: figure %s not available.' % num)
82 82 else:
83 83 figs.append(f.canvas.figure)
84 84 return figs
85 85
86 86
87 87 def figsize(sizex, sizey):
88 88 """Set the default figure size to be [sizex, sizey].
89 89
90 90 This is just an easy to remember, convenience wrapper that sets::
91 91
92 92 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
93 93 """
94 94 import matplotlib
95 95 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
96 96
97 97
98 98 def print_figure(fig, fmt='png', bbox_inches='tight', **kwargs):
99 99 """Print a figure to an image, and return the resulting bytes
100 100
101 101 Any keyword args are passed to fig.canvas.print_figure,
102 102 such as ``quality`` or ``bbox_inches``.
103 103 """
104 104 from matplotlib import rcParams
105 105 # When there's an empty figure, we shouldn't return anything, otherwise we
106 106 # get big blank areas in the qt console.
107 107 if not fig.axes and not fig.lines:
108 108 return
109 109
110 110 dpi = rcParams['savefig.dpi']
111 111 if fmt == 'retina':
112 112 dpi = dpi * 2
113 113 fmt = 'png'
114 114
115 115 # build keyword args
116 116 kw = dict(
117 117 format=fmt,
118 118 fc=fig.get_facecolor(),
119 119 ec=fig.get_edgecolor(),
120 120 dpi=dpi,
121 121 bbox_inches=bbox_inches,
122 122 )
123 123 # **kwargs get higher priority
124 124 kw.update(kwargs)
125 125
126 126 bytes_io = BytesIO()
127 127 fig.canvas.print_figure(bytes_io, **kw)
128 128 return bytes_io.getvalue()
129 129
130 130 def retina_figure(fig, **kwargs):
131 131 """format a figure as a pixel-doubled (retina) PNG"""
132 132 pngdata = print_figure(fig, fmt='retina', **kwargs)
133 133 w, h = _pngxy(pngdata)
134 134 metadata = dict(width=w//2, height=h//2)
135 135 return pngdata, metadata
136 136
137 137 # We need a little factory function here to create the closure where
138 138 # safe_execfile can live.
139 139 def mpl_runner(safe_execfile):
140 140 """Factory to return a matplotlib-enabled runner for %run.
141 141
142 142 Parameters
143 143 ----------
144 144 safe_execfile : function
145 145 This must be a function with the same interface as the
146 146 :meth:`safe_execfile` method of IPython.
147 147
148 148 Returns
149 149 -------
150 150 A function suitable for use as the ``runner`` argument of the %run magic
151 151 function.
152 152 """
153 153
154 154 def mpl_execfile(fname,*where,**kw):
155 155 """matplotlib-aware wrapper around safe_execfile.
156 156
157 157 Its interface is identical to that of the :func:`execfile` builtin.
158 158
159 159 This is ultimately a call to execfile(), but wrapped in safeties to
160 160 properly handle interactive rendering."""
161 161
162 162 import matplotlib
163 163 import matplotlib.pylab as pylab
164 164
165 165 #print '*** Matplotlib runner ***' # dbg
166 166 # turn off rendering until end of script
167 167 is_interactive = matplotlib.rcParams['interactive']
168 168 matplotlib.interactive(False)
169 169 safe_execfile(fname,*where,**kw)
170 170 matplotlib.interactive(is_interactive)
171 171 # make rendering call now, if the user tried to do it
172 172 if pylab.draw_if_interactive.called:
173 173 pylab.draw()
174 174 pylab.draw_if_interactive.called = False
175 175
176 176 return mpl_execfile
177 177
178 178
179 179 def select_figure_formats(shell, formats, **kwargs):
180 180 """Select figure formats for the inline backend.
181 181
182 182 Parameters
183 183 ==========
184 184 shell : InteractiveShell
185 185 The main IPython instance.
186 186 formats : str or set
187 187 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
188 188 **kwargs : any
189 189 Extra keyword arguments to be passed to fig.canvas.print_figure.
190 190 """
191 191 from matplotlib.figure import Figure
192 192 from IPython.kernel.zmq.pylab import backend_inline
193 193
194 194 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
195 195 png_formatter = shell.display_formatter.formatters['image/png']
196 196 jpg_formatter = shell.display_formatter.formatters['image/jpeg']
197 197 pdf_formatter = shell.display_formatter.formatters['application/pdf']
198 198
199 199 if isinstance(formats, py3compat.string_types):
200 200 formats = {formats}
201 201 # cast in case of list / tuple
202 202 formats = set(formats)
203 203
204 204 [ f.pop(Figure, None) for f in shell.display_formatter.formatters.values() ]
205 205
206 206 supported = {'png', 'png2x', 'retina', 'jpg', 'jpeg', 'svg', 'pdf'}
207 207 bad = formats.difference(supported)
208 208 if bad:
209 209 bs = "%s" % ','.join([repr(f) for f in bad])
210 210 gs = "%s" % ','.join([repr(f) for f in supported])
211 211 raise ValueError("supported formats are: %s not %s" % (gs, bs))
212 212
213 213 if 'png' in formats:
214 214 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
215 215 if 'retina' in formats or 'png2x' in formats:
216 216 png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))
217 217 if 'jpg' in formats or 'jpeg' in formats:
218 218 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', **kwargs))
219 219 if 'svg' in formats:
220 220 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg', **kwargs))
221 221 if 'pdf' in formats:
222 222 pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf', **kwargs))
223 223
224 224 #-----------------------------------------------------------------------------
225 225 # Code for initializing matplotlib and importing pylab
226 226 #-----------------------------------------------------------------------------
227 227
228 228
229 229 def find_gui_and_backend(gui=None, gui_select=None):
230 230 """Given a gui string return the gui and mpl backend.
231 231
232 232 Parameters
233 233 ----------
234 234 gui : str
235 235 Can be one of ('tk','gtk','wx','qt','qt4','inline').
236 236 gui_select : str
237 237 Can be one of ('tk','gtk','wx','qt','qt4','inline').
238 238 This is any gui already selected by the shell.
239 239
240 240 Returns
241 241 -------
242 242 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
243 243 'WXAgg','Qt4Agg','module://IPython.kernel.zmq.pylab.backend_inline').
244 244 """
245 245
246 246 import matplotlib
247 247
248 248 if gui and gui != 'auto':
249 249 # select backend based on requested gui
250 250 backend = backends[gui]
251 251 else:
252 252 # We need to read the backend from the original data structure, *not*
253 253 # from mpl.rcParams, since a prior invocation of %matplotlib may have
254 254 # overwritten that.
255 255 # WARNING: this assumes matplotlib 1.1 or newer!!
256 256 backend = matplotlib.rcParamsOrig['backend']
257 257 # In this case, we need to find what the appropriate gui selection call
258 258 # should be for IPython, so we can activate inputhook accordingly
259 259 gui = backend2gui.get(backend, None)
260 260
261 261 # If we have already had a gui active, we need it and inline are the
262 262 # ones allowed.
263 263 if gui_select and gui != gui_select:
264 264 gui = gui_select
265 265 backend = backends[gui]
266 266
267 267 return gui, backend
268 268
269 269
270 270 def activate_matplotlib(backend):
271 271 """Activate the given backend and set interactive to True."""
272 272
273 273 import matplotlib
274 274 matplotlib.interactive(True)
275 275
276 276 # Matplotlib had a bug where even switch_backend could not force
277 277 # the rcParam to update. This needs to be set *before* the module
278 278 # magic of switch_backend().
279 279 matplotlib.rcParams['backend'] = backend
280 280
281 281 import matplotlib.pyplot
282 282 matplotlib.pyplot.switch_backend(backend)
283 283
284 284 # This must be imported last in the matplotlib series, after
285 285 # backend/interactivity choices have been made
286 286 import matplotlib.pylab as pylab
287 287
288 288 pylab.show._needmain = False
289 289 # We need to detect at runtime whether show() is called by the user.
290 290 # For this, we wrap it into a decorator which adds a 'called' flag.
291 291 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
292 292
293 293
294 294 def import_pylab(user_ns, import_all=True):
295 295 """Populate the namespace with pylab-related values.
296 296
297 297 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
298 298
299 299 Also imports a few names from IPython (figsize, display, getfigs)
300 300
301 301 """
302 302
303 303 # Import numpy as np/pyplot as plt are conventions we're trying to
304 304 # somewhat standardize on. Making them available to users by default
305 305 # will greatly help this.
306 306 s = ("import numpy\n"
307 307 "import matplotlib\n"
308 308 "from matplotlib import pylab, mlab, pyplot\n"
309 309 "np = numpy\n"
310 310 "plt = pyplot\n"
311 311 )
312 312 exec(s, user_ns)
313 313
314 314 if import_all:
315 315 s = ("from matplotlib.pylab import *\n"
316 316 "from numpy import *\n")
317 317 exec(s, user_ns)
318 318
319 319 # IPython symbols to add
320 320 user_ns['figsize'] = figsize
321 321 from IPython.core.display import display
322 322 # Add display and getfigs to the user's namespace
323 323 user_ns['display'] = display
324 324 user_ns['getfigs'] = getfigs
325 325
326 326
327 327 def configure_inline_support(shell, backend):
328 328 """Configure an IPython shell object for matplotlib use.
329 329
330 330 Parameters
331 331 ----------
332 332 shell : InteractiveShell instance
333 333
334 334 backend : matplotlib backend
335 335 """
336 336 # If using our svg payload backend, register the post-execution
337 337 # function that will pick up the results for display. This can only be
338 338 # done with access to the real shell object.
339 339
340 340 # Note: if we can't load the inline backend, then there's no point
341 341 # continuing (such as in terminal-only shells in environments without
342 342 # zeromq available).
343 343 try:
344 344 from IPython.kernel.zmq.pylab.backend_inline import InlineBackend
345 345 except ImportError:
346 346 return
347 347 from matplotlib import pyplot
348 348
349 349 cfg = InlineBackend.instance(parent=shell)
350 350 cfg.shell = shell
351 351 if cfg not in shell.configurables:
352 352 shell.configurables.append(cfg)
353 353
354 354 if backend == backends['inline']:
355 355 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
356 shell.register_post_execute(flush_figures)
356 shell.events.register('post_execute', flush_figures)
357 357
358 358 # Save rcParams that will be overwrittern
359 359 shell._saved_rcParams = dict()
360 360 for k in cfg.rc:
361 361 shell._saved_rcParams[k] = pyplot.rcParams[k]
362 362 # load inline_rc
363 363 pyplot.rcParams.update(cfg.rc)
364 364 else:
365 365 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
366 if flush_figures in shell._post_execute:
367 shell._post_execute.pop(flush_figures)
366 try:
367 shell.events.unregister('post_execute', flush_figures)
368 except ValueError:
369 pass
368 370 if hasattr(shell, '_saved_rcParams'):
369 371 pyplot.rcParams.update(shell._saved_rcParams)
370 372 del shell._saved_rcParams
371 373
372 374 # Setup the default figure format
373 375 select_figure_formats(shell, cfg.figure_formats, **cfg.print_figure_kwargs)
374 376
@@ -1,715 +1,730 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for the key interactiveshell module.
3 3
4 4 Historically the main classes in interactiveshell have been under-tested. This
5 5 module should grow as many single-method tests as possible to trap many of the
6 6 recurring bugs we seem to encounter with high-level interaction.
7 7
8 8 Authors
9 9 -------
10 10 * Fernando Perez
11 11 """
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2011 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22 # stdlib
23 23 import ast
24 24 import os
25 25 import signal
26 26 import shutil
27 27 import sys
28 28 import tempfile
29 29 import unittest
30 try:
31 from unittest import mock
32 except ImportError:
33 import mock
30 34 from os.path import join
31 35
32 36 # third-party
33 37 import nose.tools as nt
34 38
35 39 # Our own
36 40 from IPython.core.inputtransformer import InputTransformer
37 41 from IPython.testing.decorators import skipif, skip_win32, onlyif_unicode_paths
38 42 from IPython.testing import tools as tt
39 43 from IPython.utils import io
40 44 from IPython.utils import py3compat
41 45 from IPython.utils.py3compat import unicode_type, PY3
42 46
43 47 if PY3:
44 48 from io import StringIO
45 49 else:
46 50 from StringIO import StringIO
47 51
48 52 #-----------------------------------------------------------------------------
49 53 # Globals
50 54 #-----------------------------------------------------------------------------
51 55 # This is used by every single test, no point repeating it ad nauseam
52 56 ip = get_ipython()
53 57
54 58 #-----------------------------------------------------------------------------
55 59 # Tests
56 60 #-----------------------------------------------------------------------------
57 61
58 62 class InteractiveShellTestCase(unittest.TestCase):
59 63 def test_naked_string_cells(self):
60 64 """Test that cells with only naked strings are fully executed"""
61 65 # First, single-line inputs
62 66 ip.run_cell('"a"\n')
63 67 self.assertEqual(ip.user_ns['_'], 'a')
64 68 # And also multi-line cells
65 69 ip.run_cell('"""a\nb"""\n')
66 70 self.assertEqual(ip.user_ns['_'], 'a\nb')
67 71
68 72 def test_run_empty_cell(self):
69 73 """Just make sure we don't get a horrible error with a blank
70 74 cell of input. Yes, I did overlook that."""
71 75 old_xc = ip.execution_count
72 76 ip.run_cell('')
73 77 self.assertEqual(ip.execution_count, old_xc)
74 78
75 79 def test_run_cell_multiline(self):
76 80 """Multi-block, multi-line cells must execute correctly.
77 81 """
78 82 src = '\n'.join(["x=1",
79 83 "y=2",
80 84 "if 1:",
81 85 " x += 1",
82 86 " y += 1",])
83 87 ip.run_cell(src)
84 88 self.assertEqual(ip.user_ns['x'], 2)
85 89 self.assertEqual(ip.user_ns['y'], 3)
86 90
87 91 def test_multiline_string_cells(self):
88 92 "Code sprinkled with multiline strings should execute (GH-306)"
89 93 ip.run_cell('tmp=0')
90 94 self.assertEqual(ip.user_ns['tmp'], 0)
91 95 ip.run_cell('tmp=1;"""a\nb"""\n')
92 96 self.assertEqual(ip.user_ns['tmp'], 1)
93 97
94 98 def test_dont_cache_with_semicolon(self):
95 99 "Ending a line with semicolon should not cache the returned object (GH-307)"
96 100 oldlen = len(ip.user_ns['Out'])
97 101 a = ip.run_cell('1;', store_history=True)
98 102 newlen = len(ip.user_ns['Out'])
99 103 self.assertEqual(oldlen, newlen)
100 104 #also test the default caching behavior
101 105 ip.run_cell('1', store_history=True)
102 106 newlen = len(ip.user_ns['Out'])
103 107 self.assertEqual(oldlen+1, newlen)
104 108
105 109 def test_In_variable(self):
106 110 "Verify that In variable grows with user input (GH-284)"
107 111 oldlen = len(ip.user_ns['In'])
108 112 ip.run_cell('1;', store_history=True)
109 113 newlen = len(ip.user_ns['In'])
110 114 self.assertEqual(oldlen+1, newlen)
111 115 self.assertEqual(ip.user_ns['In'][-1],'1;')
112 116
113 117 def test_magic_names_in_string(self):
114 118 ip.run_cell('a = """\n%exit\n"""')
115 119 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
116 120
117 121 def test_trailing_newline(self):
118 122 """test that running !(command) does not raise a SyntaxError"""
119 123 ip.run_cell('!(true)\n', False)
120 124 ip.run_cell('!(true)\n\n\n', False)
121 125
122 126 def test_gh_597(self):
123 127 """Pretty-printing lists of objects with non-ascii reprs may cause
124 128 problems."""
125 129 class Spam(object):
126 130 def __repr__(self):
127 131 return "\xe9"*50
128 132 import IPython.core.formatters
129 133 f = IPython.core.formatters.PlainTextFormatter()
130 134 f([Spam(),Spam()])
131 135
132 136
133 137 def test_future_flags(self):
134 138 """Check that future flags are used for parsing code (gh-777)"""
135 139 ip.run_cell('from __future__ import print_function')
136 140 try:
137 141 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
138 142 assert 'prfunc_return_val' in ip.user_ns
139 143 finally:
140 144 # Reset compiler flags so we don't mess up other tests.
141 145 ip.compile.reset_compiler_flags()
142 146
143 147 def test_future_unicode(self):
144 148 """Check that unicode_literals is imported from __future__ (gh #786)"""
145 149 try:
146 150 ip.run_cell(u'byte_str = "a"')
147 151 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
148 152 ip.run_cell('from __future__ import unicode_literals')
149 153 ip.run_cell(u'unicode_str = "a"')
150 154 assert isinstance(ip.user_ns['unicode_str'], unicode_type) # strings literals are now unicode
151 155 finally:
152 156 # Reset compiler flags so we don't mess up other tests.
153 157 ip.compile.reset_compiler_flags()
154 158
155 159 def test_can_pickle(self):
156 160 "Can we pickle objects defined interactively (GH-29)"
157 161 ip = get_ipython()
158 162 ip.reset()
159 163 ip.run_cell(("class Mylist(list):\n"
160 164 " def __init__(self,x=[]):\n"
161 165 " list.__init__(self,x)"))
162 166 ip.run_cell("w=Mylist([1,2,3])")
163 167
164 168 from pickle import dumps
165 169
166 170 # We need to swap in our main module - this is only necessary
167 171 # inside the test framework, because IPython puts the interactive module
168 172 # in place (but the test framework undoes this).
169 173 _main = sys.modules['__main__']
170 174 sys.modules['__main__'] = ip.user_module
171 175 try:
172 176 res = dumps(ip.user_ns["w"])
173 177 finally:
174 178 sys.modules['__main__'] = _main
175 179 self.assertTrue(isinstance(res, bytes))
176 180
177 181 def test_global_ns(self):
178 182 "Code in functions must be able to access variables outside them."
179 183 ip = get_ipython()
180 184 ip.run_cell("a = 10")
181 185 ip.run_cell(("def f(x):\n"
182 186 " return x + a"))
183 187 ip.run_cell("b = f(12)")
184 188 self.assertEqual(ip.user_ns["b"], 22)
185 189
186 190 def test_bad_custom_tb(self):
187 191 """Check that InteractiveShell is protected from bad custom exception handlers"""
188 192 from IPython.utils import io
189 193 save_stderr = io.stderr
190 194 try:
191 195 # capture stderr
192 196 io.stderr = StringIO()
193 197 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
194 198 self.assertEqual(ip.custom_exceptions, (IOError,))
195 199 ip.run_cell(u'raise IOError("foo")')
196 200 self.assertEqual(ip.custom_exceptions, ())
197 201 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
198 202 finally:
199 203 io.stderr = save_stderr
200 204
201 205 def test_bad_custom_tb_return(self):
202 206 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
203 207 from IPython.utils import io
204 208 save_stderr = io.stderr
205 209 try:
206 210 # capture stderr
207 211 io.stderr = StringIO()
208 212 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
209 213 self.assertEqual(ip.custom_exceptions, (NameError,))
210 214 ip.run_cell(u'a=abracadabra')
211 215 self.assertEqual(ip.custom_exceptions, ())
212 216 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
213 217 finally:
214 218 io.stderr = save_stderr
215 219
216 220 def test_drop_by_id(self):
217 221 myvars = {"a":object(), "b":object(), "c": object()}
218 222 ip.push(myvars, interactive=False)
219 223 for name in myvars:
220 224 assert name in ip.user_ns, name
221 225 assert name in ip.user_ns_hidden, name
222 226 ip.user_ns['b'] = 12
223 227 ip.drop_by_id(myvars)
224 228 for name in ["a", "c"]:
225 229 assert name not in ip.user_ns, name
226 230 assert name not in ip.user_ns_hidden, name
227 231 assert ip.user_ns['b'] == 12
228 232 ip.reset()
229 233
230 234 def test_var_expand(self):
231 235 ip.user_ns['f'] = u'Ca\xf1o'
232 236 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
233 237 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
234 238 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
235 239 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
236 240
237 241 ip.user_ns['f'] = b'Ca\xc3\xb1o'
238 242 # This should not raise any exception:
239 243 ip.var_expand(u'echo $f')
240 244
241 245 def test_var_expand_local(self):
242 246 """Test local variable expansion in !system and %magic calls"""
243 247 # !system
244 248 ip.run_cell('def test():\n'
245 249 ' lvar = "ttt"\n'
246 250 ' ret = !echo {lvar}\n'
247 251 ' return ret[0]\n')
248 252 res = ip.user_ns['test']()
249 253 nt.assert_in('ttt', res)
250 254
251 255 # %magic
252 256 ip.run_cell('def makemacro():\n'
253 257 ' macroname = "macro_var_expand_locals"\n'
254 258 ' %macro {macroname} codestr\n')
255 259 ip.user_ns['codestr'] = "str(12)"
256 260 ip.run_cell('makemacro()')
257 261 nt.assert_in('macro_var_expand_locals', ip.user_ns)
258 262
259 263 def test_var_expand_self(self):
260 264 """Test variable expansion with the name 'self', which was failing.
261 265
262 266 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
263 267 """
264 268 ip.run_cell('class cTest:\n'
265 269 ' classvar="see me"\n'
266 270 ' def test(self):\n'
267 271 ' res = !echo Variable: {self.classvar}\n'
268 272 ' return res[0]\n')
269 273 nt.assert_in('see me', ip.user_ns['cTest']().test())
270 274
271 275 def test_bad_var_expand(self):
272 276 """var_expand on invalid formats shouldn't raise"""
273 277 # SyntaxError
274 278 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
275 279 # NameError
276 280 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
277 281 # ZeroDivisionError
278 282 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
279 283
280 def test_silent_nopostexec(self):
281 """run_cell(silent=True) doesn't invoke post-exec funcs"""
282 d = dict(called=False)
283 def set_called():
284 d['called'] = True
284 def test_silent_postexec(self):
285 """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks"""
286 pre_explicit = mock.Mock()
287 pre_always = mock.Mock()
288 post_explicit = mock.Mock()
289 post_always = mock.Mock()
290
291 ip.events.register('pre_run_cell', pre_explicit)
292 ip.events.register('pre_execute', pre_always)
293 ip.events.register('post_run_cell', post_explicit)
294 ip.events.register('post_execute', post_always)
285 295
286 ip.register_post_execute(set_called)
296 try:
287 297 ip.run_cell("1", silent=True)
288 self.assertFalse(d['called'])
298 assert pre_always.called
299 assert not pre_explicit.called
300 assert post_always.called
301 assert not post_explicit.called
289 302 # double-check that non-silent exec did what we expected
290 303 # silent to avoid
291 304 ip.run_cell("1")
292 self.assertTrue(d['called'])
305 assert pre_explicit.called
306 assert post_explicit.called
307 finally:
293 308 # remove post-exec
294 ip._post_execute.pop(set_called)
309 ip.events.reset_all()
295 310
296 311 def test_silent_noadvance(self):
297 312 """run_cell(silent=True) doesn't advance execution_count"""
298 313 ec = ip.execution_count
299 314 # silent should force store_history=False
300 315 ip.run_cell("1", store_history=True, silent=True)
301 316
302 317 self.assertEqual(ec, ip.execution_count)
303 318 # double-check that non-silent exec did what we expected
304 319 # silent to avoid
305 320 ip.run_cell("1", store_history=True)
306 321 self.assertEqual(ec+1, ip.execution_count)
307 322
308 323 def test_silent_nodisplayhook(self):
309 324 """run_cell(silent=True) doesn't trigger displayhook"""
310 325 d = dict(called=False)
311 326
312 327 trap = ip.display_trap
313 328 save_hook = trap.hook
314 329
315 330 def failing_hook(*args, **kwargs):
316 331 d['called'] = True
317 332
318 333 try:
319 334 trap.hook = failing_hook
320 335 ip.run_cell("1", silent=True)
321 336 self.assertFalse(d['called'])
322 337 # double-check that non-silent exec did what we expected
323 338 # silent to avoid
324 339 ip.run_cell("1")
325 340 self.assertTrue(d['called'])
326 341 finally:
327 342 trap.hook = save_hook
328 343
329 344 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
330 345 def test_print_softspace(self):
331 346 """Verify that softspace is handled correctly when executing multiple
332 347 statements.
333 348
334 349 In [1]: print 1; print 2
335 350 1
336 351 2
337 352
338 353 In [2]: print 1,; print 2
339 354 1 2
340 355 """
341 356
342 357 def test_ofind_line_magic(self):
343 358 from IPython.core.magic import register_line_magic
344 359
345 360 @register_line_magic
346 361 def lmagic(line):
347 362 "A line magic"
348 363
349 364 # Get info on line magic
350 365 lfind = ip._ofind('lmagic')
351 366 info = dict(found=True, isalias=False, ismagic=True,
352 367 namespace = 'IPython internal', obj= lmagic.__wrapped__,
353 368 parent = None)
354 369 nt.assert_equal(lfind, info)
355 370
356 371 def test_ofind_cell_magic(self):
357 372 from IPython.core.magic import register_cell_magic
358 373
359 374 @register_cell_magic
360 375 def cmagic(line, cell):
361 376 "A cell magic"
362 377
363 378 # Get info on cell magic
364 379 find = ip._ofind('cmagic')
365 380 info = dict(found=True, isalias=False, ismagic=True,
366 381 namespace = 'IPython internal', obj= cmagic.__wrapped__,
367 382 parent = None)
368 383 nt.assert_equal(find, info)
369 384
370 385 def test_custom_exception(self):
371 386 called = []
372 387 def my_handler(shell, etype, value, tb, tb_offset=None):
373 388 called.append(etype)
374 389 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
375 390
376 391 ip.set_custom_exc((ValueError,), my_handler)
377 392 try:
378 393 ip.run_cell("raise ValueError('test')")
379 394 # Check that this was called, and only once.
380 395 self.assertEqual(called, [ValueError])
381 396 finally:
382 397 # Reset the custom exception hook
383 398 ip.set_custom_exc((), None)
384 399
385 400 @skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
386 401 def test_future_environment(self):
387 402 "Can we run code with & without the shell's __future__ imports?"
388 403 ip.run_cell("from __future__ import division")
389 404 ip.run_cell("a = 1/2", shell_futures=True)
390 405 self.assertEqual(ip.user_ns['a'], 0.5)
391 406 ip.run_cell("b = 1/2", shell_futures=False)
392 407 self.assertEqual(ip.user_ns['b'], 0)
393 408
394 409 ip.compile.reset_compiler_flags()
395 410 # This shouldn't leak to the shell's compiler
396 411 ip.run_cell("from __future__ import division \nc=1/2", shell_futures=False)
397 412 self.assertEqual(ip.user_ns['c'], 0.5)
398 413 ip.run_cell("d = 1/2", shell_futures=True)
399 414 self.assertEqual(ip.user_ns['d'], 0)
400 415
401 416
402 417 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
403 418
404 419 @onlyif_unicode_paths
405 420 def setUp(self):
406 421 self.BASETESTDIR = tempfile.mkdtemp()
407 422 self.TESTDIR = join(self.BASETESTDIR, u"åäö")
408 423 os.mkdir(self.TESTDIR)
409 424 with open(join(self.TESTDIR, u"åäötestscript.py"), "w") as sfile:
410 425 sfile.write("pass\n")
411 426 self.oldpath = py3compat.getcwd()
412 427 os.chdir(self.TESTDIR)
413 428 self.fname = u"åäötestscript.py"
414 429
415 430 def tearDown(self):
416 431 os.chdir(self.oldpath)
417 432 shutil.rmtree(self.BASETESTDIR)
418 433
419 434 @onlyif_unicode_paths
420 435 def test_1(self):
421 436 """Test safe_execfile with non-ascii path
422 437 """
423 438 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
424 439
425 440 class ExitCodeChecks(tt.TempFileMixin):
426 441 def test_exit_code_ok(self):
427 442 self.system('exit 0')
428 443 self.assertEqual(ip.user_ns['_exit_code'], 0)
429 444
430 445 def test_exit_code_error(self):
431 446 self.system('exit 1')
432 447 self.assertEqual(ip.user_ns['_exit_code'], 1)
433 448
434 449 @skipif(not hasattr(signal, 'SIGALRM'))
435 450 def test_exit_code_signal(self):
436 451 self.mktmp("import signal, time\n"
437 452 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
438 453 "time.sleep(1)\n")
439 454 self.system("%s %s" % (sys.executable, self.fname))
440 455 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
441 456
442 457 class TestSystemRaw(unittest.TestCase, ExitCodeChecks):
443 458 system = ip.system_raw
444 459
445 460 @onlyif_unicode_paths
446 461 def test_1(self):
447 462 """Test system_raw with non-ascii cmd
448 463 """
449 464 cmd = u'''python -c "'åäö'" '''
450 465 ip.system_raw(cmd)
451 466
452 467 # TODO: Exit codes are currently ignored on Windows.
453 468 class TestSystemPipedExitCode(unittest.TestCase, ExitCodeChecks):
454 469 system = ip.system_piped
455 470
456 471 @skip_win32
457 472 def test_exit_code_ok(self):
458 473 ExitCodeChecks.test_exit_code_ok(self)
459 474
460 475 @skip_win32
461 476 def test_exit_code_error(self):
462 477 ExitCodeChecks.test_exit_code_error(self)
463 478
464 479 @skip_win32
465 480 def test_exit_code_signal(self):
466 481 ExitCodeChecks.test_exit_code_signal(self)
467 482
468 483 class TestModules(unittest.TestCase, tt.TempFileMixin):
469 484 def test_extraneous_loads(self):
470 485 """Test we're not loading modules on startup that we shouldn't.
471 486 """
472 487 self.mktmp("import sys\n"
473 488 "print('numpy' in sys.modules)\n"
474 489 "print('IPython.parallel' in sys.modules)\n"
475 490 "print('IPython.kernel.zmq' in sys.modules)\n"
476 491 )
477 492 out = "False\nFalse\nFalse\n"
478 493 tt.ipexec_validate(self.fname, out)
479 494
480 495 class Negator(ast.NodeTransformer):
481 496 """Negates all number literals in an AST."""
482 497 def visit_Num(self, node):
483 498 node.n = -node.n
484 499 return node
485 500
486 501 class TestAstTransform(unittest.TestCase):
487 502 def setUp(self):
488 503 self.negator = Negator()
489 504 ip.ast_transformers.append(self.negator)
490 505
491 506 def tearDown(self):
492 507 ip.ast_transformers.remove(self.negator)
493 508
494 509 def test_run_cell(self):
495 510 with tt.AssertPrints('-34'):
496 511 ip.run_cell('print (12 + 22)')
497 512
498 513 # A named reference to a number shouldn't be transformed.
499 514 ip.user_ns['n'] = 55
500 515 with tt.AssertNotPrints('-55'):
501 516 ip.run_cell('print (n)')
502 517
503 518 def test_timeit(self):
504 519 called = set()
505 520 def f(x):
506 521 called.add(x)
507 522 ip.push({'f':f})
508 523
509 524 with tt.AssertPrints("best of "):
510 525 ip.run_line_magic("timeit", "-n1 f(1)")
511 526 self.assertEqual(called, set([-1]))
512 527 called.clear()
513 528
514 529 with tt.AssertPrints("best of "):
515 530 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
516 531 self.assertEqual(called, set([-2, -3]))
517 532
518 533 def test_time(self):
519 534 called = []
520 535 def f(x):
521 536 called.append(x)
522 537 ip.push({'f':f})
523 538
524 539 # Test with an expression
525 540 with tt.AssertPrints("Wall time: "):
526 541 ip.run_line_magic("time", "f(5+9)")
527 542 self.assertEqual(called, [-14])
528 543 called[:] = []
529 544
530 545 # Test with a statement (different code path)
531 546 with tt.AssertPrints("Wall time: "):
532 547 ip.run_line_magic("time", "a = f(-3 + -2)")
533 548 self.assertEqual(called, [5])
534 549
535 550 def test_macro(self):
536 551 ip.push({'a':10})
537 552 # The AST transformation makes this do a+=-1
538 553 ip.define_macro("amacro", "a+=1\nprint(a)")
539 554
540 555 with tt.AssertPrints("9"):
541 556 ip.run_cell("amacro")
542 557 with tt.AssertPrints("8"):
543 558 ip.run_cell("amacro")
544 559
545 560 class IntegerWrapper(ast.NodeTransformer):
546 561 """Wraps all integers in a call to Integer()"""
547 562 def visit_Num(self, node):
548 563 if isinstance(node.n, int):
549 564 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
550 565 args=[node], keywords=[])
551 566 return node
552 567
553 568 class TestAstTransform2(unittest.TestCase):
554 569 def setUp(self):
555 570 self.intwrapper = IntegerWrapper()
556 571 ip.ast_transformers.append(self.intwrapper)
557 572
558 573 self.calls = []
559 574 def Integer(*args):
560 575 self.calls.append(args)
561 576 return args
562 577 ip.push({"Integer": Integer})
563 578
564 579 def tearDown(self):
565 580 ip.ast_transformers.remove(self.intwrapper)
566 581 del ip.user_ns['Integer']
567 582
568 583 def test_run_cell(self):
569 584 ip.run_cell("n = 2")
570 585 self.assertEqual(self.calls, [(2,)])
571 586
572 587 # This shouldn't throw an error
573 588 ip.run_cell("o = 2.0")
574 589 self.assertEqual(ip.user_ns['o'], 2.0)
575 590
576 591 def test_timeit(self):
577 592 called = set()
578 593 def f(x):
579 594 called.add(x)
580 595 ip.push({'f':f})
581 596
582 597 with tt.AssertPrints("best of "):
583 598 ip.run_line_magic("timeit", "-n1 f(1)")
584 599 self.assertEqual(called, set([(1,)]))
585 600 called.clear()
586 601
587 602 with tt.AssertPrints("best of "):
588 603 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
589 604 self.assertEqual(called, set([(2,), (3,)]))
590 605
591 606 class ErrorTransformer(ast.NodeTransformer):
592 607 """Throws an error when it sees a number."""
593 608 def visit_Num(self):
594 609 raise ValueError("test")
595 610
596 611 class TestAstTransformError(unittest.TestCase):
597 612 def test_unregistering(self):
598 613 err_transformer = ErrorTransformer()
599 614 ip.ast_transformers.append(err_transformer)
600 615
601 616 with tt.AssertPrints("unregister", channel='stderr'):
602 617 ip.run_cell("1 + 2")
603 618
604 619 # This should have been removed.
605 620 nt.assert_not_in(err_transformer, ip.ast_transformers)
606 621
607 622 def test__IPYTHON__():
608 623 # This shouldn't raise a NameError, that's all
609 624 __IPYTHON__
610 625
611 626
612 627 class DummyRepr(object):
613 628 def __repr__(self):
614 629 return "DummyRepr"
615 630
616 631 def _repr_html_(self):
617 632 return "<b>dummy</b>"
618 633
619 634 def _repr_javascript_(self):
620 635 return "console.log('hi');", {'key': 'value'}
621 636
622 637
623 638 def test_user_variables():
624 639 # enable all formatters
625 640 ip.display_formatter.active_types = ip.display_formatter.format_types
626 641
627 642 ip.user_ns['dummy'] = d = DummyRepr()
628 643 keys = set(['dummy', 'doesnotexist'])
629 644 r = ip.user_variables(keys)
630 645
631 646 nt.assert_equal(keys, set(r.keys()))
632 647 dummy = r['dummy']
633 648 nt.assert_equal(set(['status', 'data', 'metadata']), set(dummy.keys()))
634 649 nt.assert_equal(dummy['status'], 'ok')
635 650 data = dummy['data']
636 651 metadata = dummy['metadata']
637 652 nt.assert_equal(data.get('text/html'), d._repr_html_())
638 653 js, jsmd = d._repr_javascript_()
639 654 nt.assert_equal(data.get('application/javascript'), js)
640 655 nt.assert_equal(metadata.get('application/javascript'), jsmd)
641 656
642 657 dne = r['doesnotexist']
643 658 nt.assert_equal(dne['status'], 'error')
644 659 nt.assert_equal(dne['ename'], 'KeyError')
645 660
646 661 # back to text only
647 662 ip.display_formatter.active_types = ['text/plain']
648 663
649 664 def test_user_expression():
650 665 # enable all formatters
651 666 ip.display_formatter.active_types = ip.display_formatter.format_types
652 667 query = {
653 668 'a' : '1 + 2',
654 669 'b' : '1/0',
655 670 }
656 671 r = ip.user_expressions(query)
657 672 import pprint
658 673 pprint.pprint(r)
659 674 nt.assert_equal(set(r.keys()), set(query.keys()))
660 675 a = r['a']
661 676 nt.assert_equal(set(['status', 'data', 'metadata']), set(a.keys()))
662 677 nt.assert_equal(a['status'], 'ok')
663 678 data = a['data']
664 679 metadata = a['metadata']
665 680 nt.assert_equal(data.get('text/plain'), '3')
666 681
667 682 b = r['b']
668 683 nt.assert_equal(b['status'], 'error')
669 684 nt.assert_equal(b['ename'], 'ZeroDivisionError')
670 685
671 686 # back to text only
672 687 ip.display_formatter.active_types = ['text/plain']
673 688
674 689
675 690
676 691
677 692
678 693 class TestSyntaxErrorTransformer(unittest.TestCase):
679 694 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
680 695
681 696 class SyntaxErrorTransformer(InputTransformer):
682 697
683 698 def push(self, line):
684 699 pos = line.find('syntaxerror')
685 700 if pos >= 0:
686 701 e = SyntaxError('input contains "syntaxerror"')
687 702 e.text = line
688 703 e.offset = pos + 1
689 704 raise e
690 705 return line
691 706
692 707 def reset(self):
693 708 pass
694 709
695 710 def setUp(self):
696 711 self.transformer = TestSyntaxErrorTransformer.SyntaxErrorTransformer()
697 712 ip.input_splitter.python_line_transforms.append(self.transformer)
698 713 ip.input_transformer_manager.python_line_transforms.append(self.transformer)
699 714
700 715 def tearDown(self):
701 716 ip.input_splitter.python_line_transforms.remove(self.transformer)
702 717 ip.input_transformer_manager.python_line_transforms.remove(self.transformer)
703 718
704 719 def test_syntaxerror_input_transformer(self):
705 720 with tt.AssertPrints('1234'):
706 721 ip.run_cell('1234')
707 722 with tt.AssertPrints('SyntaxError: invalid syntax'):
708 723 ip.run_cell('1 2 3') # plain python syntax error
709 724 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
710 725 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
711 726 with tt.AssertPrints('3456'):
712 727 ip.run_cell('3456')
713 728
714 729
715 730
@@ -1,507 +1,505 b''
1 1 """IPython extension to reload modules before executing user code.
2 2
3 3 ``autoreload`` reloads modules automatically before entering the execution of
4 4 code typed at the IPython prompt.
5 5
6 6 This makes for example the following workflow possible:
7 7
8 8 .. sourcecode:: ipython
9 9
10 10 In [1]: %load_ext autoreload
11 11
12 12 In [2]: %autoreload 2
13 13
14 14 In [3]: from foo import some_function
15 15
16 16 In [4]: some_function()
17 17 Out[4]: 42
18 18
19 19 In [5]: # open foo.py in an editor and change some_function to return 43
20 20
21 21 In [6]: some_function()
22 22 Out[6]: 43
23 23
24 24 The module was reloaded without reloading it explicitly, and the object
25 25 imported with ``from foo import ...`` was also updated.
26 26
27 27 Usage
28 28 =====
29 29
30 30 The following magic commands are provided:
31 31
32 32 ``%autoreload``
33 33
34 34 Reload all modules (except those excluded by ``%aimport``)
35 35 automatically now.
36 36
37 37 ``%autoreload 0``
38 38
39 39 Disable automatic reloading.
40 40
41 41 ``%autoreload 1``
42 42
43 43 Reload all modules imported with ``%aimport`` every time before
44 44 executing the Python code typed.
45 45
46 46 ``%autoreload 2``
47 47
48 48 Reload all modules (except those excluded by ``%aimport``) every
49 49 time before executing the Python code typed.
50 50
51 51 ``%aimport``
52 52
53 53 List modules which are to be automatically imported or not to be imported.
54 54
55 55 ``%aimport foo``
56 56
57 57 Import module 'foo' and mark it to be autoreloaded for ``%autoreload 1``
58 58
59 59 ``%aimport -foo``
60 60
61 61 Mark module 'foo' to not be autoreloaded.
62 62
63 63 Caveats
64 64 =======
65 65
66 66 Reloading Python modules in a reliable way is in general difficult,
67 67 and unexpected things may occur. ``%autoreload`` tries to work around
68 68 common pitfalls by replacing function code objects and parts of
69 69 classes previously in the module with new versions. This makes the
70 70 following things to work:
71 71
72 72 - Functions and classes imported via 'from xxx import foo' are upgraded
73 73 to new versions when 'xxx' is reloaded.
74 74
75 75 - Methods and properties of classes are upgraded on reload, so that
76 76 calling 'c.foo()' on an object 'c' created before the reload causes
77 77 the new code for 'foo' to be executed.
78 78
79 79 Some of the known remaining caveats are:
80 80
81 81 - Replacing code objects does not always succeed: changing a @property
82 82 in a class to an ordinary method or a method to a member variable
83 83 can cause problems (but in old objects only).
84 84
85 85 - Functions that are removed (eg. via monkey-patching) from a module
86 86 before it is reloaded are not upgraded.
87 87
88 88 - C extension modules cannot be reloaded, and so cannot be autoreloaded.
89 89 """
90 90 from __future__ import print_function
91 91
92 92 skip_doctest = True
93 93
94 94 #-----------------------------------------------------------------------------
95 95 # Copyright (C) 2000 Thomas Heller
96 96 # Copyright (C) 2008 Pauli Virtanen <pav@iki.fi>
97 97 # Copyright (C) 2012 The IPython Development Team
98 98 #
99 99 # Distributed under the terms of the BSD License. The full license is in
100 100 # the file COPYING, distributed as part of this software.
101 101 #-----------------------------------------------------------------------------
102 102 #
103 103 # This IPython module is written by Pauli Virtanen, based on the autoreload
104 104 # code by Thomas Heller.
105 105
106 106 #-----------------------------------------------------------------------------
107 107 # Imports
108 108 #-----------------------------------------------------------------------------
109 109
110 110 import os
111 111 import sys
112 112 import traceback
113 113 import types
114 114 import weakref
115 115
116 116 try:
117 117 # Reload is not defined by default in Python3.
118 118 reload
119 119 except NameError:
120 120 from imp import reload
121 121
122 122 from IPython.utils import openpy
123 123 from IPython.utils.py3compat import PY3
124 124
125 125 #------------------------------------------------------------------------------
126 126 # Autoreload functionality
127 127 #------------------------------------------------------------------------------
128 128
129 129 class ModuleReloader(object):
130 130 enabled = False
131 131 """Whether this reloader is enabled"""
132 132
133 133 failed = {}
134 134 """Modules that failed to reload: {module: mtime-on-failed-reload, ...}"""
135 135
136 136 modules = {}
137 137 """Modules specially marked as autoreloadable."""
138 138
139 139 skip_modules = {}
140 140 """Modules specially marked as not autoreloadable."""
141 141
142 142 check_all = True
143 143 """Autoreload all modules, not just those listed in 'modules'"""
144 144
145 145 old_objects = {}
146 146 """(module-name, name) -> weakref, for replacing old code objects"""
147 147
148 148 def mark_module_skipped(self, module_name):
149 149 """Skip reloading the named module in the future"""
150 150 try:
151 151 del self.modules[module_name]
152 152 except KeyError:
153 153 pass
154 154 self.skip_modules[module_name] = True
155 155
156 156 def mark_module_reloadable(self, module_name):
157 157 """Reload the named module in the future (if it is imported)"""
158 158 try:
159 159 del self.skip_modules[module_name]
160 160 except KeyError:
161 161 pass
162 162 self.modules[module_name] = True
163 163
164 164 def aimport_module(self, module_name):
165 165 """Import a module, and mark it reloadable
166 166
167 167 Returns
168 168 -------
169 169 top_module : module
170 170 The imported module if it is top-level, or the top-level
171 171 top_name : module
172 172 Name of top_module
173 173
174 174 """
175 175 self.mark_module_reloadable(module_name)
176 176
177 177 __import__(module_name)
178 178 top_name = module_name.split('.')[0]
179 179 top_module = sys.modules[top_name]
180 180 return top_module, top_name
181 181
182 182 def check(self, check_all=False):
183 183 """Check whether some modules need to be reloaded."""
184 184
185 185 if not self.enabled and not check_all:
186 186 return
187 187
188 188 if check_all or self.check_all:
189 189 modules = list(sys.modules.keys())
190 190 else:
191 191 modules = list(self.modules.keys())
192 192
193 193 for modname in modules:
194 194 m = sys.modules.get(modname, None)
195 195
196 196 if modname in self.skip_modules:
197 197 continue
198 198
199 199 if not hasattr(m, '__file__'):
200 200 continue
201 201
202 202 if m.__name__ == '__main__':
203 203 # we cannot reload(__main__)
204 204 continue
205 205
206 206 filename = m.__file__
207 207 path, ext = os.path.splitext(filename)
208 208
209 209 if ext.lower() == '.py':
210 210 pyc_filename = openpy.cache_from_source(filename)
211 211 py_filename = filename
212 212 else:
213 213 pyc_filename = filename
214 214 try:
215 215 py_filename = openpy.source_from_cache(filename)
216 216 except ValueError:
217 217 continue
218 218
219 219 try:
220 220 pymtime = os.stat(py_filename).st_mtime
221 221 if pymtime <= os.stat(pyc_filename).st_mtime:
222 222 continue
223 223 if self.failed.get(py_filename, None) == pymtime:
224 224 continue
225 225 except OSError:
226 226 continue
227 227
228 228 try:
229 229 superreload(m, reload, self.old_objects)
230 230 if py_filename in self.failed:
231 231 del self.failed[py_filename]
232 232 except:
233 233 print("[autoreload of %s failed: %s]" % (
234 234 modname, traceback.format_exc(1)), file=sys.stderr)
235 235 self.failed[py_filename] = pymtime
236 236
237 237 #------------------------------------------------------------------------------
238 238 # superreload
239 239 #------------------------------------------------------------------------------
240 240
241 241 if PY3:
242 242 func_attrs = ['__code__', '__defaults__', '__doc__',
243 243 '__closure__', '__globals__', '__dict__']
244 244 else:
245 245 func_attrs = ['func_code', 'func_defaults', 'func_doc',
246 246 'func_closure', 'func_globals', 'func_dict']
247 247
248 248
249 249 def update_function(old, new):
250 250 """Upgrade the code object of a function"""
251 251 for name in func_attrs:
252 252 try:
253 253 setattr(old, name, getattr(new, name))
254 254 except (AttributeError, TypeError):
255 255 pass
256 256
257 257
258 258 def update_class(old, new):
259 259 """Replace stuff in the __dict__ of a class, and upgrade
260 260 method code objects"""
261 261 for key in list(old.__dict__.keys()):
262 262 old_obj = getattr(old, key)
263 263
264 264 try:
265 265 new_obj = getattr(new, key)
266 266 except AttributeError:
267 267 # obsolete attribute: remove it
268 268 try:
269 269 delattr(old, key)
270 270 except (AttributeError, TypeError):
271 271 pass
272 272 continue
273 273
274 274 if update_generic(old_obj, new_obj): continue
275 275
276 276 try:
277 277 setattr(old, key, getattr(new, key))
278 278 except (AttributeError, TypeError):
279 279 pass # skip non-writable attributes
280 280
281 281
282 282 def update_property(old, new):
283 283 """Replace get/set/del functions of a property"""
284 284 update_generic(old.fdel, new.fdel)
285 285 update_generic(old.fget, new.fget)
286 286 update_generic(old.fset, new.fset)
287 287
288 288
289 289 def isinstance2(a, b, typ):
290 290 return isinstance(a, typ) and isinstance(b, typ)
291 291
292 292
293 293 UPDATE_RULES = [
294 294 (lambda a, b: isinstance2(a, b, type),
295 295 update_class),
296 296 (lambda a, b: isinstance2(a, b, types.FunctionType),
297 297 update_function),
298 298 (lambda a, b: isinstance2(a, b, property),
299 299 update_property),
300 300 ]
301 301
302 302
303 303 if PY3:
304 304 UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.MethodType),
305 305 lambda a, b: update_function(a.__func__, b.__func__)),
306 306 ])
307 307 else:
308 308 UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.ClassType),
309 309 update_class),
310 310 (lambda a, b: isinstance2(a, b, types.MethodType),
311 311 lambda a, b: update_function(a.__func__, b.__func__)),
312 312 ])
313 313
314 314
315 315 def update_generic(a, b):
316 316 for type_check, update in UPDATE_RULES:
317 317 if type_check(a, b):
318 318 update(a, b)
319 319 return True
320 320 return False
321 321
322 322
323 323 class StrongRef(object):
324 324 def __init__(self, obj):
325 325 self.obj = obj
326 326 def __call__(self):
327 327 return self.obj
328 328
329 329
330 330 def superreload(module, reload=reload, old_objects={}):
331 331 """Enhanced version of the builtin reload function.
332 332
333 333 superreload remembers objects previously in the module, and
334 334
335 335 - upgrades the class dictionary of every old class in the module
336 336 - upgrades the code object of every old function and method
337 337 - clears the module's namespace before reloading
338 338
339 339 """
340 340
341 341 # collect old objects in the module
342 342 for name, obj in list(module.__dict__.items()):
343 343 if not hasattr(obj, '__module__') or obj.__module__ != module.__name__:
344 344 continue
345 345 key = (module.__name__, name)
346 346 try:
347 347 old_objects.setdefault(key, []).append(weakref.ref(obj))
348 348 except TypeError:
349 349 # weakref doesn't work for all types;
350 350 # create strong references for 'important' cases
351 351 if not PY3 and isinstance(obj, types.ClassType):
352 352 old_objects.setdefault(key, []).append(StrongRef(obj))
353 353
354 354 # reload module
355 355 try:
356 356 # clear namespace first from old cruft
357 357 old_dict = module.__dict__.copy()
358 358 old_name = module.__name__
359 359 module.__dict__.clear()
360 360 module.__dict__['__name__'] = old_name
361 361 module.__dict__['__loader__'] = old_dict['__loader__']
362 362 except (TypeError, AttributeError, KeyError):
363 363 pass
364 364
365 365 try:
366 366 module = reload(module)
367 367 except:
368 368 # restore module dictionary on failed reload
369 369 module.__dict__.update(old_dict)
370 370 raise
371 371
372 372 # iterate over all objects and update functions & classes
373 373 for name, new_obj in list(module.__dict__.items()):
374 374 key = (module.__name__, name)
375 375 if key not in old_objects: continue
376 376
377 377 new_refs = []
378 378 for old_ref in old_objects[key]:
379 379 old_obj = old_ref()
380 380 if old_obj is None: continue
381 381 new_refs.append(old_ref)
382 382 update_generic(old_obj, new_obj)
383 383
384 384 if new_refs:
385 385 old_objects[key] = new_refs
386 386 else:
387 387 del old_objects[key]
388 388
389 389 return module
390 390
391 391 #------------------------------------------------------------------------------
392 392 # IPython connectivity
393 393 #------------------------------------------------------------------------------
394 394
395 from IPython.core.hooks import TryNext
396 395 from IPython.core.magic import Magics, magics_class, line_magic
397 396
398 397 @magics_class
399 398 class AutoreloadMagics(Magics):
400 399 def __init__(self, *a, **kw):
401 400 super(AutoreloadMagics, self).__init__(*a, **kw)
402 401 self._reloader = ModuleReloader()
403 402 self._reloader.check_all = False
404 403
405 404 @line_magic
406 405 def autoreload(self, parameter_s=''):
407 406 r"""%autoreload => Reload modules automatically
408 407
409 408 %autoreload
410 409 Reload all modules (except those excluded by %aimport) automatically
411 410 now.
412 411
413 412 %autoreload 0
414 413 Disable automatic reloading.
415 414
416 415 %autoreload 1
417 416 Reload all modules imported with %aimport every time before executing
418 417 the Python code typed.
419 418
420 419 %autoreload 2
421 420 Reload all modules (except those excluded by %aimport) every time
422 421 before executing the Python code typed.
423 422
424 423 Reloading Python modules in a reliable way is in general
425 424 difficult, and unexpected things may occur. %autoreload tries to
426 425 work around common pitfalls by replacing function code objects and
427 426 parts of classes previously in the module with new versions. This
428 427 makes the following things to work:
429 428
430 429 - Functions and classes imported via 'from xxx import foo' are upgraded
431 430 to new versions when 'xxx' is reloaded.
432 431
433 432 - Methods and properties of classes are upgraded on reload, so that
434 433 calling 'c.foo()' on an object 'c' created before the reload causes
435 434 the new code for 'foo' to be executed.
436 435
437 436 Some of the known remaining caveats are:
438 437
439 438 - Replacing code objects does not always succeed: changing a @property
440 439 in a class to an ordinary method or a method to a member variable
441 440 can cause problems (but in old objects only).
442 441
443 442 - Functions that are removed (eg. via monkey-patching) from a module
444 443 before it is reloaded are not upgraded.
445 444
446 445 - C extension modules cannot be reloaded, and so cannot be
447 446 autoreloaded.
448 447
449 448 """
450 449 if parameter_s == '':
451 450 self._reloader.check(True)
452 451 elif parameter_s == '0':
453 452 self._reloader.enabled = False
454 453 elif parameter_s == '1':
455 454 self._reloader.check_all = False
456 455 self._reloader.enabled = True
457 456 elif parameter_s == '2':
458 457 self._reloader.check_all = True
459 458 self._reloader.enabled = True
460 459
461 460 @line_magic
462 461 def aimport(self, parameter_s='', stream=None):
463 462 """%aimport => Import modules for automatic reloading.
464 463
465 464 %aimport
466 465 List modules to automatically import and not to import.
467 466
468 467 %aimport foo
469 468 Import module 'foo' and mark it to be autoreloaded for %autoreload 1
470 469
471 470 %aimport -foo
472 471 Mark module 'foo' to not be autoreloaded for %autoreload 1
473 472 """
474 473 modname = parameter_s
475 474 if not modname:
476 475 to_reload = sorted(self._reloader.modules.keys())
477 476 to_skip = sorted(self._reloader.skip_modules.keys())
478 477 if stream is None:
479 478 stream = sys.stdout
480 479 if self._reloader.check_all:
481 480 stream.write("Modules to reload:\nall-except-skipped\n")
482 481 else:
483 482 stream.write("Modules to reload:\n%s\n" % ' '.join(to_reload))
484 483 stream.write("\nModules to skip:\n%s\n" % ' '.join(to_skip))
485 484 elif modname.startswith('-'):
486 485 modname = modname[1:]
487 486 self._reloader.mark_module_skipped(modname)
488 487 else:
489 488 top_module, top_name = self._reloader.aimport_module(modname)
490 489
491 490 # Inject module to user namespace
492 491 self.shell.push({top_name: top_module})
493 492
494 def pre_run_code_hook(self, ip):
495 if not self._reloader.enabled:
496 raise TryNext
493 def pre_run_cell(self):
494 if self._reloader.enabled:
497 495 try:
498 496 self._reloader.check()
499 497 except:
500 498 pass
501 499
502 500
503 501 def load_ipython_extension(ip):
504 502 """Load the extension in IPython."""
505 503 auto_reload = AutoreloadMagics(ip)
506 504 ip.register_magics(auto_reload)
507 ip.set_hook('pre_run_code_hook', auto_reload.pre_run_code_hook)
505 ip.events.register('pre_run_cell', auto_reload.pre_run_cell)
@@ -1,322 +1,321 b''
1 1 """Tests for autoreload extension.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (c) 2012 IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the Modified BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 import os
16 16 import sys
17 17 import tempfile
18 18 import shutil
19 19 import random
20 20 import time
21 21
22 22 import nose.tools as nt
23 23 import IPython.testing.tools as tt
24 24
25 25 from IPython.extensions.autoreload import AutoreloadMagics
26 from IPython.core.hooks import TryNext
26 from IPython.core.events import EventManager, pre_run_cell
27 27 from IPython.utils.py3compat import PY3
28 28
29 29 if PY3:
30 30 from io import StringIO
31 31 else:
32 32 from StringIO import StringIO
33 33
34 34 #-----------------------------------------------------------------------------
35 35 # Test fixture
36 36 #-----------------------------------------------------------------------------
37 37
38 38 noop = lambda *a, **kw: None
39 39
40 40 class FakeShell(object):
41 41
42 42 def __init__(self):
43 43 self.ns = {}
44 self.events = EventManager(self, {'pre_run_cell', pre_run_cell})
44 45 self.auto_magics = AutoreloadMagics(shell=self)
46 self.events.register('pre_run_cell', self.auto_magics.pre_run_cell)
45 47
46 48 register_magics = set_hook = noop
47 49
48 50 def run_code(self, code):
49 try:
50 self.auto_magics.pre_run_code_hook(self)
51 except TryNext:
52 pass
51 self.events.trigger('pre_run_cell')
53 52 exec(code, self.ns)
54 53
55 54 def push(self, items):
56 55 self.ns.update(items)
57 56
58 57 def magic_autoreload(self, parameter):
59 58 self.auto_magics.autoreload(parameter)
60 59
61 60 def magic_aimport(self, parameter, stream=None):
62 61 self.auto_magics.aimport(parameter, stream=stream)
63 62
64 63
65 64 class Fixture(object):
66 65 """Fixture for creating test module files"""
67 66
68 67 test_dir = None
69 68 old_sys_path = None
70 69 filename_chars = "abcdefghijklmopqrstuvwxyz0123456789"
71 70
72 71 def setUp(self):
73 72 self.test_dir = tempfile.mkdtemp()
74 73 self.old_sys_path = list(sys.path)
75 74 sys.path.insert(0, self.test_dir)
76 75 self.shell = FakeShell()
77 76
78 77 def tearDown(self):
79 78 shutil.rmtree(self.test_dir)
80 79 sys.path = self.old_sys_path
81 80
82 81 self.test_dir = None
83 82 self.old_sys_path = None
84 83 self.shell = None
85 84
86 85 def get_module(self):
87 86 module_name = "tmpmod_" + "".join(random.sample(self.filename_chars,20))
88 87 if module_name in sys.modules:
89 88 del sys.modules[module_name]
90 89 file_name = os.path.join(self.test_dir, module_name + ".py")
91 90 return module_name, file_name
92 91
93 92 def write_file(self, filename, content):
94 93 """
95 94 Write a file, and force a timestamp difference of at least one second
96 95
97 96 Notes
98 97 -----
99 98 Python's .pyc files record the timestamp of their compilation
100 99 with a time resolution of one second.
101 100
102 101 Therefore, we need to force a timestamp difference between .py
103 102 and .pyc, without having the .py file be timestamped in the
104 103 future, and without changing the timestamp of the .pyc file
105 104 (because that is stored in the file). The only reliable way
106 105 to achieve this seems to be to sleep.
107 106 """
108 107
109 108 # Sleep one second + eps
110 109 time.sleep(1.05)
111 110
112 111 # Write
113 112 f = open(filename, 'w')
114 113 try:
115 114 f.write(content)
116 115 finally:
117 116 f.close()
118 117
119 118 def new_module(self, code):
120 119 mod_name, mod_fn = self.get_module()
121 120 f = open(mod_fn, 'w')
122 121 try:
123 122 f.write(code)
124 123 finally:
125 124 f.close()
126 125 return mod_name, mod_fn
127 126
128 127 #-----------------------------------------------------------------------------
129 128 # Test automatic reloading
130 129 #-----------------------------------------------------------------------------
131 130
132 131 class TestAutoreload(Fixture):
133 132 def _check_smoketest(self, use_aimport=True):
134 133 """
135 134 Functional test for the automatic reloader using either
136 135 '%autoreload 1' or '%autoreload 2'
137 136 """
138 137
139 138 mod_name, mod_fn = self.new_module("""
140 139 x = 9
141 140
142 141 z = 123 # this item will be deleted
143 142
144 143 def foo(y):
145 144 return y + 3
146 145
147 146 class Baz(object):
148 147 def __init__(self, x):
149 148 self.x = x
150 149 def bar(self, y):
151 150 return self.x + y
152 151 @property
153 152 def quux(self):
154 153 return 42
155 154 def zzz(self):
156 155 '''This method will be deleted below'''
157 156 return 99
158 157
159 158 class Bar: # old-style class: weakref doesn't work for it on Python < 2.7
160 159 def foo(self):
161 160 return 1
162 161 """)
163 162
164 163 #
165 164 # Import module, and mark for reloading
166 165 #
167 166 if use_aimport:
168 167 self.shell.magic_autoreload("1")
169 168 self.shell.magic_aimport(mod_name)
170 169 stream = StringIO()
171 170 self.shell.magic_aimport("", stream=stream)
172 171 nt.assert_true(("Modules to reload:\n%s" % mod_name) in
173 172 stream.getvalue())
174 173
175 174 nt.assert_raises(
176 175 ImportError,
177 176 self.shell.magic_aimport, "tmpmod_as318989e89ds")
178 177 else:
179 178 self.shell.magic_autoreload("2")
180 179 self.shell.run_code("import %s" % mod_name)
181 180 stream = StringIO()
182 181 self.shell.magic_aimport("", stream=stream)
183 182 nt.assert_true("Modules to reload:\nall-except-skipped" in
184 183 stream.getvalue())
185 184 nt.assert_in(mod_name, self.shell.ns)
186 185
187 186 mod = sys.modules[mod_name]
188 187
189 188 #
190 189 # Test module contents
191 190 #
192 191 old_foo = mod.foo
193 192 old_obj = mod.Baz(9)
194 193 old_obj2 = mod.Bar()
195 194
196 195 def check_module_contents():
197 196 nt.assert_equal(mod.x, 9)
198 197 nt.assert_equal(mod.z, 123)
199 198
200 199 nt.assert_equal(old_foo(0), 3)
201 200 nt.assert_equal(mod.foo(0), 3)
202 201
203 202 obj = mod.Baz(9)
204 203 nt.assert_equal(old_obj.bar(1), 10)
205 204 nt.assert_equal(obj.bar(1), 10)
206 205 nt.assert_equal(obj.quux, 42)
207 206 nt.assert_equal(obj.zzz(), 99)
208 207
209 208 obj2 = mod.Bar()
210 209 nt.assert_equal(old_obj2.foo(), 1)
211 210 nt.assert_equal(obj2.foo(), 1)
212 211
213 212 check_module_contents()
214 213
215 214 #
216 215 # Simulate a failed reload: no reload should occur and exactly
217 216 # one error message should be printed
218 217 #
219 218 self.write_file(mod_fn, """
220 219 a syntax error
221 220 """)
222 221
223 222 with tt.AssertPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'):
224 223 self.shell.run_code("pass") # trigger reload
225 224 with tt.AssertNotPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'):
226 225 self.shell.run_code("pass") # trigger another reload
227 226 check_module_contents()
228 227
229 228 #
230 229 # Rewrite module (this time reload should succeed)
231 230 #
232 231 self.write_file(mod_fn, """
233 232 x = 10
234 233
235 234 def foo(y):
236 235 return y + 4
237 236
238 237 class Baz(object):
239 238 def __init__(self, x):
240 239 self.x = x
241 240 def bar(self, y):
242 241 return self.x + y + 1
243 242 @property
244 243 def quux(self):
245 244 return 43
246 245
247 246 class Bar: # old-style class
248 247 def foo(self):
249 248 return 2
250 249 """)
251 250
252 251 def check_module_contents():
253 252 nt.assert_equal(mod.x, 10)
254 253 nt.assert_false(hasattr(mod, 'z'))
255 254
256 255 nt.assert_equal(old_foo(0), 4) # superreload magic!
257 256 nt.assert_equal(mod.foo(0), 4)
258 257
259 258 obj = mod.Baz(9)
260 259 nt.assert_equal(old_obj.bar(1), 11) # superreload magic!
261 260 nt.assert_equal(obj.bar(1), 11)
262 261
263 262 nt.assert_equal(old_obj.quux, 43)
264 263 nt.assert_equal(obj.quux, 43)
265 264
266 265 nt.assert_false(hasattr(old_obj, 'zzz'))
267 266 nt.assert_false(hasattr(obj, 'zzz'))
268 267
269 268 obj2 = mod.Bar()
270 269 nt.assert_equal(old_obj2.foo(), 2)
271 270 nt.assert_equal(obj2.foo(), 2)
272 271
273 272 self.shell.run_code("pass") # trigger reload
274 273 check_module_contents()
275 274
276 275 #
277 276 # Another failure case: deleted file (shouldn't reload)
278 277 #
279 278 os.unlink(mod_fn)
280 279
281 280 self.shell.run_code("pass") # trigger reload
282 281 check_module_contents()
283 282
284 283 #
285 284 # Disable autoreload and rewrite module: no reload should occur
286 285 #
287 286 if use_aimport:
288 287 self.shell.magic_aimport("-" + mod_name)
289 288 stream = StringIO()
290 289 self.shell.magic_aimport("", stream=stream)
291 290 nt.assert_true(("Modules to skip:\n%s" % mod_name) in
292 291 stream.getvalue())
293 292
294 293 # This should succeed, although no such module exists
295 294 self.shell.magic_aimport("-tmpmod_as318989e89ds")
296 295 else:
297 296 self.shell.magic_autoreload("0")
298 297
299 298 self.write_file(mod_fn, """
300 299 x = -99
301 300 """)
302 301
303 302 self.shell.run_code("pass") # trigger reload
304 303 self.shell.run_code("pass")
305 304 check_module_contents()
306 305
307 306 #
308 307 # Re-enable autoreload: reload should now occur
309 308 #
310 309 if use_aimport:
311 310 self.shell.magic_aimport(mod_name)
312 311 else:
313 312 self.shell.magic_autoreload("")
314 313
315 314 self.shell.run_code("pass") # trigger reload
316 315 nt.assert_equal(mod.x, -99)
317 316
318 317 def test_smoketest_aimport(self):
319 318 self._check_smoketest(use_aimport=True)
320 319
321 320 def test_smoketest_autoreload(self):
322 321 self._check_smoketest(use_aimport=False)
@@ -1,140 +1,142 b''
1 1 """Base class for a Comm"""
2 2
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (C) 2013 The IPython Development Team
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING, distributed as part of this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 14 import uuid
15 15
16 16 from IPython.config import LoggingConfigurable
17 17 from IPython.core.getipython import get_ipython
18 18
19 19 from IPython.utils.traitlets import Instance, Unicode, Bytes, Bool, Dict, Any
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Code
23 23 #-----------------------------------------------------------------------------
24 24
25 25 class Comm(LoggingConfigurable):
26 26
27 27 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
28 28 def _shell_default(self):
29 29 return get_ipython()
30 30
31 31 iopub_socket = Any()
32 32 def _iopub_socket_default(self):
33 33 return self.shell.kernel.iopub_socket
34 34 session = Instance('IPython.kernel.zmq.session.Session')
35 35 def _session_default(self):
36 36 if self.shell is None:
37 37 return
38 38 return self.shell.kernel.session
39 39
40 40 target_name = Unicode('comm')
41 41
42 42 topic = Bytes()
43 43 def _topic_default(self):
44 44 return ('comm-%s' % self.comm_id).encode('ascii')
45 45
46 46 _open_data = Dict(help="data dict, if any, to be included in comm_open")
47 47 _close_data = Dict(help="data dict, if any, to be included in comm_close")
48 48
49 49 _msg_callback = Any()
50 50 _close_callback = Any()
51 51
52 52 _closed = Bool(False)
53 53 comm_id = Unicode()
54 54 def _comm_id_default(self):
55 55 return uuid.uuid4().hex
56 56
57 57 primary = Bool(True, help="Am I the primary or secondary Comm?")
58 58
59 59 def __init__(self, target_name='', data=None, **kwargs):
60 60 if target_name:
61 61 kwargs['target_name'] = target_name
62 62 super(Comm, self).__init__(**kwargs)
63 63 get_ipython().comm_manager.register_comm(self)
64 64 if self.primary:
65 65 # I am primary, open my peer.
66 66 self.open(data)
67 67
68 68 def _publish_msg(self, msg_type, data=None, metadata=None, **keys):
69 69 """Helper for sending a comm message on IOPub"""
70 70 data = {} if data is None else data
71 71 metadata = {} if metadata is None else metadata
72 72 self.session.send(self.iopub_socket, msg_type,
73 73 dict(data=data, comm_id=self.comm_id, **keys),
74 74 metadata=metadata,
75 75 parent=self.shell.get_parent(),
76 76 ident=self.topic,
77 77 )
78 78
79 79 def __del__(self):
80 80 """trigger close on gc"""
81 81 self.close()
82 82
83 83 # publishing messages
84 84
85 85 def open(self, data=None, metadata=None):
86 86 """Open the frontend-side version of this comm"""
87 87 if data is None:
88 88 data = self._open_data
89 89 self._publish_msg('comm_open', data, metadata, target_name=self.target_name)
90 90
91 91 def close(self, data=None, metadata=None):
92 92 """Close the frontend-side version of this comm"""
93 93 if self._closed:
94 94 # only close once
95 95 return
96 96 if data is None:
97 97 data = self._close_data
98 98 self._publish_msg('comm_close', data, metadata)
99 99 self._closed = True
100 100
101 101 def send(self, data=None, metadata=None):
102 102 """Send a message to the frontend-side version of this comm"""
103 103 self._publish_msg('comm_msg', data, metadata)
104 104
105 105 # registering callbacks
106 106
107 107 def on_close(self, callback):
108 108 """Register a callback for comm_close
109 109
110 110 Will be called with the `data` of the close message.
111 111
112 112 Call `on_close(None)` to disable an existing callback.
113 113 """
114 114 self._close_callback = callback
115 115
116 116 def on_msg(self, callback):
117 117 """Register a callback for comm_msg
118 118
119 119 Will be called with the `data` of any comm_msg messages.
120 120
121 121 Call `on_msg(None)` to disable an existing callback.
122 122 """
123 123 self._msg_callback = callback
124 124
125 125 # handling of incoming messages
126 126
127 127 def handle_close(self, msg):
128 128 """Handle a comm_close message"""
129 129 self.log.debug("handle_close[%s](%s)", self.comm_id, msg)
130 130 if self._close_callback:
131 131 self._close_callback(msg)
132 132
133 133 def handle_msg(self, msg):
134 134 """Handle a comm_msg message"""
135 135 self.log.debug("handle_msg[%s](%s)", self.comm_id, msg)
136 136 if self._msg_callback:
137 self.shell.events.trigger('pre_execute')
137 138 self._msg_callback(msg)
139 self.shell.events.trigger('post_execute')
138 140
139 141
140 142 __all__ = ['Comm']
@@ -1,819 +1,813 b''
1 """Function signature objects for callables
1 """Function signature objects for callables.
2 2
3 3 Back port of Python 3.3's function signature tools from the inspect module,
4 modified to be compatible with Python 2.6, 2.7 and 3.2+.
4 modified to be compatible with Python 2.7 and 3.2+.
5 5 """
6 6
7 7 #-----------------------------------------------------------------------------
8 8 # Python 3.3 stdlib inspect.py is public domain
9 9 #
10 10 # Backports Copyright (C) 2013 Aaron Iles
11 11 # Used under Apache License Version 2.0
12 12 #
13 13 # Further Changes are Copyright (C) 2013 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 from __future__ import absolute_import, division, print_function
20 20 import itertools
21 21 import functools
22 22 import re
23 23 import types
24 24
25 25
26 26 # patch for single-file
27 27 # we don't support 2.6, so we can just import OrderedDict
28 28 from collections import OrderedDict
29 29
30 30 __version__ = '0.3'
31 31 # end patch
32 32
33 33 __all__ = ['BoundArguments', 'Parameter', 'Signature', 'signature']
34 34
35 35
36 36 _WrapperDescriptor = type(type.__call__)
37 37 _MethodWrapper = type(all.__call__)
38 38
39 39 _NonUserDefinedCallables = (_WrapperDescriptor,
40 40 _MethodWrapper,
41 41 types.BuiltinFunctionType)
42 42
43 43
44 44 def formatannotation(annotation, base_module=None):
45 45 if isinstance(annotation, type):
46 46 if annotation.__module__ in ('builtins', '__builtin__', base_module):
47 47 return annotation.__name__
48 48 return annotation.__module__+'.'+annotation.__name__
49 49 return repr(annotation)
50 50
51 51
52 52 def _get_user_defined_method(cls, method_name, *nested):
53 53 try:
54 54 if cls is type:
55 55 return
56 56 meth = getattr(cls, method_name)
57 57 for name in nested:
58 58 meth = getattr(meth, name, meth)
59 59 except AttributeError:
60 60 return
61 61 else:
62 62 if not isinstance(meth, _NonUserDefinedCallables):
63 63 # Once '__signature__' will be added to 'C'-level
64 64 # callables, this check won't be necessary
65 65 return meth
66 66
67 67
68 68 def signature(obj):
69 69 '''Get a signature object for the passed callable.'''
70 70
71 71 if not callable(obj):
72 72 raise TypeError('{0!r} is not a callable object'.format(obj))
73 73
74 74 if isinstance(obj, types.MethodType):
75 75 # In this case we skip the first parameter of the underlying
76 76 # function (usually `self` or `cls`).
77 77 sig = signature(obj.__func__)
78 78 return sig.replace(parameters=tuple(sig.parameters.values())[1:])
79 79
80 80 try:
81 81 sig = obj.__signature__
82 82 except AttributeError:
83 83 pass
84 84 else:
85 85 if sig is not None:
86 86 return sig
87 87
88 88 try:
89 89 # Was this function wrapped by a decorator?
90 90 wrapped = obj.__wrapped__
91 91 except AttributeError:
92 92 pass
93 93 else:
94 94 return signature(wrapped)
95 95
96 96 if isinstance(obj, types.FunctionType):
97 97 return Signature.from_function(obj)
98 98
99 99 if isinstance(obj, functools.partial):
100 100 sig = signature(obj.func)
101 101
102 102 new_params = OrderedDict(sig.parameters.items())
103 103
104 104 partial_args = obj.args or ()
105 105 partial_keywords = obj.keywords or {}
106 106 try:
107 107 ba = sig.bind_partial(*partial_args, **partial_keywords)
108 108 except TypeError as ex:
109 109 msg = 'partial object {0!r} has incorrect arguments'.format(obj)
110 110 raise ValueError(msg)
111 111
112 112 for arg_name, arg_value in ba.arguments.items():
113 113 param = new_params[arg_name]
114 114 if arg_name in partial_keywords:
115 115 # We set a new default value, because the following code
116 116 # is correct:
117 117 #
118 118 # >>> def foo(a): print(a)
119 119 # >>> print(partial(partial(foo, a=10), a=20)())
120 120 # 20
121 121 # >>> print(partial(partial(foo, a=10), a=20)(a=30))
122 122 # 30
123 123 #
124 124 # So, with 'partial' objects, passing a keyword argument is
125 125 # like setting a new default value for the corresponding
126 126 # parameter
127 127 #
128 128 # We also mark this parameter with '_partial_kwarg'
129 129 # flag. Later, in '_bind', the 'default' value of this
130 130 # parameter will be added to 'kwargs', to simulate
131 131 # the 'functools.partial' real call.
132 132 new_params[arg_name] = param.replace(default=arg_value,
133 133 _partial_kwarg=True)
134 134
135 135 elif (param.kind not in (_VAR_KEYWORD, _VAR_POSITIONAL) and
136 136 not param._partial_kwarg):
137 137 new_params.pop(arg_name)
138 138
139 139 return sig.replace(parameters=new_params.values())
140 140
141 141 sig = None
142 142 if isinstance(obj, type):
143 143 # obj is a class or a metaclass
144 144
145 145 # First, let's see if it has an overloaded __call__ defined
146 146 # in its metaclass
147 147 call = _get_user_defined_method(type(obj), '__call__')
148 148 if call is not None:
149 149 sig = signature(call)
150 150 else:
151 151 # Now we check if the 'obj' class has a '__new__' method
152 152 new = _get_user_defined_method(obj, '__new__')
153 153 if new is not None:
154 154 sig = signature(new)
155 155 else:
156 156 # Finally, we should have at least __init__ implemented
157 157 init = _get_user_defined_method(obj, '__init__')
158 158 if init is not None:
159 159 sig = signature(init)
160 160 elif not isinstance(obj, _NonUserDefinedCallables):
161 161 # An object with __call__
162 162 # We also check that the 'obj' is not an instance of
163 163 # _WrapperDescriptor or _MethodWrapper to avoid
164 164 # infinite recursion (and even potential segfault)
165 165 call = _get_user_defined_method(type(obj), '__call__', 'im_func')
166 166 if call is not None:
167 167 sig = signature(call)
168 168
169 169 if sig is not None:
170 170 return sig
171 171
172 172 if isinstance(obj, types.BuiltinFunctionType):
173 173 # Raise a nicer error message for builtins
174 174 msg = 'no signature found for builtin function {0!r}'.format(obj)
175 175 raise ValueError(msg)
176 176
177 177 raise ValueError('callable {0!r} is not supported by signature'.format(obj))
178 178
179 179
180 180 class _void(object):
181 181 '''A private marker - used in Parameter & Signature'''
182 182
183 183
184 184 class _empty(object):
185 185 pass
186 186
187 187
188 188 class _ParameterKind(int):
189 189 def __new__(self, *args, **kwargs):
190 190 obj = int.__new__(self, *args)
191 191 obj._name = kwargs['name']
192 192 return obj
193 193
194 194 def __str__(self):
195 195 return self._name
196 196
197 197 def __repr__(self):
198 198 return '<_ParameterKind: {0!r}>'.format(self._name)
199 199
200 200
201 201 _POSITIONAL_ONLY = _ParameterKind(0, name='POSITIONAL_ONLY')
202 202 _POSITIONAL_OR_KEYWORD = _ParameterKind(1, name='POSITIONAL_OR_KEYWORD')
203 203 _VAR_POSITIONAL = _ParameterKind(2, name='VAR_POSITIONAL')
204 204 _KEYWORD_ONLY = _ParameterKind(3, name='KEYWORD_ONLY')
205 205 _VAR_KEYWORD = _ParameterKind(4, name='VAR_KEYWORD')
206 206
207 207
208 208 class Parameter(object):
209 209 '''Represents a parameter in a function signature.
210 210
211 211 Has the following public attributes:
212 212
213 213 * name : str
214 214 The name of the parameter as a string.
215 215 * default : object
216 216 The default value for the parameter if specified. If the
217 217 parameter has no default value, this attribute is not set.
218 218 * annotation
219 219 The annotation for the parameter if specified. If the
220 220 parameter has no annotation, this attribute is not set.
221 221 * kind : str
222 222 Describes how argument values are bound to the parameter.
223 223 Possible values: `Parameter.POSITIONAL_ONLY`,
224 224 `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
225 225 `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
226 226 '''
227 227
228 228 __slots__ = ('_name', '_kind', '_default', '_annotation', '_partial_kwarg')
229 229
230 230 POSITIONAL_ONLY = _POSITIONAL_ONLY
231 231 POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD
232 232 VAR_POSITIONAL = _VAR_POSITIONAL
233 233 KEYWORD_ONLY = _KEYWORD_ONLY
234 234 VAR_KEYWORD = _VAR_KEYWORD
235 235
236 236 empty = _empty
237 237
238 238 def __init__(self, name, kind, default=_empty, annotation=_empty,
239 239 _partial_kwarg=False):
240 240
241 241 if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD,
242 242 _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD):
243 243 raise ValueError("invalid value for 'Parameter.kind' attribute")
244 244 self._kind = kind
245 245
246 246 if default is not _empty:
247 247 if kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
248 248 msg = '{0} parameters cannot have default values'.format(kind)
249 249 raise ValueError(msg)
250 250 self._default = default
251 251 self._annotation = annotation
252 252
253 253 if name is None:
254 254 if kind != _POSITIONAL_ONLY:
255 255 raise ValueError("None is not a valid name for a "
256 256 "non-positional-only parameter")
257 257 self._name = name
258 258 else:
259 259 name = str(name)
260 260 if kind != _POSITIONAL_ONLY and not re.match(r'[a-z_]\w*$', name, re.I):
261 261 msg = '{0!r} is not a valid parameter name'.format(name)
262 262 raise ValueError(msg)
263 263 self._name = name
264 264
265 265 self._partial_kwarg = _partial_kwarg
266 266
267 267 @property
268 268 def name(self):
269 269 return self._name
270 270
271 271 @property
272 272 def default(self):
273 273 return self._default
274 274
275 275 @property
276 276 def annotation(self):
277 277 return self._annotation
278 278
279 279 @property
280 280 def kind(self):
281 281 return self._kind
282 282
283 283 def replace(self, name=_void, kind=_void, annotation=_void,
284 284 default=_void, _partial_kwarg=_void):
285 285 '''Creates a customized copy of the Parameter.'''
286 286
287 287 if name is _void:
288 288 name = self._name
289 289
290 290 if kind is _void:
291 291 kind = self._kind
292 292
293 293 if annotation is _void:
294 294 annotation = self._annotation
295 295
296 296 if default is _void:
297 297 default = self._default
298 298
299 299 if _partial_kwarg is _void:
300 300 _partial_kwarg = self._partial_kwarg
301 301
302 302 return type(self)(name, kind, default=default, annotation=annotation,
303 303 _partial_kwarg=_partial_kwarg)
304 304
305 305 def __str__(self):
306 306 kind = self.kind
307 307
308 308 formatted = self._name
309 309 if kind == _POSITIONAL_ONLY:
310 310 if formatted is None:
311 311 formatted = ''
312 312 formatted = '<{0}>'.format(formatted)
313 313
314 314 # Add annotation and default value
315 315 if self._annotation is not _empty:
316 316 formatted = '{0}:{1}'.format(formatted,
317 317 formatannotation(self._annotation))
318 318
319 319 if self._default is not _empty:
320 320 formatted = '{0}={1}'.format(formatted, repr(self._default))
321 321
322 322 if kind == _VAR_POSITIONAL:
323 323 formatted = '*' + formatted
324 324 elif kind == _VAR_KEYWORD:
325 325 formatted = '**' + formatted
326 326
327 327 return formatted
328 328
329 329 def __repr__(self):
330 330 return '<{0} at {1:#x} {2!r}>'.format(self.__class__.__name__,
331 331 id(self), self.name)
332 332
333 333 def __hash__(self):
334 334 msg = "unhashable type: '{0}'".format(self.__class__.__name__)
335 335 raise TypeError(msg)
336 336
337 337 def __eq__(self, other):
338 338 return (issubclass(other.__class__, Parameter) and
339 339 self._name == other._name and
340 340 self._kind == other._kind and
341 341 self._default == other._default and
342 342 self._annotation == other._annotation)
343 343
344 344 def __ne__(self, other):
345 345 return not self.__eq__(other)
346 346
347 347
348 348 class BoundArguments(object):
349 '''Result of `Signature.bind` call. Holds the mapping of arguments
349 '''Result of :meth:`Signature.bind` call. Holds the mapping of arguments
350 350 to the function's parameters.
351 351
352 352 Has the following public attributes:
353 353
354 * arguments : OrderedDict
354 arguments : :class:`collections.OrderedDict`
355 355 An ordered mutable mapping of parameters' names to arguments' values.
356 356 Does not contain arguments' default values.
357 * signature : Signature
357 signature : :class:`Signature`
358 358 The Signature object that created this instance.
359 * args : tuple
359 args : tuple
360 360 Tuple of positional arguments values.
361 * kwargs : dict
361 kwargs : dict
362 362 Dict of keyword arguments values.
363 363 '''
364 364
365 365 def __init__(self, signature, arguments):
366 366 self.arguments = arguments
367 367 self._signature = signature
368 368
369 369 @property
370 370 def signature(self):
371 371 return self._signature
372 372
373 373 @property
374 374 def args(self):
375 375 args = []
376 376 for param_name, param in self._signature.parameters.items():
377 377 if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
378 378 param._partial_kwarg):
379 379 # Keyword arguments mapped by 'functools.partial'
380 380 # (Parameter._partial_kwarg is True) are mapped
381 381 # in 'BoundArguments.kwargs', along with VAR_KEYWORD &
382 382 # KEYWORD_ONLY
383 383 break
384 384
385 385 try:
386 386 arg = self.arguments[param_name]
387 387 except KeyError:
388 388 # We're done here. Other arguments
389 389 # will be mapped in 'BoundArguments.kwargs'
390 390 break
391 391 else:
392 392 if param.kind == _VAR_POSITIONAL:
393 393 # *args
394 394 args.extend(arg)
395 395 else:
396 396 # plain argument
397 397 args.append(arg)
398 398
399 399 return tuple(args)
400 400
401 401 @property
402 402 def kwargs(self):
403 403 kwargs = {}
404 404 kwargs_started = False
405 405 for param_name, param in self._signature.parameters.items():
406 406 if not kwargs_started:
407 407 if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
408 408 param._partial_kwarg):
409 409 kwargs_started = True
410 410 else:
411 411 if param_name not in self.arguments:
412 412 kwargs_started = True
413 413 continue
414 414
415 415 if not kwargs_started:
416 416 continue
417 417
418 418 try:
419 419 arg = self.arguments[param_name]
420 420 except KeyError:
421 421 pass
422 422 else:
423 423 if param.kind == _VAR_KEYWORD:
424 424 # **kwargs
425 425 kwargs.update(arg)
426 426 else:
427 427 # plain keyword argument
428 428 kwargs[param_name] = arg
429 429
430 430 return kwargs
431 431
432 432 def __hash__(self):
433 433 msg = "unhashable type: '{0}'".format(self.__class__.__name__)
434 434 raise TypeError(msg)
435 435
436 436 def __eq__(self, other):
437 437 return (issubclass(other.__class__, BoundArguments) and
438 438 self.signature == other.signature and
439 439 self.arguments == other.arguments)
440 440
441 441 def __ne__(self, other):
442 442 return not self.__eq__(other)
443 443
444 444
445 445 class Signature(object):
446 446 '''A Signature object represents the overall signature of a function.
447 447 It stores a Parameter object for each parameter accepted by the
448 448 function, as well as information specific to the function itself.
449 449
450 A Signature object has the following public attributes and methods:
450 A Signature object has the following public attributes:
451 451
452 * parameters : OrderedDict
452 parameters : :class:`collections.OrderedDict`
453 453 An ordered mapping of parameters' names to the corresponding
454 454 Parameter objects (keyword-only arguments are in the same order
455 455 as listed in `code.co_varnames`).
456 * return_annotation : object
456 return_annotation
457 457 The annotation for the return type of the function if specified.
458 458 If the function has no annotation for its return type, this
459 459 attribute is not set.
460 * bind(*args, **kwargs) -> BoundArguments
461 Creates a mapping from positional and keyword arguments to
462 parameters.
463 * bind_partial(*args, **kwargs) -> BoundArguments
464 Creates a partial mapping from positional and keyword arguments
465 to parameters (simulating 'functools.partial' behavior.)
466 460 '''
467 461
468 462 __slots__ = ('_return_annotation', '_parameters')
469 463
470 464 _parameter_cls = Parameter
471 465 _bound_arguments_cls = BoundArguments
472 466
473 467 empty = _empty
474 468
475 469 def __init__(self, parameters=None, return_annotation=_empty,
476 470 __validate_parameters__=True):
477 471 '''Constructs Signature from the given list of Parameter
478 472 objects and 'return_annotation'. All arguments are optional.
479 473 '''
480 474
481 475 if parameters is None:
482 476 params = OrderedDict()
483 477 else:
484 478 if __validate_parameters__:
485 479 params = OrderedDict()
486 480 top_kind = _POSITIONAL_ONLY
487 481
488 482 for idx, param in enumerate(parameters):
489 483 kind = param.kind
490 484 if kind < top_kind:
491 485 msg = 'wrong parameter order: {0} before {1}'
492 486 msg = msg.format(top_kind, param.kind)
493 487 raise ValueError(msg)
494 488 else:
495 489 top_kind = kind
496 490
497 491 name = param.name
498 492 if name is None:
499 493 name = str(idx)
500 494 param = param.replace(name=name)
501 495
502 496 if name in params:
503 497 msg = 'duplicate parameter name: {0!r}'.format(name)
504 498 raise ValueError(msg)
505 499 params[name] = param
506 500 else:
507 501 params = OrderedDict(((param.name, param)
508 502 for param in parameters))
509 503
510 504 self._parameters = params
511 505 self._return_annotation = return_annotation
512 506
513 507 @classmethod
514 508 def from_function(cls, func):
515 509 '''Constructs Signature for the given python function'''
516 510
517 511 if not isinstance(func, types.FunctionType):
518 512 raise TypeError('{0!r} is not a Python function'.format(func))
519 513
520 514 Parameter = cls._parameter_cls
521 515
522 516 # Parameter information.
523 517 func_code = func.__code__
524 518 pos_count = func_code.co_argcount
525 519 arg_names = func_code.co_varnames
526 520 positional = tuple(arg_names[:pos_count])
527 521 keyword_only_count = getattr(func_code, 'co_kwonlyargcount', 0)
528 522 keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)]
529 523 annotations = getattr(func, '__annotations__', {})
530 524 defaults = func.__defaults__
531 525 kwdefaults = getattr(func, '__kwdefaults__', None)
532 526
533 527 if defaults:
534 528 pos_default_count = len(defaults)
535 529 else:
536 530 pos_default_count = 0
537 531
538 532 parameters = []
539 533
540 534 # Non-keyword-only parameters w/o defaults.
541 535 non_default_count = pos_count - pos_default_count
542 536 for name in positional[:non_default_count]:
543 537 annotation = annotations.get(name, _empty)
544 538 parameters.append(Parameter(name, annotation=annotation,
545 539 kind=_POSITIONAL_OR_KEYWORD))
546 540
547 541 # ... w/ defaults.
548 542 for offset, name in enumerate(positional[non_default_count:]):
549 543 annotation = annotations.get(name, _empty)
550 544 parameters.append(Parameter(name, annotation=annotation,
551 545 kind=_POSITIONAL_OR_KEYWORD,
552 546 default=defaults[offset]))
553 547
554 548 # *args
555 549 if func_code.co_flags & 0x04:
556 550 name = arg_names[pos_count + keyword_only_count]
557 551 annotation = annotations.get(name, _empty)
558 552 parameters.append(Parameter(name, annotation=annotation,
559 553 kind=_VAR_POSITIONAL))
560 554
561 555 # Keyword-only parameters.
562 556 for name in keyword_only:
563 557 default = _empty
564 558 if kwdefaults is not None:
565 559 default = kwdefaults.get(name, _empty)
566 560
567 561 annotation = annotations.get(name, _empty)
568 562 parameters.append(Parameter(name, annotation=annotation,
569 563 kind=_KEYWORD_ONLY,
570 564 default=default))
571 565 # **kwargs
572 566 if func_code.co_flags & 0x08:
573 567 index = pos_count + keyword_only_count
574 568 if func_code.co_flags & 0x04:
575 569 index += 1
576 570
577 571 name = arg_names[index]
578 572 annotation = annotations.get(name, _empty)
579 573 parameters.append(Parameter(name, annotation=annotation,
580 574 kind=_VAR_KEYWORD))
581 575
582 576 return cls(parameters,
583 577 return_annotation=annotations.get('return', _empty),
584 578 __validate_parameters__=False)
585 579
586 580 @property
587 581 def parameters(self):
588 582 try:
589 583 return types.MappingProxyType(self._parameters)
590 584 except AttributeError:
591 585 return OrderedDict(self._parameters.items())
592 586
593 587 @property
594 588 def return_annotation(self):
595 589 return self._return_annotation
596 590
597 591 def replace(self, parameters=_void, return_annotation=_void):
598 592 '''Creates a customized copy of the Signature.
599 593 Pass 'parameters' and/or 'return_annotation' arguments
600 594 to override them in the new copy.
601 595 '''
602 596
603 597 if parameters is _void:
604 598 parameters = self.parameters.values()
605 599
606 600 if return_annotation is _void:
607 601 return_annotation = self._return_annotation
608 602
609 603 return type(self)(parameters,
610 604 return_annotation=return_annotation)
611 605
612 606 def __hash__(self):
613 607 msg = "unhashable type: '{0}'".format(self.__class__.__name__)
614 608 raise TypeError(msg)
615 609
616 610 def __eq__(self, other):
617 611 if (not issubclass(type(other), Signature) or
618 612 self.return_annotation != other.return_annotation or
619 613 len(self.parameters) != len(other.parameters)):
620 614 return False
621 615
622 616 other_positions = dict((param, idx)
623 617 for idx, param in enumerate(other.parameters.keys()))
624 618
625 619 for idx, (param_name, param) in enumerate(self.parameters.items()):
626 620 if param.kind == _KEYWORD_ONLY:
627 621 try:
628 622 other_param = other.parameters[param_name]
629 623 except KeyError:
630 624 return False
631 625 else:
632 626 if param != other_param:
633 627 return False
634 628 else:
635 629 try:
636 630 other_idx = other_positions[param_name]
637 631 except KeyError:
638 632 return False
639 633 else:
640 634 if (idx != other_idx or
641 635 param != other.parameters[param_name]):
642 636 return False
643 637
644 638 return True
645 639
646 640 def __ne__(self, other):
647 641 return not self.__eq__(other)
648 642
649 643 def _bind(self, args, kwargs, partial=False):
650 644 '''Private method. Don't use directly.'''
651 645
652 646 arguments = OrderedDict()
653 647
654 648 parameters = iter(self.parameters.values())
655 649 parameters_ex = ()
656 650 arg_vals = iter(args)
657 651
658 652 if partial:
659 653 # Support for binding arguments to 'functools.partial' objects.
660 654 # See 'functools.partial' case in 'signature()' implementation
661 655 # for details.
662 656 for param_name, param in self.parameters.items():
663 657 if (param._partial_kwarg and param_name not in kwargs):
664 658 # Simulating 'functools.partial' behavior
665 659 kwargs[param_name] = param.default
666 660
667 661 while True:
668 662 # Let's iterate through the positional arguments and corresponding
669 663 # parameters
670 664 try:
671 665 arg_val = next(arg_vals)
672 666 except StopIteration:
673 667 # No more positional arguments
674 668 try:
675 669 param = next(parameters)
676 670 except StopIteration:
677 671 # No more parameters. That's it. Just need to check that
678 672 # we have no `kwargs` after this while loop
679 673 break
680 674 else:
681 675 if param.kind == _VAR_POSITIONAL:
682 676 # That's OK, just empty *args. Let's start parsing
683 677 # kwargs
684 678 break
685 679 elif param.name in kwargs:
686 680 if param.kind == _POSITIONAL_ONLY:
687 681 msg = '{arg!r} parameter is positional only, ' \
688 682 'but was passed as a keyword'
689 683 msg = msg.format(arg=param.name)
690 684 raise TypeError(msg)
691 685 parameters_ex = (param,)
692 686 break
693 687 elif (param.kind == _VAR_KEYWORD or
694 688 param.default is not _empty):
695 689 # That's fine too - we have a default value for this
696 690 # parameter. So, lets start parsing `kwargs`, starting
697 691 # with the current parameter
698 692 parameters_ex = (param,)
699 693 break
700 694 else:
701 695 if partial:
702 696 parameters_ex = (param,)
703 697 break
704 698 else:
705 699 msg = '{arg!r} parameter lacking default value'
706 700 msg = msg.format(arg=param.name)
707 701 raise TypeError(msg)
708 702 else:
709 703 # We have a positional argument to process
710 704 try:
711 705 param = next(parameters)
712 706 except StopIteration:
713 707 raise TypeError('too many positional arguments')
714 708 else:
715 709 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
716 710 # Looks like we have no parameter for this positional
717 711 # argument
718 712 raise TypeError('too many positional arguments')
719 713
720 714 if param.kind == _VAR_POSITIONAL:
721 715 # We have an '*args'-like argument, let's fill it with
722 716 # all positional arguments we have left and move on to
723 717 # the next phase
724 718 values = [arg_val]
725 719 values.extend(arg_vals)
726 720 arguments[param.name] = tuple(values)
727 721 break
728 722
729 723 if param.name in kwargs:
730 724 raise TypeError('multiple values for argument '
731 725 '{arg!r}'.format(arg=param.name))
732 726
733 727 arguments[param.name] = arg_val
734 728
735 729 # Now, we iterate through the remaining parameters to process
736 730 # keyword arguments
737 731 kwargs_param = None
738 732 for param in itertools.chain(parameters_ex, parameters):
739 733 if param.kind == _POSITIONAL_ONLY:
740 734 # This should never happen in case of a properly built
741 735 # Signature object (but let's have this check here
742 736 # to ensure correct behaviour just in case)
743 737 raise TypeError('{arg!r} parameter is positional only, '
744 738 'but was passed as a keyword'. \
745 739 format(arg=param.name))
746 740
747 741 if param.kind == _VAR_KEYWORD:
748 742 # Memorize that we have a '**kwargs'-like parameter
749 743 kwargs_param = param
750 744 continue
751 745
752 746 param_name = param.name
753 747 try:
754 748 arg_val = kwargs.pop(param_name)
755 749 except KeyError:
756 750 # We have no value for this parameter. It's fine though,
757 751 # if it has a default value, or it is an '*args'-like
758 752 # parameter, left alone by the processing of positional
759 753 # arguments.
760 754 if (not partial and param.kind != _VAR_POSITIONAL and
761 755 param.default is _empty):
762 756 raise TypeError('{arg!r} parameter lacking default value'. \
763 757 format(arg=param_name))
764 758
765 759 else:
766 760 arguments[param_name] = arg_val
767 761
768 762 if kwargs:
769 763 if kwargs_param is not None:
770 764 # Process our '**kwargs'-like parameter
771 765 arguments[kwargs_param.name] = kwargs
772 766 else:
773 767 raise TypeError('too many keyword arguments')
774 768
775 769 return self._bound_arguments_cls(self, arguments)
776 770
777 771 def bind(self, *args, **kwargs):
778 '''Get a BoundArguments object, that maps the passed `args`
779 and `kwargs` to the function's signature. Raises `TypeError`
772 '''Get a :class:`BoundArguments` object, that maps the passed `args`
773 and `kwargs` to the function's signature. Raises :exc:`TypeError`
780 774 if the passed arguments can not be bound.
781 775 '''
782 776 return self._bind(args, kwargs)
783 777
784 778 def bind_partial(self, *args, **kwargs):
785 '''Get a BoundArguments object, that partially maps the
779 '''Get a :class:`BoundArguments` object, that partially maps the
786 780 passed `args` and `kwargs` to the function's signature.
787 Raises `TypeError` if the passed arguments can not be bound.
781 Raises :exc:`TypeError` if the passed arguments can not be bound.
788 782 '''
789 783 return self._bind(args, kwargs, partial=True)
790 784
791 785 def __str__(self):
792 786 result = []
793 787 render_kw_only_separator = True
794 788 for idx, param in enumerate(self.parameters.values()):
795 789 formatted = str(param)
796 790
797 791 kind = param.kind
798 792 if kind == _VAR_POSITIONAL:
799 793 # OK, we have an '*args'-like parameter, so we won't need
800 794 # a '*' to separate keyword-only arguments
801 795 render_kw_only_separator = False
802 796 elif kind == _KEYWORD_ONLY and render_kw_only_separator:
803 797 # We have a keyword-only parameter to render and we haven't
804 798 # rendered an '*args'-like parameter before, so add a '*'
805 799 # separator to the parameters list ("foo(arg1, *, arg2)" case)
806 800 result.append('*')
807 801 # This condition should be only triggered once, so
808 802 # reset the flag
809 803 render_kw_only_separator = False
810 804
811 805 result.append(formatted)
812 806
813 807 rendered = '({0})'.format(', '.join(result))
814 808
815 809 if self.return_annotation is not _empty:
816 810 anno = formatannotation(self.return_annotation)
817 811 rendered += ' -> {0}'.format(anno)
818 812
819 813 return rendered
@@ -1,30 +1,31 b''
1 1 .. _config_index:
2 2
3 3 ===============================
4 4 Configuration and customization
5 5 ===============================
6 6
7 7 Configuring IPython
8 8 -------------------
9 9
10 10 .. toctree::
11 11 :maxdepth: 2
12 12
13 13 intro
14 14 options/index
15 15 details
16 16
17 17 .. seealso::
18 18
19 19 :doc:`/development/config`
20 20 Technical details of the config system.
21 21
22 22 Extending and integrating with IPython
23 23 --------------------------------------
24 24
25 25 .. toctree::
26 26 :maxdepth: 2
27 27
28 28 extensions/index
29 29 integrating
30 30 inputtransforms
31 callbacks
@@ -1,339 +1,343 b''
1 1 #!/usr/bin/env python
2 2 # -*- coding: utf-8 -*-
3 3 """Setup script for IPython.
4 4
5 5 Under Posix environments it works like a typical setup.py script.
6 6 Under Windows, the command sdist is not supported, since IPython
7 7 requires utilities which are not available under Windows."""
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (c) 2008-2011, IPython Development Team.
11 11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 14 #
15 15 # Distributed under the terms of the Modified BSD License.
16 16 #
17 17 # The full license is in the file COPYING.txt, distributed with this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Minimal Python version sanity check
22 22 #-----------------------------------------------------------------------------
23 23 from __future__ import print_function
24 24
25 25 import sys
26 26
27 27 # This check is also made in IPython/__init__, don't forget to update both when
28 28 # changing Python version requirements.
29 29 if sys.version_info[:2] < (2,7):
30 30 error = "ERROR: IPython requires Python Version 2.7 or above."
31 31 print(error, file=sys.stderr)
32 32 sys.exit(1)
33 33
34 34 PY3 = (sys.version_info[0] >= 3)
35 35
36 36 # At least we're on the python version we need, move on.
37 37
38 38 #-------------------------------------------------------------------------------
39 39 # Imports
40 40 #-------------------------------------------------------------------------------
41 41
42 42 # Stdlib imports
43 43 import os
44 44 import shutil
45 45
46 46 from glob import glob
47 47
48 48 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
49 49 # update it when the contents of directories change.
50 50 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
51 51
52 52 from distutils.core import setup
53 53
54 54 # Our own imports
55 55 from setupbase import target_update
56 56
57 57 from setupbase import (
58 58 setup_args,
59 59 find_packages,
60 60 find_package_data,
61 61 check_package_data_first,
62 62 find_entry_points,
63 63 build_scripts_entrypt,
64 64 find_data_files,
65 65 check_for_dependencies,
66 66 git_prebuild,
67 67 check_submodule_status,
68 68 update_submodules,
69 69 require_submodules,
70 70 UpdateSubmodules,
71 71 get_bdist_wheel,
72 72 CompileCSS,
73 73 JavascriptVersion,
74 74 install_symlinked,
75 75 install_lib_symlink,
76 76 install_scripts_for_symlink,
77 77 unsymlink,
78 78 )
79 79 from setupext import setupext
80 80
81 81 isfile = os.path.isfile
82 82 pjoin = os.path.join
83 83
84 84 #-----------------------------------------------------------------------------
85 85 # Function definitions
86 86 #-----------------------------------------------------------------------------
87 87
88 88 def cleanup():
89 89 """Clean up the junk left around by the build process"""
90 90 if "develop" not in sys.argv and "egg_info" not in sys.argv:
91 91 try:
92 92 shutil.rmtree('ipython.egg-info')
93 93 except:
94 94 try:
95 95 os.unlink('ipython.egg-info')
96 96 except:
97 97 pass
98 98
99 99 #-------------------------------------------------------------------------------
100 100 # Handle OS specific things
101 101 #-------------------------------------------------------------------------------
102 102
103 103 if os.name in ('nt','dos'):
104 104 os_name = 'windows'
105 105 else:
106 106 os_name = os.name
107 107
108 108 # Under Windows, 'sdist' has not been supported. Now that the docs build with
109 109 # Sphinx it might work, but let's not turn it on until someone confirms that it
110 110 # actually works.
111 111 if os_name == 'windows' and 'sdist' in sys.argv:
112 112 print('The sdist command is not available under Windows. Exiting.')
113 113 sys.exit(1)
114 114
115 115 #-------------------------------------------------------------------------------
116 116 # Make sure we aren't trying to run without submodules
117 117 #-------------------------------------------------------------------------------
118 118 here = os.path.abspath(os.path.dirname(__file__))
119 119
120 120 def require_clean_submodules():
121 121 """Check on git submodules before distutils can do anything
122 122
123 123 Since distutils cannot be trusted to update the tree
124 124 after everything has been set in motion,
125 125 this is not a distutils command.
126 126 """
127 127 # PACKAGERS: Add a return here to skip checks for git submodules
128 128
129 129 # don't do anything if nothing is actually supposed to happen
130 130 for do_nothing in ('-h', '--help', '--help-commands', 'clean', 'submodule'):
131 131 if do_nothing in sys.argv:
132 132 return
133 133
134 134 status = check_submodule_status(here)
135 135
136 136 if status == "missing":
137 137 print("checking out submodules for the first time")
138 138 update_submodules(here)
139 139 elif status == "unclean":
140 140 print('\n'.join([
141 141 "Cannot build / install IPython with unclean submodules",
142 142 "Please update submodules with",
143 143 " python setup.py submodule",
144 144 "or",
145 145 " git submodule update",
146 146 "or commit any submodule changes you have made."
147 147 ]))
148 148 sys.exit(1)
149 149
150 150 require_clean_submodules()
151 151
152 152 #-------------------------------------------------------------------------------
153 153 # Things related to the IPython documentation
154 154 #-------------------------------------------------------------------------------
155 155
156 156 # update the manuals when building a source dist
157 157 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
158 158
159 159 # List of things to be updated. Each entry is a triplet of args for
160 160 # target_update()
161 161 to_update = [
162 162 # FIXME - Disabled for now: we need to redo an automatic way
163 163 # of generating the magic info inside the rst.
164 164 #('docs/magic.tex',
165 165 #['IPython/Magic.py'],
166 166 #"cd doc && ./update_magic.sh" ),
167 167
168 168 ('docs/man/ipcluster.1.gz',
169 169 ['docs/man/ipcluster.1'],
170 170 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
171 171
172 172 ('docs/man/ipcontroller.1.gz',
173 173 ['docs/man/ipcontroller.1'],
174 174 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
175 175
176 176 ('docs/man/ipengine.1.gz',
177 177 ['docs/man/ipengine.1'],
178 178 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
179 179
180 180 ('docs/man/ipython.1.gz',
181 181 ['docs/man/ipython.1'],
182 182 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
183 183
184 184 ]
185 185
186 186
187 187 [ target_update(*t) for t in to_update ]
188 188
189 189 #---------------------------------------------------------------------------
190 190 # Find all the packages, package data, and data_files
191 191 #---------------------------------------------------------------------------
192 192
193 193 packages = find_packages()
194 194 package_data = find_package_data()
195 195
196 196 data_files = find_data_files()
197 197
198 198 setup_args['packages'] = packages
199 199 setup_args['package_data'] = package_data
200 200 setup_args['data_files'] = data_files
201 201
202 202 #---------------------------------------------------------------------------
203 203 # custom distutils commands
204 204 #---------------------------------------------------------------------------
205 205 # imports here, so they are after setuptools import if there was one
206 206 from distutils.command.sdist import sdist
207 207 from distutils.command.upload import upload
208 208
209 209 class UploadWindowsInstallers(upload):
210 210
211 211 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
212 212 user_options = upload.user_options + [
213 213 ('files=', 'f', 'exe file (or glob) to upload')
214 214 ]
215 215 def initialize_options(self):
216 216 upload.initialize_options(self)
217 217 meta = self.distribution.metadata
218 218 base = '{name}-{version}'.format(
219 219 name=meta.get_name(),
220 220 version=meta.get_version()
221 221 )
222 222 self.files = os.path.join('dist', '%s.*.exe' % base)
223 223
224 224 def run(self):
225 225 for dist_file in glob(self.files):
226 226 self.upload_file('bdist_wininst', 'any', dist_file)
227 227
228 228 setup_args['cmdclass'] = {
229 229 'build_py': check_package_data_first(git_prebuild('IPython')),
230 230 'sdist' : git_prebuild('IPython', sdist),
231 231 'upload_wininst' : UploadWindowsInstallers,
232 232 'submodule' : UpdateSubmodules,
233 233 'css' : CompileCSS,
234 234 'symlink': install_symlinked,
235 235 'install_lib_symlink': install_lib_symlink,
236 236 'install_scripts_sym': install_scripts_for_symlink,
237 237 'unsymlink': unsymlink,
238 238 'jsversion' : JavascriptVersion,
239 239 }
240 240
241 241 #---------------------------------------------------------------------------
242 242 # Handle scripts, dependencies, and setuptools specific things
243 243 #---------------------------------------------------------------------------
244 244
245 245 # For some commands, use setuptools. Note that we do NOT list install here!
246 246 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
247 247 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
248 248 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
249 249 'egg_info', 'easy_install', 'upload', 'install_egg_info',
250 250 ))
251 251 if sys.platform == 'win32':
252 252 # Depend on setuptools for install on *Windows only*
253 253 # If we get script-installation working without setuptools,
254 254 # then we can back off, but until then use it.
255 255 # See Issue #369 on GitHub for more
256 256 needs_setuptools.add('install')
257 257
258 258 if len(needs_setuptools.intersection(sys.argv)) > 0:
259 259 import setuptools
260 260
261 261 # This dict is used for passing extra arguments that are setuptools
262 262 # specific to setup
263 263 setuptools_extra_args = {}
264 264
265 265 # setuptools requirements
266 266
267 267 extras_require = dict(
268 268 parallel = ['pyzmq>=2.1.11'],
269 269 qtconsole = ['pyzmq>=2.1.11', 'pygments'],
270 270 zmq = ['pyzmq>=2.1.11'],
271 271 doc = ['Sphinx>=1.1', 'numpydoc'],
272 272 test = ['nose>=0.10.1'],
273 273 notebook = ['tornado>=3.1', 'pyzmq>=2.1.11', 'jinja2'],
274 274 nbconvert = ['pygments', 'jinja2', 'Sphinx>=0.3']
275 275 )
276 if sys.version_info < (3, 3):
277 extras_require['test'].append('mock')
278
276 279 everything = set()
277 280 for deps in extras_require.values():
278 281 everything.update(deps)
279 282 extras_require['all'] = everything
283
280 284 install_requires = []
281 285 if sys.platform == 'darwin':
282 286 if any(arg.startswith('bdist') for arg in sys.argv) or not setupext.check_for_readline():
283 287 install_requires.append('gnureadline')
284 288 elif sys.platform.startswith('win'):
285 289 # Pyreadline has unicode and Python 3 fixes in 2.0
286 290 install_requires.append('pyreadline>=2.0')
287 291
288 292 if 'setuptools' in sys.modules:
289 293 # setup.py develop should check for submodules
290 294 from setuptools.command.develop import develop
291 295 setup_args['cmdclass']['develop'] = require_submodules(develop)
292 296 setup_args['cmdclass']['bdist_wheel'] = get_bdist_wheel()
293 297
294 298 setuptools_extra_args['zip_safe'] = False
295 299 setuptools_extra_args['entry_points'] = {'console_scripts':find_entry_points()}
296 300 setup_args['extras_require'] = extras_require
297 301 requires = setup_args['install_requires'] = install_requires
298 302
299 303 # Script to be run by the windows binary installer after the default setup
300 304 # routine, to add shortcuts and similar windows-only things. Windows
301 305 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
302 306 # doesn't find them.
303 307 if 'bdist_wininst' in sys.argv:
304 308 if len(sys.argv) > 2 and \
305 309 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
306 310 print >> sys.stderr, "ERROR: bdist_wininst must be run alone. Exiting."
307 311 sys.exit(1)
308 312 setup_args['data_files'].append(
309 313 ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')])
310 314 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
311 315 setup_args['options'] = {"bdist_wininst":
312 316 {"install_script":
313 317 "ipython_win_post_install.py"}}
314 318
315 319 else:
316 320 # If we are installing without setuptools, call this function which will
317 321 # check for dependencies an inform the user what is needed. This is
318 322 # just to make life easy for users.
319 323 for install_cmd in ('install', 'symlink'):
320 324 if install_cmd in sys.argv:
321 325 check_for_dependencies()
322 326 break
323 327 # scripts has to be a non-empty list, or install_scripts isn't called
324 328 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
325 329
326 330 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
327 331
328 332 #---------------------------------------------------------------------------
329 333 # Do the actual setup now
330 334 #---------------------------------------------------------------------------
331 335
332 336 setup_args.update(setuptools_extra_args)
333 337
334 338 def main():
335 339 setup(**setup_args)
336 340 cleanup()
337 341
338 342 if __name__ == '__main__':
339 343 main()
@@ -1,695 +1,696 b''
1 1 # encoding: utf-8
2 2 """
3 3 This module defines the things that are used in setup.py for building IPython
4 4
5 5 This includes:
6 6
7 7 * The basic arguments to setup
8 8 * Functions for finding things like packages, package data, etc.
9 9 * A function for checking dependencies.
10 10 """
11 11 from __future__ import print_function
12 12
13 13 #-------------------------------------------------------------------------------
14 14 # Copyright (C) 2008 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-------------------------------------------------------------------------------
19 19
20 20 #-------------------------------------------------------------------------------
21 21 # Imports
22 22 #-------------------------------------------------------------------------------
23 23 import errno
24 24 import os
25 25 import sys
26 26
27 27 from distutils.command.build_py import build_py
28 28 from distutils.command.build_scripts import build_scripts
29 29 from distutils.command.install import install
30 30 from distutils.command.install_scripts import install_scripts
31 31 from distutils.cmd import Command
32 32 from glob import glob
33 33 from subprocess import call
34 34
35 35 from setupext import install_data_ext
36 36
37 37 #-------------------------------------------------------------------------------
38 38 # Useful globals and utility functions
39 39 #-------------------------------------------------------------------------------
40 40
41 41 # A few handy globals
42 42 isfile = os.path.isfile
43 43 pjoin = os.path.join
44 44 repo_root = os.path.dirname(os.path.abspath(__file__))
45 45
46 46 def oscmd(s):
47 47 print(">", s)
48 48 os.system(s)
49 49
50 50 # Py3 compatibility hacks, without assuming IPython itself is installed with
51 51 # the full py3compat machinery.
52 52
53 53 try:
54 54 execfile
55 55 except NameError:
56 56 def execfile(fname, globs, locs=None):
57 57 locs = locs or globs
58 58 exec(compile(open(fname).read(), fname, "exec"), globs, locs)
59 59
60 60 # A little utility we'll need below, since glob() does NOT allow you to do
61 61 # exclusion on multiple endings!
62 62 def file_doesnt_endwith(test,endings):
63 63 """Return true if test is a file and its name does NOT end with any
64 64 of the strings listed in endings."""
65 65 if not isfile(test):
66 66 return False
67 67 for e in endings:
68 68 if test.endswith(e):
69 69 return False
70 70 return True
71 71
72 72 #---------------------------------------------------------------------------
73 73 # Basic project information
74 74 #---------------------------------------------------------------------------
75 75
76 76 # release.py contains version, authors, license, url, keywords, etc.
77 77 execfile(pjoin(repo_root, 'IPython','core','release.py'), globals())
78 78
79 79 # Create a dict with the basic information
80 80 # This dict is eventually passed to setup after additional keys are added.
81 81 setup_args = dict(
82 82 name = name,
83 83 version = version,
84 84 description = description,
85 85 long_description = long_description,
86 86 author = author,
87 87 author_email = author_email,
88 88 url = url,
89 89 download_url = download_url,
90 90 license = license,
91 91 platforms = platforms,
92 92 keywords = keywords,
93 93 classifiers = classifiers,
94 94 cmdclass = {'install_data': install_data_ext},
95 95 )
96 96
97 97
98 98 #---------------------------------------------------------------------------
99 99 # Find packages
100 100 #---------------------------------------------------------------------------
101 101
102 102 def find_packages():
103 103 """
104 104 Find all of IPython's packages.
105 105 """
106 106 excludes = ['deathrow', 'quarantine']
107 107 packages = []
108 108 for dir,subdirs,files in os.walk('IPython'):
109 109 package = dir.replace(os.path.sep, '.')
110 110 if any(package.startswith('IPython.'+exc) for exc in excludes):
111 111 # package is to be excluded (e.g. deathrow)
112 112 continue
113 113 if '__init__.py' not in files:
114 114 # not a package
115 115 continue
116 116 packages.append(package)
117 117 return packages
118 118
119 119 #---------------------------------------------------------------------------
120 120 # Find package data
121 121 #---------------------------------------------------------------------------
122 122
123 123 def find_package_data():
124 124 """
125 125 Find IPython's package_data.
126 126 """
127 127 # This is not enough for these things to appear in an sdist.
128 128 # We need to muck with the MANIFEST to get this to work
129 129
130 130 # exclude components from the walk,
131 131 # we will build the components separately
132 132 excludes = ['components']
133 133
134 134 # add 'static/' prefix to exclusions, and tuplify for use in startswith
135 135 excludes = tuple([pjoin('static', ex) for ex in excludes])
136 136
137 137 # walk notebook resources:
138 138 cwd = os.getcwd()
139 139 os.chdir(os.path.join('IPython', 'html'))
140 140 static_data = []
141 141 for parent, dirs, files in os.walk('static'):
142 142 if parent.startswith(excludes):
143 143 continue
144 144 for f in files:
145 145 static_data.append(pjoin(parent, f))
146 146 components = pjoin("static", "components")
147 147 # select the components we actually need to install
148 148 # (there are lots of resources we bundle for sdist-reasons that we don't actually use)
149 149 static_data.extend([
150 150 pjoin(components, "backbone", "backbone-min.js"),
151 151 pjoin(components, "bootstrap", "bootstrap", "js", "bootstrap.min.js"),
152 152 pjoin(components, "font-awesome", "font", "*.*"),
153 153 pjoin(components, "highlight.js", "build", "highlight.pack.js"),
154 154 pjoin(components, "jquery", "jquery.min.js"),
155 155 pjoin(components, "jquery-ui", "ui", "minified", "jquery-ui.min.js"),
156 156 pjoin(components, "jquery-ui", "themes", "smoothness", "jquery-ui.min.css"),
157 157 pjoin(components, "marked", "lib", "marked.js"),
158 158 pjoin(components, "requirejs", "require.js"),
159 159 pjoin(components, "underscore", "underscore-min.js"),
160 160 ])
161 161
162 162 # Ship all of Codemirror's CSS and JS
163 163 for parent, dirs, files in os.walk(pjoin(components, 'codemirror')):
164 164 for f in files:
165 165 if f.endswith(('.js', '.css')):
166 166 static_data.append(pjoin(parent, f))
167 167
168 168 os.chdir(os.path.join('tests',))
169 169 js_tests = glob('*.js') + glob('*/*.js')
170 170
171 171 os.chdir(os.path.join(cwd, 'IPython', 'nbconvert'))
172 172 nbconvert_templates = [os.path.join(dirpath, '*.*')
173 173 for dirpath, _, _ in os.walk('templates')]
174 174
175 175 os.chdir(cwd)
176 176
177 177 package_data = {
178 178 'IPython.config.profile' : ['README*', '*/*.py'],
179 179 'IPython.core.tests' : ['*.png', '*.jpg'],
180 180 'IPython.lib.tests' : ['*.wav'],
181 181 'IPython.testing.plugin' : ['*.txt'],
182 182 'IPython.html' : ['templates/*'] + static_data,
183 183 'IPython.html.tests' : js_tests,
184 184 'IPython.qt.console' : ['resources/icon/*.svg'],
185 185 'IPython.nbconvert' : nbconvert_templates +
186 186 ['tests/files/*.*', 'exporters/tests/files/*.*'],
187 187 'IPython.nbconvert.filters' : ['marked.js'],
188 188 'IPython.nbformat' : ['tests/*.ipynb']
189 189 }
190 190
191 191 return package_data
192 192
193 193
194 194 def check_package_data(package_data):
195 195 """verify that package_data globs make sense"""
196 196 print("checking package data")
197 197 for pkg, data in package_data.items():
198 198 pkg_root = pjoin(*pkg.split('.'))
199 199 for d in data:
200 200 path = pjoin(pkg_root, d)
201 201 if '*' in path:
202 202 assert len(glob(path)) > 0, "No files match pattern %s" % path
203 203 else:
204 204 assert os.path.exists(path), "Missing package data: %s" % path
205 205
206 206
207 207 def check_package_data_first(command):
208 208 """decorator for checking package_data before running a given command
209 209
210 210 Probably only needs to wrap build_py
211 211 """
212 212 class DecoratedCommand(command):
213 213 def run(self):
214 214 check_package_data(self.package_data)
215 215 command.run(self)
216 216 return DecoratedCommand
217 217
218 218
219 219 #---------------------------------------------------------------------------
220 220 # Find data files
221 221 #---------------------------------------------------------------------------
222 222
223 223 def make_dir_struct(tag,base,out_base):
224 224 """Make the directory structure of all files below a starting dir.
225 225
226 226 This is just a convenience routine to help build a nested directory
227 227 hierarchy because distutils is too stupid to do this by itself.
228 228
229 229 XXX - this needs a proper docstring!
230 230 """
231 231
232 232 # we'll use these a lot below
233 233 lbase = len(base)
234 234 pathsep = os.path.sep
235 235 lpathsep = len(pathsep)
236 236
237 237 out = []
238 238 for (dirpath,dirnames,filenames) in os.walk(base):
239 239 # we need to strip out the dirpath from the base to map it to the
240 240 # output (installation) path. This requires possibly stripping the
241 241 # path separator, because otherwise pjoin will not work correctly
242 242 # (pjoin('foo/','/bar') returns '/bar').
243 243
244 244 dp_eff = dirpath[lbase:]
245 245 if dp_eff.startswith(pathsep):
246 246 dp_eff = dp_eff[lpathsep:]
247 247 # The output path must be anchored at the out_base marker
248 248 out_path = pjoin(out_base,dp_eff)
249 249 # Now we can generate the final filenames. Since os.walk only produces
250 250 # filenames, we must join back with the dirpath to get full valid file
251 251 # paths:
252 252 pfiles = [pjoin(dirpath,f) for f in filenames]
253 253 # Finally, generate the entry we need, which is a pari of (output
254 254 # path, files) for use as a data_files parameter in install_data.
255 255 out.append((out_path, pfiles))
256 256
257 257 return out
258 258
259 259
260 260 def find_data_files():
261 261 """
262 262 Find IPython's data_files.
263 263
264 264 Just man pages at this point.
265 265 """
266 266
267 267 manpagebase = pjoin('share', 'man', 'man1')
268 268
269 269 # Simple file lists can be made by hand
270 270 manpages = [f for f in glob(pjoin('docs','man','*.1.gz')) if isfile(f)]
271 271 if not manpages:
272 272 # When running from a source tree, the manpages aren't gzipped
273 273 manpages = [f for f in glob(pjoin('docs','man','*.1')) if isfile(f)]
274 274
275 275 # And assemble the entire output list
276 276 data_files = [ (manpagebase, manpages) ]
277 277
278 278 return data_files
279 279
280 280
281 281 def make_man_update_target(manpage):
282 282 """Return a target_update-compliant tuple for the given manpage.
283 283
284 284 Parameters
285 285 ----------
286 286 manpage : string
287 287 Name of the manpage, must include the section number (trailing number).
288 288
289 289 Example
290 290 -------
291 291
292 292 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
293 293 ('docs/man/ipython.1.gz',
294 294 ['docs/man/ipython.1'],
295 295 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
296 296 """
297 297 man_dir = pjoin('docs', 'man')
298 298 manpage_gz = manpage + '.gz'
299 299 manpath = pjoin(man_dir, manpage)
300 300 manpath_gz = pjoin(man_dir, manpage_gz)
301 301 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
302 302 locals() )
303 303 return (manpath_gz, [manpath], gz_cmd)
304 304
305 305 # The two functions below are copied from IPython.utils.path, so we don't need
306 306 # to import IPython during setup, which fails on Python 3.
307 307
308 308 def target_outdated(target,deps):
309 309 """Determine whether a target is out of date.
310 310
311 311 target_outdated(target,deps) -> 1/0
312 312
313 313 deps: list of filenames which MUST exist.
314 314 target: single filename which may or may not exist.
315 315
316 316 If target doesn't exist or is older than any file listed in deps, return
317 317 true, otherwise return false.
318 318 """
319 319 try:
320 320 target_time = os.path.getmtime(target)
321 321 except os.error:
322 322 return 1
323 323 for dep in deps:
324 324 dep_time = os.path.getmtime(dep)
325 325 if dep_time > target_time:
326 326 #print "For target",target,"Dep failed:",dep # dbg
327 327 #print "times (dep,tar):",dep_time,target_time # dbg
328 328 return 1
329 329 return 0
330 330
331 331
332 332 def target_update(target,deps,cmd):
333 333 """Update a target with a given command given a list of dependencies.
334 334
335 335 target_update(target,deps,cmd) -> runs cmd if target is outdated.
336 336
337 337 This is just a wrapper around target_outdated() which calls the given
338 338 command if target is outdated."""
339 339
340 340 if target_outdated(target,deps):
341 341 os.system(cmd)
342 342
343 343 #---------------------------------------------------------------------------
344 344 # Find scripts
345 345 #---------------------------------------------------------------------------
346 346
347 347 def find_entry_points():
348 348 """Find IPython's scripts.
349 349
350 350 if entry_points is True:
351 351 return setuptools entry_point-style definitions
352 352 else:
353 353 return file paths of plain scripts [default]
354 354
355 355 suffix is appended to script names if entry_points is True, so that the
356 356 Python 3 scripts get named "ipython3" etc.
357 357 """
358 358 ep = [
359 359 'ipython%s = IPython:start_ipython',
360 360 'ipcontroller%s = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
361 361 'ipengine%s = IPython.parallel.apps.ipengineapp:launch_new_instance',
362 362 'ipcluster%s = IPython.parallel.apps.ipclusterapp:launch_new_instance',
363 363 'iptest%s = IPython.testing.iptestcontroller:main',
364 364 ]
365 365 suffix = str(sys.version_info[0])
366 366 return [e % '' for e in ep] + [e % suffix for e in ep]
367 367
368 368 script_src = """#!{executable}
369 369 # This script was automatically generated by setup.py
370 370 if __name__ == '__main__':
371 371 from {mod} import {func}
372 372 {func}()
373 373 """
374 374
375 375 class build_scripts_entrypt(build_scripts):
376 376 def run(self):
377 377 self.mkpath(self.build_dir)
378 378 outfiles = []
379 379 for script in find_entry_points():
380 380 name, entrypt = script.split('=')
381 381 name = name.strip()
382 382 entrypt = entrypt.strip()
383 383 outfile = os.path.join(self.build_dir, name)
384 384 outfiles.append(outfile)
385 385 print('Writing script to', outfile)
386 386
387 387 mod, func = entrypt.split(':')
388 388 with open(outfile, 'w') as f:
389 389 f.write(script_src.format(executable=sys.executable,
390 390 mod=mod, func=func))
391 391
392 392 return outfiles, outfiles
393 393
394 394 class install_lib_symlink(Command):
395 395 user_options = [
396 396 ('install-dir=', 'd', "directory to install to"),
397 397 ]
398 398
399 399 def initialize_options(self):
400 400 self.install_dir = None
401 401
402 402 def finalize_options(self):
403 403 self.set_undefined_options('symlink',
404 404 ('install_lib', 'install_dir'),
405 405 )
406 406
407 407 def run(self):
408 408 if sys.platform == 'win32':
409 409 raise Exception("This doesn't work on Windows.")
410 410 pkg = os.path.join(os.getcwd(), 'IPython')
411 411 dest = os.path.join(self.install_dir, 'IPython')
412 412 if os.path.islink(dest):
413 413 print('removing existing symlink at %s' % dest)
414 414 os.unlink(dest)
415 415 print('symlinking %s -> %s' % (pkg, dest))
416 416 os.symlink(pkg, dest)
417 417
418 418 class unsymlink(install):
419 419 def run(self):
420 420 dest = os.path.join(self.install_lib, 'IPython')
421 421 if os.path.islink(dest):
422 422 print('removing symlink at %s' % dest)
423 423 os.unlink(dest)
424 424 else:
425 425 print('No symlink exists at %s' % dest)
426 426
427 427 class install_symlinked(install):
428 428 def run(self):
429 429 if sys.platform == 'win32':
430 430 raise Exception("This doesn't work on Windows.")
431 431
432 432 # Run all sub-commands (at least those that need to be run)
433 433 for cmd_name in self.get_sub_commands():
434 434 self.run_command(cmd_name)
435 435
436 436 # 'sub_commands': a list of commands this command might have to run to
437 437 # get its work done. See cmd.py for more info.
438 438 sub_commands = [('install_lib_symlink', lambda self:True),
439 439 ('install_scripts_sym', lambda self:True),
440 440 ]
441 441
442 442 class install_scripts_for_symlink(install_scripts):
443 443 """Redefined to get options from 'symlink' instead of 'install'.
444 444
445 445 I love distutils almost as much as I love setuptools.
446 446 """
447 447 def finalize_options(self):
448 448 self.set_undefined_options('build', ('build_scripts', 'build_dir'))
449 449 self.set_undefined_options('symlink',
450 450 ('install_scripts', 'install_dir'),
451 451 ('force', 'force'),
452 452 ('skip_build', 'skip_build'),
453 453 )
454 454
455 455 #---------------------------------------------------------------------------
456 456 # Verify all dependencies
457 457 #---------------------------------------------------------------------------
458 458
459 459 def check_for_dependencies():
460 460 """Check for IPython's dependencies.
461 461
462 462 This function should NOT be called if running under setuptools!
463 463 """
464 464 from setupext.setupext import (
465 465 print_line, print_raw, print_status,
466 466 check_for_sphinx, check_for_pygments,
467 467 check_for_nose, check_for_pexpect,
468 468 check_for_pyzmq, check_for_readline,
469 469 check_for_jinja2, check_for_tornado
470 470 )
471 471 print_line()
472 472 print_raw("BUILDING IPYTHON")
473 473 print_status('python', sys.version)
474 474 print_status('platform', sys.platform)
475 475 if sys.platform == 'win32':
476 476 print_status('Windows version', sys.getwindowsversion())
477 477
478 478 print_raw("")
479 479 print_raw("OPTIONAL DEPENDENCIES")
480 480
481 481 check_for_sphinx()
482 482 check_for_pygments()
483 483 check_for_nose()
484 484 if os.name == 'posix':
485 485 check_for_pexpect()
486 486 check_for_pyzmq()
487 487 check_for_tornado()
488 488 check_for_readline()
489 489 check_for_jinja2()
490 490
491 491 #---------------------------------------------------------------------------
492 492 # VCS related
493 493 #---------------------------------------------------------------------------
494 494
495 495 # utils.submodule has checks for submodule status
496 496 execfile(pjoin('IPython','utils','submodule.py'), globals())
497 497
498 498 class UpdateSubmodules(Command):
499 499 """Update git submodules
500 500
501 501 IPython's external javascript dependencies live in a separate repo.
502 502 """
503 503 description = "Update git submodules"
504 504 user_options = []
505 505
506 506 def initialize_options(self):
507 507 pass
508 508
509 509 def finalize_options(self):
510 510 pass
511 511
512 512 def run(self):
513 513 failure = False
514 514 try:
515 515 self.spawn('git submodule init'.split())
516 516 self.spawn('git submodule update --recursive'.split())
517 517 except Exception as e:
518 518 failure = e
519 519 print(e)
520 520
521 521 if not check_submodule_status(repo_root) == 'clean':
522 522 print("submodules could not be checked out")
523 523 sys.exit(1)
524 524
525 525
526 526 def git_prebuild(pkg_dir, build_cmd=build_py):
527 527 """Return extended build or sdist command class for recording commit
528 528
529 529 records git commit in IPython.utils._sysinfo.commit
530 530
531 531 for use in IPython.utils.sysinfo.sys_info() calls after installation.
532 532
533 533 Also ensures that submodules exist prior to running
534 534 """
535 535
536 536 class MyBuildPy(build_cmd):
537 537 ''' Subclass to write commit data into installation tree '''
538 538 def run(self):
539 539 build_cmd.run(self)
540 540 # this one will only fire for build commands
541 541 if hasattr(self, 'build_lib'):
542 542 self._record_commit(self.build_lib)
543 543
544 544 def make_release_tree(self, base_dir, files):
545 545 # this one will fire for sdist
546 546 build_cmd.make_release_tree(self, base_dir, files)
547 547 self._record_commit(base_dir)
548 548
549 549 def _record_commit(self, base_dir):
550 550 import subprocess
551 551 proc = subprocess.Popen('git rev-parse --short HEAD',
552 552 stdout=subprocess.PIPE,
553 553 stderr=subprocess.PIPE,
554 554 shell=True)
555 555 repo_commit, _ = proc.communicate()
556 556 repo_commit = repo_commit.strip().decode("ascii")
557 557
558 558 out_pth = pjoin(base_dir, pkg_dir, 'utils', '_sysinfo.py')
559 559 if os.path.isfile(out_pth) and not repo_commit:
560 560 # nothing to write, don't clobber
561 561 return
562 562
563 563 print("writing git commit '%s' to %s" % (repo_commit, out_pth))
564 564
565 565 # remove to avoid overwriting original via hard link
566 566 try:
567 567 os.remove(out_pth)
568 568 except (IOError, OSError):
569 569 pass
570 570 with open(out_pth, 'w') as out_file:
571 571 out_file.writelines([
572 572 '# GENERATED BY setup.py\n',
573 573 'commit = "%s"\n' % repo_commit,
574 574 ])
575 575 return require_submodules(MyBuildPy)
576 576
577 577
578 578 def require_submodules(command):
579 579 """decorator for instructing a command to check for submodules before running"""
580 580 class DecoratedCommand(command):
581 581 def run(self):
582 582 if not check_submodule_status(repo_root) == 'clean':
583 583 print("submodules missing! Run `setup.py submodule` and try again")
584 584 sys.exit(1)
585 585 command.run(self)
586 586 return DecoratedCommand
587 587
588 588 #---------------------------------------------------------------------------
589 589 # bdist related
590 590 #---------------------------------------------------------------------------
591 591
592 592 def get_bdist_wheel():
593 593 """Construct bdist_wheel command for building wheels
594 594
595 595 Constructs py2-none-any tag, instead of py2.7-none-any
596 596 """
597 597 class RequiresWheel(Command):
598 598 description = "Dummy command for missing bdist_wheel"
599 599 user_options = []
600 600
601 601 def initialize_options(self):
602 602 pass
603 603
604 604 def finalize_options(self):
605 605 pass
606 606
607 607 def run(self):
608 608 print("bdist_wheel requires the wheel package")
609 609 sys.exit(1)
610 610
611 611 if 'setuptools' not in sys.modules:
612 612 return RequiresWheel
613 613 else:
614 614 try:
615 615 from wheel.bdist_wheel import bdist_wheel, read_pkg_info, write_pkg_info
616 616 except ImportError:
617 617 return RequiresWheel
618 618
619 619 class bdist_wheel_tag(bdist_wheel):
620 620
621 621 def get_tag(self):
622 622 return ('py%i' % sys.version_info[0], 'none', 'any')
623 623
624 624 def add_requirements(self, metadata_path):
625 625 """transform platform-dependent requirements"""
626 626 pkg_info = read_pkg_info(metadata_path)
627 627 # pkg_info is an email.Message object (?!)
628 628 # we have to remove the unconditional 'readline' and/or 'pyreadline' entries
629 629 # and transform them to conditionals
630 630 requires = pkg_info.get_all('Requires-Dist')
631 631 del pkg_info['Requires-Dist']
632 632 def _remove_startswith(lis, prefix):
633 633 """like list.remove, but with startswith instead of =="""
634 634 found = False
635 635 for idx, item in enumerate(lis):
636 636 if item.startswith(prefix):
637 637 found = True
638 638 break
639 639 if found:
640 640 lis.pop(idx)
641 641
642 for pkg in ("gnureadline", "pyreadline"):
642 for pkg in ("gnureadline", "pyreadline", "mock"):
643 643 _remove_startswith(requires, pkg)
644 644 requires.append("gnureadline; sys.platform == 'darwin' and platform.python_implementation == 'CPython'")
645 645 requires.append("pyreadline (>=2.0); sys.platform == 'win32' and platform.python_implementation == 'CPython'")
646 requires.append("mock; extra == 'test' and python_version < '3.3'")
646 647 for r in requires:
647 648 pkg_info['Requires-Dist'] = r
648 649 write_pkg_info(metadata_path, pkg_info)
649 650
650 651 return bdist_wheel_tag
651 652
652 653 #---------------------------------------------------------------------------
653 654 # Notebook related
654 655 #---------------------------------------------------------------------------
655 656
656 657 class CompileCSS(Command):
657 658 """Recompile Notebook CSS
658 659
659 660 Regenerate the compiled CSS from LESS sources.
660 661
661 662 Requires various dev dependencies, such as fabric and lessc.
662 663 """
663 664 description = "Recompile Notebook CSS"
664 665 user_options = []
665 666
666 667 def initialize_options(self):
667 668 pass
668 669
669 670 def finalize_options(self):
670 671 pass
671 672
672 673 def run(self):
673 674 call("fab css", shell=True, cwd=pjoin(repo_root, "IPython", "html"))
674 675
675 676 class JavascriptVersion(Command):
676 677 """write the javascript version to notebook javascript"""
677 678 description = "Write IPython version to javascript"
678 679 user_options = []
679 680
680 681 def initialize_options(self):
681 682 pass
682 683
683 684 def finalize_options(self):
684 685 pass
685 686
686 687 def run(self):
687 688 nsfile = pjoin(repo_root, "IPython", "html", "static", "base", "js", "namespace.js")
688 689 with open(nsfile) as f:
689 690 lines = f.readlines()
690 691 with open(nsfile, 'w') as f:
691 692 for line in lines:
692 693 if line.startswith("IPython.version"):
693 694 line = 'IPython.version = "{0}";\n'.format(version)
694 695 f.write(line)
695 696
@@ -1,24 +1,25 b''
1 1 # Tox (http://tox.testrun.org/) is a tool for running tests
2 2 # in multiple virtualenvs. This configuration file will run the
3 3 # test suite on all supported python versions. To use it, "pip install tox"
4 4 # and then run "tox" from this directory.
5 5
6 6 [tox]
7 7 envlist = py27, py33
8 8
9 9 [testenv]
10 10 deps =
11 11 nose
12 mock
12 13 tornado
13 14 jinja2
14 15 sphinx
15 16 pygments
16 17 # To avoid loading IPython module in the current directory, change
17 18 # current directory to ".tox/py*/tmp" before running test.
18 19 changedir = {envtmpdir}
19 20
20 21 commands =
21 22 # As pip does not treat egg, use easy_install to install PyZMQ.
22 23 # See also: https://github.com/zeromq/pyzmq
23 24 easy_install -q pyzmq
24 25 iptest --all
General Comments 0
You need to be logged in to leave comments. Login now