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