##// END OF EJS Templates
Merge pull request #11680 from switowski/2019-04-08-store-remove-alias-doc-improvement...
Matthias Bussonnier -
r25002:378022e1 merge
parent child Browse files
Show More
@@ -1,225 +1,226 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.StoreMagics.autorestore = True
10 c.StoreMagics.autorestore = True
11 """
11 """
12
12
13 # Copyright (c) IPython Development Team.
13 # Copyright (c) IPython Development Team.
14 # Distributed under the terms of the Modified BSD License.
14 # Distributed under the terms of the Modified BSD License.
15
15
16 import inspect, os, sys, textwrap
16 import inspect, os, sys, textwrap
17
17
18 from IPython.core.error import UsageError
18 from IPython.core.error import UsageError
19 from IPython.core.magic import Magics, magics_class, line_magic
19 from IPython.core.magic import Magics, magics_class, line_magic
20 from traitlets import Bool
20 from traitlets import Bool
21
21
22
22
23 def restore_aliases(ip):
23 def restore_aliases(ip):
24 staliases = ip.db.get('stored_aliases', {})
24 staliases = ip.db.get('stored_aliases', {})
25 for k,v in staliases.items():
25 for k,v in staliases.items():
26 #print "restore alias",k,v # dbg
26 #print "restore alias",k,v # dbg
27 #self.alias_table[k] = v
27 #self.alias_table[k] = v
28 ip.alias_manager.define_alias(k,v)
28 ip.alias_manager.define_alias(k,v)
29
29
30
30
31 def refresh_variables(ip):
31 def refresh_variables(ip):
32 db = ip.db
32 db = ip.db
33 for key in db.keys('autorestore/*'):
33 for key in db.keys('autorestore/*'):
34 # strip autorestore
34 # strip autorestore
35 justkey = os.path.basename(key)
35 justkey = os.path.basename(key)
36 try:
36 try:
37 obj = db[key]
37 obj = db[key]
38 except KeyError:
38 except KeyError:
39 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)
40 print("The error was:", sys.exc_info()[0])
40 print("The error was:", sys.exc_info()[0])
41 else:
41 else:
42 #print "restored",justkey,"=",obj #dbg
42 #print "restored",justkey,"=",obj #dbg
43 ip.user_ns[justkey] = obj
43 ip.user_ns[justkey] = obj
44
44
45
45
46 def restore_dhist(ip):
46 def restore_dhist(ip):
47 ip.user_ns['_dh'] = ip.db.get('dhist',[])
47 ip.user_ns['_dh'] = ip.db.get('dhist',[])
48
48
49
49
50 def restore_data(ip):
50 def restore_data(ip):
51 refresh_variables(ip)
51 refresh_variables(ip)
52 restore_aliases(ip)
52 restore_aliases(ip)
53 restore_dhist(ip)
53 restore_dhist(ip)
54
54
55
55
56 @magics_class
56 @magics_class
57 class StoreMagics(Magics):
57 class StoreMagics(Magics):
58 """Lightweight persistence for python variables.
58 """Lightweight persistence for python variables.
59
59
60 Provides the %store magic."""
60 Provides the %store magic."""
61
61
62 autorestore = Bool(False, help=
62 autorestore = Bool(False, help=
63 """If True, any %store-d variables will be automatically restored
63 """If True, any %store-d variables will be automatically restored
64 when IPython starts.
64 when IPython starts.
65 """
65 """
66 ).tag(config=True)
66 ).tag(config=True)
67
67
68 def __init__(self, shell):
68 def __init__(self, shell):
69 super(StoreMagics, self).__init__(shell=shell)
69 super(StoreMagics, self).__init__(shell=shell)
70 self.shell.configurables.append(self)
70 self.shell.configurables.append(self)
71 if self.autorestore:
71 if self.autorestore:
72 restore_data(self.shell)
72 restore_data(self.shell)
73
73
74 @line_magic
74 @line_magic
75 def store(self, parameter_s=''):
75 def store(self, parameter_s=''):
76 """Lightweight persistence for python variables.
76 """Lightweight persistence for python variables.
77
77
78 Example::
78 Example::
79
79
80 In [1]: l = ['hello',10,'world']
80 In [1]: l = ['hello',10,'world']
81 In [2]: %store l
81 In [2]: %store l
82 In [3]: exit
82 In [3]: exit
83
83
84 (IPython session is closed and started again...)
84 (IPython session is closed and started again...)
85
85
86 ville@badger:~$ ipython
86 ville@badger:~$ ipython
87 In [1]: l
87 In [1]: l
88 NameError: name 'l' is not defined
88 NameError: name 'l' is not defined
89 In [2]: %store -r
89 In [2]: %store -r
90 In [3]: l
90 In [3]: l
91 Out[3]: ['hello', 10, 'world']
91 Out[3]: ['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 (overwrite
101 * ``%store -r`` - Refresh all variables from store (overwrite
102 current vals)
102 current vals)
103 * ``%store -r spam bar`` - Refresh specified variables from store
103 * ``%store -r spam bar`` - Refresh specified variables from store
104 (delete 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 To remove an alias from the storage, use the %unalias magic.
115 """
116 """
116
117
117 opts,argsl = self.parse_options(parameter_s,'drz',mode='string')
118 opts,argsl = self.parse_options(parameter_s,'drz',mode='string')
118 args = argsl.split(None,1)
119 args = argsl.split(None,1)
119 ip = self.shell
120 ip = self.shell
120 db = ip.db
121 db = ip.db
121 # delete
122 # delete
122 if 'd' in opts:
123 if 'd' in opts:
123 try:
124 try:
124 todel = args[0]
125 todel = args[0]
125 except IndexError:
126 except IndexError:
126 raise UsageError('You must provide the variable to forget')
127 raise UsageError('You must provide the variable to forget')
127 else:
128 else:
128 try:
129 try:
129 del db['autorestore/' + todel]
130 del db['autorestore/' + todel]
130 except:
131 except:
131 raise UsageError("Can't delete variable '%s'" % todel)
132 raise UsageError("Can't delete variable '%s'" % todel)
132 # reset
133 # reset
133 elif 'z' in opts:
134 elif 'z' in opts:
134 for k in db.keys('autorestore/*'):
135 for k in db.keys('autorestore/*'):
135 del db[k]
136 del db[k]
136
137
137 elif 'r' in opts:
138 elif 'r' in opts:
138 if args:
139 if args:
139 for arg in args:
140 for arg in args:
140 try:
141 try:
141 obj = db['autorestore/' + arg]
142 obj = db['autorestore/' + arg]
142 except KeyError:
143 except KeyError:
143 print("no stored variable %s" % arg)
144 print("no stored variable %s" % arg)
144 else:
145 else:
145 ip.user_ns[arg] = obj
146 ip.user_ns[arg] = obj
146 else:
147 else:
147 restore_data(ip)
148 restore_data(ip)
148
149
149 # run without arguments -> list variables & values
150 # run without arguments -> list variables & values
150 elif not args:
151 elif not args:
151 vars = db.keys('autorestore/*')
152 vars = db.keys('autorestore/*')
152 vars.sort()
153 vars.sort()
153 if vars:
154 if vars:
154 size = max(map(len, vars))
155 size = max(map(len, vars))
155 else:
156 else:
156 size = 0
157 size = 0
157
158
158 print('Stored variables and their in-db values:')
159 print('Stored variables and their in-db values:')
159 fmt = '%-'+str(size)+'s -> %s'
160 fmt = '%-'+str(size)+'s -> %s'
160 get = db.get
161 get = db.get
161 for var in vars:
162 for var in vars:
162 justkey = os.path.basename(var)
163 justkey = os.path.basename(var)
163 # print 30 first characters from every var
164 # print 30 first characters from every var
164 print(fmt % (justkey, repr(get(var, '<unavailable>'))[:50]))
165 print(fmt % (justkey, repr(get(var, '<unavailable>'))[:50]))
165
166
166 # default action - store the variable
167 # default action - store the variable
167 else:
168 else:
168 # %store foo >file.txt or >>file.txt
169 # %store foo >file.txt or >>file.txt
169 if len(args) > 1 and args[1].startswith('>'):
170 if len(args) > 1 and args[1].startswith('>'):
170 fnam = os.path.expanduser(args[1].lstrip('>').lstrip())
171 fnam = os.path.expanduser(args[1].lstrip('>').lstrip())
171 if args[1].startswith('>>'):
172 if args[1].startswith('>>'):
172 fil = open(fnam, 'a')
173 fil = open(fnam, 'a')
173 else:
174 else:
174 fil = open(fnam, 'w')
175 fil = open(fnam, 'w')
175 with fil:
176 with fil:
176 obj = ip.ev(args[0])
177 obj = ip.ev(args[0])
177 print("Writing '%s' (%s) to file '%s'." % (args[0],
178 print("Writing '%s' (%s) to file '%s'." % (args[0],
178 obj.__class__.__name__, fnam))
179 obj.__class__.__name__, fnam))
179
180
180 if not isinstance (obj, str):
181 if not isinstance (obj, str):
181 from pprint import pprint
182 from pprint import pprint
182 pprint(obj, fil)
183 pprint(obj, fil)
183 else:
184 else:
184 fil.write(obj)
185 fil.write(obj)
185 if not obj.endswith('\n'):
186 if not obj.endswith('\n'):
186 fil.write('\n')
187 fil.write('\n')
187
188
188 return
189 return
189
190
190 # %store foo
191 # %store foo
191 try:
192 try:
192 obj = ip.user_ns[args[0]]
193 obj = ip.user_ns[args[0]]
193 except KeyError:
194 except KeyError:
194 # it might be an alias
195 # it might be an alias
195 name = args[0]
196 name = args[0]
196 try:
197 try:
197 cmd = ip.alias_manager.retrieve_alias(name)
198 cmd = ip.alias_manager.retrieve_alias(name)
198 except ValueError:
199 except ValueError:
199 raise UsageError("Unknown variable '%s'" % name)
200 raise UsageError("Unknown variable '%s'" % name)
200
201
201 staliases = db.get('stored_aliases',{})
202 staliases = db.get('stored_aliases',{})
202 staliases[name] = cmd
203 staliases[name] = cmd
203 db['stored_aliases'] = staliases
204 db['stored_aliases'] = staliases
204 print("Alias stored: %s (%s)" % (name, cmd))
205 print("Alias stored: %s (%s)" % (name, cmd))
205 return
206 return
206
207
207 else:
208 else:
208 modname = getattr(inspect.getmodule(obj), '__name__', '')
209 modname = getattr(inspect.getmodule(obj), '__name__', '')
209 if modname == '__main__':
210 if modname == '__main__':
210 print(textwrap.dedent("""\
211 print(textwrap.dedent("""\
211 Warning:%s is %s
212 Warning:%s is %s
212 Proper storage of interactively declared classes (or instances
213 Proper storage of interactively declared classes (or instances
213 of those classes) is not possible! Only instances
214 of those classes) is not possible! Only instances
214 of classes in real modules on file system can be %%store'd.
215 of classes in real modules on file system can be %%store'd.
215 """ % (args[0], obj) ))
216 """ % (args[0], obj) ))
216 return
217 return
217 #pickled = pickle.dumps(obj)
218 #pickled = pickle.dumps(obj)
218 db[ 'autorestore/' + args[0] ] = obj
219 db[ 'autorestore/' + args[0] ] = obj
219 print("Stored '%s' (%s)" % (args[0], obj.__class__.__name__))
220 print("Stored '%s' (%s)" % (args[0], obj.__class__.__name__))
220
221
221
222
222 def load_ipython_extension(ip):
223 def load_ipython_extension(ip):
223 """Load the extension in IPython."""
224 """Load the extension in IPython."""
224 ip.register_magics(StoreMagics)
225 ip.register_magics(StoreMagics)
225
226
General Comments 0
You need to be logged in to leave comments. Login now