#15644: django.core.files.base.File enhancement / fix
---------------------------+---------------------------
 Reporter:  nickname123    |         Owner:  nobody
   Status:  new            |     Milestone:  1.3
Component:  Uncategorized  |       Version:  1.2
 Keywords:  file           |  Triage Stage:  Unreviewed
Has patch:  1              |
---------------------------+---------------------------
 Hi,

 I think that django.core.files.base.File should be expanded to handle a
 wider range of file objects.  In my specific case, StringIO/cStringIO and
 tempfile.SpooledTemporaryFile objects.

 Here is a simple demonstration of where the File class breaks:
 {{{
 from tempfile import SpooledTemporaryFile
 from django.core.files import File
 f = SpooledTemporaryFile(
                 max_size    = 1024,# 1kb
                 mode        = 'w+b',# must be open in binary mode
                 bufsize     = -1,
                 suffix      = '',
                 prefix      = 'tmp',
                 dir         = None
 )
 f.write("hello")
 print len(File(f))
 }}}

 Here is the result (on Windows using Python2.6):
 {{{
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "C:\...\django\core\files\base.py", line 33, in __len__
     return self.size
   File "C:\...\django\core\files\base.py", line 39, in _get_size
     elif os.path.exists(self.file.name):
   File "C:\...\lib\tempfile.py", line 559, in name
     return self._file.name
 AttributeError: 'cStringIO.StringO' object has no attribute 'name'
 }}}

 It should be noted that not only does the current implementation fail, but
 it breaks in the wrong code block because it doesn't verify that the name
 attribute is available.

 I propose that the file objects seek and tell method be used as an
 additional fallback before throwing the attribute error as follows:
 {{{
 def _get_size(self):
         if not hasattr(self, '_size'):
                 if hasattr(self.file, 'size'):
                         self._size = self.file.size
                 elif hasattr(self.file, 'name') and
 os.path.exists(self.file.name):
                         self._size = os.path.getsize(self.file.name)
                 elif hasattr(self.file, 'tell') and hasattr(self.file,
 'seek'):
                         pos = self.file.tell()
                         self.file.seek(0,os.SEEK_END)
                         self._size = self.file.tell()
                         self.file.seek(pos)
                 else:
                         raise AttributeError("Unable to determine the
 file's size.")
         return self._size
 }}}

 My proposed patch fixes the problems mentioned above.

-- 
Ticket URL: <http://code.djangoproject.com/ticket/15644>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to