class_docstr: Utility to find and replace the `source_type` in Python objects.
  
  `source_type` can either be a single type or a tuple of multiple types.
  
  The caller must first call `find_nodes()`, then compute a replacement table and
  pass it to `replace_nodes`.
  
  This uses cloudpickle under the hood, so all sub-objects that are not `source_type`
  must be serializable.
  
  Args:
      source_type: the type(s) of object to find and replace. Default to DAGNodeBase.
code: def __init__(self, source_type: Union[Type, Tuple] = DAGNodeBase):
      self.source_type = source_type
      # Buffer to keep intermediate serialized state.
      self._buf = io.BytesIO()
      # List of top-level SourceType found during the serialization pass.
      self._found = None
      # List of other objects found during the serialization pass.
      # This is used to store references to objects so they won't be
      # serialized by cloudpickle.
      self._objects = []
      # Replacement table to consult during deserialization.
      self._replace_table: Dict[SourceType, TransformedType] = None
      _instances[id(self)] = self
      super().__init__(self._buf)
  
file_path: ray/python/ray/dag/py_obj_scanner.py
imports: import io
  from typing import Any, Dict, Generic, List, Tuple, Type, TypeVar, Union
  import pickle
  import ray
  from ray.dag.base import DAGNodeBase
label_desc: Use image node_id 1 to create a new _PyObjScanner object from inherited base classes: ray.cloudpickle, Generic with example: obj = _PyObjScanner(source_type)