| 
					
				 | 
			
			
				@@ -280,6 +280,96 @@ class Local(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             raise AttributeError(name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class LocalStack(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """This class works similar to a :class:`Local` but keeps a stack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    of objects instead.  This is best explained with an example:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> ls = LocalStack() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> ls.push(42) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> ls.top 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        42 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> ls.push(23) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> ls.top 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        23 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> ls.pop() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        23 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> ls.top 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        42 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    They can be force released by using a :class:`LocalManager` or with 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    the :func:`release_local` function but the correct way is to pop the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    item from the stack after using.  When the stack is empty it will 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    no longer be bound to the current context (and as such released). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    By calling the stack without arguments it returns a proxy that resolves to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    the topmost item on the stack. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __init__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self._local = Local() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __release_local__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self._local.__release_local__() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def _get__ident_func__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return self._local.__ident_func__ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def _set__ident_func__(self, value): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        object.__setattr__(self._local, '__ident_func__', value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    __ident_func__ = property(_get__ident_func__, _set__ident_func__) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    del _get__ident_func__, _set__ident_func__ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __call__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        def _lookup(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            rv = self.top 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if rv is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                raise RuntimeError('object unbound') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return rv 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Proxy(_lookup) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def push(self, obj): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """Pushes a new item to the stack""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rv = getattr(self._local, 'stack', None) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if rv is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self._local.stack = rv = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rv.append(obj) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return rv 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def pop(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """Removes the topmost item from the stack, will return the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        old value or `None` if the stack was already empty. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        stack = getattr(self._local, 'stack', None) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if stack is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif len(stack) == 1: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            release_local(self._local) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return stack[-1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return stack.pop() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @property 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def stack(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """get_current_worker_task uses this to find 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        the original task that was executed by the worker.""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        stack = getattr(self._local, 'stack', None) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if stack is not None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return stack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @property 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def top(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """The topmost item on the stack.  If the stack is empty, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        `None` is returned. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return self._local.stack[-1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        except (AttributeError, IndexError): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class LocalManager(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     """Local objects cannot manage themselves. For that you need a local 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     manager.  You can pass a local manager multiple locals or add them later 
			 |