System-level execution tracer for Python 3.12+ (PEP 669)
Project description
🌐 Also available in: Русская версия
🌀 FlowTrace — Visual Execution Tracing for Python 3.12+
FlowTrace is a system-level tracer built on Python’s Monitoring API (PEP 669). It doesn’t “profile time by default”. Instead, it reconstructs what happened in your program — calls, returns, structure — with minimal overhead and zero monkey-patching.
Status: experimental alpha. Python 3.12+ only.
Installation
pip install flowtrace
Quick Start
1) One-line decorator
from flowtrace import trace
@trace
def fib(n):
return n if n < 2 else fib(n-1) + fib(n-2)
fib(3)
Output:
→ fib(3)
→ fib(2)
→ fib(1) → 1
→ fib(0) → 0
← fib(2) → 1
→ fib(1) → 1
← fib(3) → 2
2) Timing when you need it
from flowtrace import trace
@trace(show_timing=True)
def compute(a, b):
return a * b
compute(6, 7)
Output:
→ compute(6, 7) [0.000265s] → 42
3) Manual session
from flowtrace import start_tracing, stop_tracing, print_tree
def fib(n):
return n if n < 2 else fib(n-1) + fib(n-2)
start_tracing()
fib(3)
events = stop_tracing()
print_tree(events)
Output:
→ fib()
→ fib()
→ fib() → 1
→ fib() → 0
← fib() → 1
→ fib() → 1
← fib() → 2
4) Context manager
FlowTrace provides a context manager for scoped tracing inside specific code blocks.
This approach is especially convenient for short-lived runs, tests, or async tasks.
from flowtrace.core import active_tracing
from flowtrace import print_tree
def run_demo():
...
with active_tracing():
run_demo()
print_tree()
Each with active_tracing(): block creates its own isolated tracing session,
so concurrent async tasks or nested runs don’t interfere with each other.
Global configuration
import flowtrace
import flowtrace
flowtrace.config(
show_args=True,
show_result=True,
show_timing=True,
show_exc=False,
inline_return=False,
)
Controls which information is collected globally. All flags default to True.
| Flag | Type | Description |
|---|---|---|
show_args |
bool | capture and display call arguments |
show_result |
bool | capture and display return values |
show_timing |
bool | measure and display function duration |
show_exc |
bool / int | enable exception trace capture; int sets traceback depth |
inline_return |
bool | compact one-line output for leaf calls |
Function-level overrides
@flowtrace.trace(show_args=True)
def foo(x): ...
Local flags temporarily override global ones for this function only; child calls inherit the global configuration.
Example
import flowtrace
flowtrace.config(show_args=False, show_result=True, show_timing=True)
@flowtrace.trace
def a(x): return b(x) + 1
@flowtrace.trace(show_args=True)
def b(y): return y * 2
a(10)
Output:
→ a() [0.000032s] → 21
→ b(y=10) [0.000010s] → 20
← b(y=10)
← a()
Why FlowTrace?
-
Not a profiler: profilers answer “how long”. FlowTrace answers “what, in which order, and why”.
-
Direct line to the VM: listens to bytecode-level events via sys.monitoring (PEP 669).
-
No code intrusion: no sys.settrace, no monkey-patching, no stdout noise.
API (current)
from flowtrace import trace, config, start_tracing, stop_tracing, get_trace_data, print_tree
-
@trace(measure_time: bool = True)Decorate a function to include its calls in the trace. Whenmeasure_time=True, durations for this function’s calls are recorded. -
start_tracing()/stop_tracing() -> list[CallEvent]Start/stop a process-wide tracing session. By default no timing is recorded here — only structure. -
get_trace_data() -> list[CallEvent]Access the last recorded events. -
print_tree(events)Pretty-print a hierarchical call tree. -
get_config() -> Config— access the current typed configuration object.
Event model (CallEvent):
id: int
kind: str
func_name: str
parent_id: int | None
args_repr: str | None
result_repr: str | None
duration: float | None
collect_args: bool
collect_result: bool
collect_timing: bool
Design choices (snapshot)
-
Only
PY_START/PY_RETURN: we do not listen toCALLto keep the core lean. Argument strings are provided by the decorator right before the call starts. -
Exception lifecycle tracing: FlowTrace now listens to exception-related signals (
RAISE,RERAISE,EXCEPTION_HANDLED,PY_UNWIND). Each function frame produces at most one exception event, labeled as[caught](handled locally) or[propagated](escaped outward). -
Timing is opt-in:
perf_counter()is used only whenmeasure_time=True. Starting/stopping a session alone does not add timing overhead. -
Filter user code: internal modules and site-packages are excluded from the default output.
Design notes
-
Zero-overhead when disabled: arguments, results, and timing are gathered only if their flags are True.
-
Named argument binding: readable form like a=5, b=2 via inspect.signature, cached at decoration time.
-
No cascades: per-function flags affect only that decorated function.
Roadmap
-
Async/coroutine transitions.
-
JSON export for post-processing.
-
Include/exclude filters & colorized output.
-
Minimal CLI helpers.
Contributing
We welcome small, surgical PRs. The codebase is intentionally compact to be an approachable learning tool for exploring Python 3.12+ internals.
Development
python -m pip install -U pip
pip install -e . # editable install
pip install -U ruff mypy pytest pre-commit
pre-commit install
pytest -q
ruff format .
ruff check .
mypy flowtrace
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 flowtrace-0.6.0.tar.gz.
File metadata
- Download URL: flowtrace-0.6.0.tar.gz
- Upload date:
- Size: 26.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1a6f4356ce7655f9b18d7f6ed948b780cd604f2625c417427c5035302686872
|
|
| MD5 |
54ae727b84bbb4c570aefaea89478e19
|
|
| BLAKE2b-256 |
e07064802b15cdcfeef88f64e011981b0eebf7990222b3a2575bdb087b96055f
|
File details
Details for the file flowtrace-0.6.0-py3-none-any.whl.
File metadata
- Download URL: flowtrace-0.6.0-py3-none-any.whl
- Upload date:
- Size: 24.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9527bd30e30661cba8a113fe1a400c0c6422c2a9d365870017416bc026b15995
|
|
| MD5 |
f0bcb7cd4b80fbc33efe5f659951d2f5
|
|
| BLAKE2b-256 |
fe2f34b59b11a0328d5a071a28aa6fc816a00fba9d479662b4969f19397c9bde
|