nodes: 0, module; 1, function_definition; 2, function_name:get_upstream_artifacts_full_paths_per_task_id; 3, parameters; 4, block; 5, identifier:context; 6, expression_statement; 7, expression_statement; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, expression_statement; 12, for_statement; 13, return_statement; 14, comment:"""List the downloaded upstream artifacts.
  
      Args:
          context (scriptworker.context.Context): the scriptworker context.
  
      Returns:
          dict, dict: lists of the paths to upstream artifacts, sorted by task_id.
              First dict represents the existing upstream artifacts. The second one
              maps the optional artifacts that couldn't be downloaded
  
      Raises:
          scriptworker.exceptions.ScriptWorkerTaskException: when an artifact doesn't exist.
  
      """; 15, assignment; 16, assignment; 17, assignment; 18, assignment; 19, assignment; 20, pattern_list; 21, identifier:task_ids_and_relative_paths; 22, block; 23, expression_list; 24, identifier:upstream_artifacts; 25, subscript; 26, identifier:task_ids_and_relative_paths; 27, list_comprehension; 28, identifier:optional_artifacts_per_task_id; 29, call; 30, identifier:upstream_artifacts_full_paths_per_task_id; 31, dictionary; 32, identifier:failed_paths_per_task_id; 33, dictionary; 34, identifier:task_id; 35, identifier:paths; 36, for_statement; 37, identifier:upstream_artifacts_full_paths_per_task_id; 38, identifier:failed_paths_per_task_id; 39, subscript; 40, string; 41, tuple; 42, for_in_clause; 43, identifier:get_optional_artifacts_per_task_id; 44, argument_list; 45, identifier:path; 46, identifier:paths; 47, block; 48, attribute; 49, string; 50, string_content:upstreamArtifacts; 51, subscript; 52, subscript; 53, identifier:artifact_definition; 54, identifier:upstream_artifacts; 55, identifier:upstream_artifacts; 56, try_statement; 57, identifier:context; 58, identifier:task; 59, string_content:payload; 60, identifier:artifact_definition; 61, string; 62, identifier:artifact_definition; 63, string; 64, block; 65, except_clause; 66, string_content:taskId; 67, string_content:paths; 68, expression_statement; 69, expression_statement; 70, identifier:ScriptWorkerTaskException; 71, block; 72, assignment; 73, call; 74, if_statement; 75, identifier:path_to_add; 76, call; 77, identifier:add_enumerable_item_to_dict; 78, argument_list; 79, comparison_operator:path in optional_artifacts_per_task_id.get(task_id, []); 80, block; 81, else_clause; 82, identifier:get_and_check_single_upstream_artifact_full_path; 83, argument_list; 84, keyword_argument; 85, keyword_argument; 86, keyword_argument; 87, identifier:path; 88, call; 89, expression_statement; 90, expression_statement; 91, block; 92, identifier:context; 93, identifier:task_id; 94, identifier:path; 95, identifier:dict_; 96, identifier:upstream_artifacts_full_paths_per_task_id; 97, identifier:key; 98, identifier:task_id; 99, identifier:item; 100, identifier:path_to_add; 101, attribute; 102, argument_list; 103, call; 104, call; 105, raise_statement; 106, identifier:optional_artifacts_per_task_id; 107, identifier:get; 108, identifier:task_id; 109, list; 110, attribute; 111, argument_list; 112, identifier:add_enumerable_item_to_dict; 113, argument_list; 114, identifier:log; 115, identifier:warning; 116, call; 117, keyword_argument; 118, keyword_argument; 119, keyword_argument; 120, attribute; 121, argument_list; 122, identifier:dict_; 123, identifier:failed_paths_per_task_id; 124, identifier:key; 125, identifier:task_id; 126, identifier:item; 127, identifier:path; 128, string:'Optional artifact "{}" of task "{}" not found'; 129, identifier:format; 130, identifier:path; 131, identifier:task_id
code: def get_upstream_artifacts_full_paths_per_task_id(context):
      """List the downloaded upstream artifacts.
  
      Args:
          context (scriptworker.context.Context): the scriptworker context.
  
      Returns:
          dict, dict: lists of the paths to upstream artifacts, sorted by task_id.
              First dict represents the existing upstream artifacts. The second one
              maps the optional artifacts that couldn't be downloaded
  
      Raises:
          scriptworker.exceptions.ScriptWorkerTaskException: when an artifact doesn't exist.
  
      """
      upstream_artifacts = context.task['payload']['upstreamArtifacts']
      task_ids_and_relative_paths = [
          (artifact_definition['taskId'], artifact_definition['paths'])
          for artifact_definition in upstream_artifacts
      ]
  
      optional_artifacts_per_task_id = get_optional_artifacts_per_task_id(upstream_artifacts)
  
      upstream_artifacts_full_paths_per_task_id = {}
      failed_paths_per_task_id = {}
      for task_id, paths in task_ids_and_relative_paths:
          for path in paths:
              try:
                  path_to_add = get_and_check_single_upstream_artifact_full_path(context, task_id, path)
                  add_enumerable_item_to_dict(
                      dict_=upstream_artifacts_full_paths_per_task_id,
                      key=task_id, item=path_to_add
                  )
              except ScriptWorkerTaskException:
                  if path in optional_artifacts_per_task_id.get(task_id, []):
                      log.warning('Optional artifact "{}" of task "{}" not found'.format(path, task_id))
                      add_enumerable_item_to_dict(
                          dict_=failed_paths_per_task_id,
                          key=task_id, item=path
                      )
                  else:
                      raise
  
      return upstream_artifacts_full_paths_per_task_id, failed_paths_per_task_id