code: def step(self, new_step):
      old_step = self._step
      self._step = new_step
  
      # Update outputs of old step to point to the new step
      # Note that the dataplaceholders keep the name from the old step
      # TODO: Maybe the output dataplaceholders should be replaced too
      for output in self._outputs:
          output._step = new_step
  
      # Special process to transfer functions:
      # if it is a bound method get the corresponding method bound to the
      # new step otherwise leave it as is.
      # Note that Step._check_[fit_]compute_func guarantees step.[fit_]compute_func
      # is a callable (i.e: assert callable(old_step.[fit_]compute_func) passes)
      for attr_name in ("fit_func", "compute_func", "fit_compute_func"):
          old_attr = getattr(self, attr_name)
          if inspect.ismethod(old_attr):
              assert old_attr.__self__ is old_step
              setattr(
                  self, attr_name, getattr(new_step, old_attr.__name__)
              )
  
imports: import inspect
  import warnings
  from typing import Any, Callable, Dict, List, Optional, Union, TYPE_CHECKING
  from baikal._core.data_placeholder import DataPlaceholder, is_data_placeholder_list
  from baikal._core.utils import listify, make_name, make_repr
label_desc: Use image node_id 3 for calling the Node obj's underlying member method code with example usage: obj.step(new_step) without return types