Closed PaulWhitingUVC closed 3 months ago
Call response.close()
at the end. See Flask itself for examples of this in tests.
Call
response.close()
at the end. See Flask itself for examples of this in tests.
@davidism, I assume you are referring to the call to rv.close()
in the test_send_from_directory code.
Unfortunately, the call to send_from_directory and the associated close both happen in the test code proper. When called by production code the call to response.close()
cannot be done without error. When I modify download_resources
to the following it causes additional errors:
@app.route('/<path:name>')
def download_resources(name):
response = send_from_directory('resources', name)
response.close()
return response
Error:
self = <werkzeug.wsgi.FileWrapper object at 0x10c061150>
def __next__(self) -> bytes:
> data = self.file.read(self.buffer_size)
E ValueError: read of closed file
venv/lib/python3.11/site-packages/werkzeug/wsgi.py:332: ValueError
The documentation does not mention a call to response.close()
.
Other documentation similarly does not call response.close()
.
It seems to me that the rv.close()
in Flask's test case masks the unclosed file error, as you are not using send_from_directory via an external call like a Flask app would.
Thoughts?
You don't call it in your application, only in your test. WSGI servers close the response automatically, the test client cannot.
When warnings are set to error, pytest claims there is an unclosed file when
send_from_directory
is called. I assume this indicates there is a resource leak. Even if Python garbage collects this at some point, this causes issues with testing flask applications that use send_from_directory with warnings as errors enabled.app.py:
resources/file.txt
tests/conftest.py:
tests/test_app.py:
Execute
pytest -Werror
.The results (results.txt) include the following error:
ResourceWarning: unclosed file <_io.BufferedReader name='/flask-test/resources/file.txt'>
Expected Results:
Execute
pytest
without warnings as errors. This is the expected result:Environment: