code: def _get_base_return_type(class_name, attr):
      if (
          not hasattr(attr, "__annotations__")
          or "return" not in attr.__annotations__
      ):
          return None
  
      try:
          type_hints = typing.get_type_hints(attr)
  
          if "return" in type_hints:
              ret_type = type_hints["return"]
  
              is_generic = isinstance(ret_type, typing._GenericAlias)
  
              if is_generic:
                  return _process_generic(ret_type)
              elif issubclass(ret_type, CumlArray):
                  return "array"
              elif issubclass(ret_type, SparseCumlArray):
                  return "sparsearray"
              elif issubclass(ret_type, cuml.internals.base.Base):
                  return "base"
              else:
                  return None
      except NameError:
          # A NameError is raised if the return type is the same as the
          # type being defined (which is incomplete). Check that here and
          # return base if the name matches
          # Cython 3 changed to preferring types rather than strings for
          # annotations. Strings end up wrapped in an extra layer of quotes,
          # which we have to replace here.
          if (
              attr.__annotations__["return"].replace("'", "")
              == class_name
          ):
              return "base"
      except Exception:
          assert False, "Shouldn't get here"
          return None
  
      return None
  
imports: import cuml.internals
  import typing
  from cuml.internals.array import CumlArray
  from cuml.internals.array_sparse import SparseCumlArray
label_desc: Use image node_id 2 for calling a global function with example usage: _get_base_return_type(class_name, attr) and returns: None, None, None, _process_generic, str, str, str, str, None