[Python-Dev] Capabilities / Restricted Execution

Talin talin at acm.org
Tue Jul 11 12:36:09 CEST 2006


I thought a little bit more about Guido's comment that you can hide 
Python objects in a C wrapper class. However, as I was trying to sleep, 
I realized that you don't even need C to do it.

The trick is to store the object reference as a closure variable. 
Assuming that there's no mechanism to directly access such variables, 
you can effectively have 'private' variables.

Here's an pure-Python implementation of a wrapper that restricts access 
to all class members except those marked with the 'public' decorator. 
Note in the test cases below that even '__class__' and '__dict__' are 
inaccessible.
------------------------------------------------------------------

# Exception to throw when we violate restrictions
class GuardException( Exception ): pass

# Decorator function
def public(func):
     func.f_public = True
     return func

# Wrapper function
def guard(content):
     class Guard(object):
         def __getattribute__(self, name):
             # This will throw an AttributeException if the
             # attribute doesn't exist, which is what
             # we want.
             attr = object.__getattribute__(content,name)
             if hasattr( attr, 'im_func' ):
                 if hasattr( attr.im_func, 'f_public' ):
                     # We can't return the bound method directly,
                     # instead we create a proxy for it.
                     def proxy_attr( *args, **kwargs ):
                         return attr( *args, **kwargs )
                     return proxy_attr

             # Attribute exists but has no proxy
             raise GuardException( name )

     return Guard()

# Test class
class Test(object):
     def __init__(self,name):
         self.name = name

     @public
     def get_name(self):
         return self.name

     def set_name(self,name):
         self,name = name

# Test objects. First is unwrapped, second is wrapped.
t1 = Test("alpha")
t2 = guard(Test("beta"))

# These functions work correctly
print t1.name
print t2.get_name()

# This gets AttributeError because there's no such attribute
print t2.unk()

# These generate GuardException
print t2.set_name()
print t2.__dict__
print t2.__class__
print t2.name

------------------------------------------------------

-- Talin


More information about the Python-Dev mailing list