Wrap and intercept function calls

Terry Reedy tjreedy at udel.edu
Wed Feb 17 15:57:57 EST 2010


On 2/17/2010 11:04 AM, Dan Yamins wrote:
> Really, nobody has any idea about this?   (Sorry to repost.)

> On Tue, Feb 16, 2010 at 7:29 PM, Dan Yamins <dyamins at gmail.com
> <mailto:dyamins at gmail.com>> wrote:
>
>     Hi:
>
>     I'm wondering what the best way to wrap and modify function calls
>     is.    Essentially what I want to achieve is to have a function like
>     this:
>
>     def Wrap(frame,event,arg):
>           if event == 'call':
>              result = PerformCheck(GetArgumentsFromFrame(frame))
>              if Condition(result):
>                  return result
>              else:
>                  return [normal function call]
>
>     called whenever a "call" event is about to occur.

For yourself as interpreter, execute the above for every call.

For CPython, alternative 1 is to create a custom interpreter to change 
(wrap) the interpretation of the call-function bytecode in the ceval 
loop. That is its 'call event', and I believe this would catch every 
explicit f(args) call and only such calls.

Python has no general metasyntax for changing the semantics of its 
syntax. The __xx__ methods are special cases for the corresponding 
operators *and* the corresponding user-defined class. The '__call__' 
method of a class applies to instances of that class. Alternative 2:

class func_wrap:
   def __init__(self, func):
     self._func = func
   def __call__(self, args, kwds):
     result = PerformCheck(args, kwds)
     if Condition(result):
       return result
     else:
       return self._func(*args,**kwds)

Now wrap *every* function you are interested in. Builtin functions are 
no problem; methods of builtin classes cannont be wrapped without 
subclassing.

Terry Jan Reedy

>     When I say "return result" I mean:  return that data object instead
>     of what the function would have returned, and prevent execution of
>     the function.
>
>     Is there any way to do this using sys.settrace?  Or perhaps
>     something from the bdb or pbd module?
>
>
> In other words, what I'm looking for is a way to intercept all function
> calls with a "wrapper" --  like one can do using settrace and other
> debugging methods -- but, unlike the debugging methods, have the
> "wrapping" function actually be able to intervene in the stack and, for
> instance, conditionally replace the function call's return with
> something determined in the wrapping function and prevent the function
> call's execution.   I want to be able to do this by setting a single
> system-wide (or at any rate, thread-wide) value, like with settrace, and
> not have to modify individual functions one by one.
>
> Could I, for example, set a settrace function that somehow modifies the
> stack?  Or is there some much better way to do this?  Or, if someone can
> tell me that this can't be done without having to roll my own
> implementation of the Python interpreter, that would be great to know too.
>
> Thanks again,
> Dan
>





More information about the Python-list mailing list