code: def info(
      prefixes,
      num_workers=None,
      inputs=None,
      verbose=None,
      listing=None,
      s3role=None,
      s3sessionvars=None,
      s3clientparams=None,
      inject_failure=0,
  ):
      s3config = S3Config(
          s3role,
          json.loads(s3sessionvars) if s3sessionvars else None,
          json.loads(s3clientparams) if s3clientparams else None,
      )
  
      # Construct a list of URL (prefix) objects
      urllist = []
      to_iterate, is_transient_retry = _populate_prefixes(
          prefixes, inputs
      )
      for idx, prefix, url, _ in to_iterate:
          src = urlparse(url)
          url = S3Url(
              url=url,
              bucket=src.netloc,
              path=src.path.lstrip("/"),
              local=generate_local_path(url, suffix="info"),
              prefix=prefix,
              range=None,
              idx=idx,
          )
          if src.scheme != "s3":
              exit(ERROR_INVALID_URL, url)
          urllist.append(url)
  
      sz_results = process_urls(
          "info",
          urllist,
          verbose,
          inject_failure,
          num_workers,
          s3config,
      )
  
      retry_lines = []
      out_lines = []
      for idx, sz in enumerate(sz_results):
          url = urllist[idx]
          if listing and sz != -ERROR_TRANSIENT:
              out_lines.append(
                  format_result_line(
                      url.idx, url.prefix, url.url, url.local
                  )
                  + "\n"
              )
          else:
              retry_lines.append(
                  "%d %s <norange>\n"
                  % (
                      url.idx,
                      url_quote(url.url).decode(encoding="utf-8"),
                  )
              )
              if not is_transient_retry:
                  out_lines.append(
                      "%d %s\n"
                      % (url.idx, TRANSIENT_RETRY_LINE_CONTENT)
                  )
  
      if out_lines:
          sys.stdout.writelines(out_lines)
          sys.stdout.flush()
  
      if retry_lines:
          sys.stderr.write("%s\n" % TRANSIENT_RETRY_START_LINE)
          sys.stderr.writelines(retry_lines)
          sys.stderr.flush()
          sys.exit(ERROR_TRANSIENT)
  
imports: from __future__ import print_function
  import json
  import time
  import math
  import random
  import re
  import sys
  import os
  import traceback
  from collections import namedtuple
  from functools import partial, wraps
  from hashlib import sha1
  from tempfile import NamedTemporaryFile
  from multiprocessing import Process, Queue
  from itertools import starmap, chain, islice
  from boto3.s3.transfer import TransferConfig
  from metaflow._vendor import click
  from metaflow.util import TempDir, url_quote, url_unquote
  from metaflow.multicore_utils import parallel_map
  from metaflow.plugins.datatools.s3.s3util import aws_retry, read_in_chunks, get_timestamp, TRANSIENT_RETRY_LINE_CONTENT, TRANSIENT_RETRY_START_LINE
  import metaflow.tracing
label_desc: Use image node_id 21 for calling a global function with example usage: info(prefixes, num_workers, inputs, verbose, listing, s3role, s3sessionvars, s3clientparams, inject_failure) without return types