def cache(cell, path, vars=[],
          # HACK: this function implementing the magic's logic is testable
          # without IPython, by giving mock functions here instead of IPython
          # methods.
          ip_user_ns={}, ip_run_cell=None, ip_push=None, ip_clear_output=lambda : None,
          force=False, read=False, verbose=True):
    
    if not path:
        raise ValueError("The path needs to be specified as a first argument.")
    
    path = os.path.abspath(path)
    cell_md5 = hashlib.md5(cell.encode()).hexdigest()
        
    if do_save(path, force=force, read=read):
        # Capture the outputs of the cell.
        with capture_output_and_print() as io:
            try:
                ip_run_cell(cell)
            except:
                # Display input/output.
                io()
                return
        # Create the cache from the namespace.
        try:
            cached = {var: ip_user_ns[var] for var in vars}
        except KeyError:
            vars_missing = set(vars) - set(ip_user_ns.keys())
            vars_missing_str = ', '.join(["'{0:s}'".format(_) 
                for _ in vars_missing])
            raise ValueError(("Variable(s) {0:s} could not be found in the "
                              "interactive namespace").format(vars_missing_str))
        # Save the outputs in the cache.
        cached['_captured_io'] = save_captured_io(io)
        cached['_cell_md5'] = cell_md5
        # Save the cache in the pickle file.
        save_vars(path, cached)
        ip_clear_output() # clear away the temporary output and replace with the saved output (ideal?)
        if verbose:
            print("[Saved variables '{0:s}' to file '{1:s}'.]".format(
                ', '.join(vars), path))
        
    # If the cache file exists, and no --force mode, load the requested 
    # variables from the specified file into the interactive namespace.
    else:
        # Load the variables from cache in inject them in the namespace.
        force_recalc = False
        try:
            cached = load_vars(path, vars)
        except __HOLE__ as e:
            if 'The following variables' in str(e):
                if read:
                    raise
                force_recalc = True
            else:
                raise
            cached = {}
        if not '_cell_md5' in cached or cell_md5 != cached['_cell_md5']:
            force_recalc = True
        if force_recalc and not read:
            return cache(cell, path, vars, ip_user_ns, ip_run_cell, ip_push, ip_clear_output, True, read, verbose)
        # Handle the outputs separately.
        io = load_captured_io(cached.get('_captured_io', {}))
        # Push the remaining variables in the namespace.
        ip_push(cached)
        if verbose:
            print(("[Skipped the cell's code and loaded variables {0:s} "
                   "from file '{1:s}'.]").format(', '.join(vars), path))

    # Display the outputs, whether they come from the cell's execution
    # or the pickle file.
    io() # output is only printed when loading file
dataset/ETHPy150Open rossant/ipycache/ipycache.py/cache