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