retracesoftware-proxy 0.1.21__py3-none-any.whl → 0.2.0__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.
- retracesoftware/__main__.py +266 -0
- retracesoftware/autoenable.py +53 -0
- retracesoftware/config.json +19 -295
- retracesoftware/install/config.py +6 -0
- retracesoftware/install/edgecases.py +23 -1
- retracesoftware/install/patcher.py +93 -649
- retracesoftware/install/patchfindspec.py +117 -0
- retracesoftware/install/phases.py +338 -0
- retracesoftware/install/record.py +97 -37
- retracesoftware/install/replace.py +28 -0
- retracesoftware/install/replay.py +55 -11
- retracesoftware/install/tracer.py +87 -77
- retracesoftware/modules.toml +384 -0
- retracesoftware/proxy/messagestream.py +204 -0
- retracesoftware/proxy/proxysystem.py +283 -64
- retracesoftware/proxy/proxytype.py +34 -10
- retracesoftware/proxy/record.py +97 -64
- retracesoftware/proxy/replay.py +62 -219
- retracesoftware/proxy/serializer.py +28 -0
- retracesoftware/proxy/startthread.py +40 -0
- retracesoftware/proxy/stubfactory.py +42 -19
- retracesoftware/replay.py +104 -0
- retracesoftware/run.py +373 -0
- retracesoftware/stackdifference.py +133 -0
- {retracesoftware_proxy-0.1.21.dist-info → retracesoftware_proxy-0.2.0.dist-info}/METADATA +2 -1
- retracesoftware_proxy-0.2.0.dist-info/RECORD +41 -0
- retracesoftware_proxy-0.1.21.dist-info/RECORD +0 -29
- {retracesoftware_proxy-0.1.21.dist-info → retracesoftware_proxy-0.2.0.dist-info}/WHEEL +0 -0
- {retracesoftware_proxy-0.1.21.dist-info → retracesoftware_proxy-0.2.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import itertools
|
|
2
|
+
import inspect
|
|
3
|
+
import ast
|
|
4
|
+
from typing import Optional
|
|
5
|
+
import importlib
|
|
6
|
+
import retracesoftware.utils as utils
|
|
7
|
+
|
|
8
|
+
def frozen_to_module(name: str):
|
|
9
|
+
"""
|
|
10
|
+
Given a frozen filename like "<frozen importlib._bootstrap>",
|
|
11
|
+
return the actual module object (or None if not frozen).
|
|
12
|
+
"""
|
|
13
|
+
if not name.startswith("<frozen ") or not name.endswith(">"):
|
|
14
|
+
return None
|
|
15
|
+
|
|
16
|
+
# Extract the part between <frozen ...>
|
|
17
|
+
module_name = name[len("<frozen "):-1]
|
|
18
|
+
|
|
19
|
+
# Special case: the stdlib ships some as _frozen_importlib and _frozen_importlib_external
|
|
20
|
+
if module_name == "importlib._bootstrap":
|
|
21
|
+
return sys.modules.get("_frozen_importlib") or importlib._bootstrap
|
|
22
|
+
if module_name == "importlib._bootstrap_external":
|
|
23
|
+
return sys.modules.get("_frozen_importlib_external") or importlib._bootstrap_external
|
|
24
|
+
|
|
25
|
+
# Everything else is directly importable
|
|
26
|
+
return importlib.import_module(module_name)
|
|
27
|
+
|
|
28
|
+
def get_function_at_line(filename: str, source: str, lineno: int) -> Optional[str]:
|
|
29
|
+
"""
|
|
30
|
+
Return the name of the function (or class/method) that contains the given line number.
|
|
31
|
+
|
|
32
|
+
Returns None if:
|
|
33
|
+
- file not found
|
|
34
|
+
- syntax error
|
|
35
|
+
- line is outside any function (module level)
|
|
36
|
+
"""
|
|
37
|
+
# except FileNotFoundError:
|
|
38
|
+
# return None
|
|
39
|
+
# except UnicodeDecodeError:
|
|
40
|
+
# return None
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
tree = ast.parse(source, filename=filename)
|
|
44
|
+
except SyntaxError:
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
class FunctionFinder(ast.NodeVisitor):
|
|
48
|
+
def __init__(self, target_lineno: int):
|
|
49
|
+
self.target_lineno = target_lineno
|
|
50
|
+
self.current: Optional[str] = None
|
|
51
|
+
self.stack: list[str] = []
|
|
52
|
+
|
|
53
|
+
def visit_FunctionDef(self, node):
|
|
54
|
+
if node.lineno <= self.target_lineno <= node.end_lineno:
|
|
55
|
+
# breakpoint()
|
|
56
|
+
self.stack.append(node.name)
|
|
57
|
+
self.current = node.name
|
|
58
|
+
self.generic_visit(node)
|
|
59
|
+
self.stack.pop()
|
|
60
|
+
elif self.stack:
|
|
61
|
+
# We're inside a nested function/class, keep traversing
|
|
62
|
+
self.generic_visit(node)
|
|
63
|
+
|
|
64
|
+
def visit_AsyncFunctionDef(self, node):
|
|
65
|
+
self.visit_FunctionDef(node) # same logic
|
|
66
|
+
|
|
67
|
+
def visit_ClassDef(self, node):
|
|
68
|
+
if node.lineno <= self.target_lineno <= node.end_lineno:
|
|
69
|
+
self.stack.append(node.name)
|
|
70
|
+
# Don't set current here — we prefer method names
|
|
71
|
+
self.generic_visit(node)
|
|
72
|
+
self.stack.pop()
|
|
73
|
+
|
|
74
|
+
# def get_result(self) -> Optional[str]:
|
|
75
|
+
# if not self.stack:
|
|
76
|
+
# return None
|
|
77
|
+
# # Return the deepest (most specific) function/method name
|
|
78
|
+
# return self.current
|
|
79
|
+
# # return self.stack[-1]
|
|
80
|
+
|
|
81
|
+
finder = FunctionFinder(lineno)
|
|
82
|
+
finder.visit(tree)
|
|
83
|
+
# print(f'foind: {finder.current}')
|
|
84
|
+
return finder.current
|
|
85
|
+
|
|
86
|
+
def get_source(filename):
|
|
87
|
+
try:
|
|
88
|
+
with open(filename, "r", encoding="utf-8") as f:
|
|
89
|
+
return f.read()
|
|
90
|
+
except FileNotFoundError:
|
|
91
|
+
return inspect.getsource(frozen_to_module(filename))
|
|
92
|
+
|
|
93
|
+
def all_elements_same(t):
|
|
94
|
+
return len(set(t)) <= 1
|
|
95
|
+
|
|
96
|
+
def first(coll): return coll[0]
|
|
97
|
+
|
|
98
|
+
def common_prefix(*colls):
|
|
99
|
+
return list(map(first, itertools.takewhile(all_elements_same, zip(*colls))))
|
|
100
|
+
|
|
101
|
+
def render_stack(frames):
|
|
102
|
+
for filename,lineno in frames:
|
|
103
|
+
try:
|
|
104
|
+
source = get_source(filename)
|
|
105
|
+
print(f'File "{filename}", line {lineno}, in {get_function_at_line(filename, source, lineno)}')
|
|
106
|
+
print(f' {source.splitlines()[lineno - 1].lstrip()}')
|
|
107
|
+
except Exception:
|
|
108
|
+
print(f'File not found: "{filename}", line {lineno}')
|
|
109
|
+
|
|
110
|
+
def on_stack_difference(previous, record, replay):
|
|
111
|
+
|
|
112
|
+
# previous = [x for x in previous if x not in excludes]
|
|
113
|
+
# record = [x for x in record if x not in excludes]
|
|
114
|
+
# replay = [x for x in replay if x not in excludes]
|
|
115
|
+
|
|
116
|
+
if record != replay:
|
|
117
|
+
common = common_prefix(previous, record, replay) if previous else common_prefix(record, replay)
|
|
118
|
+
|
|
119
|
+
if common:
|
|
120
|
+
print('Common root:')
|
|
121
|
+
render_stack(common)
|
|
122
|
+
|
|
123
|
+
if previous:
|
|
124
|
+
print('\nlast matching:')
|
|
125
|
+
render_stack(previous[len(common):])
|
|
126
|
+
|
|
127
|
+
print('\nrecord:')
|
|
128
|
+
render_stack(record[len(common):])
|
|
129
|
+
|
|
130
|
+
print('\nreplay:')
|
|
131
|
+
render_stack(replay[len(common):])
|
|
132
|
+
|
|
133
|
+
utils.sigtrap('on_stack_difference!!!!!')
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
retracesoftware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
retracesoftware/__main__.py,sha256=legPSoOYPrfnB_t2v5NsdGuoBXjFRd8qub98QRXCtFM,8408
|
|
3
|
+
retracesoftware/autoenable.py,sha256=s7dSykM0y3xVqRzrWouGgoed4-lMNRhdA7Gnm1f04NA,1772
|
|
4
|
+
retracesoftware/config.json,sha256=Cw5YZCfTo8GLmtbTH2LYwST7wNe7925DAwsTtRIGhBE,3817
|
|
5
|
+
retracesoftware/config.yaml,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
retracesoftware/modules.toml,sha256=C3O4LnHwWInRT9ZSB-crSM8Q98vYCZSFJB3akGJLfVM,14536
|
|
7
|
+
retracesoftware/replay.py,sha256=rKuhen_MDDi_5WVDmQgchxJ0ZrCbYL1yZZboZsu_q54,3601
|
|
8
|
+
retracesoftware/run.py,sha256=ovunjJjDAe23ik-KbYrLUseb9u2bZ26uZNg-QIPENMc,11966
|
|
9
|
+
retracesoftware/stackdifference.py,sha256=nM9r5YHMCNQcrWozMjUX4ZTrZL5U0rQChSGzpiXy_DU,4466
|
|
10
|
+
retracesoftware/install/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
retracesoftware/install/config.py,sha256=AnSlHI3lWQrPUg0fOS26PqXiq1hJSy56SwrNL8mbAG8,1546
|
|
12
|
+
retracesoftware/install/edgecases.py,sha256=zv6xjUFoiuNWeBhIDIKb7kN6DVv8gxoG797sNV2ak8Y,7099
|
|
13
|
+
retracesoftware/install/globals.py,sha256=F8XvIoZQQ10gSRalk30dvdKllxlwxkaggYY6FogLDxY,510
|
|
14
|
+
retracesoftware/install/install.py,sha256=HCD_ji8XCr96b5fNzNdL_8qcEp0Jf05Em7T6GA6u8HU,4969
|
|
15
|
+
retracesoftware/install/patcher.py,sha256=sHgsKvdvjMJSVl8lOa3YiCjGf6zYhxgkWp67-ptJvlk,4157
|
|
16
|
+
retracesoftware/install/patchfindspec.py,sha256=uQkfdOQOY20hFAcwDAqx7m8rbtGM2rBKOfC3Szb1zhw,4942
|
|
17
|
+
retracesoftware/install/phases.py,sha256=OWaw86xzC924tdIA9C-12Qdr3sCx67hEOn-Ih9FM--4,9359
|
|
18
|
+
retracesoftware/install/predicate.py,sha256=tX7NQc0rGkyyHYO3mduYHcJHbw1wczT53m_Dpkzo6do,2679
|
|
19
|
+
retracesoftware/install/record.py,sha256=08q7zc9cfyCyhLsh15q1d_5vFIhKbs9ln6VvL6kED5o,5861
|
|
20
|
+
retracesoftware/install/references.py,sha256=A-G651IDOfuo00MkbAdpbIQh_15ChvJ7uAVTSmE6zd4,1721
|
|
21
|
+
retracesoftware/install/replace.py,sha256=FYiSJtNrXEhl-H6M5tJm0kbliBA0sZdxE0306pr-YQg,872
|
|
22
|
+
retracesoftware/install/replay.py,sha256=bB2eMpIP2vXZzeJ98jtlkGSE1DEYWk3olUbiBQcdVj0,3539
|
|
23
|
+
retracesoftware/install/tracer.py,sha256=GO3Nnzd0ylxM7-A7RN0LzLCFdouJIiHtIcJ2zjFx0Q0,9363
|
|
24
|
+
retracesoftware/install/typeutils.py,sha256=-oFzgUfq_nHeOkj3YKZiMLlMzQhCedg3qymLiEJNkVE,2253
|
|
25
|
+
retracesoftware/proxy/__init__.py,sha256=ntIyqKhBRkKEkcW_oOPodikh-mxYl8OXRnSaj-9-Xwc,178
|
|
26
|
+
retracesoftware/proxy/gateway.py,sha256=xESohWXkiNm4ZutU0RgWUwxjxcBWRQ4rQyxIGQXv_F4,1590
|
|
27
|
+
retracesoftware/proxy/globalref.py,sha256=yXtJsOeBHN9xoEgJWA3MJco-jD2SQUef_fDatA4A6rg,803
|
|
28
|
+
retracesoftware/proxy/messagestream.py,sha256=kjxIugCSr7YSJbIqsqqXeW7dyE2SzWow2E-UJnkAflk,5890
|
|
29
|
+
retracesoftware/proxy/proxyfactory.py,sha256=qhOqDfMJnLDNkQs26JqDB431MwjjRhGQi8xupJ45asg,12272
|
|
30
|
+
retracesoftware/proxy/proxysystem.py,sha256=Pj9sk5FE3Mfyf4-PAtXSz2Pvr_GwXcpfhUSJvkz00dg,15076
|
|
31
|
+
retracesoftware/proxy/proxytype.py,sha256=LZ1rNMsxXRUMdI4uTzDvGkUyPOYxCFroT_ZAtOGTbBk,14012
|
|
32
|
+
retracesoftware/proxy/record.py,sha256=JTmeZ13ISbsVal1WOtae425DP0iA-QiAv0C6azPpV8k,6680
|
|
33
|
+
retracesoftware/proxy/replay.py,sha256=Kx4XrsP0T35IvTzf3pwhR24Lotoz43p7E8LBevEQHpE,4948
|
|
34
|
+
retracesoftware/proxy/serializer.py,sha256=S5yhHoP2iYaXBY7Jr8Ei630Z31521x0IO6DeuClOD9s,958
|
|
35
|
+
retracesoftware/proxy/startthread.py,sha256=YKUcOSjA-9_5ZsDHhyP0fXJSP3RWDKV-ajX-I0SI-bU,1270
|
|
36
|
+
retracesoftware/proxy/stubfactory.py,sha256=fyQtCZnkXvLaTlGcxE0Lx8od09ZOgnPWPn0YvNFfVeQ,6219
|
|
37
|
+
retracesoftware/proxy/thread.py,sha256=T1ME6DHB8O0xVnX3Rt1lMl7oCJ2Y0aoFT91D76yNICk,3073
|
|
38
|
+
retracesoftware_proxy-0.2.0.dist-info/METADATA,sha256=AgcbtJte96VMAlP8jBHZmX7pRsqJd5lcUCR_zzAtTxs,226
|
|
39
|
+
retracesoftware_proxy-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
40
|
+
retracesoftware_proxy-0.2.0.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
|
|
41
|
+
retracesoftware_proxy-0.2.0.dist-info/RECORD,,
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
retracesoftware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
retracesoftware/config.json,sha256=iy5d3441PtihMT2QH-ikTYdzlf8zfIcSyvtpsJK5tUQ,9261
|
|
3
|
-
retracesoftware/config.yaml,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
retracesoftware/install/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
retracesoftware/install/config.py,sha256=EzE5ifQF2lo--hu2njI4T0FJ-zlnWDJV6i7x0DMkVTw,1364
|
|
6
|
-
retracesoftware/install/edgecases.py,sha256=NR3lyvad9sRsyeDv_Ya8V4xMgPsMPOi9rMcnFOJGOEA,6330
|
|
7
|
-
retracesoftware/install/globals.py,sha256=F8XvIoZQQ10gSRalk30dvdKllxlwxkaggYY6FogLDxY,510
|
|
8
|
-
retracesoftware/install/install.py,sha256=HCD_ji8XCr96b5fNzNdL_8qcEp0Jf05Em7T6GA6u8HU,4969
|
|
9
|
-
retracesoftware/install/patcher.py,sha256=XwpySyqaop3bnLc8ewtowxLchAC0mOtXWDfmk5zTE_s,22195
|
|
10
|
-
retracesoftware/install/predicate.py,sha256=tX7NQc0rGkyyHYO3mduYHcJHbw1wczT53m_Dpkzo6do,2679
|
|
11
|
-
retracesoftware/install/record.py,sha256=mjk4bien8uWp8c-vWNw3Y4BRR5xO4AWsZi1aodkW5yc,3590
|
|
12
|
-
retracesoftware/install/references.py,sha256=A-G651IDOfuo00MkbAdpbIQh_15ChvJ7uAVTSmE6zd4,1721
|
|
13
|
-
retracesoftware/install/replay.py,sha256=36x40dk8pCmVjHz8zKd2OLY3B7UkP0NEb-1V1X8o3Rg,1992
|
|
14
|
-
retracesoftware/install/tracer.py,sha256=MiaTPlUwcRbgL4CTNhvC4Y5mUhkb--Y7_icTPhscSmY,9014
|
|
15
|
-
retracesoftware/install/typeutils.py,sha256=-oFzgUfq_nHeOkj3YKZiMLlMzQhCedg3qymLiEJNkVE,2253
|
|
16
|
-
retracesoftware/proxy/__init__.py,sha256=ntIyqKhBRkKEkcW_oOPodikh-mxYl8OXRnSaj-9-Xwc,178
|
|
17
|
-
retracesoftware/proxy/gateway.py,sha256=xESohWXkiNm4ZutU0RgWUwxjxcBWRQ4rQyxIGQXv_F4,1590
|
|
18
|
-
retracesoftware/proxy/globalref.py,sha256=yXtJsOeBHN9xoEgJWA3MJco-jD2SQUef_fDatA4A6rg,803
|
|
19
|
-
retracesoftware/proxy/proxyfactory.py,sha256=qhOqDfMJnLDNkQs26JqDB431MwjjRhGQi8xupJ45asg,12272
|
|
20
|
-
retracesoftware/proxy/proxysystem.py,sha256=zXrK4eMBJHZlmRJ2pQMltzYHF5CjnAZV6Z_teGH6DO8,8071
|
|
21
|
-
retracesoftware/proxy/proxytype.py,sha256=83y5rQRSts-5rLZu_k3tT90mwX2M-Ny6RZ91l-LTJ6k,13199
|
|
22
|
-
retracesoftware/proxy/record.py,sha256=AsoVhuTX0pVVAqOih9-Mgh54psyggqfAXwAYYwy7umM,5818
|
|
23
|
-
retracesoftware/proxy/replay.py,sha256=mMb3jiCPS8W-Nev1JMaBIQSxRjV1sKTJYRPWAurw4i0,10264
|
|
24
|
-
retracesoftware/proxy/stubfactory.py,sha256=eHlbzWR1LoQVkIRX1HoLPPQSOpYhOO_5R_p3buD4o7s,5256
|
|
25
|
-
retracesoftware/proxy/thread.py,sha256=T1ME6DHB8O0xVnX3Rt1lMl7oCJ2Y0aoFT91D76yNICk,3073
|
|
26
|
-
retracesoftware_proxy-0.1.21.dist-info/METADATA,sha256=VgiJFRiDUgZhUA5wfe4TLOD62q0y2Dvu3jCGGuR2t4s,203
|
|
27
|
-
retracesoftware_proxy-0.1.21.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
28
|
-
retracesoftware_proxy-0.1.21.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
|
|
29
|
-
retracesoftware_proxy-0.1.21.dist-info/RECORD,,
|
|
File without changes
|
{retracesoftware_proxy-0.1.21.dist-info → retracesoftware_proxy-0.2.0.dist-info}/top_level.txt
RENAMED
|
File without changes
|