class_docstr: Internal early stopping callable class.
class_docstr_tok: ["Internal","early","stopping","callable","class","."]
code: def __call__(self, env: CallbackEnv) -> None:
      if env.iteration == env.begin_iteration:
          self._init(env)
      if not self.enabled:
          return
      if env.evaluation_result_list is None:
          raise RuntimeError(
              "early_stopping() callback enabled but no evaluation results found. This is a probably bug in LightGBM. "
              "Please report it at https://github.com/microsoft/LightGBM/issues"
          )
      # self.best_score_list is initialized to an empty list
      first_time_updating_best_score_list = self.best_score_list == []
      for i in range(len(env.evaluation_result_list)):
          score = env.evaluation_result_list[i][2]
          if first_time_updating_best_score_list or self.cmp_op[i](
              score, self.best_score[i]
          ):
              self.best_score[i] = score
              self.best_iter[i] = env.iteration
              if first_time_updating_best_score_list:
                  self.best_score_list.append(
                      env.evaluation_result_list
                  )
              else:
                  self.best_score_list[i] = env.evaluation_result_list
          # split is needed for "<dataset type> <metric>" case (e.g. "train l1")
          eval_name_splitted = env.evaluation_result_list[i][1].split(
              " "
          )
          if (
              self.first_metric_only
              and self.first_metric != eval_name_splitted[-1]
          ):
              continue  # use only the first metric for early stopping
          if self._is_train_set(
              ds_name=env.evaluation_result_list[i][0],
              eval_name=eval_name_splitted[0],
              env=env,
          ):
              continue  # train data for lgb.cv or sklearn wrapper (underlying lgb.train)
          elif (
              env.iteration - self.best_iter[i] >= self.stopping_rounds
          ):
              if self.verbose:
                  eval_result_str = "\t".join(
                      [
                          _format_eval_result(x, show_stdv=True)
                          for x in self.best_score_list[i]
                      ]
                  )
                  _log_info(
                      f"Early stopping, best iteration is:\n[{self.best_iter[i] + 1}]\t{eval_result_str}"
                  )
                  if self.first_metric_only:
                      _log_info(
                          f"Evaluated only: {eval_name_splitted[-1]}"
                      )
              raise EarlyStopException(
                  self.best_iter[i], self.best_score_list[i]
              )
          self._final_iteration_check(env, eval_name_splitted, i)
  
imports: from collections import OrderedDict
  from dataclasses import dataclass
  from functools import partial
  from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union
  from .basic import Booster, _ConfigAliases, _LGBM_BoosterEvalMethodResultType, _LGBM_BoosterEvalMethodResultWithStandardDeviationType, _log_info, _log_warning
label_desc: Use image node_id 8 for calling the _EarlyStoppingCallback obj's underlying member method code with example usage: obj.__call__(env) without return types