[Zope-Checkins] CVS: Zope/lib/python/RestrictedPython - RestrictionMutator.py:1.8.8.2
Shane Hathaway
shane@digicool.com
Fri, 21 Dec 2001 11:22:16 -0500
Update of /cvs-repository/Zope/lib/python/RestrictedPython
In directory cvs.zope.org:/tmp/cvs-serv28729
Modified Files:
Tag: RestrictedPython-2_2-branch
RestrictionMutator.py
Log Message:
We've been using a strategy of turning expressions into code suites in
order to bind the global names '_getitem_' and '_getattr_' locally, but
this seems brittle somehow. This new strategy avoids the need to bind
the names locally when in an expression. Note that the change only
takes effect for the Python 2.2 compiler since RCompile_2_1.py turns
expressions into functions calls. If you're really following this,
I hope I didn't give you a headache. ;-)
=== Zope/lib/python/RestrictedPython/RestrictionMutator.py 1.8.8.1 => 1.8.8.2 ===
_print_target_name = ast.Name('_print')
_getattr_name = ast.Name('_getattr')
+_getattr_name_expr = ast.Name('_getattr_')
_getitem_name = ast.Name('_getitem')
+_getitem_name_expr = ast.Name('_getitem_')
_write_guard_name = ast.Name('_write')
# Constants.
@@ -76,9 +78,11 @@
_getattr_used = 0
_getitem_used = 0
_write_used = 0
+ _is_suite = 0 # True for modules and functions, false for expressions
class RestrictionMutator:
+
def __init__(self):
self.funcinfo = FuncInfo()
self.warnings = []
@@ -111,6 +115,8 @@
'because it starts with "_".' % name)
def prepBody(self, body):
+ """Appends prep code to the beginning of a code suite.
+ """
info = self.funcinfo
if info._print_used or info._printed_used:
# Add code at top for creating _print_target
@@ -136,6 +142,7 @@
former_funcinfo = self.funcinfo
self.funcinfo = FuncInfo()
+ self.funcinfo._is_suite = 1
node = walker.defaultVisitNode(node, exclude=('defaults',))
self.prepBody(node.code.nodes)
self.funcinfo = former_funcinfo
@@ -187,8 +194,11 @@
#expr.append(_write_guard_name)
#self.funcinfo._write_used = 1
self.funcinfo._getattr_used = 1
- return ast.CallFunc(_getattr_name,
- [node.expr, ast.Const(node.attrname)])
+ if self.funcinfo._is_suite:
+ ga = _getattr_name
+ else:
+ ga = _getattr_name_expr
+ return ast.CallFunc(ga, [node.expr, ast.Const(node.attrname)])
def visitSubscript(self, node, walker):
node = walker.defaultVisitNode(node)
@@ -221,7 +231,11 @@
if upper is None:
upper = _None_const
subs = ast.Sliceobj([lower, upper])
- return ast.CallFunc(_getitem_name, [node.expr, subs])
+ if self.funcinfo._is_suite:
+ gi = _getitem_name
+ else:
+ gi = _getitem_name_expr
+ return ast.CallFunc(gi, [node.expr, subs])
elif node.flags in (OP_DELETE, OP_ASSIGN):
# set or remove subscript or slice
node.expr = ast.CallFunc(_write_guard_name, [node.expr])
@@ -249,6 +263,7 @@
return walker.defaultVisitNode(node)
def visitModule(self, node, walker):
+ self.funcinfo._is_suite = 1
node = walker.defaultVisitNode(node)
self.prepBody(node.node.nodes)
return node