code: def wrap_function(
      train_func: Callable[[Any], Any],
      warn: bool = True,
      name: Optional[str] = None,
  ) -> Type["FunctionTrainable"]:
      inherit_from = (FunctionTrainable,)
  
      if hasattr(train_func, "__mixins__"):
          inherit_from = train_func.__mixins__ + inherit_from
  
      func_args = inspect.getfullargspec(train_func).args
      use_checkpoint = _detect_checkpoint_function(train_func)
      use_config_single = _detect_config_single(train_func)
      use_reporter = _detect_reporter(train_func)
  
      if use_checkpoint:
          raise DeprecationWarning(_CHECKPOINT_DIR_ARG_DEPRECATION_MSG)
  
      if use_reporter:
          raise DeprecationWarning(_REPORTER_ARG_DEPRECATION_MSG)
  
      if not use_config_single:
          # use_reporter is hidden
          raise ValueError(
              "Unknown argument found in the Trainable function. "
              "The function args must include a 'config' positional parameter."
              "Found: {}".format(func_args)
          )
  
      resources = getattr(train_func, "_resources", None)
  
      class ImplicitFunc(*inherit_from):
          _name = name or (
              train_func.__name__
              if hasattr(train_func, "__name__")
              else "func"
          )
  
          def __repr__(self):
              return self._name
  
          def _trainable_func(self, config):
              fn = partial(train_func, config)
  
              def handle_output(output):
                  if not output:
                      return
                  elif isinstance(output, dict):
                      ray.train.report(output)
                  elif isinstance(output, Number):
                      ray.train.report({DEFAULT_METRIC: output})
                  else:
                      raise ValueError(
                          "Invalid return or yield value. Either return/yield "
                          "a single number or a dictionary object in your "
                          "trainable function."
                      )
  
              output = None
              if inspect.isgeneratorfunction(train_func):
                  for output in fn():
                      handle_output(output)
              else:
                  output = fn()
                  handle_output(output)
  
              # If train_func returns, we need to notify the main event loop
              # of the last result while avoiding double logging. This is done
              # with the keyword RESULT_DUPLICATE -- see tune/tune_controller.py.
              ray.train.report({RESULT_DUPLICATE: True})
              return output
  
          @classmethod
          def default_resource_request(
              cls, config: Dict[str, Any]
          ) -> Optional[PlacementGroupFactory]:
              if not isinstance(
                  resources, PlacementGroupFactory
              ) and callable(resources):
                  return resources(config)
              return resources
  
      return ImplicitFunc
  
imports: import inspect
  import logging
  import os
  from functools import partial
  from numbers import Number
  from typing import Any, Callable, Dict, Optional, Type
  from ray.air._internal.util import StartTraceback, RunnerThread
  import queue
  from ray.air.constants import _ERROR_FETCH_TIMEOUT
  import ray.train
  from ray.train._internal.checkpoint_manager import _TrainingResult
  from ray.train._internal.session import init_session, get_session, shutdown_session, _TrainSession, TrialInfo
  from ray.tune.execution.placement_groups import PlacementGroupFactory
  from ray.tune.result import DEFAULT_METRIC, RESULT_DUPLICATE, SHOULD_CHECKPOINT
  from ray.tune.trainable import Trainable
  from ray.tune.utils import _detect_checkpoint_function, _detect_config_single, _detect_reporter
  from ray.util.annotations import DeveloperAPI
label_desc: Use image node_id 1 for calling a global function with example usage: wrap_function(train_func, warn, name) and returns: ImplicitFunc, self, output, resources, resources