It seems many people are confused about web2py. In recent discussions, I understood better the nature of this confusion. Perhaps this will help eliminate some of the misunderstandings.
web2py does not use exec to execute user input but to execute application code. Here is why. In a computer system running Python, you have a hardware layer, an OS layer, the Python (interpreter) layer, and the Python (user code) layer. All frameworks but web2py are designed so that the web framework and the web application are linked to each other (via import) and therefore both comprise together the user code layer. When we designed web2py, we purposely separated the framework layer from the web application(s) layer, and we use the Python interpreter within the framework itself to execute (via exec) the user application code. The application code is still written in Python, and it can still use imports for the modules it needs, and it can run without restrictions compatibly with the permission with the user running the web server (it is our applications and if we run, we trust it). So why are we doing this? Because this allows hot swap and plug-and-play of applications and/or parts of an application without ever restarting the server, in development as well as in production, with any web server. This allows the system administrator to change any part of an application by installing a plugin at runtime. This opens the doors to many interesting possibilities. We believe there is a value in keeping the framework layer and the web application layer separated. Some of the ease of use in web2py is possible only because of this design choice.
Other frameworks that do not use exec, implement module reloading. That only works with the built-in servers, can cause memory leaks and inconsistent references (when modules define global objects), it is discouraged by the official Python documents, and does not quite achieve the hot swap and web based edit capability that make web2py popular.
Web2py does provide a web based Python shell and web based IDE. The code inserted via the shell or via admin is also executed. Access to shell and IDE is restricted to the administrator. We identify the administrator via a one-time password that must be set server side at web2py startup. Since the administrator is, by definition, the user who has login access to the server, we do not restrict what the administrator can do via the shell or IDE. Authentication of the administrator only works from localhost or via https using secure cookies.
Anyway, both the shell and the web based idea can be disabled with a flag at web2py start-up.
People who browse the web2py source code superficially are usually confused by the presence of a file called import_all that imports almost all standard Python modules. Why would anybody sane of mind do that? For two very good reasons that probably never occurred to you:
Sometimes applications fail because they cannot find a required system module (because it has been accidentally deleted or is corrupted or is missing in the current Python version). We do not like when a user downloads a web2py application from the web, uploads it into a running web2py instance, and finds the application crashes because of a missing module. We want web2py to check when the framework starts up that all required modules are where they are supposed to be and can be properly imported.
We use py2exe and py2app to build binary distributions of web2py for Windows and Mac. This is done independently of user applications since these are plugged in later. Still py2exe and py2app need to find and bytecode compile not simply modules that are used by the frameworks, but modules which may later be used by a plugged in application. import_all is used to inform py2exe and py2app about the list of modules that applications can rely on.
Perhaps there is a better way to achieve these goals but nobody has proposed one. Anyway, we are always open to suggestions.
There is a lot of duplication of code in web2py between the files sql.py and dal.py. That is because dal.py is a rewrite of sql.py. Only sql.py is actually used but we ship dal.py too because we encourage users to test it.
We strongly believe in PEP8. We take a lot of efforts in making web2py source code PEP8 compliant. Sometimes it is difficult, but we try. We went through many PEP8 cleanup revisions.
Yet we need to distinguish web2py source code and web2py application code (as executed by the web2py framework). Because we have an extra layer which exposes a few new symbols (variables, classes, objects), we need a few extra conventions to deal with them. Our goal is make those symbols obvious to the developer of the app, and yet not conflict with symbols defined by the developer, who is assumed to follow PEP8. So we adopted this convention:
The reason for the all caps is that those objects are classes but they are defined at the framework layer, not at the web application layer. That means that the application should treat them as constants classes and not change any class attributes. All caps seems appropriate.
Web2py was a one man project but not for long (don’t all project start with one person?). We have a very large community and at least 50 people have actively contributed to web2py, and the group is growing.