test.py:
import web
render = web.template.render('templates/')
urls = (
'/', 'index'
)
class index:
def GET(self):
name='Bob'
return render.test(name)
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
templates/test.html:
$def with (name)
$if name:
I just wanted to say <em>hello</em> to $name.
$else:
<em>Hello</em>, world!
Environment: Python38 x64, Windows 10, Web.py==0.4
Error Details:
raise SecurityError("\n".join([str(err) for err in self.errors]))
web.template.SecurityError: templates\test.html:3 - execution of 'Constant' statements is denied
templates\test.html:7 - execution of 'Constant' statements is denied
templates\test.html:7 - execution of 'Constant' statements is denied
templates\test.html:7 - execution of 'Constant' statements is denied
templates\test.html:9 - execution of 'Constant' statements is denied
Solution Found:
How to fix "execution of 'Constant' statements is denied" error?
As pbuck suggested that just add:
from web.template import ALLOWED_AST_NODES
ALLOWED_AST_NODES.append('Constant')
and it works!
Question:
Why it's disallowing my particular statement in test.html (not sure what it means by "'Constant' is a node in python3 AST, but not in python2" in pbuck's answer)?
Is there any problem with my code?
Why/How does the solution work?
It's not a bug in your code, it's a compatibility issue which should be fixed in web.py.
AST is the abstract syntax tree -- an internal structure python creates while parsing your python code (Your template is converted to python code by web.py and then executed).
Part of the syntax tree is indicated what everything is -- statement, expression, arguments, operators, etc. (See https://docs.python.org/3/library/ast.html#ast.parse) ... but you really don't need to know all that.
The result of the parse, web.py goes through to make sure (for security reasons) you're using only "allowed" node types. That is, not all legal python constructs are legal within a web.py template. (Why? no idea -- that's the way web.py was designed.)
web.py started as python2 and ported to python3. The 'Constant' node was introduced in python3 and in 3.8, 'Constant' is now being used by all constants. (Why? beats me -- that's internal python magic.) It would appear web.py should be updated to allow Constant nodes in templates.
Until the web.py release is updated, you can update your code so it works without problem.