views:

158

answers:

1

I'm unable to access the request object in my Pylons 0.9.7 controller when I set debug = false in the .ini file. I have the following code:

def run_something(self):
    print('!!! request = %r' % request)
    print('!!! request.params = %r' % request.params)
    yield 'Stuff'

With debugging enabled this works fine and prints out:

!!! request = <Request at 0x9571190 POST http://my_url&gt;
!!! request.params = UnicodeMultiDict([... lots of stuff ...])

If I set debug = false I get the following:

!!! request = <paste.registry.StackedObjectProxy object at 0x4093790>
Error - <type 'exceptions.TypeError'>: No object (name: request) has been registered for this thread

The stack trace confirms that the error is on the print('!!! request.params = %r' % request.params) line.

I'm running it using the Paste server and these two lines are the very first lines in my controller method.

This only occurs if I have yield statements in the method (even though the statements aren't reached). I'm guessing Pylons sees that it's a generator method and runs it on some other thread. My questions are:

  1. How do I make it work with debug = false ?
  2. Why does it work with debug = true ? Obviously this is quite a dangerous bug, since I normally develop with debug = true, so it can go unnoticed during development.
+2  A: 

You should not yield from action directly. Try making inner function and returning func():

def run_something(self):
    request = pylons.request._current_obj()
    def func():
        print('!!! request = %r' % request)
        print('!!! request.params = %r' % request.params)
        yield 'Stuff'
    return func()
Yaroslav
OK, that works. I modified it slightly by assigning `self.request = request._current_obj()`. But why do I have to do this at all and why only with debug = false?
Evgeny
Because 'request' is a module-level variable of type StackedObjectProxy. It is shared between all threads and performs operations on the real object bound to currently running thread. The reason of getting _current_obj() manually is probably of the Pylons design. I think it 'unbounds' request from the current thread when the action is complete. When pylons yield results from 'func' function the action is already completed.Not sure about debug=false setting but I suppose it is due to some middleware that changes request behavior.
Yaroslav
You need to set debug=false because in the other case output is buffered and you would not have 'streaming' effect.
Yaroslav