473,666 Members | 2,480 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Injecting code into a function

Is there a general way of injecting code into a function, typically
before and/or after the existing code ? I know that for most purposes,
an OO solution, such as the template pattern, is a cleaner way to get
the same effect, but it's not always applicable (e.g. if you have no
control over the design and you are given a function to start with). In
particular, I want to get access to the function's locals() just before
it exits, i.e. something like:

def analyzeLocals(f unc):
func_locals = {}
def probeFunc():
# insert func's code here
sys._getframe(1 ).f_locals["func_local s"].update(locals( ))
probeFunc()
# func_locals now contains func's locals

So, how can I add func's code in probeFunc so that the injected code
(the update line here) is always called before the function exits ?
That is, don't just inject it lexically in the end of the function if
there are more than one exit points. I guess a solution will involve a
good deal bytecode hacking, on which i know very little; if there's a
link to a (relatively) simple HOWTO, it would be very useful.

Thanks,
George

Jul 19 '05 #1
17 6511
use eval.
eval will accept any string and treat the string as a code.

pujo

Jul 19 '05 #2
Perhalps metaclasses are of interest to you. You can decorate existing
methods with additional behavior using metaclasses. A simple example
can be found at http://soiland.no/software/logmeta
I've gathered some more links under
http://www.gungfu.de/facts/wiki/fiel...etaProgramming
regards
Steffen

Jul 19 '05 #3
Ron
George Sakkis wrote:
Is there a general way of injecting code into a function, typically
before and/or after the existing code ? I know that for most purposes,
an OO solution, such as the template pattern, is a cleaner way to get
the same effect, but it's not always applicable (e.g. if you have no
control over the design and you are given a function to start with). In
particular, I want to get access to the function's locals() just before
it exits, i.e. something like:

def analyzeLocals(f unc):
func_locals = {}
def probeFunc():
# insert func's code here
sys._getframe(1 ).f_locals["func_local s"].update(locals( ))
probeFunc()
# func_locals now contains func's locals

So, how can I add func's code in probeFunc so that the injected code
(the update line here) is always called before the function exits ?
That is, don't just inject it lexically in the end of the function if
there are more than one exit points. I guess a solution will involve a
good deal bytecode hacking, on which i know very little; if there's a
link to a (relatively) simple HOWTO, it would be very useful.

Thanks,
George


I'd like to know this as well. :)

I think you will have to modify the function func in some way to get
locals when it exits.

def func():
x = 20
y = 40
func.locals = locals() # inserted line

func()
print func.locals
On a related note, I'd like to know how to import locals into a function.

Cheers,
Ron



Jul 19 '05 #4
Try searching for: 'python aspect-oriented' as aspect oriented
programming is about modifying existing class-methods (not exactly
functions which is what you asked for).
You might also do a search for "AOP considered harmful"
http://www.infosun.fmi.uni-passau.de...op_harmful.pdf

The main point is that when you are reading the source you don't know
what the code is as it may be augmented by an "external" change.

Jul 19 '05 #5
George Sakkis wrote:
Is there a general way of injecting code into a function, typically
before and/or after the existing code ? I know that for most purposes,
an OO solution, such as the template pattern, is a cleaner way to get
the same effect, but it's not always applicable (e.g. if you have no
control over the design and you are given a function to start with). In
particular, I want to get access to the function's locals() just before
it exits, i.e. something like:

def analyzeLocals(f unc):
func_locals = {}
def probeFunc():
# insert func's code here
sys._getframe(1 ).f_locals["func_local s"].update(locals( ))
probeFunc()
# func_locals now contains func's locals

So, how can I add func's code in probeFunc so that the injected code
(the update line here) is always called before the function exits ?
That is, don't just inject it lexically in the end of the function if
there are more than one exit points. I guess a solution will involve a
good deal bytecode hacking, on which i know very little; if there's a
link to a (relatively) simple HOWTO, it would be very useful.

Thanks,
George

A decorator would seem to be the sensible way to do this, assuming you
are using Python 2.4.

def decorated(func) :
def wrapper(arg1, arg2, arg3):
print "Arg2:", arg2
func(arg1)
print "Arg3:", arg3
return wrapper

@decorated
def f1(x):
print "F1:", x

f1('ARG1', 'ARG2', 'ARG3')

Arg2: ARG2
F1: ARG1
Arg3: ARG3

All the decorator really does is compute one function from another.
There's been enough discussion on the list recently that I won't repeat
the theory.

regards
Steve
--
Steve Holden +1 703 861 4237 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/
Python Web Programming http://pydish.holdenweb.com/

Jul 19 '05 #6
I expect you could combine the following with decorators as an easy way
to grab a function's locals just before it exits... you could also use
exec or eval to execute code in the function's local namespace.
---------------------------------------

# Try it:

def trace_returns(f rame, event, arg):
if event == 'return':
print "[frame locals just before return: %s]" % frame.f_locals
return trace_returns

def foo(a, b):
return a + b

import sys
sys.settrace(tr ace_returns)

foo(1,2)

Jul 19 '05 #7
"Lonnie Princehouse" wrote:
I expect you could combine the following with decorators as an easy way to grab a function's locals just before it exits... you could also use exec or eval to execute code in the function's local namespace.
---------------------------------------

# Try it:

def trace_returns(f rame, event, arg):
if event == 'return':
print "[frame locals just before return: %s]" % frame.f_locals
return trace_returns

def foo(a, b):
return a + b

import sys
sys.settrace(tr ace_returns)

foo(1,2)


Thanks, that's the closest to what I wanted. A minor point I didn't
quite get from the documentation is how to set a local trace instead of
a global (sys) trace. Also, there's no sys.gettrace() to return the
current tracer; is there a way around this ?

George

Jul 19 '05 #8
George Sakkis wrote:
Thanks, that's the closest to what I wanted. A minor point I didn't
quite get from the documentation is how to set a local trace instead of a global (sys) trace.
You never do. "Local" in this context only means that those local trace
functions are called inside the one global trace-function and return
the global trace function again.

In Lonnies example there are no local-trace functions at all.
Also, there's no sys.gettrace() to return the
current tracer; is there a way around this ?


The default tracer is None i.e. no debugging. The programmer has to
control his tracer which might not be to hard:
class Analyzer:
def trace_returns(s elf, frame, event, arg):
if event == 'return':
self.func_local s = frame.f_locals
return self.trace_retu rns

def analyzeLocals(s elf, func,*args,**kw ):
sys.settrace(se lf.trace_return s)
func(*args,**kw )
sys.settrace(No ne)

Ciao,
Kay

Jul 19 '05 #9
I don't know of a way to get the current global trace function. This
could certainly cause trouble if you're trying to be compatible with
other packages that want to use their own trace functions (like psyco,
or debuggers). Does anyone know how to get the global trace?

On the other hand, the local trace function is in the f_trace attribute
of a frame.

It looks like global trace functions only get the "call" event, and are
expected to return a local trace function that will receive "line" and
"return" events, so you will need a global trace in order to set local
traces (setting myframe.f_trace explicitly doesn't seem to do it).

Jul 19 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
2879
by: Nadav | last post by:
Hi, Introduction: ************************************************************ I am working on a project that should encrypt PE files ( Portable executable ), this require me to inject some code to existing PEs. First, I have tried: 1. to inject some code to the end of the ‘.text’ segment of an existing PE 2. to set the entry point RVA to the address of the injected code 3. at the end of the injected code I have set a jmp to the...
10
6843
by: Brian W | last post by:
Hi All, I have a web user control that, among other things, provides Print this page, and Email this page functionality I have this script that is to execute on the click of the asp:hyperlinks I have a function in a <SCRIPT> block that I want in the <head></head> section of the page. Unfortunately, RegisterClientScriptBlock, RegisterStartupScript don't always work, and when they do the script is placed inside the <form> tag (this...
9
3514
by: tai | last post by:
Hi. I'm looking for a way to define a function that's only effective inside specified function. Featurewise, here's what I want to do: bar_plugin_func = function() { ...; setTimeout(...); ... }; wrap_func(bar_plugin_func); bar_plugin_func(); // calls custom "setTimeout"
14
1774
by: ofiras | last post by:
Hii everyone, I'm a web programmer, but I never understood sql injecting. All I found was that you can write "a' or 'a'='a" in the password field to try to connect without knowing the password. I heard that there are many other ways to do sql injecting, and I never found how. I know that you can even manage to get data from sql tables using sql injecting. How can it be? How can someone do it? Please help,
4
1141
by: Peter Waller | last post by:
Dear Pythoners, I know this will probably be perceived as 'evil voodoo', and fair enough: it probably is. I guess it is unpythonic. ... but I want to know how to do it anyway - mostly for my own interest. Consider the following snippet of code:
1
1870
by: rh.krish | last post by:
Hi, I have a unique situation. We have many applications (approx - 20) built on .NET framework 1.1 & 2.0 and hosted in one single IIS website in PROD. We have similar setup in TEST. Now we want to have a banner indicating that the website being accessed by the user is TEST. This is because, there are some users who have access to both and sometimes they do stuffs in PROD which are meant to be done only in TEST. By displaying somekind of...
0
8362
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8878
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8560
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8644
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7389
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6200
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4200
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4372
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2012
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.