On Thu, 31 Mar 2005 16:28:15 +1200, Greg Ewing
<gr**@cosc.canterbury.ac.nz> wrote:
Oren Tirosh wrote: def noglobals(f):
. import new
. return new.function(
. f.func_code,
. {'__builtins__':__builtins__},
. f.func_name,
. f.func_defaults,
. f.func_closure
. )
Be aware that this will render the function incapable
of seeing *any* globals at all, including other
functions and classes defined in the same module --
which you may find rather inconvenient!
Developing this idea further...
This allows a programmer to specify what globals to allow read and or
writes.
Cheers,
Ron
#---start---
# useglobals.py
"""
A function to specify what globals and builtins
a function may access.
Author: Ronald Adam
"""
def useglobals(rw_globals=None, r_globals=None, builtins=True):
#import dis
import sys
write_list = []
read_list = []
if rw_globals != None:
rw_globals = rw_globals.replace(' ','')
write_list = rw_globals.split(',')
if r_globals != None:
r_globals = r_globals.replace(' ','')
read_list = r_globals.split(',')
if builtins == True:
read_list.extend(dir(__builtins__))
elif builtins != None:
builtins = builtins.replace(' ','')
read_list.extend(builtins.split(','))
# Add own name to read list.
read_list.append(sys._getframe(0).f_code.co_name)
read_list.extend(write_list)
#print read_list, write_list
names = sys._getframe(1).f_code.co_names
code = sys._getframe(1).f_code.co_code
#print dis.disassemble(sys._getframe(1).f_code)
i = 0
while i < len(code):
#print ord(code[i])
op = ord(code[i])
if op == 116: # dis.opmap['LOAD_GLOBAL']
oparg = ord(code[i+1]) + ord(code[i+2]) * 256
if str(names[oparg]) not in read_list:
raise NameError, "read from global name %s, detected"
% names[oparg]
elif op == 97: # dis.opmap['STORE_GLOBAL']
oparg = ord(code[i+1]) + ord(code[i+2]) * 256
if names[oparg] not in write_list:
raise NameError, "write to global name %s, detected" %
names[oparg]
if op >= 90: # dis.HAVE_ARGUMENT
i += 3 # Not sure if this is always the same?
else:
i += 1
if __name__ == '__main__':
"""
Test useglobals() function. Change values to test
for error catching.
"""
def a():
useglobals(rw_globals='x', r_globals='y,b')
# This function can read or write 'x',
# Can read 'y', and function 'b',
# and can access all builtins.
global x
y = 5
x += y
x = b(x)
return x
def b(g):
useglobals('','y,c','int')
# This function can only read 'y' and
# function 'c' in globals, and can
# only access 'int' in builtins.
g = g+y
c(int(g))
return g
def c(w):
useglobals(builtins=None)
# This function has no builtins or globals.
w = w**2
return w
y = 4
x = 5
z = 6
print a(),x,y,z
#---end---