| | |
| | """ |
| | %store magic for lightweight persistence. |
| | |
| | Stores variables, aliases and macros in IPython's database. |
| | |
| | To automatically restore stored variables at startup, add this to your |
| | :file:`ipython_config.py` file:: |
| | |
| | c.StoreMagics.autorestore = True |
| | """ |
| |
|
| | |
| | |
| |
|
| | import inspect, os, sys, textwrap |
| |
|
| | from IPython.core.error import UsageError |
| | from IPython.core.magic import Magics, magics_class, line_magic |
| | from IPython.testing.skipdoctest import skip_doctest |
| | from traitlets import Bool |
| |
|
| |
|
| | def restore_aliases(ip, alias=None): |
| | staliases = ip.db.get('stored_aliases', {}) |
| | if alias is None: |
| | for k,v in staliases.items(): |
| | |
| | |
| | ip.alias_manager.define_alias(k,v) |
| | else: |
| | ip.alias_manager.define_alias(alias, staliases[alias]) |
| |
|
| |
|
| | def refresh_variables(ip): |
| | db = ip.db |
| | for key in db.keys('autorestore/*'): |
| | |
| | justkey = os.path.basename(key) |
| | try: |
| | obj = db[key] |
| | except KeyError: |
| | print("Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey) |
| | print("The error was:", sys.exc_info()[0]) |
| | else: |
| | |
| | ip.user_ns[justkey] = obj |
| |
|
| |
|
| | def restore_dhist(ip): |
| | ip.user_ns['_dh'] = ip.db.get('dhist',[]) |
| |
|
| |
|
| | def restore_data(ip): |
| | refresh_variables(ip) |
| | restore_aliases(ip) |
| | restore_dhist(ip) |
| |
|
| |
|
| | @magics_class |
| | class StoreMagics(Magics): |
| | """Lightweight persistence for python variables. |
| | |
| | Provides the %store magic.""" |
| |
|
| | autorestore = Bool(False, help= |
| | """If True, any %store-d variables will be automatically restored |
| | when IPython starts. |
| | """ |
| | ).tag(config=True) |
| |
|
| | def __init__(self, shell): |
| | super(StoreMagics, self).__init__(shell=shell) |
| | self.shell.configurables.append(self) |
| | if self.autorestore: |
| | restore_data(self.shell) |
| |
|
| | @skip_doctest |
| | @line_magic |
| | def store(self, parameter_s=''): |
| | """Lightweight persistence for python variables. |
| | |
| | Example:: |
| | |
| | In [1]: l = ['hello',10,'world'] |
| | In [2]: %store l |
| | Stored 'l' (list) |
| | In [3]: exit |
| | |
| | (IPython session is closed and started again...) |
| | |
| | ville@badger:~$ ipython |
| | In [1]: l |
| | NameError: name 'l' is not defined |
| | In [2]: %store -r |
| | In [3]: l |
| | Out[3]: ['hello', 10, 'world'] |
| | |
| | Usage: |
| | |
| | * ``%store`` - Show list of all variables and their current |
| | values |
| | * ``%store spam bar`` - Store the *current* value of the variables spam |
| | and bar to disk |
| | * ``%store -d spam`` - Remove the variable and its value from storage |
| | * ``%store -z`` - Remove all variables from storage |
| | * ``%store -r`` - Refresh all variables, aliases and directory history |
| | from store (overwrite current vals) |
| | * ``%store -r spam bar`` - Refresh specified variables and aliases from store |
| | (delete current val) |
| | * ``%store foo >a.txt`` - Store value of foo to new file a.txt |
| | * ``%store foo >>a.txt`` - Append value of foo to file a.txt |
| | |
| | It should be noted that if you change the value of a variable, you |
| | need to %store it again if you want to persist the new value. |
| | |
| | Note also that the variables will need to be pickleable; most basic |
| | python types can be safely %store'd. |
| | |
| | Also aliases can be %store'd across sessions. |
| | To remove an alias from the storage, use the %unalias magic. |
| | """ |
| |
|
| | opts,argsl = self.parse_options(parameter_s,'drz',mode='string') |
| | args = argsl.split() |
| | ip = self.shell |
| | db = ip.db |
| | |
| | if 'd' in opts: |
| | try: |
| | todel = args[0] |
| | except IndexError as e: |
| | raise UsageError('You must provide the variable to forget') from e |
| | else: |
| | try: |
| | del db['autorestore/' + todel] |
| | except BaseException as e: |
| | raise UsageError("Can't delete variable '%s'" % todel) from e |
| | |
| | elif 'z' in opts: |
| | for k in db.keys('autorestore/*'): |
| | del db[k] |
| |
|
| | elif 'r' in opts: |
| | if args: |
| | for arg in args: |
| | try: |
| | obj = db['autorestore/' + arg] |
| | except KeyError: |
| | try: |
| | restore_aliases(ip, alias=arg) |
| | except KeyError: |
| | print("no stored variable or alias %s" % arg) |
| | else: |
| | ip.user_ns[arg] = obj |
| | else: |
| | restore_data(ip) |
| |
|
| | |
| | elif not args: |
| | vars = db.keys('autorestore/*') |
| | vars.sort() |
| | if vars: |
| | size = max(map(len, vars)) |
| | else: |
| | size = 0 |
| |
|
| | print('Stored variables and their in-db values:') |
| | fmt = '%-'+str(size)+'s -> %s' |
| | get = db.get |
| | for var in vars: |
| | justkey = os.path.basename(var) |
| | |
| | print(fmt % (justkey, repr(get(var, '<unavailable>'))[:50])) |
| |
|
| | |
| | else: |
| | |
| | if len(args) > 1 and args[1].startswith(">"): |
| | fnam = os.path.expanduser(args[1].lstrip(">").lstrip()) |
| | if args[1].startswith(">>"): |
| | fil = open(fnam, "a", encoding="utf-8") |
| | else: |
| | fil = open(fnam, "w", encoding="utf-8") |
| | with fil: |
| | obj = ip.ev(args[0]) |
| | print("Writing '%s' (%s) to file '%s'." % (args[0], |
| | obj.__class__.__name__, fnam)) |
| |
|
| | if not isinstance (obj, str): |
| | from pprint import pprint |
| | pprint(obj, fil) |
| | else: |
| | fil.write(obj) |
| | if not obj.endswith('\n'): |
| | fil.write('\n') |
| |
|
| | return |
| |
|
| | |
| | for arg in args: |
| | try: |
| | obj = ip.user_ns[arg] |
| | except KeyError: |
| | |
| | name = arg |
| | try: |
| | cmd = ip.alias_manager.retrieve_alias(name) |
| | except ValueError as e: |
| | raise UsageError("Unknown variable '%s'" % name) from e |
| |
|
| | staliases = db.get('stored_aliases',{}) |
| | staliases[name] = cmd |
| | db['stored_aliases'] = staliases |
| | print("Alias stored: %s (%s)" % (name, cmd)) |
| | return |
| |
|
| | else: |
| | modname = getattr(inspect.getmodule(obj), '__name__', '') |
| | if modname == '__main__': |
| | print(textwrap.dedent("""\ |
| | Warning:%s is %s |
| | Proper storage of interactively declared classes (or instances |
| | of those classes) is not possible! Only instances |
| | of classes in real modules on file system can be %%store'd. |
| | """ % (arg, obj) )) |
| | return |
| | |
| | db[ 'autorestore/' + arg ] = obj |
| | print("Stored '%s' (%s)" % (arg, obj.__class__.__name__)) |
| |
|
| |
|
| | def load_ipython_extension(ip): |
| | """Load the extension in IPython.""" |
| | ip.register_magics(StoreMagics) |
| |
|
| |
|