code: def _make_decorator_function(
      context_manager_cls: InternalAPIContextBase,
      process_return=True,
      needs_self: bool = False,
      **defaults,
  ) -> typing.Callable[..., _DecoratorType]:
      # This function generates a function to be applied as decorator to a
      # wrapped function. For example:
      #
      #       a_decorator = _make_decorator_function(...)
      #
      #       ...
      #
      #       @a_decorator(...)  # apply decorator where appropriate
      #       def fit(X, y):
      #           ...
      #
      # Note: The decorator function can be partially closed by directly
      # providing keyword arguments to this function to be used as defaults.
  
      def decorator_function(
          input_arg: str = ...,
          target_arg: str = ...,
          get_output_type: bool = False,
          set_output_type: bool = False,
          get_output_dtype: bool = False,
          set_output_dtype: bool = False,
          set_n_features_in: bool = False,
      ) -> _DecoratorType:
          def decorator_closure(func):
              # This function constitutes the closed decorator that will return
              # the wrapped function. It performs function introspection at
              # function definition time. The code within the wrapper function is
              # executed at function execution time.
  
              # Prepare arguments
              sig = inspect.signature(func, follow_wrapped=True)
  
              has_self = _has_self(sig)
              if needs_self and not has_self:
                  raise Exception("No self found on function!")
  
              if input_arg is not None and (
                  set_output_type
                  or set_output_dtype
                  or set_n_features_in
                  or get_output_type
              ):
                  input_arg_ = _find_arg(sig, input_arg or "X", 0)
              else:
                  input_arg_ = None
  
              if set_output_dtype or (
                  get_output_dtype and not has_self
              ):
                  target_arg_ = _find_arg(sig, target_arg or "y", 1)
              else:
                  target_arg_ = None
  
              @_wrap_once(func)
              def wrapper(*args, **kwargs):
                  # Wraps the decorated function, executed at runtime.
  
                  with context_manager_cls(func, args) as cm:
                      self_val = args[0] if has_self else None
  
                      if input_arg_:
                          input_val = _get_value(
                              args, kwargs, *input_arg_
                          )
                      else:
                          input_val = None
                      if target_arg_:
                          target_val = _get_value(
                              args, kwargs, *target_arg_
                          )
                      else:
                          target_val = None
  
                      if set_output_type:
                          assert self_val is not None
                          self_val._set_output_type(input_val)
                      if set_output_dtype:
                          assert self_val is not None
                          self_val._set_target_dtype(target_val)
                      if (
                          set_n_features_in
                          and len(input_val.shape) >= 2
                      ):
                          assert self_val is not None
                          self_val._set_n_features_in(input_val)
  
                      if get_output_type:
                          if self_val is None:
                              assert input_val is not None
                              out_type = iu.determine_array_type(
                                  input_val
                              )
                          elif input_val is None:
                              out_type = self_val.output_type
                              if out_type == "input":
                                  out_type = self_val._input_type
                          else:
                              out_type = self_val._get_output_type(
                                  input_val
                              )
  
                          set_api_output_type(out_type)
  
                      if get_output_dtype:
                          if self_val is None:
                              assert target_val is not None
                              output_dtype = iu.determine_array_dtype(
                                  target_val
                              )
                          else:
                              output_dtype = (
                                  self_val._get_target_dtype()
                              )
  
                          set_api_output_dtype(output_dtype)
  
                      if process_return:
                          ret = func(*args, **kwargs)
                      else:
                          return func(*args, **kwargs)
  
                  return cm.process_return(ret)
  
              return wrapper
  
          return decorator_closure
  
      return functools.partial(decorator_function, **defaults)
  
imports: import contextlib
  import functools
  import inspect
  import typing
  import warnings
  from cuml.internals import input_utils
  from cuml.internals.api_context_managers import BaseReturnAnyCM
  from cuml.internals.api_context_managers import BaseReturnArrayCM
  from cuml.internals.api_context_managers import BaseReturnGenericCM
  from cuml.internals.api_context_managers import BaseReturnSparseArrayCM
  from cuml.internals.api_context_managers import InternalAPIContextBase
  from cuml.internals.api_context_managers import ReturnAnyCM
  from cuml.internals.api_context_managers import ReturnArrayCM
  from cuml.internals.api_context_managers import ReturnGenericCM
  from cuml.internals.api_context_managers import ReturnSparseArrayCM
  from cuml.internals.api_context_managers import set_api_output_dtype
  from cuml.internals.api_context_managers import set_api_output_type
  from cuml.internals.constants import CUML_WRAPPED_FLAG
  from cuml.internals.global_settings import GlobalSettings
  from cuml.internals.memory_utils import using_output_type
  from cuml.internals.type_utils import _DecoratorType, wraps_typed
  from cuml.internals import logger
label_desc: Use image node_id 5 for calling a global function with example usage: _make_decorator_function(context_manager_cls, process_return, needs_) and returns: functools, decorator_closure, wrapper, cm, func