/usr/share/pyshared/RestrictedPython/MutatingWalker.py is in python-restrictedpython 3.6.0-0ubuntu4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
__version__='$Revision: 1.6 $'[11:-2]
from SelectCompiler import ast
ListType = type([])
TupleType = type(())
SequenceTypes = (ListType, TupleType)
class MutatingWalker:
def __init__(self, visitor):
self.visitor = visitor
self._cache = {}
def defaultVisitNode(self, node, walker=None, exclude=None):
for name, child in node.__dict__.items():
if exclude is not None and name in exclude:
continue
v = self.dispatchObject(child)
if v is not child:
# Replace the node.
node.__dict__[name] = v
return node
def visitSequence(self, seq):
res = seq
for idx in range(len(seq)):
child = seq[idx]
v = self.dispatchObject(child)
if v is not child:
# Change the sequence.
if type(res) is ListType:
res[idx : idx + 1] = [v]
else:
res = res[:idx] + (v,) + res[idx + 1:]
return res
def dispatchObject(self, ob):
'''
Expected to return either ob or something that will take
its place.
'''
if isinstance(ob, ast.Node):
return self.dispatchNode(ob)
elif type(ob) in SequenceTypes:
return self.visitSequence(ob)
else:
return ob
def dispatchNode(self, node):
klass = node.__class__
meth = self._cache.get(klass, None)
if meth is None:
className = klass.__name__
meth = getattr(self.visitor, 'visit' + className,
self.defaultVisitNode)
self._cache[klass] = meth
return meth(node, self)
def walk(tree, visitor):
return MutatingWalker(visitor).dispatchNode(tree)
|