forked from orbit-oss/flask
deprecated init_jinja_globals
This commit is contained in:
parent
4c8c503326
commit
0da56d7f5c
4 changed files with 88 additions and 16 deletions
3
CHANGES
3
CHANGES
|
|
@ -40,6 +40,9 @@ Release date to be announced, codename to be selected
|
||||||
- Added `teardown_request` decorator, for functions that should run at the end
|
- Added `teardown_request` decorator, for functions that should run at the end
|
||||||
of a request regardless of whether an exception occurred.
|
of a request regardless of whether an exception occurred.
|
||||||
- Implemented :func:`flask.has_request_context`
|
- Implemented :func:`flask.has_request_context`
|
||||||
|
- Deprecated `init_jinja_globals`. Override the
|
||||||
|
:meth:`~flask.Flask.create_jinja_environment` method instead to
|
||||||
|
achieve the same functionality.
|
||||||
|
|
||||||
Version 0.6.1
|
Version 0.6.1
|
||||||
-------------
|
-------------
|
||||||
|
|
|
||||||
50
flask/app.py
50
flask/app.py
|
|
@ -24,7 +24,7 @@ from werkzeug.exceptions import HTTPException, InternalServerError, \
|
||||||
MethodNotAllowed
|
MethodNotAllowed
|
||||||
|
|
||||||
from .helpers import _PackageBoundObject, url_for, get_flashed_messages, \
|
from .helpers import _PackageBoundObject, url_for, get_flashed_messages, \
|
||||||
_tojson_filter, _endpoint_from_view_func
|
locked_cached_property, _tojson_filter, _endpoint_from_view_func
|
||||||
from .wrappers import Request, Response
|
from .wrappers import Request, Response
|
||||||
from .config import ConfigAttribute, Config
|
from .config import ConfigAttribute, Config
|
||||||
from .ctx import _RequestContext
|
from .ctx import _RequestContext
|
||||||
|
|
@ -317,11 +317,6 @@ class Flask(_PackageBoundObject):
|
||||||
endpoint='static',
|
endpoint='static',
|
||||||
view_func=self.send_static_file)
|
view_func=self.send_static_file)
|
||||||
|
|
||||||
#: The Jinja2 environment. It is created from the
|
|
||||||
#: :attr:`jinja_options`.
|
|
||||||
self.jinja_env = self.create_jinja_environment()
|
|
||||||
self.init_jinja_globals()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def propagate_exceptions(self):
|
def propagate_exceptions(self):
|
||||||
"""Returns the value of the `PROPAGATE_EXCEPTIONS` configuration
|
"""Returns the value of the `PROPAGATE_EXCEPTIONS` configuration
|
||||||
|
|
@ -356,16 +351,43 @@ class Flask(_PackageBoundObject):
|
||||||
self._logger = rv = create_logger(self)
|
self._logger = rv = create_logger(self)
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
|
@locked_cached_property
|
||||||
|
def jinja_env(self):
|
||||||
|
"""The Jinja2 environment used to load templates."""
|
||||||
|
rv = self.create_jinja_environment()
|
||||||
|
|
||||||
|
# Hack to support the init_jinja_globals method which is supported
|
||||||
|
# until 1.0 but has an API deficiency.
|
||||||
|
if getattr(self.init_jinja_globals, 'im_func', None) is not \
|
||||||
|
Flask.init_jinja_globals.im_func:
|
||||||
|
from warnings import warn
|
||||||
|
warn(DeprecationWarning('This flask class uses a customized '
|
||||||
|
'init_jinja_globals() method which is deprecated. '
|
||||||
|
'Move the code from that method into the '
|
||||||
|
'create_jinja_environment() method instead.'))
|
||||||
|
self.__dict__['jinja_env'] = rv
|
||||||
|
self.init_jinja_globals()
|
||||||
|
|
||||||
|
return rv
|
||||||
|
|
||||||
def create_jinja_environment(self):
|
def create_jinja_environment(self):
|
||||||
"""Creates the Jinja2 environment based on :attr:`jinja_options`
|
"""Creates the Jinja2 environment based on :attr:`jinja_options`
|
||||||
and :meth:`select_jinja_autoescape`.
|
and :meth:`select_jinja_autoescape`. Since 0.7 this also adds
|
||||||
|
the Jinja2 globals and filters after initialization. Override
|
||||||
|
this function to customize the behavior.
|
||||||
|
|
||||||
.. versionadded:: 0.5
|
.. versionadded:: 0.5
|
||||||
"""
|
"""
|
||||||
options = dict(self.jinja_options)
|
options = dict(self.jinja_options)
|
||||||
if 'autoescape' not in options:
|
if 'autoescape' not in options:
|
||||||
options['autoescape'] = self.select_jinja_autoescape
|
options['autoescape'] = self.select_jinja_autoescape
|
||||||
return Environment(loader=self.create_jinja_loader(), **options)
|
rv = Environment(loader=self.create_jinja_loader(), **options)
|
||||||
|
rv.globals.update(
|
||||||
|
url_for=url_for,
|
||||||
|
get_flashed_messages=get_flashed_messages
|
||||||
|
)
|
||||||
|
rv.filters['tojson'] = _tojson_filter
|
||||||
|
return rv
|
||||||
|
|
||||||
def create_jinja_loader(self):
|
def create_jinja_loader(self):
|
||||||
"""Creates the loader for the Jinja2 environment. Can be used to
|
"""Creates the loader for the Jinja2 environment. Can be used to
|
||||||
|
|
@ -376,17 +398,13 @@ class Flask(_PackageBoundObject):
|
||||||
return _DispatchingJinjaLoader(self)
|
return _DispatchingJinjaLoader(self)
|
||||||
|
|
||||||
def init_jinja_globals(self):
|
def init_jinja_globals(self):
|
||||||
"""Called directly after the environment was created to inject
|
"""Deprecated. Used to initialize the Jinja2 globals.
|
||||||
some defaults (like `url_for`, `get_flashed_messages` and the
|
|
||||||
`tojson` filter.
|
|
||||||
|
|
||||||
.. versionadded:: 0.5
|
.. versionadded:: 0.5
|
||||||
|
.. versionchanged:: 0.7
|
||||||
|
This method is deprecated with 0.7. Override
|
||||||
|
:meth:`create_jinja_environment` instead.
|
||||||
"""
|
"""
|
||||||
self.jinja_env.globals.update(
|
|
||||||
url_for=url_for,
|
|
||||||
get_flashed_messages=get_flashed_messages
|
|
||||||
)
|
|
||||||
self.jinja_env.filters['tojson'] = _tojson_filter
|
|
||||||
|
|
||||||
def select_jinja_autoescape(self, filename):
|
def select_jinja_autoescape(self, filename):
|
||||||
"""Returns `True` if autoescaping should be active for the given
|
"""Returns `True` if autoescaping should be active for the given
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import posixpath
|
||||||
import mimetypes
|
import mimetypes
|
||||||
from time import time
|
from time import time
|
||||||
from zlib import adler32
|
from zlib import adler32
|
||||||
|
from threading import RLock
|
||||||
|
|
||||||
# try to load the best simplejson implementation available. If JSON
|
# try to load the best simplejson implementation available. If JSON
|
||||||
# is not installed, we add a failing class.
|
# is not installed, we add a failing class.
|
||||||
|
|
@ -58,6 +59,10 @@ else:
|
||||||
_tojson_filter = json.dumps
|
_tojson_filter = json.dumps
|
||||||
|
|
||||||
|
|
||||||
|
# sentinel
|
||||||
|
_missing = object()
|
||||||
|
|
||||||
|
|
||||||
# what separators does this operating system provide that are not a slash?
|
# what separators does this operating system provide that are not a slash?
|
||||||
# this is used by the send_from_directory function to ensure that nobody is
|
# this is used by the send_from_directory function to ensure that nobody is
|
||||||
# able to access files from outside the filesystem.
|
# able to access files from outside the filesystem.
|
||||||
|
|
@ -435,6 +440,32 @@ def _get_package_path(name):
|
||||||
return os.getcwd()
|
return os.getcwd()
|
||||||
|
|
||||||
|
|
||||||
|
class locked_cached_property(object):
|
||||||
|
"""A decorator that converts a function into a lazy property. The
|
||||||
|
function wrapped is called the first time to retrieve the result
|
||||||
|
and then that calculated result is used the next time you access
|
||||||
|
the value. Works like the one in Werkzeug but has a lock for
|
||||||
|
thread safety.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, func, name=None, doc=None):
|
||||||
|
self.__name__ = name or func.__name__
|
||||||
|
self.__module__ = func.__module__
|
||||||
|
self.__doc__ = doc or func.__doc__
|
||||||
|
self.func = func
|
||||||
|
self.lock = RLock()
|
||||||
|
|
||||||
|
def __get__(self, obj, type=None):
|
||||||
|
if obj is None:
|
||||||
|
return self
|
||||||
|
with self.lock:
|
||||||
|
value = obj.__dict__.get(self.__name__, _missing)
|
||||||
|
if value is _missing:
|
||||||
|
value = self.func(obj)
|
||||||
|
obj.__dict__[self.__name__] = value
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
class _PackageBoundObject(object):
|
class _PackageBoundObject(object):
|
||||||
|
|
||||||
def __init__(self, import_name):
|
def __init__(self, import_name):
|
||||||
|
|
|
||||||
|
|
@ -1564,6 +1564,25 @@ class TestSignals(unittest.TestCase):
|
||||||
flask.got_request_exception.disconnect(record, app)
|
flask.got_request_exception.disconnect(record, app)
|
||||||
|
|
||||||
|
|
||||||
|
class DeprecationsTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_init_jinja_globals(self):
|
||||||
|
class MyFlask(flask.Flask):
|
||||||
|
def init_jinja_globals(self):
|
||||||
|
self.jinja_env.globals['foo'] = '42'
|
||||||
|
|
||||||
|
with catch_warnings() as log:
|
||||||
|
app = MyFlask(__name__)
|
||||||
|
@app.route('/')
|
||||||
|
def foo():
|
||||||
|
return app.jinja_env.globals['foo']
|
||||||
|
|
||||||
|
c = app.test_client()
|
||||||
|
assert c.get('/').data == '42'
|
||||||
|
assert len(log) == 1
|
||||||
|
assert 'init_jinja_globals' in str(log[0]['message'])
|
||||||
|
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
from minitwit_tests import MiniTwitTestCase
|
from minitwit_tests import MiniTwitTestCase
|
||||||
from flaskr_tests import FlaskrTestCase
|
from flaskr_tests import FlaskrTestCase
|
||||||
|
|
@ -1576,6 +1595,7 @@ def suite():
|
||||||
suite.addTest(unittest.makeSuite(LoggingTestCase))
|
suite.addTest(unittest.makeSuite(LoggingTestCase))
|
||||||
suite.addTest(unittest.makeSuite(ConfigTestCase))
|
suite.addTest(unittest.makeSuite(ConfigTestCase))
|
||||||
suite.addTest(unittest.makeSuite(SubdomainTestCase))
|
suite.addTest(unittest.makeSuite(SubdomainTestCase))
|
||||||
|
suite.addTest(unittest.makeSuite(DeprecationsTestCase))
|
||||||
if flask.json_available:
|
if flask.json_available:
|
||||||
suite.addTest(unittest.makeSuite(JSONTestCase))
|
suite.addTest(unittest.makeSuite(JSONTestCase))
|
||||||
if flask.signals_available:
|
if flask.signals_available:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue