def METHOD_NAME(function=None,
             data_flow_kernel: Optional[DataFlowKernel] = None,
             cache: bool = False,
             ignore_for_cache: Optional[List[str]] = None):
    """Decorator function for making join apps
    Parameters
    ----------
    function : function
        Do not pass this keyword argument directly. This is needed in order to allow for omitted parenthesis,
        for example, ``@python_app`` if using all defaults or ``@python_app(walltime=120)``. If the
        decorator is used alone, function will be the actual function being decorated, whereas if it
        is called with arguments, function will be None. Default is None.
    data_flow_kernel : DataFlowKernel
        The :class:`~parsl.dataflow.dflow.DataFlowKernel` responsible for managing this app. This can
        be omitted only after calling :meth:`parsl.dataflow.dflow.DataFlowKernelLoader.load`. Default is None.
    cache : bool
        Enable caching of the app call. Default is False.
    """
    from parsl.app.python import PythonApp
    def decorator(func):
        def wrapper(f):
            return PythonApp(f,
                             data_flow_kernel=data_flow_kernel,
                             cache=cache,
                             executors=["_parsl_internal"],
                             ignore_for_cache=ignore_for_cache,
                             join=True)
        return wrapper(func)
    if function is not None:
        return decorator(function)
    return decorator