Python
Programming
Debugging
Scripting
Code Analysis

filename and line number of Python script

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Python, "filename and line number" can mean two different things: the location of the current source file, or the location of the current call site while code is running. The best tool depends on which one you want, because __file__, inspect, and traceback solve different problems.

If You Only Need The Script Filename

For the current module or script path, use __file__:

python
1from pathlib import Path
2
3print(__file__)
4print(Path(__file__).name)
5print(Path(__file__).resolve())

This gives you the file containing the running code, not the line where a function was called.

Use this when you need:

  • the script location
  • a path relative to the module
  • debug output identifying the current file

If You Need The Current Line Number

For runtime introspection, use inspect.currentframe():

python
1import inspect
2
3def show_location():
4    frame = inspect.currentframe()
5    print(frame.f_code.co_filename)
6    print(frame.f_lineno)
7
8show_location()

This prints the filename and line number inside show_location(). It is useful in small debug helpers, though the logging module is often better for production code.

Getting The Caller's Location

Sometimes you do not want the helper function's location. You want the code that called it. In that case, look one frame back.

python
1import inspect
2
3def caller_location():
4    frame = inspect.currentframe()
5    caller = frame.f_back
6    return caller.f_code.co_filename, caller.f_lineno
7
8def run():
9    filename, line = caller_location()
10    print(filename, line)
11
12run()

This pattern is common in custom logging utilities and debug wrappers.

Exception Locations Use Tracebacks

If you are handling an error, use the traceback from the exception rather than currentframe(). That tells you where the failure happened.

python
1try:
2    1 / 0
3except ZeroDivisionError as exc:
4    tb = exc.__traceback__
5    while tb.tb_next is not None:
6        tb = tb.tb_next
7
8    print(tb.tb_frame.f_code.co_filename)
9    print(tb.tb_lineno)

For user-facing diagnostics, traceback.format_exc() is often simpler:

python
1import traceback
2
3try:
4    int("bad")
5except ValueError:
6    print(traceback.format_exc())

That gives a full stack trace instead of just one line number.

Use Logging When Possible

If your real goal is diagnostic output, Python's logging module already knows how to include source information.

python
1import logging
2
3logging.basicConfig(
4    level=logging.INFO,
5    format="%(filename)s:%(lineno)d %(levelname)s %(message)s"
6)
7
8logging.info("Application started")

This is usually better than manually calling inspect all over the codebase. It is clearer, faster to read, and easier to standardize.

There is also sys._getframe() for low-level frame access, but it is less friendly than inspect and rarely needed outside specialized tooling.

Which Tool To Use

Choose based on intent:

  • use __file__ for the current module path
  • use inspect.currentframe() for runtime location introspection
  • use f_back when you want the caller
  • use exception tracebacks when handling failures
  • use logging for routine diagnostics

Those are related tasks, but not identical ones.

Common Pitfalls

  • Using __file__ when you actually need the current execution line number.
  • Using inspect.currentframe() in production logging instead of the built-in logging metadata.
  • Forgetting that helper functions report their own line unless you explicitly inspect the caller frame.
  • Keeping frame references around too long, which can make debugging harder and sometimes delay garbage collection.
  • Extracting only one line number from an exception when the full traceback would be more useful.

Summary

  • '__file__ gives the file path of the current module.'
  • 'inspect.currentframe() gives access to runtime frame information such as filename and line number.'
  • Use f_back to inspect the caller rather than the helper itself.
  • For exceptions, use the traceback attached to the error.
  • For normal diagnostics, the logging module is usually the cleanest solution.

Course illustration
Course illustration

All Rights Reserved.