Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/IPython/extensions/storemagic.py: 16%
116 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +0000
1# -*- coding: utf-8 -*-
2"""
3%store magic for lightweight persistence.
5Stores variables, aliases and macros in IPython's database.
7To automatically restore stored variables at startup, add this to your
8:file:`ipython_config.py` file::
10 c.StoreMagics.autorestore = True
11"""
13# Copyright (c) IPython Development Team.
14# Distributed under the terms of the Modified BSD License.
16import inspect, os, sys, textwrap
18from IPython.core.error import UsageError
19from IPython.core.magic import Magics, magics_class, line_magic
20from IPython.testing.skipdoctest import skip_doctest
21from traitlets import Bool
24def restore_aliases(ip, alias=None):
25 staliases = ip.db.get('stored_aliases', {})
26 if alias is None:
27 for k,v in staliases.items():
28 #print "restore alias",k,v # dbg
29 #self.alias_table[k] = v
30 ip.alias_manager.define_alias(k,v)
31 else:
32 ip.alias_manager.define_alias(alias, staliases[alias])
35def refresh_variables(ip):
36 db = ip.db
37 for key in db.keys('autorestore/*'):
38 # strip autorestore
39 justkey = os.path.basename(key)
40 try:
41 obj = db[key]
42 except KeyError:
43 print("Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey)
44 print("The error was:", sys.exc_info()[0])
45 else:
46 #print "restored",justkey,"=",obj #dbg
47 ip.user_ns[justkey] = obj
50def restore_dhist(ip):
51 ip.user_ns['_dh'] = ip.db.get('dhist',[])
54def restore_data(ip):
55 refresh_variables(ip)
56 restore_aliases(ip)
57 restore_dhist(ip)
60@magics_class
61class StoreMagics(Magics):
62 """Lightweight persistence for python variables.
64 Provides the %store magic."""
66 autorestore = Bool(False, help=
67 """If True, any %store-d variables will be automatically restored
68 when IPython starts.
69 """
70 ).tag(config=True)
72 def __init__(self, shell):
73 super(StoreMagics, self).__init__(shell=shell)
74 self.shell.configurables.append(self)
75 if self.autorestore:
76 restore_data(self.shell)
78 @skip_doctest
79 @line_magic
80 def store(self, parameter_s=''):
81 """Lightweight persistence for python variables.
83 Example::
85 In [1]: l = ['hello',10,'world']
86 In [2]: %store l
87 Stored 'l' (list)
88 In [3]: exit
90 (IPython session is closed and started again...)
92 ville@badger:~$ ipython
93 In [1]: l
94 NameError: name 'l' is not defined
95 In [2]: %store -r
96 In [3]: l
97 Out[3]: ['hello', 10, 'world']
99 Usage:
101 * ``%store`` - Show list of all variables and their current
102 values
103 * ``%store spam bar`` - Store the *current* value of the variables spam
104 and bar to disk
105 * ``%store -d spam`` - Remove the variable and its value from storage
106 * ``%store -z`` - Remove all variables from storage
107 * ``%store -r`` - Refresh all variables, aliases and directory history
108 from store (overwrite current vals)
109 * ``%store -r spam bar`` - Refresh specified variables and aliases from store
110 (delete current val)
111 * ``%store foo >a.txt`` - Store value of foo to new file a.txt
112 * ``%store foo >>a.txt`` - Append value of foo to file a.txt
114 It should be noted that if you change the value of a variable, you
115 need to %store it again if you want to persist the new value.
117 Note also that the variables will need to be pickleable; most basic
118 python types can be safely %store'd.
120 Also aliases can be %store'd across sessions.
121 To remove an alias from the storage, use the %unalias magic.
122 """
124 opts,argsl = self.parse_options(parameter_s,'drz',mode='string')
125 args = argsl.split()
126 ip = self.shell
127 db = ip.db
128 # delete
129 if 'd' in opts:
130 try:
131 todel = args[0]
132 except IndexError as e:
133 raise UsageError('You must provide the variable to forget') from e
134 else:
135 try:
136 del db['autorestore/' + todel]
137 except BaseException as e:
138 raise UsageError("Can't delete variable '%s'" % todel) from e
139 # reset
140 elif 'z' in opts:
141 for k in db.keys('autorestore/*'):
142 del db[k]
144 elif 'r' in opts:
145 if args:
146 for arg in args:
147 try:
148 obj = db['autorestore/' + arg]
149 except KeyError:
150 try:
151 restore_aliases(ip, alias=arg)
152 except KeyError:
153 print("no stored variable or alias %s" % arg)
154 else:
155 ip.user_ns[arg] = obj
156 else:
157 restore_data(ip)
159 # run without arguments -> list variables & values
160 elif not args:
161 vars = db.keys('autorestore/*')
162 vars.sort()
163 if vars:
164 size = max(map(len, vars))
165 else:
166 size = 0
168 print('Stored variables and their in-db values:')
169 fmt = '%-'+str(size)+'s -> %s'
170 get = db.get
171 for var in vars:
172 justkey = os.path.basename(var)
173 # print 30 first characters from every var
174 print(fmt % (justkey, repr(get(var, '<unavailable>'))[:50]))
176 # default action - store the variable
177 else:
178 # %store foo >file.txt or >>file.txt
179 if len(args) > 1 and args[1].startswith(">"):
180 fnam = os.path.expanduser(args[1].lstrip(">").lstrip())
181 if args[1].startswith(">>"):
182 fil = open(fnam, "a", encoding="utf-8")
183 else:
184 fil = open(fnam, "w", encoding="utf-8")
185 with fil:
186 obj = ip.ev(args[0])
187 print("Writing '%s' (%s) to file '%s'." % (args[0],
188 obj.__class__.__name__, fnam))
190 if not isinstance (obj, str):
191 from pprint import pprint
192 pprint(obj, fil)
193 else:
194 fil.write(obj)
195 if not obj.endswith('\n'):
196 fil.write('\n')
198 return
200 # %store foo
201 for arg in args:
202 try:
203 obj = ip.user_ns[arg]
204 except KeyError:
205 # it might be an alias
206 name = arg
207 try:
208 cmd = ip.alias_manager.retrieve_alias(name)
209 except ValueError as e:
210 raise UsageError("Unknown variable '%s'" % name) from e
212 staliases = db.get('stored_aliases',{})
213 staliases[name] = cmd
214 db['stored_aliases'] = staliases
215 print("Alias stored: %s (%s)" % (name, cmd))
216 return
218 else:
219 modname = getattr(inspect.getmodule(obj), '__name__', '')
220 if modname == '__main__':
221 print(textwrap.dedent("""\
222 Warning:%s is %s
223 Proper storage of interactively declared classes (or instances
224 of those classes) is not possible! Only instances
225 of classes in real modules on file system can be %%store'd.
226 """ % (arg, obj) ))
227 return
228 #pickled = pickle.dumps(obj)
229 db[ 'autorestore/' + arg ] = obj
230 print("Stored '%s' (%s)" % (arg, obj.__class__.__name__))
233def load_ipython_extension(ip):
234 """Load the extension in IPython."""
235 ip.register_magics(StoreMagics)