code: def cache(
      func,
      memory,
      func_memory_level=None,
      memory_level=None,
      shelve=False,
      **kwargs,
  ):
      """Return a joblib.Memory object.
  
      The memory_level determines the level above which the wrapped
      function output is cached. By specifying a numeric value for
      this level, the user can to control the amount of cache memory
      used. This function will cache the function call or not
      depending on the cache level.
  
      Parameters
      ----------
      func : function
          The function which output is to be cached.
  
      memory : instance of joblib.Memory, string or pathlib.Path
          Used to cache the function call.
  
      func_memory_level : int, optional
          The memory_level from which caching must be enabled for the wrapped
          function.
  
      memory_level : int, optional
          The memory_level used to determine if function call must
          be cached or not (if user_memory_level is equal of greater than
          func_memory_level the function is cached).
  
      shelve : bool, default=False
          Whether to return a joblib MemorizedResult, callable by a .get()
          method, instead of the return value of func.
  
      kwargs : keyword arguments, optional
          The keyword arguments passed to memory.cache.
  
      Returns
      -------
      mem : joblib.MemorizedFunc, wrapped in _ShelvedFunc if shelving
          Object that wraps the function func to cache its further call.
          This object may be a no-op, if the requested level is lower
          than the value given to _cache()).
          For consistency, a callable object is always returned.
  
      """
      verbose = kwargs.get("verbose", 0)
  
      # memory_level and func_memory_level must be both None or both integers.
      memory_levels = [memory_level, func_memory_level]
      both_params_integers = all(
          isinstance(lvl, int) for lvl in memory_levels
      )
      both_params_none = all(lvl is None for lvl in memory_levels)
  
      if not (both_params_integers or both_params_none):
          raise ValueError(
              "Reference and user memory levels must be both None "
              "or both integers."
          )
  
      if memory is not None and (
          func_memory_level is None or memory_level >= func_memory_level
      ):
          memory = stringify_path(memory)
          if isinstance(memory, str):
              memory = Memory(location=memory, verbose=verbose)
          if not isinstance(memory, MEMORY_CLASSES):
              raise TypeError(
                  "'memory' argument must be a string or a "
                  "joblib.Memory object. "
                  f"{memory} {type(memory)} was given."
              )
          if (
              memory.location is None
              and memory_level is not None
              and memory_level > 1
          ):
              warnings.warn(
                  f"Caching has been enabled (memory_level = {memory_level}) "
                  "but no Memory object or path has been provided"
                  " (parameter memory). Caching deactivated for "
                  f"function {func.__name__}.",
                  stacklevel=2,
              )
      else:
          memory = Memory(location=None, verbose=verbose)
      cached_func = memory.cache(func, **kwargs)
      if shelve:
          cached_func = _ShelvedFunc(cached_func)
      return cached_func
  
file_path: nilearn/nilearn/_utils/cache_mixin.py
imports: import os
  import warnings
  from joblib import Memory
  import nilearn
  from .helpers import stringify_path
label_desc: Use image node_id 2 for calling a global function with example usage: cache(func, memory, func_memory_level, memory_level, shelve) and returns: cached_func