retracesoftware-proxy 0.1.1__py3-none-any.whl → 0.1.3__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.
- retracesoftware/install/install.py +1 -7
- retracesoftware/install/patcher.py +22 -3
- retracesoftware/install/record.py +7 -0
- retracesoftware/install/references.py +2 -1
- retracesoftware/install/replay.py +1 -1
- retracesoftware/install/tracer.py +16 -14
- retracesoftware/proxy/gateway.py +3 -112
- retracesoftware/proxy/proxyfactory.py +194 -194
- retracesoftware/proxy/proxysystem.py +77 -61
- retracesoftware/proxy/proxytype.py +184 -103
- retracesoftware/proxy/record.py +85 -88
- retracesoftware/proxy/replay.py +55 -33
- retracesoftware/proxy/stubfactory.py +140 -0
- retracesoftware/proxy/thread.py +1 -1
- {retracesoftware_proxy-0.1.1.dist-info → retracesoftware_proxy-0.1.3.dist-info}/METADATA +1 -1
- retracesoftware_proxy-0.1.3.dist-info/RECORD +27 -0
- retracesoftware_proxy-0.1.1.dist-info/RECORD +0 -26
- {retracesoftware_proxy-0.1.1.dist-info → retracesoftware_proxy-0.1.3.dist-info}/WHEEL +0 -0
- {retracesoftware_proxy-0.1.1.dist-info → retracesoftware_proxy-0.1.3.dist-info}/top_level.txt +0 -0
retracesoftware/proxy/record.py
CHANGED
|
@@ -1,41 +1,24 @@
|
|
|
1
1
|
import retracesoftware.functional as functional
|
|
2
|
-
import
|
|
2
|
+
import retracesoftware.utils as utils
|
|
3
3
|
import retracesoftware.stream as stream
|
|
4
4
|
|
|
5
|
-
from retracesoftware.proxy.proxytype import
|
|
5
|
+
from retracesoftware.proxy.proxytype import *
|
|
6
6
|
# from retracesoftware.proxy.gateway import gateway_pair
|
|
7
7
|
from retracesoftware.proxy.proxysystem import ProxySystem
|
|
8
8
|
from retracesoftware.proxy.thread import write_thread_switch
|
|
9
9
|
from retracesoftware.install.tracer import Tracer
|
|
10
|
+
from retracesoftware.proxy.stubfactory import StubRef, ExtendedRef
|
|
11
|
+
|
|
10
12
|
import sys
|
|
11
13
|
import os
|
|
12
14
|
import types
|
|
15
|
+
import gc
|
|
13
16
|
|
|
14
17
|
class Placeholder:
|
|
15
18
|
__slots__ = ['id', '__weakref__']
|
|
16
19
|
|
|
17
20
|
def __init__(self, id):
|
|
18
21
|
self.id = id
|
|
19
|
-
|
|
20
|
-
class ExtendedProxy:
|
|
21
|
-
__slots__ = []
|
|
22
|
-
|
|
23
|
-
class ProxyRef:
|
|
24
|
-
def __init__(self, module, name):
|
|
25
|
-
self.module = module
|
|
26
|
-
self.name = name
|
|
27
|
-
|
|
28
|
-
def resolve(self):
|
|
29
|
-
return getattr(sys.modules[self.module], self.name)
|
|
30
|
-
|
|
31
|
-
class ProxySpec(ProxyRef):
|
|
32
|
-
def __init__(self, module, name, methods, members):
|
|
33
|
-
super().__init__(module, name)
|
|
34
|
-
self.methods = methods
|
|
35
|
-
self.members = members
|
|
36
|
-
|
|
37
|
-
def __str__(self):
|
|
38
|
-
return f'ProxySpec(module = {self.module}, name = {self.name}, methods = {self.methods}, members = {self.members})'
|
|
39
22
|
|
|
40
23
|
def keys_where_value(pred, dict):
|
|
41
24
|
for key,value in dict.items():
|
|
@@ -101,10 +84,10 @@ class RecordProxySystem(ProxySystem):
|
|
|
101
84
|
|
|
102
85
|
self.writer = stream.writer(path)
|
|
103
86
|
|
|
104
|
-
w = self.writer.handle('TRACE')
|
|
105
|
-
def trace_writer(*args):
|
|
106
|
-
|
|
107
|
-
|
|
87
|
+
# w = self.writer.handle('TRACE')
|
|
88
|
+
# def trace_writer(*args):
|
|
89
|
+
# print(f'Trace: {args}')
|
|
90
|
+
# w(*args)
|
|
108
91
|
|
|
109
92
|
self.extended_types = {}
|
|
110
93
|
self.bindings = utils.id_dict()
|
|
@@ -116,17 +99,7 @@ class RecordProxySystem(ProxySystem):
|
|
|
116
99
|
utils.thread_switch_monitor(
|
|
117
100
|
functional.repeatedly(functional.sequence(utils.thread_id, self.writer)))
|
|
118
101
|
|
|
119
|
-
# self.sync = lambda function: functional.observer(on_call = functional.always(writer.handle('SYNC')), function = function)
|
|
120
102
|
self.sync = lambda function: functional.firstof(thread_switch_monitor, functional.always(self.writer.handle('SYNC')), function)
|
|
121
|
-
|
|
122
|
-
# trace_handle = writer.handle('TRACE')
|
|
123
|
-
# tracer = Tracer(tracing_config, writer = trace_handle)
|
|
124
|
-
|
|
125
|
-
# on_ext_result = writer.handle('RESULT')
|
|
126
|
-
# on_ext_result = functional.if_then_else(
|
|
127
|
-
# functional.isinstanceof(str), self.writer.handle('RESULT'), functional.sequence(serialize, self.writer))
|
|
128
|
-
|
|
129
|
-
# on_int_call = functional.mapargs(transform = serialize, function = self.writer.handle('CALL'))
|
|
130
103
|
|
|
131
104
|
error = self.writer.handle('ERROR')
|
|
132
105
|
|
|
@@ -137,25 +110,7 @@ class RecordProxySystem(ProxySystem):
|
|
|
137
110
|
|
|
138
111
|
def watch(f): return functional.either(thread_switch_monitor, f)
|
|
139
112
|
|
|
140
|
-
tracer = Tracer(tracing_config, writer =
|
|
141
|
-
|
|
142
|
-
# def wrap_int_to_ext(self, obj): return obj
|
|
143
|
-
# def wrap_ext_to_int(self, obj): return obj
|
|
144
|
-
|
|
145
|
-
# def on_int_call(self, func, *args, **kwargs):
|
|
146
|
-
# pass
|
|
147
|
-
|
|
148
|
-
# def on_ext_result(self, result):
|
|
149
|
-
# pass
|
|
150
|
-
|
|
151
|
-
# def on_ext_error(self, err_type, err_value, err_tarceback):
|
|
152
|
-
# pass
|
|
153
|
-
|
|
154
|
-
# def ext_apply(self, func, *args, **kwargs):
|
|
155
|
-
# return func(*args, **kwargs)
|
|
156
|
-
|
|
157
|
-
# def int_apply(self, func, *args, **kwargs):
|
|
158
|
-
# return func(*args, **kwargs)
|
|
113
|
+
tracer = Tracer(tracing_config, writer = self.writer.handle('TRACE'))
|
|
159
114
|
|
|
160
115
|
self.wrap_int_to_ext = watch
|
|
161
116
|
|
|
@@ -171,22 +126,50 @@ class RecordProxySystem(ProxySystem):
|
|
|
171
126
|
self.ext_apply = self.int_apply = functional.apply
|
|
172
127
|
|
|
173
128
|
super().__init__(thread_state = thread_state, tracer = tracer, immutable_types = immutable_types)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
# on_ext_result = on_ext_result,
|
|
177
|
-
# on_ext_error = write_error)
|
|
129
|
+
|
|
130
|
+
def dynamic_ext_proxytype(self, cls):
|
|
178
131
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
132
|
+
proxytype = super().dynamic_ext_proxytype(cls)
|
|
133
|
+
|
|
134
|
+
blacklist = ['__class__', '__dict__', '__module__', '__doc__']
|
|
135
|
+
|
|
136
|
+
methods = []
|
|
137
|
+
members = []
|
|
138
|
+
|
|
139
|
+
for key,value in proxytype.__dict__.items():
|
|
140
|
+
if key not in blacklist:
|
|
141
|
+
if utils.is_method_descriptor(value):
|
|
142
|
+
methods.append(key)
|
|
143
|
+
elif not key.startswith("__retrace"):
|
|
144
|
+
members.append(key)
|
|
145
|
+
|
|
146
|
+
ref = self.writer.handle(StubRef(
|
|
147
|
+
name = cls.__name__,
|
|
148
|
+
module = cls.__module__,
|
|
149
|
+
methods = methods,
|
|
150
|
+
members = members))
|
|
151
|
+
|
|
152
|
+
# list(proxytype.__dict__.keys())
|
|
153
|
+
|
|
154
|
+
# if resolveable_name(cls):
|
|
155
|
+
# module, name = resolveable_name(cls)
|
|
156
|
+
# ref = self.writer.handle(StubRef(type = 'dynamic', name = name, module = module))
|
|
157
|
+
# else:
|
|
158
|
+
# blacklist = ['__getattribute__']
|
|
159
|
+
# descriptors = {k: v for k,v in superdict(cls).items() if k not in blacklist and is_descriptor(v) }
|
|
160
|
+
|
|
161
|
+
# methods = [k for k, v in descriptors.items() if utils.is_method_descriptor(v)]
|
|
162
|
+
# members = [k for k, v in descriptors.items() if not utils.is_method_descriptor(v)]
|
|
163
|
+
|
|
164
|
+
# ref = self.writer.handle(ProxySpec(name = cls.__name__,
|
|
165
|
+
# module = cls.__module__,
|
|
166
|
+
# methods = methods,
|
|
167
|
+
# members = members))
|
|
168
|
+
|
|
169
|
+
self.writer.type_serializer[proxytype] = functional.constantly(ref)
|
|
170
|
+
|
|
171
|
+
return proxytype
|
|
172
|
+
|
|
190
173
|
def ext_proxytype(self, cls):
|
|
191
174
|
assert isinstance(cls, type), f"record.proxytype requires a type but was passed: {cls}"
|
|
192
175
|
|
|
@@ -194,31 +177,45 @@ class RecordProxySystem(ProxySystem):
|
|
|
194
177
|
|
|
195
178
|
proxytype = super().ext_proxytype(cls)
|
|
196
179
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
blacklist = ['__getattribute__']
|
|
202
|
-
descriptors = {k: v for k,v in superdict(cls).items() if k not in blacklist and is_descriptor(v) }
|
|
180
|
+
assert resolve(cls) is cls
|
|
181
|
+
|
|
182
|
+
# ref = self.writer.handle(StubRef(name = cls.__name__,
|
|
183
|
+
# module = cls.__module__))
|
|
203
184
|
|
|
204
|
-
|
|
205
|
-
|
|
185
|
+
# if resolveable_name(cls):
|
|
186
|
+
# module, name = resolveable_name(cls)
|
|
187
|
+
# ref = self.writer.handle(StubRef(name = cls.__name__, module = cls.__module__))
|
|
188
|
+
# else:
|
|
189
|
+
# blacklist = ['__getattribute__']
|
|
190
|
+
# descriptors = {k: v for k,v in superdict(cls).items() if k not in blacklist and is_descriptor(v) }
|
|
206
191
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
192
|
+
# methods = [k for k, v in descriptors.items() if utils.is_method_descriptor(v)]
|
|
193
|
+
# members = [k for k, v in descriptors.items() if not utils.is_method_descriptor(v)]
|
|
194
|
+
|
|
195
|
+
# ref = self.writer.handle(ProxySpec(name = cls.__name__,
|
|
196
|
+
# module = cls.__module__,
|
|
197
|
+
# methods = methods,
|
|
198
|
+
# members = members))
|
|
211
199
|
|
|
212
|
-
self.writer.type_serializer[proxytype] = functional.constantly(ref)
|
|
200
|
+
# self.writer.type_serializer[proxytype] = functional.constantly(ref)
|
|
213
201
|
return proxytype
|
|
214
202
|
|
|
215
|
-
def extend_type(self, base):
|
|
216
203
|
|
|
217
|
-
|
|
218
|
-
return self.extended_types[base]
|
|
204
|
+
def extend_type(self, cls):
|
|
219
205
|
|
|
220
|
-
|
|
206
|
+
if cls in self.extended_types:
|
|
207
|
+
return self.extended_types[cls]
|
|
208
|
+
|
|
209
|
+
extended = super().extend_type(cls)
|
|
221
210
|
|
|
222
|
-
self.extended_types[
|
|
211
|
+
self.extended_types[cls] = extended
|
|
212
|
+
|
|
213
|
+
ref = self.writer.handle(ExtendedRef(name = cls.__name__,
|
|
214
|
+
module = cls.__module__))
|
|
215
|
+
|
|
216
|
+
# for binding?
|
|
217
|
+
# self.writer(ref)
|
|
218
|
+
|
|
219
|
+
self.writer.type_serializer[extended] = functional.constantly(ref)
|
|
223
220
|
|
|
224
221
|
return extended
|
retracesoftware/proxy/replay.py
CHANGED
|
@@ -4,34 +4,41 @@ import retracesoftware.stream as stream
|
|
|
4
4
|
|
|
5
5
|
from retracesoftware.install.tracer import Tracer
|
|
6
6
|
from retracesoftware.proxy.thread import per_thread_messages
|
|
7
|
-
from retracesoftware.proxy.proxytype import
|
|
7
|
+
from retracesoftware.proxy.proxytype import *
|
|
8
8
|
# from retracesoftware.proxy.gateway import gateway_pair
|
|
9
|
-
from retracesoftware.proxy.record import
|
|
10
|
-
from retracesoftware.proxy.proxysystem import ProxySystem
|
|
9
|
+
from retracesoftware.proxy.record import StubRef, Placeholder
|
|
10
|
+
from retracesoftware.proxy.proxysystem import ProxySystem, RetraceError
|
|
11
|
+
from retracesoftware.proxy.stubfactory import StubFactory, StubFunction
|
|
11
12
|
|
|
12
13
|
import os
|
|
13
14
|
import weakref
|
|
15
|
+
import traceback
|
|
14
16
|
# we can have a dummy method descriptor, its has a __name__ and when called, returns the next element
|
|
15
17
|
|
|
16
18
|
# for types, we can patch the __new__ method
|
|
17
19
|
# do it from C and immutable types can be patched too
|
|
18
20
|
# patch the tp_new pointer?
|
|
19
21
|
|
|
22
|
+
class ReplayError(RetraceError):
|
|
23
|
+
pass
|
|
24
|
+
|
|
20
25
|
class ReplayProxySystem(ProxySystem):
|
|
21
26
|
|
|
22
27
|
def stubtype(self, cls):
|
|
28
|
+
assert not issubclass(cls, Proxy)
|
|
29
|
+
|
|
23
30
|
return dynamic_proxytype(handler = self.ext_handler, cls = cls)
|
|
24
31
|
|
|
25
32
|
def create_stub(self): return True
|
|
26
33
|
|
|
27
|
-
def stubtype_from_spec(self, spec):
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
# def stubtype_from_spec(self, spec):
|
|
35
|
+
# print (f'FOOO!!! {spec}')
|
|
36
|
+
# return stubtype_from_spec(
|
|
37
|
+
# handler = self.ext_handler,
|
|
38
|
+
# module = spec.module,
|
|
39
|
+
# name = spec.name,
|
|
40
|
+
# methods = spec.methods,
|
|
41
|
+
# members = spec.members)
|
|
35
42
|
|
|
36
43
|
@utils.striptraceback
|
|
37
44
|
def next_result(self):
|
|
@@ -55,7 +62,7 @@ class ReplayProxySystem(ProxySystem):
|
|
|
55
62
|
err_value = self.messages()
|
|
56
63
|
utils.raise_exception(err_type, err_value)
|
|
57
64
|
else:
|
|
58
|
-
assert
|
|
65
|
+
assert type(next) is not str
|
|
59
66
|
return next
|
|
60
67
|
|
|
61
68
|
def bind(self, obj):
|
|
@@ -78,6 +85,15 @@ class ReplayProxySystem(ProxySystem):
|
|
|
78
85
|
self.reader.path = self.new_child_path(self.reader.path)
|
|
79
86
|
super().after_fork_in_child()
|
|
80
87
|
|
|
88
|
+
# def dynamic_ext_proxytype(self, cls):
|
|
89
|
+
# raise Exception('dynamic_ext_proxytype should not be called in replay')
|
|
90
|
+
|
|
91
|
+
def proxy_function(self, obj):
|
|
92
|
+
func = functional.repeatedly(self.next_result)
|
|
93
|
+
func.__name__ = obj.__name__
|
|
94
|
+
|
|
95
|
+
return super().proxy_function(func)
|
|
96
|
+
|
|
81
97
|
def __init__(self,
|
|
82
98
|
thread_state,
|
|
83
99
|
immutable_types,
|
|
@@ -96,15 +112,19 @@ class ReplayProxySystem(ProxySystem):
|
|
|
96
112
|
|
|
97
113
|
self.messages = functional.sequence(per_thread_messages(reader), deserialize)
|
|
98
114
|
|
|
115
|
+
self.stub_factory = StubFactory(thread_state = thread_state, next_result = self.next_result)
|
|
116
|
+
|
|
99
117
|
# messages = reader
|
|
100
118
|
|
|
101
119
|
def readnext():
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
120
|
+
with thread_state.select('disabled'):
|
|
121
|
+
try:
|
|
122
|
+
return self.messages()
|
|
123
|
+
except Exception as error:
|
|
124
|
+
# print(f'Error reading stream: {error}')
|
|
125
|
+
traceback.print_exc()
|
|
126
|
+
|
|
127
|
+
os._exit(1)
|
|
108
128
|
|
|
109
129
|
# print(f'read: {obj}')
|
|
110
130
|
# return obj
|
|
@@ -119,7 +139,7 @@ class ReplayProxySystem(ProxySystem):
|
|
|
119
139
|
def read_required(required):
|
|
120
140
|
obj = readnext()
|
|
121
141
|
if obj != required:
|
|
122
|
-
print(f'
|
|
142
|
+
print(f'Replay: {required} Record: {obj}')
|
|
123
143
|
for i in range(5):
|
|
124
144
|
print(readnext())
|
|
125
145
|
|
|
@@ -128,13 +148,14 @@ class ReplayProxySystem(ProxySystem):
|
|
|
128
148
|
raise Exception(f'Expected: {required} but got: {obj}')
|
|
129
149
|
|
|
130
150
|
def trace_writer(name, *args):
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
151
|
+
with thread_state.select('disabled'):
|
|
152
|
+
print(f'Trace: {name} {args}')
|
|
153
|
+
|
|
154
|
+
read_required('TRACE')
|
|
155
|
+
read_required(name)
|
|
135
156
|
|
|
136
|
-
|
|
137
|
-
|
|
157
|
+
for arg in args:
|
|
158
|
+
read_required(arg)
|
|
138
159
|
|
|
139
160
|
# self.tracer = Tracer(tracing_config, writer = trace_writer)
|
|
140
161
|
# self.immutable_types = immutable_types
|
|
@@ -147,10 +168,12 @@ class ReplayProxySystem(ProxySystem):
|
|
|
147
168
|
# immutable_types.add(cls)
|
|
148
169
|
|
|
149
170
|
# add_stubtype = functional.side_effect(foo)
|
|
150
|
-
add_stubtype = functional.side_effect(immutable_types.add)
|
|
171
|
+
# add_stubtype = functional.side_effect(immutable_types.add)
|
|
172
|
+
|
|
173
|
+
# reader.type_deserializer[ProxyRef] = functional.sequence(lambda ref: ref.resolve(), self.stubtype, add_stubtype)
|
|
151
174
|
|
|
152
|
-
reader.type_deserializer[
|
|
153
|
-
reader.type_deserializer[ProxySpec] = functional.sequence(self.stubtype_from_spec, add_stubtype)
|
|
175
|
+
reader.type_deserializer[StubRef] = self.stub_factory
|
|
176
|
+
# reader.type_deserializer[ProxySpec] = functional.sequence(self.stubtype_from_spec, add_stubtype)
|
|
154
177
|
|
|
155
178
|
# on_ext_result = functional.if_then_else(
|
|
156
179
|
# functional.is_instanceof(str), writer.handle('RESULT'), writer)
|
|
@@ -158,12 +181,11 @@ class ReplayProxySystem(ProxySystem):
|
|
|
158
181
|
# def int_proxytype(gateway):
|
|
159
182
|
# return lambda cls: dynamic_int_proxytype(handler = gateway, cls = cls, bind = self.bind)
|
|
160
183
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
create_stubs = functional.walker(functional.when(is_stub_type, lambda cls: cls()))
|
|
184
|
+
# create_stubs = functional.walker(functional.when(is_stub_ref, lambda stub: stub.create()))
|
|
185
|
+
# create_stubs = functional.walker(functional.when(is_stub_type, lambda cls: cls()))
|
|
165
186
|
|
|
166
|
-
self.ext_apply = functional.repeatedly(functional.sequence(self.next_result, create_stubs))
|
|
187
|
+
# self.ext_apply = functional.repeatedly(functional.sequence(self.next_result, create_stubs))
|
|
188
|
+
# self.ext_apply = functional.repeatedly(self.next_result)
|
|
167
189
|
|
|
168
190
|
def read_sync(): read_required('SYNC')
|
|
169
191
|
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
import retracesoftware.functional as functional
|
|
5
|
+
import retracesoftware.utils as utils
|
|
6
|
+
|
|
7
|
+
class Stub:
|
|
8
|
+
__slots__ = []
|
|
9
|
+
|
|
10
|
+
class ExtendedRef:
|
|
11
|
+
def __init__(self, module, name):
|
|
12
|
+
self.type = type
|
|
13
|
+
self.module = module
|
|
14
|
+
|
|
15
|
+
class StubRef:
|
|
16
|
+
def __init__(self, module, name, methods, members):
|
|
17
|
+
self.name = name
|
|
18
|
+
self.module = module
|
|
19
|
+
self.methods = methods
|
|
20
|
+
self.members = members
|
|
21
|
+
|
|
22
|
+
def __str__(self):
|
|
23
|
+
return f'StubRef(module = {self.module}, name = {self.name}, methods = {self.methods}, members = {self.members})'
|
|
24
|
+
|
|
25
|
+
def resolve(module, name):
|
|
26
|
+
try:
|
|
27
|
+
return getattr(sys.modules[module], name)
|
|
28
|
+
except:
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
class StubMethodDescriptor(functional.repeatedly):
|
|
32
|
+
def __init__(self, name, next_result):
|
|
33
|
+
super().__init__(next_result)
|
|
34
|
+
self.__name__ = name
|
|
35
|
+
|
|
36
|
+
def __str__(self):
|
|
37
|
+
return f"stub - {__name__}"
|
|
38
|
+
|
|
39
|
+
class StubMemberDescriptor:
|
|
40
|
+
def __init__(self, name, next_result):
|
|
41
|
+
self.next_result = next_result
|
|
42
|
+
self.__name__ = name
|
|
43
|
+
|
|
44
|
+
def __get__(self, instance, owner):
|
|
45
|
+
if instance is None:
|
|
46
|
+
return self
|
|
47
|
+
|
|
48
|
+
return self.next_result()
|
|
49
|
+
|
|
50
|
+
def __set__(self, instance, value):
|
|
51
|
+
return self.next_result()
|
|
52
|
+
|
|
53
|
+
def __delete__(self, instance):
|
|
54
|
+
return self.next_result()
|
|
55
|
+
|
|
56
|
+
def __str__(self):
|
|
57
|
+
return f"stub member - {__name__}"
|
|
58
|
+
|
|
59
|
+
class StubFunction(functional.repeatedly):
|
|
60
|
+
def __init__(self, name, next_result):
|
|
61
|
+
super().__init__(next_result)
|
|
62
|
+
self.__name__ = name
|
|
63
|
+
|
|
64
|
+
def __str__(self):
|
|
65
|
+
return f"stub function - {__name__}"
|
|
66
|
+
|
|
67
|
+
class StubFactory:
|
|
68
|
+
|
|
69
|
+
__slots__ = ['next_result', 'thread_state', 'cache']
|
|
70
|
+
|
|
71
|
+
def __init__(self, thread_state, next_result):
|
|
72
|
+
self.next_result = next_result
|
|
73
|
+
self.thread_state = thread_state
|
|
74
|
+
self.cache = {}
|
|
75
|
+
|
|
76
|
+
def create_member(self, name):
|
|
77
|
+
def disabled(*args, **kwargs):
|
|
78
|
+
if self.thread_state.value == 'disabled' and name == '__repr__':
|
|
79
|
+
return f"stub member - {name}"
|
|
80
|
+
else:
|
|
81
|
+
print(f'Error trying to call member descriptor: {name} {args} {kwargs}, retrace mode: {self.thread_state.value}')
|
|
82
|
+
utils.sigtrap(None)
|
|
83
|
+
os._exit(1)
|
|
84
|
+
|
|
85
|
+
next_result = self.thread_state.dispatch(disabled, external = self.next_result)
|
|
86
|
+
|
|
87
|
+
return StubMemberDescriptor(name = name, next_result = next_result)
|
|
88
|
+
|
|
89
|
+
def create_method(self, name):
|
|
90
|
+
|
|
91
|
+
def disabled(*args, **kwargs):
|
|
92
|
+
if self.thread_state.value == 'disabled' and name == '__repr__':
|
|
93
|
+
return f"stub - {name}"
|
|
94
|
+
else:
|
|
95
|
+
print(f'Error trying to call descriptor: {name} {args} {kwargs}, retrace mode: {self.thread_state.value}')
|
|
96
|
+
utils.sigtrap(None)
|
|
97
|
+
os._exit(1)
|
|
98
|
+
|
|
99
|
+
next_result = self.thread_state.dispatch(disabled, external = self.next_result)
|
|
100
|
+
|
|
101
|
+
func = functional.repeatedly(next_result)
|
|
102
|
+
func.__name__ = name
|
|
103
|
+
|
|
104
|
+
return func
|
|
105
|
+
|
|
106
|
+
def create_stubtype(self, spec):
|
|
107
|
+
|
|
108
|
+
slots = {
|
|
109
|
+
'__module__': spec.module,
|
|
110
|
+
'__qualname__': spec.name,
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
for method in spec.methods:
|
|
114
|
+
slots[method] = self.create_method(method)
|
|
115
|
+
assert utils.is_method_descriptor(slots[method])
|
|
116
|
+
|
|
117
|
+
for member in spec.members:
|
|
118
|
+
slots[member] = self.create_member(member)
|
|
119
|
+
|
|
120
|
+
resolved = resolve(spec.module, spec.name)
|
|
121
|
+
|
|
122
|
+
if isinstance(resolved, type):
|
|
123
|
+
slots['__class__'] = property(functional.repeatedly(resolved))
|
|
124
|
+
|
|
125
|
+
stubtype = type(spec.name, (Stub, ), slots)
|
|
126
|
+
|
|
127
|
+
for method in spec.methods:
|
|
128
|
+
slots[method].__objclass__ = stubtype
|
|
129
|
+
|
|
130
|
+
return stubtype
|
|
131
|
+
|
|
132
|
+
def __call__(self, spec):
|
|
133
|
+
print(f'In stubFactory.__call__ {spec}')
|
|
134
|
+
if spec not in self.cache:
|
|
135
|
+
self.cache[spec] = self.create_stubtype(spec)
|
|
136
|
+
|
|
137
|
+
stubtype = self.cache[spec]
|
|
138
|
+
stub = stubtype.__new__(stubtype)
|
|
139
|
+
print(f'In stubFactory created new')
|
|
140
|
+
return stub
|
retracesoftware/proxy/thread.py
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
retracesoftware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
retracesoftware/config.json,sha256=zhi3DZKG0pIT3Mh2EUXlzQai-U6YrknueOjMJLwNKxY,8281
|
|
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=HCD_ji8XCr96b5fNzNdL_8qcEp0Jf05Em7T6GA6u8HU,4969
|
|
8
|
+
retracesoftware/install/patcher.py,sha256=zSDmaVmgwTteF-ysMjHFbum793mt93J0gVHDOnYg2uM,17286
|
|
9
|
+
retracesoftware/install/predicate.py,sha256=tX7NQc0rGkyyHYO3mduYHcJHbw1wczT53m_Dpkzo6do,2679
|
|
10
|
+
retracesoftware/install/record.py,sha256=tseF_jV4k4HLPTgBPJdjcahl4EQqagoiisMAdGNC52Q,3257
|
|
11
|
+
retracesoftware/install/references.py,sha256=A-G651IDOfuo00MkbAdpbIQh_15ChvJ7uAVTSmE6zd4,1721
|
|
12
|
+
retracesoftware/install/replay.py,sha256=VUiHvQK3mgAJEGmtE2TFs9kXzxdWtsjibEcGkhZVCVE,1830
|
|
13
|
+
retracesoftware/install/tracer.py,sha256=NFilwwtopDrEXjh4ZLkwyIgvPvzApQYC6BA78B11WTQ,4675
|
|
14
|
+
retracesoftware/install/typeutils.py,sha256=_a1PuwdCsYjG1Nkd77V-flqYtwbD4RkJVKn6Z-xABL4,1813
|
|
15
|
+
retracesoftware/proxy/__init__.py,sha256=ZlDZIuUmKFsE9Tvfd2EKGabTepqv8nrbr5pQhCM3IKc,193
|
|
16
|
+
retracesoftware/proxy/gateway.py,sha256=xESohWXkiNm4ZutU0RgWUwxjxcBWRQ4rQyxIGQXv_F4,1590
|
|
17
|
+
retracesoftware/proxy/proxyfactory.py,sha256=qhOqDfMJnLDNkQs26JqDB431MwjjRhGQi8xupJ45asg,12272
|
|
18
|
+
retracesoftware/proxy/proxysystem.py,sha256=eUYinugkA2EZgTkxcXcdDntQmK5HCQp5oOwRzfhosx4,6698
|
|
19
|
+
retracesoftware/proxy/proxytype.py,sha256=iKN57FPRrACgYIFEDsCMvROA_tuhuGtZVguOxGlzVEE,12246
|
|
20
|
+
retracesoftware/proxy/record.py,sha256=YEwfqldpb1MQGi6EngPxdbmjbCIjbz9EQCZuXubLSy4,7503
|
|
21
|
+
retracesoftware/proxy/replay.py,sha256=4DxEuBlQSA6e-vB401JVfJV9Dgfesf5qbuBQBD-ApkA,7847
|
|
22
|
+
retracesoftware/proxy/stubfactory.py,sha256=6dvDnbClDY1tDLIDvPYOPxuCIGsg3TYa1qf2SqrmAvg,4114
|
|
23
|
+
retracesoftware/proxy/thread.py,sha256=-SvnyVbANkmX2lLRpOvFtkpdpAoF6DhnnYdOOs7Q8vo,1379
|
|
24
|
+
retracesoftware_proxy-0.1.3.dist-info/METADATA,sha256=J7wYAHin2b8ikm4VVMN9YfzRDZ9VEg43dpEbvqm0BXw,202
|
|
25
|
+
retracesoftware_proxy-0.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
26
|
+
retracesoftware_proxy-0.1.3.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
|
|
27
|
+
retracesoftware_proxy-0.1.3.dist-info/RECORD,,
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
retracesoftware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
retracesoftware/config.json,sha256=zhi3DZKG0pIT3Mh2EUXlzQai-U6YrknueOjMJLwNKxY,8281
|
|
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=nHnXjLnZDcY2untKR7BsPJEAcwoHfvXqgCmdHLiwRPE,5104
|
|
8
|
-
retracesoftware/install/patcher.py,sha256=PY4j3aXzu5l5fOGiChT8Y54nzhVpnHkWTGcxPtpe5mo,16773
|
|
9
|
-
retracesoftware/install/predicate.py,sha256=tX7NQc0rGkyyHYO3mduYHcJHbw1wczT53m_Dpkzo6do,2679
|
|
10
|
-
retracesoftware/install/record.py,sha256=Y-vDuUP_ZVzMC8PGhZP2fp8gLkIa5FJPhMKTBUSXi_o,3113
|
|
11
|
-
retracesoftware/install/references.py,sha256=0nUY_9BkeFz2imcw97rcJNq2jqISCB8dysBbCrh1eCo,1623
|
|
12
|
-
retracesoftware/install/replay.py,sha256=SV7-k05xZFiNfBaxrlLrqbB8-i01IPvnJQjRj9zuinI,1828
|
|
13
|
-
retracesoftware/install/tracer.py,sha256=UUVzBD_Nd91VH4iTs7ZDzaIbp_WeiOCSQnSe76dmfjM,4588
|
|
14
|
-
retracesoftware/install/typeutils.py,sha256=_a1PuwdCsYjG1Nkd77V-flqYtwbD4RkJVKn6Z-xABL4,1813
|
|
15
|
-
retracesoftware/proxy/__init__.py,sha256=ZlDZIuUmKFsE9Tvfd2EKGabTepqv8nrbr5pQhCM3IKc,193
|
|
16
|
-
retracesoftware/proxy/gateway.py,sha256=qRaE1xIdbRy6kBWmvvrBh-xKRmywWybO01yi1ppVdu8,6062
|
|
17
|
-
retracesoftware/proxy/proxyfactory.py,sha256=2PgC0NtDbRmhmU--caTiQDsaF8s1h9tavQxvPIow_bM,11912
|
|
18
|
-
retracesoftware/proxy/proxysystem.py,sha256=aX5bYqL2yf7mSgbjtDh1-n8dQ98nHZLT55kSLdVMy_c,6442
|
|
19
|
-
retracesoftware/proxy/proxytype.py,sha256=RuZL0xl48hfSnOFMum74FXdde-UNJ1Urz-ILBNMs4Ts,9398
|
|
20
|
-
retracesoftware/proxy/record.py,sha256=ShQrPSiNvZ9hckW6eaOoHj-w7_-X1o7R6zlaZkV_zdI,7687
|
|
21
|
-
retracesoftware/proxy/replay.py,sha256=jsg0DZTe1TBU5kjRt9weqLpHl8AlDQeqakNddYhBE2E,7111
|
|
22
|
-
retracesoftware/proxy/thread.py,sha256=zAqzLDJuhZxieMPtHzipTbuZ8WSO4nmRBgDBs7kPQy0,1373
|
|
23
|
-
retracesoftware_proxy-0.1.1.dist-info/METADATA,sha256=QuPCODtdgePy3CzNyVoMpLZAVbScOYpeHPfpTOwTIrQ,202
|
|
24
|
-
retracesoftware_proxy-0.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
25
|
-
retracesoftware_proxy-0.1.1.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
|
|
26
|
-
retracesoftware_proxy-0.1.1.dist-info/RECORD,,
|
|
File without changes
|
{retracesoftware_proxy-0.1.1.dist-info → retracesoftware_proxy-0.1.3.dist-info}/top_level.txt
RENAMED
|
File without changes
|