aboutsummaryrefslogtreecommitdiffstats
path: root/python/flask/ctx.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/flask/ctx.py')
-rw-r--r--python/flask/ctx.py457
1 files changed, 0 insertions, 457 deletions
diff --git a/python/flask/ctx.py b/python/flask/ctx.py
deleted file mode 100644
index ec8e787..0000000
--- a/python/flask/ctx.py
+++ /dev/null
@@ -1,457 +0,0 @@
-# -*- 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,
- )