code: def rename_channels(
      info, mapping, allow_duplicates=False, *, verbose=None
  ):
      """Rename channels.
  
      Parameters
      ----------
      %(info_not_none)s Note: modified in place.
      %(mapping_rename_channels_duplicates)s
      %(verbose)s
      """
      _validate_type(info, Info, "info")
      info._check_consistency()
      bads = list(info["bads"])  # make our own local copies
      ch_names = list(info["ch_names"])
  
      # first check and assemble clean mappings of index and name
      if isinstance(mapping, dict):
          _check_dict_keys(
              mapping,
              ch_names,
              key_description="channel name(s)",
              valid_key_source="info",
          )
          new_names = [
              (ch_names.index(ch_name), new_name)
              for ch_name, new_name in mapping.items()
          ]
      elif callable(mapping):
          new_names = [
              (ci, mapping(ch_name))
              for ci, ch_name in enumerate(ch_names)
          ]
      else:
          raise ValueError(
              f"mapping must be callable or dict, not {type(mapping)}"
          )
  
      # check we got all strings out of the mapping
      for new_name in new_names:
          _validate_type(new_name[1], "str", "New channel mappings")
  
      # do the remapping locally
      for c_ind, new_name in new_names:
          for bi, bad in enumerate(bads):
              if bad == ch_names[c_ind]:
                  bads[bi] = new_name
          ch_names[c_ind] = new_name
  
      # check that all the channel names are unique
      if (
          len(ch_names) != len(np.unique(ch_names))
          and not allow_duplicates
      ):
          raise ValueError(
              "New channel names are not unique, renaming failed"
          )
  
      # do the remapping in info
      info["bads"] = []
      ch_names_mapping = dict()
      for ch, ch_name in zip(info["chs"], ch_names):
          ch_names_mapping[ch["ch_name"]] = ch_name
          ch["ch_name"] = ch_name
      # .get b/c fwd info omits it
      _rename_comps(info.get("comps", []), ch_names_mapping)
      if "projs" in info:  # fwd might omit it
          for proj in info["projs"]:
              proj["data"]["col_names"][:] = _rename_list(
                  proj["data"]["col_names"], ch_names_mapping
              )
      info._update_redundant()
      info["bads"] = bads
      info._check_consistency()
  
imports: import os.path
  import string
  import sys
  from collections import OrderedDict
  from copy import deepcopy
  from dataclasses import dataclass
  from functools import partial
  from pathlib import Path
  from typing import Union
  import numpy
  from scipy.io import loadmat
  from scipy.sparse import csr_matrix, lil_matrix
  from scipy.spatial import Delaunay
  from scipy.stats import zscore
  from .._fiff.constants import FIFF
  from .._fiff.meas_info import Info, MontageMixin, _merge_info, _rename_comps, _unit2human, create_info
  from .._fiff.pick import _check_excludes_includes, _pick_data_channels, _picks_by_type, _picks_to_idx, _second_rules, channel_indices_by_type, channel_type, pick_channels, pick_info, pick_types
  from .._fiff.proj import setup_proj
  from .._fiff.reference import add_reference_channels, set_eeg_reference
  from .._fiff.tag import _rename_list
  from ..bem import _check_origin
  from ..defaults import HEAD_SIZE_DEFAULT, _handle_default
  from ..utils import _check_dict_keys, _check_fname, _check_option, _check_preload, _get_stim_channel, _on_missing, _validate_type, fill_doc, legacy, logger, verbose, warn
label_desc: Use image node_id 4 for calling a global function with example usage: rename_channels(info, mapping, allow_duplicates) without return types