Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#29278 closed Cleanup/optimization (fixed)

FileResponse documentation should warn against using context managers

Reported by: Mike DePalatis Owned by: Windson yang
Component: Documentation Version: 2.0
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: yes UI/UX: no

Description

Idiomatic Python usually opens file objects using a context manager like this:

with open("filename.txt", "rb") as fo:
    # do stuff with fo

This is problematic when using a FileResponse which requires a file-like object rather than a path. Doing something like:

with open("filename.txt", "rb") as fo:
    return FileResponse(fo)

results in an error due to trying to operate on a closed file:

Exception happened during processing of request from ('127.0.0.1', 60169)
Traceback (most recent call last):
  File "/Users/zduey/anaconda3/envs/cml/lib/python3.5/wsgiref/handlers.py", line 138, in run
    self.finish_response()
  File "/Users/zduey/anaconda3/envs/cml/lib/python3.5/wsgiref/handlers.py", line 179, in finish_response
    for data in self.result:
  File "/Users/zduey/anaconda3/envs/cml/lib/python3.5/wsgiref/util.py", line 30, in __next__
    data = self.filelike.read(self.blksize)
ValueError: read of closed file

The documentation for FileResponse should be updated to explicitly warn users against passing in file objects opened with a context manager and make clear that the file will be closed automatically.

Change History (9)

comment:1 by Claude Paroz, 6 years ago

Triage Stage: UnreviewedAccepted
Type: UncategorizedCleanup/optimization

comment:2 by Windson yang, 6 years ago

Owner: changed from nobody to Windson yang
Status: newassigned

comment:3 by Windson yang, 6 years ago

comment:4 by andrei kulakov, 6 years ago

I don't think this requires a warning because the sole function and purpose of with construct is to close file objects / clean up state when done with the block. By the same logic we would have to document all Python features in Django docs.

in reply to:  4 ; comment:5 by Mike DePalatis, 6 years ago

Replying to andrei kulakov:

I don't think this requires a warning because the sole function and purpose of with construct is to close file objects / clean up state when done with the block. By the same logic we would have to document all Python features in Django docs.

I don't think all Python features need to be documented. However, this is a special case where the required way of opening a file goes against the usual best practices and thus it makes sense that this should be explicitly noted.

in reply to:  5 comment:6 by andrei kulakov, 6 years ago

Replying to Mike DePalatis:

I don't think all Python features need to be documented. However, this is a special case where the required way of opening a file goes against the usual best practices and thus it makes sense that this should be explicitly noted.

In theory, perhaps, but in this case someone using this best practice needs to understand the reason for 'with' construct. It's a fairly common construct and its
use is much more general than just file objects. Also the way it works is neither very obscure nor complex to understand.

You could also argue that the best practice is "use with construct and complete all work on file within the with block", and so this best practice does not apply
here because obviously no work is completed in the example.

comment:7 by Claude Paroz, 6 years ago

Has patch: set
Patch needs improvement: set

I think it's useful for users to know FileResponse will close the file itself, and that it's not possible to close the file before the response has finished streaming it.

comment:8 by Tim Graham <timograham@…>, 6 years ago

Resolution: fixed
Status: assignedclosed

In 4fe5d846:

Fixed #29278 -- Doc'd that a context manager can't be used with FileResponse.

comment:9 by Tim Graham <timograham@…>, 6 years ago

In a390cc71:

[2.0.x] Fixed #29278 -- Doc'd that a context manager can't be used with FileResponse.

Backport of 4fe5d846666d46a5395a5f0ea2845a96b6837a75 from master

Note: See TracTickets for help on using tickets.
Back to Top