atrace 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl

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.
atrace/__init__.py CHANGED
@@ -1,2 +1,101 @@
1
- def hello() -> str:
2
- return "Hello from atrace!"
1
+ import copy
2
+ import inspect
3
+ import sys
4
+ from types import FrameType
5
+ from typing import Any
6
+
7
+ paused = True
8
+ last_locals = {}
9
+
10
+ ignored_variables = set(
11
+ [
12
+ "tid",
13
+ ]
14
+ )
15
+
16
+
17
+ def ignore_variable(var: str):
18
+ return var in ignored_variables
19
+
20
+
21
+ def copy_carefully_using_ignored_variables(d: dict[str, Any]):
22
+ res = {}
23
+ for k, v in d.items():
24
+ if not ignore_variable(k):
25
+ res[k] = copy.deepcopy(v)
26
+ return res
27
+
28
+
29
+ def copy_carefully(d: dict[str, Any]):
30
+ res = {}
31
+ for k, v in d.items():
32
+ try:
33
+ v_copy = copy.deepcopy(v)
34
+ except:
35
+ v_copy = v
36
+ res[k] = v_copy
37
+ return res
38
+
39
+
40
+ def trace_vars(frame: FrameType, event: str, arg: Any):
41
+ if paused:
42
+ return
43
+ # print(frame.f_lineno, frame.f_code.co_name, frame.f_locals, event)
44
+ if event != "line":
45
+ return trace_vars
46
+ code = frame.f_code
47
+ lineno = frame.f_lineno
48
+ locals_now = copy_carefully(frame.f_locals)
49
+ global last_locals
50
+
51
+ if last_locals is None: # We're being unloaded, it's the end of the program
52
+ return None
53
+
54
+ if code.co_name not in last_locals:
55
+ last_locals[code.co_name] = locals_now
56
+ return trace_vars
57
+
58
+ old_locals = last_locals[code.co_name]
59
+
60
+ for var, new_val in locals_now.items():
61
+ if not ignore_variable(var):
62
+ if var not in old_locals:
63
+ print(f"[{lineno}] NEW {var} = {new_val}")
64
+ elif old_locals[var] != new_val:
65
+ print(f"[{lineno}] MODIFIED {var}: {old_locals[var]} → {new_val}")
66
+
67
+ for var in old_locals:
68
+ if not ignore_variable(var):
69
+ if var not in locals_now:
70
+ print(f"[{lineno}] DELETED {var}")
71
+
72
+ last_locals[code.co_name] = locals_now
73
+ return trace_vars
74
+
75
+
76
+ def just_kicking_off(frame: FrameType, event: str, arg: Any):
77
+ return None
78
+
79
+
80
+ def get_importer_frame():
81
+ # Get the current call stack
82
+ for frame_info in inspect.stack():
83
+ # Filter out internal importlib frames and the current module's frame
84
+ filename = frame_info.filename
85
+ if not filename.startswith("<") and filename != __file__:
86
+ return frame_info.frame
87
+ return None
88
+
89
+
90
+ # This will work next time we enter a function.
91
+ # It also kicks off the tracing machinery (so that the lines below work)
92
+ sys.settrace(trace_vars)
93
+
94
+
95
+ # This reaches into the importing module's frame to setup tracing
96
+ importer_frame = get_importer_frame()
97
+ if importer_frame:
98
+ importer_frame.f_trace = trace_vars
99
+ paused = False
100
+ else:
101
+ print("Cannot trace")
@@ -0,0 +1,65 @@
1
+ Metadata-Version: 2.4
2
+ Name: atrace
3
+ Version: 0.1.1
4
+ Summary: Generate trace tables for programs
5
+ Project-URL: Repository, https://github.com/nwolff/atrace.git
6
+ Author-email: Nicholas Wolff <nwolff@gmail.com>
7
+ Requires-Python: >=3.7
8
+ Description-Content-Type: text/markdown
9
+
10
+ # TODO:
11
+
12
+ - entering a function, binding the local arguments, returning
13
+ - ignore function definitions (look at the type of object)
14
+
15
+ - display at end only
16
+
17
+ # Usage and intent
18
+
19
+ A package that automatically prints a trace table of a program, just by importing the module
20
+
21
+ - Should not interfere with the running program (apart from capturing stdout)
22
+ - Should display the trace at the end of execution (not while the program is interacting with the user)
23
+ - Should display the trace even if an exception interrupts the program
24
+ - Should display the trace even if the user interrupts the program
25
+ - Should handle mutations to objects like lists
26
+ - Should handle functions properly:
27
+ - entering the function
28
+ - binding the local arguments
29
+ - returning
30
+
31
+ An animated example of a trace table: https://www.101computing.net/using-trace-tables/
32
+
33
+ # Not in scope
34
+
35
+ - Multithreaded programs
36
+
37
+ # Implementation
38
+
39
+ To trace variables :
40
+
41
+ - Either https://docs.python.org/3/library/sys.html#sys.settrace
42
+ - Or https://docs.python.org/3/library/trace.html
43
+
44
+ To capture stdout :
45
+
46
+ - Either https://docs.python.org/3/library/contextlib.html#contextlib.redirect_stdout
47
+ - Or just reassign stdout
48
+
49
+ To trap sigint:
50
+
51
+ - https://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python
52
+
53
+ # Build
54
+
55
+ Automatically deployed to pypi every time a new tag is pushed: https://pypi.org/project/atrace/
56
+
57
+ # Technical Refs
58
+
59
+ - First similar thing I found, doesn't work (chokes on deep copying some variables): https://github.com/DarshanLakshman/PyTracerTool
60
+
61
+ - 11 years old, doesn't work: https://github.com/mihneadb/python-execution-trace
62
+
63
+ - A hot mess: https://stackoverflow.com/questions/1645028/trace-table-for-python-programs
64
+
65
+ - A tutorial on the trace module: https://pymotw.com/2/trace/
@@ -0,0 +1,5 @@
1
+ atrace/__init__.py,sha256=wUmeppysEV7VYt8ZpVnhX9IL_Pec_50FjGqHmS5gEwc,2550
2
+ atrace/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ atrace-0.1.1.dist-info/METADATA,sha256=4oknmUUp4BvNtji0hRV121JKvtkjC2BOO6pt9zPqDgI,2026
4
+ atrace-0.1.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
5
+ atrace-0.1.1.dist-info/RECORD,,
@@ -1,5 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: atrace
3
- Version: 0.1.0
4
- Author-email: Nicholas Wolff <nwolff@gmail.com>
5
- Requires-Python: >=3.7
@@ -1,5 +0,0 @@
1
- atrace/__init__.py,sha256=aT0BUPvWpbdoOpN9gOZcLNFxgENSl-ptao0487nheGE,52
2
- atrace/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- atrace-0.1.0.dist-info/METADATA,sha256=P1Ej3l3jeT-SKZnSNzwb-zH7q9cwCW_7mf6DiIrWM0I,121
4
- atrace-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
5
- atrace-0.1.0.dist-info/RECORD,,
File without changes