<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def restrict_access(scope, mod=None, login=None, oauth_only=False, generator_called=False):
 """Restrict function access unless the user has the necessary permissions. Raises one of the following exceptions when appropriate: * LoginRequired * LoginOrOAuthRequired * the scope attribute will provide the necessary scope name * ModeratorRequired * ModeratorOrOAuthRequired * the scope attribute will provide the necessary scope name :param scope: Indicate the scope that is required for the API call. None or False must be passed to indicate that no scope handles the API call. All scopes save for `read` imply login=True. Scopes with 'mod' in their name imply mod=True. :param mod: Indicate that a moderator is required. Implies login=True. :param login: Indicate that a login is required. :param oauth_only: Indicate that only OAuth is supported for the function. :param generator_called: Indicate that the function consists solely of exhausting one or more oauth_generator wrapped generators. This is because the oauth_generator itself will determine whether or not to use the oauth domain. Returned data is not modified. This decorator assumes that all mod required functions fit one of these categories: * have the subreddit as the first argument (Reddit instance functions) or have a subreddit keyword argument * are called upon a subreddit object (Subreddit RedditContentObject) * are called upon a RedditContent object with attribute subreddit """

    if not scope and oauth_only:
        raise TypeError('`scope` must be set when `oauth_only` is set')

    mod = mod is not False and (mod or scope and 'mod' in scope)
    login = login is not False and (login or mod or scope and scope != 'read')

    @decorator.decorator
    def wrap(function, *args, **kwargs):
        if args[0] is None:  # Occurs with (un)friend
            assert login
            raise errors.LoginRequired(function.__name__)
        # This segment of code uses hasattr to determine what instance type
        # the function was called on. We could use isinstance if we wanted
        # to import the types at runtime (decorators is used by all the
        # types).
        if mod:
            if hasattr(args[0], 'reddit_session'):
                # Defer access until necessary for RedditContentObject.
                # This is because scoped sessions may not require this
                # attribute to exist, thus it might not be set.
                from .objects import Subreddit
                subreddit = args[0] if isinstance(args[0], Subreddit) \
                    else False
            else:
                subreddit = kwargs.get(
                    'subreddit', args[1] if len(args) > 1 else None)
                if subreddit is None:  # Try the default value
                    defaults = six.get_function_defaults(function)
                    subreddit = defaults[0] if defaults else None
        else:
            subreddit = None

        obj = getattr(args[0], 'reddit_session', args[0])
        # This function sets _use_oauth for one time use only.
        # Verify that statement is actually true.
        assert not obj._use_oauth  # pylint: disable=W0212

        if scope and obj.has_scope(scope):
            obj._use_oauth = not generator_called  # pylint: disable=W0212
        elif oauth_only:
            raise errors.OAuthScopeRequired(function.__name__, scope)
        elif login and obj.is_logged_in():
            if subreddit is False:
                # Now fetch the subreddit attribute. There is no good
                # reason for it to not be set during a logged in session.
                subreddit = args[0].subreddit
            if mod and not _is_mod_of_all(obj.user, subreddit):
                if scope:
                    raise errors.ModeratorOrScopeRequired(
                        function.__name__, scope)
                raise errors.ModeratorRequired(function.__name__)
        elif login:
            if scope:
                raise errors.LoginOrScopeRequired(function.__name__, scope)
            raise errors.LoginRequired(function.__name__)
        try:
            return function(*args, **kwargs)
        finally:
            obj._use_oauth = False  # pylint: disable=W0212
    return wrap