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