code: def async_variant(normal_func):  # type: ignore
      def decorator(async_func):  # type: ignore
          pass_arg = _PassArg.from_obj(normal_func)
          need_eval_context = pass_arg is None
  
          if pass_arg is _PassArg.environment:
  
              def is_async(args: t.Any) -> bool:
                  return t.cast(bool, args[0].is_async)
  
          else:
  
              def is_async(args: t.Any) -> bool:
                  return t.cast(bool, args[0].environment.is_async)
  
          # Take the doc and annotations from the sync function, but the
          # name from the async function. Pallets-Sphinx-Themes
          # build_function_directive expects __wrapped__ to point to the
          # sync function.
          async_func_attrs = ("__module__", "__name__", "__qualname__")
          normal_func_attrs = tuple(
              set(WRAPPER_ASSIGNMENTS).difference(async_func_attrs)
          )
  
          @wraps(normal_func, assigned=normal_func_attrs)
          @wraps(async_func, assigned=async_func_attrs, updated=())
          def wrapper(*args, **kwargs):  # type: ignore
              b = is_async(args)
  
              if need_eval_context:
                  args = args[1:]
  
              if b:
                  return async_func(*args, **kwargs)
  
              return normal_func(*args, **kwargs)
  
          if need_eval_context:
              wrapper = pass_eval_context(wrapper)
  
          wrapper.jinja_async_variant = True
          return wrapper
  
      return decorator
  
imports: import inspect
  import typing
  from functools import WRAPPER_ASSIGNMENTS
  from functools import wraps
  from .utils import _PassArg
  from .utils import pass_eval_context
label_desc: Use image node_id 1 for calling a global function with example usage: async_variant(normal_func) and returns: decorator, wrapper, normal_func, t, t, async_func