This is an annoying problem I am having with Twisted.web. Basically, I have a class that inherits from twisted.web.resource.Resource
and adds some default stuff to Mako templates:
from twisted.web.resource import Resource
from mako.lookup import TemplateLookup
from project.session import SessionData
from project.security import make_nonce
class Page(Resource):
template = ""
def display(self, request, **kwargs):
session = SessionData(request.getSession())
if self.template:
templates = TemplateLookup(directories=['templates'])
template = templates.get_template(self.template)
return template.render(user=session.user,
info=session.info,
current_path=request.path,
nonce=make_nonce(session),
**kwargs)
else:
return ""
Then, and I have narrowed the problem down to this small class (which I tested), I write a resource which inherits from Page
:
class Test(pages.Page):
def render_GET(self, request):
return "<form method='post'><input type='submit'></form>"
def render_POST(self, request):
request.redirect("/test")
request.finish()
I'd like to note that, in every other case, if request.finish()
isn't the last line in a function, then I return
immediately after it.
Anyways, I add this class to the site at /test
and when I navigate there, I get a submit button. I click the submit button, and in the console I get:
C:\Python26\lib\site-packages\twisted\web\server.py:200: UserWarning: Warning! request.finish called twice. self.finish()
But, I get this ONLY the first time I submit the page. Every other time, it's fine. I would just ignore this, but it's been nagging at me, and I can't for the life of me figure out why it's doing this at all, and why only the first time the page is submitted. I can't seem to find anything online, and even dropping print statements and tracebacks in the request.finish()
code didn't reveal anything.
edit
This morning I tried adding a second request.finish()
line to the resource, and it still only gave me the error one time. I suppose it will only warn about it in a resource once -- maybe per run of the program, or per session, I'm not sure. In any case, I changed it to:
class Test(pages.Page):
def render_GET(self, request):
return "<form method='post'><input type='submit'></form>"
def render_POST(self, request):
request.redirect("/test")
request.finish()
request.finish()
and just got two messages, one time. I still have no idea why I can't redirect the request without it saying I finished it twice (because I can't redirect without request.finish()
).