docs: def on_exception_report_input(func_=None, force=False, keys=None):
      """
      If an error is thrown in the scope of this function's stack frame then the
      decorated function name and the arguments passed to it will be printed to
      the utool print function.
      """
      def _closure_onexceptreport(func):
          if not ONEX_REPORT_INPUT and not force:
              return func
          @ignores_exc_tb(outer_wrapper=False)
          #@wraps(func)
          def wrp_onexceptreport(*args, **kwargs):
              try:
                  #import utool
                  #if utool.DEBUG:
                  #    print('[IN EXCPRPT] args=%r' % (args,))
                  #    print('[IN EXCPRPT] kwargs=%r' % (kwargs,))
                  return func(*args, **kwargs)
              except Exception as ex:
                  from utool import util_str
                  print('ERROR occured! Reporting input to function')
                  if keys is not None:
                      from utool import util_inspect
                      from utool import util_list
                      from utool import util_dict
                      argspec = util_inspect.get_func_argspec(func)
                      in_kwargs_flags = [key in kwargs for key in keys]
                      kwarg_keys = util_list.compress(keys, in_kwargs_flags)
                      kwarg_vals = [kwargs.get(key) for key in kwarg_keys]
                      flags = util_list.not_list(in_kwargs_flags)
                      arg_keys = util_list.compress(keys, flags)
                      arg_idxs = [argspec.args.index(key) for key in arg_keys]
                      num_nodefault = len(argspec.args) - len(argspec.defaults)
                      default_vals = (([None] * (num_nodefault)) +
                                      list(argspec.defaults))
                      args_ = list(args) + default_vals[len(args) + 1:]
                      arg_vals = util_list.take(args_, arg_idxs)
                      requested_dict = dict(util_list.flatten(
                          [zip(kwarg_keys, kwarg_vals), zip(arg_keys, arg_vals)]))
                      print('input dict = ' + util_str.repr4(
                          util_dict.dict_subset(requested_dict, keys)))
                      # (print out specific keys only)
                      pass
                  arg_strs = ', '.join([repr(util_str.truncate_str(str(arg)))
                                        for arg in args])
                  kwarg_strs = ', '.join([
                      util_str.truncate_str('%s=%r' % (key, val))
                      for key, val in six.iteritems(kwargs)])
                  msg = ('\nERROR: funcname=%r,\n * args=%s,\n * kwargs=%r\n' % (
                      meta_util_six.get_funcname(func), arg_strs, kwarg_strs))
                  msg += ' * len(args) = %r\n' % len(args)
                  msg += ' * len(kwargs) = %r\n' % len(kwargs)
                  util_dbg.printex(ex, msg, pad_stdout=True)
                  raise
          wrp_onexceptreport = preserve_sig(wrp_onexceptreport, func)
          return wrp_onexceptreport
      if func_ is None:
          return _closure_onexceptreport
      else:
          return _closure_onexceptreport(func_)