Browse Source

Changed interface for `flask.g`

This now makes it behave like it did before, it's just an object.
It did however gain ``__contains__`` and ``__iter__`` and I added
a ``get()`` method to fetch an attribute without raising an
error.  This fixes #759.
pull/764/head
Armin Ronacher 11 years ago
parent
commit
c889fbc231
  1. 4
      CHANGES
  2. 8
      docs/api.rst
  3. 15
      flask/ctx.py
  4. 21
      flask/testsuite/basic.py

4
CHANGES

@ -40,6 +40,10 @@ Release date to be decided.
``flask.json.dumps`` to return bytestrings by default.
- ``flask.g`` is now stored on the app context instead of the request
context.
- ``flask.g`` now gained a ``get()`` method for not erroring out on non
existing items.
- ``flask.g`` now can be used with the ``in`` operator to see what's defined
and it now is iterable and will yield all attributes stored.
- ``flask.Flask.request_globals_class`` got renamed to
``flask.Flask.app_ctx_globals_class`` which is a better name to what it
does since 0.10.

8
docs/api.rst

@ -276,12 +276,12 @@ thing, like it does for :class:`request` and :class:`session`.
is especially useful when combined with the :ref:`faking-resources`
pattern for testing.
Additionally as of 0.10 you can use the subscription operator syntax to
get an attribute or `None` if it's not set. These two usages are now
equivalent::
Additionally as of 0.10 you can use the :meth:`get` method to
get an attribute or `None` (or the second argument) if it's not set.
These two usages are now equivalent::
user = getattr(flask.g, 'user', None)
user = flask.g['user']
user = flask.g.get('user', None)
This is a proxy. See :ref:`notes-on-proxies` for more information.

15
flask/ctx.py

@ -24,17 +24,14 @@ from .signals import appcontext_pushed, appcontext_popped
class _AppCtxGlobals(object):
"""A plain object."""
def __getitem__(self, name):
try:
return getattr(self, name)
except AttributeError:
return None
def get(self, name, default=None):
return self.__dict__.get(name, default)
def __setitem__(self, name, value):
setattr(self, name, value)
def __contains__(self, item):
return item in self.__dict__
def __delitem__(self, name, value):
delattr(self, name, value)
def __iter__(self):
return iter(self.__dict__)
def __repr__(self):
top = _app_ctx_stack.top

21
flask/testsuite/basic.py

@ -1116,18 +1116,27 @@ class BasicFunctionalityTestCase(FlaskTestCase):
self.assert_equal(len(errors), 3)
self.assert_equal(errors[1], None)
def test_subscript_syntax_on_g(self):
def test_get_method_on_g(self):
app = flask.Flask(__name__)
app.testing = True
with app.app_context():
self.assert_equal(flask.g['x'], None)
self.assert_equal(flask.g.get('x'), None)
self.assert_equal(flask.g.get('x', 11), 11)
flask.g.x = 42
self.assert_equal(flask.g['x'], 42)
self.assert_equal(flask.g.get('x'), 42)
self.assert_equal(flask.g.x, 42)
flask.g['x'] = 23
self.assert_equal(flask.g['x'], 23)
self.assert_equal(flask.g.x, 23)
def test_g_iteration_protocol(self):
app = flask.Flask(__name__)
app.testing = True
with app.app_context():
flask.g.foo = 23
flask.g.bar = 42
self.assert_equal('foo' in flask.g, True)
self.assert_equal('foos' in flask.g, False)
self.assert_equal(sorted(flask.g), ['bar', 'foo'])
class SubdomainTestCase(FlaskTestCase):

Loading…
Cancel
Save