<s> import threading <EOL> import copy <EOL> stackIds = [ <NUM_LIT:0> ] <EOL> stackLock = threading . Lock ( ) <EOL> def allocateStackId ( ) : <EOL> with stackLock : <EOL> stackIds [ <NUM_LIT:0> ] += <NUM_LIT:1> <EOL> return stackIds [ <NUM_LIT:0> ] <EOL> class ThreadLocalStack ( object ) : <EOL> """<STR_LIT>""" <EOL> threadLocalStorage = threading . local ( ) <EOL> @ staticmethod <EOL> def copyContents ( ) : <EOL> return dict ( ( copy . copy ( key ) , copy . copy ( value ) ) for key , value in <EOL> ThreadLocalStack . threadLocalStorage . __dict__ . iteritems ( ) ) <EOL> @ staticmethod <EOL> def setContents ( contentsDict ) : <EOL> ThreadLocalStack . threadLocalStorage . __dict__ . update ( contentsDict ) <EOL> def __init__ ( self ) : <EOL> self . stackId_ = allocateStackId ( ) <EOL> def push ( self , element ) : <EOL> stack = self . getOrCreateStack ( ) <EOL> stack . append ( element ) <EOL> def pop ( self ) : <EOL> stack = self . getStackAssertIfEmpty ( ) <EOL> stack . pop ( ) <EOL> remaining = len ( stack ) <EOL> if ( remaining == <NUM_LIT:0> ) : <EOL> setattr ( ThreadLocalStack . threadLocalStorage , str ( self . stackId_ ) , None ) <EOL> return remaining <EOL> @ property <EOL> def top ( self ) : <EOL> stack = self . getStackAssertIfEmpty ( ) <EOL> return stack [ - <NUM_LIT:1> ] <EOL> @ property <EOL> def topOrNone ( self ) : <EOL> stack = self . getStack ( ) <EOL> return None if stack is None or len ( stack ) == <NUM_LIT:0> else stack [ - <NUM_LIT:1> ] <EOL> def getOrCreateStack ( self ) : <EOL> stack = self . getStack ( ) <EOL> if stack is None : <EOL> stack = [ ] <EOL> setattr ( ThreadLocalStack . threadLocalStorage , str ( self . stackId_ ) , stack ) <EOL> return stack <EOL> def getStack ( self ) : <EOL> return getattr ( ThreadLocalStack . threadLocalStorage , str ( self . stackId_ ) , None ) <EOL> def getStackAssertIfEmpty ( self ) : <EOL> stack = self . getStack ( ) <EOL> assert stack is not None <EOL> assert len ( stack ) > <NUM_LIT:0> <EOL> return stack <EOL> threadLocalStackPushableDescendents_ = { } <EOL> def threadLocalStackPushClassFor_ ( t ) : <EOL> """<STR_LIT>""" <EOL> if type not in threadLocalStackPushableDescendents_ : <EOL> threadLocalStackPushableDescendents_ [ t ] = computeThreadLocalStackPushClassFor_ ( t ) <EOL> return threadLocalStackPushableDescendents_ [ t ] <EOL> def computeThreadLocalStackPushClassFor_ ( t ) : <EOL> for b in t . __bases__ : <EOL> if b is ThreadLocalStackPushable : <EOL> return t <EOL> for b in t . __bases__ : <EOL> candidate = threadLocalStackPushClassFor_ ( b ) <EOL> if candidate is not None : <EOL> return candidate <EOL> return None <EOL> class NullContextPusher ( object ) : <EOL> def __init__ ( self , classToPush ) : <EOL> self . classToPush_ = classToPush <EOL> def __enter__ ( self ) : <EOL> toLookup = threadLocalStackPushClassFor_ ( self . classToPush_ ) <EOL> ThreadLocalStackPushable . classToStackMap [ toLookup ] . push ( None ) <EOL> def __exit__ ( self , * args ) : <EOL> toLookup = threadLocalStackPushClassFor_ ( self . classToPush_ ) <EOL> ThreadLocalStackPushable . classToStackMap [ toLookup ] . pop ( ) <EOL> class ThreadLocalStackPushable ( object ) : <EOL> classToStackMap = { } <EOL> def __init__ ( self ) : <EOL> toLookup = threadLocalStackPushClassFor_ ( type ( self ) ) <EOL> if toLookup not in ThreadLocalStackPushable . classToStackMap : <EOL> ThreadLocalStackPushable . classToStackMap [ toLookup ] = ThreadLocalStack ( ) <EOL> def __enter__ ( self ) : <EOL> toLookup = threadLocalStackPushClassFor_ ( type ( self ) ) <EOL> ThreadLocalStackPushable . classToStackMap [ toLookup ] . push ( self ) <EOL> def __exit__ ( self , * args ) : <EOL> toLookup = threadLocalStackPushClassFor_ ( type ( self ) ) <EOL> ThreadLocalStackPushable . classToStackMap [ toLookup ] . pop ( ) <EOL> @ classmethod <EOL> def getCurrent ( cls ) : <EOL> toLookup = threadLocalStackPushClassFor_ ( cls ) <EOL> if toLookup not in ThreadLocalStackPushable . classToStackMap : <EOL> return None <EOL> return ThreadLocalStackPushable . classToStackMap [ toLookup ] . topOrNone <EOL> @ classmethod <EOL> def getNullContext ( cls ) : <EOL> return NullContextPusher ( cls ) </s>
