Recently I have started developing an application using the excellent Python web framework web2py. Web2py comes with its own a web-based integrated development environment that makes it easy to write small web based applications from within your browser. However once you start developing something bigger you will want the convenience of a real IDE. Code completion, multiple open files and a debugger will all make the experience more comfortable. However due to web2py’s mode of operation your IDE will require some additional help from you to allow its full powers to blossom.
Web2py’s mode of operation
Contrary to other Python web frameworks, such a Django, web2py doesn’t use Python’s import statement to load your code. Instead it executes your code using Python’s built in function execfile and supplies it with a prepared environment that contains a number of global objects that are central to web2py’s programming model (e.g. request, response, session objects, HTML helper functions, etc). This also means that your IDE has no knowledge of these objects and functions unless you explicitly tell it about them.
Informing your IDE about web2py’s prepared environment
Even though I use Eclipse/PyDev, the trick to let any Python aware IDE know about these objects is the same. In fact I got the idea from the How-To Using Wing IDE with web2py.
From the IDE’s point of view there are two types of files that it requires additional information about:
- models
- controllers
Simply adding import statements for the global objects and functions web2py is going to provide us with at runtime might cause unforeseen problems. Hence we need to import them conditionally.
For models adding the following snippet of code at the top will suffice:
if 0:
from gluon.sql import *
from gluon.validators import *
For controllers the following will do:
if 0:
from gluon.globals import *
from gluon.html import *
from gluon.http import *
from gluon.sqlhtml import SQLFORM, SQLTABLE, form_factory
session = Session()
request = Request()
response = Response()
How does this work? The conditional 0 will always evaluate to False. This means that at run-time the statements following the if statement will never be executed. It’s dead code and hence will never interfere with whatever web2py has setup for us in its prepared environment.
It’s different for the IDE. The Python parser that’s part of your preferred Python IDE only parses your code. It does not evaluate it as Python does. As such it has to take the possibility into account that it might be executed at some point in time and that other code might depend on it. It has to read in the imports and consequently has all the information needed for code completion. Your IDE is now aware of web2py’s prepared environment
desfrenes said
Nice when using the ide, but it breaks one of web2py’s strength which is not having to import the framework components.
Hans said
@desfrenes
if I understood the Guido’s explanation right then the import statements are never executed with the exception of the IDE doing it unconditionally, hence in production there are no imports executed anyway. Or did I miss something?
rev said
I’m trying out web2py and would like to use Eclipse/PyDev.
I fail to get breakpoints/debugging working.
Any hints?
Guido said
@rev
No hints, except for the obvious. Do make sure you’re not merely running your program, but actually debugging it by right clicking on web2py.py, Debug As, Python run. For some reason you can’t set break points using CTRL-Shift-B in Pydev. Instead you have to double click in the margin of the line of code you want to set the breakpoint in. You also might have to tinker with your working directory. My Pydev project simply starts at the root of the web2py directory. Also make sure that you’ve added that root directory to your PYTHONPATH as a source folder in your project properties.
rev said
That’s exactly what I tried, but it didn’t work.
Started all over again from scratch and now it’s working.
That’s Eclipse for you… bweugh.
Carl Roach said
I’m trying to get nosetests working with web2py & eclipse.
In my test (testinit.py) I “from project.gluon.globals import *” causing nosetests to report “No Module named gluon.utils”.
Have you used nosetests with eclipse/web2py and can help?
And if you’re using an alternative unit testing system could you share your experiences?
Guido said
Can’t help you here. Haven’t tried writing any tests yet.
Carl Roach said
I’ve tried to get nosetests to work with web2py within Eclipse but failed. Web2py has a dynamic environment which trips nosetests up. Right now I think only doctests is being used in anger with web2py codebases.