nodes: 0, module; 1, function_definition; 2, function_name:patch_ast; 3, parameters; 4, block; 5, identifier:node; 6, identifier:source; 7, default_parameter; 8, expression_statement; 9, if_statement; 10, expression_statement; 11, expression_statement; 12, return_statement; 13, identifier:sorted_children; 14, False; 15, comment:"""Patches the given node
  
      After calling, each node in `node` will have a new field named
      `region` that is a tuple containing the start and end offsets
      of the code that generated it.
  
      If `sorted_children` is true, a `sorted_children` field will
      be created for each node, too.  It is a list containing child
      nodes as well as whitespaces and comments that occur between
      them.
  
      """; 16, call; 17, block; 18, assignment; 19, call; 20, identifier:node; 21, identifier:hasattr; 22, argument_list; 23, return_statement; 24, identifier:walker; 25, call; 26, attribute; 27, argument_list; 28, identifier:node; 29, string; 30, identifier:node; 31, identifier:_PatchingASTWalker; 32, argument_list; 33, identifier:ast; 34, identifier:call_for_nodes; 35, identifier:node; 36, identifier:walker; 37, string_content:region; 38, identifier:source; 39, keyword_argument; 40, identifier:children; 41, identifier:sorted_children
code: def patch_ast(node, source, sorted_children=False):
      """Patches the given node
  
      After calling, each node in `node` will have a new field named
      `region` that is a tuple containing the start and end offsets
      of the code that generated it.
  
      If `sorted_children` is true, a `sorted_children` field will
      be created for each node, too.  It is a list containing child
      nodes as well as whitespaces and comments that occur between
      them.
  
      """
      if hasattr(node, 'region'):
          return node
      walker = _PatchingASTWalker(source, children=sorted_children)
      ast.call_for_nodes(node, walker)
      return node