Method logging in Python - python

I'd like something equivalent to
calling method: $METHOD_NAME
args: $ARGS
output: $OUTPUT
to be automatically logged to a file (via the logging module, possibly) for every (user-defined) method call. The best solution I can come up with is to write a decorator that will do this, and then add it to every function. Is there a better way?
Thanks

You could look at the trace module in the standard library, which
allows you to trace program execution, generate annotated statement coverage listings, print caller/callee relationships and list functions executed during a program run. It can be used in another program or from the command line.
You can also log to disk:
import sys
import trace
# create a Trace object, telling it what to ignore, and whether to
# do tracing or line-counting or both.
tracer = trace.Trace(
ignoredirs=[sys.prefix, sys.exec_prefix],
trace=0,
count=1)
# run the new command using the given tracer
tracer.run('main()')
# make a report, placing output in /tmp
r = tracer.results()
r.write_results(show_missing=True, coverdir="/tmp")

One approach that might simplify things a bit would be to use a metaclass to automatically apply your decorator for you. It'd cut down on the typing at the expense of requiring you to delve into the arcane and mysterious world of metaclass programming.

It depends how exactly are you going to use it.
Most generic approach would be to follow stdlib's 'profile' module path and therefore have control over each call, but its somewhat slow.
If you know which modules you need to track before giving them control, I'd go with iterating over all their members and wrapping with tracking decorator. This way tracked code stays clean and it doesn't take too much coding to implement.

A decorator would be a simple approach for a smaller project, however with decorators you have to be careful about passing arguments to make sure that they don't get mangled on their way through. A metaclass would probably be more of the "right" way to do it without having to worry about adding decorators to every new method.

Related

How can I inject code in the beginning of a function?

I would like to be able to inject a piece of code in the beginning of a given function.
Research mostly mentions using decorators, but for my specific use case I wouldn't want to wrap the modified function with an additional function call.
I am also unable to add a parameter to the function - I have an already compiled function at runtime and that's it.
The reason I wouldn't want to use a wrapper, is because I'd like to write a utility library which allows the programmer to "paste" a piece of code at the beginning of an already written function, without adding another level to the call stack at all. Mainly for performance reasons.
How can this be done? And would it work across Python versions without breaking?
Premature optimization is the root of all evil. You should not "simply assume" a wrapper function will have a major performance impact. There is no safe, simple, portable, way to do what you're asking. The most applicable solution is a custom metaclass as it allows you to control the creation of new objects based on it.

Programmatically modifying someones AppDelegate - categories, subclass?

I am working on a framework installer script. The script needs to modify the users AppDelegate file and inject a few lines of code at the beginning or end of the applicationDidFinishLaunching and applicationWillTerminatate methods.
Some options I've thought about:
Parse the source code, and insert lines at correct positions. (Can be difficult to get right and work for everyone's code, just about equivalent to writing a compiler...)
Subclass the AppDelegate file (is this possible?)
Categories??
Which of these is the best option? Any other suggestions?
If you really need to make this something that modifies the AppDelegate with no intervention at all from the developer, and you can modify the xcodeproj and the nib but not the source, there is a way to do it.
First, make sure your classes get compiled in, and an instance of your class gets created in the nib.
Now, here's what you do:
Define a -[AHHackClass applicationDidFinishLaunching] method that does your extra stuff, then calls the [self originalApplicationDidFinishLaunching].
In -[AHHackClass awakeFromNib:], use objc runtime calls to copy the -[AHHackClass applicationDidFinishLaunching] method to the application delegate as -[originalApplicationDidFinishLaunching], then use method swizzling to swap the two methods' implementations.
Do the same to swizzle applicationWillTerminate.
See JRSwizzle for some code that makes the method swizzling much easier, and MethodSwizzling at CocoaDev for some background.
However, there may be a much easier way to do this: Does your extra stuff really need to be called from the app delegate's applicationDidFinishLaunching and applicationWillTerminate methods? Can't you just set up to listen for notifications in your awakeFromNib and handle things there?
And if, for some reason, you can't do that, can you just put a line in the instructions to the developer to call your method from their applicationDidFinishLaunching method?
One solution I am currently considering:
Add NewAppDelegate.m/h file that subclasses AppDelegate.
This subclass, does what I want, and then calls the super methods.
Find/replace AppDelegate with NewAppDelegate.m.h in main.m
This seems pretty simple and robust. Thoughts on this? Will this work for all/most projects?

What is the most Pythonic way to pass objects between imported libraries of code?

I have a program which imports two modules, one we will call operations (which is just a series of functions) and the other we call tracking (which is a class). The program tracking module monitors a series of messages, has some error state flags, and so forth. The program sorts information in tracking by severity and relevant parties, then dumps this to different files at the end.
I create a single instance of the tracking class with myTrack = tracking.Tracking(). (Yes, this is global state and therefore bad, but it is pretty handy)
Unforunately, I would like to use my tracking object within the operations module, just to track errors and warnings. It looks like I can pass myTrack to functions in the operations module as an argument, modifying each and every one of the functions.
However, is there a "better" or "more Pythonic" way to do this? I suspect there is something with namespaces which I have failed to grasp.
There are a lot of ways you could refactor this, but one place you might start is to add a track() function to your operations module. Have it do nothing by default.
def track(message): # use the right signature though!
pass
In your operations module you would then call your track() function anywhere you might want to track something.
Assuming your Tracking object has a method called track() that does the actual tracking, then in your main module, you can do this:
myTrack = tracking.Tracking()
operations.track = myTrack.track
This replaces the module's (do-nothing) track function with the method from your Tracking instance.
Basically, you have provided a "hook" which anyone can use to add tracking to your operations module, and then used that hook yourself.
Yes, this is more "global state," but it's module-global, which is not really global.
Your tracking module (recording details about a series of events for later analysis or display) sounds suspiciously like the standard library's logging module. So you may want to investigate that a little more closely.
If you decide to head down that path, then the operations module would just log events to a specific logger (e.g. "myapp.operations"), your tracking module would provide a logging handler that did what you wanted, and your main module would hook the two together (by registering the tracking handler with the "myapp.operations" logger).
You can also set up something like that yourself, but really, if you want to track events in a Python program... just use logging.
I am not sure I understand your problem correctly, but I think you are looking for a way to make the functions in one module automatically aware of the state an object in another module without explicitly passing that object every time you call a function.
The basic problem is that at some level you have to pass the object and have it available to all the functions you need. Modules are simply not meant to work like that.
I think a better idea will be to define an Operations class that contains all the functions you need as methods as well as holding an instance of Tracking. You can just pass in your Tracking object and create an Operations instance, and use that to call whatever function that you need.
myTrack = tracking.Tracking()
myOperation=operations.Operations(myTrack)
myOperation.doSomething()

Should I forward arguments as *args & **kwargs?

I have a class that handles command line arguments in my program using python's optparse module. It is also inherited by several classes to create subsets of parameters. To encapsulate the option parsing mechanism I want to reveal only a function add_option to inheriting classes. What this function does is then call optparse.make_option.
Is it a good practice to simply have my add_option method say that it accepts the same arguments as optparse.make_option in the documentation, and forward the arguments as *args and **kwargs?
Should I do some parameter checking beforehand? In a way I want to avoid this to decouple that piece of code as much from a specific version of optparse.
It seems that you want your subclasses to have awareness of the command line stuff, which is often not a good idea.
You want to encapsulate the whole config input portion of your program so that you can drive it with a command line, config file, other python program, whatever.
So, I would remove any call to add_option from your subclasses.
If you want to discover what your config requirements look like at runtime, I would simply add that data to your subclasses; let each one have a member or method that can be used to figure out what kind of inputs it needs.
Then, you can have an input organizer class walk over them, pull this data out, and use it to drive a command line, config file, or what have you.
But honestly, I've never needed to do this at run time. I usually pull all that config stuff out to it's own separate thing which answers the question "What does the user need to tell the tool?", and then the subclasses go looking in the config data structure for what they need.
Are you sure that subclassing is what you want to do? Your overriding behavior could just be implemented in a function.

What's the best way to record the type of every variable assignment in a Python program?

Python is so dynamic that it's not always clear what's going on in a large program, and looking at a tiny bit of source code does not always help. To make matters worse, editors tend to have poor support for navigating to the definitions of tokens or import statements in a Python file.
One way to compensate might be to write a special profiler that, instead of timing the program, would record the runtime types and paths of objects of the program and expose this data to the editor.
This might be implemented with sys.settrace() which sets a callback for each line of code and is how pdb is implemented, or by using the ast module and an import hook to instrument the code, or is there a better strategy? How would you write something like this without making it impossibly slow, and without runnning afoul of extreme dynamism e.g side affects on property access?
I don't think you can help making it slow, but it should be possible to detect the address of each variable when you encounter a STORE_FAST STORE_NAME STORE_* opcode.
Whether or not this has been done before, I do not know.
If you need debugging, look at PDB, this will allow you to step through your code and access any variables.
import pdb
def test():
print 1
pdb.set_trace() # you will enter an interpreter here
print 2
What if you monkey-patched object's class or another prototypical object?
This might not be the easiest if you're not using new-style classes.
You might want to check out PyChecker's code - it does (i think) what you are looking to do.
Pythoscope does something very similar to what you describe and it uses a combination of static information in a form of AST and dynamic information through sys.settrace.
BTW, if you have problems refactoring your project, give Pythoscope a try.

Categories