code: def make_action_immutable(obj):
      """Flags actions immutable to notify users when trying to change them.
  
      Can also be used with any tree-like structure containing either
      dictionaries, numpy arrays or already immutable objects per se.
      Note, however that `tree.map_structure()` will in general not
      include the shallow object containing all others and therefore
      immutability will hold only for all objects contained in it.
      Use `tree.traverse(fun, action, top_down=False)` to include
      also the containing object.
  
      Args:
          obj: The object to be made immutable.
  
      Returns:
          The immutable object.
  
      .. testcode::
          :skipif: True
  
          import tree
          import numpy as np
          from ray.rllib.utils.numpy import make_action_immutable
          arr = np.arange(1,10)
          d = dict(a = 1, b = (arr, arr))
          tree.traverse(make_action_immutable, d, top_down=False)
      """
      if isinstance(obj, np.ndarray):
          obj.setflags(write=False)
          return obj
      elif isinstance(obj, OrderedDict):
          return MappingProxyType(dict(obj))
      elif isinstance(obj, dict):
          return MappingProxyType(obj)
      else:
          return obj
  
imports: from collections import OrderedDict
  from gymnasium.spaces import Discrete, MultiDiscrete
  import numpy
  import tree
  from types import MappingProxyType
  from typing import List, Optional
  from ray.rllib.utils.annotations import PublicAPI
  from ray.rllib.utils.deprecation import Deprecated
  from ray.rllib.utils.framework import try_import_tf, try_import_torch
  from ray.rllib.utils.typing import SpaceStruct, TensorType, TensorStructType, Union
label_desc: Use image node_id 6 for calling a global function with example usage: make_action_immutable(obj) and returns: obj, MappingProxyType, MappingProxyType, obj