traceflow-py 1.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,11 @@
1
+ All Rights Reserved
2
+
3
+ Copyright (c) 2025 Aarav Agarwal
4
+
5
+ This software and associated documentation files (the "Software") may not be
6
+ copied, modified, merged, published, distributed, sublicensed, or sold without
7
+ the express written permission of the copyright holder.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
@@ -0,0 +1,409 @@
1
+ Metadata-Version: 2.4
2
+ Name: traceflow-py
3
+ Version: 1.2.0
4
+ Summary: A lightweight decorator for visually tracing Python function calls with indented call trees, timing, variable tracking, and async support.
5
+ Author: Aarav Agarwal
6
+ License: All Rights Reserved
7
+ Project-URL: Homepage, https://github.com/Firestar3/TraceFlow
8
+ Project-URL: Repository, https://github.com/Firestar3/TraceFlow
9
+ Project-URL: Bug Tracker, https://github.com/Firestar3/TraceFlow/issues
10
+ Keywords: tracing,debugging,decorator,call-tree,profiling,recursion,async,logging
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Debuggers
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.7
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Operating System :: OS Independent
24
+ Requires-Python: >=3.7
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Dynamic: license-file
28
+
29
+ # TraceFlow
30
+
31
+ **TraceFlow** is a lightweight, zero-dependency Python decorator library for visually tracing function execution. It renders beautiful, indented call trees directly to your console — making debugging recursive, nested, and async code effortless.
32
+
33
+ ```
34
+ fibonacci(3)
35
+ ├── fibonacci(2)
36
+ │ ├── fibonacci(1)
37
+ │ │ └── return 1 [0.0003s]
38
+ │ ├── fibonacci(0)
39
+ │ │ └── return 0 [0.0000s]
40
+ │ └── return 1 [0.0006s]
41
+ ├── fibonacci(1)
42
+ │ └── return 1 [0.0000s]
43
+ └── return 2 [0.0008s]
44
+ ```
45
+
46
+ ---
47
+
48
+ ## Features
49
+
50
+ | Feature | Description |
51
+ |---|---|
52
+ | 🌳 **Call Trees** | Nested, indented tree visualization for every function call |
53
+ | ⏱️ **Execution Time** | Per-call timing with `[0.0042s]` annotations |
54
+ | 📐 **Truncation** | Smart character-limit truncation for large arguments and returns |
55
+ | 💥 **Exception Tracing** | Captures and renders exceptions inline in the call tree |
56
+ | 🔁 **Async Support** | Safely traces `async`/`await` functions and `asyncio.gather` |
57
+ | 🔒 **Depth Limiting** | Cap tracing depth with `max_depth` to reduce noise |
58
+ | 📁 **File Export** | Redirect trace output to a file instead of the console |
59
+ | 🔇 **Global Toggle** | `traceflow.disable()` / `traceflow.enable()` to control all tracing at runtime |
60
+ | 🔬 **Variable Tracking** | `track_vars=True` to log every local variable assignment inside a function |
61
+
62
+ ---
63
+
64
+ ## Installation
65
+
66
+ ```bash
67
+ # Clone the repo
68
+ git clone https://github.com/Firestar3/TraceFlow.git
69
+ cd TraceFlow
70
+
71
+ # Install locally
72
+ pip install .
73
+ ```
74
+
75
+ Or simply drop the `traceflow/` folder into your project — no dependencies required.
76
+
77
+ ---
78
+
79
+ ## Quick Start
80
+
81
+ ```python
82
+ from traceflow import watch
83
+
84
+ @watch()
85
+ def fibonacci(n):
86
+ if n <= 1:
87
+ return n
88
+ return fibonacci(n - 1) + fibonacci(n - 2)
89
+
90
+ fibonacci(3)
91
+ ```
92
+
93
+ **Output:**
94
+ ```
95
+ fibonacci(3)
96
+ ├── fibonacci(2)
97
+ │ ├── fibonacci(1)
98
+ │ │ └── return 1 [0.0003s]
99
+ │ ├── fibonacci(0)
100
+ │ │ └── return 0 [0.0000s]
101
+ │ └── return 1 [0.0006s]
102
+ ├── fibonacci(1)
103
+ │ └── return 1 [0.0000s]
104
+ └── return 2 [0.0008s]
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Feature Guide
110
+
111
+ ### 1. Execution Time Tracking
112
+
113
+ Every traced call automatically measures wall-clock time.
114
+
115
+ ```python
116
+ from traceflow import watch
117
+ import time
118
+
119
+ @watch(track_time=True)
120
+ def slow_add(a, b):
121
+ time.sleep(0.05)
122
+ return a + b
123
+
124
+ slow_add(10, 20)
125
+ ```
126
+
127
+ ```
128
+ slow_add(10, 20)
129
+ └── return 30 [0.0502s]
130
+ ```
131
+
132
+ Set `track_time=False` to disable timing:
133
+
134
+ ```python
135
+ @watch(track_time=False)
136
+ def add(a, b):
137
+ return a + b
138
+
139
+ add(1, 2)
140
+ ```
141
+
142
+ ```
143
+ add(1, 2)
144
+ └── return 3
145
+ ```
146
+
147
+ ---
148
+
149
+ ### 2. Argument & Return Truncation
150
+
151
+ Prevent massive data structures from flooding your console with `truncate_len`.
152
+
153
+ ```python
154
+ @watch(truncate_len=30)
155
+ def process(data):
156
+ return [x * 2 for x in data]
157
+
158
+ process(list(range(50)))
159
+ ```
160
+
161
+ ```
162
+ process([0, 1, 2, 3, 4, 5, 6, 7, 8,...)
163
+ └── return [0, 2, 4, 6, 8, 10, 12, 14,... [0.0000s]
164
+ ```
165
+
166
+ The character limit applies to both arguments and return values. Set `truncate_len=None` or `truncate_len=0` to disable truncation entirely.
167
+
168
+ ---
169
+
170
+ ### 3. Exception Tracing
171
+
172
+ Exceptions are captured, rendered in the tree, and re-raised — so your error handling works normally while you get full visibility.
173
+
174
+ ```python
175
+ @watch()
176
+ def divide(a, b):
177
+ return a / b
178
+
179
+ @watch()
180
+ def safe_math(x, y):
181
+ return divide(x, y)
182
+
183
+ try:
184
+ safe_math(10, 0)
185
+ except ZeroDivisionError:
186
+ pass
187
+ ```
188
+
189
+ ```
190
+ safe_math(10, 0)
191
+ ├── divide(10, 0)
192
+ │ └── ZeroDivisionError: division by zero [0.0000s]
193
+ └── ZeroDivisionError: division by zero [0.0000s]
194
+ ```
195
+
196
+ The exception propagates through each level of the call tree, showing exactly where it originated and how it bubbled up.
197
+
198
+ ---
199
+
200
+ ### 4. Max Depth Limiting
201
+
202
+ Reduce noise in deeply recursive functions by capping the trace depth.
203
+
204
+ ```python
205
+ @watch(max_depth=2)
206
+ def deep_fib(n):
207
+ if n <= 1:
208
+ return n
209
+ return deep_fib(n - 1) + deep_fib(n - 2)
210
+
211
+ deep_fib(4)
212
+ ```
213
+
214
+ ```
215
+ deep_fib(4)
216
+ ├── deep_fib(3)
217
+ │ └── return 2 [0.0000s]
218
+ ├── deep_fib(2)
219
+ │ └── return 1 [0.0000s]
220
+ └── return 3 [0.0000s]
221
+ ```
222
+
223
+ Calls beyond `max_depth` still execute normally — they just aren't traced.
224
+
225
+ ---
226
+
227
+ ### 5. Async Function Support
228
+
229
+ TraceFlow natively supports `async` functions. Concurrent tasks from `asyncio.gather` are traced cleanly.
230
+
231
+ ```python
232
+ import asyncio
233
+ from traceflow import watch
234
+
235
+ @watch()
236
+ async def fetch_data(id):
237
+ await asyncio.sleep(0.01)
238
+ return f"data_{id}"
239
+
240
+ @watch()
241
+ async def fetch_all():
242
+ return await asyncio.gather(fetch_data(1), fetch_data(2), fetch_data(3))
243
+
244
+ asyncio.run(fetch_all())
245
+ ```
246
+
247
+ ```
248
+ fetch_all()
249
+ ├── fetch_data(1)
250
+ │ └── return 'data_1' [0.0123s]
251
+ ├── fetch_data(2)
252
+ │ └── return 'data_2' [0.0123s]
253
+ ├── fetch_data(3)
254
+ │ └── return 'data_3' [0.0123s]
255
+ └── return ['data_1', 'data_2', 'data_3'] [0.0126s]
256
+ ```
257
+
258
+ ---
259
+
260
+ ### 6. File Export
261
+
262
+ Redirect all trace output to a text file instead of the console.
263
+
264
+ ```python
265
+ @watch(export_path="trace_output.txt")
266
+ def fibonacci(n):
267
+ if n <= 1:
268
+ return n
269
+ return fibonacci(n - 1) + fibonacci(n - 2)
270
+
271
+ fibonacci(3)
272
+ # -> Trace written to trace_output.txt
273
+ ```
274
+
275
+ The file is appended to, so multiple runs accumulate in the same file.
276
+
277
+ ---
278
+
279
+ ### 7. Global Enable / Disable
280
+
281
+ Turn all tracing on or off at runtime without removing decorators. Functions still execute normally when tracing is disabled — only the output is suppressed.
282
+
283
+ ```python
284
+ import traceflow
285
+ from traceflow import watch
286
+
287
+ @watch()
288
+ def add(a, b):
289
+ return a + b
290
+
291
+ add(1, 2) # Trace is printed
292
+
293
+ traceflow.disable()
294
+ add(3, 4) # No trace output, but returns 7 normally
295
+
296
+ traceflow.enable()
297
+ add(5, 6) # Trace resumes
298
+ ```
299
+
300
+ ```
301
+ add(1, 2)
302
+ └── return 3 [0.0000s]
303
+
304
+ add(5, 6)
305
+ └── return 11 [0.0000s]
306
+ ```
307
+
308
+ Also available: `traceflow.is_enabled()` to check current state.
309
+
310
+ ---
311
+
312
+ ### 8. Variable State Tracking
313
+
314
+ See exactly how local variables change inside a function, line by line. Parameters are captured as a baseline and not logged (they're already visible in the call signature).
315
+
316
+ ```python
317
+ @watch(track_vars=True)
318
+ def compute(x, y):
319
+ total = x + y
320
+ doubled = total * 2
321
+ message = f"Result: {doubled}"
322
+ return doubled
323
+
324
+ compute(5, 3)
325
+ ```
326
+
327
+ ```
328
+ compute(5, 3)
329
+ │ · total = 8
330
+ │ · doubled = 16
331
+ │ · message = 'Result: 16'
332
+ └── return 16 [0.0002s]
333
+ ```
334
+
335
+ Variable tracking inside a loop:
336
+
337
+ ```python
338
+ @watch(track_vars=True)
339
+ def sum_list(items):
340
+ total = 0
341
+ for val in items:
342
+ total += val
343
+ return total
344
+
345
+ sum_list([10, 20, 30])
346
+ ```
347
+
348
+ ```
349
+ sum_list([10, 20, 30])
350
+ │ · total = 0
351
+ │ · val = 10
352
+ │ · total = 10
353
+ │ · val = 20
354
+ │ · total = 30
355
+ │ · val = 30
356
+ │ · total = 60
357
+ └── return 60 [0.0001s]
358
+ ```
359
+
360
+ > **Note:** Variable tracking uses `sys.settrace` and is only available for synchronous functions. It adds overhead and is best used for targeted debugging, not production code.
361
+
362
+ ---
363
+
364
+ ### 9. Keyword Arguments
365
+
366
+ TraceFlow displays both positional and keyword arguments.
367
+
368
+ ```python
369
+ @watch()
370
+ def greet(name, greeting="Hello", punctuation="!"):
371
+ return f"{greeting}, {name}{punctuation}"
372
+
373
+ greet("Aarav", greeting="Hey", punctuation="!!")
374
+ ```
375
+
376
+ ```
377
+ greet('Aarav', greeting='Hey', punctuation='!!')
378
+ └── return 'Hey, Aarav!!' [0.0000s]
379
+ ```
380
+
381
+ ---
382
+
383
+ ## Configuration Reference
384
+
385
+ | Parameter | Type | Default | Description |
386
+ |---|---|---|---|
387
+ | `track_time` | `bool` | `True` | Append `[0.0042s]` execution time to each return line |
388
+ | `truncate_len` | `int` | `50` | Max characters for argument/return repr. `0` or `None` to disable |
389
+ | `max_depth` | `int` | `None` | Stop tracing beyond this call depth. `None` for unlimited |
390
+ | `export_path` | `str` | `None` | Write trace to a file instead of stdout |
391
+ | `track_vars` | `bool` | `False` | Log local variable assignments inside the function (sync only) |
392
+
393
+ ### Global Functions
394
+
395
+ | Function | Description |
396
+ |---|---|
397
+ | `traceflow.enable()` | Enable all tracing (default state) |
398
+ | `traceflow.disable()` | Disable all tracing — decorated functions still run normally |
399
+ | `traceflow.is_enabled()` | Returns `True` if tracing is currently active |
400
+
401
+ ---
402
+
403
+ ## Author
404
+
405
+ **Aarav Agarwal**
406
+
407
+ ## License
408
+
409
+ All Rights Reserved.