1
# -*- test-case-name: twisted.test.test_context -*-
2
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
3
# See LICENSE for details.
8
Dynamic pseudo-scoping for Python.
10
Call functions with context.call({key: value}, func); func and
11
functions that it calls will be able to use 'context.get(key)' to
18
from threading import local
22
from twisted.python import threadable
24
defaultContextDict = {}
26
setDefault = defaultContextDict.__setitem__
30
self.contexts = [defaultContextDict]
32
def callWithContext(self, ctx, func, *args, **kw):
33
newContext = self.contexts[-1].copy()
34
newContext.update(ctx)
35
self.contexts.append(newContext)
37
return func(*args,**kw)
41
def getContext(self, key, default=None):
42
return self.contexts[-1].get(key, default)
45
class _ThreadedContextTracker:
47
self.threadId = threadable.getThreadID
48
self.contextPerThread = {}
50
def currentContext(self):
51
tkey = self.threadId()
53
return self.contextPerThread[tkey]
55
ct = self.contextPerThread[tkey] = ContextTracker()
58
def callWithContext(self, ctx, func, *args, **kw):
59
return self.currentContext().callWithContext(ctx, func, *args, **kw)
61
def getContext(self, key, default=None):
62
return self.currentContext().getContext(key, default)
65
class _TLSContextTracker(_ThreadedContextTracker):
67
self.storage = local()
69
def currentContext(self):
71
return self.storage.ct
72
except AttributeError:
73
ct = self.storage.ct = ContextTracker()
77
ThreadedContextTracker = _ThreadedContextTracker
79
ThreadedContextTracker = _TLSContextTracker
81
def installContextTracker(ctr):
82
global theContextTracker
86
theContextTracker = ctr
87
call = theContextTracker.callWithContext
88
get = theContextTracker.getContext
90
installContextTracker(ThreadedContextTracker())