code: def rename_feature(
      spec,
      current_name,
      new_name,
      rename_inputs=True,
      rename_outputs=True,
  ):
      """
      Rename a feature in the specification.
  
      Parameters
      ----------
      spec: Model_pb
          The specification containing the feature to rename.
  
      current_name: str
          Current name of the feature. If this feature doesn't exist, the rename
          is a no-op.
  
      new_name: str
          New name of the feature.
  
      rename_inputs: bool
          Search for `current_name` only in the input features (i.e ignore output
          features)
  
      rename_outputs: bool
          Search for `current_name` only in the output features (i.e ignore input
          features)
  
      Examples
      --------
      .. sourcecode:: python
  
          # In-place rename of spec
          model = MLModel("model.mlmodel")
          spec = model.get_spec()
          coremltools.utils.rename_feature(spec, "old_feature", "new_feature_name")
          # re-initialize model
          model = MLModel(spec)
          model.save("model.mlmodel")
  
          # Rename a spec when the model is an mlprogram, in that case, weights are stored outside of the spec
          model = coremltools.convert(torch_model, convert_to="mlprogram")
          spec = model.get_spec()
          # print info about inputs and outputs
          print(spec.description)
          coremltools.utils.rename_feature(spec, "old_feature", "new_feature_name")
          # re-initialize model
          model = MLModel(spec, weights_dir=model.weights_dir)
          model.save("model.mlpackage")
      """
  
      if not rename_inputs and not rename_outputs:
          return
  
      changed_input = False
      changed_output = False
  
      if rename_inputs:
          for input in spec.description.input:
              if input.name == current_name:
                  input.name = new_name
                  changed_input = True
  
      if rename_outputs:
          for output in spec.description.output:
              if output.name == current_name:
                  output.name = new_name
                  changed_output = True
  
          if spec.description.predictedFeatureName == current_name:
              spec.description.predictedFeatureName = new_name
  
          if (
              spec.description.predictedProbabilitiesName
              == current_name
          ):
              spec.description.predictedProbabilitiesName = new_name
  
      if not changed_input and not changed_output:
          return
  
      # Rename internally in NN model
      nn = None
      for nn_type in [
          "neuralNetwork",
          "neuralNetworkClassifier",
          "neuralNetworkRegressor",
      ]:
          if spec.HasField(nn_type):
              nn = getattr(spec, nn_type)
  
      if nn is not None:
          for layer in nn.layers:
              if rename_inputs:
                  for index, name in enumerate(layer.input):
                      if name == current_name:
                          layer.input[index] = new_name
                  if rename_outputs:
                      for index, name in enumerate(layer.output):
                          if name == current_name:
                              layer.output[index] = new_name
  
          if rename_inputs:
              for preprocess_params in nn.preprocessing:
                  if preprocess_params.featureName == current_name:
                      preprocess_params.featureName = new_name
  
          if spec.HasField("neuralNetworkClassifier"):
              if nn.labelProbabilityLayerName == current_name:
                  nn.labelProbabilityLayerName = new_name
  
      # Rename internally for feature vectorizer
      if spec.HasField("featureVectorizer") and rename_inputs:
          for input in spec.featureVectorizer.inputList:
              if input.inputColumn == current_name:
                  input.inputColumn = new_name
                  changed_input = True
  
      # Rename for pipeline models
      pipeline = None
      if spec.HasField("pipeline"):
          pipeline = spec.pipeline
      elif spec.HasField("pipelineClassifier"):
          pipeline = spec.pipelineClassifier.pipeline
      elif spec.HasField("pipelineRegressor"):
          pipeline = spec.pipelineRegressor.pipeline
  
      if pipeline is not None:
          for index, model in enumerate(pipeline.models):
              rename_feature(
                  model,
                  current_name,
                  new_name,
                  rename_inputs or (index != 0),
                  rename_outputs or (index < len(spec.pipeline.models)),
              )
  
      # Rename for mlProgram
      if spec.HasField("mlProgram"):
          new_name_sanitized = _NameSanitizer().sanitize_name(new_name)
          if new_name != new_name_sanitized:
              raise ValueError(
                  "Input/output names for ML Program must be of the format [a-zA-Z_][a-zA-Z0-9_]*. "
                  "That is, it must start with a letter and only contain numerals, underscore or letters. "
                  'Provided feature name, "{}" does not satisfy these requirements.'.format(
                      new_name
                  )
              )
          mil = spec.mlProgram
          for function in mil.functions.values():
              for name_value_type in function.inputs:
                  if name_value_type.name == current_name:
                      name_value_type.name = new_name
              for block in function.block_specializations.values():
                  for i, out_name in enumerate(block.outputs):
                      if out_name == current_name:
                          block.outputs[i] = new_name
                  for op in block.operations:
                      for argument in op.inputs.values():
                          for binding in argument.arguments:
                              if binding.HasField("name"):
                                  if binding.name == current_name:
                                      binding.name = new_name
                      for name_value_type in op.outputs:
                          if name_value_type.name == current_name:
                              name_value_type.name = new_name
  
imports: from collections.abc import Iterable
  from functools import lru_cache
  import math
  import os
  import shutil
  import subprocess
  import sys
  import tempfile
  from typing import Optional, Union
  import warnings
  import numpy
  import coremltools
  from coremltools import ComputeUnit
  from coremltools.converters.mil.mil.passes.defs.preprocess import NameSanitizer
  from coremltools.proto import Model_pb2
  import coremltools.proto.MIL_pb2
  from .._deps import _HAS_SCIPY
label_desc: Use image node_id 16 for calling a global function with example usage: rename_feature(spec, current_name, new_name, rename_inputs, rename_outputs) without return types