pytracecall: A debugging module with sync and async decorators (CallTracer and aCallTracer) for tracing function calls, and a function (stack) for logging the current call stack
Project description
A powerful, flexible, and user-friendly debugging module for tracing function calls in Python.
pytracecall provides simple yet powerful tools to help you understand your code's execution flow without a full step-by-step debugger. It is designed to integrate seamlessly with Python's standard logging module and can produce output for human analysis, IDEs, and automated systems.
Why PyTraceCall?
- Unmatched Insight, Zero Intrusion: Get deep insights into your code's execution flow, arguments, return values, and performance without modifying your core logic. The decorator pattern keeps your code clean and readable.
- Debug Concurrency with Confidence: Built from the ground up with
contextvars,pytracecallprovides clear, isolated traces for complexasyncioapplications, eliminating the guesswork of concurrent execution flows. - From Quick Glance to Deep Analysis: Whether you need a quick print-style debug, a detailed performance profile with exclusive timings, or structured JSON for automated analysis, the flexible API scales to your needs.
- Highly Configurable & User-Friendly: Fine-tune everything from output colors and argument visibility to conditional tracing triggers. The power is in your hands.
- A Joy to Use: With features like clickable IDE/terminal integration and beautiful
richtree views, debugging stops being a chore and becomes an insightful, and even enjoyable, experience.
Features
- Synchronous and Asynchronous Tracing: Decorators for both standard (
def) and asynchronous (async def) functions. - Rich Interactive Output: Optional integration with the
richlibrary to render call stacks as beautiful, dynamic trees. - IDE & Terminal Integration: Generates log entries that are clickable in modern IDEs (VSCode, PyCharm) and terminals (iTerm2 with OSC 8 support), taking you directly to the source code line.
- Advanced Performance Profiling: Measure execution time with multiple system clocks. Differentiate between inclusive time (total) and exclusive time (function's own work, excluding children).
- Conditional Tracing: Define custom rules to activate tracing only for specific calls, preventing log spam and focusing on what matters.
- Argument & Return Value Control: Mask sensitive data (like passwords), truncate long values, and even hide arguments (like
self) from the output. - Structured JSON Output: Log trace events as JSON objects for easy parsing, filtering, and analysis by automated systems.
- Runtime Control: Programmatically enable or disable any tracer instance on the fly.
- Concurrency Safe: Uses
contextvarsto safely trace concurrent tasks without mixing up call chains.
Installation
You can install the package from PyPI using pip.
pip install pytracecall
To enable the optional rich integration for beautiful tree-like logging, install the rich extra:
pip install "pytracecall[rich]"
Usage Examples
Basic Synchronous Tracing
First, ensure you configure Python's logging module to see the output.
import logging
from calltracer import CallTracer
# Configure logging to display DEBUG level messages
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(message)s',
datefmt='%H:%M:%S'
)
trace = CallTracer()
@trace
def add(x, y):
return x + y
add(10, 5)
Output:
21:15:10 - --> Calling add(x=10, y=5)
21:15:10 - <-- Exiting add(x=10, y=5), returned: 15
Advanced Features Showcase
The true power of pytracecall lies in its rich configuration.
Rich Interactive Trees
For the most intuitive visualization, use the RichPyTraceHandler.
Code (rex.py):
import logging
from calltracer import CallTracer, DFMT, RichPyTraceHandler
# 1. Configure a logger to use the Rich handler exclusively
log = logging.getLogger("rich_demo")
log.setLevel(logging.DEBUG)
log.handlers = [RichPyTraceHandler(overwrite=False)] # `overwrite=False` for append-only tree
log.propagate = False
# 2. Configure the tracer to output JSON for the handler to consume
trace = CallTracer(logger=log, output="json", timing="Mh")
@trace
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)
fib(5)
Output:
Call Chain Tracing (trace_chain)
Set trace_chain=True to see the full context for every call.
trace_with_chain = CallTracer(trace_chain=True)
Output:
Performance Profiling (timing)
Measure performance using different clocks. Use lowercase for inclusive time and uppercase for exclusive time.
# M: Exclusive monotonic time, h: Inclusive perf_counter time
profile_trace = CallTracer(timing="Mh", timing_fmt=DFMT.SINGLE)
IDE & Terminal Integration
Make your logs clickable! ide_support creates links for IDEs, while term_support uses OSC 8 for modern terminals.
# For clickable links in PyCharm/VSCode
ide_trace = CallTracer(ide_support=True)
# For Ctrl/Cmd-Click in iTerm2 and other modern terminals
term_trace = CallTracer(term_support=True)
Output in iTerm2 (with term_support=True): The function signature becomes a clickable link that opens the file at the correct line in your editor.
Asynchronous Tracing
aCallTracer handles async functions and concurrency flawlessly, keeping call chains isolated.
Output:
Full API Reference
The CallTracer and aCallTracer classes share the same rich set of initialization parameters, inherited from a base class.
CallTracer / aCallTracer Parameters
__init__(self,
level=logging.DEBUG,
trace_chain=False,
logger=None,
transform=None,
max_argval_len=None,
return_transform: Optional[Callable] = None,
max_return_len: Optional[int] = None,
condition: Optional[Callable] = None,
timing: str = None,
timing_fmt: DFMT = DFMT.SINGLE,
output: str = 'text',
ide_support: bool = False,
term_support: bool = False,
rel_path: bool = True)
level(int): The logging level for trace messages.trace_chain(bool): IfTrue, logs the full call chain for each event.logger(logging.Logger): A custom logger instance to use.transform(dict): A dictionary of callbacks to transform/hide argument values. Keys are(func_qualname, arg_name)tuples. A wildcard('*', arg_name)can be used. If a callback returnsNone, only the argument name is printed.max_argval_len(int): Maximum length for the string representation of argument values.return_transform(Callable): A function to transform the return value before logging.max_return_len(int): Maximum length for the string representation of the return value.condition(Callable): A function(func_name, *args, **kwargs) -> boolthat determines if tracing should be active for a call. If it returnsFalse, this call and all nested calls are skipped.timing(str): Enables [poor mens'] profiling. A string of characters specifying clocks to use (monotonic,high-perf,cpu,thread). Lowercase measures inclusive (total) time. Uppercase measures exclusive time (total time minus decorated child calls).timing_fmt(DFMT): The display format for timing values (DFMT.NANO,DFMT.MICRO,DFMT.SEC,DFMT.SINGLE,DFMT.HUMAN). See docstrings for details.output(str): The output format.'text'(default) for human-readable logs or'json'for structured logging.ide_support(bool): IfTrue, formats text logs to be clickable in IDEs (e.g., PyCharm, VSCode).term_support(bool): IfTrue, formats text logs with OSC 8 hyperlinks for modern terminals.rel_path(bool): IfTrue, uses relative paths foride_supportandterm_support.
Methods:
enable()/disable(): Each tracer instance has these methods to control tracing at runtime.
RichPyTraceHandler Parameters
The handler for beautiful rich tree output.
__init__(self,
overwrite: bool = False,
color_enter: str = "green",
color_exit: str = "bold blue",
color_exception: str = "bold red",
color_timing: str = "yellow")
overwrite(bool): IfFalse(default), creates an append-only tree showing both enter and exit events. IfTrue, uses aLiveanimated display to overwrite enter nodes with exit information.color_*(str): Rich markup strings to customize the output colors.
stack() Function
stack(level=logging.DEBUG, logger=None, limit=None, start=0)
Logs the current call stack.
level(int): The logging level for the stack trace message.logger(logging.Logger): The logger to use.limit(int): Maximum number of frames to show.start(int): Frame offset to start from.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytracecall-4.2.0.tar.gz.
File metadata
- Download URL: pytracecall-4.2.0.tar.gz
- Upload date:
- Size: 25.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36a17d224fca24f99ee6e222e8901f0cb761a15c688b18e54c211445b8e81bfd
|
|
| MD5 |
5291d170324203541640537194a94a19
|
|
| BLAKE2b-256 |
0b838da779ff99e1a59f083923aa103c368897a37634d41031af1ec7ba40f436
|
File details
Details for the file pytracecall-4.2.0-py3-none-any.whl.
File metadata
- Download URL: pytracecall-4.2.0-py3-none-any.whl
- Upload date:
- Size: 24.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82a0f8ffeab400a466a83349a3e8cdb6bdf937ca7e6cc3efa2300b9cbfffd832
|
|
| MD5 |
73e4a27d0d6d2bb91c927b004683158c
|
|
| BLAKE2b-256 |
e6ad1b7def9b98e5aa8ee301bd605d2d9985c8572acd90855674d20a34064791
|