##// END OF EJS Templates
Added handling of multiple args to store -r and removed error message
Michael Shuffett -
Show More
@@ -1,224 +1,224 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.
5 Stores variables, aliases and macros in IPython's database.
6
6
7 To automatically restore stored variables at startup, add this to your
7 To automatically restore stored variables at startup, add this to your
8 :file:`ipython_config.py` file::
8 :file:`ipython_config.py` file::
9
9
10 c.StoreMagic.autorestore = True
10 c.StoreMagic.autorestore = True
11 """
11 """
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (c) 2012, The IPython Development Team.
13 # Copyright (c) 2012, The IPython Development Team.
14 #
14 #
15 # Distributed under the terms of the Modified BSD License.
15 # Distributed under the terms of the Modified BSD License.
16 #
16 #
17 # The full license is in the file COPYING.txt, distributed with this software.
17 # The full license is in the file COPYING.txt, distributed with this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 # Stdlib
24 # Stdlib
25 import inspect, os, sys, textwrap
25 import inspect, os, sys, textwrap
26
26
27 # Our own
27 # Our own
28 from IPython.core.error import UsageError
28 from IPython.core.error import UsageError
29 from IPython.core.fakemodule import FakeModule
29 from IPython.core.fakemodule import FakeModule
30 from IPython.core.magic import Magics, magics_class, line_magic
30 from IPython.core.magic import Magics, magics_class, line_magic
31 from IPython.testing.skipdoctest import skip_doctest
31 from IPython.testing.skipdoctest import skip_doctest
32
32
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 # Functions and classes
34 # Functions and classes
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36
36
37 def restore_aliases(ip):
37 def restore_aliases(ip):
38 staliases = ip.db.get('stored_aliases', {})
38 staliases = ip.db.get('stored_aliases', {})
39 for k,v in staliases.items():
39 for k,v in staliases.items():
40 #print "restore alias",k,v # dbg
40 #print "restore alias",k,v # dbg
41 #self.alias_table[k] = v
41 #self.alias_table[k] = v
42 ip.alias_manager.define_alias(k,v)
42 ip.alias_manager.define_alias(k,v)
43
43
44
44
45 def refresh_variables(ip):
45 def refresh_variables(ip):
46 db = ip.db
46 db = ip.db
47 for key in db.keys('autorestore/*'):
47 for key in db.keys('autorestore/*'):
48 # strip autorestore
48 # strip autorestore
49 justkey = os.path.basename(key)
49 justkey = os.path.basename(key)
50 try:
50 try:
51 obj = db[key]
51 obj = db[key]
52 except KeyError:
52 except KeyError:
53 print "Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey
53 print "Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey
54 print "The error was:", sys.exc_info()[0]
54 print "The error was:", sys.exc_info()[0]
55 else:
55 else:
56 #print "restored",justkey,"=",obj #dbg
56 #print "restored",justkey,"=",obj #dbg
57 ip.user_ns[justkey] = obj
57 ip.user_ns[justkey] = obj
58
58
59
59
60 def restore_dhist(ip):
60 def restore_dhist(ip):
61 ip.user_ns['_dh'] = ip.db.get('dhist',[])
61 ip.user_ns['_dh'] = ip.db.get('dhist',[])
62
62
63
63
64 def restore_data(ip):
64 def restore_data(ip):
65 refresh_variables(ip)
65 refresh_variables(ip)
66 restore_aliases(ip)
66 restore_aliases(ip)
67 restore_dhist(ip)
67 restore_dhist(ip)
68
68
69
69
70 @magics_class
70 @magics_class
71 class StoreMagics(Magics):
71 class StoreMagics(Magics):
72 """Lightweight persistence for python variables.
72 """Lightweight persistence for python variables.
73
73
74 Provides the %store magic."""
74 Provides the %store magic."""
75
75
76 @skip_doctest
76 @skip_doctest
77 @line_magic
77 @line_magic
78 def store(self, parameter_s=''):
78 def store(self, parameter_s=''):
79 """Lightweight persistence for python variables.
79 """Lightweight persistence for python variables.
80
80
81 Example::
81 Example::
82
82
83 In [1]: l = ['hello',10,'world']
83 In [1]: l = ['hello',10,'world']
84 In [2]: %store l
84 In [2]: %store l
85 In [3]: exit
85 In [3]: exit
86
86
87 (IPython session is closed and started again...)
87 (IPython session is closed and started again...)
88
88
89 ville@badger:~$ ipython
89 ville@badger:~$ ipython
90 In [1]: l
90 In [1]: l
91 Out[1]: ['hello', 10, 'world']
91 Out[1]: ['hello', 10, 'world']
92
92
93 Usage:
93 Usage:
94
94
95 * ``%store`` - Show list of all variables and their current
95 * ``%store`` - Show list of all variables and their current
96 values
96 values
97 * ``%store spam`` - Store the *current* value of the variable spam
97 * ``%store spam`` - Store the *current* value of the variable spam
98 to disk
98 to disk
99 * ``%store -d spam`` - Remove the variable and its value from storage
99 * ``%store -d spam`` - Remove the variable and its value from storage
100 * ``%store -z`` - Remove all variables from storage
100 * ``%store -z`` - Remove all variables from storage
101 * ``%store -r`` - Refresh all variables from store (delete
101 * ``%store -r`` - Refresh all variables from store (delete
102 current vals)
102 current vals)
103 * ``%store -r spam`` - Refresh specified variable from store (delete
103 * ``%store -r spam bar`` - Refresh specified variables from store
104 current val)
104 (delete current val)
105 * ``%store foo >a.txt`` - Store value of foo to new file a.txt
105 * ``%store foo >a.txt`` - Store value of foo to new file a.txt
106 * ``%store foo >>a.txt`` - Append value of foo to file a.txt
106 * ``%store foo >>a.txt`` - Append value of foo to file a.txt
107
107
108 It should be noted that if you change the value of a variable, you
108 It should be noted that if you change the value of a variable, you
109 need to %store it again if you want to persist the new value.
109 need to %store it again if you want to persist the new value.
110
110
111 Note also that the variables will need to be pickleable; most basic
111 Note also that the variables will need to be pickleable; most basic
112 python types can be safely %store'd.
112 python types can be safely %store'd.
113
113
114 Also aliases can be %store'd across sessions.
114 Also aliases can be %store'd across sessions.
115 """
115 """
116
116
117 opts,argsl = self.parse_options(parameter_s,'drz',mode='string')
117 opts,argsl = self.parse_options(parameter_s,'drz',mode='string')
118 args = argsl.split(None,1)
118 args = argsl.split(None,1)
119 ip = self.shell
119 ip = self.shell
120 db = ip.db
120 db = ip.db
121 # delete
121 # delete
122 if 'd' in opts:
122 if 'd' in opts:
123 try:
123 try:
124 todel = args[0]
124 todel = args[0]
125 except IndexError:
125 except IndexError:
126 raise UsageError('You must provide the variable to forget')
126 raise UsageError('You must provide the variable to forget')
127 else:
127 else:
128 try:
128 try:
129 del db['autorestore/' + todel]
129 del db['autorestore/' + todel]
130 except:
130 except:
131 raise UsageError("Can't delete variable '%s'" % todel)
131 raise UsageError("Can't delete variable '%s'" % todel)
132 # reset
132 # reset
133 elif 'z' in opts:
133 elif 'z' in opts:
134 for k in db.keys('autorestore/*'):
134 for k in db.keys('autorestore/*'):
135 del db[k]
135 del db[k]
136
136
137 elif 'r' in opts:
137 elif 'r' in opts:
138 if args:
138 if args:
139 try:
139 for arg in args:
140 obj = db['autorestore/' + args[0]]
140 try:
141 except KeyError:
141 obj = db['autorestore/' + arg]
142 print "Unable to restore variable '%s', (use %%store -d to forget!)" % args[0]
142 except KeyError:
143 print "The error was:", sys.exc_info()[0]
143 print "no stored variable %s" % arg
144 else:
144 else:
145 ip.user_ns[args[0]] = obj
145 ip.user_ns[arg] = obj
146 else:
146 else:
147 refresh_variables(ip)
147 refresh_variables(ip)
148
148
149 # run without arguments -> list variables & values
149 # run without arguments -> list variables & values
150 elif not args:
150 elif not args:
151 vars = db.keys('autorestore/*')
151 vars = db.keys('autorestore/*')
152 vars.sort()
152 vars.sort()
153 if vars:
153 if vars:
154 size = max(map(len, vars))
154 size = max(map(len, vars))
155 else:
155 else:
156 size = 0
156 size = 0
157
157
158 print 'Stored variables and their in-db values:'
158 print 'Stored variables and their in-db values:'
159 fmt = '%-'+str(size)+'s -> %s'
159 fmt = '%-'+str(size)+'s -> %s'
160 get = db.get
160 get = db.get
161 for var in vars:
161 for var in vars:
162 justkey = os.path.basename(var)
162 justkey = os.path.basename(var)
163 # print 30 first characters from every var
163 # print 30 first characters from every var
164 print fmt % (justkey, repr(get(var, '<unavailable>'))[:50])
164 print fmt % (justkey, repr(get(var, '<unavailable>'))[:50])
165
165
166 # default action - store the variable
166 # default action - store the variable
167 else:
167 else:
168 # %store foo >file.txt or >>file.txt
168 # %store foo >file.txt or >>file.txt
169 if len(args) > 1 and args[1].startswith('>'):
169 if len(args) > 1 and args[1].startswith('>'):
170 fnam = os.path.expanduser(args[1].lstrip('>').lstrip())
170 fnam = os.path.expanduser(args[1].lstrip('>').lstrip())
171 if args[1].startswith('>>'):
171 if args[1].startswith('>>'):
172 fil = open(fnam, 'a')
172 fil = open(fnam, 'a')
173 else:
173 else:
174 fil = open(fnam, 'w')
174 fil = open(fnam, 'w')
175 obj = ip.ev(args[0])
175 obj = ip.ev(args[0])
176 print "Writing '%s' (%s) to file '%s'." % (args[0],
176 print "Writing '%s' (%s) to file '%s'." % (args[0],
177 obj.__class__.__name__, fnam)
177 obj.__class__.__name__, fnam)
178
178
179
179
180 if not isinstance (obj, basestring):
180 if not isinstance (obj, basestring):
181 from pprint import pprint
181 from pprint import pprint
182 pprint(obj, fil)
182 pprint(obj, fil)
183 else:
183 else:
184 fil.write(obj)
184 fil.write(obj)
185 if not obj.endswith('\n'):
185 if not obj.endswith('\n'):
186 fil.write('\n')
186 fil.write('\n')
187
187
188 fil.close()
188 fil.close()
189 return
189 return
190
190
191 # %store foo
191 # %store foo
192 try:
192 try:
193 obj = ip.user_ns[args[0]]
193 obj = ip.user_ns[args[0]]
194 except KeyError:
194 except KeyError:
195 # it might be an alias
195 # it might be an alias
196 # This needs to be refactored to use the new AliasManager stuff.
196 # This needs to be refactored to use the new AliasManager stuff.
197 if args[0] in ip.alias_manager:
197 if args[0] in ip.alias_manager:
198 name = args[0]
198 name = args[0]
199 nargs, cmd = ip.alias_manager.alias_table[ name ]
199 nargs, cmd = ip.alias_manager.alias_table[ name ]
200 staliases = db.get('stored_aliases',{})
200 staliases = db.get('stored_aliases',{})
201 staliases[ name ] = cmd
201 staliases[ name ] = cmd
202 db['stored_aliases'] = staliases
202 db['stored_aliases'] = staliases
203 print "Alias stored: %s (%s)" % (name, cmd)
203 print "Alias stored: %s (%s)" % (name, cmd)
204 return
204 return
205 else:
205 else:
206 raise UsageError("Unknown variable '%s'" % args[0])
206 raise UsageError("Unknown variable '%s'" % args[0])
207
207
208 else:
208 else:
209 if isinstance(inspect.getmodule(obj), FakeModule):
209 if isinstance(inspect.getmodule(obj), FakeModule):
210 print textwrap.dedent("""\
210 print textwrap.dedent("""\
211 Warning:%s is %s
211 Warning:%s is %s
212 Proper storage of interactively declared classes (or instances
212 Proper storage of interactively declared classes (or instances
213 of those classes) is not possible! Only instances
213 of those classes) is not possible! Only instances
214 of classes in real modules on file system can be %%store'd.
214 of classes in real modules on file system can be %%store'd.
215 """ % (args[0], obj) )
215 """ % (args[0], obj) )
216 return
216 return
217 #pickled = pickle.dumps(obj)
217 #pickled = pickle.dumps(obj)
218 db[ 'autorestore/' + args[0] ] = obj
218 db[ 'autorestore/' + args[0] ] = obj
219 print "Stored '%s' (%s)" % (args[0], obj.__class__.__name__)
219 print "Stored '%s' (%s)" % (args[0], obj.__class__.__name__)
220
220
221
221
222 def load_ipython_extension(ip):
222 def load_ipython_extension(ip):
223 """Load the extension in IPython."""
223 """Load the extension in IPython."""
224 ip.register_magics(StoreMagics)
224 ip.register_magics(StoreMagics)
General Comments 0
You need to be logged in to leave comments. Login now