code: def slice_alike_object_to_indices(
      slice_alike_object: Union[
          slice, int, Iterable[int], Tensor, ndarray
      ],
      max_length: int,
  ) -> Iterable[int]:
      """
      Utility function used to obtain the sequence of indices given a slice
      object.
  
      This fuction offers some additional flexibility by also accepting generic
      Iterable[int], PyTorch Tensor and NumPy ndarray.
  
      Beware that this function only supports 1-D slicing.
  
      This will also take care of managing negative indices.
  
      If the input object is a native slice or int, then negative indices will be
      managed as usual (like when used on a native Python list). If a tensor or
      generic iterable is passed, then indices will be transformed as they where
      int(s).
      """
  
      indexes_iterator: Iterable[int]
      check_bounds = True
  
      # Makes dataset sliceable
      if isinstance(slice_alike_object, (int, np.integer)):
          # Single index (Python native or NumPy)
          indexes_iterator = [int(slice_alike_object)]
      elif isinstance(slice_alike_object, slice):
          # Slice object (Python native)
          indexes_iterator = range(
              *slice_alike_object.indices(max_length)
          )
          check_bounds = False
      elif hasattr(slice_alike_object, "shape"):
          tensor_shape = getattr(slice_alike_object, "shape")
          if len(tensor_shape) == 0:
              # Manages 0-d ndarray / Tensor
              indexes_iterator = [int(slice_alike_object)]  # type: ignore
          else:
              if len(tensor_shape) == 1:
                  if tensor_shape[0] == 0:
                      # Empty Tensor (NumPy or PyTorch)
                      indexes_iterator = []
                  else:
                      # Flat Tensor (NumPy or PyTorch)
                      indexes_iterator = slice_alike_object.tolist()  # type: ignore
              else:
                  # Last attempt
                  indexes_iterator = [slice_alike_object.item()]  # type: ignore
              if len(indexes_iterator) > 0:  # type: ignore
                  assert isinstance(indexes_iterator, int)
      else:
          # Generic iterable
          indexes_iterator = slice_alike_object  # type: ignore
  
      if check_bounds:
          # Executed only if slice_alike_object is not a slice
          # (because "slice" already takes care of managing negative indices)
  
          # This will:
          # 1) transform negative indices to positive indices
          # 2) check that max(indices) < max_length
          # 3) check that min(indices) >= 0
  
          iterator_as_list = []
          for idx in indexes_iterator:
              assert isinstance(idx, int)
              if idx >= 0:
                  if idx >= max_length:
                      raise IndexError(
                          f"Index {idx} out of range for sequence "
                          f"of length {max_length}"
                      )
              else:
                  pos_idx = max_length - idx  # Negative to positive
                  if pos_idx < 0:
                      raise IndexError(
                          f"Index {idx} out of range for sequence "
                          f"of length {max_length}"
                      )
                  idx = pos_idx
  
              iterator_as_list.append(idx)
          indexes_iterator = iterator_as_list
  
      return indexes_iterator
  
imports: from abc import ABC, abstractmethod
  import bisect
  import copy
  from typing import Iterator, overload
  from typing_extensions import final
  import numpy
  from numpy import ndarray
  from torch import Tensor
  from torch.utils.data import Subset
  from .dataset_definitions import IDatasetWithTargets
  from typing import Sequence, List, Iterable, Union, Optional, TypeVar, Callable, Generic
label_desc: Use image node_id 3 for calling a global function with example usage: slice_alike_object_to_indices(slice_alike_object, max_length) and returns: indexes_iterator