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

1# -*- coding: utf-8 -*- 

2""" 

3%store magic for lightweight persistence. 

4 

5Stores variables, aliases and macros in IPython's database. 

6 

7To automatically restore stored variables at startup, add this to your 

8:file:`ipython_config.py` file:: 

9 

10 c.StoreMagics.autorestore = True 

11""" 

12 

13# Copyright (c) IPython Development Team. 

14# Distributed under the terms of the Modified BSD License. 

15 

16import inspect, os, sys, textwrap 

17 

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 

22 

23 

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]) 

33 

34 

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 

48 

49 

50def restore_dhist(ip): 

51 ip.user_ns['_dh'] = ip.db.get('dhist',[]) 

52 

53 

54def restore_data(ip): 

55 refresh_variables(ip) 

56 restore_aliases(ip) 

57 restore_dhist(ip) 

58 

59 

60@magics_class 

61class StoreMagics(Magics): 

62 """Lightweight persistence for python variables. 

63 

64 Provides the %store magic.""" 

65 

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) 

71 

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) 

77 

78 @skip_doctest 

79 @line_magic 

80 def store(self, parameter_s=''): 

81 """Lightweight persistence for python variables. 

82 

83 Example:: 

84 

85 In [1]: l = ['hello',10,'world'] 

86 In [2]: %store l 

87 Stored 'l' (list) 

88 In [3]: exit 

89 

90 (IPython session is closed and started again...) 

91 

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'] 

98 

99 Usage: 

100 

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 

113 

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. 

116 

117 Note also that the variables will need to be pickleable; most basic 

118 python types can be safely %store'd. 

119 

120 Also aliases can be %store'd across sessions. 

121 To remove an alias from the storage, use the %unalias magic. 

122 """ 

123 

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] 

143 

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) 

158 

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 

167 

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])) 

175 

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)) 

189 

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') 

197 

198 return 

199 

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 

211 

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 

217 

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__)) 

231 

232 

233def load_ipython_extension(ip): 

234 """Load the extension in IPython.""" 

235 ip.register_magics(StoreMagics) 

236