This is really stumping me... Here is the nub of the issue:
if hasattr(sys.stderr, 'fileno'):
if callable(sys.stderr.fileno):
i = sys.stderr.fileno()
When this statement executes, the 2 conditions pass, BUT the call to fileno() bombs with an AttributeError!! Don't believe me? Here's the stack dump:
Request Method: GET Request URL:
https://XXXX/YYYY/abcdef/hazards/NSP-F15-22/pdf/
Django Version: 1.8.3 Python Version: 3.4.0 Installed Applications: ('django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.sites', 'django.contrib.flatpages', 'crispy_forms', 'wkhtmltopdf', 'ckeditor', ...) Installed Middleware: ('django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware')
Traceback: File "/usr/local/lib/python3.4/dist-packages/django/core/handlers/base.py" in get_response 164. response = response.render() File "/usr/local/lib/python3.4/dist-packages/django/template/response.py" in render 158. self.content = self.rendered_content File "/usr/local/lib/python3.4/dist-packages/wkhtmltopdf/views.py" in rendered_content 148.footer_filename=footer_filename) File "/usr/local/lib/python3.4/dist-packages/wkhtmltopdf/views.py" in convert_to_pdf 107. return wkhtmltopdf(pages=[filename], **cmd_options) File "/usr/local/lib/python3.4/dist-packages/wkhtmltopdf/utils.py" in wkhtmltopdf
101. i = sys.stderr.fileno()
Exception Type: AttributeError at /abcdef/hazards/NSP-F15-22/pdf/
Exception Value: 'mod_wsgi.Log' object has no attribute 'fileno'
This all runs fine in our development environment running django dev server (i.e., not using wsgi). But in our production env. we are serving a Django app on apache with mod_wsgi on Ubuntu. All software latest stable versions (Ubuntu 14.04, python 3.4, django 1.8, libapache2-mod-wsgi-py3 3.4-4ubuntu2.1.14.04.2) .
The issue seems to stem from wsgi replacing sys.stderr with a mod_wsgi.Log object. Back in 2013 a patch was added in django-wkhtml2pdf to fix this issue... see: https://github.com/incuna/django-wkhtmltopdf/pull/40
Unfortunately, as you can see from the code that is bombing on me, sys.stderr does have a 'fileno' attribute AND the fileno attribute is callable, BUT when you go to call it, Python raises the AttributeError exception shown above.
I'm at wits end - must be missing something really stupid here. Would be ever so grateful for any hints on what might be the cause or where to look next.
type(sys.stderr)
is an extension class (i.e. implemented in C instead of Python) which raises an AttributeError when you call itsfileno()
method. Maybe it's trying to proxy to some other object (perhaps a mod_wsgi.Log instance) in a really strange/broken way? I'd try to reduce this to a minimal test case and report a bug in Django. – Kevin