retracesoftware-proxy 0.1.13__py3-none-any.whl → 0.1.14__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.
@@ -159,8 +159,10 @@
159
159
  "modules": {
160
160
  "_imp": {
161
161
  "patch_extension_exec": ["exec_dynamic", "exec_builtin"],
162
- "with_state": {
163
- "internal": ["create_dynamic"]
162
+ "comment": {
163
+ "with_state": {
164
+ "internal": ["create_dynamic"]
165
+ }
164
166
  }
165
167
  },
166
168
  "bdb": {
@@ -186,7 +188,11 @@
186
188
 
187
189
  "importlib._bootstrap": {
188
190
  "with_state": {
189
- "bootstrap": ["_load_unlocked", "_find_spec"]
191
+ "bootstrap": [
192
+ "_load_unlocked",
193
+ "_find_spec",
194
+ "_lock_unlock_module",
195
+ "_get_module_lock"]
190
196
  }
191
197
  },
192
198
 
@@ -218,14 +224,20 @@
218
224
  ]
219
225
  },
220
226
  "types": {
227
+ "patch_hash": ["FunctionType"],
221
228
  "immutable_types": [
222
- "TracebackType"
229
+ "TracebackType",
230
+ "ModuleType"
223
231
  ]
224
232
  },
225
233
  "builtins": {
226
- "replace": {
227
- "set": "retracesoftware_utils.set",
228
- "frozenset": "retracesoftware_utils.frozenset"
234
+ "patch_hash": ["object"],
235
+
236
+ "comment": {
237
+ "replace": {
238
+ "set": "retracesoftware_utils.set",
239
+ "frozenset": "retracesoftware_utils.frozenset"
240
+ }
229
241
  },
230
242
  "immutable_types": [
231
243
  "BaseException",
@@ -121,9 +121,22 @@ def patch(func):
121
121
  if isinstance(spec, str):
122
122
  return wrapper(self, [spec], mod_dict)
123
123
  elif isinstance(spec, list):
124
- return {name: func(self, mod_dict[name]) for name in spec if name in mod_dict}
124
+ res = {}
125
+ for name in spec:
126
+ if name in mod_dict:
127
+ value = func(self, mod_dict[name])
128
+ if value is not None:
129
+ res[name] = value
130
+ return res
125
131
  elif isinstance(spec, dict):
126
- return {name: func(self, mod_dict[name], value) for name, value in spec.items() if name in mod_dict}
132
+ # return {name: func(self, mod_dict[name], value) for name, value in spec.items() if name in mod_dict}
133
+ res = {}
134
+ for name,value in spec.items():
135
+ if name in mod_dict:
136
+ value = func(self, mod_dict[name], value)
137
+ if value is not None:
138
+ res[name] = value
139
+ return res
127
140
  else:
128
141
  raise Exception('TODO')
129
142
 
@@ -155,6 +168,11 @@ def wrap_method_descriptors(wrapper, prefix, base):
155
168
 
156
169
  return extended
157
170
 
171
+ class PerThread(threading.local):
172
+ def __init__(self):
173
+ self.internal = utils.counter()
174
+ self.externak = utils.counter()
175
+
158
176
  class Patcher:
159
177
 
160
178
  def __init__(self, thread_state, config, system,
@@ -164,7 +182,7 @@ class Patcher:
164
182
  post_commit = None):
165
183
 
166
184
  # validate(config)
167
- # system.set_thread_id(0)
185
+ system.set_thread_id(0)
168
186
  # utils.set_thread_id(0)
169
187
  self.thread_counter = system.sync(utils.counter(1))
170
188
  # self.set_thread_number = set_thread_number
@@ -181,6 +199,13 @@ class Patcher:
181
199
  self.exclude_paths = [re.compile(s) for s in config.get('exclude_paths', [])]
182
200
  self.typepatcher = {}
183
201
 
202
+ per_thread = PerThread()
203
+
204
+ self.hashfunc = self.thread_state.dispatch(
205
+ functional.constantly(None),
206
+ internal = functional.repeatedly(functional.partial(getattr, per_thread, 'internal')),
207
+ external = functional.repeatedly(functional.partial(getattr, per_thread, 'external')))
208
+
184
209
  def is_phase(name): return getattr(getattr(self, name, None), "is_phase", False)
185
210
 
186
211
  self.phases = [(name, getattr(self, name)) for name in Patcher.__dict__.keys() if is_phase(name)]
@@ -303,19 +328,35 @@ class Patcher:
303
328
  source.co_name == '<module>' and inspect.getmodule(source)
304
329
 
305
330
  def exec_wrapper(source, *args,**kwargs):
306
- if self.thread_state.value != 'boostrap' and is_module_exec(source):
307
- with self.thread_state.select('disabled'):
331
+ module = None
332
+
333
+ with self.thread_state.select('disabled'):
334
+ if is_module_exec(source):
308
335
  module = inspect.getmodule(source)
309
- with self.thread_state.select('internal'):
310
- result = exec(source, *args, **kwargs)
311
-
336
+
337
+ if module:
338
+ result = exec(source, *args, **kwargs)
312
339
  self(module)
313
-
314
340
  return result
315
341
  else:
316
342
  return exec(source, *args,**kwargs)
317
343
 
318
- return exec_wrapper
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)
353
+
354
+ # return result
355
+ # else:
356
+ # return exec(source, *args,**kwargs)
357
+
358
+ return self.thread_state.dispatch(exec, internal = exec_wrapper)
359
+ # self.thread_state.wrap(desired_state = 'disabled', function = exec_wrapper)
319
360
 
320
361
  @patch
321
362
  def sync_types(self, value):
@@ -372,6 +413,11 @@ class Patcher:
372
413
 
373
414
  return updates
374
415
 
416
+ @patch
417
+ def patch_hash(self, cls):
418
+ print(f'patching hash for: {cls}')
419
+ utils.patch_hash(cls = cls, hashfunc = self.hashfunc)
420
+
375
421
  @patch
376
422
  def patch_extension_exec(self, exec):
377
423
 
@@ -13,9 +13,15 @@ from datetime import datetime
13
13
  import json
14
14
  from pathlib import Path
15
15
 
16
- class ThreadSwitch:
17
- def __init__(self, id):
18
- self.id = id
16
+ # class ThreadSwitch:
17
+ # def __init__(self, id):
18
+ # self.id = id
19
+
20
+ # def __repr__(self):
21
+ # return f'ThreadSwitch<{self.id}>'
22
+
23
+ # def __str__(self):
24
+ # return f'ThreadSwitch<{self.id}>'
19
25
 
20
26
  def write_files(recording_path):
21
27
  with open(recording_path / 'env', 'w') as f:
@@ -1,3 +1,3 @@
1
1
  from retracesoftware.proxy.record import RecordProxySystem
2
2
  from retracesoftware.proxy.replay import ReplayProxySystem
3
- from retracesoftware.proxy.thread import set_thread_id, per_thread_messages
3
+ from retracesoftware.proxy.thread import per_thread_messages
@@ -0,0 +1,31 @@
1
+ import types
2
+ import sys
3
+
4
+ def find_module_name(mod):
5
+ for name,value in sys.modules.items():
6
+ if value is mod:
7
+ return name
8
+
9
+ raise Exception(f"Cannot create GlobalRef as module {mod} not found in sys.modules")
10
+
11
+ class GlobalRef:
12
+ __slots__ = ['parts']
13
+
14
+ def __init__(self, obj):
15
+ if isinstance(obj, types.ModuleType):
16
+ self.parts = (find_module_name(obj),)
17
+ else:
18
+ raise Exception(f"Cannot create GlobalRef from {obj}")
19
+
20
+ def __call__(self):
21
+ module = self.parts[0]
22
+
23
+ if len(self.parts) == 0:
24
+ return module
25
+ else:
26
+ obj = getattr(module, self.parts[1])
27
+
28
+ if len(self.parts) == 1:
29
+ return obj
30
+ else:
31
+ raise Exception(f"TODO")
@@ -214,10 +214,16 @@ def dynamic_proxytype(handler, cls):
214
214
 
215
215
  for name in superdict(cls).keys():
216
216
  if name not in blacklist:
217
- value = getattr(cls, name)
218
- if is_descriptor(value):
219
- if utils.is_method_descriptor(value):
220
- spec[name] = wrap(value)
217
+ try:
218
+ value = getattr(cls, name)
219
+ if is_descriptor(value):
220
+ if utils.is_method_descriptor(value):
221
+ spec[name] = wrap(value)
222
+ except Exception as error:
223
+ print(f'FOO! {cls} {name} {error}')
224
+ breakpoint()
225
+ raise
226
+
221
227
  # else:
222
228
  # spec[name] = DescriptorProxy(handler = handler, target = value)
223
229
 
@@ -5,9 +5,10 @@ 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
8
+ from retracesoftware.proxy.thread import write_thread_switch, ThreadSwitch
9
9
  from retracesoftware.install.tracer import Tracer
10
10
  from retracesoftware.proxy.stubfactory import StubRef, ExtendedRef
11
+ from retracesoftware.proxy.globalref import GlobalRef
11
12
 
12
13
  import sys
13
14
  import os
@@ -69,14 +70,11 @@ class RecordProxySystem(ProxySystem):
69
70
  super().after_fork_in_parent()
70
71
  self.thread_state.value = self.saved_thread_state
71
72
  self.writer.reopen()
72
-
73
- def sync(self, function):
74
- write_sync = functional.always(self.writer.handle('SYNC'))
75
-
76
- return utils.observer(
77
- on_call = functional.firstof(self.thread_switch_monitor, write_sync),
78
- function = function)
79
73
 
74
+ def set_thread_id(self, id):
75
+ utils.set_thread_id(self.writer.handle(ThreadSwitch(id)))
76
+ # utils.set_thread_id(id)
77
+
80
78
  def __init__(self, thread_state,
81
79
  immutable_types,
82
80
  tracing_config,
@@ -91,6 +89,15 @@ class RecordProxySystem(ProxySystem):
91
89
 
92
90
  self.writer = stream.writer(path)
93
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())
98
+
99
+ write = utils.observer(on_call = utils.thread_switch_monitor(on_switch), function = self.writer)
100
+
94
101
  # w = self.writer.handle('TRACE')
95
102
  # def trace_writer(*args):
96
103
  # print(f'Trace: {args}')
@@ -102,39 +109,50 @@ class RecordProxySystem(ProxySystem):
102
109
 
103
110
  serialize = functional.walker(self.bindings.get_else_key)
104
111
 
105
- self.thread_switch_monitor = \
106
- utils.thread_switch_monitor(
107
- functional.repeatedly(functional.sequence(utils.thread_id, self.writer)))
112
+ # def on_switch():
113
+ # print("On thread switch!!!")
114
+ # # utils.sigtrap(utils.thread_id())
115
+ # utils.thread_id()()
116
+ # # utils.sigtrap(utils.thread_id())
117
+
118
+ # self.thread_switch_monitor = utils.thread_switch_monitor(on_switch)
119
+
120
+ # self.thread_switch_monitor = utils.thread_switch_monitor(functional.repeatedly(utils.thread_id))
108
121
 
109
122
  # self.sync = lambda function: functional.firstof(self.thread_switch_monitor, functional.always(self.writer.handle('SYNC')), function)
110
-
123
+
124
+ self.sync = lambda function: \
125
+ utils.observer(
126
+ on_call = functional.lazy(write, self.writer.handle('SYNC')),
127
+ function = function)
128
+
111
129
  error = self.writer.handle('ERROR')
112
130
 
113
131
  def write_error(cls, val, traceback):
114
- error(cls, val)
132
+ write(error, cls, val)
115
133
 
116
134
  # self.set_thread_id = functional.partial(utils.set_thread_id, self.writer)
117
135
 
118
- def watch(f): return functional.either(self.thread_switch_monitor, f)
119
-
120
136
  # w = self.writer.handle('TRACE')
121
137
  # def foo(name, *args):
122
138
  # print(f'writing: {self.writer.messages_written} {name} {args}')
123
139
  # w(self.writer.messages_written, name, *args)
124
140
 
125
141
  # tracer = Tracer(tracing_config, writer = foo)
126
- tracer = Tracer(tracing_config, writer = self.writer.handle('TRACE'))
142
+ tracer = Tracer(tracing_config, writer = functional.partial(write, self.writer.handle('TRACE')))
127
143
 
128
- self.wrap_int_to_ext = watch
144
+ # self.wrap_int_to_ext = self.sync
129
145
 
130
- self.on_int_call = functional.mapargs(transform = serialize, function = self.writer.handle('CALL'))
146
+ self.on_int_call = functional.mapargs(transform = serialize, function = functional.partial(write, self.writer.handle('CALL')))
131
147
 
132
- self.on_ext_result = functional.sequence(serialize, self.writer.handle('RESULT'))
148
+ self.on_ext_result = functional.sequence(serialize, functional.partial(write, self.writer.handle('RESULT')))
133
149
 
134
150
  self.on_ext_error = write_error
135
151
 
136
152
  self.ext_apply = self.int_apply = functional.apply
137
153
 
154
+ self.writer.type_serializer[types.ModuleType] = GlobalRef
155
+
138
156
  super().__init__(thread_state = thread_state,
139
157
  tracer = tracer,
140
158
  immutable_types = immutable_types)
@@ -8,7 +8,8 @@ from retracesoftware.proxy.proxytype import *
8
8
  # from retracesoftware.proxy.gateway import gateway_pair
9
9
  from retracesoftware.proxy.record import StubRef, Placeholder
10
10
  from retracesoftware.proxy.proxysystem import ProxySystem, RetraceError
11
- from retracesoftware.proxy.stubfactory import StubFactory, StubFunction
11
+ from retracesoftware.proxy.stubfactory import StubFactory, Stub, StubFunction
12
+ from retracesoftware.proxy.globalref import GlobalRef
12
13
 
13
14
  import os
14
15
  import weakref
@@ -153,12 +154,16 @@ class ReplayProxySystem(ProxySystem):
153
154
  def read_required(self, required):
154
155
  obj = self.readnext()
155
156
  if obj != required:
157
+ print('---------------------------------')
158
+ print('last matching stack')
159
+ print('---------------------------------')
156
160
  if self.last_matching_stack:
157
161
  for line in self.last_matching_stack:
158
162
  print(line)
159
163
 
160
164
  print('---------------------------------')
161
165
  print(f'Replay: {required}')
166
+ print('---------------------------------')
162
167
  for line in utils.stacktrace():
163
168
  print(line)
164
169
  print('---------------------------------')
@@ -196,9 +201,6 @@ class ReplayProxySystem(ProxySystem):
196
201
  for arg in args:
197
202
  self.read_required(arg)
198
203
 
199
- def sync(self, function):
200
- return utils.observer(on_call = functional.always(self.read_sync), function = function)
201
-
202
204
  def __init__(self,
203
205
  thread_state,
204
206
  immutable_types,
@@ -210,25 +212,44 @@ class ReplayProxySystem(ProxySystem):
210
212
  self.reader = stream.reader(path)
211
213
 
212
214
  self.bindings = utils.id_dict()
213
- self.set_thread_id = utils.set_thread_id
215
+ # self.set_thread_id = utils.set_thread_id
214
216
  self.fork_path = fork_path
215
217
  deserialize = functional.walker(self.bindings.get_else_key)
216
218
 
217
219
  # def count(res):
218
220
  # self.messages_read += 1
219
221
  # return res
222
+
223
+ read_res = functional.vector(functional.lazy(getattr, self.reader, 'messages_read'), self.reader)
224
+
225
+ def foo():
226
+ try:
227
+ messages_read, res = read_res()
228
+ if issubclass(type(res), Stub):
229
+ print(f'res: {utils.thread_id()} {messages_read} stub: {type(res)}')
230
+ else:
231
+ print(f'res: {utils.thread_id()} {messages_read} {res}')
232
+
233
+ return res
234
+ except Exception as error:
235
+ print(f'Error reading next result: {error}')
236
+ raise(error)
220
237
 
221
- self.messages = functional.sequence(per_thread_messages(self.reader),
222
- deserialize)
238
+ self.messages = functional.sequence(per_thread_messages(foo), deserialize)
239
+
240
+ # self.messages = functional.sequence(per_thread_messages(self.reader), deserialize)
223
241
 
224
242
  self.stub_factory = StubFactory(thread_state = thread_state, next_result = self.next_result)
225
243
 
226
244
  self.last_matching_stack = None
227
245
 
228
246
  self.reader.type_deserializer[StubRef] = self.stub_factory
247
+ self.reader.type_deserializer[GlobalRef] = lambda ref: ref()
229
248
 
230
- self.read_sync = functional.always(lambda: self.read_required('SYNC'))
231
-
249
+ read_sync = functional.lazy(self.read_required, 'SYNC')
250
+
251
+ self.sync = lambda function: utils.observer(on_call = read_sync, function = function)
252
+
232
253
  super().__init__(thread_state = thread_state,
233
254
  tracer = Tracer(tracing_config, writer = self.trace_writer),
234
255
  immutable_types = immutable_types)
@@ -11,17 +11,28 @@ class ThreadSwitch:
11
11
  def __init__(self, id):
12
12
  self.id = id
13
13
 
14
- def set_thread_id(writer, id):
15
- utils.set_thread_id(writer.handle(ThreadSwitch(id)))
14
+ def __repr__(self):
15
+ return f'ThreadSwitch<{self.id}>'
16
+
17
+ def __str__(self):
18
+ return f'ThreadSwitch<{self.id}>'
19
+
20
+ # def set_thread_id(writer, id):
21
+ # utils.sigtrap(id)
22
+ # utils.set_thread_id(writer.handle(ThreadSwitch(id)))
16
23
 
17
24
  def write_thread_switch(writer):
18
25
  on_thread_switch = functional.repeatedly(functional.sequence(utils.thread_id, writer))
19
26
 
20
27
  return lambda f: utils.thread_aware_proxy(target = f, on_thread_switch = on_thread_switch, sticky = False)
21
28
 
22
- def prefix_with_thread_id(f, current):
29
+ def prefix_with_thread_id(f, thread_id):
30
+ current = None
31
+
23
32
  def next():
24
33
  nonlocal current, f
34
+ if current is None: current = thread_id()
35
+
25
36
  obj = f()
26
37
 
27
38
  while issubclass(type(obj), ThreadSwitch):
@@ -36,7 +47,8 @@ def per_thread_messages(messages):
36
47
  thread_id = utils.thread_id
37
48
  # thread_id = lambda: 'FOOOOO!!!'
38
49
 
39
- demux = utils.demux(source = prefix_with_thread_id(messages, thread_id()), key_function = lambda obj: obj[0])
50
+ demux = utils.demux(source = prefix_with_thread_id(messages, thread_id),
51
+ key_function = lambda obj: obj[0])
40
52
 
41
53
  # def next():
42
54
  # thread,message = demux(thread_id())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: retracesoftware_proxy
3
- Version: 0.1.13
3
+ Version: 0.1.14
4
4
  License: Apache-2.0
5
5
  Requires-Dist: retracesoftware_utils
6
6
  Requires-Dist: retracesoftware_functional
@@ -1,28 +1,29 @@
1
1
  retracesoftware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- retracesoftware/config.json,sha256=WfqWtMeimFWl9aEs0V34Nshb77TmXBeTkwT6alWpN2Q,8779
2
+ retracesoftware/config.json,sha256=JU3LYWZbqBLqiHXDc9fBYVh0owMUcKGw3W-vaVm-roo,9024
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=IUkQx5kr4AnniKZ2gWnnx2is1j_y_eb7nz2UKyHyqSA,18894
9
+ retracesoftware/install/patcher.py,sha256=ryX73_KjdcUCC0oy0Uqel_L3bwfZZldS3CIYQ-XAl_k,20520
10
10
  retracesoftware/install/predicate.py,sha256=tX7NQc0rGkyyHYO3mduYHcJHbw1wczT53m_Dpkzo6do,2679
11
- retracesoftware/install/record.py,sha256=tseF_jV4k4HLPTgBPJdjcahl4EQqagoiisMAdGNC52Q,3257
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
14
  retracesoftware/install/tracer.py,sha256=cHEjiVxIp2iVTJEWndwSbMuiXVyGJQxJYZSGrfpSbCw,5723
15
15
  retracesoftware/install/typeutils.py,sha256=_a1PuwdCsYjG1Nkd77V-flqYtwbD4RkJVKn6Z-xABL4,1813
16
- retracesoftware/proxy/__init__.py,sha256=ZlDZIuUmKFsE9Tvfd2EKGabTepqv8nrbr5pQhCM3IKc,193
16
+ retracesoftware/proxy/__init__.py,sha256=ntIyqKhBRkKEkcW_oOPodikh-mxYl8OXRnSaj-9-Xwc,178
17
17
  retracesoftware/proxy/gateway.py,sha256=xESohWXkiNm4ZutU0RgWUwxjxcBWRQ4rQyxIGQXv_F4,1590
18
+ retracesoftware/proxy/globalref.py,sha256=yXtJsOeBHN9xoEgJWA3MJco-jD2SQUef_fDatA4A6rg,803
18
19
  retracesoftware/proxy/proxyfactory.py,sha256=qhOqDfMJnLDNkQs26JqDB431MwjjRhGQi8xupJ45asg,12272
19
20
  retracesoftware/proxy/proxysystem.py,sha256=ZX6eNT8go-YDbLWD2pq5j_V8DZAHteu-iNfkMO8jLWg,7567
20
- retracesoftware/proxy/proxytype.py,sha256=H6SJKX0izor1yLOK_QxRlfKLcJC08eMuIYJ1amnoZvQ,12812
21
- retracesoftware/proxy/record.py,sha256=vtNsoTHP5gsBVJ6dTGHR7QXHGbKm0eONfGcXOb9fhFk,4696
22
- retracesoftware/proxy/replay.py,sha256=Ckkl7v-n-4KWEJXENOsMjmtNLguYudVgLrguVLLCMEA,7742
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
23
24
  retracesoftware/proxy/stubfactory.py,sha256=37UX1r8HCAbASTwPdz8QKCrg72NQmM5PsiCho7N2nzg,5129
24
- retracesoftware/proxy/thread.py,sha256=-SvnyVbANkmX2lLRpOvFtkpdpAoF6DhnnYdOOs7Q8vo,1379
25
- retracesoftware_proxy-0.1.13.dist-info/METADATA,sha256=yQJQrwJgTMPNl8u68MMD7QycdnOOrIW04JersxwXHXk,203
26
- retracesoftware_proxy-0.1.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- retracesoftware_proxy-0.1.13.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
28
- retracesoftware_proxy-0.1.13.dist-info/RECORD,,
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,,