docs: def parse_return_type(sourcecode):
      r"""
  
      parse_return_type
  
      Args:
          sourcecode (?):
  
      Returns:
          tuple: (return_type, return_name, return_header)
  
      Ignore:
          testcase
          automated_helpers query_vsone_verified
  
      CommandLine:
          python -m utool.util_inspect parse_return_type
          python -m utool.util_inspect --test-parse_return_type
  
  
      Example:
          >>> # ENABLE_DOCTEST
          >>> from utool.util_inspect import *  # NOQA
          >>> import utool as ut
          >>> sourcecode = ut.codeblock(
          ...     'def foo(tmp=False):\n'
          ...     '    bar = True\n'
          ...     '    return bar\n'
          ... )
          >>> returninfo = parse_return_type(sourcecode)
          >>> result = ut.repr2(returninfo)
          >>> print(result)
          ('?', 'bar', 'Returns', '')
  
      Example:
          >>> # ENABLE_DOCTEST
          >>> from utool.util_inspect import *  # NOQA
          >>> import utool as ut
          >>> sourcecode = ut.codeblock(
          ...     'def foo(tmp=False):\n'
          ...     '    return True\n'
          ... )
          >>> returninfo = parse_return_type(sourcecode)
          >>> result = ut.repr2(returninfo)
          >>> print(result)
          ('bool', 'True', 'Returns', '')
  
      Example:
          >>> # ENABLE_DOCTEST
          >>> from utool.util_inspect import *  # NOQA
          >>> import utool as ut
          >>> sourcecode = ut.codeblock(
          ...     'def foo(tmp=False):\n'
          ...     '    for i in range(2): \n'
          ...     '        yield i\n'
          ... )
          >>> returninfo = parse_return_type(sourcecode)
          >>> result = ut.repr2(returninfo)
          >>> print(result)
          ('?', 'i', 'Yields', '')
  
      Example:
          >>> # ENABLE_DOCTEST
          >>> from utool.util_inspect import *  # NOQA
          >>> import utool as ut
          >>> sourcecode = ut.codeblock(
          ...     'def foo(tmp=False):\n'
          ...     '    if tmp is True:\n'
          ...     '        return (True, False)\n'
          ...     '    elif tmp is False:\n'
          ...     '        return 1\n'
          ...     '    else:\n'
          ...     '        bar = baz()\n'
          ...     '        return bar\n'
          ... )
          >>> returninfo = parse_return_type(sourcecode)
          >>> result = ut.repr2(returninfo)
          >>> print(result)
          ('tuple', '(True, False)', 'Returns', '')
      """
      import ast
      return_type, return_name, return_header = (None, None, None)
  
      if sourcecode is None:
          return return_type, return_name, return_header, None
  
      sourcecode = 'from __future__ import print_function\n' + sourcecode
  
      pt = ast.parse(sourcecode)
      import utool as ut
      debug = ut.get_argflag('--debug-parse-return')
      #debug = True
  
      if debug:
          import astor
          print('\nSource:')
          print(sourcecode)
          print('\nParse:')
          print(astor.dump(pt))
          print('... starting')
  
      def print_visit(type_, node):
          if debug:
              import utool as ut
              print('+---')
              print('\nVISIT %s node = %r' % (type_, node,))
              print('node.__dict__ = ' + ut.repr2(node.__dict__, nl=True))
              print('L___')
  
      def get_node_name_and_type(node):
          if isinstance(node, ast.Tuple):
              tupnode_list = node.elts
              tupleid = '(%s)' % (', '.join([str(get_node_name_and_type(tupnode)[1]) for tupnode in tupnode_list]))
              node_type = 'tuple'
              node_name = tupleid
          elif isinstance(node, ast.Dict):
              node_type = 'dict'
              node_name = None
          elif isinstance(node, ast.Name):
              node_name = node.id
              node_type = '?'
              if node_name in ['True', 'False']:
                  node_type = 'bool'
              elif node_name == 'None':
                  node_type = 'None'
          elif six.PY3 and isinstance(node, ast.NameConstant):
              node_name = str(node.value)
              node_type = '?'
              if node_name in ['True', 'False', True, False]:
                  node_type = 'bool'
              elif node_name in ['None', None]:
                  node_type = 'None'
          else:
              node_name = None
              node_type = '?'
              #node_type = 'ADD_TO_GET_NODE_NAME_AND_TYPE: ' + str(type(node.value))
          return node_type, node_name
  
      class ReturnVisitor(ast.NodeVisitor):
          def init(self):
              self.found_nodes = []
              self.return_header = None
  
          def visit_FunctionDef(self, node):
              print_visit('FunctionDef', node)
              # TODO: ignore subfunction return types
              ast.NodeVisitor.generic_visit(self, node)
  
          def visit_Return(self, node):
              print_visit('Return', node)
              ast.NodeVisitor.generic_visit(self, node)
              return_value = node.value
              print_visit('ReturnValue', return_value)
              self.found_nodes.append(return_value)
              self.return_header = 'Returns'
  
          def visit_Yield(self, node):
              print_visit('Yield', node)
              ast.NodeVisitor.generic_visit(self, node)
              return_value = node.value
              print_visit('YieldValue', return_value)
              self.found_nodes.append(return_value)
              self.return_header = 'Yields'
      try:
          self = ReturnVisitor()
          self.init()
          self.visit(pt)
          return_header = self.return_header
          if len(self.found_nodes) > 0:
              # hack rectify multiple return values
              node = self.found_nodes[0]
              return_type, return_name = get_node_name_and_type(node)
          else:
              return_name = None
              return_type = 'None'
  
      except Exception:
          if debug:
              raise
  
      return_desc = ''
  
      if return_type == '?':
          tup = infer_arg_types_and_descriptions([return_name], [])
          argtype_list, argdesc_list, argdefault_list, hasdefault_list = tup
          return_type = argtype_list[0]
          return_desc = argdesc_list[0]
  
      return return_type, return_name, return_header, return_desc