-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcollect_runtime_types.py
73 lines (62 loc) · 2.2 KB
/
collect_runtime_types.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import io
import json
import pdb
_in = io.StringIO("step")
_out = io.StringIO()
class Debugger(pdb.Pdb):
def __init__(self, *args, **kwargs):
self.identifiers = {}
self.all_identifiers = None
super().__init__(*args, **kwargs)
# super().__init__(stdin=_in, stdout=_out, *args, **kwargs)
def user_line(self, frame):
# Ignore internal Python identifiers
valid_identifiers = {
k: v
for k, v in frame.f_locals.items()
if (
not k.startswith("__")
and k
not in [
"io",
"json",
"pdb",
"_in",
"_out",
"Debugger",
"debugger",
"cmd",
"globals",
"locals",
]
)
}
# Collect local variable identifiers and their types
for identifier, value in valid_identifiers.items():
# Define the scope
if frame.f_code.co_name == "<module>":
scope = "global"
else:
scope = frame.f_code.co_name # function name
# Add line number, scope, and identifier to the identifiers
if f"{frame.f_lineno-1}" not in self.identifiers:
self.identifiers[frame.f_lineno - 1] = {}
if identifier not in self.identifiers[frame.f_lineno - 1]:
self.identifiers[frame.f_lineno - 1][identifier] = {
"identifier": identifier,
"context": scope,
"type": [type(value).__name__],
}
else:
print("###############################")
self.identifiers[frame.f_lineno - 1][identifier]["type"].append(
type(value).__name__
)
# self.do_step(None) # Continue execution
# self.onecmd("step")
# _in.write("")
# Run the debugger
debugger = Debugger()
debugger.run(open("test.py").read())
# Print the collected identifiers and their types
print(json.dumps(debugger.identifiers, indent=4, sort_keys=1))