code: def test_sequential_encoder_general(self):
      ts = tg.linear_timeseries(length=24, freq="MS")
      covs = tg.linear_timeseries(length=24, freq="MS")
  
      # encoders must be named function for pickling
      def extract_month(index):
          return index.month
  
      def extract_year(index):
          return index.year
  
      input_chunk_length = 12
      output_chunk_length = 6
      add_encoders = {
          "cyclic": {
              "past": ["month", "day"],
              "future": ["day", "month"],
          },
          "datetime_attribute": {
              "past": ["month", "year"],
              "future": ["year", "month"],
          },
          "position": {
              "past": ["relative"],
              "future": ["relative"],
          },
          "custom": {
              "past": [extract_month, extract_year],
              "future": [extract_month, extract_year],
          },
          "transformer": Scaler(),
          "tz": "CET",
      }
      # given `add_encoders` dict, we expect encoders to generate the following components
      comps_expected_past = pd.Index(
          [
              "darts_enc_pc_cyc_month_sin",
              "darts_enc_pc_cyc_month_cos",
              "darts_enc_pc_cyc_day_sin",
              "darts_enc_pc_cyc_day_cos",
              "darts_enc_pc_dta_month",
              "darts_enc_pc_dta_year",
              "darts_enc_pc_pos_relative",
              "darts_enc_pc_cus_custom",
              "darts_enc_pc_cus_custom_1",
          ]
      )
      comps_expected_future = pd.Index(
          [
              "darts_enc_fc_cyc_day_sin",
              "darts_enc_fc_cyc_day_cos",
              "darts_enc_fc_cyc_month_sin",
              "darts_enc_fc_cyc_month_cos",
              "darts_enc_fc_dta_year",
              "darts_enc_fc_dta_month",
              "darts_enc_fc_pos_relative",
              "darts_enc_fc_cus_custom",
              "darts_enc_fc_cus_custom_1",
          ]
      )
      kwargs = {
          "add_encoders": add_encoders,
          "input_chunk_length": input_chunk_length,
          "output_chunk_length": output_chunk_length,
          "takes_future_covariates": True,
          "takes_past_covariates": True,
      }
      kwargs_copy = copy.deepcopy(kwargs)
  
      # with `position` encoder, we have to call `encode_train()` before inference set
      kwargs_copy["add_encoders"] = {
          k: val
          for k, val in kwargs["add_encoders"].items()
          if k not in ["transformer"]
      }
      enc = SequentialEncoder(**kwargs_copy)
      assert enc.requires_fit
      # inference directly does not work
      with pytest.raises(ValueError):
          _ = enc.encode_inference(
              n=1,
              target=ts,
              past_covariates=covs,
              future_covariates=covs,
          )
      # train first then inference does work
      _ = enc.encode_train(
          target=ts, past_covariates=covs, future_covariates=covs
      )
      _ = enc.encode_inference(
          n=1, target=ts, past_covariates=covs, future_covariates=covs
      )
      # train_inference works directly
      enc = SequentialEncoder(**kwargs_copy)
      _ = enc.encode_train_inference(
          n=1, target=ts, past_covariates=covs, future_covariates=covs
      )
  
      # with `transformer`, we have to call `encode_train()` before inference set
      kwargs_copy["add_encoders"] = {
          k: val
          for k, val in kwargs["add_encoders"].items()
          if k not in ["position"]
      }
      enc = SequentialEncoder(**kwargs_copy)
      assert enc.requires_fit
      # inference directly does not work
      with pytest.raises(ValueError):
          _ = enc.encode_inference(
              n=1,
              target=ts,
              past_covariates=covs,
              future_covariates=covs,
          )
      # train first then inference does work
      _ = enc.encode_train(
          target=ts, past_covariates=covs, future_covariates=covs
      )
      _ = enc.encode_inference(
          n=1, target=ts, past_covariates=covs, future_covariates=covs
      )
      # train_inference works directly
      enc = SequentialEncoder(**kwargs_copy)
      _ = enc.encode_train_inference(
          n=1, target=ts, past_covariates=covs, future_covariates=covs
      )
  
      # without position encoder and transformer, we can directly encode the inference set
      kwargs_copy["add_encoders"] = {
          k: val
          for k, val in kwargs["add_encoders"].items()
          if k not in ["position", "transformer"]
      }
      enc = SequentialEncoder(**kwargs_copy)
      assert not enc.requires_fit
      _ = enc.encode_inference(
          n=1, target=ts, past_covariates=covs, future_covariates=covs
      )
  
      # ==> test `encode_train()` with all encoders and transformer
      enc = SequentialEncoder(**kwargs)
      assert not enc.fit_called
      assert enc.requires_fit
      pc, fc = enc.encode_train(
          target=ts, past_covariates=covs, future_covariates=covs
      )
  
      assert enc.past_components.equals(comps_expected_past)
      assert comps_expected_past.isin(pc.components).all()
      assert covs.components.isin(pc.components).all()
  
      assert enc.future_components.equals(comps_expected_future)
      assert comps_expected_future.isin(fc.components).all()
      assert covs.components.isin(fc.components).all()
  
      # we can also take the output from a previous `encode_train` call as input covariates.
      # the encoded components get overwritten by the second call
      pc_train, fc_train = enc.encode_train(
          target=ts, past_covariates=pc, future_covariates=fc
      )
      assert pc_train == pc
      assert fc_train == fc
      pc_train, fc_train = enc.encode_train_inference(
          n=10, target=ts, past_covariates=pc, future_covariates=fc
      )
      assert pc_train == pc
      assert fc_train == fc
  
      # ==> test `encode_inference()` with all encoders and transformer
      assert enc.fit_called
      pc, fc = enc.encode_inference(
          n=1, target=ts, past_covariates=covs, future_covariates=covs
      )
      assert enc.past_components.equals(comps_expected_past)
      assert comps_expected_past.isin(pc.components).all()
      assert covs.components.isin(pc.components).all()
  
      assert enc.future_components.equals(comps_expected_future)
      assert comps_expected_future.isin(fc.components).all()
      assert covs.components.isin(fc.components).all()
  
      # ==> test the same for `encode_train_inference`
      enc = SequentialEncoder(**kwargs)
      assert not enc.fit_called
      pc, fc = enc.encode_train_inference(
          n=1, target=ts, past_covariates=covs, future_covariates=covs
      )
      assert enc.fit_called
      assert enc.past_components.equals(comps_expected_past)
      assert comps_expected_past.isin(pc.components).all()
      assert covs.components.isin(pc.components).all()
  
      assert enc.future_components.equals(comps_expected_future)
      assert comps_expected_future.isin(fc.components).all()
      assert covs.components.isin(fc.components).all()
  
      # we can also take the output from `encode_train()` as input covariates to `encode_inference()` to get the
      # same results
      pc_inf, fc_inf = enc.encode_inference(
          n=1,
          target=ts,
          past_covariates=pc_train,
          future_covariates=fc_train,
      )
      assert pc_inf == pc
      assert fc_inf == fc
  
      # or take the output from `encode_inference()` and get the same results
      pc_inf2, fc_inf2 = enc.encode_inference(
          n=1, target=ts, past_covariates=pc, future_covariates=fc
      )
      assert pc_inf2 == pc
      assert fc_inf2 == fc
  
      pc_train, fc_train = enc.encode_train_inference(
          n=10, target=ts, past_covariates=pc, future_covariates=fc
      )
  
imports: import copy
  from typing import Optional, Sequence
  import numpy
  import pandas
  import pytest
  from darts import TimeSeries
  from darts.dataprocessing.encoders import FutureCallableIndexEncoder, FutureCyclicEncoder, FutureDatetimeAttributeEncoder, FutureIntegerIndexEncoder, PastCallableIndexEncoder, PastCyclicEncoder, PastDatetimeAttributeEncoder, PastIntegerIndexEncoder, SequentialEncoder
  from darts.dataprocessing.encoders.encoder_base import PastCovariatesIndexGenerator, SingleEncoder
  from darts.dataprocessing.encoders.encoders import CallableIndexEncoder, CyclicTemporalEncoder, DatetimeAttributeEncoder, IntegerIndexEncoder
  from darts.dataprocessing.transformers import Scaler
  from darts.logging import get_logger, raise_log
  from darts.utils import timeseries_generation
label_desc: Use image node_id 7 for calling the TestEncoder obj's underlying member method code with example usage: obj.test_sequential_encoder_general() and returns: index, index