Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doctest causes a working out of context RuntimeError with request #2485

Closed
alexprengere opened this issue Aug 2, 2022 · 3 comments · Fixed by #2497
Closed

doctest causes a working out of context RuntimeError with request #2485

alexprengere opened this issue Aug 2, 2022 · 3 comments · Fixed by #2497
Milestone

Comments

@alexprengere
Copy link

alexprengere commented Aug 2, 2022

Migrating from Flask 2.1 to 2.2 failed a few unit tests of mine. It looks like we can no longer import flask.request top level in a test file (reproduced across Python 3.7, 3.8, 3.9, 3.10):

from flask import Flask
from flask import request

def test_something():
    assert True

This gives a RuntimeError:

E   RuntimeError: Working outside of request context.
E
E   This typically means that you attempted to use functionality that needed
E   an active HTTP request. Consult the documentation on testing for
E   information about how to avoid this problem.

On my side the fix was simple: importing flask.request outside of the global scope, just when I actually need it (my actual tests create small Flask apps to test a client).

Edit: forgot to mention that this only occurs when pytest is run with --doctest-modules

@davidism davidism changed the title Importing flask.request in a test file gives a RuntimeError on Flask 2.2 doctest causes a working out of context RuntimeError with request Aug 2, 2022
@davidism
Copy link
Member

davidism commented Aug 2, 2022

This used to happen in pallets/flask#1680, but was fixed in Werkzeug #924 a long time ago. Seems it has started happening again.

@davidism davidism transferred this issue from pallets/flask Aug 2, 2022
@davidism
Copy link
Member

davidism commented Aug 2, 2022

Running python -m doctest example.py, with just from flask import request in the file, causes the error.

What's happening is that Werkzeug only sets __wrapped__ if the Local wraps a function, but does not set the attribute otherwise. Flask 2.2 started wrapping ContextVar directly instead of a function. Doctest uses inspect.unwrap to access that attribute, which fails with a proxy error instead of an attribute error. This bug was always present with doctest and previous versions, but it was hidden because of the way Flask previously used Local.

Unfortunately, just the presence of __wrapped__ indicates to inspect.unwrap that something is a wrapper. So we can't set it to None, as that would make it present but incorrect.

I really think this is a bug in Python's inspect, it should ignore errors when accessing the attribute, but it's unlikely to get fixed there. The only think we can really do in Werkzeug is to either set the attribute to something incorrect, or see if there's a way to simulate an AttributeError on access.

@davidism
Copy link
Member

davidism commented Aug 8, 2022

This was reported in doctest years ago: python/cpython#70186. I think this is an issue with doctest, Sphinx uses inspect.unwrap as well but catches exceptions so that it doesn't fail.

For now, I'll set __wrapped__ to whatever LocalProxy is wrapping, not only if it's wrapping a function.

@davidism davidism added this to the 2.2.2 milestone Aug 8, 2022
@davidism davidism linked a pull request Aug 8, 2022 that will close this issue
@davidism davidism closed this as completed Aug 8, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants