You need to call resp.close()
to close the file opened by send_file()
I had a basic Flask app using send_file()
, which I was testing with pytest:
#!/usr/bin/env python3
from flask import Flask, send_file
app = Flask(__name__)
@app.route("/source.py")
def source_code():
return send_file(__file__)
def test_can_get_source_code():
with app.test_client() as client:
resp = client.get("/source.py")
assert resp.data.startswith(b"#!/usr/bin/env python3\n")
but when I ran this test with warnings-as-errors, I got a warning about a file not being closed:
$ py.test app.py
...
E pytest.PytestUnraisableExceptionWarning: Exception ignored in: <_io.FileIO [closed]>
E
E Traceback (most recent call last):
E File "/.venv/lib/python3.12/site-packages/_pytest/python.py", line 193, in pytest_pyfunc_call
E result = testfunction(**testargs)
E ^^^^^^^^^^^^^^^^^^^^^^^^
E ResourceWarning: unclosed file <_io.BufferedReader name='app.py'>
I found several GitHub issues about this warning (pallets/flask#3735, pallets/werkzeug#1785). Neither of them provide an explicit answer, but the clue is in the answer of the linked pull request (pallets/werkzeug#2041).
If I close the response when I’m done, the warning goes away:
def test_can_get_source_code():
with app.test_client() as client:
resp = client.get("/source.py")
assert resp.data.startswith(b"#!/usr/bin/env python3\n")
+ resp.close()