globals.py

Official Document

Define all the global objects that are proxies to the current active context.

Overview

This is a simple module which utilize the concept of proxy objects. Click here to find a useful blog which explains how it works.

Details

Two Stacks

_request_ctx_stack and _app_ctx_stack are instances of werkzeug.local.LocalStack, and now we can treat them as normal stacks named request stack and app stack, respectively.

_request_ctx_stack = LocalStack()
_app_ctx_stack = LocalStack()

Three Methods

_lookup_req_object(name), _lookup_app_object(name) and _find_app() are helper methods which are used to access attributes of top elements.

Calling _find_app() means to get app attribute of the top element in the app stack.

def _find_app():
    top = _app_ctx_stack.top
    if top is None:
        raise RuntimeError(_app_ctx_err_msg)
    return top.app

Calling _lookup_req_object(name) means to get {name} attribute of the top element in the request stack. Calling _lookup_app_object(name) is almost as same as calling _lookup_req_object(name), and the only difference is that the top element is from app stack.

def _lookup_req_object(name):
    top = _request_ctx_stack.top
    if top is None:
        raise RuntimeError(_request_ctx_err_msg)
    return getattr(top, name)


def _lookup_app_object(name):
    top = _app_ctx_stack.top
    if top is None:
        raise RuntimeError(_app_ctx_err_msg)
    return getattr(top, name)

Exposed Objects

There are four exposed proxy objects in this module: current_app, request, session and g.

When accessing current_app, _find_app() is called. LocalProxy ensures that current_app always has the latest value.

current_app = LocalProxy(_find_app)

When accessing request and session, _lookup_req_object('request') and _lookup_req_object('session') are called. Note that partial is a functionality of high-order function in Python, and we can treat is as fixing parameters of methods.

request = LocalProxy(partial(_lookup_req_object, "request"))
session = LocalProxy(partial(_lookup_req_object, "session"))

When accessing g, _lookup_app_object('g') is called so that we can always get the latest g attribute of app stack’s top element.

g = LocalProxy(partial(_lookup_app_object, "g"))

Note

This is almost the simplest module in Flask project, and I think it could be a good start to analyze its source code.

Source Code

# -*- coding: utf-8 -*-
"""
    flask.globals
    ~~~~~~~~~~~~~

    Defines all the global objects that are proxies to the current
    active context.

    :copyright: 2010 Pallets
    :license: BSD-3-Clause
"""
from functools import partial

from werkzeug.local import LocalProxy
from werkzeug.local import LocalStack


_request_ctx_err_msg = """\
Working outside of request context.

This typically means that you attempted to use functionality that needed
an active HTTP request.  Consult the documentation on testing for
information about how to avoid this problem.\
"""
_app_ctx_err_msg = """\
Working outside of application context.

This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context().  See the
documentation for more information.\
"""


def _lookup_req_object(name):
    top = _request_ctx_stack.top
    if top is None:
        raise RuntimeError(_request_ctx_err_msg)
    return getattr(top, name)


def _lookup_app_object(name):
    top = _app_ctx_stack.top
    if top is None:
        raise RuntimeError(_app_ctx_err_msg)
    return getattr(top, name)


def _find_app():
    top = _app_ctx_stack.top
    if top is None:
        raise RuntimeError(_app_ctx_err_msg)
    return top.app


# context locals
_request_ctx_stack = LocalStack()
_app_ctx_stack = LocalStack()
current_app = LocalProxy(_find_app)
request = LocalProxy(partial(_lookup_req_object, "request"))
session = LocalProxy(partial(_lookup_req_object, "session"))
g = LocalProxy(partial(_lookup_app_object, "g"))