| 
					
				 | 
			
			
				@@ -15,12 +15,14 @@ import traceback 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from kombu.syn import detect_environment 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+from celery.local import Proxy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+USE_PURE_LOCALS = os.environ.get("USE_PURE_LOCALS") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 _Thread = threading.Thread 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 _Event = threading._Event 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 active_count = (getattr(threading, 'active_count', None) or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 threading.activeCount) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-USE_PURE_LOCALS = os.environ.get("USE_PURE_LOCALS") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class Event(_Event): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -93,20 +95,234 @@ class bgThread(Thread): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if self.is_alive(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             self.join(1e100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    from greenlet import getcurrent as get_ident 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+except ImportError:  # pragma: no cover 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        from thread import get_ident  # noqa 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    except ImportError:  # pragma: no cover 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            from dummy_thread import get_ident  # noqa 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        except ImportError:  # pragma: no cover 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            from _thread import get_ident  # noqa 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def release_local(local): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """Releases the contents of the local for the current context. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    This makes it possible to use locals without a manager. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Example:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> loc = Local() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> loc.foo = 42 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> release_local(loc) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> hasattr(loc, 'foo') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    With this function one can release :class:`Local` objects as well 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    as :class:`StackLocal` objects.  However it is not possible to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    release data held by proxies that way, one always has to retain 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    a reference to the underlying local object in order to be able 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    to release it. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .. versionadded:: 0.6.1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    local.__release_local__() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class Local(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    __slots__ = ('__storage__', '__ident_func__') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __init__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        object.__setattr__(self, '__storage__', {}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        object.__setattr__(self, '__ident_func__', get_ident) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __iter__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return iter(self.__storage__.items()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __call__(self, proxy): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """Create a proxy for a name.""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Proxy(self, proxy) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __release_local__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.__storage__.pop(self.__ident_func__(), None) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __getattr__(self, name): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return self.__storage__[self.__ident_func__()][name] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        except KeyError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            raise AttributeError(name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __setattr__(self, name, value): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ident = self.__ident_func__() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        storage = self.__storage__ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            storage[ident][name] = value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        except KeyError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            storage[ident] = {name: value} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __delattr__(self, name): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            del self.__storage__[self.__ident_func__()][name] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        except KeyError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            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 by appending them to `manager.locals`.  Everytime the manager 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cleans up it, will clean up all the data left in the locals for this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    context. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    The `ident_func` parameter can be added to override the default ident 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function for the wrapped locals. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __init__(self, locals=None, ident_func=None): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if locals is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.locals = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif isinstance(locals, Local): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.locals = [locals] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.locals = list(locals) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if ident_func is not None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.ident_func = ident_func 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for local in self.locals: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                object.__setattr__(local, '__ident_func__', ident_func) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.ident_func = get_ident 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def get_ident(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """Return the context identifier the local objects use internally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for this context.  You cannot override this method to change the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        behavior but use it to link other context local objects (such as 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SQLAlchemy's scoped sessions) to the Werkzeug locals.""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return self.ident_func() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def cleanup(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """Manually clean up the data in the locals for this context. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Call this at the end of the request or use `make_middleware()`. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for local in self.locals: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            release_local(local) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __repr__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return '<{0} storages: {1}>'.format( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.__class__.__name__, len(self.locals)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class _FastLocalStack(threading.local): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __init__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.stack = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.push = self.stack.append 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.pop = self.stack.pop 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @property 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def top(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return self.stack[-1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        except (AttributeError, IndexError): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 if detect_environment() == 'default' and not USE_PURE_LOCALS: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    class LocalStack(threading.local): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        def __init__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            self.stack = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            self.push = self.stack.append 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            self.pop = self.stack.pop 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        @property 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        def top(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return self.stack[-1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            except (AttributeError, IndexError): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    LocalStack = _FastLocalStack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    # See #706 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    from celery.local import LocalStack  # noqa 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # - See #706 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # since each thread has its own greenlet we can just use those as 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # identifiers for the context.  If greenlets are not available we 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # fall back to the  current thread ident. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    LocalStack = _LocalStack  # noqa 
			 |