code: def test_historical_forecasts(self, config):
      train_length = 10
      forecast_horizon = 8
      # if no fit and retrain=false, should fit at fist iteration
      model_cls, kwargs, model_kwarg, bounds = config
      model = model_cls(**kwargs, **model_kwarg)
  
      # time index
      forecasts = model.historical_forecasts(
          series=self.ts_pass_val,
          forecast_horizon=forecast_horizon,
          stride=1,
          train_length=train_length,
          retrain=True,
          overlap_end=False,
      )
  
      theorical_forecast_length = (
          self.ts_val_length
          - max(
              [
                  (
                      bounds[0] + bounds[1] + 1
                  ),  # +1 as sklearn models require min 2 train samples
                  train_length,
              ]
          )  # because we train
          - forecast_horizon  # because we have overlap_end = False
          + 1  # because we include the first element
      )
  
      assert len(forecasts) == theorical_forecast_length, (
          f"Model {model_cls.__name__} does not return the right number of historical forecasts in the case "
          f"of retrain=True and overlap_end=False, and a time index of type DateTimeIndex. "
          f"Expected {theorical_forecast_length}, got {len(forecasts)}"
      )
  
      # range index
      forecasts = model.historical_forecasts(
          series=self.ts_pass_val_range,
          forecast_horizon=forecast_horizon,
          train_length=train_length,
          stride=1,
          retrain=True,
          overlap_end=False,
      )
  
      assert len(forecasts) == theorical_forecast_length, (
          f"Model {model_cls.__name__} does not return the right number of historical forecasts in the case "
          f"of retrain=True, overlap_end=False, and a time index of type RangeIndex."
          f"Expected {theorical_forecast_length}, got {len(forecasts)}"
      )
  
      # stride 2
      forecasts = model.historical_forecasts(
          series=self.ts_pass_val_range,
          forecast_horizon=forecast_horizon,
          train_length=train_length,
          stride=2,
          retrain=True,
          overlap_end=False,
      )
  
      theorical_forecast_length = np.floor(
          (
              (
                  self.ts_val_length
                  - max(
                      [
                          (
                              bounds[0] + bounds[1] + 1
                          ),  # +1 as sklearn models require min 2 train samples
                          train_length,
                      ]
                  )  # because we train
                  - forecast_horizon  # because we have overlap_end = False
                  + 1  # because we include the first element
              )
              - 1
          )
          / 2
          + 1  # because of stride
      )  # if odd number of elements, we keep the floor
  
      assert len(forecasts) == theorical_forecast_length, (
          f"Model {model_cls.__name__} does not return the right number of historical forecasts in the case "
          f"of retrain=True and overlap_end=False and stride=2. "
          f"Expected {theorical_forecast_length}, got {len(forecasts)}"
      )
  
      # stride 3
      forecasts = model.historical_forecasts(
          series=self.ts_pass_val_range,
          forecast_horizon=forecast_horizon,
          train_length=train_length,
          stride=3,
          retrain=True,
          overlap_end=False,
      )
  
      theorical_forecast_length = np.floor(
          (
              (
                  self.ts_val_length
                  - max(
                      [
                          (
                              bounds[0] + bounds[1] + 1
                          ),  # +1 as sklearn models require min 2 train samples
                          train_length,
                      ]
                  )  # because we train
                  - forecast_horizon  # because we have overlap_end = False
                  + 1  # because we include the first element
              )
              - 1
          )  # the first is always included, so we calculate a modulo on the rest
          / 3  # because of stride
          + 1  # and we readd the first
      )  # if odd number of elements, we keep the floor
  
      # Here to adapt if forecast_horizon or train_length change
      assert len(forecasts) == theorical_forecast_length, (
          f"Model {model_cls.__name__} does not return the right number of historical forecasts in the case "
          f"of retrain=True and overlap_end=False and stride=3. "
          f"Expected {theorical_forecast_length}, got {len(forecasts)}"
      )
  
      # last points only False
      forecasts = model.historical_forecasts(
          series=self.ts_pass_val_range,
          forecast_horizon=forecast_horizon,
          train_length=train_length,
          stride=1,
          retrain=True,
          overlap_end=False,
          last_points_only=False,
      )
  
      theorical_forecast_length = (
          self.ts_val_length
          - max(
              [
                  (
                      bounds[0] + bounds[1] + 1
                  ),  # +1 as sklearn models require min 2 train samples
                  train_length,
              ]
          )  # because we train
          - forecast_horizon  # because we have overlap_end = False
          + 1  # because we include the first element
      )
  
      assert len(forecasts) == theorical_forecast_length, (
          f"Model {model_cls} does not return the right number of historical forecasts in the case of "
          f"retrain=True and overlap_end=False, and last_points_only=False. "
          f"expected {theorical_forecast_length}, got {len(forecasts)}"
      )
  
      assert len(forecasts[0]) == forecast_horizon, (
          f"Model {model_cls} does not return forecast_horizon points per historical forecast in the case of "
          f"retrain=True and overlap_end=False, and last_points_only=False"
      )
  
      if not model.supports_past_covariates:
          with pytest.raises(ValueError) as msg:
              model.historical_forecasts(
                  series=self.ts_pass_val_range,
                  past_covariates=self.ts_passengers,
                  retrain=True,
              )
          assert str(msg.value).startswith(
              "Model cannot be fit/trained with `past_covariates`."
          )
  
      if not model.supports_future_covariates:
          with pytest.raises(ValueError) as msg:
              model.historical_forecasts(
                  series=self.ts_pass_val_range,
                  future_covariates=self.ts_passengers,
                  last_points_only=False,
              )
          assert str(msg.value).startswith(
              "Model cannot be fit/trained with `future_covariates`."
          )
  
imports: import itertools
  from itertools import product
  import numpy
  import pandas
  import pytest
  import darts
  from darts import TimeSeries, concatenate
  from darts.dataprocessing.transformers import Scaler
  from darts.datasets import AirPassengersDataset
  from darts.logging import get_logger
  from darts.models import ARIMA, AutoARIMA, CatBoostModel, LightGBMModel, LinearRegressionModel, NaiveSeasonal, NotImportedModule
  from darts.tests.conftest import tfm_kwargs
  from darts.utils import timeseries_generation
label_desc: Use image node_id 7 for calling the TestHistoricalforecast obj's underlying member method code with example usage: obj.test_historical_forecasts(config) without return types