retracesoftware-proxy 0.1.0__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.
@@ -0,0 +1,280 @@
1
+ import retracesoftware_utils as utils
2
+ import retracesoftware.functional as functional
3
+
4
+ import types
5
+
6
+ class Proxy:
7
+ __slots__ = []
8
+
9
+ class Stub(Proxy):
10
+ __slots__ = []
11
+
12
+ class DynamicProxy(Proxy):
13
+ __slots__ = []
14
+
15
+ class ExtendingProxy(Proxy):
16
+ __slots__ = []
17
+
18
+ class InternalProxy:
19
+ __slots__ = []
20
+
21
+ def superdict(cls):
22
+ result = {}
23
+ for cls in list(reversed(cls.__mro__))[1:]:
24
+ result.update(cls.__dict__)
25
+
26
+ return result
27
+
28
+ def is_method_descriptor(obj):
29
+ return isinstance(obj, types.FunctionType) or \
30
+ (isinstance(obj, (types.WrapperDescriptorType, types.MethodDescriptorType)) and obj.__objclass__ != object)
31
+
32
+ def proxy_method_descriptors(cls, handler):
33
+ for name, target in cls.__dict__.items():
34
+ if is_method_descriptor(target):
35
+ proxied = utils.wrapped_function(handler = handler, target = target)
36
+ setattr(cls, name, proxied)
37
+
38
+ def methods(cls):
39
+ for name,value in superdict(cls).items():
40
+ if is_descriptor(value) and is_method_descriptor(value):
41
+ yield name
42
+
43
+ def is_descriptor(obj):
44
+ return hasattr(obj, '__get__') or hasattr(obj, '__set__') or hasattr(obj, '__delete__')
45
+
46
+ class Named:
47
+ def __init__(self, name):
48
+ self.__name__ = name
49
+
50
+ class DescriptorStub:
51
+
52
+ __slots__ = ['handler', 'name']
53
+
54
+ def __init__(self, handler, name):
55
+ self.handler = handler
56
+ self.name = name
57
+
58
+ def __get__(self, instance, owner):
59
+ return self.handler(Named('getattr'), self.name)
60
+
61
+ def __set__(self, instance, value):
62
+ return self.handler(Named('setattr'), self.name, value)
63
+
64
+ def __delete__(self, instance):
65
+ return self.handler(Named('delattr'), self.name)
66
+
67
+ def stubtype_from_spec(handler, module, name, methods, members):
68
+
69
+ spec = {
70
+ '__module__': module,
71
+ }
72
+
73
+ for method in methods:
74
+ spec[method] = utils.wrapped_function(
75
+ handler = handler, target = Named(method))
76
+
77
+ for member in members:
78
+ spec[member] = DescriptorStub(handler = handler, name = member)
79
+
80
+ return type(name, (Stub, DynamicProxy,), spec)
81
+
82
+ # stubtype.__new__ = thread_state.dispatch(disabled__new__, internal = stub.__new__, external = stub.__new__)
83
+ # stub.__retrace_unproxied__ = cls
84
+
85
+ def dynamic_stubtype(handler, cls):
86
+
87
+ assert not issubclass(cls, BaseException)
88
+
89
+ blacklist = ['__getattribute__', '__hash__', '__del__', '__init__', '__call__']
90
+
91
+ to_proxy = [m for m in methods(cls) if m not in blacklist]
92
+
93
+ def wrap(name): return utils.wrapped_function(handler = handler,
94
+ target = Named(name))
95
+
96
+ spec = { name: wrap(name) for name in to_proxy }
97
+
98
+ spec['__getattr__'] = wrap('__getattr__')
99
+ spec['__setattr__'] = wrap('__setattr__')
100
+
101
+ if utils.yields_callable_instances(cls):
102
+ spec['__call__'] = handler
103
+
104
+ spec['__retrace_target_class__'] = cls
105
+ spec['__class__'] = property(functional.repeatedly(cls))
106
+
107
+ name = f'retrace.proxied.{cls.__module__}.{cls.__name__}'
108
+
109
+ return type(name, (Stub, DynamicProxy), spec)
110
+
111
+ def dynamic_proxytype(handler, cls):
112
+
113
+ assert not issubclass(cls, BaseException)
114
+
115
+ blacklist = ['__getattribute__', '__hash__', '__del__', '__init__', '__call__']
116
+
117
+ to_proxy = [m for m in methods(cls) if m not in blacklist]
118
+
119
+ def wrap(target): return utils.wrapped_function(handler = handler, target = target)
120
+
121
+ spec = { name: wrap(getattr(cls, name)) for name in to_proxy }
122
+
123
+ spec['__getattr__'] = wrap(getattr)
124
+ spec['__setattr__'] = wrap(setattr)
125
+
126
+ if utils.yields_callable_instances(cls):
127
+ spec['__call__'] = handler
128
+
129
+ spec['__retrace_target_class__'] = cls
130
+
131
+ target_type = functional.compose(utils.unwrap, functional.typeof)
132
+ spec['__class__'] = property(target_type)
133
+
134
+ name = f'retrace.proxied.{cls.__module__}.{cls.__name__}'
135
+
136
+ return type(name, (utils.Wrapped, DynamicProxy), spec)
137
+
138
+ def dynamic_int_proxytype(handler, cls, bind):
139
+ proxytype = dynamic_proxytype(handler = handler, cls = cls)
140
+ proxytype.__new__ = functional.sequence(proxytype.__new__, functional.side_effect(bind))
141
+ return proxytype
142
+
143
+ class DescriptorProxy:
144
+
145
+ __slots__ = ['handler', 'proxytype', 'name']
146
+
147
+ def __init__(self, proxytype, handler, name):
148
+ self.proxytype = proxytype
149
+ self.handler = handler
150
+ self.name = name
151
+
152
+ def __get__(self, instance, owner):
153
+ inst = owner if instance is None else instance
154
+ getter = functional.partial(getattr, super(self.proxytype, inst))
155
+ return self.handler(getter, self.name)
156
+
157
+ def __set__(self, instance, value):
158
+ setter = functional.partial(setattr, super(self.proxytype, instance))
159
+ return self.handler(setter, self.name, value)
160
+
161
+ def __delete__(self, instance):
162
+ deleter = functional.partial(delattr, super(self.proxytype, instance))
163
+ return self.handler(deleter, self.name)
164
+
165
+
166
+ blacklist = ['__getattribute__', '__hash__', '__del__']
167
+
168
+ # if the type can be patched, thats better, all new instances must be of correct type
169
+
170
+ def extending_proxytype(cls, thread_state, ext_handler, int_handler, on_subclass_new, is_stub = False):
171
+
172
+ assert not issubclass(cls, BaseException)
173
+
174
+ def init_subclass(subclass, **kwargs):
175
+ print(f'In init_subclass: {subclass} {kwargs}')
176
+ # subclass.__retrace_unproxied__ = create_unproxied_type(subclass)
177
+
178
+ proxy_method_descriptors(cls = subclass, handler = int_handler)
179
+
180
+ if not issubclass(subclass, InternalProxy):
181
+ subclass.__new__ = functional.compose(subclass.__new__, functional.side_effect(on_subclass_new))
182
+ subclass.__bases__ = subclass.__bases__ + (InternalProxy,)
183
+
184
+ slots = { "__slots__": (), "__init_subclass__": init_subclass }
185
+
186
+ def wrap(target): return utils.wrapped_function(handler = ext_handler, target = target)
187
+
188
+ descriptors = []
189
+
190
+ for name,value in superdict(cls).items():
191
+ if name not in blacklist:
192
+ if is_method_descriptor(value):
193
+ slots[name] = wrap(getattr(cls, name))
194
+ elif is_descriptor(value):
195
+ descriptors.append(name)
196
+
197
+ name = f'retrace.extended.{cls.__module__}.{cls.__name__}'
198
+
199
+ extended = type(name, (cls, ExtendingProxy), slots)
200
+
201
+ for name in descriptors:
202
+ proxy = DescriptorProxy(handler = ext_handler, name = name, proxytype = extended)
203
+ setattr(extended, name, proxy)
204
+
205
+ # def disabled__new__(subcls, *args, **kwargs):
206
+ # print('IN Diabled new!!!')
207
+
208
+ # instance = cls.__new__(subcls.__retrace_unproxied__, *args, **kwargs)
209
+ # instance.__init__(*args, **kwargs)
210
+ # return instance
211
+
212
+ # __new__ = functional.compose(cls.__new__, functional.side_effect(on_new))
213
+ if is_stub:
214
+ def __new__(cls, *args, **kwargs):
215
+ instance = utils.create_stub_object(cls)
216
+ # print(instance is None)
217
+ # utils.sigtrap(None)
218
+ return instance
219
+
220
+ extended.__new__ = thread_state.dispatch(cls.__new__, internal = __new__, external = __new__)
221
+
222
+ # extended.__retrace_unproxied__ = cls
223
+
224
+ return extended
225
+
226
+
227
+ def stubtype(cls, result, thread_state, handler):
228
+
229
+ name = f'retrace.stub.{cls.__module__}.{cls.__name__}'
230
+
231
+ slots = {}
232
+
233
+ def wrap(name):
234
+ return utils.wrapped_function(
235
+ handler = handler,
236
+ target = StubMethodDescriptor(name = name, result = result))
237
+
238
+ for name,value in superdict(cls).items():
239
+ if name not in blacklist:
240
+ if is_method_descriptor(value):
241
+ slots[name] = wrap(name)
242
+ elif is_descriptor(value):
243
+ slots[name] = DescriptorStub(handler = handler, name = name)
244
+
245
+ def disabled__new__(subcls, *args, **kwargs):
246
+ instance = cls.__new__(subcls.__retrace_unproxied__, *args, **kwargs)
247
+ instance.__init__(*args, **kwargs)
248
+ return instance
249
+
250
+ stub = type(name, (Stub,), slots)
251
+
252
+ stub.__new__ = thread_state.dispatch(disabled__new__, internal = stub.__new__, external = stub.__new__)
253
+
254
+ stub.__retrace_unproxied__ = cls
255
+
256
+ return stub
257
+
258
+ def create_unproxied_type(cls):
259
+ name = f'{cls.__module__}.{cls.__name__}'
260
+
261
+ def unproxy_type(cls):
262
+ return cls.__retrace_unproxied__ if issubclass(cls, ExtendingProxy) else cls
263
+
264
+ return type(name, tuple(map(unproxy_type, cls.__bases__)), dict(cls.__dict__))
265
+
266
+ def make_extensible(cls, handler, on_new):
267
+
268
+ cls.__retrace_unproxied__ = cls.__base__
269
+
270
+ def init_subclass(*args, **kwargs):
271
+ print(f'In init_subclass: {args} {kwargs}')
272
+ # subclass.__retrace_unproxied__ = create_unproxied_type(subclass)
273
+
274
+ # proxy_method_descriptors(cls = subclass, handler = handler)
275
+
276
+ # if not issubclass(subclass, InternalProxy):
277
+ # cls.__new__ = functional.compose(cls.__new__, functional.side_effect(on_new))
278
+ # cls.__bases__ = cls.__bases__ + (InternalProxy,)
279
+
280
+ cls.__init_subclass__ = init_subclass
@@ -0,0 +1,133 @@
1
+ import retracesoftware.functional as functional
2
+ import retracesoftware_utils as utils
3
+
4
+ from retracesoftware.proxy.proxytype import dynamic_proxytype, superdict, is_descriptor, extending_proxytype, dynamic_int_proxytype, make_extensible
5
+ from retracesoftware.proxy.gateway import gateway_pair
6
+ from retracesoftware.proxy.proxysystem import ProxySystem
7
+
8
+ import sys
9
+
10
+ class ExtendedProxy:
11
+ __slots__ = []
12
+
13
+ class ProxyRef:
14
+ def __init__(self, module, name):
15
+ self.module = module
16
+ self.name = name
17
+
18
+ def resolve(self):
19
+ return getattr(sys.modules[self.module], self.name)
20
+
21
+ class ProxySpec(ProxyRef):
22
+ def __init__(self, module, name, methods, members):
23
+ super().__init__(module, name)
24
+ self.methods = methods
25
+ self.members = members
26
+
27
+ def __str__(self):
28
+ return f'ProxySpec(module = {self.module}, name = {self.name}, methods = {self.methods}, members = {self.members})'
29
+
30
+ def keys_where_value(pred, dict):
31
+ for key,value in dict.items():
32
+ if pred(value): yield key
33
+
34
+ def resolveable(obj):
35
+ try:
36
+ return getattr(sys.modules[obj.__module__], obj.__name__) is obj
37
+ except:
38
+ return False
39
+
40
+ class ExtProxytype:
41
+
42
+ def __init__(self, gateway, extended_types, writer):
43
+ self.gateway = gateway
44
+ self.writer = writer
45
+ self.extended_types = extended_types
46
+
47
+ def __call__(self, cls):
48
+ assert isinstance(cls, type)
49
+
50
+ if cls in self.extended_types:
51
+ return functional.side_effect(lambda obj: utils.set_type(obj, self.extended_types[cls]))
52
+ else:
53
+ if resolveable(cls):
54
+ ref = self.writer.handle(ProxyRef(name = cls.__name__, module = cls.__module__))
55
+ else:
56
+ blacklist = ['__getattribute__']
57
+ descriptors = {k: v for k,v in superdict(cls).items() if k not in blacklist and is_descriptor(v) }
58
+
59
+ methods = [k for k, v in descriptors.items() if utils.is_method_descriptor(v)]
60
+ members = [k for k, v in descriptors.items() if not utils.is_method_descriptor(v)]
61
+
62
+ ref = self.writer.handle(ProxySpec(name = cls.__name__,
63
+ module = cls.__module__,
64
+ methods = methods,
65
+ members = members))
66
+
67
+ proxytype = dynamic_proxytype(handler = self.gateway, cls = cls)
68
+
69
+ self.writer.type_serializer[proxytype] = functional.constantly(ref)
70
+ return proxytype
71
+
72
+
73
+ # when
74
+ class RecordProxySystem(ProxySystem):
75
+
76
+ def __init__(self, thread_state, immutable_types, tracer, writer):
77
+ super().__init__(thread_state = thread_state)
78
+
79
+ self.immutable_types = immutable_types
80
+
81
+ self.extended_types = {}
82
+ self.writer = writer
83
+ self.bind = writer.placeholder
84
+
85
+ # on_ext_result = writer.handle('RESULT')
86
+ on_ext_result = functional.if_then_else(
87
+ functional.isinstanceof(str), writer.handle('RESULT'), writer)
88
+
89
+ def int_proxytype(gateway):
90
+ return lambda cls: dynamic_int_proxytype(handler = gateway, cls = cls, bind = self.bind)
91
+
92
+ def ext_proxytype(gateway):
93
+ return ExtProxytype(gateway = gateway, writer = writer, extended_types = self.extended_types)
94
+
95
+ error = writer.handle('ERROR')
96
+
97
+ def write_error(cls, val, traceback):
98
+ error(cls, val)
99
+
100
+ self.ext_handler, self.int_handler = gateway_pair(
101
+ thread_state,
102
+ tracer,
103
+ immutable_types = immutable_types,
104
+ int_proxytype = int_proxytype,
105
+ ext_proxytype = ext_proxytype,
106
+ on_int_call = writer.handle('CALL'),
107
+ on_ext_result = functional.side_effect(on_ext_result),
108
+ on_ext_error = write_error)
109
+
110
+ def extend_type(self, base):
111
+
112
+ if base in self.extended_types:
113
+ return self.extended_types[base]
114
+
115
+ # self.tracer.log('proxy.ext.new.extended', f'{base.__module__}.{base.__name__}')
116
+
117
+ extended = extending_proxytype(
118
+ cls = base,
119
+ thread_state = self.thread_state,
120
+ ext_handler = self.ext_handler,
121
+ int_handler = self.int_handler,
122
+ on_subclass_new = self.bind,
123
+ is_stub = False)
124
+
125
+ ref = self.writer.handle(ProxyRef(name = base.__name__, module = base.__module__,))
126
+ self.writer.type_serializer[extended] = functional.constantly(ref)
127
+
128
+ # make_extensible(cls = extended, handler = self.int_handler, on_new = self.writer.placeholder)
129
+
130
+ self.immutable_types.add(extended)
131
+ self.extended_types[base] = extended
132
+
133
+ return extended
@@ -0,0 +1,110 @@
1
+ import retracesoftware.functional as functional
2
+ import retracesoftware_utils as utils
3
+
4
+ from retracesoftware.proxy.proxytype import dynamic_proxytype, dynamic_int_proxytype, extending_proxytype, make_extensible, dynamic_stubtype, stubtype_from_spec, Stub
5
+ from retracesoftware.proxy.gateway import gateway_pair
6
+
7
+ from retracesoftware.proxy.record import ProxyRef, ProxySpec
8
+ from retracesoftware.proxy.proxysystem import ProxySystem
9
+
10
+ import os
11
+
12
+ # we can have a dummy method descriptor, its has a __name__ and when called, returns the next element
13
+
14
+ # for types, we can patch the __new__ method
15
+ # do it from C and immutable types can be patched too
16
+ # patch the tp_new pointer?
17
+
18
+ class ReplayProxySystem(ProxySystem):
19
+
20
+ def stubtype(self, cls):
21
+ return dynamic_proxytype(handler = self.ext_handler, cls = cls)
22
+
23
+ def stubtype_from_spec(self, spec):
24
+ print (f'FOOO!!! {spec}')
25
+ return stubtype_from_spec(
26
+ handler = self.ext_handler,
27
+ module = spec.module,
28
+ name = spec.name,
29
+ methods = spec.methods,
30
+ members = spec.members)
31
+
32
+ @utils.striptraceback
33
+ def next_result(self):
34
+ while True:
35
+ next = self.reader()
36
+
37
+ if next == 'CALL':
38
+ func = self.reader()
39
+ args = self.reader()
40
+ kwargs = self.reader()
41
+
42
+ try:
43
+ func(*args, **kwargs)
44
+ except:
45
+ pass
46
+
47
+ elif next == 'RESULT':
48
+ return self.reader()
49
+ elif next == 'ERROR':
50
+ err_type = self.reader()
51
+ err_value = self.reader()
52
+ utils.raise_exception(err_type, err_value)
53
+ else:
54
+ assert not isinstance(next, str)
55
+ return next
56
+
57
+ def __init__(self, thread_state, immutable_types, tracer, reader):
58
+ # self.writer = writer
59
+ super().__init__(thread_state = thread_state)
60
+ self.immutable_types = immutable_types
61
+ self.reader = reader
62
+ self.bind = self.reader.supply
63
+
64
+ add_stubtype = functional.side_effect(immutable_types.add)
65
+
66
+ reader.type_deserializer[ProxyRef] = functional.sequence(lambda ref: ref.resolve(), self.stubtype, add_stubtype)
67
+ reader.type_deserializer[ProxySpec] = functional.sequence(self.stubtype_from_spec, add_stubtype)
68
+
69
+ # on_ext_result = functional.if_then_else(
70
+ # functional.is_instanceof(str), writer.handle('RESULT'), writer)
71
+
72
+ def int_proxytype(gateway):
73
+ return lambda cls: dynamic_int_proxytype(handler = gateway, cls = cls, bind = self.bind)
74
+
75
+ def is_stub_type(obj):
76
+ return functional.typeof(obj) is type and issubclass(obj, Stub)
77
+
78
+ create_stubs = functional.walker(functional.when(is_stub_type, lambda cls: cls()))
79
+
80
+ ext_apply = functional.repeatedly(functional.sequence(self.next_result, create_stubs))
81
+
82
+ self.ext_handler, self.int_handler = gateway_pair(
83
+ thread_state,
84
+ tracer,
85
+ immutable_types = immutable_types,
86
+ ext_apply = ext_apply,
87
+ int_proxytype = int_proxytype,
88
+ ext_proxytype = functional.identity)
89
+
90
+ def extend_type(self, base):
91
+
92
+ # ok, how to provide __getattr__ style access,
93
+
94
+ extended = extending_proxytype(
95
+ cls = base,
96
+ thread_state = self.thread_state,
97
+ int_handler = self.int_handler,
98
+ ext_handler = self.ext_handler,
99
+ on_subclass_new = self.bind,
100
+ is_stub = True)
101
+
102
+ self.immutable_types.add(extended)
103
+ # proxytype = extending_proxytype(base)
104
+
105
+ # make_extensible(cls = extended,
106
+ # int_handler = self.int_handler,
107
+ # ext_handler = self.ext_handler,
108
+ # on_new = self.reader.supply)
109
+
110
+ return extended
@@ -0,0 +1,11 @@
1
+ import retracesoftware.functional as functional
2
+ import retracesoftware_utils as utils
3
+
4
+ class ThreadSwitch:
5
+ def __init__(self, thread_id):
6
+ self.thread_id = thread_id
7
+
8
+
9
+ def thread_aware_writer(writer):
10
+ on_thread_switch = functional.sequence(utils.thread_id(), writer.handle('THREAD_SWITCH'))
11
+ return utils.threadawareproxy(on_thread_switch = on_thread_switch, target = writer)
@@ -0,0 +1,12 @@
1
+ Metadata-Version: 2.4
2
+ Name: retracesoftware_proxy
3
+ Version: 0.1.0
4
+ Summary: Proxy layer for retracesoftware runtime
5
+ License: Apache-2.0
6
+ Requires-Python: >=3.11
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: retracesoftware_utils
9
+ Requires-Dist: retracesoftware_functional
10
+ Requires-Dist: retracesoftware_stream
11
+
12
+ # proxy
@@ -0,0 +1,26 @@
1
+ retracesoftware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ retracesoftware/config.json,sha256=aedf9CXxOBkcQk3BJVrh0GuBkIAjBGBRlrTXdoRJ-MY,8108
3
+ retracesoftware/install/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ retracesoftware/install/config.py,sha256=EzE5ifQF2lo--hu2njI4T0FJ-zlnWDJV6i7x0DMkVTw,1364
5
+ retracesoftware/install/edgecases.py,sha256=NR3lyvad9sRsyeDv_Ya8V4xMgPsMPOi9rMcnFOJGOEA,6330
6
+ retracesoftware/install/globals.py,sha256=F8XvIoZQQ10gSRalk30dvdKllxlwxkaggYY6FogLDxY,510
7
+ retracesoftware/install/install.py,sha256=VNtivSf6A9wtLzIkZKJQ7thPkYTdjtTmxaIkPUOwLhg,5942
8
+ retracesoftware/install/patcher.py,sha256=5DGzVaNM53Z_KWz-wWQxlr1WqeWuuxKoVZyN5tNGuTw,15866
9
+ retracesoftware/install/predicate.py,sha256=tX7NQc0rGkyyHYO3mduYHcJHbw1wczT53m_Dpkzo6do,2679
10
+ retracesoftware/install/record.py,sha256=mJyz8ZFnrveDCvrUHksTXaFZbBX10yqH6UBV1QH5EwA,4370
11
+ retracesoftware/install/references.py,sha256=0nUY_9BkeFz2imcw97rcJNq2jqISCB8dysBbCrh1eCo,1623
12
+ retracesoftware/install/replay.py,sha256=ox43e8k_uvn9w6vf6rt8f3KwaXcBVx2GbvWaLZpwqR4,4952
13
+ retracesoftware/install/tracer.py,sha256=dFhXKkmvGLF-_WzQvZXxNO1Ftj6crH1SM6pGBU4cqMY,4586
14
+ retracesoftware/install/typeutils.py,sha256=_a1PuwdCsYjG1Nkd77V-flqYtwbD4RkJVKn6Z-xABL4,1813
15
+ retracesoftware/proxy/__init__.py,sha256=NaGsqoj4X3NpHfTAmRIfsXM16R6AGE99ciQeknj3sXc,119
16
+ retracesoftware/proxy/gateway.py,sha256=JtSwwllXiUykpNdojbK7okyYadRnILGgpRCHxAQijZs,3911
17
+ retracesoftware/proxy/proxyfactory.py,sha256=2PgC0NtDbRmhmU--caTiQDsaF8s1h9tavQxvPIow_bM,11912
18
+ retracesoftware/proxy/proxysystem.py,sha256=kDdtea-vCcsqdwSwmgGBBvVrIRl6Gwb89Wgx6VSIwgQ,759
19
+ retracesoftware/proxy/proxytype.py,sha256=P78aL3_aemG8p3NKmP4YfAcwC8IDr7LIq5-dkV4n0Ec,9038
20
+ retracesoftware/proxy/record.py,sha256=yI8CH0oOyrAyvjy9JsawgkQh9jYTlg9sQ_CcejrFKO4,4772
21
+ retracesoftware/proxy/replay.py,sha256=usbb2OTX6uJG_zialqHk9en0mxD2xEhjPajMZDjZnkQ,3940
22
+ retracesoftware/proxy/thread.py,sha256=9_6gWiRbir77f9kelpvXaTWviRfZo0ACkKPdGNbrq2Q,394
23
+ retracesoftware_proxy-0.1.0.dist-info/METADATA,sha256=c24hdDKP-miIrX6mM1yVyXCQeu0ozLP4N0ebtqiGccw,324
24
+ retracesoftware_proxy-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
+ retracesoftware_proxy-0.1.0.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
26
+ retracesoftware_proxy-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ retracesoftware