ionelmc/python-lazy-object-proxy

Is it possible to replace a Proxy object with its __wrapped__

KOLANICH opened this issue · 1 comments

I mean that let's assumme that we have inherited from Proxy and created some hooks for example on getattr. And we wanna these hooks work only for unwrapped object.

For example we wanna collect every set attr into a dict and then apply it when it is set. So we create a dict, add into the factory a loop applying it, add into setattr impl the stuff populating it.

But when the factory is triggered, we need to access the original object. So we disable this behaviour in our proxy, but ... our python code is still executed.

def ProxyWithWorkaround_(factory, *args, **kwargs):
	_delayed={"__path__":None}
	class ProxyWithWorkaround(lazy_object_proxy.Proxy):
		def __getattr__(self, key):
			if _delayed is not None and key in _delayed:
				return _delayed[key]
			else:
				return super().__getattr__(key)
		def __setattr__(self, key, value):
			if _delayed is not None:
				_delayed[key]=value
			else:
				super().__setattr__(key, value)
	
	@functools.wraps(factory)
	def factory1(*args, **kwargs):
		nonlocal _delayed
		res=factory(*args, **kwargs)
		for k, v in _delayed.items():
			setattr(res, k, v)
		_delayed=None
		return res
	return ProxyWithWorkaround(factory1, *args, **kwargs)

Proxy has done its purpose, but we still have overhead.

So, I wonder if it is possible to get all the refs to the Proxy from the interpreter internals and replace them with the refs to the constructed object.

https://benkurtovic.com/2015/01/28/python-object-replacement.html

Seems horrendously unsafe to mess with raw memory. If overhead is really a problem for you then fork this project and add the _delayed stuff in the cext implementation.