inspect

Updated March 13, 2026 · Modules
stdlib introspection reflection debugging

The inspect module provides functions for getting information about live objects in Python. You can examine modules, classes, functions, tracebacks, frames, and code objects at runtime. It’s essential for debugging, building IDEs, and implementing tools that need to understand code structure.

Inspecting Functions and Callables

inspect.signature()

Returns the signature of a callable, showing all parameters with their defaults.

inspect.signature(callable, *, follow_wrapped=True)
ParameterTypeDefaultDescription
callablecallableThe function or method to inspect
follow_wrappedboolTrueFollow the __wrapped__ attribute to original function
import inspect

def greet(name, greeting="Hello", punctuation="!"):
    return f"{greeting}, {name}{punctuation}"

sig = inspect.signature(greet)
print(sig)
# Output: (name, greeting='Hello', punctuation='!')

# Iterate over parameters
for param_name, param in sig.parameters.items():
    print(f"{param_name}: default={param.default}, kind={param.kind.name}")
# Output:
# name: default=inspect.Parameter.empty, kind=POSITIONAL_OR_KEYWORD
# greeting: default=Hello, kind=POSITIONAL_OR_KEYWORD
# punctuation: default=!, kind=POSITIONAL_OR_KEYWORD

inspect.getmembers()

Returns all members of an object that match a given predicate.

inspect.getmembers(object, predicate=None)
ParameterTypeDefaultDescription
objectobjectThe object to inspect
predicatecallableNoneOptional filter function(member_name, member_value) -> bool
import inspect

class MyClass:
    class_attr = 42
    
    def __init__(self):
        self.instance_attr = "hello"
    
    def method(self):
        pass

# Get all members
for name, value in inspect.getmembers(MyClass):
    print(f"{name}: {type(value).__name__}")
# Output shows all attributes including __init__, __class__, etc.

# Filter to only methods
methods = inspect.getmembers(MyClass, inspect.isfunction)
print([m[0] for m in methods])
# Output: ['__init__', 'method']

Getting Source Code

inspect.getsource()

Returns the source code of a function, class, or method as a string.

inspect.getsource(object)
import inspect

def example_function(x, y):
    """This is a docstring."""
    result = x + y
    return result

print(inspect.getsource(example_function))
# Output:
# def example_function(x, y):
#     """This is a docstring."""
#     result = x + y
#     return result

inspect.getfile()

Returns the name of the Python file where an object is defined.

inspect.getfile(object)
import inspect
import os

print(inspect.getfile(inspect.signature))
# Output: /usr/lib/python3.11/inspect.py

print(inspect.getfile(os))
# Output: <frozen os> (built-in module)

# Works with custom classes
class MyClass:
    pass

print(inspect.getfile(MyClass))
# Output: /path/to/current/file.py

Frame and Stack Inspection

inspect.currentframe()

Returns the current frame object. Frames contain execution context.

inspect.currentframe() -> FrameType
import inspect

def caller():
    frame = inspect.currentframe()
    print(f"Called from: {frame.f_code.co_filename}")
    print(f"Line number: {frame.f_lineno}")
    print(f"Function name: {frame.f_code.co_name}")
    
    # Access local variables
    print(f"Local variables: {frame.f_locals}")
    return frame

def wrapper():
    x = 42
    y = "test"
    caller()

wrapper()

inspect.stack()

Returns a list of FrameInfo namedtuples representing the call stack.

inspect.stack(context=1) -> list[FrameInfo]
ParameterTypeDefaultDescription
contextint1Number of lines of source code to include before/after
import inspect

def function_c():
    for frame_info in inspect.stack():
        print(f"{frame_info.function} at {frame_info.filename}:{frame_info.lineno}")

def function_b():
    function_c()

def function_a():
    function_b()

function_a()
# Output:
# function_c at /path/to/file.py:15
# function_b at /path/to/file.py:19
# function_a at /path/to/file.py:23
# <module> at /path/to/file.py:26

Other Useful Functions

inspect.getdoc()

Gets the docstring of an object, cleaned up.

import inspect

def documented():
    """
    This is a multi-line
    docstring.
    """
    pass

print(inspect.getdoc(documented))
# Output: This is a multi-line\n    docstring.

inspect.getmodulename()

Extracts the module name from a filename.

print(inspect.getmodulename("/path/to/mymodule.py"))
# Output: mymodule

print(inspect.getmodulename("/path/to/mymodule"))
# Output: mymodule

inspect.ismodule(), inspect.isclass(), inspect.isfunction(), inspect.ismethod()

Type-checking predicates for introspection.

import inspect
import os

print(inspect.ismodule(os))           # True
print(inspect.isclass(os))            # False
print(inspect.isfunction(inspect.stack))  # True
print(inspect.ismethod(os.path.join)) # True

Practical Example: Building a Simple Debugger

import inspect

def debug_call(frame, event, arg):
    if event == 'call':
        code = frame.f_code
        args = inspect.signature(code.co_varnames[:code.co_argcount])
        print(f"Calling {code.co_name}({', '.join(args)}) at line {frame.f_lineno}")
    return debug_call

# Enable tracing
# sys.settrace(debug_call)

See Also