Testing for the existence of a Flask request context
I just finished reviewing a pull request that contained an extraneous statement inside a try
block.
Here's the code in question:
try:
if signature not in g._celery_tasks:
g._celery_tasks.append(signature)
except RuntimeError:
signature()
While this code works fine, the RuntimeError
being caught is expected to be raised when g._celery_tasks
is accessed.
Because g
is a werkzeug.LocalProxy
object, the exception is raised if there is no active request context. My concern
was that if the next line raised a RuntimeError
, it would also be caught. As this is not the intent of this handler
catching such an error would be unexpected behavior.
PEP8 briefly addresses this as well, under Programming Recommendations:
[...] for all try/except clauses, limit the try clause to the absolute minimum amount of code necessary. Again, this avoids masking bugs.
When I got to this point I suddenly lost the ability to Python, and had to turn to the Internet for assistance. After
some research, I asked for help in #pocoo
on Freenode. Here's the result:
This not only allows us to move that spurious line of code from the try
block, but also to completely prevent the
RuntimeError
from being thrown.
from flask import _app_ctx_stack as context_stack
if context_stack.top is None:
signature()
elif signature not in g._celery_tasks:
tasks.append(signature)
Since my cursory search for an easy way to determine if a request context were active wasn't very helpful, I decided to go ahead and document my method here.
My thanks to mattupstate for the recommendation on IRC. If you're feeling generous, please consider supporting him on Gratipay.