You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					458 lines
				
				16 KiB
			
		
		
			
		
	
	
					458 lines
				
				16 KiB
			| 
								 
											8 years ago
										 
									 | 
							
								# -*- coding: utf-8 -*-
							 | 
						||
| 
								 | 
							
								"""
							 | 
						||
| 
								 | 
							
								    flask.ctx
							 | 
						||
| 
								 | 
							
								    ~~~~~~~~~
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Implements the objects required to keep the context.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    :copyright: © 2010 by the Pallets team.
							 | 
						||
| 
								 | 
							
								    :license: BSD, see LICENSE for more details.
							 | 
						||
| 
								 | 
							
								"""
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import sys
							 | 
						||
| 
								 | 
							
								from functools import update_wrapper
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								from werkzeug.exceptions import HTTPException
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								from .globals import _request_ctx_stack, _app_ctx_stack
							 | 
						||
| 
								 | 
							
								from .signals import appcontext_pushed, appcontext_popped
							 | 
						||
| 
								 | 
							
								from ._compat import BROKEN_PYPY_CTXMGR_EXIT, reraise
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# a singleton sentinel value for parameter defaults
							 | 
						||
| 
								 | 
							
								_sentinel = object()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class _AppCtxGlobals(object):
							 | 
						||
| 
								 | 
							
								    """A plain object. Used as a namespace for storing data during an
							 | 
						||
| 
								 | 
							
								    application context.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Creating an app context automatically creates this object, which is
							 | 
						||
| 
								 | 
							
								    made available as the :data:`g` proxy.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    .. describe:: 'key' in g
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Check whether an attribute is present.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        .. versionadded:: 0.10
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    .. describe:: iter(g)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Return an iterator over the attribute names.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        .. versionadded:: 0.10
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def get(self, name, default=None):
							 | 
						||
| 
								 | 
							
								        """Get an attribute by name, or a default value. Like
							 | 
						||
| 
								 | 
							
								        :meth:`dict.get`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        :param name: Name of attribute to get.
							 | 
						||
| 
								 | 
							
								        :param default: Value to return if the attribute is not present.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        .. versionadded:: 0.10
							 | 
						||
| 
								 | 
							
								        """
							 | 
						||
| 
								 | 
							
								        return self.__dict__.get(name, default)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def pop(self, name, default=_sentinel):
							 | 
						||
| 
								 | 
							
								        """Get and remove an attribute by name. Like :meth:`dict.pop`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        :param name: Name of attribute to pop.
							 | 
						||
| 
								 | 
							
								        :param default: Value to return if the attribute is not present,
							 | 
						||
| 
								 | 
							
								            instead of raise a ``KeyError``.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        .. versionadded:: 0.11
							 | 
						||
| 
								 | 
							
								        """
							 | 
						||
| 
								 | 
							
								        if default is _sentinel:
							 | 
						||
| 
								 | 
							
								            return self.__dict__.pop(name)
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            return self.__dict__.pop(name, default)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def setdefault(self, name, default=None):
							 | 
						||
| 
								 | 
							
								        """Get the value of an attribute if it is present, otherwise
							 | 
						||
| 
								 | 
							
								        set and return a default value. Like :meth:`dict.setdefault`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        :param name: Name of attribute to get.
							 | 
						||
| 
								 | 
							
								        :param: default: Value to set and return if the attribute is not
							 | 
						||
| 
								 | 
							
								            present.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        .. versionadded:: 0.11
							 | 
						||
| 
								 | 
							
								        """
							 | 
						||
| 
								 | 
							
								        return self.__dict__.setdefault(name, default)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __contains__(self, item):
							 | 
						||
| 
								 | 
							
								        return item in self.__dict__
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __iter__(self):
							 | 
						||
| 
								 | 
							
								        return iter(self.__dict__)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __repr__(self):
							 | 
						||
| 
								 | 
							
								        top = _app_ctx_stack.top
							 | 
						||
| 
								 | 
							
								        if top is not None:
							 | 
						||
| 
								 | 
							
								            return '<flask.g of %r>' % top.app.name
							 | 
						||
| 
								 | 
							
								        return object.__repr__(self)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def after_this_request(f):
							 | 
						||
| 
								 | 
							
								    """Executes a function after this request.  This is useful to modify
							 | 
						||
| 
								 | 
							
								    response objects.  The function is passed the response object and has
							 | 
						||
| 
								 | 
							
								    to return the same or a new one.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Example::
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        @app.route('/')
							 | 
						||
| 
								 | 
							
								        def index():
							 | 
						||
| 
								 | 
							
								            @after_this_request
							 | 
						||
| 
								 | 
							
								            def add_header(response):
							 | 
						||
| 
								 | 
							
								                response.headers['X-Foo'] = 'Parachute'
							 | 
						||
| 
								 | 
							
								                return response
							 | 
						||
| 
								 | 
							
								            return 'Hello World!'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    This is more useful if a function other than the view function wants to
							 | 
						||
| 
								 | 
							
								    modify a response.  For instance think of a decorator that wants to add
							 | 
						||
| 
								 | 
							
								    some headers without converting the return value into a response object.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    .. versionadded:: 0.9
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								    _request_ctx_stack.top._after_request_functions.append(f)
							 | 
						||
| 
								 | 
							
								    return f
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def copy_current_request_context(f):
							 | 
						||
| 
								 | 
							
								    """A helper function that decorates a function to retain the current
							 | 
						||
| 
								 | 
							
								    request context.  This is useful when working with greenlets.  The moment
							 | 
						||
| 
								 | 
							
								    the function is decorated a copy of the request context is created and
							 | 
						||
| 
								 | 
							
								    then pushed when the function is called.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Example::
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        import gevent
							 | 
						||
| 
								 | 
							
								        from flask import copy_current_request_context
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        @app.route('/')
							 | 
						||
| 
								 | 
							
								        def index():
							 | 
						||
| 
								 | 
							
								            @copy_current_request_context
							 | 
						||
| 
								 | 
							
								            def do_some_work():
							 | 
						||
| 
								 | 
							
								                # do some work here, it can access flask.request like you
							 | 
						||
| 
								 | 
							
								                # would otherwise in the view function.
							 | 
						||
| 
								 | 
							
								                ...
							 | 
						||
| 
								 | 
							
								            gevent.spawn(do_some_work)
							 | 
						||
| 
								 | 
							
								            return 'Regular response'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    .. versionadded:: 0.10
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								    top = _request_ctx_stack.top
							 | 
						||
| 
								 | 
							
								    if top is None:
							 | 
						||
| 
								 | 
							
								        raise RuntimeError('This decorator can only be used at local scopes '
							 | 
						||
| 
								 | 
							
								            'when a request context is on the stack.  For instance within '
							 | 
						||
| 
								 | 
							
								            'view functions.')
							 | 
						||
| 
								 | 
							
								    reqctx = top.copy()
							 | 
						||
| 
								 | 
							
								    def wrapper(*args, **kwargs):
							 | 
						||
| 
								 | 
							
								        with reqctx:
							 | 
						||
| 
								 | 
							
								            return f(*args, **kwargs)
							 | 
						||
| 
								 | 
							
								    return update_wrapper(wrapper, f)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def has_request_context():
							 | 
						||
| 
								 | 
							
								    """If you have code that wants to test if a request context is there or
							 | 
						||
| 
								 | 
							
								    not this function can be used.  For instance, you may want to take advantage
							 | 
						||
| 
								 | 
							
								    of request information if the request object is available, but fail
							 | 
						||
| 
								 | 
							
								    silently if it is unavailable.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ::
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        class User(db.Model):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            def __init__(self, username, remote_addr=None):
							 | 
						||
| 
								 | 
							
								                self.username = username
							 | 
						||
| 
								 | 
							
								                if remote_addr is None and has_request_context():
							 | 
						||
| 
								 | 
							
								                    remote_addr = request.remote_addr
							 | 
						||
| 
								 | 
							
								                self.remote_addr = remote_addr
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Alternatively you can also just test any of the context bound objects
							 | 
						||
| 
								 | 
							
								    (such as :class:`request` or :class:`g` for truthness)::
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        class User(db.Model):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            def __init__(self, username, remote_addr=None):
							 | 
						||
| 
								 | 
							
								                self.username = username
							 | 
						||
| 
								 | 
							
								                if remote_addr is None and request:
							 | 
						||
| 
								 | 
							
								                    remote_addr = request.remote_addr
							 | 
						||
| 
								 | 
							
								                self.remote_addr = remote_addr
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    .. versionadded:: 0.7
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								    return _request_ctx_stack.top is not None
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def has_app_context():
							 | 
						||
| 
								 | 
							
								    """Works like :func:`has_request_context` but for the application
							 | 
						||
| 
								 | 
							
								    context.  You can also just do a boolean check on the
							 | 
						||
| 
								 | 
							
								    :data:`current_app` object instead.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    .. versionadded:: 0.9
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								    return _app_ctx_stack.top is not None
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class AppContext(object):
							 | 
						||
| 
								 | 
							
								    """The application context binds an application object implicitly
							 | 
						||
| 
								 | 
							
								    to the current thread or greenlet, similar to how the
							 | 
						||
| 
								 | 
							
								    :class:`RequestContext` binds request information.  The application
							 | 
						||
| 
								 | 
							
								    context is also implicitly created if a request context is created
							 | 
						||
| 
								 | 
							
								    but the application is not on top of the individual application
							 | 
						||
| 
								 | 
							
								    context.
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __init__(self, app):
							 | 
						||
| 
								 | 
							
								        self.app = app
							 | 
						||
| 
								 | 
							
								        self.url_adapter = app.create_url_adapter(None)
							 | 
						||
| 
								 | 
							
								        self.g = app.app_ctx_globals_class()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Like request context, app contexts can be pushed multiple times
							 | 
						||
| 
								 | 
							
								        # but there a basic "refcount" is enough to track them.
							 | 
						||
| 
								 | 
							
								        self._refcnt = 0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def push(self):
							 | 
						||
| 
								 | 
							
								        """Binds the app context to the current context."""
							 | 
						||
| 
								 | 
							
								        self._refcnt += 1
							 | 
						||
| 
								 | 
							
								        if hasattr(sys, 'exc_clear'):
							 | 
						||
| 
								 | 
							
								            sys.exc_clear()
							 | 
						||
| 
								 | 
							
								        _app_ctx_stack.push(self)
							 | 
						||
| 
								 | 
							
								        appcontext_pushed.send(self.app)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def pop(self, exc=_sentinel):
							 | 
						||
| 
								 | 
							
								        """Pops the app context."""
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            self._refcnt -= 1
							 | 
						||
| 
								 | 
							
								            if self._refcnt <= 0:
							 | 
						||
| 
								 | 
							
								                if exc is _sentinel:
							 | 
						||
| 
								 | 
							
								                    exc = sys.exc_info()[1]
							 | 
						||
| 
								 | 
							
								                self.app.do_teardown_appcontext(exc)
							 | 
						||
| 
								 | 
							
								        finally:
							 | 
						||
| 
								 | 
							
								            rv = _app_ctx_stack.pop()
							 | 
						||
| 
								 | 
							
								        assert rv is self, 'Popped wrong app context.  (%r instead of %r)' \
							 | 
						||
| 
								 | 
							
								            % (rv, self)
							 | 
						||
| 
								 | 
							
								        appcontext_popped.send(self.app)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __enter__(self):
							 | 
						||
| 
								 | 
							
								        self.push()
							 | 
						||
| 
								 | 
							
								        return self
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __exit__(self, exc_type, exc_value, tb):
							 | 
						||
| 
								 | 
							
								        self.pop(exc_value)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if BROKEN_PYPY_CTXMGR_EXIT and exc_type is not None:
							 | 
						||
| 
								 | 
							
								            reraise(exc_type, exc_value, tb)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class RequestContext(object):
							 | 
						||
| 
								 | 
							
								    """The request context contains all request relevant information.  It is
							 | 
						||
| 
								 | 
							
								    created at the beginning of the request and pushed to the
							 | 
						||
| 
								 | 
							
								    `_request_ctx_stack` and removed at the end of it.  It will create the
							 | 
						||
| 
								 | 
							
								    URL adapter and request object for the WSGI environment provided.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Do not attempt to use this class directly, instead use
							 | 
						||
| 
								 | 
							
								    :meth:`~flask.Flask.test_request_context` and
							 | 
						||
| 
								 | 
							
								    :meth:`~flask.Flask.request_context` to create this object.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    When the request context is popped, it will evaluate all the
							 | 
						||
| 
								 | 
							
								    functions registered on the application for teardown execution
							 | 
						||
| 
								 | 
							
								    (:meth:`~flask.Flask.teardown_request`).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    The request context is automatically popped at the end of the request
							 | 
						||
| 
								 | 
							
								    for you.  In debug mode the request context is kept around if
							 | 
						||
| 
								 | 
							
								    exceptions happen so that interactive debuggers have a chance to
							 | 
						||
| 
								 | 
							
								    introspect the data.  With 0.4 this can also be forced for requests
							 | 
						||
| 
								 | 
							
								    that did not fail and outside of ``DEBUG`` mode.  By setting
							 | 
						||
| 
								 | 
							
								    ``'flask._preserve_context'`` to ``True`` on the WSGI environment the
							 | 
						||
| 
								 | 
							
								    context will not pop itself at the end of the request.  This is used by
							 | 
						||
| 
								 | 
							
								    the :meth:`~flask.Flask.test_client` for example to implement the
							 | 
						||
| 
								 | 
							
								    deferred cleanup functionality.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    You might find this helpful for unittests where you need the
							 | 
						||
| 
								 | 
							
								    information from the context local around for a little longer.  Make
							 | 
						||
| 
								 | 
							
								    sure to properly :meth:`~werkzeug.LocalStack.pop` the stack yourself in
							 | 
						||
| 
								 | 
							
								    that situation, otherwise your unittests will leak memory.
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __init__(self, app, environ, request=None):
							 | 
						||
| 
								 | 
							
								        self.app = app
							 | 
						||
| 
								 | 
							
								        if request is None:
							 | 
						||
| 
								 | 
							
								            request = app.request_class(environ)
							 | 
						||
| 
								 | 
							
								        self.request = request
							 | 
						||
| 
								 | 
							
								        self.url_adapter = app.create_url_adapter(self.request)
							 | 
						||
| 
								 | 
							
								        self.flashes = None
							 | 
						||
| 
								 | 
							
								        self.session = None
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Request contexts can be pushed multiple times and interleaved with
							 | 
						||
| 
								 | 
							
								        # other request contexts.  Now only if the last level is popped we
							 | 
						||
| 
								 | 
							
								        # get rid of them.  Additionally if an application context is missing
							 | 
						||
| 
								 | 
							
								        # one is created implicitly so for each level we add this information
							 | 
						||
| 
								 | 
							
								        self._implicit_app_ctx_stack = []
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # indicator if the context was preserved.  Next time another context
							 | 
						||
| 
								 | 
							
								        # is pushed the preserved context is popped.
							 | 
						||
| 
								 | 
							
								        self.preserved = False
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # remembers the exception for pop if there is one in case the context
							 | 
						||
| 
								 | 
							
								        # preservation kicks in.
							 | 
						||
| 
								 | 
							
								        self._preserved_exc = None
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Functions that should be executed after the request on the response
							 | 
						||
| 
								 | 
							
								        # object.  These will be called before the regular "after_request"
							 | 
						||
| 
								 | 
							
								        # functions.
							 | 
						||
| 
								 | 
							
								        self._after_request_functions = []
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        self.match_request()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def _get_g(self):
							 | 
						||
| 
								 | 
							
								        return _app_ctx_stack.top.g
							 | 
						||
| 
								 | 
							
								    def _set_g(self, value):
							 | 
						||
| 
								 | 
							
								        _app_ctx_stack.top.g = value
							 | 
						||
| 
								 | 
							
								    g = property(_get_g, _set_g)
							 | 
						||
| 
								 | 
							
								    del _get_g, _set_g
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def copy(self):
							 | 
						||
| 
								 | 
							
								        """Creates a copy of this request context with the same request object.
							 | 
						||
| 
								 | 
							
								        This can be used to move a request context to a different greenlet.
							 | 
						||
| 
								 | 
							
								        Because the actual request object is the same this cannot be used to
							 | 
						||
| 
								 | 
							
								        move a request context to a different thread unless access to the
							 | 
						||
| 
								 | 
							
								        request object is locked.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        .. versionadded:: 0.10
							 | 
						||
| 
								 | 
							
								        """
							 | 
						||
| 
								 | 
							
								        return self.__class__(self.app,
							 | 
						||
| 
								 | 
							
								            environ=self.request.environ,
							 | 
						||
| 
								 | 
							
								            request=self.request
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def match_request(self):
							 | 
						||
| 
								 | 
							
								        """Can be overridden by a subclass to hook into the matching
							 | 
						||
| 
								 | 
							
								        of the request.
							 | 
						||
| 
								 | 
							
								        """
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            url_rule, self.request.view_args = \
							 | 
						||
| 
								 | 
							
								                self.url_adapter.match(return_rule=True)
							 | 
						||
| 
								 | 
							
								            self.request.url_rule = url_rule
							 | 
						||
| 
								 | 
							
								        except HTTPException as e:
							 | 
						||
| 
								 | 
							
								            self.request.routing_exception = e
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def push(self):
							 | 
						||
| 
								 | 
							
								        """Binds the request context to the current context."""
							 | 
						||
| 
								 | 
							
								        # If an exception occurs in debug mode or if context preservation is
							 | 
						||
| 
								 | 
							
								        # activated under exception situations exactly one context stays
							 | 
						||
| 
								 | 
							
								        # on the stack.  The rationale is that you want to access that
							 | 
						||
| 
								 | 
							
								        # information under debug situations.  However if someone forgets to
							 | 
						||
| 
								 | 
							
								        # pop that context again we want to make sure that on the next push
							 | 
						||
| 
								 | 
							
								        # it's invalidated, otherwise we run at risk that something leaks
							 | 
						||
| 
								 | 
							
								        # memory.  This is usually only a problem in test suite since this
							 | 
						||
| 
								 | 
							
								        # functionality is not active in production environments.
							 | 
						||
| 
								 | 
							
								        top = _request_ctx_stack.top
							 | 
						||
| 
								 | 
							
								        if top is not None and top.preserved:
							 | 
						||
| 
								 | 
							
								            top.pop(top._preserved_exc)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Before we push the request context we have to ensure that there
							 | 
						||
| 
								 | 
							
								        # is an application context.
							 | 
						||
| 
								 | 
							
								        app_ctx = _app_ctx_stack.top
							 | 
						||
| 
								 | 
							
								        if app_ctx is None or app_ctx.app != self.app:
							 | 
						||
| 
								 | 
							
								            app_ctx = self.app.app_context()
							 | 
						||
| 
								 | 
							
								            app_ctx.push()
							 | 
						||
| 
								 | 
							
								            self._implicit_app_ctx_stack.append(app_ctx)
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            self._implicit_app_ctx_stack.append(None)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if hasattr(sys, 'exc_clear'):
							 | 
						||
| 
								 | 
							
								            sys.exc_clear()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        _request_ctx_stack.push(self)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Open the session at the moment that the request context is available.
							 | 
						||
| 
								 | 
							
								        # This allows a custom open_session method to use the request context.
							 | 
						||
| 
								 | 
							
								        # Only open a new session if this is the first time the request was
							 | 
						||
| 
								 | 
							
								        # pushed, otherwise stream_with_context loses the session.
							 | 
						||
| 
								 | 
							
								        if self.session is None:
							 | 
						||
| 
								 | 
							
								            session_interface = self.app.session_interface
							 | 
						||
| 
								 | 
							
								            self.session = session_interface.open_session(
							 | 
						||
| 
								 | 
							
								                self.app, self.request
							 | 
						||
| 
								 | 
							
								            )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if self.session is None:
							 | 
						||
| 
								 | 
							
								                self.session = session_interface.make_null_session(self.app)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def pop(self, exc=_sentinel):
							 | 
						||
| 
								 | 
							
								        """Pops the request context and unbinds it by doing that.  This will
							 | 
						||
| 
								 | 
							
								        also trigger the execution of functions registered by the
							 | 
						||
| 
								 | 
							
								        :meth:`~flask.Flask.teardown_request` decorator.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        .. versionchanged:: 0.9
							 | 
						||
| 
								 | 
							
								           Added the `exc` argument.
							 | 
						||
| 
								 | 
							
								        """
							 | 
						||
| 
								 | 
							
								        app_ctx = self._implicit_app_ctx_stack.pop()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            clear_request = False
							 | 
						||
| 
								 | 
							
								            if not self._implicit_app_ctx_stack:
							 | 
						||
| 
								 | 
							
								                self.preserved = False
							 | 
						||
| 
								 | 
							
								                self._preserved_exc = None
							 | 
						||
| 
								 | 
							
								                if exc is _sentinel:
							 | 
						||
| 
								 | 
							
								                    exc = sys.exc_info()[1]
							 | 
						||
| 
								 | 
							
								                self.app.do_teardown_request(exc)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                # If this interpreter supports clearing the exception information
							 | 
						||
| 
								 | 
							
								                # we do that now.  This will only go into effect on Python 2.x,
							 | 
						||
| 
								 | 
							
								                # on 3.x it disappears automatically at the end of the exception
							 | 
						||
| 
								 | 
							
								                # stack.
							 | 
						||
| 
								 | 
							
								                if hasattr(sys, 'exc_clear'):
							 | 
						||
| 
								 | 
							
								                    sys.exc_clear()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                request_close = getattr(self.request, 'close', None)
							 | 
						||
| 
								 | 
							
								                if request_close is not None:
							 | 
						||
| 
								 | 
							
								                    request_close()
							 | 
						||
| 
								 | 
							
								                clear_request = True
							 | 
						||
| 
								 | 
							
								        finally:
							 | 
						||
| 
								 | 
							
								            rv = _request_ctx_stack.pop()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            # get rid of circular dependencies at the end of the request
							 | 
						||
| 
								 | 
							
								            # so that we don't require the GC to be active.
							 | 
						||
| 
								 | 
							
								            if clear_request:
							 | 
						||
| 
								 | 
							
								                rv.request.environ['werkzeug.request'] = None
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            # Get rid of the app as well if necessary.
							 | 
						||
| 
								 | 
							
								            if app_ctx is not None:
							 | 
						||
| 
								 | 
							
								                app_ctx.pop(exc)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            assert rv is self, 'Popped wrong request context.  ' \
							 | 
						||
| 
								 | 
							
								                '(%r instead of %r)' % (rv, self)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def auto_pop(self, exc):
							 | 
						||
| 
								 | 
							
								        if self.request.environ.get('flask._preserve_context') or \
							 | 
						||
| 
								 | 
							
								           (exc is not None and self.app.preserve_context_on_exception):
							 | 
						||
| 
								 | 
							
								            self.preserved = True
							 | 
						||
| 
								 | 
							
								            self._preserved_exc = exc
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            self.pop(exc)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __enter__(self):
							 | 
						||
| 
								 | 
							
								        self.push()
							 | 
						||
| 
								 | 
							
								        return self
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __exit__(self, exc_type, exc_value, tb):
							 | 
						||
| 
								 | 
							
								        # do not pop the request stack if we are in debug mode and an
							 | 
						||
| 
								 | 
							
								        # exception happened.  This will allow the debugger to still
							 | 
						||
| 
								 | 
							
								        # access the request object in the interactive shell.  Furthermore
							 | 
						||
| 
								 | 
							
								        # the context can be force kept alive for the test client.
							 | 
						||
| 
								 | 
							
								        # See flask.testing for how this works.
							 | 
						||
| 
								 | 
							
								        self.auto_pop(exc_value)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if BROKEN_PYPY_CTXMGR_EXIT and exc_type is not None:
							 | 
						||
| 
								 | 
							
								            reraise(exc_type, exc_value, tb)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __repr__(self):
							 | 
						||
| 
								 | 
							
								        return '<%s \'%s\' [%s] of %s>' % (
							 | 
						||
| 
								 | 
							
								            self.__class__.__name__,
							 | 
						||
| 
								 | 
							
								            self.request.url,
							 | 
						||
| 
								 | 
							
								            self.request.method,
							 | 
						||
| 
								 | 
							
								            self.app.name,
							 | 
						||
| 
								 | 
							
								        )
							 |