retracesoftware-proxy 0.1.15__py3-none-any.whl → 0.1.17__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",
@@ -156,6 +157,13 @@
156
157
  },
157
158
 
158
159
  "modules": {
160
+ "_frozen_importlib_external": {
161
+ "comment": {
162
+ "with_state": {
163
+ "disabled": ["_path_stat"]
164
+ }
165
+ }
166
+ },
159
167
  "_imp": {
160
168
  "patch_extension_exec": ["exec_dynamic", "exec_builtin"],
161
169
  "comment": {
@@ -241,16 +249,12 @@
241
249
  "builtins": {
242
250
  "patch_hash": ["object"],
243
251
 
244
- "with_state": {
245
- "disabled": ["__import__"]
246
- },
247
-
248
252
  "comment": {
249
- "replace": {
250
- "set": "retracesoftware_utils.set",
251
- "frozenset": "retracesoftware_utils.frozenset"
253
+ "with_state": {
254
+ "disabled": ["__import__"]
252
255
  }
253
256
  },
257
+
254
258
  "immutable_types": [
255
259
  "BaseException",
256
260
  "memoryview",
@@ -303,7 +307,9 @@
303
307
  ]
304
308
  },
305
309
  "io": {
306
- "proxy": ["open_code", "open"],
310
+ "comment": {
311
+ "proxy": ["open_code", "open"]
312
+ },
307
313
  "path_predicates": {
308
314
  "open_code": "path",
309
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
 
@@ -486,8 +490,6 @@ class Patcher:
486
490
 
487
491
  def patch_module_with_name(self, mod_name, module):
488
492
  with self.disable:
489
- print(f'Patching: {module}')
490
-
491
493
  self.log('install.module', mod_name)
492
494
 
493
495
  # self.system.log(f'patching module: {mod_name}')
@@ -504,6 +506,10 @@ class Patcher:
504
506
  for ref in gc.get_referrers(value):
505
507
  if ref is not originals:
506
508
  container_replace(container = ref, old = value, new = updates[name])
509
+ if isinstance(updates[name], type) and isinstance(value, type) and issubclass(updates[name], value):
510
+ for subclass in value.__subclasses__():
511
+ if subclass not in updates.values():
512
+ subclass.__bases__ = tuple(replace({value: updates[name]}, subclass.__bases__))
507
513
 
508
514
  module.__retrace__ = originals
509
515
 
@@ -512,12 +518,8 @@ class Patcher:
512
518
 
513
519
  def __call__(self, module):
514
520
 
515
- print(f'patcher called with: {module} {self.thread_state.value}')
516
-
517
521
  if not hasattr(module, '__retrace__'):
518
522
 
519
- print(f'patcher called with: {module} 1')
520
-
521
523
  configs = list(self.configs(module))
522
524
 
523
525
  if len(configs) > 0:
@@ -604,6 +606,8 @@ def install(mode):
604
606
 
605
607
  # print(f'MODULES: {list(sys.modules.keys())}')
606
608
 
609
+ importlib.invalidate_caches()
610
+
607
611
  with thread_state.select('internal'):
608
612
 
609
613
  atexit.register(lambda: at_exit)
@@ -615,6 +619,7 @@ def install(mode):
615
619
  for library in config.get('preload', []):
616
620
  importlib.import_module(library)
617
621
 
622
+ importlib.invalidate_caches()
618
623
  # # if env_truthy('RETRACE_TRACE_CALLS'):
619
624
  # # trace_calls(system = retracesystem)
620
625
 
@@ -625,4 +630,6 @@ def install(mode):
625
630
 
626
631
  threading.current_thread().__retrace__ = system
627
632
 
633
+ # utils.sigtrap(None)
634
+
628
635
  return system
@@ -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
 
@@ -36,8 +38,12 @@ def resolve(obj):
36
38
  def is_function_type(cls):
37
39
  return cls in [types.BuiltinFunctionType, types.FunctionType]
38
40
 
41
+ method_types = (types.MethodDescriptorType,
42
+ types.WrapperDescriptorType,
43
+ types.FunctionType)
44
+
39
45
  def is_instance_method(obj):
40
- return isinstance(obj, types.MethodDescriptorType) or isinstance(obj, types.FunctionType)
46
+ return isinstance(obj, method_types)
41
47
 
42
48
  class ProxySystem:
43
49
 
@@ -111,6 +117,8 @@ class ProxySystem:
111
117
  func = self.thread_state.dispatch(lambda *args: None, internal = func)
112
118
  sys.settrace(func)
113
119
 
120
+ tracer.trace_calls(thread_state)
121
+
114
122
  def new_child_path(self, path):
115
123
  return path.parent / f'fork-{self.fork_counter}' / path.name
116
124
 
@@ -148,7 +156,8 @@ class ProxySystem:
148
156
  breakpoint()
149
157
 
150
158
  proxytype = dynamic_proxytype(handler = self.ext_dispatch, cls = cls)
151
-
159
+ proxytype.__retrace_source__ = 'external'
160
+
152
161
  if self.on_proxytype: self.on_proxytype(proxytype)
153
162
 
154
163
  return proxytype
@@ -159,8 +168,6 @@ class ProxySystem:
159
168
  return utils.wrapped_function(handler = self.ext_handler, target = obj)
160
169
 
161
170
  def patchtype(self, cls):
162
- print(f'Proxying type: {cls}')
163
-
164
171
  if cls in self.immutable_types or issubclass(cls, tuple):
165
172
  return cls
166
173
 
@@ -177,14 +184,29 @@ class ProxySystem:
177
184
 
178
185
  return self.thread_state.dispatch(func, internal = new)
179
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
180
196
  if utils.is_extendable(cls):
181
197
  slots = {'__module__': cls.__module__, '__slots__': []}
182
198
 
199
+ extended = utils.extend_type(cls)
200
+
183
201
  for name, value in superdict(cls).items():
184
202
  if callable(value) and not is_instance_method(value):
185
- slots[name] = wrap_new(value) if name == '__new__' else wrap(value)
203
+ setattr(extended, name, wrap_new(value) if name == '__new__' else wrap(value))
186
204
 
187
- return type(cls.__name__, (cls,), slots)
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)
188
210
 
189
211
  elif not utils.is_immutable(cls):
190
212
  def update(name, f):
@@ -215,6 +237,8 @@ class ProxySystem:
215
237
  return classmethod(func)
216
238
  else:
217
239
  proxytype = dynamic_proxytype(handler = self.ext_dispatch, cls = type(obj))
240
+ proxytype.__retrace_source__ = 'external'
241
+
218
242
  if self.on_proxytype: self.on_proxytype(proxytype)
219
243
 
220
244
  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.15
3
+ Version: 0.1.17
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=yMAD8410r8VEnBToXNmtfaBz6MClBVEiKsq6vKgSI0c,9121
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=_J8YTDd0QNLgURRyrUFikNsImgMOBhCv8Nmps5rjkZI,20241
9
+ retracesoftware/install/patcher.py,sha256=7wYERlRNBwjwMtbUkCrhQI2b_V_C88aWNcnSTo9gr-E,20654
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=ttzHcNH4O2GrlTjy3R386HTwRY7Z5QKWbMt6BOf7Jto,7722
21
- retracesoftware/proxy/proxytype.py,sha256=hP-1vJmWBa9KgZFB3CnZy0UbC4u8Wr2e76lGI0JM2SA,12992
20
+ retracesoftware/proxy/proxysystem.py,sha256=6CxAaD_DJ-nDYemGbVnE5fY7Olwa56_oeF2o7XT1m2w,8535
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.15.dist-info/METADATA,sha256=5EIkVm31Txgu2-FN94NLguxj4YtbZ7pU_VaZLisxhCE,203
27
- retracesoftware_proxy-0.1.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
28
- retracesoftware_proxy-0.1.15.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
29
- retracesoftware_proxy-0.1.15.dist-info/RECORD,,
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,,