##// END OF EJS Templates
pspersistence report UsageError's instead of crashing on 'error'
Ville M. Vainio -
Show More
@@ -1,183 +1,184 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 %store magic for lightweight persistence.
4 4
5 5 Stores variables, aliases etc. in PickleShare database.
6 6
7 7 $Id: iplib.py 1107 2006-01-30 19:02:20Z vivainio $
8 8 """
9 9
10 10 import IPython.ipapi
11 from IPython.ipapi import UsageError
11 12 ip = IPython.ipapi.get()
12 13
13 14 import pickleshare
14 15
15 16 import inspect,pickle,os,sys,textwrap
16 17 from IPython.FakeModule import FakeModule
17 18
18 19 def restore_aliases(self):
19 20 ip = self.getapi()
20 21 staliases = ip.db.get('stored_aliases', {})
21 22 for k,v in staliases.items():
22 23 #print "restore alias",k,v # dbg
23 24 #self.alias_table[k] = v
24 25 ip.defalias(k,v)
25 26
26 27
27 28 def refresh_variables(ip):
28 29 db = ip.db
29 30 for key in db.keys('autorestore/*'):
30 31 # strip autorestore
31 32 justkey = os.path.basename(key)
32 33 try:
33 34 obj = db[key]
34 35 except KeyError:
35 36 print "Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey
36 37 print "The error was:",sys.exc_info()[0]
37 38 else:
38 39 #print "restored",justkey,"=",obj #dbg
39 40 ip.user_ns[justkey] = obj
40 41
41 42
42 43 def restore_dhist(ip):
43 44 db = ip.db
44 45 ip.user_ns['_dh'] = db.get('dhist',[])
45 46
46 47 def restore_data(self):
47 48 ip = self.getapi()
48 49 refresh_variables(ip)
49 50 restore_aliases(self)
50 51 restore_dhist(self)
51 52 raise IPython.ipapi.TryNext
52 53
53 54 ip.set_hook('late_startup_hook', restore_data)
54 55
55 56 def magic_store(self, parameter_s=''):
56 57 """Lightweight persistence for python variables.
57 58
58 59 Example:
59 60
60 61 ville@badger[~]|1> A = ['hello',10,'world']\\
61 62 ville@badger[~]|2> %store A\\
62 63 ville@badger[~]|3> Exit
63 64
64 65 (IPython session is closed and started again...)
65 66
66 67 ville@badger:~$ ipython -p pysh\\
67 68 ville@badger[~]|1> print A
68 69
69 70 ['hello', 10, 'world']
70 71
71 72 Usage:
72 73
73 74 %store - Show list of all variables and their current values\\
74 75 %store <var> - Store the *current* value of the variable to disk\\
75 76 %store -d <var> - Remove the variable and its value from storage\\
76 77 %store -z - Remove all variables from storage\\
77 78 %store -r - Refresh all variables from store (delete current vals)\\
78 79 %store foo >a.txt - Store value of foo to new file a.txt\\
79 80 %store foo >>a.txt - Append value of foo to file a.txt\\
80 81
81 82 It should be noted that if you change the value of a variable, you
82 83 need to %store it again if you want to persist the new value.
83 84
84 85 Note also that the variables will need to be pickleable; most basic
85 86 python types can be safely %stored.
86 87
87 88 Also aliases can be %store'd across sessions.
88 89 """
89 90
90 91 opts,argsl = self.parse_options(parameter_s,'drz',mode='string')
91 92 args = argsl.split(None,1)
92 93 ip = self.getapi()
93 94 db = ip.db
94 95 # delete
95 96 if opts.has_key('d'):
96 97 try:
97 98 todel = args[0]
98 99 except IndexError:
99 error('You must provide the variable to forget')
100 raise UsageError('You must provide the variable to forget')
100 101 else:
101 102 try:
102 103 del db['autorestore/' + todel]
103 104 except:
104 error("Can't delete variable '%s'" % todel)
105 raise UsageError("Can't delete variable '%s'" % todel)
105 106 # reset
106 107 elif opts.has_key('z'):
107 108 for k in db.keys('autorestore/*'):
108 109 del db[k]
109 110
110 111 elif opts.has_key('r'):
111 112 refresh_variables(ip)
112 113
113 114
114 115 # run without arguments -> list variables & values
115 116 elif not args:
116 117 vars = self.db.keys('autorestore/*')
117 118 vars.sort()
118 119 if vars:
119 120 size = max(map(len,vars))
120 121 else:
121 122 size = 0
122 123
123 124 print 'Stored variables and their in-db values:'
124 125 fmt = '%-'+str(size)+'s -> %s'
125 126 get = db.get
126 127 for var in vars:
127 128 justkey = os.path.basename(var)
128 129 # print 30 first characters from every var
129 130 print fmt % (justkey,repr(get(var,'<unavailable>'))[:50])
130 131
131 132 # default action - store the variable
132 133 else:
133 134 # %store foo >file.txt or >>file.txt
134 135 if len(args) > 1 and args[1].startswith('>'):
135 136 fnam = os.path.expanduser(args[1].lstrip('>').lstrip())
136 137 if args[1].startswith('>>'):
137 138 fil = open(fnam,'a')
138 139 else:
139 140 fil = open(fnam,'w')
140 141 obj = ip.ev(args[0])
141 142 print "Writing '%s' (%s) to file '%s'." % (args[0],
142 143 obj.__class__.__name__, fnam)
143 144
144 145
145 146 if not isinstance (obj,basestring):
146 147 from pprint import pprint
147 148 pprint(obj,fil)
148 149 else:
149 150 fil.write(obj)
150 151 if not obj.endswith('\n'):
151 152 fil.write('\n')
152 153
153 154 fil.close()
154 155 return
155 156
156 157 # %store foo
157 158 try:
158 159 obj = ip.user_ns[args[0]]
159 160 except KeyError:
160 161 # it might be an alias
161 162 if args[0] in self.alias_table:
162 163 staliases = db.get('stored_aliases',{})
163 164 staliases[ args[0] ] = self.alias_table[ args[0] ]
164 165 db['stored_aliases'] = staliases
165 166 print "Alias stored:", args[0], self.alias_table[ args[0] ]
166 167 return
167 168 else:
168 print "Error: unknown variable '%s'" % args[0]
169 raise UsageError("Unknown variable '%s'" % args[0])
169 170
170 171 else:
171 172 if isinstance(inspect.getmodule(obj), FakeModule):
172 173 print textwrap.dedent("""\
173 174 Warning:%s is %s
174 175 Proper storage of interactively declared classes (or instances
175 176 of those classes) is not possible! Only instances
176 177 of classes in real modules on file system can be %%store'd.
177 178 """ % (args[0], obj) )
178 179 return
179 180 #pickled = pickle.dumps(obj)
180 181 self.db[ 'autorestore/' + args[0] ] = obj
181 182 print "Stored '%s' (%s)" % (args[0], obj.__class__.__name__)
182 183
183 184 ip.expose_magic('store',magic_store)
General Comments 0
You need to be logged in to leave comments. Login now