2

I am using django-imagekit to process upload images, and I ran into the following error:

AttributeError at /car/7/

'cStringIO.StringO' object has no attribute 'fileno'

Request Method:     GET 
Request URL:    http://luxingnan.azurewebsites.net/car/7/
Django Version:     1.8
Exception Type:     AttributeError
Exception Value:    

'cStringIO.StringO' object has no attribute 'fileno'

Exception Location:     D:\home\site\wwwroot\env\Lib\site-packages\pilkit\utils.py in
__enter__, line 248
Python Executable:  D:\Python27\python.exe
Python Version:     2.7.8
Python Path:    

[u'D:\\home\\site\\wwwroot\\env\\Lib\\site-packages',  '.',  'D:\\Windows\\SYSTEM32\\python27.zip',  'D:\\Python27\\DLLs',  'D:\\Python27\\lib',  'D:\\Python27\\lib\\plat-win',  'D:\\Python27\\lib\\lib-tk',  'D:\\Python27',  'D:\\Python27\\lib\\site-packages',  'D:\\home\\site\\wwwroot']

Server time:    Thu, 16 Apr 2015 12:28:26 +0000

below is my code:

# models.py
class Carpic(models.Model):
    picture = models.ImageField('pic',upload_to='car-pictures')
    picture_slide = ImageSpecField(source='picture',
        processors=[ResizeToFill(762, 456)],
        format='JPEG',
        options={'quality': 60}
        )
# template.html
{% for pic in pictures %}
<li><img src="{{pic.picture_slide.url}}"/></li>
{% endfor %}

Can someone tell me what should I do? Thanks

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
JSNoob
  • 1,477
  • 2
  • 18
  • 31
  • this error is related to the pilkit image processing package, i traced the problem with some research and found that the problem is related to the FileWrapper class in pilkit/utils.py trying to call fileno() on a StringIO instance, this SO answer provides detailed explanation http://stackoverflow.com/a/5903627/4724196 – HassenPy Apr 16 '15 at 15:53
  • try to open an issue in pilkit's repo here https://github.com/matthewwithanm/pilkit/issues – HassenPy Apr 16 '15 at 15:54
  • what's weird is that everything is fine in local environment. But after I deploy it to Azure, it gives me that error – JSNoob Apr 16 '15 at 20:33
  • you develop on a linux environment or on windows? – HassenPy Apr 17 '15 at 04:45
  • @HassenPy Thanks Hassen. Instead I tried Heroku and everything is working well right now. I guess it's probably Azure's problem – JSNoob Apr 17 '15 at 06:09
  • @HaseeenPy I don't see why FileWrapper is the issue, that's just acting as a proxy. The problem is that the underlying file (StringIO) doesn't have a `fileno()` and something wants it. The first step to solving this would be to find out what's calling `fileno()` – matthewwithanm Apr 20 '15 at 18:07

1 Answers1

1

Just got a chance to look at this (and your GH Issue). I'll include my response here cuz that seems like the right thing to do SO-wise (:

So it looks like this is a quirk of Azure but we can definitely fix it in PILKit.

PILKit has a utility for quieting some of PIL's noise. The way it does this is by temporarily replacing stderr (using its file descriptor). Apparently on Azure, stderr is an instance of StringIO (which doesn't have a file descriptor). We'll just have to add a guard to the utility for that case (just like the one for when dev/null isn't writeable). It's a small change but I'm pretty busy at the moment. A PR would be much appreciated!

So, in other words, it's not an issue with FileWrapper (as suggested in the comments), but rather a combination of Azure's fake stderr and PILKit's quiet utility.

matthewwithanm
  • 3,733
  • 2
  • 21
  • 27
  • This seems like an odd way to accomplish that. It's my understanding that reassigning `sys.stderr` is the normal method of temporarily redirecting stderr, and that should work just fine with StringIO etc. – Kevin Apr 20 '15 at 18:32
  • Reassigning Python's sys.stderr doesn't do the same thing. PIL's noisiness is actually happening at a lower level. Check out [this SQ question](http://stackoverflow.com/questions/977840/redirecting-fortran-called-via-f2py-output-in-python) for a better description of the problem we're solving there. – matthewwithanm Apr 20 '15 at 21:00
  • Hm... In that case, the "real" stderr should still point to *something*. On most systems, stderr is fd #2. You might be able to hard-code that, if it's reliable enough. I also believe there's a C macro that expands to the stderr fd, for greater portability. I suppose it might be closed, but in that case, "preserving" it should be trivial. – Kevin Apr 21 '15 at 03:11
  • I think I feel more comfortable just trying to get the fd and backing out if there's an error than making assumptions about the descriptor. But if you feel strongly about it, we can discuss it more on GH. – matthewwithanm Apr 21 '15 at 11:23