__FILE__ and __LINE__ in Python

Sunday 3 October 2004

In C++, if you want your code to talk about itself, you often use the predefined magic macros __FILE__ and __LINE__ to get the filename and line number of the current line:

// Use this macro if you can't write the code yet.
#define NOTYET()    NoCodeYet(__FILE__, __LINE__);

void NoCodeYet(const char * pszFile, int nLine)
    fprintf(stderr, "No code yet at %s(%d)\n", pszFile, nLine);


void ComplicatedFunctionFromTheFuture()
    NOTYET()       // I'll get to this later.

This provides a convenient way to leave breadcrumbs that will direct you to the spot in the code later.

How to do it in Python? With help from the Python Cookbook, I created this. It uses scary functions from sys (_getframe has a leading underscore and is described as "for internal and specialized uses only"):

def _functionId(nFramesUp):
    """ Create a string naming the function n frames up on the stack.
    co = sys._getframe(nFramesUp+1).f_code
    return "%s (%s @ %d)" % (co.co_name, co.co_filename, co.co_firstlineno)

def notYetImplemented():
    """ Call this function to indicate that a method isn't implemented yet.
    raise Exception("Not yet implemented: %s" % _functionId(1))


def complicatedFunctionFromTheFuture():

This goes one further than the C++ technique, by providing the function name as well as the file and line.


Remco Boerma 9:44 AM on 3 Oct 2004

I've used the following code. .
Using one less f_back, you see where the routines was called from. . .

Using 2 f_back's, and then using 1:

>>> lineheretest.linehere()
"@[file: ...ework\\interact.py, line 257 in 'runcode']"
>>> lineheretest.linehere()
"@[file: , line 1 in '?']"

note: it might also be usefull to some people to use a similar trick to get the callers caller's variables:

def parentVars():
frame = inspect.currentframe().f_back.f_back
return frame.f_globals, frame.f_locals

import inspect
def linehere():
"""Give linenumer, file, and functionname of the callers,
caller.. Uses the standard module inspect
info = inspect.getframeinfo(inspect.currentframe().f_back.f_back)[0:3]
# Break long filenames
if len(info[0])>20:
return '@[file: %s, line %s in %r]'% tuple(printInfo)

Get the source with correct indention by running:

import base64,zlib;f=file("lineheretest.py",'wb');f.write(zlib.decompress(base64.decodestring("""

(source to create this data can be found on: gwork.blogspot.com

Kent 12:32 PM on 3 Oct 2004

Why not just raise NotImplementedError? The stack trace will show the file, line and function with the error.

Ned Batchelder 12:43 PM on 3 Oct 2004

In this case, I could have simply raised an exception. I used notYetImplemented() as an illustration of getting the file and line of the current line. It can be used in other ways that don't lend themselves to raising exceptions.

David Brownell 6:17 PM on 3 Oct 2004

This may or may not be of any use to you, but many C++ compilers do make the current function name available via __FILE__ and __LINE__-like macros. For example, MSVC defines __FUNCSIG__ that will print out the current function.

Boost provides a handy macro called BOOST_CURRENT_FUNCTION that is mapped to the appropriate macro based on your current compiler. The macro is #defined in boost\current_function.hpp.

I hope this helps someone out there!

Ian Bicking 8:18 PM on 3 Oct 2004

In addition to inspect -- which is very complete -- you can also use the warnings module. There's a "stack" argument, which says how far back in the stack you should go to find the bad code. So in your case, you might go back two steps -- one to get out of your generic warning wrapper, and another to get out of the not-yet-implemented function to the function's caller; this can be even better, because you probably know that the function isn't implemented, but you may be more concerned about the function that called the not-yet-implemented function (or maybe it's a poorly-implemented function, or a deprecated function).

Also, you can use the traceback module to print a traceback, without actually raising an exception.

Jorge Constanzo 12:37 AM on 12 Jan 2005


I saw the code and i thought that it may be very useful to me for finishing a program that i'm making.

But i have a question with the _getframe() function. If i want to get the filename of the current program that it's running, i.e. the path of the self program; which is the argument for _getframe() (in this case nFramesUp+1) that i must input for this purpose?

Beforehand, thank you very much.

Add a comment:

Ignore this:
not displayed and no spam.
Leave this empty:
not searched.
Name and either email or www are required.
Don't put anything here:
Leave this empty:
URLs auto-link and some tags are allowed: <a><b><i><p><br><pre>.