code: def test_deprecated_field_aliases():
      config = {
          "ludwig_version": "0.4",
          INPUT_FEATURES: [{"name": "num_in", "type": "numerical"}],
          OUTPUT_FEATURES: [{"name": "num_out", "type": "numerical"}],
          HYPEROPT: {
              "parameters": {
                  "training.learning_rate": {
                      "space": "loguniform",
                      "lower": 0.001,
                      "upper": 0.1,
                  },
              },
              "goal": "minimize",
              "sampler": {
                  "type": "grid",
                  "num_samples": 2,
                  "scheduler": {"type": "fifo"},
              },
              "executor": {
                  "type": "grid",
                  "search_alg": "bohb",
              },
          },
          PREPROCESSING: {
              "numerical": {
                  "fill_value": 2,
                  "missing_value_strategy": "fill_with_const",
              },
          },
          "training": {
              "epochs": 2,
              "eval_batch_size": 0,
              "reduce_learning_rate_on_plateau": 2,
              "reduce_learning_rate_on_plateau_patience": 5,
              "decay": True,
              "learning_rate_warmup_epochs": 2,
          },
      }
  
      updated_config = upgrade_config_dict_to_latest_version(config)
  
      assert updated_config["input_features"][0][TYPE] == NUMBER
      assert updated_config["output_features"][0][TYPE] == NUMBER
  
      # "numerical" preprocssing directive should be translated to "number" and moved into the defaults section.
      assert PREPROCESSING not in updated_config
      assert (
          updated_config[DEFAULTS][NUMBER][PREPROCESSING]["fill_value"]
          == 2
      )
  
      assert "training" not in updated_config
      assert updated_config[TRAINER]["epochs"] == 2
      assert updated_config[TRAINER][EVAL_BATCH_SIZE] is None
  
      assert LEARNING_RATE_SCHEDULER in updated_config[TRAINER]
      assert (
          updated_config[TRAINER][LEARNING_RATE_SCHEDULER][
              "reduce_on_plateau"
          ]
          == 2
      )
      assert (
          updated_config[TRAINER][LEARNING_RATE_SCHEDULER][
              "reduce_on_plateau_patience"
          ]
          == 5
      )
      assert (
          updated_config[TRAINER][LEARNING_RATE_SCHEDULER]["decay"]
          == "exponential"
      )
      assert (
          updated_config[TRAINER][LEARNING_RATE_SCHEDULER][
              "warmup_evaluations"
          ]
          == 2
      )
  
      hparams = updated_config[HYPEROPT]["parameters"]
      assert "training.learning_rate" not in hparams
      assert "trainer.learning_rate" in hparams
  
      assert "sampler" not in updated_config[HYPEROPT]
  
      assert updated_config[HYPEROPT]["executor"]["type"] == "ray"
      assert "num_samples" in updated_config[HYPEROPT]["executor"]
      assert "scheduler" in updated_config[HYPEROPT]["executor"]
  
      ModelConfig.from_dict(updated_config)
  
imports: import copy
  import math
  from typing import Any, Dict
  import pytest
  from ludwig.constants import BATCH_SIZE, BFILL, CLASS_WEIGHTS, DEFAULTS, EVAL_BATCH_SIZE, EXECUTOR, HYPEROPT, INPUT_FEATURES, LEARNING_RATE_SCHEDULER, LOSS, NUMBER, OUTPUT_FEATURES, PREPROCESSING, SCHEDULER, SPLIT, TRAINER, TYPE
  from ludwig.schema.model_config import ModelConfig
  from ludwig.schema.trainer import ECDTrainerConfig
  from ludwig.utils.backward_compatibility import _update_backend_cache_credentials, _upgrade_encoder_decoder_params, _upgrade_feature, _upgrade_preprocessing_split, upgrade_config_dict_to_latest_version, upgrade_missing_value_strategy, upgrade_model_progress
  from ludwig.utils.trainer_utils import TrainerMetric
label_desc: Use image node_id 4 for calling a global function with example usage: test_deprecated_field_aliases() without return types