retracesoftware-proxy 0.0.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.
Files changed (41) hide show
  1. retracesoftware/__init__.py +0 -0
  2. retracesoftware/__main__.py +266 -0
  3. retracesoftware/autoenable.py +53 -0
  4. retracesoftware/config.json +175 -0
  5. retracesoftware/config.yaml +0 -0
  6. retracesoftware/install/__init__.py +0 -0
  7. retracesoftware/install/config.py +59 -0
  8. retracesoftware/install/edgecases.py +242 -0
  9. retracesoftware/install/globals.py +17 -0
  10. retracesoftware/install/install.py +142 -0
  11. retracesoftware/install/patcher.py +122 -0
  12. retracesoftware/install/patchfindspec.py +117 -0
  13. retracesoftware/install/phases.py +338 -0
  14. retracesoftware/install/predicate.py +92 -0
  15. retracesoftware/install/record.py +174 -0
  16. retracesoftware/install/references.py +66 -0
  17. retracesoftware/install/replace.py +28 -0
  18. retracesoftware/install/replay.py +102 -0
  19. retracesoftware/install/tracer.py +284 -0
  20. retracesoftware/install/typeutils.py +92 -0
  21. retracesoftware/modules.toml +384 -0
  22. retracesoftware/proxy/__init__.py +3 -0
  23. retracesoftware/proxy/gateway.py +49 -0
  24. retracesoftware/proxy/globalref.py +31 -0
  25. retracesoftware/proxy/messagestream.py +204 -0
  26. retracesoftware/proxy/proxyfactory.py +357 -0
  27. retracesoftware/proxy/proxysystem.py +454 -0
  28. retracesoftware/proxy/proxytype.py +424 -0
  29. retracesoftware/proxy/record.py +211 -0
  30. retracesoftware/proxy/replay.py +138 -0
  31. retracesoftware/proxy/serializer.py +28 -0
  32. retracesoftware/proxy/startthread.py +40 -0
  33. retracesoftware/proxy/stubfactory.py +195 -0
  34. retracesoftware/proxy/thread.py +106 -0
  35. retracesoftware/replay.py +104 -0
  36. retracesoftware/run.py +373 -0
  37. retracesoftware/stackdifference.py +133 -0
  38. retracesoftware_proxy-0.0.0.dist-info/METADATA +8 -0
  39. retracesoftware_proxy-0.0.0.dist-info/RECORD +41 -0
  40. retracesoftware_proxy-0.0.0.dist-info/WHEEL +5 -0
  41. retracesoftware_proxy-0.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,424 @@
1
+ import retracesoftware.utils as utils
2
+ import retracesoftware.functional as functional
3
+
4
+ import types
5
+
6
+ from retracesoftware.proxy.stubfactory import StubMethodDescriptor, Stub
7
+
8
+ class Proxy:
9
+ __slots__ = []
10
+
11
+ class DynamicProxy(Proxy):
12
+ __slots__ = []
13
+
14
+ class ExtendingProxy(Proxy):
15
+ __slots__ = []
16
+
17
+ class InternalProxy:
18
+ __slots__ = []
19
+
20
+ @functional.memoize_one_arg
21
+ def unproxy_type(cls):
22
+ if not issubclass(cls, Proxy):
23
+ return cls
24
+
25
+ # Prefer attribute on the class, not on the mappingproxy
26
+ target = getattr(cls, '__retrace_target_class__', None)
27
+ if target is not None:
28
+ return unproxy_type(target)
29
+
30
+ # Rebuild with unproxied bases, preserving metaclass and critical dunder attrs
31
+ new_bases = tuple(map(unproxy_type, cls.__bases__))
32
+
33
+ # Copy attrs, but omit implementation-managed ones
34
+ attrs = {}
35
+ classcell = None
36
+ for k, v in cls.__dict__.items():
37
+ if k in ('__dict__', '__weakref__'):
38
+ continue
39
+ if k == '__classcell__':
40
+ # must be passed through at class creation for zero-arg super()
41
+ classcell = v
42
+ continue
43
+ attrs[k] = v
44
+
45
+ # Ensure module/doc are kept (in case they weren't in __dict__)
46
+ attrs.setdefault('__module__', cls.__module__)
47
+ attrs.setdefault('__doc__', cls.__doc__)
48
+
49
+ # Use types.new_class if you want full class-creation protocol
50
+ def exec_body(ns):
51
+ ns.update(attrs)
52
+ if classcell is not None:
53
+ ns['__classcell__'] = classcell
54
+
55
+ return types.new_class(cls.__name__, new_bases, {'metaclass': type(cls)}, exec_body)
56
+
57
+
58
+ def superdict(cls):
59
+ result = {}
60
+ for cls in list(reversed(cls.__mro__))[1:]:
61
+ result.update(cls.__dict__)
62
+
63
+ return result
64
+
65
+ def is_method_descriptor(obj):
66
+ return isinstance(obj, types.FunctionType) or \
67
+ (isinstance(obj, (types.WrapperDescriptorType,
68
+ types.MethodDescriptorType,
69
+ StubMethodDescriptor)) and obj.__objclass__ != object)
70
+
71
+ def proxy_method_descriptors(cls, handler):
72
+ for name, target in cls.__dict__.items():
73
+ if is_method_descriptor(target):
74
+ proxied = utils.wrapped_function(handler = handler, target = target)
75
+ setattr(cls, name, proxied)
76
+
77
+ def methods(cls):
78
+ for name,value in superdict(cls).items():
79
+ if is_descriptor(value) and is_method_descriptor(value):
80
+ yield name
81
+
82
+ def is_descriptor(obj):
83
+ return hasattr(obj, '__get__') or hasattr(obj, '__set__') or hasattr(obj, '__delete__')
84
+
85
+ class Named:
86
+ def __init__(self, name):
87
+ self.__name__ = name
88
+
89
+ class DescriptorStub:
90
+
91
+ __slots__ = ['handler', 'name']
92
+
93
+ def __init__(self, handler, name):
94
+ self.handler = handler
95
+ self.name = name
96
+
97
+ def __get__(self, instance, owner):
98
+ return self.handler(Named('getattr'), self.name)
99
+
100
+ def __set__(self, instance, value):
101
+ return self.handler(Named('setattr'), self.name, value)
102
+
103
+ def __delete__(self, instance):
104
+ return self.handler(Named('delattr'), self.name)
105
+
106
+ def stubtype_from_spec(handler, module, name, methods, members):
107
+
108
+ spec = {
109
+ '__module__': module,
110
+ }
111
+
112
+ for method in methods:
113
+ spec[method] = utils.wrapped_function(
114
+ handler = handler, target = Named(method))
115
+
116
+ for member in members:
117
+ spec[member] = DescriptorStub(handler = handler, name = member)
118
+
119
+ return type(name, (Stub, DynamicProxy,), spec)
120
+
121
+ # stubtype.__new__ = thread_state.dispatch(disabled__new__, internal = stub.__new__, external = stub.__new__)
122
+ # stub.__retrace_unproxied__ = cls
123
+
124
+ def dynamic_stubtype(handler, cls):
125
+
126
+ assert not issubclass(cls, BaseException)
127
+
128
+ blacklist = ['__getattribute__', '__hash__', '__del__', '__call__']
129
+
130
+ to_proxy = [m for m in methods(cls) if m not in blacklist]
131
+
132
+ def wrap(name): return utils.wrapped_function(handler = handler,
133
+ target = Named(name))
134
+
135
+ spec = { name: wrap(name) for name in to_proxy }
136
+
137
+ spec['__getattr__'] = wrap('__getattr__')
138
+ spec['__setattr__'] = wrap('__setattr__')
139
+
140
+ if utils.yields_callable_instances(cls):
141
+ spec['__call__'] = handler
142
+
143
+ spec['__retrace_target_class__'] = cls
144
+
145
+ target_type = functional.sequence(utils.unwrap, functional.typeof)
146
+ spec['__class__'] = property(target_type)
147
+
148
+ spec['__module__'] = cls.__module__
149
+ spec['__qualname__'] = cls.__name__
150
+
151
+ # name = f'retrace.proxied.{cls.__module__}.{cls.__name__}'
152
+
153
+ return type(cls.__name__, (Stub, DynamicProxy), spec)
154
+
155
+ class DescriptorProxy:
156
+ __slots__ = ['target', 'handler']
157
+
158
+ def __init__(self, handler, target):
159
+ self.handler = handler
160
+ self.target = target
161
+
162
+ def __get__(self, obj, cls):
163
+ try:
164
+ return self.handler(self.target.__get__, obj, cls)
165
+ except:
166
+ print(f'error calling __get__')
167
+ raise
168
+
169
+ def __set__(self, obj, value):
170
+ return self.handler(self.target.__set__, obj, value)
171
+
172
+ def __delete__(self, obj):
173
+ return self.handler(self.target.__delete__, obj)
174
+
175
+ # class ExtendingDescriptorProxy:
176
+
177
+ # __slots__ = ['handler', 'proxytype', 'name']
178
+
179
+ # def __init__(self, proxytype, handler, name):
180
+ # self.proxytype = proxytype
181
+ # self.handler = handler
182
+ # self.name = name
183
+
184
+ # def __get__(self, instance, owner):
185
+ # inst = owner if instance is None else instance
186
+ # getter = functional.partial(getattr, super(self.proxytype, inst))
187
+ # return self.handler(getter, self.name)
188
+
189
+ # def __set__(self, instance, value):
190
+ # breakpoint()
191
+ # setter = functional.partial(setattr, super(self.proxytype, instance))
192
+ # return self.handler(setter, self.name, value)
193
+
194
+ # def __delete__(self, instance):
195
+ # deleter = functional.partial(delattr, super(self.proxytype, instance))
196
+ # return self.handler(deleter, self.name)
197
+
198
+
199
+ def dynamic_proxytype(handler, cls):
200
+
201
+ if cls.__module__.startswith('retracesoftware'):
202
+ print(cls)
203
+ utils.sigtrap('HERE5')
204
+
205
+ assert not cls.__module__.startswith('retracesoftware')
206
+
207
+ # print(f'In dynamic_proxytype: {cls}')
208
+
209
+ assert not issubclass(cls, Proxy)
210
+ assert not issubclass(cls, BaseException)
211
+
212
+ blacklist = ['__getattribute__', '__hash__', '__del__', '__call__', '__new__']
213
+
214
+ spec = {}
215
+
216
+ def wrap(func): return utils.wrapped_function(handler = handler, target = func)
217
+
218
+ for name in superdict(cls).keys():
219
+ if name not in blacklist:
220
+ value = getattr(cls, name)
221
+
222
+ if issubclass(type(value), utils.dispatch):
223
+ value = utils.dispatch.table(value)['disabled']
224
+
225
+ # if is_descriptor(value):
226
+ if utils.is_method_descriptor(value):
227
+ spec[name] = wrap(value)
228
+
229
+ # try:
230
+ # value = getattr(cls, name)
231
+
232
+ # assert type(value) is not utils.dispatch
233
+
234
+ # if is_descriptor(value):
235
+ # if utils.is_method_descriptor(value):
236
+ # spec[name] = wrap(value)
237
+ # except Exception as error:
238
+ # print(f'FOO! {cls} {name} {error}')
239
+ # breakpoint()
240
+ # raise
241
+
242
+ # else:
243
+ # spec[name] = DescriptorProxy(handler = handler, target = value)
244
+
245
+ # to_proxy = [m for m in methods(cls) if m not in blacklist]
246
+
247
+ # def wrap(target): return utils.wrapped_function(handler = handler, target = target)
248
+
249
+ # spec = { name: wrap(getattr(cls, name)) for name in to_proxy }
250
+
251
+ # def foo(obj, name, default = None):
252
+ # print(f'dynamic_proxytype.__getattr__: {type(obj).__mro__} {name}')
253
+ # utils.sigtrap(obj)
254
+ # return getattr(obj, name, default)
255
+
256
+ # spec['__getattr__'] = wrap(foo)
257
+ spec['__getattr__'] = wrap(getattr)
258
+ spec['__setattr__'] = wrap(setattr)
259
+
260
+ if utils.yields_callable_instances(cls):
261
+ spec['__call__'] = handler
262
+
263
+ spec['__retrace_target_class__'] = cls
264
+
265
+ # target_type = functional.sequence(utils.unwrap, functional.typeof)
266
+
267
+ target_type = cls.__retrace_target_type__ if issubclass(cls, Stub) else cls
268
+ # functional.repeatedly(resolved)
269
+
270
+ # spec['__class__'] = property(target_type)
271
+ spec['__class__'] = property(functional.constantly(target_type))
272
+
273
+ spec['__name__'] = cls.__name__
274
+ spec['__module__'] = cls.__module__
275
+ # name = f'retrace.proxied.{cls.__module__}.{cls.__name__}'
276
+
277
+ return type(cls.__name__, (utils.Wrapped, DynamicProxy), spec)
278
+
279
+ def dynamic_from_extended(cls):
280
+
281
+ base = cls.__base__
282
+
283
+ name = f'retrace.proxied1.{base.__module__}.{base.__name__}'
284
+
285
+ spec = dict(cls.__dict__)
286
+
287
+ spec['__retrace_target_class__'] = base
288
+
289
+ del spec['__init_subclass__']
290
+ # del spec['__new__']
291
+
292
+ target_type = functional.sequence(utils.unwrap, functional.typeof)
293
+ spec['__class__'] = property(target_type)
294
+
295
+ return type(name, (utils.Wrapped, DynamicProxy), spec)
296
+
297
+
298
+ def instantiable_dynamic_proxytype(handler, cls, thread_state, create_stub = False):
299
+
300
+ proxytype = dynamic_proxytype(handler = handler, cls = cls)
301
+
302
+ def create_original(proxytype, *args, **kwargs):
303
+ instance = cls(*args, **kwargs)
304
+ instance.__init__(*args, **kwargs)
305
+ return instance
306
+
307
+ def __new__(proxytype, *args, **kwargs):
308
+ instance = utils.create_stub_object(cls) if create_stub else cls(*args, **kwargs)
309
+ return utils.create_wrapped(proxytype, instance)
310
+
311
+ proxytype.__new__ = thread_state.dispatch(create_original, internal = __new__)
312
+
313
+ return proxytype
314
+
315
+ def dynamic_int_proxytype(handler, cls, bind):
316
+ proxytype = dynamic_proxytype(handler = handler, cls = cls)
317
+ proxytype.__new__ = functional.sequence(proxytype.__new__, functional.side_effect(bind))
318
+ proxytype.__retrace_source__ = 'internal'
319
+ return proxytype
320
+
321
+
322
+ blacklist = ['__getattribute__', '__hash__', '__del__', '__dict__']
323
+
324
+ # if the type can be patched, thats better, all new instances must be of correct type
325
+
326
+ # def make_extensible(thread_state, proxy_method_descriptor, cls):
327
+
328
+ # @functional.memoize_one_arg
329
+ # def proxy_subclass(subclass):
330
+ # if '__retrace_target_type__' in subclass.__dict__:
331
+ # return subclass
332
+
333
+ # attrs = {k: proxy_method_descriptor(v) for k, v in subclass.__dict__.items() if is_method_descriptor(v) }
334
+
335
+ # # Ensure module/doc are kept (in case they weren't in __dict__)
336
+ # attrs.setdefault('__module__', subclass.__module__)
337
+ # attrs.setdefault('__doc__', subclass.__doc__)
338
+ # attrs['__retrace_target_type__'] = subclass
339
+
340
+ # return type(subclass.__name__, (subclass,), attrs)
341
+
342
+ # orig__new__ = cls.__new__
343
+
344
+ # def proxied__new__(subclass, *args, **kwargs):
345
+ # nonlocal orig__new__
346
+ # return orig__new__(proxy_subclass(subclass), *args, **kwargs)
347
+
348
+ # def unproxied__new__(subclass, *args, **kwargs):
349
+ # return unproxy_type(subclass)(*args, **kwargs)
350
+
351
+ # # Dispatch which constructor to use based on your thread_state policy
352
+ # cls.__new__ = thread_state.dispatch(unproxied__new__, internal = proxied__new__)
353
+
354
+ def create_unproxied_type(cls):
355
+ def unproxy_type(cls):
356
+ return cls.__dict__.get('__retrace_unproxied__', cls)
357
+
358
+ bases = tuple(map(unproxy_type, cls.__bases__))
359
+ slots = dict(cls.__dict__)
360
+
361
+ if '__slots__' in slots:
362
+ for slot in slots['__slots__']:
363
+ slots.pop(slot)
364
+
365
+ # del slots['__init_subclass__']
366
+ return type(cls.__name__, tuple(bases), slots)
367
+
368
+ def extending_proxytype(cls, base, thread_state, ext_handler, int_handler, on_subclass_new):
369
+
370
+ # assert cls is base
371
+ assert not issubclass(cls, BaseException)
372
+ assert not issubclass(cls, ExtendingProxy)
373
+
374
+ def init_subclass(subclass, **kwargs):
375
+ # print(f'In init_subclass: {subclass} {subclass.__mro__} {kwargs}')
376
+ unproxied = create_unproxied_type(subclass)
377
+ subclass.__retrace_unproxied__ = unproxied
378
+
379
+ proxy_method_descriptors(cls = subclass, handler = int_handler)
380
+
381
+ if not issubclass(subclass, InternalProxy):
382
+ subclass.__new__ = functional.sequence(subclass.__new__, functional.side_effect(on_subclass_new))
383
+ subclass.__bases__ = subclass.__bases__ + (InternalProxy,)
384
+
385
+ assert not issubclass(subclass.__retrace_unproxied__, ExtendingProxy)
386
+
387
+ slots = { "__slots__": (),
388
+ "__retrace_unproxied__": cls,
389
+ "__module__": cls.__module__,
390
+ "__init_subclass__": init_subclass }
391
+
392
+ def wrap(target): return utils.wrapped_function(handler = ext_handler, target = target)
393
+
394
+ descriptors = []
395
+
396
+ for name,value in superdict(cls).items():
397
+ if name not in blacklist:
398
+ if is_method_descriptor(value):
399
+ slots[name] = wrap(getattr(base, name))
400
+ elif is_descriptor(value):
401
+ descriptors.append(name)
402
+
403
+ slots['__retrace_unproxied__'] = cls
404
+
405
+ extended = type(cls.__name__, (base, ExtendingProxy), slots)
406
+
407
+ for name in descriptors:
408
+ # proxy = ExtendingDescriptorProxy(handler = ext_handler, name = name, proxytype = extended)
409
+ proxy = DescriptorProxy(handler = ext_handler, target = getattr(cls, name))
410
+ setattr(extended, name, proxy)
411
+
412
+ def unproxied__new__(subclass, *args, **kwargs):
413
+ return subclass.__retrace_unproxied__(*args, **kwargs)
414
+
415
+ assert callable(base.__new__)
416
+
417
+ extended.__new__ = thread_state.dispatch(unproxied__new__, internal = base.__new__)
418
+
419
+ assert not issubclass(extended.__retrace_unproxied__, ExtendingProxy)
420
+ assert extended.__dict__['__retrace_unproxied__'] is extended.__retrace_unproxied__
421
+ # print(f'FOO: {extended} {id(extended)} {id(extended.__retrace_unproxied__)}')
422
+ # breakpoint()
423
+
424
+ return extended
@@ -0,0 +1,211 @@
1
+ import retracesoftware.functional as functional
2
+ import retracesoftware.utils as utils
3
+ import retracesoftware.stream as stream
4
+
5
+ from retracesoftware.proxy.proxytype import *
6
+ # from retracesoftware.proxy.gateway import gateway_pair
7
+ from retracesoftware.proxy.proxysystem import ProxySystem
8
+ from retracesoftware.proxy.thread import write_thread_switch, ThreadSwitch, thread_id
9
+ from retracesoftware.install.tracer import Tracer
10
+ from retracesoftware.install.patchfindspec import patch_find_spec
11
+ from retracesoftware.proxy.stubfactory import StubRef, ExtendedRef
12
+ from retracesoftware.proxy.globalref import GlobalRef
13
+
14
+ import sys
15
+ import os
16
+ import types
17
+ import gc
18
+
19
+ # class Placeholder:
20
+ # __slots__ = ['id', '__weakref__']
21
+
22
+ # def __init__(self, id):
23
+ # self.id = id
24
+
25
+ def keys_where_value(pred, dict):
26
+ for key,value in dict.items():
27
+ if pred(value): yield key
28
+
29
+ types_lookup = {v:k for k,v in types.__dict__.items() if isinstance(v, type)}
30
+
31
+ def resolve(obj):
32
+ try:
33
+ return getattr(sys.modules[obj.__module__], obj.__name__)
34
+ except:
35
+ return None
36
+
37
+ def resolveable(obj):
38
+ try:
39
+ return getattr(sys.modules[obj.__module__], obj.__name__) is obj
40
+ except:
41
+ return False
42
+
43
+ def resolveable_name(obj):
44
+ if obj in types_lookup:
45
+ return ('types', types_lookup[obj])
46
+ elif resolve(obj) is obj:
47
+ return (obj.__module__, obj.__name__)
48
+ else:
49
+ return None
50
+
51
+ # when
52
+ class RecordProxySystem(ProxySystem):
53
+
54
+ # def bind(self, obj):
55
+ # self.bindings[obj] = self.writer.handle(Placeholder(self.next_placeholder_id))
56
+ # self.writer(self.bindings[obj])
57
+ # self.next_placeholder_id += 1
58
+
59
+ def before_fork(self):
60
+ self.writer.keep_open = False
61
+ # self.writer.close()
62
+ super().before_fork()
63
+ # self.writer.path = self.dynamic_path
64
+
65
+ def after_fork_in_child(self):
66
+ new_path = self.new_child_path(self.writer.path)
67
+ new_path.parent.mkdir()
68
+ self.writer.path = new_path
69
+ self.writer.keep_open = True
70
+ super().after_fork_in_child()
71
+
72
+ def after_fork_in_parent(self):
73
+ super().after_fork_in_parent()
74
+ self.thread_state.value = self.saved_thread_state
75
+ self.writer.keep_open = True
76
+ # self.writer.reopen()
77
+
78
+ def set_thread_id(self, id):
79
+ utils.set_thread_id(self.writer.handle(ThreadSwitch(id)))
80
+ # utils.set_thread_id(id)
81
+
82
+ # def is_entry_frame(self, frame):
83
+ # if super().is_entry_frame(frame):
84
+ # self.write_main_path(frame.function.__code__.co_filename)
85
+ # return True
86
+ # return False
87
+
88
+ def create_from_external(self, obj):
89
+ # class of obj is bound
90
+ # can now write type(obj)
91
+
92
+ self.bind(obj)
93
+
94
+ breakpoint()
95
+
96
+ def patch_type(self, cls):
97
+
98
+ patched = super().patch_type(cls)
99
+
100
+ self.writer.type_serializer[patched] = functional.side_effect(self.writer.ext_bind)
101
+
102
+ return patched
103
+
104
+ def exclude_from_stacktrace(self, func):
105
+ self.writer.exclude_from_stacktrace(func)
106
+
107
+ def on_gc_event(self, phase, info):
108
+ if phase == 'start':
109
+ self.writer.stacktraces = False
110
+ self.on_start_collect(info['generation'])
111
+
112
+ elif phase == 'stop':
113
+ self.on_end_collect()
114
+ self.writer.stacktraces = self.stacktraces
115
+
116
+ def __init__(self, thread_state,
117
+ writer,
118
+ immutable_types,
119
+ tracing_config,
120
+ maybe_collect,
121
+ traceargs):
122
+
123
+ self.fork_counter = 0
124
+ # self.write_main_path = write_main_path
125
+
126
+ self.getpid = thread_state.wrap(
127
+ desired_state = 'disabled', function = os.getpid)
128
+
129
+ self.pid = self.getpid()
130
+
131
+ self.writer = writer
132
+
133
+ self.stacktraces = self.writer.stacktraces
134
+
135
+ if self.stacktraces:
136
+ def set(status):
137
+ self.writer.stacktraces = status
138
+
139
+ self.wrap_weakref_callback = functional.sequence(
140
+ self.wrap_weakref_callback,
141
+ lambda callback:
142
+ utils.observer(
143
+ on_call = functional.lazy(set, False),
144
+ on_result = functional.lazy(set, True),
145
+ on_error = functional.lazy(set, True),
146
+ function = callback))
147
+
148
+ self.exclude_from_stacktrace(RecordProxySystem.patch_type)
149
+ self.exclude_from_stacktrace(patch_find_spec.__call__)
150
+
151
+ self.extended_types = {}
152
+
153
+ sync_handle = self.writer.handle('SYNC')
154
+
155
+ self.on_ext_call = functional.lazy(utils.runall(maybe_collect, sync_handle) if maybe_collect else sync_handle)
156
+
157
+ write_sync = thread_state.dispatch(utils.noop, internal = functional.lazy(sync_handle))
158
+
159
+ self.sync = lambda function: \
160
+ utils.observer(on_call = write_sync, function = function)
161
+ error = self.writer.handle('ERROR')
162
+
163
+ def write_error(cls, val, traceback):
164
+ assert isinstance(val, BaseException)
165
+ error(cls, val)
166
+
167
+ tracer = Tracer(tracing_config, writer = self.writer.handle('TRACE'))
168
+
169
+ self.writer.exclude_from_stacktrace(write_error)
170
+ # self.writer.exclude_from_stacktrace(Tracer.write_call)
171
+
172
+ self.on_int_call = self.writer.handle('CALL')
173
+
174
+ # write_new_ref = self.writer.handle('RESULT')
175
+
176
+ self.on_ext_result = self.writer.handle('RESULT')
177
+
178
+ self.on_ext_error = write_error
179
+
180
+ self.writer.type_serializer[types.ModuleType] = GlobalRef
181
+
182
+ self.bind = self.writer.bind
183
+
184
+ self.create_from_external = self.writer.ext_bind
185
+
186
+ self.write_trace = self.writer.handle('TRACER')
187
+
188
+ self.checkpoint = self.writer.handle('CHECKPOINT')
189
+
190
+ self.on_weakref_callback_start = functional.lazy(self.writer.handle('ON_WEAKREF_CALLBACK_START'))
191
+ self.on_weakref_callback_end = functional.lazy(self.writer.handle('ON_WEAKREF_CALLBACK_END'))
192
+
193
+ self.on_start_collect = self.writer.handle('ON_START_COLLECT')
194
+ self.on_end_collect = self.writer.handle('ON_END_COLLECT')
195
+
196
+ super().__init__(thread_state = thread_state,
197
+ tracer = tracer,
198
+ traceargs = traceargs,
199
+ immutable_types = immutable_types)
200
+
201
+ def ext_proxytype(self, cls):
202
+
203
+ proxytype = super().ext_proxytype(cls)
204
+
205
+ ref = self.writer.handle(StubRef(proxytype))
206
+
207
+ self.writer.type_serializer[proxytype] = functional.constantly(ref)
208
+
209
+ return proxytype
210
+
211
+