API Reference

functrace.trace(callback, *, apply_defaults=False, undefined_value=None, include=None, exclude=None, stack_level=1)[source]

Creates a decorator that provides detailed tracing of function execution and invokes a callback with metadata about the execution. This decorator is useful for monitoring, debugging, and performance analysis.

Parameters:
  • callback (collections.abc.Callable) – A callable that will be invoked with a TraceResult instance at the beginning and end of the traced function’s execution. The TraceResult provides information about the function call, such as parameters, return value, and execution status. This callback is useful for logging, monitoring, or other forms of tracing.

  • apply_defaults (bool, default False) – If True, the decorator will apply default values to any missing arguments when creating the TraceResult. This means that if a function is called with fewer arguments than it expects, the missing arguments will be filled with their default values as defined in the function signature. If False, missing arguments are represented as undefined_value in the TraceResult.

  • undefined_value (Any, default None) – The value to use for arguments that are missing or not provided if apply_defaults is set to False. This allows customization of how missing or undefined arguments are represented in the TraceResult. For example, you might use a specific placeholder object or value to indicate that an argument was not supplied.

  • include (str, tuple of str, default None) – A selection of parameter names to include in the TraceResult. If set to None, all parameters of the traced function are included. This allows for filtering the parameters that are captured and reported by the callback. If specified, only the parameters listed will be included in the trace output, while others will be omitted.

  • exclude (str, tuple of str, default None) – A selection of parameter names to exclude from the TraceResult. If set to None, no parameters are excluded, and all are included. This allows for excluding certain parameters from the trace output. For instance, you might exclude large data structures or sensitive information that should not be included in the trace.

  • stack_level (int, default 1) – Specifies the number of stack frames to go back when tracing the function’s execution. A stack level of 1 means inspecting the immediate caller’s frame, a level of 2 means inspecting the caller of the immediate caller, and so on. This parameter controls how deep in the call stack the tracing occurs.

Returns:

A decorator that wraps the traced function. This decorator adds tracing functionality to the function, invoking the specified callback with TraceResult instances before and after the function execution.

Return type:

collections.abc.Callable

Notes

  • The callback function is invoked twice: once with an is_started flag before the function begins execution, and once with either is_completed or is_failed flag after the function finishes or raises an exception.

  • The include and exclude parameters provide fine-grained control over which function parameters are captured in the trace output.

  • The stack_level parameter helps in tracing functions through different layers of abstraction by adjusting how deep in the call stack the tracing occurs.

Examples

Defining a callback function:

>>> from functrace import TraceResult, trace
...
>>> def trace_callback(result: TraceResult) -> None:
...     function_call = result.function_call.format()
...     elapsed_time = result.elapsed_time.format()
...     returned_value = repr(result.returned_value)
...     exception = repr(result.exception)
...     parts = [function_call]
...     if result.is_started:
...         parts.extend(['Started'])
...     if result.is_completed:
...         parts.extend(['Completed', elapsed_time, returned_value])
...     if result.is_failed:
...         parts.extend(['Failed', elapsed_time, exception])
...     message = ' | '.join(parts)
...     print(message)

Minimal example:

>>> @trace(callback=trace_callback)
... def func(a, b)
...     return a / b
...
>>> func(1, 2)
func(a=1, b=2) | Started
func(a=1, b=2) | Completed | X seconds | 0.5

Minimal example (raised exception):

>>> @trace(callback=trace_callback)
... def func(a, b)
...     return a / b
...
>>> func(1, 0)
func(a=1, b=2) | Started
func(a=1, b=2) | Failed | X seconds | ZeroDivisionError('division by zero')

Applying defaults:

>>> @trace(callback=trace_callback, apply_defaults=False)
... def func(a=1, b=2)
...     return a, b
...
>>> func()
func(a=None, b=None) | Started
func(a=None, b=None) | Completed | X seconds | (1, 2)
>>> @trace(callback=trace_callback, apply_defaults=True)
... def func(a=1, b=2)
...     return a, b
...
>>> func()
func(a=1, b=2) | Started
func(a=1, b=2) | Completed | X seconds | (1, 2)

Using undefined value:

>>> @trace(callback=trace_callback, undefined_value=None)
... def func(a=1, b=None)
...     return a, b
...
>>> func(b=None)
func(a=None, b=None) | Started
func(a=None, b=None) | Completed | X seconds | (1, None)
>>> @trace(callback=trace_callback, undefined_value=Ellipsis)
... def func(a=1, b=None)
...     return a, b
...
>>> func(b=None)
func(a=Ellipsis, b=None) | Started
func(a=Ellipsis, b=None) | Completed | X seconds | (1, None)

Including one parameter:

>>> @trace(callback=trace_callback, include='b')
... def func(a, b, c)
...     return a + b + c
...
>>> func(1, 2, 3)
func(b=2) | Started
func(b=2) | Completed | X seconds | 6

Including many parameters:

>>> @trace(callback=trace_callback, include=('a', 'c'))
... def func(a, b, c)
...     return a + b + c
...
>>> func(1, 2, 3)
func(a=1, c=3) | Started
func(a=1, c=3) | Completed | X seconds | 6

Excluding one parameter:

>>> @trace(callback=trace_callback, exclude='b')
... def func(a, b, c)
...     return a + b + c
...
>>> func(1, 2, 3)
func(a=1, c=3) | Started
func(a=1, c=3) | Completed | X seconds | 6

Excluding many parameters:

>>> @trace(callback=trace_callback, exclude=('a', 'c'))
... def func(a, b, c)
...     return a + b + c
...
>>> func(1, 2, 3)
func(b=2) | Started
func(b=2) | Completed | X seconds | 6
class functrace.TraceResult(function_call, elapsed_time=<factory>, is_started=False, is_completed=False, is_failed=False, returned_value=None, exception=None, traceback=None)[source]

Captures comprehensive metadata for a traced function, including performance metrics, input arguments, return values, and any exceptions encountered.

This class provides a detailed snapshot of a function’s execution, facilitating in-depth tracing and analysis. It includes information about the function’s start, completion, and any errors that may have occurred, along with performance timing.

Key features include:

  • Detailed function call information: Provides specifics about the function name, arguments, and other relevant metadata.

  • Timing metrics for execution duration: Measures the time taken for the function to execute, allowing performance analysis.

  • Status indicators for function execution: Flags to indicate whether the function has started, completed successfully, or failed.

  • Captured return values and exceptions: Records the function’s return value upon successful completion or any exceptions raised during execution.

This enables robust monitoring and debugging, offering insights into both successful executions and failures.

Parameters:
  • function_call (FunctionCall)

  • elapsed_time (ElapsedTime)

  • is_started (bool)

  • is_completed (bool)

  • is_failed (bool)

  • returned_value (Any)

  • exception (Exception | None)

  • traceback (str | None)

function_call

Contains details about the function call, such as the function’s name, arguments, and other relevant metadata.

Type:

FunctionCall

elapsed_time

Represents the duration of the function’s execution. This attribute captures the time taken from the start to the end of the function, but it is only measured when the function has completed or failed.

Specifically:

  • If is_completed is True or is_failed is True, elapsed_time represents the total execution time of the function from start to finish.

  • If is_started is True, indicating that the function is still in progress, elapsed_time will be set to NaN (Not a Number) to indicate that the time duration is not applicable or unavailable.

This design ensures that elapsed_time accurately reflects the execution duration only when the function has fully completed or failed, providing relevant timing information.

Type:

ElapsedTime

is_started

Indicates whether the function has started execution. This is set to True when the function begins execution.

Type:

bool

is_completed

Indicates whether the function has completed execution successfully. This is set to True when the function completes without raising an exception.

Type:

bool

is_failed

Indicates whether the function has failed during execution. This is set to True if the function raises an exception.

Type:

bool

returned_value

The value returned by the function upon successful completion. This attribute is set only if is_completed is True. If the function does not return a value, this attribute will be None.

Type:

Any, optional

exception

The exception raised during function execution, if any. This attribute is set only if is_failed is True. It provides details about the error encountered during execution.

Type:

Exception, optional

traceback

The traceback of the exception, if any. This provides a string representation of the stack trace where the exception occurred. This attribute is only set if is_failed is True and an exception was raised.

Type:

str, optional

Notes

  • Only one of is_started, is_completed, and is_failed can be True at any given time, reflecting the mutually exclusive states of function execution.

  • The function_call attribute is an instance of FunctionCall and contains detailed information about the function invocation, including its name and arguments.

  • The elapsed_time is represented by an ElapsedTime object, which provides a standardized way to measure and report time intervals.

class functrace.utilities.FunctionCall(func, args, kwargs, apply_defaults, undefined_value, include, exclude, frame, stack_level)[source]

Represents detailed information about a function call for tracing and debugging purposes.

This class provides a comprehensive view of a function invocation, including its name, arguments, and contextual information related to the call. It is primarily used internally to capture and analyze the details of function execution, which can be useful for monitoring, performance analysis, and debugging.

Notes

  • This class is intended for internal use within the tracing mechanism, and users should not instantiate it directly. Instead, instances of FunctionCall are created and managed by the tracing system to provide structured information about function calls and execution contexts.

Parameters:
  • func (Callable[[...], Any])

  • args (tuple[Any, ...])

  • kwargs (dict[str, Any])

  • apply_defaults (bool)

  • undefined_value (Any)

  • include (str | tuple[str, ...] | None)

  • exclude (str | tuple[str, ...] | None)

  • frame (FrameType)

  • stack_level (int)

property module: ModuleType

Retrieve the module in which the function is defined.

This property provides access to the module object that contains the function, allowing you to understand the context in which the function resides.

Returns:

The module object where the function is defined. This can be useful for determining the origin of the function or for module-level debugging.

Return type:

types.ModuleType

property func: Callable[[...], Any] | LambdaType | MethodType

Retrieve the function object being called.

This property provides the actual function or method object that was invoked, allowing you to access the function’s attributes or examine its behavior.

Returns:

The function or method object that was called. This can be used to inspect or manipulate the function’s attributes or execution characteristics.

Return type:

collections.abc.Callable

property args: tuple[Any, ...]

Retrieve the positional arguments passed to the function.

This property provides a tuple of the positional arguments that were supplied when the function was called. It reflects the order and values of the arguments.

Returns:

A tuple containing the positional arguments passed to the function. This can be used for inspecting or processing the arguments of the function call.

Return type:

tuple

property kwargs: dict[str, Any]

Retrieve the keyword arguments passed to the function.

This property provides a dictionary of the keyword arguments that were provided during the function call. It includes both the names and values of the keyword arguments.

Returns:

A dictionary containing the keyword arguments passed to the function. This allows for detailed inspection and manipulation of the function’s named parameters.

Return type:

dict

property signature: Signature

Retrieve the signature of the function.

This property provides the inspect.Signature object of the function, which includes information about the function’s parameters, return type, and other signature-related details.

Returns:

The inspect.Signature object representing the function’s signature. This can be used to analyze the function’s parameter structure and default values.

Return type:

inspect.Signature

property bound_arguments: BoundArguments

Retrieve the bound arguments for the function call, including any default values if applicable.

This property provides an inspect.BoundArguments object that binds the positional and keyword arguments to the function’s parameters, applying default values if apply_defaults is set to True.

Returns:

The inspect.BoundArguments object that shows how the arguments from the call are bound to the function’s parameters. It includes default values if apply_defaults is True.

Return type:

inspect.BoundArguments

property frame: FrameType

Retrieve the frame object where the function is being called.

This property provides the frame object that represents the context of the function call, including information about the call stack and execution environment.

Returns:

The frame object associated with the function call. This can be useful for debugging and understanding the execution context of the function.

Return type:

types.FrameType

property stack_level: int

Retrieve the stack level for the function call context.

This property provides the depth of the call stack where the function was invoked, which can be particularly useful for logging purposes. It helps in understanding the position of the function call within the broader call stack.

Returns:

The stack level relative to the function’s invocation. This value is useful for logging and debugging to track where the function call occurs in the call stack.

Return type:

int

Notes

  • This value can be used to log the stack level, aiding in tracing and diagnosing function call sequences and their context within the application.

  • Higher stack levels indicate deeper positions in the call stack, which can assist in understanding complex call chains.

format(pattern='{name}({params})', *, association='=', separator=', ')[source]

Generates a string representation of the function call based on the specified pattern.

This method formats the details of the function call according to the provided pattern and customization options, allowing for flexible and informative string representations of function invocations.

Parameters:
  • pattern (str, default '{name}({params})') –

    The format string used to represent the function call. It supports the following placeholders:

    • {path} : The file path where the function is defined.

    • {file} : The file name where the function is defined, including the extension

    • {module} : The module name where the function is located.

    • {name} : The function name.

    • {qualname} : The fully qualified name of the function (including class name if applicable).

    • {line} : The line number where the function call occurs.

    • {params} : A string representing the function’s parameters and their values.

  • association (str, default '=') – The string used to separate argument names from their values in the formatted representation.

  • separator (str, default ', ') – The string used to separate multiple arguments in the formatted representation.

Returns:

A formatted string representing the function call, customized according to the specified pattern, association, and separator.

Return type:

str

Examples

Given the following setup:

>>> # /home/user/python/project/module/file.py
...
>>> from functrace import trace
...
>>> class MyClass:
...     @trace(callback=...)
...     def my_func(self, a, b):
...         ...
...
>>> MyClass().my_func(123, 'abc')

Formatting the function name and its parameters:

>>> self.format('{name}({params})')
'my_func(a=123, b='abc')'

Displaying the file path and line number:

>>> self.format('{path}, line: {line}')
'/home/user/python/project/module/file.py, line: 10'

Showing the file name where the function is defined:

>>> self.format('filename: {file}')
'filename: file.py'

Including the module name and fully qualified function name:

>>> self.format('{module} - {qualname}')
'module.file - MyClass.my_func'

Customizing the parameter representation with a different separator and association:

>>> self.format('{params}', association=': ', separator=' | ')
'a: 123 | b: 'abc''
class functrace.utilities.ElapsedTime(seconds)[source]

Represents elapsed time in seconds, with support for multiple time units and human-readable formatting.

This class provides a structured way to represent and manage elapsed time. It is primarily used internally to track the duration of function executions within the tracing mechanism. This includes formatting elapsed time for monitoring and debugging purposes.

Notes

  • This class is intended for internal use within the tracing system. Users should not instantiate it directly. Instead, instances of ElapsedTime are created and managed by the tracing mechanism to handle and format time-related information.

Parameters:

seconds (float)

property nanoseconds: float

Calculate the elapsed time in nanoseconds.

Returns:

Elapsed time expressed in nanoseconds.

Return type:

float

property microseconds: float

Calculate the elapsed time in microseconds.

Returns:

Elapsed time expressed in microseconds.

Return type:

float

property milliseconds: float

Calculate the elapsed time in milliseconds.

Returns:

Elapsed time expressed in milliseconds.

Return type:

float

property seconds: float

Calculate the elapsed time in seconds.

Returns:

Total elapsed time in seconds.

Return type:

float

property minutes: float

Calculate the elapsed time in minutes.

Returns:

Elapsed time expressed in minutes.

Return type:

float

property hours: float

Calculate the elapsed time in hours.

Returns:

Elapsed time expressed in hours.

Return type:

float

property days: float

Calculate the elapsed time in days.

Returns:

Elapsed time expressed in days.

Return type:

float

property weeks: float

Calculate the elapsed time in weeks.

Returns:

Elapsed time expressed in weeks.

Return type:

float

format(*, decimals=2, trailing_zeros=False, time_parts=False, separator=', ', ignore_zeros=True)[source]

Convert the elapsed time to a human-readable string representation.

Parameters:
  • decimals (int, default 2) – Number of decimal places to display for the elapsed time. This parameter is applicable when time_parts is False or when the elapsed time is less than 1 nanosecond.

  • trailing_zeros (bool, default False) – Determines whether to include trailing zeros after the decimal point. If True, trailing zeros will be included in the output; if False, they will be removed.

  • time_parts (bool, default False) – If True, the elapsed time is broken down into its component units (e.g., hours, minutes, seconds). If False, the elapsed time is displayed as a single unit with the specified decimal precision.

  • separator (str, default ', ') – The string used to separate different units in the formatted output when time_parts is True

  • ignore_zeros (bool, default True) – Deprecated. When set to True, zero-value units are excluded from the formatted output. This option is no longer recommended, as it may be removed in future versions.

Returns:

A formatted string representing the elapsed time. If the elapsed time is float(‘nan’), the method returns None.

Return type:

str or None

Examples

Assume the elapsed time was 75 seconds:

>>> self.seconds
75.0
>>> self.minutes
1.25
>>> self.format(decimals=2)
'1.25 minutes'
>>> self.format(decimals=1)
'1.3 minutes'
>>> self.format(decimals=0)
'1 minute'

Assume the elapsed time was 60 seconds:

>>> self.seconds
60.0
>>> self.minutes
1.0
>>> self.format(trailing_zeros=False)
'1 minute'
>>> self.format(trailing_zeros=True)
'1.00 minute'

Assume the elapsed time was 3723 seconds:

>>> self.seconds
3723.0
>>> self.minutes
62.05
>>> self.format(time_parts=True)
'1 hour, 2 minutes, 3 seconds'
>>> self.format(time_parts=True, separator=' | ')
'1 hour | 2 minutes | 3 seconds'