Switch away from using None as default value for the exception when tearing down a context.

When an exception has been handled when using the request / app context in a with statement, `sys.exc_info()` will still contain the exception information even though it has been handled already. The `__exit__` methods pass in `None` for the exception value in that case, which needs to be distinguisable from the default value for the `exc` parameter. Use a dedicated singleton sentinel value instead.
This commit is contained in:
Martijn Pieters 2015-03-23 15:17:19 +00:00
parent ec5811d0a1
commit ec0d208bc1
4 changed files with 45 additions and 8 deletions

View file

@ -21,6 +21,10 @@ from .signals import appcontext_pushed, appcontext_popped
from ._compat import BROKEN_PYPY_CTXMGR_EXIT, reraise
# a singleton sentinel value for parameter defaults
_sentinel = object()
class _AppCtxGlobals(object):
"""A plain object."""
@ -168,11 +172,11 @@ class AppContext(object):
_app_ctx_stack.push(self)
appcontext_pushed.send(self.app)
def pop(self, exc=None):
def pop(self, exc=_sentinel):
"""Pops the app context."""
self._refcnt -= 1
if self._refcnt <= 0:
if exc is None:
if exc is _sentinel:
exc = sys.exc_info()[1]
self.app.do_teardown_appcontext(exc)
rv = _app_ctx_stack.pop()
@ -320,7 +324,7 @@ class RequestContext(object):
if self.session is None:
self.session = self.app.make_null_session()
def pop(self, exc=None):
def pop(self, exc=_sentinel):
"""Pops the request context and unbinds it by doing that. This will
also trigger the execution of functions registered by the
:meth:`~flask.Flask.teardown_request` decorator.
@ -334,7 +338,7 @@ class RequestContext(object):
if not self._implicit_app_ctx_stack:
self.preserved = False
self._preserved_exc = None
if exc is None:
if exc is _sentinel:
exc = sys.exc_info()[1]
self.app.do_teardown_request(exc)