retracesoftware-proxy 0.1.16__py3-none-any.whl → 0.1.18__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.
@@ -12,6 +12,7 @@
12
12
  "tracing_levels": {
13
13
  "none": [],
14
14
  "all": [
15
+ "tracecalls",
15
16
  "proxy.ext.disabled.call",
16
17
  "proxy.int.disabled.call",
17
18
  "proxy.wrapping.new",
@@ -157,8 +158,10 @@
157
158
 
158
159
  "modules": {
159
160
  "_frozen_importlib_external": {
160
- "with_state": {
161
- "disabled": ["_path_stat"]
161
+ "comment": {
162
+ "with_state": {
163
+ "disabled": ["_path_stat"]
164
+ }
162
165
  }
163
166
  },
164
167
  "_imp": {
@@ -246,16 +249,12 @@
246
249
  "builtins": {
247
250
  "patch_hash": ["object"],
248
251
 
249
- "with_state": {
250
- "disabled": ["__import__"]
251
- },
252
-
253
252
  "comment": {
254
- "replace": {
255
- "set": "retracesoftware_utils.set",
256
- "frozenset": "retracesoftware_utils.frozenset"
253
+ "with_state": {
254
+ "disabled": ["__import__"]
257
255
  }
258
256
  },
257
+
259
258
  "immutable_types": [
260
259
  "BaseException",
261
260
  "memoryview",
@@ -308,7 +307,9 @@
308
307
  ]
309
308
  },
310
309
  "io": {
311
- "proxy": ["open_code", "open"],
310
+ "comment": {
311
+ "proxy": ["open_code", "open"]
312
+ },
312
313
  "path_predicates": {
313
314
  "open_code": "path",
314
315
  "open": "file"
@@ -90,6 +90,9 @@ def resolve(path):
90
90
  # for prop in properties:
91
91
  # self.system.add_sync(getattr(inst, prop))
92
92
 
93
+ def replace(replacements, coll):
94
+ return map(lambda x: replacements.get(x, x), coll)
95
+
93
96
  def container_replace(container, old, new):
94
97
  if isinstance(container, dict):
95
98
  if old in container:
@@ -333,9 +336,10 @@ class Patcher:
333
336
  @patch
334
337
  def patch_exec(self, exec):
335
338
 
336
- def exec_wrapper2(source, *args,**kwargs):
339
+ def exec_wrapper2(source, globals = None, locals = None):
337
340
  if isinstance(source, types.CodeType) and source.co_name == '<module>':
338
- self(inspect.getmodule(source))
341
+ module = sys.modules[globals['__name__']]
342
+ self(module)
339
343
 
340
344
  def first(x): return x[0]
341
345
 
@@ -475,7 +479,10 @@ class Patcher:
475
479
 
476
480
  if phase_updates:
477
481
  self.log('install.module.phase.results', list(phase_updates.keys()))
478
- updates |= phase_updates
482
+ for name,value in phase_updates.items():
483
+ if value is not None:
484
+ updates[name] = value
485
+ # updates |= phase_updates
479
486
 
480
487
  return updates
481
488
 
@@ -486,7 +493,10 @@ class Patcher:
486
493
 
487
494
  def patch_module_with_name(self, mod_name, module):
488
495
  with self.disable:
489
- print(f'Patching: {module}')
496
+
497
+ if mod_name == 'selectors':
498
+ print('DWFEWFW!!!!!!!!!')
499
+
490
500
 
491
501
  self.log('install.module', mod_name)
492
502
 
@@ -504,6 +514,10 @@ class Patcher:
504
514
  for ref in gc.get_referrers(value):
505
515
  if ref is not originals:
506
516
  container_replace(container = ref, old = value, new = updates[name])
517
+ if isinstance(updates[name], type) and isinstance(value, type) and issubclass(updates[name], value):
518
+ for subclass in value.__subclasses__():
519
+ if subclass not in updates.values():
520
+ subclass.__bases__ = tuple(replace({value: updates[name]}, subclass.__bases__))
507
521
 
508
522
  module.__retrace__ = originals
509
523
 
@@ -511,13 +525,9 @@ class Patcher:
511
525
  self.post_commit(mod_name, updates)
512
526
 
513
527
  def __call__(self, module):
514
-
515
- print(f'patcher called with: {module} {self.thread_state.value}')
516
-
528
+
517
529
  if not hasattr(module, '__retrace__'):
518
530
 
519
- print(f'patcher called with: {module} 1')
520
-
521
531
  configs = list(self.configs(module))
522
532
 
523
533
  if len(configs) > 0:
@@ -604,6 +614,8 @@ def install(mode):
604
614
 
605
615
  # print(f'MODULES: {list(sys.modules.keys())}')
606
616
 
617
+ importlib.invalidate_caches()
618
+
607
619
  with thread_state.select('internal'):
608
620
 
609
621
  atexit.register(lambda: at_exit)
@@ -615,6 +627,7 @@ def install(mode):
615
627
  for library in config.get('preload', []):
616
628
  importlib.import_module(library)
617
629
 
630
+ importlib.invalidate_caches()
618
631
  # # if env_truthy('RETRACE_TRACE_CALLS'):
619
632
  # # trace_calls(system = retracesystem)
620
633
 
@@ -4,6 +4,7 @@ from retracesoftware.proxy.proxytype import Proxy
4
4
 
5
5
  import types
6
6
  import os
7
+ import sys
7
8
 
8
9
  def format_kwargs(kwargs):
9
10
  result = []
@@ -41,6 +42,67 @@ class Tracer:
41
42
  print(f'systrace RAISED ERROR!')
42
43
  raise
43
44
 
45
+ def trace_calls(self, thread_state):
46
+ if 'tracecalls' in self.config:
47
+ def on_call(frame):
48
+ func = frame.function
49
+
50
+ key = (func.__module__, func.__name__)
51
+
52
+ ignore = set(('abc', '__subclasscheck__'),
53
+ ('threading', '_shutdown'))
54
+
55
+ if key in ignore:
56
+ print('About to throw!!!')
57
+ raise Exception()
58
+
59
+ objtype = None
60
+
61
+ if 'self' in frame.locals:
62
+ this = frame.locals['self']
63
+ objtype = type(this)
64
+
65
+ # if objtype:
66
+ # print(f'Called!!!!: {func.__module__}.{objtype.__name__}.{func.__name__}')
67
+ # else:
68
+ # print(f'Called!!!!: {func.__module__}.{func.__name__}')
69
+
70
+ qualname = (func.__module__, objtype, func.__name__)
71
+
72
+ self.writer(f'{func.__module__}.{func.__name__}')
73
+
74
+ # if func.__name__ == '_path_stat':
75
+ # utils.sigtrap('_path_stat start')
76
+
77
+ return qualname
78
+
79
+ def on_result(qualname, res):
80
+ mod, obj, func = qualname
81
+
82
+ # if obj:
83
+ # print(f'Returning!!!!: {mod}.{obj}.{func}')
84
+ # else:
85
+ # print(f'Returning!!!!: {mod}.{func}')
86
+
87
+ # if func == '_path_stat':
88
+ # utils.sigtrap('_path_stat res')
89
+
90
+ if func != '__hash__':
91
+ ignore = set(('typing', 'inner'))
92
+
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)))
105
+
44
106
  def serialize(self, obj):
45
107
  try:
46
108
  if obj is None: return None
@@ -82,14 +144,14 @@ class Tracer:
82
144
  def checkpoint(self, obj):
83
145
  self.writer(obj)
84
146
 
85
- def stacktrace(self):
86
- self.writer('stacktrace', utils.stacktrace())
147
+ # def stacktrace(self):
148
+ # self.writer('stacktrace', utils.stacktrace())
87
149
 
88
150
  def __call__(self, name, func = None):
89
151
  if name in self.config:
90
152
  if name.endswith('.call'):
91
153
  def write_call(*args, **kwargs):
92
- self.stacktrace()
154
+ # self.stacktrace()
93
155
  if len(args) > 0:
94
156
  self.writer(name, args[0].__name__, args[1:], kwargs)
95
157
  else:
@@ -126,11 +188,11 @@ class Tracer:
126
188
 
127
189
  return wrapper
128
190
 
129
- elif name.endswith('.stack'):
130
- def write_event(*args, **kwargs):
131
- self.writer(name, utils.stacktrace())
191
+ # elif name.endswith('.stack'):
192
+ # def write_event(*args, **kwargs):
193
+ # self.writer(name, utils.stacktrace())
132
194
 
133
- return functional.firstof(write_event, func) if func else write_event
195
+ # return functional.firstof(write_event, func) if func else write_event
134
196
 
135
197
 
136
198
  return func
@@ -5,6 +5,8 @@ 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
9
+
8
10
  import sys
9
11
  import gc
10
12
 
@@ -115,6 +117,8 @@ class ProxySystem:
115
117
  func = self.thread_state.dispatch(lambda *args: None, internal = func)
116
118
  sys.settrace(func)
117
119
 
120
+ tracer.trace_calls(thread_state)
121
+
118
122
  def new_child_path(self, path):
119
123
  return path.parent / f'fork-{self.fork_counter}' / path.name
120
124
 
@@ -152,7 +156,8 @@ class ProxySystem:
152
156
  breakpoint()
153
157
 
154
158
  proxytype = dynamic_proxytype(handler = self.ext_dispatch, cls = cls)
155
-
159
+ proxytype.__retrace_source__ = 'external'
160
+
156
161
  if self.on_proxytype: self.on_proxytype(proxytype)
157
162
 
158
163
  return proxytype
@@ -163,13 +168,10 @@ class ProxySystem:
163
168
  return utils.wrapped_function(handler = self.ext_handler, target = obj)
164
169
 
165
170
  def patchtype(self, cls):
166
- print(f'Proxying type: {cls}')
167
-
168
171
  if cls in self.immutable_types or issubclass(cls, tuple):
169
172
  return cls
170
173
 
171
174
  def wrap(func):
172
- print(f'Wrapping: {cls.__name__}.{func.__name__}')
173
175
  return self.thread_state.dispatch(func, internal = self.proxy_function(func))
174
176
 
175
177
  def wrap_new(func):
@@ -182,14 +184,29 @@ class ProxySystem:
182
184
 
183
185
  return self.thread_state.dispatch(func, internal = new)
184
186
 
187
+ # with modify(cls):
188
+ # def update(name, f):
189
+ # setattr(cls, name, f(getattr(cls, name)))
190
+
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
185
196
  if utils.is_extendable(cls):
186
197
  slots = {'__module__': cls.__module__, '__slots__': []}
187
198
 
199
+ extended = utils.extend_type(cls)
200
+
188
201
  for name, value in superdict(cls).items():
189
202
  if callable(value) and not is_instance_method(value):
190
- slots[name] = wrap_new(value) if name == '__new__' else wrap(value)
203
+ setattr(extended, name, wrap_new(value) if name == '__new__' else wrap(value))
204
+
205
+ # slots[name] = wrap_new(value) if name == '__new__' else wrap(value)
206
+ extended.__module__ = cls.__module__
191
207
 
192
- return type(cls.__name__, (cls,), slots)
208
+ return extended
209
+ # return type(cls.__name__, (cls,), slots)
193
210
 
194
211
  elif not utils.is_immutable(cls):
195
212
  def update(name, f):
@@ -197,7 +214,13 @@ class ProxySystem:
197
214
 
198
215
  for name, value in superdict(cls).items():
199
216
  if callable(value) and not is_instance_method(value):
200
- update(name, wrap_new if name == '__new__' else wrap)
217
+ if name == '__new__':
218
+ handler = self.thread_state.dispatch(functional.apply, internal = self.ext_handler)
219
+
220
+ utils.intercept__new__(type = cls, handler = handler)
221
+ else:
222
+ update(name, wrap)
223
+ # update(name, wrap_new if name == '__new__' else wrap)
201
224
  else:
202
225
  return wrap(cls)
203
226
 
@@ -220,6 +243,8 @@ class ProxySystem:
220
243
  return classmethod(func)
221
244
  else:
222
245
  proxytype = dynamic_proxytype(handler = self.ext_dispatch, cls = type(obj))
246
+ proxytype.__retrace_source__ = 'external'
247
+
223
248
  if self.on_proxytype: self.on_proxytype(proxytype)
224
249
 
225
250
  return utils.create_wrapped(proxytype, obj)
@@ -3,14 +3,11 @@ import retracesoftware.functional as functional
3
3
 
4
4
  import types
5
5
 
6
- from retracesoftware.proxy.stubfactory import StubMethodDescriptor
6
+ from retracesoftware.proxy.stubfactory import StubMethodDescriptor, Stub
7
7
 
8
8
  class Proxy:
9
9
  __slots__ = []
10
10
 
11
- class Stub(Proxy):
12
- __slots__ = []
13
-
14
11
  class DynamicProxy(Proxy):
15
12
  __slots__ = []
16
13
 
@@ -241,8 +238,14 @@ def dynamic_proxytype(handler, cls):
241
238
 
242
239
  spec['__retrace_target_class__'] = cls
243
240
 
244
- target_type = functional.sequence(utils.unwrap, functional.typeof)
245
- spec['__class__'] = property(target_type)
241
+ # target_type = functional.sequence(utils.unwrap, functional.typeof)
242
+
243
+ target_type = cls.__retrace_target_type__ if issubclass(cls, Stub) else cls
244
+ # functional.repeatedly(resolved)
245
+
246
+ # spec['__class__'] = property(target_type)
247
+ spec['__class__'] = property(functional.constantly(target_type))
248
+
246
249
  spec['__name__'] = cls.__name__
247
250
  spec['__module__'] = cls.__module__
248
251
  # name = f'retrace.proxied.{cls.__module__}.{cls.__name__}'
@@ -288,6 +291,7 @@ def instantiable_dynamic_proxytype(handler, cls, thread_state, create_stub = Fal
288
291
  def dynamic_int_proxytype(handler, cls, bind):
289
292
  proxytype = dynamic_proxytype(handler = handler, cls = cls)
290
293
  proxytype.__new__ = functional.sequence(proxytype.__new__, functional.side_effect(bind))
294
+ proxytype.__retrace_source__ = 'internal'
291
295
  return proxytype
292
296
 
293
297
 
@@ -160,9 +160,6 @@ class ReplayProxySystem(ProxySystem):
160
160
  def readnext(self):
161
161
  with self.thread_state.select('disabled'):
162
162
  try:
163
- # obj = self.messages()
164
- # print(f'read {obj}')
165
- # return obj
166
163
  return self.messages()
167
164
  except Exception as error:
168
165
  # print(f'Error reading stream: {error}')
@@ -194,7 +191,7 @@ class ReplayProxySystem(ProxySystem):
194
191
  os._exit(1)
195
192
  raise Exception(f'Expected: {required} but got: {obj}')
196
193
 
197
- self.last_matching_stack = utils.stacktrace()
194
+ # self.last_matching_stack = utils.stacktrace()
198
195
 
199
196
  def trace_writer(self, name, *args):
200
197
  with self.thread_state.select('disabled'):
@@ -205,6 +202,8 @@ class ReplayProxySystem(ProxySystem):
205
202
  self.read_required(name)
206
203
 
207
204
  if name == 'stacktrace':
205
+ print('FOOO!!!')
206
+ os._exit(1)
208
207
  record = self.readnext()
209
208
  if args[0] == record:
210
209
  self.last_matching_stack = args[0]
@@ -272,7 +271,7 @@ class ReplayProxySystem(ProxySystem):
272
271
  self.reader.type_deserializer[StubRef] = self.stub_factory
273
272
  self.reader.type_deserializer[GlobalRef] = lambda ref: ref()
274
273
 
275
- read_sync = functional.lazy(self.read_required, 'SYNC')
274
+ read_sync = functional.lazy(thread_state.wrap('disabled', self.read_required), 'SYNC')
276
275
 
277
276
  self.sync = lambda function: utils.observer(on_call = read_sync, function = function)
278
277
 
@@ -152,12 +152,16 @@ class StubFactory:
152
152
 
153
153
  if isinstance(resolved, type):
154
154
  slots['__class__'] = property(functional.repeatedly(resolved))
155
+ # else:
156
+ # utils.sigtrap(f'{spec.module}.{spec.name}')
155
157
 
156
158
  stubtype = type(spec.name, (Stub, ), slots)
157
159
 
158
160
  for method in spec.methods:
159
161
  slots[method].__objclass__ = stubtype
160
162
 
163
+ stubtype.__retrace_target_type__ = resolved
164
+
161
165
  return stubtype
162
166
 
163
167
  def __call__(self, spec):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: retracesoftware_proxy
3
- Version: 0.1.16
3
+ Version: 0.1.18
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=kV7FMjIQodixCx35I-3JIivOgRd_BzGJgpx_2naw-K4,9229
2
+ retracesoftware/config.json,sha256=Nyk1Wt67_BJR-mVLoxk5Qwcf0X4z83vQ80rCBxUP03s,9182
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=b_VSG7EG1hhFh1VsAV2dHDRCiABpnEXvX_o5bsQXCDA,20268
9
+ retracesoftware/install/patcher.py,sha256=hLOowGOKKcMTtCxQthvdC-4Cx4PCNPuBzgHy-UOBbpE,20906
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=cHEjiVxIp2iVTJEWndwSbMuiXVyGJQxJYZSGrfpSbCw,5723
14
+ retracesoftware/install/tracer.py,sha256=Z1HTI74iczOjVI7sLOg8iEJ_-kMMUzC4ju_UMDyLipw,8009
15
15
  retracesoftware/install/typeutils.py,sha256=_a1PuwdCsYjG1Nkd77V-flqYtwbD4RkJVKn6Z-xABL4,1813
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=8PTljvtxb0PEqYElaGREAfEgR5EpqDhutpttFox6vWg,7858
21
- retracesoftware/proxy/proxytype.py,sha256=hP-1vJmWBa9KgZFB3CnZy0UbC4u8Wr2e76lGI0JM2SA,12992
20
+ retracesoftware/proxy/proxysystem.py,sha256=APigIjw6S7pQHTya2YWhXwsObHDcejCWfra3OMyiLvk,8859
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=RWfmTrbeLFCSvV26ow1iwitf1wWt6XfypMcKIxYXZEg,9669
24
- retracesoftware/proxy/stubfactory.py,sha256=37UX1r8HCAbASTwPdz8QKCrg72NQmM5PsiCho7N2nzg,5129
23
+ retracesoftware/proxy/replay.py,sha256=bU657DOuvC4m2oWgTHbsQQPtruQzbvMXCKSyp6if9kI,9655
24
+ retracesoftware/proxy/stubfactory.py,sha256=eHlbzWR1LoQVkIRX1HoLPPQSOpYhOO_5R_p3buD4o7s,5256
25
25
  retracesoftware/proxy/thread.py,sha256=T1ME6DHB8O0xVnX3Rt1lMl7oCJ2Y0aoFT91D76yNICk,3073
26
- retracesoftware_proxy-0.1.16.dist-info/METADATA,sha256=zTBolyYWW1whamxpNcJQR32CR3rP4XWQM2zmEoZuAWE,203
27
- retracesoftware_proxy-0.1.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
28
- retracesoftware_proxy-0.1.16.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
29
- retracesoftware_proxy-0.1.16.dist-info/RECORD,,
26
+ retracesoftware_proxy-0.1.18.dist-info/METADATA,sha256=RMIcM6zELH7mx-kFXHOCxtAu55602_u0NgJOUSJVwzc,203
27
+ retracesoftware_proxy-0.1.18.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
28
+ retracesoftware_proxy-0.1.18.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
29
+ retracesoftware_proxy-0.1.18.dist-info/RECORD,,