annotate roundup/cgi/PageTemplates/PythonExpr.py @ 8562:9c3ec0a5c7fc

chore: remove __future print_funcion from code. Not needed as of Python 3.
author John Rouillard <rouilj@ieee.org>
date Wed, 08 Apr 2026 21:39:40 -0400
parents fed0f839c260
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1 ##############################################################################
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2 #
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
4 #
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
5 # This software is subject to the provisions of the Zope Public License,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
6 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
10 # FOR A PARTICULAR PURPOSE
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
11 #
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
12 ##############################################################################
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
13 # Modified for Roundup:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
14 #
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
15 # 1. more informative traceback info
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
16
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
17 """Generic Python Expression Handler
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
18 """
1071
c08b3820edd1 Adhering to ZPL
Richard Jones <richard@users.sourceforge.net>
parents: 1065
diff changeset
19
5676
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
20 import symtable
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
21
5388
d26921b851c3 Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5384
diff changeset
22 from .TALES import CompilerError
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
23 from sys import exc_info
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
24
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
25 class getSecurityManager:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
26 '''Null security manager'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
27 def validate(self, *args, **kwargs):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
28 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
29 addContext = removeContext = validateValue = validate
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
30
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
31 class PythonExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
32 def __init__(self, name, expr, engine):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
33 self.expr = expr = expr.strip().replace('\n', ' ')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
34 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
35 d = {}
5676
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
36 self.f_code = 'def f():\n return %s\n' % expr.strip()
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
37 exec(self.f_code, d)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
38 self._f = d['f']
8528
fed0f839c260 fix: replace except: with except Exception: (by haosenwang1018@github)
John Rouillard <rouilj@ieee.org>
parents: 5676
diff changeset
39 except Exception:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 4570
diff changeset
40 raise CompilerError(('Python expression error:\n'
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 4570
diff changeset
41 '%s: %s') % exc_info()[:2])
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
42 self._get_used_names()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
44 def _get_used_names(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
45 self._f_varnames = vnames = []
5676
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
46 for vname in self._get_from_symtab():
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
47 if vname[0] not in '$_.':
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
48 vnames.append(vname)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
49
5676
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
50 def _get_from_symtab(self):
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
51 """
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
52 Get the variables used in the 'f' function.
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
53 """
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
54 variables = set()
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
55 table = symtable.symtable(self.f_code, "<string>", "exec")
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
56 if table.has_children():
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
57 variables.update(self._walk_children(table))
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
58 return variables
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
59
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
60 def _walk_children(self, sym):
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
61 """
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
62 Get the variables at this level. Recurse to get them all.
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
63 """
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
64 variables = set()
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
65 for child in sym.get_children():
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
66 variables.update(set(child.get_identifiers()))
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
67 if child.has_children():
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
68 variables.update(self._walk_children(child))
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
69 return variables
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
70
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
71 def _bind_used_names(self, econtext, _marker=[]):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
72 # Bind template variables
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
73 names = {'CONTEXTS': econtext.contexts}
5676
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
74 variables = econtext.vars
1257
93b80ad11ca8 merged Zope Collector #372 fix from ZPT CVS trunk
Richard Jones <richard@users.sourceforge.net>
parents: 1071
diff changeset
75 getType = econtext.getCompiler().getTypes().get
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
76 for vname in self._f_varnames:
5676
e70885fe72a4 issue2551026: template variable not defined even though it is.
John Rouillard <rouilj@ieee.org>
parents: 5389
diff changeset
77 val = variables.get(vname, _marker)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
78 if val is _marker:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
79 has = val = getType(vname)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
80 if has:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81 val = ExprTypeProxy(vname, val, econtext)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
82 names[vname] = val
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
83 else:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
84 names[vname] = val
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85 return names
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
87 def __call__(self, econtext):
1065
0f9aa62917bd much nicer error messages when there's a templating error
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
88 __traceback_info__ = 'python expression "%s"'%self.expr
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
89 f = self._f
5389
f8673e720f30 Python 3 preparation: update function attribute names.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
90 f.__globals__.update(self._bind_used_names(econtext))
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91 return f()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93 def __str__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
94 return 'Python expression "%s"' % self.expr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95 def __repr__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
96 return '<PythonExpr %s>' % self.expr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98 class ExprTypeProxy:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99 '''Class that proxies access to an expression type handler'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
100 def __init__(self, name, handler, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
101 self._name = name
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102 self._handler = handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
103 self._econtext = econtext
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
104 def __call__(self, text):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
105 return self._handler(self._name, text,
1257
93b80ad11ca8 merged Zope Collector #372 fix from ZPT CVS trunk
Richard Jones <richard@users.sourceforge.net>
parents: 1071
diff changeset
106 self._econtext.getCompiler())(self._econtext)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
107

Roundup Issue Tracker: http://roundup-tracker.org/