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.
@@ -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
- def ext_proxy_factory(self):
114
- return wrapping_proxy_factory(proxytype = self.proxytype, create_reference = compose(type, Reference), handler = self.ext_handler)
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
- def int_proxy_factory(self):
117
- return wrapping_proxy_factory(proxytype = self.proxytype, create_reference = Reference, handler = self.int_handler)
116
+ # def int_proxy_factory(self):
117
+ # return wrapping_proxy_factory(proxytype = self.proxytype, create_reference = Reference, handler = self.int_handler)
118
118
 
119
- def ext_call_handler(self):
120
- return self.int_handler.call_handler
119
+ # def ext_call_handler(self):
120
+ # return self.int_handler.call_handler
121
121
 
122
- def int_call_handler(self):
123
- return self.ext_handler.call_handler
122
+ # def int_call_handler(self):
123
+ # return self.ext_handler.call_handler
124
124
 
125
- def before_fork(self):
126
- pass
127
- # self.state_before_fork = self.thread_state.value
128
- # self.thread_state.value = 'disabled'
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
- def after_fork_in_child(self):
131
- self.fork_counter = 0
130
+ # def after_fork_in_child(self):
131
+ # self.fork_counter = 0
132
132
 
133
- def after_fork_in_parent(self):
134
- self.fork_counter += 1
135
- # self.thread_state.value = self.state_before_fork
133
+ # def after_fork_in_parent(self):
134
+ # self.fork_counter += 1
135
+ # # self.thread_state.value = self.state_before_fork
136
136
 
137
- def gc_start(self):
138
- self.before_gc = self.thread_state.value
139
- self.thread_state.value = 'external'
137
+ # def gc_start(self):
138
+ # self.before_gc = self.thread_state.value
139
+ # self.thread_state.value = 'external'
140
140
 
141
- def gc_end(self):
142
- self.thread_state.value = self.before_gc
143
- del self.before_gc
141
+ # def gc_end(self):
142
+ # self.thread_state.value = self.before_gc
143
+ # del self.before_gc
144
144
 
145
- def gc_hook(self, phase, info):
145
+ # def gc_hook(self, phase, info):
146
146
 
147
- if phase == 'start':
148
- self.gc_start()
147
+ # if phase == 'start':
148
+ # self.gc_start()
149
149
 
150
- elif phase == 'stop':
151
- self.gc_end()
150
+ # elif phase == 'stop':
151
+ # self.gc_end()
152
152
 
153
- def __init__(self, thread_state, on_new_proxytype, sync,
154
- debug, checkpoint, verbose,
155
- ext_proxy, ext_handler, int_proxy, int_handler):
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
- assert ext_proxy
157
+ # assert ext_proxy
158
158
 
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)
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
- # self.checkpoint_ext_call = self.arg_serializer(self.checkpoint_ext_call)
179
+ # # self.checkpoint_ext_call = self.arg_serializer(self.checkpoint_ext_call)
180
180
 
181
- self.thread_state = thread_state
182
- self.debug = debug
183
- self.fork_counter = 0
184
- self.verbose = verbose
181
+ # self.thread_state = thread_state
182
+ # self.debug = debug
183
+ # self.fork_counter = 0
184
+ # self.verbose = verbose
185
185
 
186
- self.on_new_proxytype = on_new_proxytype
187
- self._sync = sync
188
- self.thread_counter = self.sync_function(counter(1))
186
+ # self.on_new_proxytype = on_new_proxytype
187
+ # self._sync = sync
188
+ # self.thread_counter = self.sync_function(counter(1))
189
189
 
190
- # immutable_types = self.disable_for(immutable_types)
190
+ # # immutable_types = self.disable_for(immutable_types)
191
191
 
192
- gc.callbacks.append(self.gc_hook)
192
+ # gc.callbacks.append(self.gc_hook)
193
193
 
194
- def before():
195
- print("In before!!!!")
196
- with self.thread_state.select('disabled'):
197
- self.before_fork()
194
+ # def before():
195
+ # print("In before!!!!")
196
+ # with self.thread_state.select('disabled'):
197
+ # self.before_fork()
198
198
 
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))
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
- self.tracing = None
205
+ # self.tracing = None
206
206
 
207
- if debug > 3:
207
+ # if debug > 3:
208
208
 
209
- # def checkpoint(obj):
210
- # print(f'in checkpoint: {obj}')
211
- # self.checkpoint(obj)
209
+ # # def checkpoint(obj):
210
+ # # print(f'in checkpoint: {obj}')
211
+ # # self.checkpoint(obj)
212
212
 
213
- FrameTracer.install(self.thread_state.dispatch(_proxy.noop, internal = checkpoint))
213
+ # FrameTracer.install(self.thread_state.dispatch(_proxy.noop, internal = checkpoint))
214
214
 
215
- # import threading
216
- # tracer = FrameTracer(
217
- # pred = self.thread_state.predicate('internal'),
218
- # checkpoint = checkpoint)
215
+ # # import threading
216
+ # # tracer = FrameTracer(
217
+ # # pred = self.thread_state.predicate('internal'),
218
+ # # checkpoint = checkpoint)
219
219
 
220
- # sys.settrace(tracer)
221
- # threading.settrace(tracer)
222
- # self.trace = lambda event, **kwargs: checkpoint({'type': 'trace', 'event': event} | kwargs)
223
- # self.enable_tracing()
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
- def sync_type(self, base):
226
- return sync_type(sync = self.sync, base = base)
225
+ # def sync_type(self, base):
226
+ # return sync_type(sync = self.sync, base = base)
227
227
 
228
- def sync_function(self, function):
229
- return intercept(on_call = self._sync, function = function)
228
+ # def sync_function(self, function):
229
+ # return intercept(on_call = self._sync, function = function)
230
230
 
231
- def checkpoint(self, obj):
232
- pass
231
+ # def checkpoint(self, obj):
232
+ # pass
233
233
 
234
- def log(self, message):
235
- if self.verbose:
236
- print(message)
234
+ # def log(self, message):
235
+ # if self.verbose:
236
+ # print(message)
237
237
 
238
- self.checkpoint({'type': 'log', 'message': message})
238
+ # self.checkpoint({'type': 'log', 'message': message})
239
239
 
240
- @property
241
- def disable(self):
242
- return self.thread_state.select('disabled')
240
+ # @property
241
+ # def disable(self):
242
+ # return self.thread_state.select('disabled')
243
243
 
244
- def with_state(self, state, function):
245
- return self.thread_state.wrap(desired_state = state, function = function)
244
+ # def with_state(self, state, function):
245
+ # return self.thread_state.wrap(desired_state = state, function = function)
246
246
 
247
- def disable_for(self, function):
248
- return self.thread_state.wrap(desired_state = 'disabled', function = function)
247
+ # def disable_for(self, function):
248
+ # return self.thread_state.wrap(desired_state = 'disabled', function = function)
249
249
 
250
- def __call__(self, module, name, obj):
250
+ # def __call__(self, module, name, obj):
251
251
 
252
- if type(obj) == type:
253
- try:
254
- return self.extend_type(obj)
255
- except:
256
- pass
252
+ # if type(obj) == type:
253
+ # try:
254
+ # return self.extend_type(obj)
255
+ # except:
256
+ # pass
257
257
 
258
- self.checkpoint({'type': 'proxy', 'module': module, 'name': name})
258
+ # self.checkpoint({'type': 'proxy', 'module': module, 'name': name})
259
259
 
260
- if is_function_type(type(obj)) or type(obj) == type:
261
- proxied = RootProxy(module = module, name = name, handler = self.ext_handler, target = obj)
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
- 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)
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
- # return self.ext_proxy(obj)
273
+ # # return self.ext_proxy(obj)
274
274
 
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))
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
- return function(*args, **kwargs)
285
+ # return function(*args, **kwargs)
286
286
 
287
- return start_new_thread(threadrunner, *args)
287
+ # return start_new_thread(threadrunner, *args)
288
288
 
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)
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
- 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
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
- 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))
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
- def __del__(obj):
341
- try:
342
- self.on_del(Reference(obj))
343
- # self.external.handler.on_del(_proxy.Reference(obj))
344
- except:
345
- pass
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
- try:
348
- base.__del__(obj)
349
- except:
350
- pass
347
+ # try:
348
+ # base.__del__(obj)
349
+ # except:
350
+ # pass
351
351
 
352
- extended.__del__ = __del__
352
+ # extended.__del__ = __del__
353
353
 
354
- if self.on_new_proxytype:
355
- self.on_new_proxytype(base.__module__, base.__name__, extended)
354
+ # if self.on_new_proxytype:
355
+ # self.on_new_proxytype(base.__module__, base.__name__, extended)
356
356
 
357
- return extended
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.proxytype import extending_proxytype, make_extensible
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 __init__(self, thread_state):
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
- if type(obj) == type and utils.is_extendable(obj):
15
- return self.extend_type(obj)
16
- elif callable(obj):
17
- return utils.wrapped_function(handler = self.ext_handler, target = obj)
18
- else:
19
- raise Exception(f'object {obj} was not proxied as its not a extensible type and is not callable')
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}')