retracesoftware-proxy 0.1.0__py3-none-any.whl → 0.1.2__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/config.json +7 -0
- retracesoftware/install/install.py +2 -26
- retracesoftware/install/patcher.py +52 -9
- retracesoftware/install/record.py +15 -40
- retracesoftware/install/replay.py +4 -101
- retracesoftware/install/tracer.py +18 -16
- retracesoftware/proxy/__init__.py +1 -1
- retracesoftware/proxy/gateway.py +25 -76
- retracesoftware/proxy/proxyfactory.py +194 -194
- retracesoftware/proxy/proxysystem.py +192 -10
- retracesoftware/proxy/proxytype.py +235 -96
- retracesoftware/proxy/record.py +184 -96
- retracesoftware/proxy/replay.py +184 -60
- retracesoftware/proxy/stubfactory.py +141 -0
- retracesoftware/proxy/thread.py +40 -5
- {retracesoftware_proxy-0.1.0.dist-info → retracesoftware_proxy-0.1.2.dist-info}/METADATA +1 -6
- retracesoftware_proxy-0.1.2.dist-info/RECORD +27 -0
- retracesoftware_proxy-0.1.0.dist-info/RECORD +0 -26
- {retracesoftware_proxy-0.1.0.dist-info → retracesoftware_proxy-0.1.2.dist-info}/WHEEL +0 -0
- {retracesoftware_proxy-0.1.0.dist-info → retracesoftware_proxy-0.1.2.dist-info}/top_level.txt +0 -0
|
@@ -108,250 +108,250 @@ class GCHook:
|
|
|
108
108
|
elif phase == 'stop':
|
|
109
109
|
self.thread_state.value = self.saved_state
|
|
110
110
|
|
|
111
|
-
class ProxyFactory:
|
|
111
|
+
# class ProxyFactory:
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
# def ext_proxy_factory(self):
|
|
114
|
+
# return wrapping_proxy_factory(proxytype = self.proxytype, create_reference = compose(type, Reference), handler = self.ext_handler)
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
# def int_proxy_factory(self):
|
|
117
|
+
# return wrapping_proxy_factory(proxytype = self.proxytype, create_reference = Reference, handler = self.int_handler)
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
# def ext_call_handler(self):
|
|
120
|
+
# return self.int_handler.call_handler
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
# def int_call_handler(self):
|
|
123
|
+
# return self.ext_handler.call_handler
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
# def before_fork(self):
|
|
126
|
+
# pass
|
|
127
|
+
# # self.state_before_fork = self.thread_state.value
|
|
128
|
+
# # self.thread_state.value = 'disabled'
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
# def after_fork_in_child(self):
|
|
131
|
+
# self.fork_counter = 0
|
|
132
132
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
# def after_fork_in_parent(self):
|
|
134
|
+
# self.fork_counter += 1
|
|
135
|
+
# # self.thread_state.value = self.state_before_fork
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
# def gc_start(self):
|
|
138
|
+
# self.before_gc = self.thread_state.value
|
|
139
|
+
# self.thread_state.value = 'external'
|
|
140
140
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
# def gc_end(self):
|
|
142
|
+
# self.thread_state.value = self.before_gc
|
|
143
|
+
# del self.before_gc
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
# def gc_hook(self, phase, info):
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
# if phase == 'start':
|
|
148
|
+
# self.gc_start()
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
# elif phase == 'stop':
|
|
151
|
+
# self.gc_end()
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
# def __init__(self, thread_state, on_new_proxytype, sync,
|
|
154
|
+
# debug, checkpoint, verbose,
|
|
155
|
+
# ext_proxy, ext_handler, int_proxy, int_handler):
|
|
156
156
|
|
|
157
|
-
|
|
157
|
+
# assert ext_proxy
|
|
158
158
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
159
|
+
# self.ext_proxy = ext_proxy
|
|
160
|
+
# self.ext_handler = ext_handler
|
|
161
|
+
# self.int_proxy = int_proxy
|
|
162
|
+
# self.int_handler = int_handler
|
|
163
|
+
|
|
164
|
+
# def normalize(obj):
|
|
165
|
+
# if isinstance(obj, RootProxy):
|
|
166
|
+
# return str(obj)
|
|
167
|
+
# elif isinstance(obj, MethodDescriptor):
|
|
168
|
+
# return f'{obj.__objclass__.__module__}.{obj.__objclass__.__name__}.{obj.__name__}'
|
|
169
|
+
# elif isinstance(obj, Proxy):
|
|
170
|
+
# return 'Proxy'
|
|
171
|
+
# else:
|
|
172
|
+
# return obj
|
|
173
|
+
|
|
174
|
+
# self.normalize = walker(normalize)
|
|
175
|
+
|
|
176
|
+
# self.checkpoint_ext_call = mapargs(transform = self.normalize,
|
|
177
|
+
# function = self.checkpoint_ext_call)
|
|
178
178
|
|
|
179
|
-
|
|
179
|
+
# # self.checkpoint_ext_call = self.arg_serializer(self.checkpoint_ext_call)
|
|
180
180
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
181
|
+
# self.thread_state = thread_state
|
|
182
|
+
# self.debug = debug
|
|
183
|
+
# self.fork_counter = 0
|
|
184
|
+
# self.verbose = verbose
|
|
185
185
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
# self.on_new_proxytype = on_new_proxytype
|
|
187
|
+
# self._sync = sync
|
|
188
|
+
# self.thread_counter = self.sync_function(counter(1))
|
|
189
189
|
|
|
190
|
-
|
|
190
|
+
# # immutable_types = self.disable_for(immutable_types)
|
|
191
191
|
|
|
192
|
-
|
|
192
|
+
# gc.callbacks.append(self.gc_hook)
|
|
193
193
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
194
|
+
# def before():
|
|
195
|
+
# print("In before!!!!")
|
|
196
|
+
# with self.thread_state.select('disabled'):
|
|
197
|
+
# self.before_fork()
|
|
198
198
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
199
|
+
# os.register_at_fork(
|
|
200
|
+
# # before = self.thread_state.wrap('disabled', self.before_fork),
|
|
201
|
+
# before = before,
|
|
202
|
+
# after_in_parent = self.thread_state.wrap('disabled', self.after_fork_in_parent),
|
|
203
|
+
# after_in_child = self.thread_state.wrap('disabled', self.after_fork_in_child))
|
|
204
204
|
|
|
205
|
-
|
|
205
|
+
# self.tracing = None
|
|
206
206
|
|
|
207
|
-
|
|
207
|
+
# if debug > 3:
|
|
208
208
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
209
|
+
# # def checkpoint(obj):
|
|
210
|
+
# # print(f'in checkpoint: {obj}')
|
|
211
|
+
# # self.checkpoint(obj)
|
|
212
212
|
|
|
213
|
-
|
|
213
|
+
# FrameTracer.install(self.thread_state.dispatch(_proxy.noop, internal = checkpoint))
|
|
214
214
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
215
|
+
# # import threading
|
|
216
|
+
# # tracer = FrameTracer(
|
|
217
|
+
# # pred = self.thread_state.predicate('internal'),
|
|
218
|
+
# # checkpoint = checkpoint)
|
|
219
219
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
220
|
+
# # sys.settrace(tracer)
|
|
221
|
+
# # threading.settrace(tracer)
|
|
222
|
+
# # self.trace = lambda event, **kwargs: checkpoint({'type': 'trace', 'event': event} | kwargs)
|
|
223
|
+
# # self.enable_tracing()
|
|
224
224
|
|
|
225
|
-
|
|
226
|
-
|
|
225
|
+
# def sync_type(self, base):
|
|
226
|
+
# return sync_type(sync = self.sync, base = base)
|
|
227
227
|
|
|
228
|
-
|
|
229
|
-
|
|
228
|
+
# def sync_function(self, function):
|
|
229
|
+
# return intercept(on_call = self._sync, function = function)
|
|
230
230
|
|
|
231
|
-
|
|
232
|
-
|
|
231
|
+
# def checkpoint(self, obj):
|
|
232
|
+
# pass
|
|
233
233
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
# def log(self, message):
|
|
235
|
+
# if self.verbose:
|
|
236
|
+
# print(message)
|
|
237
237
|
|
|
238
|
-
|
|
238
|
+
# self.checkpoint({'type': 'log', 'message': message})
|
|
239
239
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
240
|
+
# @property
|
|
241
|
+
# def disable(self):
|
|
242
|
+
# return self.thread_state.select('disabled')
|
|
243
243
|
|
|
244
|
-
|
|
245
|
-
|
|
244
|
+
# def with_state(self, state, function):
|
|
245
|
+
# return self.thread_state.wrap(desired_state = state, function = function)
|
|
246
246
|
|
|
247
|
-
|
|
248
|
-
|
|
247
|
+
# def disable_for(self, function):
|
|
248
|
+
# return self.thread_state.wrap(desired_state = 'disabled', function = function)
|
|
249
249
|
|
|
250
|
-
|
|
250
|
+
# def __call__(self, module, name, obj):
|
|
251
251
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
252
|
+
# if type(obj) == type:
|
|
253
|
+
# try:
|
|
254
|
+
# return self.extend_type(obj)
|
|
255
|
+
# except:
|
|
256
|
+
# pass
|
|
257
257
|
|
|
258
|
-
|
|
258
|
+
# self.checkpoint({'type': 'proxy', 'module': module, 'name': name})
|
|
259
259
|
|
|
260
|
-
|
|
261
|
-
|
|
260
|
+
# if is_function_type(type(obj)) or type(obj) == type:
|
|
261
|
+
# proxied = RootProxy(module = module, name = name, handler = self.ext_handler, target = obj)
|
|
262
262
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
263
|
+
# try:
|
|
264
|
+
# # print(f"signature: {inspect.signature(obj)} for {obj}")
|
|
265
|
+
# proxied.__signature__ = inspect.signature(obj)
|
|
266
|
+
# except:
|
|
267
|
+
# pass
|
|
268
|
+
|
|
269
|
+
# return proxied
|
|
270
|
+
# else:
|
|
271
|
+
# return self.ext_proxy(obj)
|
|
272
272
|
|
|
273
|
-
|
|
273
|
+
# # return self.ext_proxy(obj)
|
|
274
274
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
275
|
+
# def start_new_thread(self, start_new_thread, function, *args):
|
|
276
|
+
# # synchronized, replay shoudl yeild correct number
|
|
277
|
+
# thread_id = self.thread_counter()
|
|
278
|
+
|
|
279
|
+
# def threadrunner(*args, **kwargs):
|
|
280
|
+
# self.set_thread_number(thread_id)
|
|
281
|
+
# with self.thread_state.select('internal'):
|
|
282
|
+
# if self.tracing:
|
|
283
|
+
# FrameTracer.install(self.thread_state.dispatch(noop, internal = self.checkpoint))
|
|
284
284
|
|
|
285
|
-
|
|
285
|
+
# return function(*args, **kwargs)
|
|
286
286
|
|
|
287
|
-
|
|
287
|
+
# return start_new_thread(threadrunner, *args)
|
|
288
288
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
289
|
+
# def wrap_start_new_thread(self, start_new_thread):
|
|
290
|
+
# wrapped = functools.partial(self.start_new_thread, start_new_thread)
|
|
291
|
+
# return self.thread_state.dispatch(start_new_thread, internal = wrapped)
|
|
292
292
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
293
|
+
# def checkpoint_ext_call(self, func, *args, **kwargs):
|
|
294
|
+
# self.checkpoint({'type':
|
|
295
|
+
# 'external.call',
|
|
296
|
+
# 'function': str(func)})
|
|
297
|
+
|
|
298
|
+
# def extend_type(self, base):
|
|
299
|
+
|
|
300
|
+
# assert not issubclass(base, BaseException)
|
|
301
|
+
|
|
302
|
+
# self.checkpoint({'type': 'log', 'message': f'extending type: {base}'})
|
|
303
|
+
|
|
304
|
+
# def custom_init_subclass(cls, **kwargs):
|
|
305
|
+
# for name, target in cls.__dict__.items():
|
|
306
|
+
# if is_method_descriptor(target):
|
|
307
|
+
# proxied = cls.method_descriptor(handler = self.int_handler,
|
|
308
|
+
# call_handler = self.thread_state.predicate('external'),
|
|
309
|
+
# name = name,
|
|
310
|
+
# target = target)
|
|
311
|
+
# setattr(cls, name, proxied)
|
|
312
|
+
|
|
313
|
+
# def __new__(cls, *args, **kwargs):
|
|
314
|
+
# instance = base.__new__(cls, *args, **kwargs)
|
|
315
|
+
# self.on_new(instance)
|
|
316
|
+
# return instance
|
|
317
317
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
318
|
+
# slots = {
|
|
319
|
+
# "__slots__": (),
|
|
320
|
+
# '__new__': __new__,
|
|
321
|
+
# "__init_subclass__": classmethod(custom_init_subclass)
|
|
322
|
+
# }
|
|
323
|
+
|
|
324
|
+
# extended = type(f'retrace.extended.{base.__module__}.{base.__name__}', (base, _proxy.ExtendedProxy), slots)
|
|
325
|
+
|
|
326
|
+
# blacklist = ['__getattribute__', '__hash__', '__del__']
|
|
327
|
+
|
|
328
|
+
# for name,value in superdict(base).items():
|
|
329
|
+
# if name not in blacklist:
|
|
330
|
+
# if is_method_descriptor(value):
|
|
331
|
+
# proxied = extended.method_descriptor(
|
|
332
|
+
# handler = self.ext_handler,
|
|
333
|
+
# name = name,
|
|
334
|
+
# target = getattr(base, name))
|
|
335
|
+
|
|
336
|
+
# setattr(extended, name, proxied)
|
|
337
|
+
# elif is_descriptor(value):
|
|
338
|
+
# setattr(extended, name, self.ext_proxy(value))
|
|
339
339
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
340
|
+
# def __del__(obj):
|
|
341
|
+
# try:
|
|
342
|
+
# self.on_del(Reference(obj))
|
|
343
|
+
# # self.external.handler.on_del(_proxy.Reference(obj))
|
|
344
|
+
# except:
|
|
345
|
+
# pass
|
|
346
346
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
347
|
+
# try:
|
|
348
|
+
# base.__del__(obj)
|
|
349
|
+
# except:
|
|
350
|
+
# pass
|
|
351
351
|
|
|
352
|
-
|
|
352
|
+
# extended.__del__ = __del__
|
|
353
353
|
|
|
354
|
-
|
|
355
|
-
|
|
354
|
+
# if self.on_new_proxytype:
|
|
355
|
+
# self.on_new_proxytype(base.__module__, base.__name__, extended)
|
|
356
356
|
|
|
357
|
-
|
|
357
|
+
# return extended
|
|
@@ -1,20 +1,202 @@
|
|
|
1
1
|
import retracesoftware.functional as functional
|
|
2
2
|
import retracesoftware_utils as utils
|
|
3
|
-
|
|
4
|
-
from retracesoftware.proxy.
|
|
3
|
+
import types
|
|
4
|
+
from retracesoftware.proxy.gateway import adapter_pair
|
|
5
|
+
from types import SimpleNamespace
|
|
6
|
+
from retracesoftware.proxy.proxytype import *
|
|
7
|
+
from retracesoftware.proxy.stubfactory import Stub
|
|
8
|
+
import sys
|
|
9
|
+
import gc
|
|
10
|
+
|
|
11
|
+
class RetraceError(Exception):
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
def proxy(proxytype):
|
|
15
|
+
return functional.spread(
|
|
16
|
+
utils.create_wrapped,
|
|
17
|
+
functional.sequence(functional.typeof, proxytype),
|
|
18
|
+
None)
|
|
19
|
+
|
|
20
|
+
def maybe_proxy(proxytype):
|
|
21
|
+
return functional.if_then_else(
|
|
22
|
+
functional.isinstanceof(utils.Wrapped),
|
|
23
|
+
utils.unwrap,
|
|
24
|
+
proxy(functional.memoize_one_arg(proxytype)))
|
|
25
|
+
|
|
26
|
+
unproxy_execute = functional.mapargs(starting = 1,
|
|
27
|
+
transform = functional.walker(utils.try_unwrap),
|
|
28
|
+
function = functional.apply)
|
|
29
|
+
|
|
30
|
+
def resolve(obj):
|
|
31
|
+
try:
|
|
32
|
+
return getattr(sys.modules[obj.__module__], obj.__name__)
|
|
33
|
+
except:
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
def is_function_type(cls):
|
|
37
|
+
return cls in [types.BuiltinFunctionType, types.FunctionType]
|
|
5
38
|
|
|
6
39
|
class ProxySystem:
|
|
7
40
|
|
|
8
|
-
def
|
|
41
|
+
def bind(self, obj): pass
|
|
42
|
+
|
|
43
|
+
def wrap_int_to_ext(self, obj):
|
|
44
|
+
return obj
|
|
45
|
+
# return functional.sequence(functional.side_effect(functional.repeatedly(gc.collect)), obj)
|
|
46
|
+
|
|
47
|
+
def wrap_ext_to_int(self, obj): return obj
|
|
48
|
+
|
|
49
|
+
def on_int_call(self, func, *args, **kwargs):
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
def on_ext_result(self, result):
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
def on_ext_error(self, err_type, err_value, err_traceback):
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
def __init__(self, thread_state, immutable_types, tracer):
|
|
59
|
+
|
|
9
60
|
self.thread_state = thread_state
|
|
61
|
+
self.fork_counter = 0
|
|
62
|
+
self.tracer = tracer
|
|
63
|
+
self.immutable_types = immutable_types
|
|
64
|
+
self.on_proxytype = None
|
|
65
|
+
|
|
66
|
+
def is_immutable_type(cls):
|
|
67
|
+
return issubclass(cls, tuple(immutable_types))
|
|
68
|
+
|
|
69
|
+
is_immutable = functional.sequence(functional.typeof, functional.memoize_one_arg(is_immutable_type))
|
|
70
|
+
|
|
71
|
+
def proxyfactory(proxytype):
|
|
72
|
+
return functional.walker(functional.when_not(is_immutable, maybe_proxy(proxytype)))
|
|
73
|
+
|
|
74
|
+
int_spec = SimpleNamespace(
|
|
75
|
+
apply = thread_state.wrap('internal', functional.apply),
|
|
76
|
+
proxy = proxyfactory(thread_state.wrap('disabled', self.int_proxytype)),
|
|
77
|
+
on_call = tracer('proxy.int.call', self.on_int_call),
|
|
78
|
+
on_result = tracer('proxy.int.result'),
|
|
79
|
+
on_error = tracer('proxy.int.error'),
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
ext_spec = SimpleNamespace(
|
|
83
|
+
apply = thread_state.wrap('external', functional.apply),
|
|
84
|
+
proxy = proxyfactory(thread_state.wrap('disabled', self.dynamic_ext_proxytype)),
|
|
85
|
+
on_call = tracer('proxy.ext.call'),
|
|
86
|
+
on_result = self.on_ext_result,
|
|
87
|
+
on_error = self.on_ext_error,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
int2ext, ext2int = adapter_pair(int_spec, ext_spec)
|
|
10
91
|
|
|
92
|
+
def gateway(name, internal = functional.apply, external = functional.apply):
|
|
93
|
+
default = tracer(name, unproxy_execute)
|
|
94
|
+
return thread_state.dispatch(default, internal = internal, external = external)
|
|
95
|
+
|
|
96
|
+
self.ext_handler = self.wrap_int_to_ext(int2ext)
|
|
97
|
+
self.int_handler = self.wrap_ext_to_int(ext2int)
|
|
98
|
+
|
|
99
|
+
self.ext_dispatch = gateway('proxy.int.disabled.event', internal = self.ext_handler)
|
|
100
|
+
self.int_dispatch = gateway('proxy.ext.disabled.event', external = self.int_handler)
|
|
101
|
+
|
|
102
|
+
def new_child_path(self, path):
|
|
103
|
+
return path.parent / f'fork-{self.fork_counter}' / path.name
|
|
104
|
+
|
|
105
|
+
def before_fork(self):
|
|
106
|
+
self.saved_thread_state = self.thread_state.value
|
|
107
|
+
self.thread_state.value = 'disabled'
|
|
108
|
+
|
|
109
|
+
def after_fork_in_child(self):
|
|
110
|
+
self.thread_state.value = self.saved_thread_state
|
|
111
|
+
self.fork_counter = 0
|
|
112
|
+
|
|
113
|
+
def after_fork_in_parent(self):
|
|
114
|
+
self.thread_state.value = self.saved_thread_state
|
|
115
|
+
self.fork_counter += 1
|
|
116
|
+
|
|
117
|
+
def create_stub(self): return False
|
|
118
|
+
|
|
119
|
+
def int_proxytype(self, cls):
|
|
120
|
+
return dynamic_int_proxytype(
|
|
121
|
+
handler = self.int_dispatch,
|
|
122
|
+
cls = cls,
|
|
123
|
+
bind = self.bind)
|
|
124
|
+
|
|
125
|
+
def dynamic_ext_proxytype(self, cls):
|
|
126
|
+
print(f'dynamic_ext_proxytype: {cls} {self.thread_state.value}')
|
|
127
|
+
|
|
128
|
+
proxytype = dynamic_proxytype(
|
|
129
|
+
handler = self.ext_dispatch,
|
|
130
|
+
cls = cls)
|
|
131
|
+
if self.on_proxytype:
|
|
132
|
+
self.on_proxytype(proxytype)
|
|
133
|
+
|
|
134
|
+
return proxytype
|
|
135
|
+
|
|
136
|
+
# resolved = resolve(cls)
|
|
137
|
+
# if isinstance(resolved, ExtendingProxy):
|
|
138
|
+
# return dynamic_from_extended(resolved)
|
|
139
|
+
# elif isinstance(resolved, DynamicProxy):
|
|
140
|
+
# return resolved
|
|
141
|
+
# else:
|
|
142
|
+
# return dynamic_proxytype(handler = self.ext_dispatch, cls = cls)
|
|
143
|
+
|
|
144
|
+
def ext_proxytype(self, cls):
|
|
145
|
+
assert isinstance(cls, type)
|
|
146
|
+
if utils.is_extendable(cls):
|
|
147
|
+
return self.extend_type(cls)
|
|
148
|
+
else:
|
|
149
|
+
return instantiable_dynamic_proxytype(
|
|
150
|
+
handler = self.ext_dispatch,
|
|
151
|
+
cls = cls,
|
|
152
|
+
thread_state = self.thread_state,
|
|
153
|
+
create_stub = self.create_stub())
|
|
154
|
+
|
|
155
|
+
def extend_type(self, cls):
|
|
156
|
+
|
|
157
|
+
extended = extending_proxytype(
|
|
158
|
+
cls = cls,
|
|
159
|
+
base = Stub if self.create_stub() else cls,
|
|
160
|
+
thread_state = self.thread_state,
|
|
161
|
+
ext_handler = self.ext_dispatch,
|
|
162
|
+
int_handler = self.int_dispatch,
|
|
163
|
+
on_subclass_new = self.bind)
|
|
164
|
+
|
|
165
|
+
self.immutable_types.add(extended)
|
|
166
|
+
|
|
167
|
+
return extended
|
|
168
|
+
|
|
169
|
+
def function_target(self, obj): return obj
|
|
170
|
+
|
|
171
|
+
def proxy_function(self, obj):
|
|
172
|
+
return utils.wrapped_function(handler = self.ext_handler, target = obj)
|
|
173
|
+
|
|
11
174
|
def __call__(self, obj):
|
|
12
175
|
assert not isinstance(obj, BaseException)
|
|
176
|
+
assert not isinstance(obj, Proxy)
|
|
177
|
+
assert not isinstance(obj, utils.wrapped_function)
|
|
178
|
+
|
|
179
|
+
try:
|
|
180
|
+
print(f'STARTING PROXYING: {obj}')
|
|
181
|
+
if type(obj) == type:
|
|
182
|
+
if obj in self.immutable_types or issubclass(obj, tuple):
|
|
183
|
+
return obj
|
|
184
|
+
|
|
185
|
+
return self.ext_proxytype(obj)
|
|
186
|
+
|
|
187
|
+
elif type(obj) in self.immutable_types:
|
|
188
|
+
return obj
|
|
189
|
+
|
|
190
|
+
elif is_function_type(type(obj)):
|
|
13
191
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
192
|
+
return self.thread_state.dispatch(
|
|
193
|
+
obj,
|
|
194
|
+
internal = self.proxy_function(obj))
|
|
195
|
+
|
|
196
|
+
else:
|
|
197
|
+
proxytype = dynamic_proxytype(handler = self.ext_dispatch, cls = type(obj))
|
|
198
|
+
|
|
199
|
+
return utils.create_wrapped(proxytype, obj)
|
|
200
|
+
# raise Exception(f'object {obj} was not proxied as its not a extensible type and is not callable')
|
|
201
|
+
finally:
|
|
202
|
+
print(f'FINISHED PROXYING: {obj}')
|