class_docstr: The model template for Multistage Forecast Estimator.
class_docstr_tok: ["The","model","template","for","Multistage","Forecast","Estimator","."]
docstr: Gets the overriden Multistage Forecast configs by ``custom``.
  
  Parameters
  ----------
  custom : `dict` [`str`, any]
      The custom dictionary in `ModelComponentsParam`.
      The only recognizable key is ``multistage_forecast_configs``,
      which takes a list of
      `~greykite.framework.templates.multistage_forecast_template_config.MultistageForecastTemplateConfig`.
  model_template : `str`
      The model template used in Multistage Forecast template.
  default_multistage_forecast_configs : `list` [
  `~greykite.framework.templates.multistage_forecast_template_config.MultistageForecastTemplateConfig`]
      The default Multistage Forecast configs from ``model_template``.
  
  Returns
  -------
  new_configs : `list` [
  `~greykite.framework.templates.multistage_forecast_template_config.MultistageForecastTemplateConfig`]
      The Multistage Forecast configs overriden by the ``multistage_forecast_configs`` in ``custom``.
docstr_tok: ["Gets","the","overriden","Multistage","Forecast","configs","by","``","custom","``",".","Parameters","--","--","--","--","--","custom",":","`","dict","`","[","`","str","`",",","any","]","The","custom","dictionary","in","`","ModelComponentsParam","`",".","The","only","recognizable","key","is","``","multistage_forecast_configs","``",",","which","takes","a","list","of","`","~greykite.framework.templates.multistage_forecast_template_config.MultistageForecastTemplateConfig","`",".","model_template",":","`","str","`","The","model","template","used","in","Multistage","Forecast","template",".","default_multistage_forecast_configs",":","`","list","`","[","`","~greykite.framework.templates.multistage_forecast_template_config.MultistageForecastTemplateConfig","`","]","The","default","Multistage","Forecast","configs","from","``","model_template","``",".","Returns","--","--","--","-","new_configs",":","`","list","`","[","`","~greykite.framework.templates.multistage_forecast_template_config.MultistageForecastTemplateConfig","`","]","The","Multistage","Forecast","configs","overriden","by","the","``","multistage_forecast_configs","``","in","``","custom","``","."]
code: def __get_multistage_forecast_configs_override(
      custom: Dict[str, any],
      model_template: str,
      default_multistage_forecast_configs: List[
          MultistageForecastTemplateConfig
      ],
  ):
      """Gets the overriden Multistage Forecast configs by ``custom``.
  
      Parameters
      ----------
      custom : `dict` [`str`, any]
          The custom dictionary in `ModelComponentsParam`.
          The only recognizable key is ``multistage_forecast_configs``,
          which takes a list of
          `~greykite.framework.templates.multistage_forecast_template_config.MultistageForecastTemplateConfig`.
      model_template : `str`
          The model template used in Multistage Forecast template.
      default_multistage_forecast_configs : `list` [
      `~greykite.framework.templates.multistage_forecast_template_config.MultistageForecastTemplateConfig`]
          The default Multistage Forecast configs from ``model_template``.
  
      Returns
      -------
      new_configs : `list` [
      `~greykite.framework.templates.multistage_forecast_template_config.MultistageForecastTemplateConfig`]
          The Multistage Forecast configs overriden by the ``multistage_forecast_configs`` in ``custom``.
      """
      if custom is not None:
          # Checks if any parameter is specified in "custom" other than "multistage_forecast_config".
          not_none_parameters = []
          for key, value in custom.items():
              if (
                  value is not None
                  and value != []
                  and key != "multistage_forecast_configs"
              ):
                  not_none_parameters.append(key)
          if not_none_parameters:
              log_message(
                  message=f"Multistage Forecast template only takes configurations through "
                  f"``custom.multistage_forecast_configs``. The following inputs are "
                  f"ignored \n{not_none_parameters}.",
                  level=LoggingLevelEnum.WARNING,
              )
          # Uses ``multistage_forecast_configs`` to override the default components if it's not None.
          multistage_forecast_configs = custom.get(
              "multistage_forecast_configs", None
          )
          if (
              multistage_forecast_configs is None
              or multistage_forecast_configs == []
          ) and model_template == "MULTISTAGE_EMPTY":
              raise ValueError(
                  f"``MULTISTAGE_EMPTY`` can not be used without overriding. "
                  f"You must provide parameters in "
                  f"``ModelComponentsParam.custom.multistage_forecast_configs``."
              )
          if multistage_forecast_configs is not None:
              # Wraps in a list if it's a single ``MultistageForecastTemplateConfig``.
              if isinstance(
                  multistage_forecast_configs,
                  MultistageForecastTemplateConfig,
              ):
                  multistage_forecast_configs = [
                      multistage_forecast_configs
                  ]
              # Must be a list.
              if not isinstance(multistage_forecast_configs, list):
                  raise ValueError(
                      f"The ``multistage_forecast_configs`` parameter must be a list of "
                      f"``MultistageForecastTemplateConfig`` objects, found "
                      f"\n{multistage_forecast_configs}."
                  )
              # Checks the lengths of default configs and overriding configs.
              num_configs_in_default = len(
                  default_multistage_forecast_configs
              )
              num_configs_in_override = len(multistage_forecast_configs)
              extra_configs = []
              if num_configs_in_default != num_configs_in_override:
                  if num_configs_in_default != 0:
                      log_message(
                          message=f"The number of configs in ``ModelComponentsParam`` ({num_configs_in_override}) "
                          f"does not match the number of configs in the default template "
                          f"({num_configs_in_default}). Appending extra configs to the end.",
                          level=LoggingLevelEnum.WARNING,
                      )
                  # These configs are extra configs, either from the default or from overriding.
                  # No matter where they come from, they will be appended to the end.
                  extra_configs = (
                      multistage_forecast_configs[
                          -(
                              num_configs_in_override
                              - num_configs_in_default
                          ) :
                      ]
                      if num_configs_in_override
                      >= num_configs_in_default
                      else default_multistage_forecast_configs[
                          -(
                              num_configs_in_default
                              - num_configs_in_override
                          ) :
                      ]
                  )
  
              # Overrides the default ``MultistageForecastTemplateConfig`` objects.
              num_to_override = min(
                  num_configs_in_default, num_configs_in_override
              )
              new_configs = []
              for i in range(num_to_override):
                  default_config = default_multistage_forecast_configs[
                      i
                  ]
                  new_config = multistage_forecast_configs[i]
                  # Overrides the original parameters.
                  keys = [
                      "train_length",
                      "fit_length",
                      "agg_freq",
                      "agg_func",
                  ]
                  for key in keys:
                      if getattr(new_config, key, None) is not None:
                          setattr(
                              default_config,
                              key,
                              getattr(new_config, key),
                          )
                  # For ``model_template`` and ``model_components``,
                  # both will be overriden if the new ``model_template`` is different
                  # from the default ``model_template``. However, if both ``model_templates``
                  # are the same, the keys/values in the new ``model_components`` will be
                  # used to override the keys/values in the default ``model_components``,
                  # instead of replacing the entire default ``model_components`` with the new ``model_components``.
                  # The consideration here is that if one only specifies partial ``model_components`` and hope
                  # the rest can be kept as the default, this is the right way to do. If one hopes to
                  # use only the parameters specified in the new ``model_components`` and do not apply defaults,
                  # they should have used the ``MULTISTAGE_EMPTY`` template,
                  # and this is also the correct behavior.
                  if (
                      new_config.model_template
                      != default_config.model_template
                      or default_config.model_components is None
                  ):
                      for key in ["model_template", "model_components"]:
                          if getattr(new_config, key, None) is not None:
                              setattr(
                                  default_config,
                                  key,
                                  getattr(new_config, key),
                              )
                  else:
                      for (
                          key
                      ) in new_config.model_components.__dict__.keys():
                          allow_unknown_keys = (
                              key == "hyperparameter_override"
                          )
                          updated_value = update_dictionaries(
                              default_dict=getattr(
                                  default_config.model_components,
                                  key,
                                  {},
                              )
                              or {},
                              overwrite_dicts=getattr(
                                  new_config.model_components, key
                              ),
                              allow_unknown_keys=allow_unknown_keys,
                          )
                          setattr(
                              default_config.model_components,
                              key,
                              updated_value,
                          )
                  new_configs.append(default_config)
              new_configs += extra_configs
          else:
              # If `ModelComponentsParam.custom["multistage_forecast_configs]"` is None,
              # use the default from template.
              new_configs = default_multistage_forecast_configs
      else:
          # If `ModelComponentsParam.custom` is None,
          # use the default from template.
          new_configs = default_multistage_forecast_configs
      return new_configs
  
imports: from itertools import product
  from typing import Dict
  from typing import List
  from typing import Type
  import pandas
  from greykite.common import constants
  from greykite.common.logging import LoggingLevelEnum
  from greykite.common.logging import log_message
  from greykite.common.python_utils import unique_in_list
  from greykite.common.python_utils import update_dictionaries
  from greykite.framework.templates.autogen.forecast_config import ForecastConfig
  from greykite.framework.templates.autogen.forecast_config import MetadataParam
  from greykite.framework.templates.base_template import BaseTemplate
  from greykite.framework.templates.multistage_forecast_template_config import MultistageForecastTemplateConfig
  from greykite.framework.templates.multistage_forecast_template_config import MultistageForecastTemplateConstants
  from greykite.sklearn.estimator.base_forecast_estimator import BaseForecastEstimator
  from greykite.sklearn.estimator.multistage_forecast_estimator import MultistageForecastEstimator
  from greykite.sklearn.estimator.multistage_forecast_estimator import MultistageForecastModelConfig
label_desc: Use image node_id 7 for calling the MultistageForecastTemplate obj's underlying member method code with example usage: obj.__get_multistage_forecast_configs_override(custom, model_template, default_multistage_forecast_configs) and returns: new_configs