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
|
||||
of a request regardless of whether an exception occurred.
|
||||
- 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
|
||||
-------------
|
||||
|
|
|
|||
50
flask/app.py
50
flask/app.py
|
|
@ -24,7 +24,7 @@ from werkzeug.exceptions import HTTPException, InternalServerError, \
|
|||
MethodNotAllowed
|
||||
|
||||
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 .config import ConfigAttribute, Config
|
||||
from .ctx import _RequestContext
|
||||
|
|
@ -317,11 +317,6 @@ class Flask(_PackageBoundObject):
|
|||
endpoint='static',
|
||||
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
|
||||
def propagate_exceptions(self):
|
||||
"""Returns the value of the `PROPAGATE_EXCEPTIONS` configuration
|
||||
|
|
@ -356,16 +351,43 @@ class Flask(_PackageBoundObject):
|
|||
self._logger = rv = create_logger(self)
|
||||
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):
|
||||
"""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
|
||||
"""
|
||||
options = dict(self.jinja_options)
|
||||
if 'autoescape' not in options:
|
||||
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):
|
||||
"""Creates the loader for the Jinja2 environment. Can be used to
|
||||
|
|
@ -376,17 +398,13 @@ class Flask(_PackageBoundObject):
|
|||
return _DispatchingJinjaLoader(self)
|
||||
|
||||
def init_jinja_globals(self):
|
||||
"""Called directly after the environment was created to inject
|
||||
some defaults (like `url_for`, `get_flashed_messages` and the
|
||||
`tojson` filter.
|
||||
"""Deprecated. Used to initialize the Jinja2 globals.
|
||||
|
||||
.. 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):
|
||||
"""Returns `True` if autoescaping should be active for the given
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import posixpath
|
|||
import mimetypes
|
||||
from time import time
|
||||
from zlib import adler32
|
||||
from threading import RLock
|
||||
|
||||
# try to load the best simplejson implementation available. If JSON
|
||||
# is not installed, we add a failing class.
|
||||
|
|
@ -58,6 +59,10 @@ else:
|
|||
_tojson_filter = json.dumps
|
||||
|
||||
|
||||
# sentinel
|
||||
_missing = object()
|
||||
|
||||
|
||||
# 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
|
||||
# able to access files from outside the filesystem.
|
||||
|
|
@ -435,6 +440,32 @@ def _get_package_path(name):
|
|||
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):
|
||||
|
||||
def __init__(self, import_name):
|
||||
|
|
|
|||
|
|
@ -1564,6 +1564,25 @@ class TestSignals(unittest.TestCase):
|
|||
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():
|
||||
from minitwit_tests import MiniTwitTestCase
|
||||
from flaskr_tests import FlaskrTestCase
|
||||
|
|
@ -1576,6 +1595,7 @@ def suite():
|
|||
suite.addTest(unittest.makeSuite(LoggingTestCase))
|
||||
suite.addTest(unittest.makeSuite(ConfigTestCase))
|
||||
suite.addTest(unittest.makeSuite(SubdomainTestCase))
|
||||
suite.addTest(unittest.makeSuite(DeprecationsTestCase))
|
||||
if flask.json_available:
|
||||
suite.addTest(unittest.makeSuite(JSONTestCase))
|
||||
if flask.signals_available:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue