retracesoftware-proxy 0.1.14__py3-none-any.whl → 0.1.16__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.
@@ -4,7 +4,6 @@
4
4
  "internal", {"comment": "Default state when retrace is disabled for a thread"},
5
5
  "external", {"comment": "When target thread is running outside the python system to be recorded"},
6
6
  "retrace", {"comment": "When target thread is running outside the retrace system"},
7
- "bootstrap", {"comment": "When the target thread is running in the low-level module load machinery"},
8
7
  "gc", {"comment": "When the target thread is running inside the pyton garbage collector"}
9
8
  ],
10
9
 
@@ -157,6 +156,11 @@
157
156
  },
158
157
 
159
158
  "modules": {
159
+ "_frozen_importlib_external": {
160
+ "with_state": {
161
+ "disabled": ["_path_stat"]
162
+ }
163
+ },
160
164
  "_imp": {
161
165
  "patch_extension_exec": ["exec_dynamic", "exec_builtin"],
162
166
  "comment": {
@@ -175,6 +179,7 @@
175
179
  "disabled": ["Bdb.trace_dispatch"]
176
180
  }
177
181
  },
182
+
178
183
  "sys": {
179
184
  "with_state": {
180
185
  "disabled": ["excepthook"]
@@ -186,13 +191,21 @@
186
191
  }
187
192
  },
188
193
 
189
- "importlib._bootstrap": {
194
+ "importlib": {
190
195
  "with_state": {
191
- "bootstrap": [
192
- "_load_unlocked",
193
- "_find_spec",
194
- "_lock_unlock_module",
195
- "_get_module_lock"]
196
+ "disabled": ["import_module"]
197
+ }
198
+ },
199
+
200
+ "importlib._bootstrap": {
201
+ "comment": {
202
+ "with_state": {
203
+ "internal": [
204
+ "_load_unlocked",
205
+ "_find_spec",
206
+ "_lock_unlock_module",
207
+ "_get_module_lock"]
208
+ }
196
209
  }
197
210
  },
198
211
 
@@ -233,6 +246,10 @@
233
246
  "builtins": {
234
247
  "patch_hash": ["object"],
235
248
 
249
+ "with_state": {
250
+ "disabled": ["__import__"]
251
+ },
252
+
236
253
  "comment": {
237
254
  "replace": {
238
255
  "set": "retracesoftware_utils.set",
@@ -29,6 +29,8 @@ import retracesoftware.utils as utils
29
29
 
30
30
  from retracesoftware.install import edgecases
31
31
  from functools import partial
32
+ from retracesoftware.proxy.thread import start_new_thread_wrapper
33
+
32
34
  # from retrace_utils.intercept import proxy
33
35
 
34
36
  # from retrace_utils.intercept.typeutils import *
@@ -300,22 +302,29 @@ class Patcher:
300
302
 
301
303
  @patch
302
304
  def patch_start_new_thread(self, value):
303
- def start_new_thread(function, *args):
304
- # synchronized, replay shoudl yield correct number
305
- thread_id = self.thread_counter()
305
+ return start_new_thread_wrapper(thread_state = self.thread_state,
306
+ on_exit = self.system.on_thread_exit,
307
+ start_new_thread = value)
308
+
309
+ # def start_new_thread(function, *args):
310
+ # # synchronized, replay shoudl yield correct number
311
+ # thread_id = self.thread_counter()
306
312
 
307
- def threadrunner(*args, **kwargs):
308
- nonlocal thread_id
309
- self.system.set_thread_id(thread_id)
313
+ # def threadrunner(*args, **kwargs):
314
+ # nonlocal thread_id
315
+ # self.system.set_thread_id(thread_id)
310
316
 
311
- with self.thread_state.select('internal'):
312
- # if self.tracing:
313
- # FrameTracer.install(self.thread_state.dispatch(noop, internal = self.checkpoint))
314
- return function(*args, **kwargs)
317
+ # with self.thread_state.select('internal'):
318
+ # try:
319
+ # # if self.tracing:
320
+ # # FrameTracer.install(self.thread_state.dispatch(noop, internal = self.checkpoint))
321
+ # return function(*args, **kwargs)
322
+ # finally:
323
+ # print(f'exiting: {thread_id}')
315
324
 
316
- return value(threadrunner, *args)
325
+ # return value(threadrunner, *args)
317
326
 
318
- return self.thread_state.dispatch(value, internal = start_new_thread)
327
+ # return self.thread_state.dispatch(value, internal = start_new_thread)
319
328
 
320
329
  @phase
321
330
  def wrappers(self, spec, mod_dict):
@@ -323,39 +332,21 @@ class Patcher:
323
332
 
324
333
  @patch
325
334
  def patch_exec(self, exec):
326
- def is_module_exec(source):
327
- return isinstance(source, types.CodeType) and \
328
- source.co_name == '<module>' and inspect.getmodule(source)
329
335
 
330
- def exec_wrapper(source, *args,**kwargs):
331
- module = None
332
-
333
- with self.thread_state.select('disabled'):
334
- if is_module_exec(source):
335
- module = inspect.getmodule(source)
336
-
337
- if module:
338
- result = exec(source, *args, **kwargs)
339
- self(module)
340
- return result
341
- else:
342
- return exec(source, *args,**kwargs)
336
+ def exec_wrapper2(source, *args,**kwargs):
337
+ if isinstance(source, types.CodeType) and source.co_name == '<module>':
338
+ self(inspect.getmodule(source))
343
339
 
344
- # if self.thread_state.value != 'bootstrap':
345
-
346
- # and is_module_exec(source):
347
- # with self.thread_state.select('disabled'):
348
- # module = inspect.getmodule(source)
349
- # with self.thread_state.select('internal'):
350
- # result = exec(source, *args, **kwargs)
351
-
352
- # self(module)
340
+ def first(x): return x[0]
341
+
342
+ wrapped_exec = functional.sequence(
343
+ functional.vector(
344
+ self.thread_state.wrap('internal', exec),
345
+ exec_wrapper2),
346
+ first)
353
347
 
354
- # return result
355
- # else:
356
- # return exec(source, *args,**kwargs)
357
-
358
- return self.thread_state.dispatch(exec, internal = exec_wrapper)
348
+ return self.thread_state.dispatch(exec, internal = wrapped_exec)
349
+
359
350
  # self.thread_state.wrap(desired_state = 'disabled', function = exec_wrapper)
360
351
 
361
352
  @patch
@@ -415,7 +406,6 @@ class Patcher:
415
406
 
416
407
  @patch
417
408
  def patch_hash(self, cls):
418
- print(f'patching hash for: {cls}')
419
409
  utils.patch_hash(cls = cls, hashfunc = self.hashfunc)
420
410
 
421
411
  @patch
@@ -496,6 +486,8 @@ class Patcher:
496
486
 
497
487
  def patch_module_with_name(self, mod_name, module):
498
488
  with self.disable:
489
+ print(f'Patching: {module}')
490
+
499
491
  self.log('install.module', mod_name)
500
492
 
501
493
  # self.system.log(f'patching module: {mod_name}')
@@ -520,19 +512,23 @@ class Patcher:
520
512
 
521
513
  def __call__(self, module):
522
514
 
523
- if self.thread_state.value == 'internal' and not hasattr(module, '__retrace__'):
524
- with self.thread_state.select('bootstrap'):
525
- configs = list(self.configs(module))
515
+ print(f'patcher called with: {module} {self.thread_state.value}')
516
+
517
+ if not hasattr(module, '__retrace__'):
518
+
519
+ print(f'patcher called with: {module} 1')
526
520
 
527
- if len(configs) > 0:
528
- if len(configs) > 1:
529
- raise Exception(f'TODO')
530
- else:
531
- module.__retrace__ = None
532
- try:
533
- self.patch_module_with_name(configs[0], module)
534
- except Exception as error:
535
- raise Exception(f'Error patching module: {configs[0]}') from error
521
+ configs = list(self.configs(module))
522
+
523
+ if len(configs) > 0:
524
+ if len(configs) > 1:
525
+ raise Exception(f'TODO')
526
+ else:
527
+ module.__retrace__ = None
528
+ try:
529
+ self.patch_module_with_name(configs[0], module)
530
+ except Exception as error:
531
+ raise Exception(f'Error patching module: {configs[0]}') from error
536
532
 
537
533
  return module
538
534
 
@@ -629,4 +625,6 @@ def install(mode):
629
625
 
630
626
  threading.current_thread().__retrace__ = system
631
627
 
628
+ # utils.sigtrap(None)
629
+
632
630
  return system
@@ -36,8 +36,12 @@ def resolve(obj):
36
36
  def is_function_type(cls):
37
37
  return cls in [types.BuiltinFunctionType, types.FunctionType]
38
38
 
39
+ method_types = (types.MethodDescriptorType,
40
+ types.WrapperDescriptorType,
41
+ types.FunctionType)
42
+
39
43
  def is_instance_method(obj):
40
- return isinstance(obj, types.MethodDescriptorType) or isinstance(obj, types.FunctionType)
44
+ return isinstance(obj, method_types)
41
45
 
42
46
  class ProxySystem:
43
47
 
@@ -100,8 +104,8 @@ class ProxySystem:
100
104
  default = tracer(name, unproxy_execute)
101
105
  return thread_state.dispatch(default, internal = internal, external = external)
102
106
 
103
- self.ext_handler = self.wrap_int_to_ext(int2ext)
104
- self.int_handler = self.wrap_ext_to_int(ext2int)
107
+ self.ext_handler = thread_state.wrap('retrace', self.wrap_int_to_ext(int2ext))
108
+ self.int_handler = thread_state.wrap('retrace', self.wrap_ext_to_int(ext2int))
105
109
 
106
110
  self.ext_dispatch = gateway('proxy.int.disabled.event', internal = self.ext_handler)
107
111
  self.int_dispatch = gateway('proxy.ext.disabled.event', external = self.int_handler)
@@ -126,6 +130,9 @@ class ProxySystem:
126
130
  self.thread_state.value = self.saved_thread_state
127
131
  self.fork_counter += 1
128
132
 
133
+ def on_thread_exit(self, thread_id):
134
+ pass
135
+
129
136
  # def create_stub(self): return False
130
137
 
131
138
  def int_proxytype(self, cls):
@@ -156,10 +163,13 @@ class ProxySystem:
156
163
  return utils.wrapped_function(handler = self.ext_handler, target = obj)
157
164
 
158
165
  def patchtype(self, cls):
166
+ print(f'Proxying type: {cls}')
167
+
159
168
  if cls in self.immutable_types or issubclass(cls, tuple):
160
169
  return cls
161
170
 
162
171
  def wrap(func):
172
+ print(f'Wrapping: {cls.__name__}.{func.__name__}')
163
173
  return self.thread_state.dispatch(func, internal = self.proxy_function(func))
164
174
 
165
175
  def wrap_new(func):
@@ -5,7 +5,7 @@ import retracesoftware.stream as stream
5
5
  from retracesoftware.proxy.proxytype import *
6
6
  # from retracesoftware.proxy.gateway import gateway_pair
7
7
  from retracesoftware.proxy.proxysystem import ProxySystem
8
- from retracesoftware.proxy.thread import write_thread_switch, ThreadSwitch
8
+ from retracesoftware.proxy.thread import write_thread_switch, ThreadSwitch, thread_id
9
9
  from retracesoftware.install.tracer import Tracer
10
10
  from retracesoftware.proxy.stubfactory import StubRef, ExtendedRef
11
11
  from retracesoftware.proxy.globalref import GlobalRef
@@ -87,16 +87,16 @@ class RecordProxySystem(ProxySystem):
87
87
 
88
88
  self.pid = self.getpid()
89
89
 
90
- self.writer = stream.writer(path)
90
+ self.writer = stream.writer(path = path, thread = thread_id)
91
91
 
92
- def on_switch():
93
- print(f"On thread switch!!!")
94
- # print(f"On thread switch!!!: {utils.thread_id().id}")
95
- # utils.sigtrap(utils.thread_id())
96
- self.writer(utils.thread_id())
97
- # utils.sigtrap(utils.thread_id())
92
+ # def on_switch():
93
+ # print(f"On thread switch!!!")
94
+ # # print(f"On thread switch!!!: {utils.thread_id().id}")
95
+ # # utils.sigtrap(utils.thread_id())
96
+ # self.writer(utils.thread_id())
97
+ # # utils.sigtrap(utils.thread_id())
98
98
 
99
- write = utils.observer(on_call = utils.thread_switch_monitor(on_switch), function = self.writer)
99
+ # write = utils.observer(on_call = utils.thread_switch_monitor(on_switch), function = self.writer)
100
100
 
101
101
  # w = self.writer.handle('TRACE')
102
102
  # def trace_writer(*args):
@@ -121,15 +121,15 @@ class RecordProxySystem(ProxySystem):
121
121
 
122
122
  # self.sync = lambda function: functional.firstof(self.thread_switch_monitor, functional.always(self.writer.handle('SYNC')), function)
123
123
 
124
+ sync_handle = self.writer.handle('SYNC')
125
+
124
126
  self.sync = lambda function: \
125
- utils.observer(
126
- on_call = functional.lazy(write, self.writer.handle('SYNC')),
127
- function = function)
127
+ utils.observer(on_call = functional.lazy(sync_handle), function = function)
128
128
 
129
129
  error = self.writer.handle('ERROR')
130
130
 
131
131
  def write_error(cls, val, traceback):
132
- write(error, cls, val)
132
+ error(cls, val)
133
133
 
134
134
  # self.set_thread_id = functional.partial(utils.set_thread_id, self.writer)
135
135
 
@@ -139,13 +139,13 @@ class RecordProxySystem(ProxySystem):
139
139
  # w(self.writer.messages_written, name, *args)
140
140
 
141
141
  # tracer = Tracer(tracing_config, writer = foo)
142
- tracer = Tracer(tracing_config, writer = functional.partial(write, self.writer.handle('TRACE')))
142
+ tracer = Tracer(tracing_config, writer = self.writer.handle('TRACE'))
143
143
 
144
144
  # self.wrap_int_to_ext = self.sync
145
145
 
146
- self.on_int_call = functional.mapargs(transform = serialize, function = functional.partial(write, self.writer.handle('CALL')))
146
+ self.on_int_call = functional.mapargs(transform = serialize, function = self.writer.handle('CALL'))
147
147
 
148
- self.on_ext_result = functional.sequence(serialize, functional.partial(write, self.writer.handle('RESULT')))
148
+ self.on_ext_result = functional.sequence(serialize, self.writer.handle('RESULT'))
149
149
 
150
150
  self.on_ext_error = write_error
151
151
 
@@ -3,7 +3,7 @@ import retracesoftware_utils as utils
3
3
  import retracesoftware.stream as stream
4
4
 
5
5
  from retracesoftware.install.tracer import Tracer
6
- from retracesoftware.proxy.thread import per_thread_messages
6
+ from retracesoftware.proxy.thread import per_thread_messages, thread_id
7
7
  from retracesoftware.proxy.proxytype import *
8
8
  # from retracesoftware.proxy.gateway import gateway_pair
9
9
  from retracesoftware.proxy.record import StubRef, Placeholder
@@ -15,6 +15,7 @@ import os
15
15
  import weakref
16
16
  import traceback
17
17
  import pprint
18
+
18
19
  from itertools import count, islice
19
20
 
20
21
  # we can have a dummy method descriptor, its has a __name__ and when called, returns the next element
@@ -61,6 +62,8 @@ def on_stack_mismatch(last_matching, record, replay):
61
62
  print('Record stacktrace:')
62
63
  for line in islice(record, 0, len(record) - matching):
63
64
  print(line)
65
+
66
+ print(f'-----------')
64
67
  else:
65
68
  matching = count_matching(reversed(record), reversed(replay))
66
69
 
@@ -75,36 +78,52 @@ def on_stack_mismatch(last_matching, record, replay):
75
78
  print('Record stacktrace:')
76
79
  for line in islice(record, 0, len(record) - matching):
77
80
  print(line)
81
+
78
82
 
79
83
 
80
84
  class ReplayProxySystem(ProxySystem):
81
85
 
82
86
  @utils.striptraceback
83
87
  def next_result(self):
84
- while True:
85
- next = self.messages()
88
+ try:
89
+ while True:
90
+ next = self.messages()
91
+
92
+ if next == 'CALL':
93
+ func = self.messages()
94
+ args = self.messages()
95
+ kwargs = self.messages()
96
+
97
+ try:
98
+ func(*args, **kwargs)
99
+ except:
100
+ pass
101
+
102
+ elif next == 'RESULT':
103
+ return self.messages()
104
+
105
+ elif next == 'ERROR':
106
+ # breakpoint()
107
+ err_type = self.messages()
108
+ err_value = self.messages()
109
+ utils.raise_exception(err_type, err_value)
110
+ else:
111
+ assert type(next) is not str
112
+ return next
113
+ except TimeoutError:
114
+ print(f'timeout for reader, active thread: {self.reader.active_thread}, next_control: {self.reader.next_control}')
86
115
 
87
- if next == 'CALL':
88
- func = self.messages()
89
- args = self.messages()
90
- kwargs = self.messages()
116
+ for thread,stack in self.reader.stacktraces.items():
117
+ print(f'thread: {thread}')
91
118
 
92
- try:
93
- func(*args, **kwargs)
94
- except:
95
- pass
119
+ formatted_frames = [
120
+ (frame.filename, frame.lineno, frame.function, frame.code_context[0].strip() if frame.code_context else None)
121
+ for frame in stack
122
+ ]
123
+ formatted_trace = traceback.format_list(formatted_frames)
124
+ print("Traceback (most recent call last):\n" + "".join(formatted_trace))
96
125
 
97
- elif next == 'RESULT':
98
- return self.messages()
99
-
100
- elif next == 'ERROR':
101
- # breakpoint()
102
- err_type = self.messages()
103
- err_value = self.messages()
104
- utils.raise_exception(err_type, err_value)
105
- else:
106
- assert type(next) is not str
107
- return next
126
+ utils.sigtrap(None)
108
127
 
109
128
  def bind(self, obj):
110
129
  read = self.messages()
@@ -138,7 +157,6 @@ class ReplayProxySystem(ProxySystem):
138
157
  def basetype(self, cls):
139
158
  return self.stub_factory.create_stubtype(StubRef(cls))
140
159
 
141
-
142
160
  def readnext(self):
143
161
  with self.thread_state.select('disabled'):
144
162
  try:
@@ -201,6 +219,11 @@ class ReplayProxySystem(ProxySystem):
201
219
  for arg in args:
202
220
  self.read_required(arg)
203
221
 
222
+ def on_thread_exit(self, thread_id):
223
+ print(f'on_thread_exit!!!!')
224
+ self.reader.wake_pending()
225
+
226
+
204
227
  def __init__(self,
205
228
  thread_state,
206
229
  immutable_types,
@@ -209,8 +232,11 @@ class ReplayProxySystem(ProxySystem):
209
232
  fork_path = []):
210
233
 
211
234
  # self.messages_read = 0
212
- self.reader = stream.reader(path)
213
235
 
236
+ self.reader = stream.reader(path,
237
+ thread = thread_id,
238
+ timeout_seconds = 5)
239
+
214
240
  self.bindings = utils.id_dict()
215
241
  # self.set_thread_id = utils.set_thread_id
216
242
  self.fork_path = fork_path
@@ -235,9 +261,9 @@ class ReplayProxySystem(ProxySystem):
235
261
  print(f'Error reading next result: {error}')
236
262
  raise(error)
237
263
 
238
- self.messages = functional.sequence(per_thread_messages(foo), deserialize)
264
+ # self.messages = functional.sequence(per_thread_messages(foo), deserialize)
239
265
 
240
- # self.messages = functional.sequence(per_thread_messages(self.reader), deserialize)
266
+ self.messages = functional.sequence(self.reader, deserialize)
241
267
 
242
268
  self.stub_factory = StubFactory(thread_state = thread_state, next_result = self.next_result)
243
269
 
@@ -1,6 +1,9 @@
1
1
  import retracesoftware.functional as functional
2
2
  import retracesoftware_utils as utils
3
3
 
4
+ import os
5
+ import _thread
6
+
4
7
  # def thread_aware_writer(writer):
5
8
  # on_thread_switch = functional.sequence(utils.thread_id(), writer.handle('THREAD_SWITCH'))
6
9
  # return utils.threadawareproxy(on_thread_switch = on_thread_switch, target = writer)
@@ -39,6 +42,7 @@ def prefix_with_thread_id(f, thread_id):
39
42
  current = obj.id
40
43
  obj = f()
41
44
 
45
+ # print(f'prefix_with_thread_id: {(current, obj)}')
42
46
  return (current, obj)
43
47
 
44
48
  return next
@@ -47,8 +51,15 @@ def per_thread_messages(messages):
47
51
  thread_id = utils.thread_id
48
52
  # thread_id = lambda: 'FOOOOO!!!'
49
53
 
54
+ def on_timeout(demux, key):
55
+ print(f'ON TIMEOUT!!!! {key} pending: {demux.pending} {demux.pending_keys}')
56
+ utils.sigtrap(demux)
57
+ os._exit(1)
58
+
50
59
  demux = utils.demux(source = prefix_with_thread_id(messages, thread_id),
51
- key_function = lambda obj: obj[0])
60
+ key_function = lambda obj: obj[0],
61
+ timeout_seconds = 60,
62
+ on_timeout = on_timeout)
52
63
 
53
64
  # def next():
54
65
  # thread,message = demux(thread_id())
@@ -56,3 +67,40 @@ def per_thread_messages(messages):
56
67
 
57
68
  # return next
58
69
  return functional.repeatedly(lambda: demux(thread_id())[1])
70
+
71
+
72
+ # _thread.start_new_thread(function, args[, kwargs])
73
+ counters = _thread._local()
74
+ counters.id = ()
75
+ counters.counter = 0
76
+
77
+ def with_thread_id(thread_id, on_exit, function):
78
+ def on_call(*args, **kwargs):
79
+ counters.id = thread_id
80
+ counters.counter = 0
81
+
82
+ def on_result(res):
83
+ on_exit(thread_id)
84
+
85
+ def on_error(*args):
86
+ on_exit(thread_id)
87
+
88
+ return utils.observer(on_call = on_call, on_result = on_result, on_error = on_error, function = function)
89
+
90
+ thread_id = functional.lazy(getattr, counters, 'id')
91
+
92
+ def start_new_thread_wrapper(thread_state, on_exit, start_new_thread):
93
+
94
+ def wrapper(function, *args):
95
+
96
+ next_id = counters.id + (counters.counter,)
97
+ counters.counter += 1
98
+
99
+ wrapped_function = with_thread_id(thread_id = next_id,
100
+ on_exit = on_exit,
101
+ function = thread_state.wrap('internal', function))
102
+
103
+ return start_new_thread(wrapped_function, *args)
104
+
105
+ return thread_state.dispatch(start_new_thread, internal = wrapper)
106
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: retracesoftware_proxy
3
- Version: 0.1.14
3
+ Version: 0.1.16
4
4
  License: Apache-2.0
5
5
  Requires-Dist: retracesoftware_utils
6
6
  Requires-Dist: retracesoftware_functional
@@ -1,12 +1,12 @@
1
1
  retracesoftware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- retracesoftware/config.json,sha256=JU3LYWZbqBLqiHXDc9fBYVh0owMUcKGw3W-vaVm-roo,9024
2
+ retracesoftware/config.json,sha256=kV7FMjIQodixCx35I-3JIivOgRd_BzGJgpx_2naw-K4,9229
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=ryX73_KjdcUCC0oy0Uqel_L3bwfZZldS3CIYQ-XAl_k,20520
9
+ retracesoftware/install/patcher.py,sha256=b_VSG7EG1hhFh1VsAV2dHDRCiABpnEXvX_o5bsQXCDA,20268
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
@@ -17,13 +17,13 @@ retracesoftware/proxy/__init__.py,sha256=ntIyqKhBRkKEkcW_oOPodikh-mxYl8OXRnSaj-9
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=ZX6eNT8go-YDbLWD2pq5j_V8DZAHteu-iNfkMO8jLWg,7567
20
+ retracesoftware/proxy/proxysystem.py,sha256=8PTljvtxb0PEqYElaGREAfEgR5EpqDhutpttFox6vWg,7858
21
21
  retracesoftware/proxy/proxytype.py,sha256=hP-1vJmWBa9KgZFB3CnZy0UbC4u8Wr2e76lGI0JM2SA,12992
22
- retracesoftware/proxy/record.py,sha256=QBx3G8mXjUiB9vCXJZ0tZdt3Mi1WEtRhuZ7HOUroNNQ,5505
23
- retracesoftware/proxy/replay.py,sha256=vVFkhYOOZSprLD_mjx-p6SpDB8fy81SK3x2A5H0odUs,8614
22
+ retracesoftware/proxy/record.py,sha256=47vhAYIUrR2bWo-rQ9xU_Xyg3kNrA5Lqq4-8Cxg4-zg,5463
23
+ retracesoftware/proxy/replay.py,sha256=RWfmTrbeLFCSvV26ow1iwitf1wWt6XfypMcKIxYXZEg,9669
24
24
  retracesoftware/proxy/stubfactory.py,sha256=37UX1r8HCAbASTwPdz8QKCrg72NQmM5PsiCho7N2nzg,5129
25
- retracesoftware/proxy/thread.py,sha256=idkJwJ8rR1kpRHfo81uCi6Y0LEIChAdfc0GqK_bFqTA,1635
26
- retracesoftware_proxy-0.1.14.dist-info/METADATA,sha256=Y6QfA5aDmUke1rEvUWSOgRIwbEAk7YbbcpW-7m00kQM,203
27
- retracesoftware_proxy-0.1.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
28
- retracesoftware_proxy-0.1.14.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
29
- retracesoftware_proxy-0.1.14.dist-info/RECORD,,
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,,