nodes: 0, module; 1, function_definition; 2, function_name:expand_source_files; 3, parameters; 4, block; 5, identifier:filenames; 6, default_parameter; 7, expression_statement; 8, expression_statement; 9, for_statement; 10, return_statement; 11, identifier:cwd; 12, None; 13, comment:"""Expand a list of filenames passed in as sources.
  
      This is a helper function for handling command line arguments that specify a
      list of source files and directories.
  
      Any directories in filenames will be scanned recursively for .py files.
      Any files that do not end with ".py" will be dropped.
  
      Args:
          filenames: A list of filenames to process.
          cwd: An optional working directory to expand relative paths
      Returns:
          A list of sorted full paths to .py files
      """; 14, assignment; 15, identifier:f; 16, call; 17, block; 18, call; 19, identifier:out; 20, list; 21, identifier:expand_paths; 22, argument_list; 23, if_statement; 24, identifier:sorted; 25, argument_list; 26, identifier:filenames; 27, identifier:cwd; 28, call; 29, comment:# If we have a directory, collect all the .py files within it.; 30, block; 31, else_clause; 32, call; 33, attribute; 34, argument_list; 35, expression_statement; 36, block; 37, identifier:set; 38, argument_list; 39, attribute; 40, identifier:isdir; 41, identifier:f; 42, augmented_assignment; 43, if_statement; 44, identifier:out; 45, identifier:os; 46, identifier:path; 47, identifier:out; 48, call; 49, call; 50, block; 51, identifier:collect_files; 52, argument_list; 53, attribute; 54, argument_list; 55, expression_statement; 56, identifier:f; 57, string:".py"; 58, identifier:f; 59, identifier:endswith; 60, string:".py"; 61, call; 62, attribute; 63, argument_list; 64, identifier:out; 65, identifier:append; 66, identifier:f
code: def expand_source_files(filenames, cwd=None):
      """Expand a list of filenames passed in as sources.
  
      This is a helper function for handling command line arguments that specify a
      list of source files and directories.
  
      Any directories in filenames will be scanned recursively for .py files.
      Any files that do not end with ".py" will be dropped.
  
      Args:
          filenames: A list of filenames to process.
          cwd: An optional working directory to expand relative paths
      Returns:
          A list of sorted full paths to .py files
      """
      out = []
      for f in expand_paths(filenames, cwd):
          if os.path.isdir(f):
              # If we have a directory, collect all the .py files within it.
              out += collect_files(f, ".py")
          else:
              if f.endswith(".py"):
                  out.append(f)
      return sorted(set(out))