views:

380

answers:

5

I'm using mod_wsgi and was wondering if it's possible to over-write the print() command (since it's useless).

Doing this doesn't work:

print = myPrintFunction

Since it's a syntax error. :(

+5  A: 

Would

import sys
sys.stdout = MyFileWrapper()

or something similar work?

CAdaker
>> AttributeError: 'function' object has no attribute 'write'(when calling the replacement) :(
Ian
Cancel that, it works if the replacement object has a "write()" function. cool. :)
Ian
+12  A: 

Print is not a function in Python 2.x, so this is not directly possible.

You can, however, override sys.stdout.

If you are on Python 3.0 in which print is now a function what you have would then work, assuming you have the right signature. Also see a related question in this site.

Paolo Bergantino
+1  A: 

If you are using 3.0, print is a function. If you are using 2.6, you can from __future__ import print_function and continue with a print function.

If <= 2.5, you can replace stdout like others have suggested, but be very careful if your wsgi server will call your app in multiple threads simultaneously. You WILL end up with simultaneous requests being sent down the same pipe.

I haven't tested it, but you could try something like this:

import sys
import threading

class ThreadedStdout(object):
    def __init__(self):
        self.local = threading.local()
    def register(self, fh):
        self.local.fh = fh
    def write(self, stuff):
        self.local.fh.write(stuff)

sys.stdout = ThreadedStdout()

def app(environ, start):
    sys.stdout.register(environ['wsgi.stdout'])

    # Whatever.
Mike Boers
+1  A: 

It is worth noting that use of 'print' to sys.stdout in Apache/mod_wsgi was deliberately restricted. This is because a portable WSGI application should not use either sys.stdin or sys.stdout as some WSGI implementations use them to communicate to the server.

Apache/mod_wsgi is therefore trying to force you to write your WSGI application such that it will be portable to other WSGI implementations.

Unfortunately, too many people seem not to care about writing good code and so mod_wsgi 3.0 will allow you to write to sys.stdout and thus use 'print' without redirecting output to 'sys.stderr' as you should be doing.

Either way, the mod_wsgi documentation details how to remove the restriction in versions of mod_wsgi prior to 3.0. In particular, see documentation about the WSGIRestrictStdout directive. The documentation about debugging techniques also talks about the issue and about mapping sys.stdout to sys.stderr.

You can read a commentary which summaries this issue at:

http://blog.dscpl.com.au/2009/04/wsgi-and-printing-to-standard-output.html

Graham Dumpleton
A: 

While you can redirect stdout to different sources like file for logging, as Paolo mentions, you probably wouldn't need it. I didn't need it. If you really needed to log stuff, you would be using logging itself in the first place, wouldn't you? Also, even when you don't print a thing, the third party libraries you use may do. Just redirect it and get going.

The simplest solution to this problem is to redirect all stdout into stderr. In the wsgi configuration file, just redirect as necessary.

sys.stdout = sys.stderr
Lakshman Prasad
Just use mod_wsgi 3.0 and you don't even have to do that.
Graham Dumpleton