diff --git a/CHANGES b/CHANGES index a8543e6c..8310761f 100644 --- a/CHANGES +++ b/CHANGES @@ -67,6 +67,7 @@ Version 1.0 - Don't leak exception info of already catched exceptions to context teardown handlers (pull request ``#1393``). - Allow custom Jinja environment subclasses (pull request ``#1422``). +- ``flask.g`` now has ``pop()`` and ``setdefault`` methods. Version 0.10.2 -------------- diff --git a/docs/api.rst b/docs/api.rst index 70be5ca2..3da975e9 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -289,6 +289,9 @@ thing, like it does for :class:`request` and :class:`session`. It's now also possible to use the ``in`` operator on it to see if an attribute is defined and it yields all keys on iteration. + As of 1.0 you can use :meth:`pop` and :meth:`setdefault` in the same + way you would use them on a dictionary. + This is a proxy. See :ref:`notes-on-proxies` for more information. diff --git a/flask/ctx.py b/flask/ctx.py index 24d0612c..91b5ee50 100644 --- a/flask/ctx.py +++ b/flask/ctx.py @@ -31,6 +31,15 @@ class _AppCtxGlobals(object): def get(self, name, default=None): return self.__dict__.get(name, default) + def pop(self, name, default=_sentinel): + if default is _sentinel: + return self.__dict__.pop(name) + else: + return self.__dict__.pop(name, default) + + def setdefault(self, name, default=None): + self.__dict__.setdefault(name, default) + def __contains__(self, item): return item in self.__dict__ diff --git a/tests/test_appctx.py b/tests/test_appctx.py index 2b0f5f94..f24704ef 100644 --- a/tests/test_appctx.py +++ b/tests/test_appctx.py @@ -93,6 +93,28 @@ def test_app_tearing_down_with_handled_exception(): assert cleanup_stuff == [None] +def test_app_ctx_globals_methods(): + app = flask.Flask(__name__) + with app.app_context(): + # get + assert flask.g.get('foo') is None + assert flask.g.get('foo', 'bar') == 'bar' + # __contains__ + assert 'foo' not in flask.g + flask.g.foo = 'bar' + assert 'foo' in flask.g + # setdefault + flask.g.setdefault('bar', 'the cake is a lie') + flask.g.setdefault('bar', 'hello world') + assert flask.g.bar == 'the cake is a lie' + # pop + assert flask.g.pop('bar') == 'the cake is a lie' + with pytest.raises(KeyError): + flask.g.pop('bar') + assert flask.g.pop('bar', 'more cake') == 'more cake' + # __iter__ + assert list(flask.g) == ['foo'] + def test_custom_app_ctx_globals_class(): class CustomRequestGlobals(object): def __init__(self):