##// END OF EJS Templates
Merge pull request #1073 from takluyver/storemagic-plugin...
Min RK -
r5683:d3ded1a8 merge
parent child Browse files
Show More
@@ -1,291 +1,292 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 A mixin for :class:`~IPython.core.application.Application` classes that
3 A mixin for :class:`~IPython.core.application.Application` classes that
4 launch InteractiveShell instances, load extensions, etc.
4 launch InteractiveShell instances, load extensions, etc.
5
5
6 Authors
6 Authors
7 -------
7 -------
8
8
9 * Min Ragan-Kelley
9 * Min Ragan-Kelley
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2011 The IPython Development Team
13 # Copyright (C) 2008-2011 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 from __future__ import absolute_import
23 from __future__ import absolute_import
24
24
25 import glob
25 import glob
26 import os
26 import os
27 import sys
27 import sys
28
28
29 from IPython.config.application import boolean_flag
29 from IPython.config.application import boolean_flag
30 from IPython.config.configurable import Configurable
30 from IPython.config.configurable import Configurable
31 from IPython.config.loader import Config
31 from IPython.config.loader import Config
32 from IPython.utils import py3compat
32 from IPython.utils import py3compat
33 from IPython.utils.path import filefind
33 from IPython.utils.path import filefind
34 from IPython.utils.traitlets import Unicode, Instance, List, Bool
34 from IPython.utils.traitlets import Unicode, Instance, List, Bool
35
35
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37 # Aliases and Flags
37 # Aliases and Flags
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39
39
40 shell_flags = {}
40 shell_flags = {}
41
41
42 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
42 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
43 addflag('autoindent', 'InteractiveShell.autoindent',
43 addflag('autoindent', 'InteractiveShell.autoindent',
44 'Turn on autoindenting.', 'Turn off autoindenting.'
44 'Turn on autoindenting.', 'Turn off autoindenting.'
45 )
45 )
46 addflag('automagic', 'InteractiveShell.automagic',
46 addflag('automagic', 'InteractiveShell.automagic',
47 """Turn on the auto calling of magic commands. Type %%magic at the
47 """Turn on the auto calling of magic commands. Type %%magic at the
48 IPython prompt for more information.""",
48 IPython prompt for more information.""",
49 'Turn off the auto calling of magic commands.'
49 'Turn off the auto calling of magic commands.'
50 )
50 )
51 addflag('pdb', 'InteractiveShell.pdb',
51 addflag('pdb', 'InteractiveShell.pdb',
52 "Enable auto calling the pdb debugger after every exception.",
52 "Enable auto calling the pdb debugger after every exception.",
53 "Disable auto calling the pdb debugger after every exception."
53 "Disable auto calling the pdb debugger after every exception."
54 )
54 )
55 # pydb flag doesn't do any config, as core.debugger switches on import,
55 # pydb flag doesn't do any config, as core.debugger switches on import,
56 # which is before parsing. This just allows the flag to be passed.
56 # which is before parsing. This just allows the flag to be passed.
57 shell_flags.update(dict(
57 shell_flags.update(dict(
58 pydb = ({},
58 pydb = ({},
59 """"Use the third party 'pydb' package as debugger, instead of pdb.
59 """"Use the third party 'pydb' package as debugger, instead of pdb.
60 Requires that pydb is installed."""
60 Requires that pydb is installed."""
61 )
61 )
62 ))
62 ))
63 addflag('pprint', 'PlainTextFormatter.pprint',
63 addflag('pprint', 'PlainTextFormatter.pprint',
64 "Enable auto pretty printing of results.",
64 "Enable auto pretty printing of results.",
65 "Disable auto auto pretty printing of results."
65 "Disable auto auto pretty printing of results."
66 )
66 )
67 addflag('color-info', 'InteractiveShell.color_info',
67 addflag('color-info', 'InteractiveShell.color_info',
68 """IPython can display information about objects via a set of func-
68 """IPython can display information about objects via a set of func-
69 tions, and optionally can use colors for this, syntax highlighting
69 tions, and optionally can use colors for this, syntax highlighting
70 source code and various other elements. However, because this
70 source code and various other elements. However, because this
71 information is passed through a pager (like 'less') and many pagers get
71 information is passed through a pager (like 'less') and many pagers get
72 confused with color codes, this option is off by default. You can test
72 confused with color codes, this option is off by default. You can test
73 it and turn it on permanently in your ipython_config.py file if it
73 it and turn it on permanently in your ipython_config.py file if it
74 works for you. Test it and turn it on permanently if it works with
74 works for you. Test it and turn it on permanently if it works with
75 your system. The magic function %%color_info allows you to toggle this
75 your system. The magic function %%color_info allows you to toggle this
76 interactively for testing.""",
76 interactively for testing.""",
77 "Disable using colors for info related things."
77 "Disable using colors for info related things."
78 )
78 )
79 addflag('deep-reload', 'InteractiveShell.deep_reload',
79 addflag('deep-reload', 'InteractiveShell.deep_reload',
80 """Enable deep (recursive) reloading by default. IPython can use the
80 """Enable deep (recursive) reloading by default. IPython can use the
81 deep_reload module which reloads changes in modules recursively (it
81 deep_reload module which reloads changes in modules recursively (it
82 replaces the reload() function, so you don't need to change anything to
82 replaces the reload() function, so you don't need to change anything to
83 use it). deep_reload() forces a full reload of modules whose code may
83 use it). deep_reload() forces a full reload of modules whose code may
84 have changed, which the default reload() function does not. When
84 have changed, which the default reload() function does not. When
85 deep_reload is off, IPython will use the normal reload(), but
85 deep_reload is off, IPython will use the normal reload(), but
86 deep_reload will still be available as dreload(). This feature is off
86 deep_reload will still be available as dreload(). This feature is off
87 by default [which means that you have both normal reload() and
87 by default [which means that you have both normal reload() and
88 dreload()].""",
88 dreload()].""",
89 "Disable deep (recursive) reloading by default."
89 "Disable deep (recursive) reloading by default."
90 )
90 )
91 nosep_config = Config()
91 nosep_config = Config()
92 nosep_config.InteractiveShell.separate_in = ''
92 nosep_config.InteractiveShell.separate_in = ''
93 nosep_config.InteractiveShell.separate_out = ''
93 nosep_config.InteractiveShell.separate_out = ''
94 nosep_config.InteractiveShell.separate_out2 = ''
94 nosep_config.InteractiveShell.separate_out2 = ''
95
95
96 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
96 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
97
97
98
98
99 # it's possible we don't want short aliases for *all* of these:
99 # it's possible we don't want short aliases for *all* of these:
100 shell_aliases = dict(
100 shell_aliases = dict(
101 autocall='InteractiveShell.autocall',
101 autocall='InteractiveShell.autocall',
102 colors='InteractiveShell.colors',
102 colors='InteractiveShell.colors',
103 logfile='InteractiveShell.logfile',
103 logfile='InteractiveShell.logfile',
104 logappend='InteractiveShell.logappend',
104 logappend='InteractiveShell.logappend',
105 c='InteractiveShellApp.code_to_run',
105 c='InteractiveShellApp.code_to_run',
106 ext='InteractiveShellApp.extra_extension',
106 ext='InteractiveShellApp.extra_extension',
107 )
107 )
108 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
108 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
109
109
110 #-----------------------------------------------------------------------------
110 #-----------------------------------------------------------------------------
111 # Main classes and functions
111 # Main classes and functions
112 #-----------------------------------------------------------------------------
112 #-----------------------------------------------------------------------------
113
113
114 class InteractiveShellApp(Configurable):
114 class InteractiveShellApp(Configurable):
115 """A Mixin for applications that start InteractiveShell instances.
115 """A Mixin for applications that start InteractiveShell instances.
116
116
117 Provides configurables for loading extensions and executing files
117 Provides configurables for loading extensions and executing files
118 as part of configuring a Shell environment.
118 as part of configuring a Shell environment.
119
119
120 Provides init_extensions() and init_code() methods, to be called
120 Provides init_extensions() and init_code() methods, to be called
121 after init_shell(), which must be implemented by subclasses.
121 after init_shell(), which must be implemented by subclasses.
122 """
122 """
123 extensions = List(Unicode, config=True,
123 extensions = List(Unicode, config=True,
124 help="A list of dotted module names of IPython extensions to load."
124 help="A list of dotted module names of IPython extensions to load."
125 )
125 )
126 extra_extension = Unicode('', config=True,
126 extra_extension = Unicode('', config=True,
127 help="dotted module name of an IPython extension to load."
127 help="dotted module name of an IPython extension to load."
128 )
128 )
129 def _extra_extension_changed(self, name, old, new):
129 def _extra_extension_changed(self, name, old, new):
130 if new:
130 if new:
131 # add to self.extensions
131 # add to self.extensions
132 self.extensions.append(new)
132 self.extensions.append(new)
133
134 # Extensions that are always loaded (not configurable)
135 default_extensions = List(Unicode, [u'storemagic'], config=False)
133
136
134 exec_files = List(Unicode, config=True,
137 exec_files = List(Unicode, config=True,
135 help="""List of files to run at IPython startup."""
138 help="""List of files to run at IPython startup."""
136 )
139 )
137 file_to_run = Unicode('', config=True,
140 file_to_run = Unicode('', config=True,
138 help="""A file to be run""")
141 help="""A file to be run""")
139
142
140 exec_lines = List(Unicode, config=True,
143 exec_lines = List(Unicode, config=True,
141 help="""lines of code to run at IPython startup."""
144 help="""lines of code to run at IPython startup."""
142 )
145 )
143 code_to_run = Unicode('', config=True,
146 code_to_run = Unicode('', config=True,
144 help="Execute the given command string."
147 help="Execute the given command string."
145 )
148 )
146 pylab_import_all = Bool(True, config=True,
149 pylab_import_all = Bool(True, config=True,
147 help="""If true, an 'import *' is done from numpy and pylab,
150 help="""If true, an 'import *' is done from numpy and pylab,
148 when using pylab"""
151 when using pylab"""
149 )
152 )
150 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
153 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
151
154
152 def init_shell(self):
155 def init_shell(self):
153 raise NotImplementedError("Override in subclasses")
156 raise NotImplementedError("Override in subclasses")
154
157
155 def init_extensions(self):
158 def init_extensions(self):
156 """Load all IPython extensions in IPythonApp.extensions.
159 """Load all IPython extensions in IPythonApp.extensions.
157
160
158 This uses the :meth:`ExtensionManager.load_extensions` to load all
161 This uses the :meth:`ExtensionManager.load_extensions` to load all
159 the extensions listed in ``self.extensions``.
162 the extensions listed in ``self.extensions``.
160 """
163 """
161 if not self.extensions:
162 return
163 try:
164 try:
164 self.log.debug("Loading IPython extensions...")
165 self.log.debug("Loading IPython extensions...")
165 extensions = self.extensions
166 extensions = self.default_extensions + self.extensions
166 for ext in extensions:
167 for ext in extensions:
167 try:
168 try:
168 self.log.info("Loading IPython extension: %s" % ext)
169 self.log.info("Loading IPython extension: %s" % ext)
169 self.shell.extension_manager.load_extension(ext)
170 self.shell.extension_manager.load_extension(ext)
170 except:
171 except:
171 self.log.warn("Error in loading extension: %s" % ext +
172 self.log.warn("Error in loading extension: %s" % ext +
172 "\nCheck your config files in %s" % self.profile_dir.location
173 "\nCheck your config files in %s" % self.profile_dir.location
173 )
174 )
174 self.shell.showtraceback()
175 self.shell.showtraceback()
175 except:
176 except:
176 self.log.warn("Unknown error in loading extensions:")
177 self.log.warn("Unknown error in loading extensions:")
177 self.shell.showtraceback()
178 self.shell.showtraceback()
178
179
179 def init_code(self):
180 def init_code(self):
180 """run the pre-flight code, specified via exec_lines"""
181 """run the pre-flight code, specified via exec_lines"""
181 self._run_startup_files()
182 self._run_startup_files()
182 self._run_exec_lines()
183 self._run_exec_lines()
183 self._run_exec_files()
184 self._run_exec_files()
184 self._run_cmd_line_code()
185 self._run_cmd_line_code()
185
186
186 # Hide variables defined here from %who etc.
187 # Hide variables defined here from %who etc.
187 self.shell.user_ns_hidden.update(self.shell.user_ns)
188 self.shell.user_ns_hidden.update(self.shell.user_ns)
188
189
189 def _run_exec_lines(self):
190 def _run_exec_lines(self):
190 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
191 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
191 if not self.exec_lines:
192 if not self.exec_lines:
192 return
193 return
193 try:
194 try:
194 self.log.debug("Running code from IPythonApp.exec_lines...")
195 self.log.debug("Running code from IPythonApp.exec_lines...")
195 for line in self.exec_lines:
196 for line in self.exec_lines:
196 try:
197 try:
197 self.log.info("Running code in user namespace: %s" %
198 self.log.info("Running code in user namespace: %s" %
198 line)
199 line)
199 self.shell.run_cell(line, store_history=False)
200 self.shell.run_cell(line, store_history=False)
200 except:
201 except:
201 self.log.warn("Error in executing line in user "
202 self.log.warn("Error in executing line in user "
202 "namespace: %s" % line)
203 "namespace: %s" % line)
203 self.shell.showtraceback()
204 self.shell.showtraceback()
204 except:
205 except:
205 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
206 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
206 self.shell.showtraceback()
207 self.shell.showtraceback()
207
208
208 def _exec_file(self, fname):
209 def _exec_file(self, fname):
209 try:
210 try:
210 full_filename = filefind(fname, [u'.', self.ipython_dir])
211 full_filename = filefind(fname, [u'.', self.ipython_dir])
211 except IOError as e:
212 except IOError as e:
212 self.log.warn("File not found: %r"%fname)
213 self.log.warn("File not found: %r"%fname)
213 return
214 return
214 # Make sure that the running script gets a proper sys.argv as if it
215 # Make sure that the running script gets a proper sys.argv as if it
215 # were run from a system shell.
216 # were run from a system shell.
216 save_argv = sys.argv
217 save_argv = sys.argv
217 sys.argv = [full_filename] + self.extra_args[1:]
218 sys.argv = [full_filename] + self.extra_args[1:]
218 # protect sys.argv from potential unicode strings on Python 2:
219 # protect sys.argv from potential unicode strings on Python 2:
219 if not py3compat.PY3:
220 if not py3compat.PY3:
220 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
221 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
221 try:
222 try:
222 if os.path.isfile(full_filename):
223 if os.path.isfile(full_filename):
223 if full_filename.endswith('.ipy'):
224 if full_filename.endswith('.ipy'):
224 self.log.info("Running file in user namespace: %s" %
225 self.log.info("Running file in user namespace: %s" %
225 full_filename)
226 full_filename)
226 self.shell.safe_execfile_ipy(full_filename)
227 self.shell.safe_execfile_ipy(full_filename)
227 else:
228 else:
228 # default to python, even without extension
229 # default to python, even without extension
229 self.log.info("Running file in user namespace: %s" %
230 self.log.info("Running file in user namespace: %s" %
230 full_filename)
231 full_filename)
231 # Ensure that __file__ is always defined to match Python behavior
232 # Ensure that __file__ is always defined to match Python behavior
232 self.shell.user_ns['__file__'] = fname
233 self.shell.user_ns['__file__'] = fname
233 try:
234 try:
234 self.shell.safe_execfile(full_filename, self.shell.user_ns)
235 self.shell.safe_execfile(full_filename, self.shell.user_ns)
235 finally:
236 finally:
236 del self.shell.user_ns['__file__']
237 del self.shell.user_ns['__file__']
237 finally:
238 finally:
238 sys.argv = save_argv
239 sys.argv = save_argv
239
240
240 def _run_startup_files(self):
241 def _run_startup_files(self):
241 """Run files from profile startup directory"""
242 """Run files from profile startup directory"""
242 startup_dir = self.profile_dir.startup_dir
243 startup_dir = self.profile_dir.startup_dir
243 startup_files = glob.glob(os.path.join(startup_dir, '*.py'))
244 startup_files = glob.glob(os.path.join(startup_dir, '*.py'))
244 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
245 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
245 if not startup_files:
246 if not startup_files:
246 return
247 return
247
248
248 self.log.debug("Running startup files from %s...", startup_dir)
249 self.log.debug("Running startup files from %s...", startup_dir)
249 try:
250 try:
250 for fname in sorted(startup_files):
251 for fname in sorted(startup_files):
251 self._exec_file(fname)
252 self._exec_file(fname)
252 except:
253 except:
253 self.log.warn("Unknown error in handling startup files:")
254 self.log.warn("Unknown error in handling startup files:")
254 self.shell.showtraceback()
255 self.shell.showtraceback()
255
256
256 def _run_exec_files(self):
257 def _run_exec_files(self):
257 """Run files from IPythonApp.exec_files"""
258 """Run files from IPythonApp.exec_files"""
258 if not self.exec_files:
259 if not self.exec_files:
259 return
260 return
260
261
261 self.log.debug("Running files in IPythonApp.exec_files...")
262 self.log.debug("Running files in IPythonApp.exec_files...")
262 try:
263 try:
263 for fname in self.exec_files:
264 for fname in self.exec_files:
264 self._exec_file(fname)
265 self._exec_file(fname)
265 except:
266 except:
266 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
267 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
267 self.shell.showtraceback()
268 self.shell.showtraceback()
268
269
269 def _run_cmd_line_code(self):
270 def _run_cmd_line_code(self):
270 """Run code or file specified at the command-line"""
271 """Run code or file specified at the command-line"""
271 if self.code_to_run:
272 if self.code_to_run:
272 line = self.code_to_run
273 line = self.code_to_run
273 try:
274 try:
274 self.log.info("Running code given at command line (c=): %s" %
275 self.log.info("Running code given at command line (c=): %s" %
275 line)
276 line)
276 self.shell.run_cell(line, store_history=False)
277 self.shell.run_cell(line, store_history=False)
277 except:
278 except:
278 self.log.warn("Error in executing line in user namespace: %s" %
279 self.log.warn("Error in executing line in user namespace: %s" %
279 line)
280 line)
280 self.shell.showtraceback()
281 self.shell.showtraceback()
281
282
282 # Like Python itself, ignore the second if the first of these is present
283 # Like Python itself, ignore the second if the first of these is present
283 elif self.file_to_run:
284 elif self.file_to_run:
284 fname = self.file_to_run
285 fname = self.file_to_run
285 try:
286 try:
286 self._exec_file(fname)
287 self._exec_file(fname)
287 except:
288 except:
288 self.log.warn("Error in executing file in user namespace: %s" %
289 self.log.warn("Error in executing file in user namespace: %s" %
289 fname)
290 fname)
290 self.shell.showtraceback()
291 self.shell.showtraceback()
291
292
@@ -1,188 +1,205 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 %store magic for lightweight persistence.
3 %store magic for lightweight persistence.
4
4
5 Stores variables, aliases and macros in IPython's database. Stored values will
5 Stores variables, aliases and macros in IPython's database.
6 be automatically restored whenever the extension is loaded.
7
6
8 To enable this functionality, list it in your default profile
7 To automatically restore stored variables at startup, add this to your
9 `ipython_config.py` file::
8 :file:`ipython_config.py` file::
10
9
11 c.InteractiveShellApp.extensions = ['storemagic']
10 c.StoreMagic.autorestore = True
12
13 Or to use it temporarily, run this in your IPython session::
14
15 %load_ext storemagic
16
11
17 """
12 """
18
13
19 from IPython.core.error import TryNext, UsageError
14 from IPython.core.error import TryNext, UsageError
15 from IPython.core.plugin import Plugin
16 from IPython.testing.skipdoctest import skip_doctest
20 from IPython.utils import pickleshare
17 from IPython.utils import pickleshare
18 from IPython.utils.traitlets import Bool, Instance
21
19
22 import inspect,pickle,os,sys,textwrap
20 import inspect,pickle,os,sys,textwrap
23 from IPython.core.fakemodule import FakeModule
21 from IPython.core.fakemodule import FakeModule
24
22
25 def restore_aliases(ip):
23 def restore_aliases(ip):
26 staliases = ip.db.get('stored_aliases', {})
24 staliases = ip.db.get('stored_aliases', {})
27 for k,v in staliases.items():
25 for k,v in staliases.items():
28 #print "restore alias",k,v # dbg
26 #print "restore alias",k,v # dbg
29 #self.alias_table[k] = v
27 #self.alias_table[k] = v
30 ip.alias_manager.define_alias(k,v)
28 ip.alias_manager.define_alias(k,v)
31
29
32
30
33 def refresh_variables(ip):
31 def refresh_variables(ip):
34 db = ip.db
32 db = ip.db
35 for key in db.keys('autorestore/*'):
33 for key in db.keys('autorestore/*'):
36 # strip autorestore
34 # strip autorestore
37 justkey = os.path.basename(key)
35 justkey = os.path.basename(key)
38 try:
36 try:
39 obj = db[key]
37 obj = db[key]
40 except KeyError:
38 except KeyError:
41 print "Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey
39 print "Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey
42 print "The error was:",sys.exc_info()[0]
40 print "The error was:",sys.exc_info()[0]
43 else:
41 else:
44 #print "restored",justkey,"=",obj #dbg
42 #print "restored",justkey,"=",obj #dbg
45 ip.user_ns[justkey] = obj
43 ip.user_ns[justkey] = obj
46
44
47
45
48 def restore_dhist(ip):
46 def restore_dhist(ip):
49 ip.user_ns['_dh'] = ip.db.get('dhist',[])
47 ip.user_ns['_dh'] = ip.db.get('dhist',[])
50
48
51 def restore_data(ip):
49 def restore_data(ip):
52 refresh_variables(ip)
50 refresh_variables(ip)
53 restore_aliases(ip)
51 restore_aliases(ip)
54 restore_dhist(ip)
52 restore_dhist(ip)
55
53
54 @skip_doctest
56 def magic_store(self, parameter_s=''):
55 def magic_store(self, parameter_s=''):
57 """Lightweight persistence for python variables.
56 """Lightweight persistence for python variables.
58
57
59 Example::
58 Example::
60
59
61 In [1]: l = ['hello',10,'world']
60 In [1]: l = ['hello',10,'world']
62 In [2]: %store l
61 In [2]: %store l
63 In [3]: exit
62 In [3]: exit
64
63
65 (IPython session is closed and started again...)
64 (IPython session is closed and started again...)
66
65
67 ville@badger:~$ ipython
66 ville@badger:~$ ipython
68 In [1]: l
67 In [1]: l
69 Out[1]: ['hello', 10, 'world']
68 Out[1]: ['hello', 10, 'world']
70
69
71 Usage:
70 Usage:
72
71
73 * ``%store`` - Show list of all variables and their current values
72 * ``%store`` - Show list of all variables and their current values
74 * ``%store spam`` - Store the *current* value of the variable spam to disk
73 * ``%store spam`` - Store the *current* value of the variable spam to disk
75 * ``%store -d spam`` - Remove the variable and its value from storage
74 * ``%store -d spam`` - Remove the variable and its value from storage
76 * ``%store -z`` - Remove all variables from storage
75 * ``%store -z`` - Remove all variables from storage
77 * ``%store -r`` - Refresh all variables from store (delete current vals)
76 * ``%store -r`` - Refresh all variables from store (delete current vals)
78 * ``%store foo >a.txt`` - Store value of foo to new file a.txt
77 * ``%store foo >a.txt`` - Store value of foo to new file a.txt
79 * ``%store foo >>a.txt`` - Append value of foo to file a.txt
78 * ``%store foo >>a.txt`` - Append value of foo to file a.txt
80
79
81 It should be noted that if you change the value of a variable, you
80 It should be noted that if you change the value of a variable, you
82 need to %store it again if you want to persist the new value.
81 need to %store it again if you want to persist the new value.
83
82
84 Note also that the variables will need to be pickleable; most basic
83 Note also that the variables will need to be pickleable; most basic
85 python types can be safely %store'd.
84 python types can be safely %store'd.
86
85
87 Also aliases can be %store'd across sessions.
86 Also aliases can be %store'd across sessions.
88 """
87 """
89
88
90 opts,argsl = self.parse_options(parameter_s,'drz',mode='string')
89 opts,argsl = self.parse_options(parameter_s,'drz',mode='string')
91 args = argsl.split(None,1)
90 args = argsl.split(None,1)
92 ip = self.shell
91 ip = self.shell
93 db = ip.db
92 db = ip.db
94 # delete
93 # delete
95 if opts.has_key('d'):
94 if opts.has_key('d'):
96 try:
95 try:
97 todel = args[0]
96 todel = args[0]
98 except IndexError:
97 except IndexError:
99 raise UsageError('You must provide the variable to forget')
98 raise UsageError('You must provide the variable to forget')
100 else:
99 else:
101 try:
100 try:
102 del db['autorestore/' + todel]
101 del db['autorestore/' + todel]
103 except:
102 except:
104 raise UsageError("Can't delete variable '%s'" % todel)
103 raise UsageError("Can't delete variable '%s'" % todel)
105 # reset
104 # reset
106 elif opts.has_key('z'):
105 elif opts.has_key('z'):
107 for k in db.keys('autorestore/*'):
106 for k in db.keys('autorestore/*'):
108 del db[k]
107 del db[k]
109
108
110 elif opts.has_key('r'):
109 elif opts.has_key('r'):
111 refresh_variables(ip)
110 refresh_variables(ip)
112
111
113
112
114 # run without arguments -> list variables & values
113 # run without arguments -> list variables & values
115 elif not args:
114 elif not args:
116 vars = self.db.keys('autorestore/*')
115 vars = self.db.keys('autorestore/*')
117 vars.sort()
116 vars.sort()
118 if vars:
117 if vars:
119 size = max(map(len,vars))
118 size = max(map(len,vars))
120 else:
119 else:
121 size = 0
120 size = 0
122
121
123 print 'Stored variables and their in-db values:'
122 print 'Stored variables and their in-db values:'
124 fmt = '%-'+str(size)+'s -> %s'
123 fmt = '%-'+str(size)+'s -> %s'
125 get = db.get
124 get = db.get
126 for var in vars:
125 for var in vars:
127 justkey = os.path.basename(var)
126 justkey = os.path.basename(var)
128 # print 30 first characters from every var
127 # print 30 first characters from every var
129 print fmt % (justkey,repr(get(var,'<unavailable>'))[:50])
128 print fmt % (justkey,repr(get(var,'<unavailable>'))[:50])
130
129
131 # default action - store the variable
130 # default action - store the variable
132 else:
131 else:
133 # %store foo >file.txt or >>file.txt
132 # %store foo >file.txt or >>file.txt
134 if len(args) > 1 and args[1].startswith('>'):
133 if len(args) > 1 and args[1].startswith('>'):
135 fnam = os.path.expanduser(args[1].lstrip('>').lstrip())
134 fnam = os.path.expanduser(args[1].lstrip('>').lstrip())
136 if args[1].startswith('>>'):
135 if args[1].startswith('>>'):
137 fil = open(fnam,'a')
136 fil = open(fnam,'a')
138 else:
137 else:
139 fil = open(fnam,'w')
138 fil = open(fnam,'w')
140 obj = ip.ev(args[0])
139 obj = ip.ev(args[0])
141 print "Writing '%s' (%s) to file '%s'." % (args[0],
140 print "Writing '%s' (%s) to file '%s'." % (args[0],
142 obj.__class__.__name__, fnam)
141 obj.__class__.__name__, fnam)
143
142
144
143
145 if not isinstance (obj,basestring):
144 if not isinstance (obj,basestring):
146 from pprint import pprint
145 from pprint import pprint
147 pprint(obj,fil)
146 pprint(obj,fil)
148 else:
147 else:
149 fil.write(obj)
148 fil.write(obj)
150 if not obj.endswith('\n'):
149 if not obj.endswith('\n'):
151 fil.write('\n')
150 fil.write('\n')
152
151
153 fil.close()
152 fil.close()
154 return
153 return
155
154
156 # %store foo
155 # %store foo
157 try:
156 try:
158 obj = ip.user_ns[args[0]]
157 obj = ip.user_ns[args[0]]
159 except KeyError:
158 except KeyError:
160 # it might be an alias
159 # it might be an alias
161 # This needs to be refactored to use the new AliasManager stuff.
160 # This needs to be refactored to use the new AliasManager stuff.
162 if args[0] in self.alias_manager:
161 if args[0] in self.alias_manager:
163 name = args[0]
162 name = args[0]
164 nargs, cmd = self.alias_manager.alias_table[ name ]
163 nargs, cmd = self.alias_manager.alias_table[ name ]
165 staliases = db.get('stored_aliases',{})
164 staliases = db.get('stored_aliases',{})
166 staliases[ name ] = cmd
165 staliases[ name ] = cmd
167 db['stored_aliases'] = staliases
166 db['stored_aliases'] = staliases
168 print "Alias stored: %s (%s)" % (name, cmd)
167 print "Alias stored: %s (%s)" % (name, cmd)
169 return
168 return
170 else:
169 else:
171 raise UsageError("Unknown variable '%s'" % args[0])
170 raise UsageError("Unknown variable '%s'" % args[0])
172
171
173 else:
172 else:
174 if isinstance(inspect.getmodule(obj), FakeModule):
173 if isinstance(inspect.getmodule(obj), FakeModule):
175 print textwrap.dedent("""\
174 print textwrap.dedent("""\
176 Warning:%s is %s
175 Warning:%s is %s
177 Proper storage of interactively declared classes (or instances
176 Proper storage of interactively declared classes (or instances
178 of those classes) is not possible! Only instances
177 of those classes) is not possible! Only instances
179 of classes in real modules on file system can be %%store'd.
178 of classes in real modules on file system can be %%store'd.
180 """ % (args[0], obj) )
179 """ % (args[0], obj) )
181 return
180 return
182 #pickled = pickle.dumps(obj)
181 #pickled = pickle.dumps(obj)
183 self.db[ 'autorestore/' + args[0] ] = obj
182 self.db[ 'autorestore/' + args[0] ] = obj
184 print "Stored '%s' (%s)" % (args[0], obj.__class__.__name__)
183 print "Stored '%s' (%s)" % (args[0], obj.__class__.__name__)
185
184
185
186 class StoreMagic(Plugin):
187 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
188 autorestore = Bool(False, config=True)
189
190 def __init__(self, shell, config):
191 super(StoreMagic, self).__init__(shell=shell, config=config)
192 shell.define_magic('store', magic_store)
193
194 if self.autorestore:
195 restore_data(shell)
196
197 _loaded = False
198
186 def load_ipython_extension(ip):
199 def load_ipython_extension(ip):
187 ip.define_magic('store', magic_store)
200 """Load the extension in IPython."""
188 restore_data(ip)
201 global _loaded
202 if not _loaded:
203 plugin = StoreMagic(shell=ip, config=ip.config)
204 ip.plugin_manager.register_plugin('storemagic', plugin)
205 _loaded = True
@@ -1,154 +1,155 b''
1 ================================================
1 ================================================
2 Development version
2 Development version
3 ================================================
3 ================================================
4
4
5 The changes listed here are a brief summary of the substantial work on IPython
5 The changes listed here are a brief summary of the substantial work on IPython
6 since the 0.11.x release series. For more details, please consult the actual
6 since the 0.11.x release series. For more details, please consult the actual
7 source.
7 source.
8
8
9 Main `ipython` branch
9 Main `ipython` branch
10 =====================
10 =====================
11
11
12
12
13 New features
13 New features
14 ------------
14 ------------
15
15
16 .. Expand on this:
16 .. Expand on this:
17 * **HTML Notebook**: A powerful new interface puts IPython in your browser. You
17 * **HTML Notebook**: A powerful new interface puts IPython in your browser. You
18 can start it with the command ``ipython notebook``. See :ref:`the Notebook
18 can start it with the command ``ipython notebook``. See :ref:`the Notebook
19 docs <htmlnotebook>` for technical details.
19 docs <htmlnotebook>` for technical details.
20
20
21 * **Tabbed QtConsole**: The QtConsole now supports starting multiple kernels in
21 * **Tabbed QtConsole**: The QtConsole now supports starting multiple kernels in
22 tabs, and has a menubar, so it looks and behaves more like a real application.
22 tabs, and has a menubar, so it looks and behaves more like a real application.
23 Keyboard enthusiasts can disable the menubar with ctrl-shift-M (:ghpull:`887`).
23 Keyboard enthusiasts can disable the menubar with ctrl-shift-M (:ghpull:`887`).
24
24
25 * **Python 3 compatibility**: IPython can now be installed from a single
25 * **Python 3 compatibility**: IPython can now be installed from a single
26 codebase on Python 2 and Python 3. The installation process for Python 3
26 codebase on Python 2 and Python 3. The installation process for Python 3
27 automatically runs 2to3. The same 'default' profile is now used for
27 automatically runs 2to3. The same 'default' profile is now used for
28 Python 2 and 3 (the previous version had a separate 'python3' profile).
28 Python 2 and 3 (the previous version had a separate 'python3' profile).
29
29
30 * **PyPy support**: The terminal interface to IPython now runs under
30 * **PyPy support**: The terminal interface to IPython now runs under
31 `PyPy <http://pypy.org/>`_.
31 `PyPy <http://pypy.org/>`_.
32
32
33 * **SSH Tunnels**: In 0.11, the :mod:`IPython.parallel` Client could tunnel its
33 * **SSH Tunnels**: In 0.11, the :mod:`IPython.parallel` Client could tunnel its
34 connections to the Controller via ssh. Now, the QtConsole :ref:`supports
34 connections to the Controller via ssh. Now, the QtConsole :ref:`supports
35 <ssh_tunnels>` ssh tunneling, as do parallel engines.
35 <ssh_tunnels>` ssh tunneling, as do parallel engines.
36
36
37 * **relaxed command-line parsing**: 0.11 was released with overly-strict
37 * **relaxed command-line parsing**: 0.11 was released with overly-strict
38 command-line parsing, preventing the ability to specify arguments with spaces,
38 command-line parsing, preventing the ability to specify arguments with spaces,
39 e.g. ``ipython --pylab qt`` or ``ipython -c "print 'hi'"``. This has
39 e.g. ``ipython --pylab qt`` or ``ipython -c "print 'hi'"``. This has
40 been fixed, by using argparse. The new parsing is a strict superset of 0.11, so
40 been fixed, by using argparse. The new parsing is a strict superset of 0.11, so
41 any commands in 0.11 should still work in 0.12.
41 any commands in 0.11 should still work in 0.12.
42
42
43 * **HistoryAccessor**: The :class:`~IPython.core.history.HistoryManager` class for
43 * **HistoryAccessor**: The :class:`~IPython.core.history.HistoryManager` class for
44 interacting with your IPython SQLite history database has been split, adding
44 interacting with your IPython SQLite history database has been split, adding
45 a parent :class:`~IPython.core.history.HistoryAccessor` class, so that users can
45 a parent :class:`~IPython.core.history.HistoryAccessor` class, so that users can
46 write code to access and search their IPython history without being in an IPython
46 write code to access and search their IPython history without being in an IPython
47 session (:ghpull:`824`).
47 session (:ghpull:`824`).
48
48
49 * **kernel %gui and %pylab**: The ``%gui`` and ``%pylab`` magics have been restored
49 * **kernel %gui and %pylab**: The ``%gui`` and ``%pylab`` magics have been restored
50 to the IPython kernel (e.g. in the qtconsole or notebook). This allows activation
50 to the IPython kernel (e.g. in the qtconsole or notebook). This allows activation
51 of pylab-mode, or eventloop integration after starting the kernel, which was
51 of pylab-mode, or eventloop integration after starting the kernel, which was
52 unavailable in 0.11. Unlike in the terminal, this can be set only once, and
52 unavailable in 0.11. Unlike in the terminal, this can be set only once, and
53 cannot be changed.
53 cannot be changed.
54
54
55 * **%config**: A new ``%config`` magic has been added, giving easy access to the
55 * **%config**: A new ``%config`` magic has been added, giving easy access to the
56 IPython configuration system at runtime (:ghpull:`923`).
56 IPython configuration system at runtime (:ghpull:`923`).
57
57
58 * **Standalone Kernel**: ``ipython kernel`` subcommand has been added, to allow
58 * **Standalone Kernel**: ``ipython kernel`` subcommand has been added, to allow
59 starting a standalone kernel, that can be used with various frontends.
59 starting a standalone kernel, that can be used with various frontends.
60
60
61 * **Multiline History**: Multiline readline history has been restored to the
61 * **Multiline History**: Multiline readline history has been restored to the
62 Terminal frontend by default (:ghpull:`838`).
62 Terminal frontend by default (:ghpull:`838`).
63
63
64 * **%store**: The ``%store`` magic from earlier versions has been updated and
64 * **%store**: The ``%store`` magic from earlier versions has been updated and
65 placed in an extension, :ref:`extensions_storemagic`. Add 'storemagic' to ``c.InteractiveShellApp.extensions``
65 re-enabled (:ref:`extensions_storemagic`; :ghpull:`1029`). To autorestore
66 in ipython_config.py to enable it (:ghpull:`1029`).
66 stored variables on startup, specify ``c.StoreMagic.autorestore = True`` in
67 :file:`ipython_config.py`.
67
68
68
69
69
70
70 Major Bugs fixed
71 Major Bugs fixed
71 ----------------
72 ----------------
72
73
73 * Simple configuration errors should no longer crash IPython. In 0.11, errors in
74 * Simple configuration errors should no longer crash IPython. In 0.11, errors in
74 config files, as well as invalid trait values, could crash IPython. Now, such
75 config files, as well as invalid trait values, could crash IPython. Now, such
75 errors are reported, and help is displayed.
76 errors are reported, and help is displayed.
76
77
77 * Certain SyntaxErrors no longer crash IPython (e.g. just typing keywords, such as
78 * Certain SyntaxErrors no longer crash IPython (e.g. just typing keywords, such as
78 ``return``, ``break``, etc.). See :ghissue:`704`.
79 ``return``, ``break``, etc.). See :ghissue:`704`.
79
80
80 * IPython path utils, such as :func:`~IPython.utils.path.get_ipython_dir` now check
81 * IPython path utils, such as :func:`~IPython.utils.path.get_ipython_dir` now check
81 for write permissions, so IPython should function on systems where the default
82 for write permissions, so IPython should function on systems where the default
82 path resolution might point to a read-only location, such as ``HOMESHARE`` on
83 path resolution might point to a read-only location, such as ``HOMESHARE`` on
83 Windows (:ghissue:`669`).
84 Windows (:ghissue:`669`).
84
85
85 * :func:`raw_input` now works in the kernel when multiple frontends are in use. The
86 * :func:`raw_input` now works in the kernel when multiple frontends are in use. The
86 request will be sent to the frontend that made the request, and an exception is
87 request will be sent to the frontend that made the request, and an exception is
87 raised if that frontend does not support stdin requests (e.g. the notebook)
88 raised if that frontend does not support stdin requests (e.g. the notebook)
88 (:ghissue:`673`).
89 (:ghissue:`673`).
89
90
90 * :mod:`zmq` version detection no longer uses simple lexicographical comparison to
91 * :mod:`zmq` version detection no longer uses simple lexicographical comparison to
91 check minimum version, which prevents 0.11 from working with pyzmq-2.1.10
92 check minimum version, which prevents 0.11 from working with pyzmq-2.1.10
92 (:ghpull:`758`).
93 (:ghpull:`758`).
93
94
94 * A bug in PySide < 1.0.7 caused crashes on OSX when tooltips were shown
95 * A bug in PySide < 1.0.7 caused crashes on OSX when tooltips were shown
95 (:ghissue:`711`). these tooltips are now disabled on old PySide (:ghpull:`963`).
96 (:ghissue:`711`). these tooltips are now disabled on old PySide (:ghpull:`963`).
96
97
97 * IPython no longer crashes when started on recent versions of Python 3 in
98 * IPython no longer crashes when started on recent versions of Python 3 in
98 Windows (:ghissue:`737`).
99 Windows (:ghissue:`737`).
99
100
100 * Instances of classes defined interactively can now be pickled (:ghissue:`29`;
101 * Instances of classes defined interactively can now be pickled (:ghissue:`29`;
101 :ghpull:`648`). Note that pickling saves a reference to the class definition,
102 :ghpull:`648`). Note that pickling saves a reference to the class definition,
102 so unpickling the instances will only work where the class has been defined.
103 so unpickling the instances will only work where the class has been defined.
103
104
104 .. * use bullet list
105 .. * use bullet list
105
106
106 Backwards incompatible changes
107 Backwards incompatible changes
107 ------------------------------
108 ------------------------------
108
109
109 * IPython connection information is no longer specified via ip/port directly,
110 * IPython connection information is no longer specified via ip/port directly,
110 rather via json connection files. These files are stored in the security
111 rather via json connection files. These files are stored in the security
111 directory, and enable us to turn on HMAC message authentication by default,
112 directory, and enable us to turn on HMAC message authentication by default,
112 significantly improving the security of kernels. Various utility functions
113 significantly improving the security of kernels. Various utility functions
113 have been added to :mod:`IPython.lib.kernel`, for easier connecting to existing
114 have been added to :mod:`IPython.lib.kernel`, for easier connecting to existing
114 kernels.
115 kernels.
115
116
116 * :class:`~IPython.zmq.kernelmanager.KernelManager` now has one ip, and several port
117 * :class:`~IPython.zmq.kernelmanager.KernelManager` now has one ip, and several port
117 traits, rather than several ip/port pair ``_addr`` traits. This better matches the
118 traits, rather than several ip/port pair ``_addr`` traits. This better matches the
118 rest of the code, where the ip cannot not be set separately for each channel.
119 rest of the code, where the ip cannot not be set separately for each channel.
119
120
120 * Custom prompts are now configured using a new class,
121 * Custom prompts are now configured using a new class,
121 :class:`~IPython.core.prompts.PromptManager`, which has traits for :attr:`in_template`,
122 :class:`~IPython.core.prompts.PromptManager`, which has traits for :attr:`in_template`,
122 :attr:`in2_template` (the ``...:`` continuation prompt), :attr:`out_template`
123 :attr:`in2_template` (the ``...:`` continuation prompt), :attr:`out_template`
123 and :attr:`rewrite_template`. This uses Python's string formatting system, so
124 and :attr:`rewrite_template`. This uses Python's string formatting system, so
124 you can use ``{time}`` and ``{cwd}``, although we have preserved the abbreviations
125 you can use ``{time}`` and ``{cwd}``, although we have preserved the abbreviations
125 from previous versions, e.g. ``\#`` (prompt number) and ``\w`` (working
126 from previous versions, e.g. ``\#`` (prompt number) and ``\w`` (working
126 directory). For the list of available fields, refer to the source of
127 directory). For the list of available fields, refer to the source of
127 :file:`IPython/core/prompts.py`.
128 :file:`IPython/core/prompts.py`.
128
129
129 * The class inheritance of the Launchers in :mod:`IPython.parallel.apps.launcher`
130 * The class inheritance of the Launchers in :mod:`IPython.parallel.apps.launcher`
130 used by ipcluster has changed, so that trait names are more consistent across
131 used by ipcluster has changed, so that trait names are more consistent across
131 batch systems. This may require a few renames in your config files, if you
132 batch systems. This may require a few renames in your config files, if you
132 customized the command-line args for launching controllers and engines. The
133 customized the command-line args for launching controllers and engines. The
133 configurable names have also been changed to be clearer that they point to class
134 configurable names have also been changed to be clearer that they point to class
134 names, and can now be specified by name only, rather than requiring the full
135 names, and can now be specified by name only, rather than requiring the full
135 import path of each class, e.g.::
136 import path of each class, e.g.::
136
137
137 IPClusterEngines.engine_launcher = 'IPython.parallel.apps.launcher.MPIExecEngineSetLauncher'
138 IPClusterEngines.engine_launcher = 'IPython.parallel.apps.launcher.MPIExecEngineSetLauncher'
138 IPClusterStart.controller_launcher = 'IPython.parallel.apps.launcher.SSHControllerLauncher'
139 IPClusterStart.controller_launcher = 'IPython.parallel.apps.launcher.SSHControllerLauncher'
139
140
140 would now be specified as::
141 would now be specified as::
141
142
142 IPClusterEngines.engine_launcher_class = 'MPIExec'
143 IPClusterEngines.engine_launcher_class = 'MPIExec'
143 IPClusterStart.controller_launcher_class = 'SSH'
144 IPClusterStart.controller_launcher_class = 'SSH'
144
145
145 The full path will still work, and is necessary for using custom launchers not in
146 The full path will still work, and is necessary for using custom launchers not in
146 IPython's launcher module.
147 IPython's launcher module.
147
148
148 * For embedding a shell, note that the parameter ``user_global_ns`` has been
149 * For embedding a shell, note that the parameter ``user_global_ns`` has been
149 replaced by ``user_module``, and expects a module-like object, rather than
150 replaced by ``user_module``, and expects a module-like object, rather than
150 a namespace dict. The ``user_ns`` parameter works the same way as before, and
151 a namespace dict. The ``user_ns`` parameter works the same way as before, and
151 calling :func:`~IPython.frontend.terminal.embed.embed` with no arguments still
152 calling :func:`~IPython.frontend.terminal.embed.embed` with no arguments still
152 works the same way.
153 works the same way.
153
154
154 .. * use bullet list
155 .. * use bullet list
General Comments 0
You need to be logged in to leave comments. Login now