Opened 8 years ago
Last modified 8 years ago
#27150 new Cleanup/optimization
Document that a name should be provided when wrapping file-like objects that don't have one with File
Reported by: | Sergei Zh | Owned by: | nobody |
---|---|---|---|
Component: | Documentation | Version: | 1.10 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
django.core.files.base.File supports file-like objects (synonym to file object in python glossary) and in fact can't rely on additional name
attribute, but in current implementation of __bool__
method it does:
def __bool__(self): return bool(self.name)
For example, until tempfile.SpooledTemporaryFile
isn't large enough to have been written to disk, his name
attribute is None
and if
statement will return False.
import tempfile from django.core.files.base import File python_file_like_object = tempfile.SpooledTemporaryFile() file_obj = File(python_file_like_object) # name keyword is None by default if file_object: # Falsy, because python_file_like_object.name is None print("42")
The same behavior with streams (BytesIO, StringIO).
Maybe __bool__
method should rely on self.file
attribute to avoid this behavior?
Change History (7)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
Hi.
Sure, it makes sense. I'll try to investigate failed tests ASAP. Think it's the best place to begin.
comment:3 by , 8 years ago
Component: | Core (Other) → Documentation |
---|---|
Summary: | Wrong File object behavior if file object has no name attribute → Document that a name should be provided when wrapping file-like objects that don't have one with File |
Triage Stage: | Unreviewed → Accepted |
Type: | Bug → Cleanup/optimization |
See #26495 for a case where this came up. Unless investigation yields otherwise, I think documenting that you should pass a name for file-like objects that don't have one is the best course of action. I'm not sure if raising an error for that case might be acceptable (there might be use cases where providing name
isn't needed) but if so, they would likely be even more helpful.
comment:4 by , 8 years ago
As I understood from #26495 python file-like objects works fine with requests
library, because in CPython file objects use object.__bool__
and always returns True if no __bool__
and __len__
.
I think documenting that you should pass a name for file-like objects that don't have one is the best course of action.
It's little bit strange for me to allow pass name=None
to Storage.save
, while disallow use empty name for file-like objects. Maybe we can restore default __bool__
behavior in Storage.save
method?
content.__bool__ = lambda _: True
comment:5 by , 8 years ago
I've realized it's wrong, we should delete __bool__
method, cause default implementation depends on __len__
method.
comment:6 by , 8 years ago
I haven't looked into the issue so I can't propose an alternative, however, I'm not sure that patching methods like that is a good practice. At least, I'm not aware of anywhere else in Django that uses that pattern.
Hi,
As far as I can tell,
File.__bool__
is not documented but it does seem to be used internally and is somewhat tested (though maybe not directly): changing it toreturn False
yields quite a few errors and failures in the test suite.Because of this lack of documentation, it's hard to tell if the behavior you're describing is a bug.
I think it'd be worth it to:
1) Document
File.__bool__
(both in the reference docs and in the docstring)2) Figure out if we can improve it by handling underlying files with no names as you suggest.
What do you think?