#36975: SimpleUploadedFile cannot be re-opened
-------------------------------------+-------------------------------------
Reporter: Denis Washington | Owner: Dinesh
| Thumma
Type: Uncategorized | Status: assigned
Component: Uncategorized | Version: 6.0
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Vishy Algo):
This appears to be a fundamental file handling problem: once a
{{{BytesIO}}} object is created and passed to parent classes, it cannot be
reconstructed if abruptly closed. Since it's an
{{{InMemoryUploadedFile}}}, we could save the content and recreate the
file object via {{{open()}}}, allowing the context manager to clean it up
automatically.
But, currently {{{InMemoryUploadedFile}}} accepts file object while
construction, we have to add it to the {{{SimpleUploadedFile}}} somewhat
similar to this,
{{{#!diff
diff --git a/django/core/files/uploadedfile.py
b/django/core/files/uploadedfile.py
index 1d006ede4f..8ff3c0a08a 100644
--- a/django/core/files/uploadedfile.py
+++ b/django/core/files/uploadedfile.py
@@ -113,6 +113,8 @@ class InMemoryUploadedFile(UploadedFile):
self.field_name = field_name
def open(self, mode=None):
+ if self.closed:
+ self.file = BytesIO(self.content)
self.file.seek(0)
return self
@@ -132,9 +134,9 @@ class SimpleUploadedFile(InMemoryUploadedFile):
"""
def __init__(self, name, content, content_type="text/plain"):
- content = content or b""
+ self.content = content or b""
super().__init__(
- BytesIO(content), None, name, content_type, len(content),
None, None
+ BytesIO(self.content), None, name, content_type,
len(self.content), None, None
)
}}}
I've verified this change with a unit test, and it works as expected. I
believe using {{{InMemoryUploadedFile}}} would have been more appropriate
than {{{SimpleUploadedFile}}}, as it enables easy reconstruction of the
file from its content throughout the request lifecycle for all in-memory
file wrappers.
I'd appreciate any second opinions or suggestions on this approach.
--
Ticket URL: <
https://code.djangoproject.com/ticket/36975#comment:2>