code: def print_provider_info(name, providers, func):
      if not isinstance(providers, List):
          providers = [providers]
      providers = list(providers)
      if len(providers) > 1:
          providers[
              -2
          ] = f"{str(providers[-2])} and {str(providers[-1])}"
          providers = providers[:-1]
      message = f"Using '{name}' provided by {', '.join(str(provider) for provider in providers)}."
  
      def build_wrapper(func):
          @functools.wraps(func)
          def wrapper(*args, **kwargs):
              rank_zero_info(message)
              return func(*args, **kwargs)
  
          return wrapper
  
      wrapper = build_wrapper(func)
  
      if inspect.isclass(func):
          callables = [
              f
              for f in dir(func)
              if callable(getattr(func, f)) and not f.startswith("_")
          ]
          for c in callables:
              setattr(wrapper, c, build_wrapper(getattr(func, c)))
  
      return wrapper
  
imports: import functools
  import inspect
  import itertools
  from typing import Any, Callable, Dict, List, Optional, Union
  from pytorch_lightning.utilities import rank_zero_info
  from flash.core.utilities.providers import Provider
label_desc: Use image node_id 1 for calling a global function with example usage: print_provider_info(name, providers, func) and returns: wrapper, wrapper, func