docs: def get_func_result_cachekey(func_, args_=tuple(), kwargs_={}):
      """
      TODO: recursive partial definitions
      kwargs = {}
      args = ([],)
      """
      import utool as ut
      # Rectify partials and whatnot
      true_args = args_
      true_kwargs = kwargs_
      true_func = func_
      if isinstance(func_, partial):
          true_func = func_.func
          if func_.args is not None:
              true_args = tuple(list(func_.args) + list(args_))
          if func_.keywords is not None:
              true_kwargs.update(func_.keywords)
  
      if ut.is_method(true_func):
          method = true_func
          true_func = method.im_func
          self = method.im_self
          true_args = tuple([self] + list(true_args))
  
      # Build up cachekey
      funcname = ut.get_funcname(true_func)
      kwdefaults = ut.get_kwdefaults(true_func, parse_source=False)
      #kwdefaults = ut.get_kwdefaults(true_func, parse_source=True)
      argnames   = ut.get_argnames(true_func)
      key_argx = None
      key_kwds = None
      func = true_func  # NOQA
      args = true_args  # NOQA
      kwargs = true_kwargs  # NOQA
      args_key = ut.get_cfgstr_from_args(true_func, true_args, true_kwargs,
                                         key_argx, key_kwds, kwdefaults,
                                         argnames)
      cachekey = funcname + '(' + args_key + ')'
      return cachekey