<s> import ast <EOL> import IECore <EOL> import Gaffer <EOL> import GafferDispatch <EOL> class PythonCommand ( GafferDispatch . ExecutableNode ) : <EOL> def __init__ ( self , name = "<STR_LIT>" ) : <EOL> GafferDispatch . ExecutableNode . __init__ ( self , name ) <EOL> self [ "<STR_LIT>" ] = Gaffer . StringPlug ( substitutions = Gaffer . Context . Substitutions . NoSubstitutions ) <EOL> self [ "<STR_LIT>" ] = Gaffer . CompoundDataPlug ( ) <EOL> self [ "<STR_LIT>" ] = Gaffer . BoolPlug ( ) <EOL> def hash ( self , context ) : <EOL> h = GafferDispatch . ExecutableNode . hash ( self , context ) <EOL> command = self [ "<STR_LIT>" ] . getValue ( ) <EOL> h . append ( command ) <EOL> parser = _Parser ( command ) <EOL> for name in parser . contextReads : <EOL> value = context . get ( name ) <EOL> if isinstance ( value , IECore . Object ) : <EOL> value . hash ( h ) <EOL> else : <EOL> h . append ( value ) <EOL> self [ "<STR_LIT>" ] . hash ( h ) <EOL> if self . requiresSequenceExecution ( ) : <EOL> h . append ( context . getFrame ( ) ) <EOL> return h <EOL> def execute ( self ) : <EOL> executionDict = self . __executionDict ( ) <EOL> exec ( self [ "<STR_LIT>" ] . getValue ( ) , executionDict , executionDict ) <EOL> def executeSequence ( self , frames ) : <EOL> if not self . requiresSequenceExecution ( ) : <EOL> Gaffer . ExecutableNode . executeSequence ( self , frames ) <EOL> return <EOL> executionDict = self . __executionDict ( frames ) <EOL> exec ( self [ "<STR_LIT>" ] . getValue ( ) , executionDict , executionDict ) <EOL> def requiresSequenceExecution ( self ) : <EOL> return self [ "<STR_LIT>" ] . getValue ( ) <EOL> def __executionDict ( self , frames = None ) : <EOL> result = { <EOL> "<STR_LIT>" : IECore , <EOL> "<STR_LIT>" : Gaffer , <EOL> "<STR_LIT>" : self , <EOL> "<STR_LIT>" : Gaffer . Context . current ( ) , <EOL> "<STR_LIT>" : _VariablesDict ( <EOL> self [ "<STR_LIT>" ] , <EOL> Gaffer . Context . current ( ) , <EOL> validFrames = set ( frames ) if frames is not None else { Gaffer . Context . current ( ) . getFrame ( ) } <EOL> ) <EOL> } <EOL> if frames is not None : <EOL> result [ "<STR_LIT>" ] = frames <EOL> return result <EOL> class _VariablesDict ( dict ) : <EOL> def __init__ ( self , variables , context , validFrames ) : <EOL> dict . __init__ ( self ) <EOL> self . __variables = variables <EOL> self . __context = context <EOL> self . __validFrames = validFrames <EOL> self . __frame = None <EOL> def keys ( self ) : <EOL> self . __update ( ) <EOL> return dict . keys ( self ) <EOL> def __getitem__ ( self , key ) : <EOL> self . __update ( ) <EOL> return dict . __getitem__ ( self , key ) <EOL> def __update ( self ) : <EOL> if self . __frame == self . __context . getFrame ( ) : <EOL> return <EOL> if self . __context . getFrame ( ) not in self . __validFrames : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> self . clear ( ) <EOL> for plug in self . __variables . children ( ) : <EOL> value , name = self . __variables . memberDataAndName ( plug ) <EOL> if value is None : <EOL> continue <EOL> with IECore . IgnoredExceptions ( Exception ) : <EOL> value = value . value <EOL> self [ name ] = value <EOL> self . __frame = self . __context . getFrame ( ) <EOL> class _Parser ( ast . NodeVisitor ) : <EOL> def __init__ ( self , expression ) : <EOL> ast . NodeVisitor . __init__ ( self ) <EOL> self . contextReads = set ( ) <EOL> self . visit ( ast . parse ( expression ) ) <EOL> def visit_Subscript ( self , node ) : <EOL> if not isinstance ( node . ctx , ast . Load ) or not isinstance ( node . value , ast . Name ) : <EOL> return <EOL> if node . value . id != "<STR_LIT>" : <EOL> return <EOL> if not isinstance ( node . slice , ast . Index ) or not isinstance ( node . slice . value , ast . Str ) : <EOL> return <EOL> self . contextReads . add ( node . slice . value . s ) <EOL> def visit_Call ( self , node ) : <EOL> if isinstance ( node . func , ast . Attribute ) : <EOL> if isinstance ( node . func . value , ast . Name ) : <EOL> if node . func . value . id == "<STR_LIT>" : <EOL> if node . func . attr == "<STR_LIT>" : <EOL> self . contextReads . add ( "<STR_LIT>" ) <EOL> elif node . func . attr == "<STR_LIT>" : <EOL> self . contextReads . add ( "<STR_LIT>" ) <EOL> self . contextReads . add ( "<STR_LIT>" ) <EOL> elif node . func . attr == "<STR_LIT>" : <EOL> self . contextReads . add ( "<STR_LIT>" ) <EOL> elif node . func . attr == "<STR_LIT>" : <EOL> if not isinstance ( node . args [ <NUM_LIT:0> ] , ast . Str ) : <EOL> raise SyntaxError ( "<STR_LIT>" ) <EOL> self . contextReads . add ( node . args [ <NUM_LIT:0> ] . s ) <EOL> ast . NodeVisitor . generic_visit ( self , node ) <EOL> IECore . registerRunTimeTyped ( PythonCommand , typeName = "<STR_LIT>" ) </s>
