code: def __inner_eval(self, data_name, data_idx, feval=None):
          
          if data_idx >= self.__num_dataset:
              raise ValueError("Data_idx should be smaller than number of dataset")
          self.__get_eval_info()
          ret = []
          if self.__num_inner_eval > 0:
              result = np.zeros(self.__num_inner_eval, dtype=np.float64)
              tmp_out_len = ctypes.c_int(0)
              _safe_call(_LIB.LGBM_BoosterGetEval(
                  self.handle,
                  ctypes.c_int(data_idx),
                  ctypes.byref(tmp_out_len),
                  result.ctypes.data_as(ctypes.POINTER(ctypes.c_double))))
              if tmp_out_len.value != self.__num_inner_eval:
                  raise ValueError("Wrong length of eval results")
              for i in range_(self.__num_inner_eval):
                  ret.append((data_name, self.__name_inner_eval[i],
                              result[i], self.__higher_better_inner_eval[i]))
          if feval is not None:
              if data_idx == 0:
                  cur_data = self.train_set
              else:
                  cur_data = self.valid_sets[data_idx - 1]
              feval_ret = feval(self.__inner_predict(data_idx), cur_data)
              if isinstance(feval_ret, list):
                  for eval_name, val, is_higher_better in feval_ret:
                      ret.append((data_name, eval_name, val, is_higher_better))
              else:
                  eval_name, val, is_higher_better = feval_ret
                  ret.append((data_name, eval_name, val, is_higher_better))
          return ret
docs: Evaluate training or validation data.