controlling method execution

anton muhin antonmuhin.REMOVE.ME.FOR.REAL.MAIL at rambler.ru
Thu Nov 20 10:31:06 CET 2003


anton muhin wrote:

> mic wrote:
> 
>> Is it possible to control method exectution using similiar mechanism 
>> as with
>> get/setatrribute special methods for attributes? I'd like to have 
>> every (or
>> some of ) method of class instance run common code defined outside the 
>> class
>> without making any explicit references to it.
>> To give an example, I'd like to prepare secure environment, in which 
>> users
>> could execute only methods that can be accessed by them. IMO the most
>> universal way to do it would be to run automatically authorisation 
>> routine
>> before every method execution.
>>
>> Regards,
>>
>> Michal
>>
>>
> Here comes my humble attempt:
> 
> import inspect
> import new
> 
> def before():
>     print "before"
> 
> class WrapperMeta(type):
>     def __new__(cls, name, bases, attrs):
>         wrapped = {}
>         for n, v in attrs.iteritems():
>             if inspect.isfunction(v):
>                 class Controled(object):
>                     def __get__(self, obj, cls):
>                         before()
>                         return new.instancemethod(v, obj, cls)
> 
>                 wrapped[n] = Controled()
>         attrs.update(wrapped)
>         return super(WrapperMeta, cls).__new__(cls, name, bases, attrs)
> 
> class Controled(object):
>     __metaclass__ = WrapperMeta
> 
> class Test(Controled):
>     def method(self, x, y):
>         print 'Test.method(%s, %s)' % (x, y)
> 
> test = Test()
> test.method(10, 11)
> 
> I hope gurus will suggest better approaches. However, I'm afraid that 
> metaclass approach cannot guarantee enough security: one can simple get 
> rid of metaclass to bypass the mechanism.
> 
> regards,
> anton.
> 

A bug: before gets called on simple Test.method. Better solution:

import inspect
import new

def before():
     print 'before'

def after():
     print 'after'

class WrapperMeta(type):
     def __new__(cls, name, bases, attrs):
         wrapped = {}
         for n, v in attrs.iteritems():
             if inspect.isfunction(v):
                 def wrapper(self, *args, **kwargs):
                     before()
                     new.instancemethod(v, self, cls)(*args, **kwargs)
                     after()

                 wrapped[n] = wrapper
         attrs.update(wrapped)
         return super(WrapperMeta, cls).__new__(cls, name, bases, attrs)

class Controled(object):
     __metaclass__ = WrapperMeta

class Test(Controled):
     def method(self, x, y):
         print 'Test.method(%s, %s)' % (x, y)

test = Test()
test.method(10, 11)
test.method

sorry,
anton.





More information about the Python-list mailing list