entries friends calendar user info Elf Sternberg's Pendorwright Projects Previous Previous Next Next
profile
Elf M. Sternberg
User: [info]elfs
Name: Elf M. Sternberg
calendar
Back July 2009
1234
567891011
12131415161718
19202122232425
262728293031
links
page summary
tags
Elf M. Sternberg - C __LINE__ equivalent in Python
elfs
[info]elfs
Add to Memories
Tell a Friend
C __LINE__ equivalent in Python

I started using this recently. If you do a lot of Python, you’ll sometimes find yourself desperate for breadcrumbs, little print statements scattered throughout your code as you try to figure what you told it to do, since it’s obviously not doing what you want it to do. I’d used inspect previously to unravel exception handlers; there’s a customized one inside the Isilon UI, so if the product fails in the field the exception will be logged to a file for later analysis, but this is a nice little routine. It’s basically a pythonic version of the C __LINE__ macro. Wherever you think you might need a debugging statement, put if DEBUG: print _line(), foo, bar, baz and you’ll not only get the fields you want to see, but also the name of the function/method, and the line number of the print statement.

import inspect
def _line():
    info = inspect.getframeinfo(inspect.currentframe().f_back)[0:3]
    return '[%s:%d]' % (info[2], info[1])

Use as needed.

This entry was automatically cross-posted from Elf's technical journal, ElfSternberg.com

Tags: ,

Comments
funos From: [info]funos Date: September 23rd, 2008 09:42 pm (UTC) (Link)
That will come in handy someday. Thanks!
From: [info]tamino Date: September 24th, 2008 12:39 am (UTC) (Link)
Even simpler:

def _line():
f = sys._getframe().f_back
return '[%s:%d]' % (f.f_code.co_filename, f.f_lineno)
elfs From: [info]elfs Date: September 24th, 2008 05:17 am (UTC) (Link)
I thought f_lineno gave you the first line of the current method, not the current line.
From: [info]tamino Date: September 24th, 2008 05:26 am (UTC) (Link)
Nope -- if you look at what inspect.getframeinfo is doing, it's getting it from f_lineno (as well as doing a bunch of other work to assemble information that you're discarding, and the gathering of which will slow things down)

You may be thinking of the f_lineno member of the python frame struct in C. You're right that that doesn't get updated on every line, but if you access it from within python, yes, it'll make sure it's up to date before it returns the value to you.

Incidentally, in gdb, where you *do* have to worry about these issues, I use:

p (char *)(((PyStringObject *)f->f_code->co_filename)->ob_sval)
p PyCode_Addr2Line(f->f_code, f->f_lasti)

the latter of which does the actual magic to get the correct line number (f->f_lineno will likely be out of date).
4 comments or Leave a comment