class_docstr: Base forecaster template class.
  
  The base forecaster specifies the methods and method signatures that all forecasters
  have to implement.
  
  Specific implementations of these methods is deferred to concrete forecasters.
class_docstr_tok: ["Base","forecaster","template","class",".","The","base","forecaster","specifies","the","methods","and","method","signatures","that","all","forecasters","have","to","implement",".","Specific","implementations","of","these","methods","is","deferred","to","concrete","forecasters","."]
docstr: Check, set and update the forecasting horizon.
  
  Called from all methods where fh can be passed:
      fit, predict-like, update-like
  
  Reads and writes to self._fh.
  Writes fh to self._fh if does not exist.
  Checks equality of fh with self._fh if exists, raises error if not equal.
  Assigns the frequency inferred from self._y
  to the returned forecasting horizon object.
  
  Parameters
  ----------
  fh : None, int, list, np.ndarray or ForecastingHorizon
  
  Returns
  -------
  self._fh : ForecastingHorizon or None
      if ForecastingHorizon, last passed fh coerced to ForecastingHorizon
  
  Raises
  ------
  ValueError if self._fh exists and is inconsistent with fh
  ValueError if fh is not passed (None) in a case where it must be:
      - in fit, if self has the tag "requires-fh-in-fit" (value True)
      - in predict, if it has not been passed in fit
docstr_tok: ["Check",",","set","and","update","the","forecasting","horizon",".","Called","from","all","methods","where","fh","can","be","passed",":","fit",",","predict-like",",","update-like","Reads","and","writes","to","self._fh",".","Writes","fh","to","self._fh","if","does","not","exist",".","Checks","equality","of","fh","with","self._fh","if","exists",",","raises","error","if","not","equal",".","Assigns","the","frequency","inferred","from","self._y","to","the","returned","forecasting","horizon","object",".","Parameters","--","--","--","--","--","fh",":","None",",","int",",","list",",","np.ndarray","or","ForecastingHorizon","Returns","--","--","--","-","self._fh",":","ForecastingHorizon","or","None","if","ForecastingHorizon",",","last","passed","fh","coerced","to","ForecastingHorizon","Raises","--","--","--","ValueError","if","self._fh","exists","and","is","inconsistent","with","fh","ValueError","if","fh","is","not","passed","(","None",")","in","a","case","where","it","must","be",":","-","in","fit",",","if","self","has","the","tag","``","requires-fh-in-fit","''","(","value","True",")","-","in","predict",",","if","it","has","not","been","passed","in","fit"]
code: def _check_fh(self, fh):
      """Check, set and update the forecasting horizon.
  
      Called from all methods where fh can be passed:
          fit, predict-like, update-like
  
      Reads and writes to self._fh.
      Writes fh to self._fh if does not exist.
      Checks equality of fh with self._fh if exists, raises error if not equal.
      Assigns the frequency inferred from self._y
      to the returned forecasting horizon object.
  
      Parameters
      ----------
      fh : None, int, list, np.ndarray or ForecastingHorizon
  
      Returns
      -------
      self._fh : ForecastingHorizon or None
          if ForecastingHorizon, last passed fh coerced to ForecastingHorizon
  
      Raises
      ------
      ValueError if self._fh exists and is inconsistent with fh
      ValueError if fh is not passed (None) in a case where it must be:
          - in fit, if self has the tag "requires-fh-in-fit" (value True)
          - in predict, if it has not been passed in fit
      """
      requires_fh = self.get_tag("requires-fh-in-fit")
  
      msg = (
          f"This is because fitting of the "
          f"forecaster {self.__class__.__name__} "
          f"depends on `fh`. "
      )
  
      # below loop treats four cases from three conditions:
      #  A. forecaster is fitted yes/no - self.is_fitted
      #  B. no fh is passed yes/no - fh is None
      #  C. fh is optional in fit yes/no - optfh
  
      # B. no fh is passed
      if fh is None:
          # A. strategy fitted (call of predict or similar)
          if self._is_fitted:
              # in case C. fh is optional in fit:
              # if there is none from before, there is none overall - raise error
              if not requires_fh and self._fh is None:
                  raise ValueError(
                      "The forecasting horizon `fh` must be passed "
                      "either to `fit` or `predict`, but was found in neither "
                      f"call of this {self.__class__.__name__} instance's methods."
                  )
              # in case C. fh is not optional in fit: this is fine
              # any error would have already been caught in fit
  
          # A. strategy not fitted (call of fit)
          elif requires_fh:
              # in case fh is not optional in fit:
              # fh must be passed in fit
              raise ValueError(
                  "The forecasting horizon `fh` must be passed to "
                  f"`fit` of {self.__class__.__name__}, but none was found. "
                  + msg
              )
              # in case C. fh is optional in fit:
              # this is fine, nothing to check/raise
  
      # B. fh is passed
      else:
          # If fh is passed, coerce to ForecastingHorizon and validate (all cases)
          fh = check_fh(fh=fh, freq=self._cutoff)
  
          # fh is written to self if one of the following is true
          # - estimator has not been fitted yet (for safety from side effects)
          # - fh has not been seen yet
          # - fh has been seen, but was optional in fit,
          #     this means fh needs not be same and can be overwritten
          if not requires_fh or not self._fh or not self._is_fitted:
              self._fh = fh
          # there is one error condition:
          # - fh is mandatory in fit, i.e., fh in predict must be same if passed
          # - fh already passed, and estimator is fitted
          # - fh that was passed in fit is not the same as seen in predict
          # note that elif means: optfh == False, and self._is_fitted == True
          elif self._fh and not np.array_equal(fh, self._fh):
              # raise error if existing fh and new one don't match
              raise ValueError(
                  "A different forecasting horizon `fh` has been "
                  "provided from "
                  "the one seen already in `fit`, in this instance of "
                  f"{self.__class__.__name__}. "
                  "If you want to change the forecasting "
                  "horizon, please re-fit the forecaster. " + msg
              )
          # if existing one and new match, ignore new one
  
      return self._fh
  
imports: from copy import deepcopy
  from itertools import product
  import numpy
  import pandas
  from sktime.base import BaseEstimator
  from sktime.datatypes import VectorizedDF, check_is_scitype, convert_to, get_cutoff, mtype_to_scitype, scitype_to_mtype, update_data
  from sktime.forecasting.base._fh import ForecastingHorizon
  from sktime.utils.datetime import _shift
  from sktime.utils.validation._dependencies import _check_estimator_deps
  from sktime.utils.validation.forecasting import check_alpha, check_cv, check_fh, check_X
  from sktime.utils.validation.series import check_equal_time_index
  from sktime.utils.warnings import warn
label_desc: Use image node_id 28 for calling the BaseForecaster obj's underlying member method code with example usage: obj._check_fh(fh) and returns: self