Update 2025-04-24_11:44:19
This commit is contained in:
		
							
								
								
									
										98
									
								
								venv/lib/python3.11/site-packages/wrapt/weakrefs.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								venv/lib/python3.11/site-packages/wrapt/weakrefs.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,98 @@
 | 
			
		||||
import functools
 | 
			
		||||
import weakref
 | 
			
		||||
 | 
			
		||||
from .__wrapt__ import ObjectProxy, _FunctionWrapperBase
 | 
			
		||||
 | 
			
		||||
# A weak function proxy. This will work on instance methods, class
 | 
			
		||||
# methods, static methods and regular functions. Special treatment is
 | 
			
		||||
# needed for the method types because the bound method is effectively a
 | 
			
		||||
# transient object and applying a weak reference to one will immediately
 | 
			
		||||
# result in it being destroyed and the weakref callback called. The weak
 | 
			
		||||
# reference is therefore applied to the instance the method is bound to
 | 
			
		||||
# and the original function. The function is then rebound at the point
 | 
			
		||||
# of a call via the weak function proxy.
 | 
			
		||||
 | 
			
		||||
def _weak_function_proxy_callback(ref, proxy, callback):
 | 
			
		||||
    if proxy._self_expired:
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    proxy._self_expired = True
 | 
			
		||||
 | 
			
		||||
    # This could raise an exception. We let it propagate back and let
 | 
			
		||||
    # the weakref.proxy() deal with it, at which point it generally
 | 
			
		||||
    # prints out a short error message direct to stderr and keeps going.
 | 
			
		||||
 | 
			
		||||
    if callback is not None:
 | 
			
		||||
        callback(proxy)
 | 
			
		||||
 | 
			
		||||
class WeakFunctionProxy(ObjectProxy):
 | 
			
		||||
 | 
			
		||||
    __slots__ = ('_self_expired', '_self_instance')
 | 
			
		||||
 | 
			
		||||
    def __init__(self, wrapped, callback=None):
 | 
			
		||||
        # We need to determine if the wrapped function is actually a
 | 
			
		||||
        # bound method. In the case of a bound method, we need to keep a
 | 
			
		||||
        # reference to the original unbound function and the instance.
 | 
			
		||||
        # This is necessary because if we hold a reference to the bound
 | 
			
		||||
        # function, it will be the only reference and given it is a
 | 
			
		||||
        # temporary object, it will almost immediately expire and
 | 
			
		||||
        # the weakref callback triggered. So what is done is that we
 | 
			
		||||
        # hold a reference to the instance and unbound function and
 | 
			
		||||
        # when called bind the function to the instance once again and
 | 
			
		||||
        # then call it. Note that we avoid using a nested function for
 | 
			
		||||
        # the callback here so as not to cause any odd reference cycles.
 | 
			
		||||
 | 
			
		||||
        _callback = callback and functools.partial(
 | 
			
		||||
                _weak_function_proxy_callback, proxy=self,
 | 
			
		||||
                callback=callback)
 | 
			
		||||
 | 
			
		||||
        self._self_expired = False
 | 
			
		||||
 | 
			
		||||
        if isinstance(wrapped, _FunctionWrapperBase):
 | 
			
		||||
            self._self_instance = weakref.ref(wrapped._self_instance,
 | 
			
		||||
                    _callback)
 | 
			
		||||
 | 
			
		||||
            if wrapped._self_parent is not None:
 | 
			
		||||
                super(WeakFunctionProxy, self).__init__(
 | 
			
		||||
                        weakref.proxy(wrapped._self_parent, _callback))
 | 
			
		||||
 | 
			
		||||
            else:
 | 
			
		||||
                super(WeakFunctionProxy, self).__init__(
 | 
			
		||||
                        weakref.proxy(wrapped, _callback))
 | 
			
		||||
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            self._self_instance = weakref.ref(wrapped.__self__, _callback)
 | 
			
		||||
 | 
			
		||||
            super(WeakFunctionProxy, self).__init__(
 | 
			
		||||
                    weakref.proxy(wrapped.__func__, _callback))
 | 
			
		||||
 | 
			
		||||
        except AttributeError:
 | 
			
		||||
            self._self_instance = None
 | 
			
		||||
 | 
			
		||||
            super(WeakFunctionProxy, self).__init__(
 | 
			
		||||
                    weakref.proxy(wrapped, _callback))
 | 
			
		||||
 | 
			
		||||
    def __call__(*args, **kwargs):
 | 
			
		||||
        def _unpack_self(self, *args):
 | 
			
		||||
            return self, args
 | 
			
		||||
 | 
			
		||||
        self, args = _unpack_self(*args)
 | 
			
		||||
 | 
			
		||||
        # We perform a boolean check here on the instance and wrapped
 | 
			
		||||
        # function as that will trigger the reference error prior to
 | 
			
		||||
        # calling if the reference had expired.
 | 
			
		||||
 | 
			
		||||
        instance = self._self_instance and self._self_instance()
 | 
			
		||||
        function = self.__wrapped__ and self.__wrapped__
 | 
			
		||||
 | 
			
		||||
        # If the wrapped function was originally a bound function, for
 | 
			
		||||
        # which we retained a reference to the instance and the unbound
 | 
			
		||||
        # function we need to rebind the function and then call it. If
 | 
			
		||||
        # not just called the wrapped function.
 | 
			
		||||
 | 
			
		||||
        if instance is None:
 | 
			
		||||
            return self.__wrapped__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
        return function.__get__(instance, type(instance))(*args, **kwargs)
 | 
			
		||||
		Reference in New Issue
	
	Block a user