retracesoftware-proxy 0.1.17__py3-none-any.whl → 0.1.19__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.
@@ -434,6 +434,9 @@
434
434
  "proxy_all_except": ["Error"]
435
435
  },
436
436
 
437
+ "_weakrefset": {
438
+ "sync_types": ["WeakSet", "_IterationGuard"]
439
+ },
437
440
  "_collections": {
438
441
  "sync_types": [
439
442
  "deque"
@@ -15,6 +15,7 @@ import gc
15
15
  import os
16
16
  import atexit
17
17
  import threading
18
+ from types import SimpleNamespace, MethodType
18
19
 
19
20
  from retracesoftware.install.typeutils import modify
20
21
  # from retracesoftware.proxy.immutabletypes import ImmutableTypes
@@ -479,7 +480,10 @@ class Patcher:
479
480
 
480
481
  if phase_updates:
481
482
  self.log('install.module.phase.results', list(phase_updates.keys()))
482
- updates |= phase_updates
483
+ for name,value in phase_updates.items():
484
+ if value is not None:
485
+ updates[name] = value
486
+ # updates |= phase_updates
483
487
 
484
488
  return updates
485
489
 
@@ -490,6 +494,9 @@ class Patcher:
490
494
 
491
495
  def patch_module_with_name(self, mod_name, module):
492
496
  with self.disable:
497
+
498
+ assert self.thread_state.value == 'disabled'
499
+
493
500
  self.log('install.module', mod_name)
494
501
 
495
502
  # self.system.log(f'patching module: {mod_name}')
@@ -517,7 +524,7 @@ class Patcher:
517
524
  self.post_commit(mod_name, updates)
518
525
 
519
526
  def __call__(self, module):
520
-
527
+
521
528
  if not hasattr(module, '__retrace__'):
522
529
 
523
530
  configs = list(self.configs(module))
@@ -608,28 +615,59 @@ def install(mode):
608
615
 
609
616
  importlib.invalidate_caches()
610
617
 
611
- with thread_state.select('internal'):
618
+ # with thread_state.select('internal'):
612
619
 
613
- atexit.register(lambda: at_exit)
614
-
615
- for key, module in list(sys.modules.items()):
616
- if not key.startswith('retracesoftware'):
617
- patcher(module)
620
+ atexit.register(lambda: at_exit)
621
+
622
+ for key, module in list(sys.modules.items()):
623
+ if not key.startswith('retracesoftware'):
624
+ patcher(module)
618
625
 
619
- for library in config.get('preload', []):
626
+ for library in config.get('preload', []):
627
+ with thread_state.select('internal'):
620
628
  importlib.import_module(library)
621
629
 
622
630
  importlib.invalidate_caches()
623
631
  # # if env_truthy('RETRACE_TRACE_CALLS'):
624
632
  # # trace_calls(system = retracesystem)
625
633
 
626
- thread_state.value = 'internal'
634
+ # thread_state.value = 'internal'
627
635
 
628
636
  # import threading
629
637
  # threading.current_thread().retrace = system
630
638
 
631
639
  threading.current_thread().__retrace__ = system
632
640
 
641
+ def is_entry_frame(frame):
642
+ return frame.globals.get("__name__", None) == "__main__"
643
+
644
+ original = atexit.register
645
+
646
+ def atexit_register(function):
647
+ if thread_state.value == 'internal':
648
+ return original(thread_state.wrap('internal', function))
649
+ else:
650
+ return original(function)
651
+
652
+ atexit.register = atexit_register
653
+
654
+ def disable_after_main(frame):
655
+ if is_entry_frame(frame):
656
+ # utils.intercept_frame_eval(None)
657
+ thread_state.value = 'internal'
658
+
659
+ def on_return():
660
+ thread_state.value = 'disabled'
661
+
662
+ obj = SimpleNamespace()
663
+ obj.on_return = on_return
664
+
665
+ return obj
666
+ else:
667
+ return disable_after_main
668
+
669
+ utils.intercept_frame_eval(disable_after_main)
670
+
633
671
  # utils.sigtrap(None)
634
672
 
635
673
  return system
@@ -13,6 +13,38 @@ def format_kwargs(kwargs):
13
13
 
14
14
  return tuple(result)
15
15
 
16
+ class CallTracer:
17
+
18
+ ignore = set([('abc', '__subclasscheck__'),
19
+ ('threading', '_shutdown'),
20
+ ('typing', 'inner')])
21
+
22
+ def __init__(self, writer, thread_state):
23
+ self.writer = writer
24
+ self.thread_state = thread_state
25
+
26
+ def on_result(self, result):
27
+ if type(result) in [str]:
28
+ self.writer(result)
29
+ else:
30
+ self.writer(str(type(result)))
31
+
32
+ def on_error(self, exc_type, exc_value, exc_traceback):
33
+ pass
34
+
35
+ def __call__(self, frame):
36
+ if self.thread_state.value == 'internal':
37
+ with self.thread_state.select('disabled'):
38
+ func = frame.function
39
+
40
+ key = (func.__module__, func.__name__)
41
+
42
+ if key not in CallTracer.ignore and func.__name__ != '__hash__':
43
+ self.writer(f'{func.__module__}.{func.__name__}')
44
+ return self
45
+ else:
46
+ return lambda *args, **kwargs: self(*args, **kwargs)
47
+
16
48
  class Tracer:
17
49
 
18
50
  def __init__(self, config, writer):
@@ -44,65 +76,66 @@ class Tracer:
44
76
 
45
77
  def trace_calls(self, thread_state):
46
78
  if 'tracecalls' in self.config:
47
- def on_call(frame):
48
- func = frame.function
79
+ # def on_call(frame):
80
+
81
+ # func = frame.function
49
82
 
50
- key = (func.__module__, func.__name__)
83
+ # key = (func.__module__, func.__name__)
51
84
 
52
- ignore = set(('abc', '__subclasscheck__'),
53
- ('threading', '_shutdown'))
85
+ # ignore = set([('abc', '__subclasscheck__'),
86
+ # ('threading', '_shutdown')])
54
87
 
55
- if key in ignore:
56
- print('About to throw!!!')
57
- raise Exception()
88
+ # if key in ignore:
89
+ # print('About to throw!!!')
90
+ # raise Exception()
58
91
 
59
- objtype = None
92
+ # objtype = None
60
93
 
61
- if 'self' in frame.locals:
62
- this = frame.locals['self']
63
- objtype = type(this)
94
+ # if 'self' in frame.locals:
95
+ # this = frame.locals['self']
96
+ # objtype = type(this)
64
97
 
65
- # if objtype:
66
- # print(f'Called!!!!: {func.__module__}.{objtype.__name__}.{func.__name__}')
67
- # else:
68
- # print(f'Called!!!!: {func.__module__}.{func.__name__}')
98
+ # # if objtype:
99
+ # # print(f'Called!!!!: {func.__module__}.{objtype.__name__}.{func.__name__}')
100
+ # # else:
101
+ # # print(f'Called!!!!: {func.__module__}.{func.__name__}')
69
102
 
70
- qualname = (func.__module__, objtype, func.__name__)
103
+ # qualname = (func.__module__, objtype, func.__name__)
71
104
 
72
- self.writer(f'{func.__module__}.{func.__name__}')
105
+ # self.writer(f'{func.__module__}.{func.__name__}')
73
106
 
74
- # if func.__name__ == '_path_stat':
75
- # utils.sigtrap('_path_stat start')
107
+ # # if func.__name__ == '_path_stat':
108
+ # # utils.sigtrap('_path_stat start')
76
109
 
77
- return qualname
110
+ # return qualname
78
111
 
79
- def on_result(qualname, res):
80
- mod, obj, func = qualname
112
+ # def on_result(qualname, res):
113
+ # mod, obj, func = qualname
81
114
 
82
- # if obj:
83
- # print(f'Returning!!!!: {mod}.{obj}.{func}')
84
- # else:
85
- # print(f'Returning!!!!: {mod}.{func}')
115
+ # # if obj:
116
+ # # print(f'Returning!!!!: {mod}.{obj}.{func}')
117
+ # # else:
118
+ # # print(f'Returning!!!!: {mod}.{func}')
86
119
 
87
- # if func == '_path_stat':
88
- # utils.sigtrap('_path_stat res')
120
+ # # if func == '_path_stat':
121
+ # # utils.sigtrap('_path_stat res')
89
122
 
90
- if func != '__hash__':
91
- ignore = set(('typing', 'inner'))
123
+ # if func != '__hash__':
124
+ # ignore = set(('typing', 'inner'))
92
125
 
93
- if qualname not in ignore:
94
- if type(res) in [str, int]:
95
- self.writer(res)
96
- else:
97
- self.writer(str(type(res)))
98
-
99
- def on_call_disabled(frame):
100
- func = frame.function
101
- print(f'disabled: {func.__module__}.{func.__name__}')
102
-
103
- utils.intercept_frame_eval(on_call = thread_state.dispatch(utils.noop, internal = thread_state.wrap('disabled', on_call)),
104
- on_result = thread_state.dispatch(utils.noop, internal = thread_state.wrap('disabled', on_result)))
126
+ # if qualname not in ignore:
127
+ # if type(res) in [str, int]:
128
+ # self.writer(res)
129
+ # else:
130
+ # self.writer(str(type(res)))
105
131
 
132
+ # def on_call_disabled(frame):
133
+ # func = frame.function
134
+ # print(f'disabled: {func.__module__}.{func.__name__}')
135
+
136
+ callback = CallTracer(writer = self.writer, thread_state = thread_state)
137
+ utils.intercept_frame_eval(callback)
138
+
106
139
  def serialize(self, obj):
107
140
  try:
108
141
  if obj is None: return None
@@ -35,6 +35,25 @@ class WithoutFlags:
35
35
  def __exit__(self, *args):
36
36
  utils.set_type_flags(self.cls, self.saved)
37
37
 
38
+ class WithFlags:
39
+
40
+ def __init__(self, cls , *flags):
41
+ self.cls = cls
42
+ self.flags = flags
43
+
44
+ def __enter__(self):
45
+ self.saved = utils.type_flags(self.cls)
46
+ flags = self.saved
47
+
48
+ for flag in self.flags:
49
+ flags |= utils.TypeFlags[flag]
50
+
51
+ utils.set_type_flags(self.cls, flags)
52
+ return self.cls
53
+
54
+ def __exit__(self, *args):
55
+ utils.set_type_flags(self.cls, self.saved)
56
+
38
57
  def add_flag(cls : type, flag):
39
58
  if isinstance(flag, str):
40
59
  flag = utils.TypeFlags[flag]
@@ -45,6 +64,7 @@ def add_flag(cls : type, flag):
45
64
  def modify(cls):
46
65
  return WithoutFlags(cls, "Py_TPFLAGS_IMMUTABLETYPE")
47
66
 
67
+
48
68
  def type_has_feature(cls, flag):
49
69
  if isinstance(flag, str):
50
70
  flag = utils.TypeFlags[flag]
@@ -5,7 +5,7 @@ from retracesoftware.proxy.gateway import adapter_pair
5
5
  from types import SimpleNamespace
6
6
  from retracesoftware.proxy.proxytype import *
7
7
  from retracesoftware.proxy.stubfactory import Stub
8
- from retracesoftware.install.typeutils import modify
8
+ from retracesoftware.install.typeutils import modify, WithFlags
9
9
 
10
10
  import sys
11
11
  import gc
@@ -166,8 +166,16 @@ class ProxySystem:
166
166
 
167
167
  def proxy_function(self, obj):
168
168
  return utils.wrapped_function(handler = self.ext_handler, target = obj)
169
-
169
+
170
+ def proxy__new__(self, *args, **kwargs):
171
+ return self.ext_handler(*args, **kwargs)
172
+
170
173
  def patchtype(self, cls):
174
+ if not utils.is_extendable(cls):
175
+ with WithFlags(cls, "Py_TPFLAGS_BASETYPE"):
176
+ assert utils.is_extendable(cls)
177
+ return self.patchtype(cls)
178
+
171
179
  if cls in self.immutable_types or issubclass(cls, tuple):
172
180
  return cls
173
181
 
@@ -184,39 +192,18 @@ class ProxySystem:
184
192
 
185
193
  return self.thread_state.dispatch(func, internal = new)
186
194
 
187
- # with modify(cls):
188
- # def update(name, f):
189
- # setattr(cls, name, f(getattr(cls, name)))
195
+ # slots = {'__module__': cls.__module__, '__slots__': []}
190
196
 
191
- # for name, value in superdict(cls).items():
192
- # if callable(value) and not is_instance_method(value):
193
- # update(name, wrap_new if name == '__new__' else wrap)
194
-
195
- # return cls
196
- if utils.is_extendable(cls):
197
- slots = {'__module__': cls.__module__, '__slots__': []}
197
+ extended = utils.extend_type(cls)
198
198
 
199
- extended = utils.extend_type(cls)
199
+ for name, value in superdict(cls).items():
200
+ if callable(value) and not is_instance_method(value):
201
+ setattr(extended, name, wrap_new(value) if name == '__new__' else wrap(value))
200
202
 
201
- for name, value in superdict(cls).items():
202
- if callable(value) and not is_instance_method(value):
203
- setattr(extended, name, wrap_new(value) if name == '__new__' else wrap(value))
203
+ # slots[name] = wrap_new(value) if name == '__new__' else wrap(value)
204
+ extended.__module__ = cls.__module__
204
205
 
205
- # slots[name] = wrap_new(value) if name == '__new__' else wrap(value)
206
- extended.__module__ = cls.__module__
207
-
208
- return extended
209
- # return type(cls.__name__, (cls,), slots)
210
-
211
- elif not utils.is_immutable(cls):
212
- def update(name, f):
213
- setattr(cls, name, f(getattr(cls, name)))
214
-
215
- for name, value in superdict(cls).items():
216
- if callable(value) and not is_instance_method(value):
217
- update(name, wrap_new if name == '__new__' else wrap)
218
- else:
219
- return wrap(cls)
206
+ return extended
220
207
 
221
208
  def __call__(self, obj):
222
209
  assert not isinstance(obj, BaseException)
@@ -154,12 +154,20 @@ class ReplayProxySystem(ProxySystem):
154
154
 
155
155
  return super().proxy_function(func)
156
156
 
157
+ def proxy__new__(self, __new__, *args, **kwargs):
158
+ func = functional.repeatedly(self.next_result)
159
+ func.__name__ = '__new__'
160
+ return super().proxy__new__(func, *args, **kwargs)
161
+
157
162
  def basetype(self, cls):
158
163
  return self.stub_factory.create_stubtype(StubRef(cls))
159
164
 
160
165
  def readnext(self):
161
166
  with self.thread_state.select('disabled'):
162
167
  try:
168
+ # obj = self.messages()
169
+ # print(f'read: {obj}')
170
+ # return obj
163
171
  return self.messages()
164
172
  except Exception as error:
165
173
  # print(f'Error reading stream: {error}')
@@ -222,7 +230,6 @@ class ReplayProxySystem(ProxySystem):
222
230
  print(f'on_thread_exit!!!!')
223
231
  self.reader.wake_pending()
224
232
 
225
-
226
233
  def __init__(self,
227
234
  thread_state,
228
235
  immutable_types,
@@ -234,7 +241,7 @@ class ReplayProxySystem(ProxySystem):
234
241
 
235
242
  self.reader = stream.reader(path,
236
243
  thread = thread_id,
237
- timeout_seconds = 5)
244
+ timeout_seconds = 60)
238
245
 
239
246
  self.bindings = utils.id_dict()
240
247
  # self.set_thread_id = utils.set_thread_id
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: retracesoftware_proxy
3
- Version: 0.1.17
3
+ Version: 0.1.19
4
4
  License: Apache-2.0
5
5
  Requires-Dist: retracesoftware_utils
6
6
  Requires-Dist: retracesoftware_functional
@@ -1,29 +1,29 @@
1
1
  retracesoftware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- retracesoftware/config.json,sha256=Nyk1Wt67_BJR-mVLoxk5Qwcf0X4z83vQ80rCBxUP03s,9182
2
+ retracesoftware/config.json,sha256=iy5d3441PtihMT2QH-ikTYdzlf8zfIcSyvtpsJK5tUQ,9261
3
3
  retracesoftware/config.yaml,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  retracesoftware/install/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  retracesoftware/install/config.py,sha256=EzE5ifQF2lo--hu2njI4T0FJ-zlnWDJV6i7x0DMkVTw,1364
6
6
  retracesoftware/install/edgecases.py,sha256=NR3lyvad9sRsyeDv_Ya8V4xMgPsMPOi9rMcnFOJGOEA,6330
7
7
  retracesoftware/install/globals.py,sha256=F8XvIoZQQ10gSRalk30dvdKllxlwxkaggYY6FogLDxY,510
8
8
  retracesoftware/install/install.py,sha256=HCD_ji8XCr96b5fNzNdL_8qcEp0Jf05Em7T6GA6u8HU,4969
9
- retracesoftware/install/patcher.py,sha256=7wYERlRNBwjwMtbUkCrhQI2b_V_C88aWNcnSTo9gr-E,20654
9
+ retracesoftware/install/patcher.py,sha256=Xzal6y9WZjLv5269PujaZx9ZCKb2Mbo5EBTI9qRA_Pk,21777
10
10
  retracesoftware/install/predicate.py,sha256=tX7NQc0rGkyyHYO3mduYHcJHbw1wczT53m_Dpkzo6do,2679
11
11
  retracesoftware/install/record.py,sha256=R2GOIA_WAggrNmVwZJh9r1xp-GVu43iKq-ykQ1VKEHE,3408
12
12
  retracesoftware/install/references.py,sha256=A-G651IDOfuo00MkbAdpbIQh_15ChvJ7uAVTSmE6zd4,1721
13
13
  retracesoftware/install/replay.py,sha256=VUiHvQK3mgAJEGmtE2TFs9kXzxdWtsjibEcGkhZVCVE,1830
14
- retracesoftware/install/tracer.py,sha256=Z1HTI74iczOjVI7sLOg8iEJ_-kMMUzC4ju_UMDyLipw,8009
15
- retracesoftware/install/typeutils.py,sha256=_a1PuwdCsYjG1Nkd77V-flqYtwbD4RkJVKn6Z-xABL4,1813
14
+ retracesoftware/install/tracer.py,sha256=MiaTPlUwcRbgL4CTNhvC4Y5mUhkb--Y7_icTPhscSmY,9014
15
+ retracesoftware/install/typeutils.py,sha256=-oFzgUfq_nHeOkj3YKZiMLlMzQhCedg3qymLiEJNkVE,2253
16
16
  retracesoftware/proxy/__init__.py,sha256=ntIyqKhBRkKEkcW_oOPodikh-mxYl8OXRnSaj-9-Xwc,178
17
17
  retracesoftware/proxy/gateway.py,sha256=xESohWXkiNm4ZutU0RgWUwxjxcBWRQ4rQyxIGQXv_F4,1590
18
18
  retracesoftware/proxy/globalref.py,sha256=yXtJsOeBHN9xoEgJWA3MJco-jD2SQUef_fDatA4A6rg,803
19
19
  retracesoftware/proxy/proxyfactory.py,sha256=qhOqDfMJnLDNkQs26JqDB431MwjjRhGQi8xupJ45asg,12272
20
- retracesoftware/proxy/proxysystem.py,sha256=6CxAaD_DJ-nDYemGbVnE5fY7Olwa56_oeF2o7XT1m2w,8535
20
+ retracesoftware/proxy/proxysystem.py,sha256=IicoTW06_axjJQqDVqZ8Pg3GeNUq1JsZc_fG58hCSK4,7968
21
21
  retracesoftware/proxy/proxytype.py,sha256=83y5rQRSts-5rLZu_k3tT90mwX2M-Ny6RZ91l-LTJ6k,13199
22
22
  retracesoftware/proxy/record.py,sha256=47vhAYIUrR2bWo-rQ9xU_Xyg3kNrA5Lqq4-8Cxg4-zg,5463
23
- retracesoftware/proxy/replay.py,sha256=bU657DOuvC4m2oWgTHbsQQPtruQzbvMXCKSyp6if9kI,9655
23
+ retracesoftware/proxy/replay.py,sha256=h5PKxG4KCgZP09zyp28fW3mE-RFX6HCmEMKPYL_kzcM,9967
24
24
  retracesoftware/proxy/stubfactory.py,sha256=eHlbzWR1LoQVkIRX1HoLPPQSOpYhOO_5R_p3buD4o7s,5256
25
25
  retracesoftware/proxy/thread.py,sha256=T1ME6DHB8O0xVnX3Rt1lMl7oCJ2Y0aoFT91D76yNICk,3073
26
- retracesoftware_proxy-0.1.17.dist-info/METADATA,sha256=w95GrRi2qFcPCAAu88JcPgQzhRf6pTSs96H_l_gR2RY,203
27
- retracesoftware_proxy-0.1.17.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
28
- retracesoftware_proxy-0.1.17.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
29
- retracesoftware_proxy-0.1.17.dist-info/RECORD,,
26
+ retracesoftware_proxy-0.1.19.dist-info/METADATA,sha256=NOPa-An94KcKOSi2HUGmv-dmZBlijYQogJMEJRJpeqs,203
27
+ retracesoftware_proxy-0.1.19.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
28
+ retracesoftware_proxy-0.1.19.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
29
+ retracesoftware_proxy-0.1.19.dist-info/RECORD,,