def getUnresolvedFreeVariableExceptionWithTrace(e, sourceFileName): chainWithPos = e.freeVarChainWithPos varLine = chainWithPos.pos.lineno varName = chainWithPos.var[0] return UnresolvedFreeVariableExceptionWithTrace( '''unable to resolve free variable '%s' for pyfora conversion''' % varName, [Exceptions.makeTraceElement(sourceFileName, varLine)])
def _convertUnresolvedFreeVariableExceptionAndRaise(e, sourceFileName): logging.error( "Converter raised an UnresolvedFreeVariableException exception: %s", traceback.format_exc()) chainWithPos = e.freeVarChainWithPos varLine = chainWithPos.pos.lineno varName = chainWithPos.var[0] raise UnresolvedFreeVariableExceptionWithTrace( '''unable to resolve free variable '%s' for pyfora conversion''' % varName, [Exceptions.makeTraceElement(sourceFileName, varLine)])
def _convertUnresolvedFreeVariableExceptionAndRaise(e, sourceFileName): logging.error( "Converter raised an UnresolvedFreeVariableException exception: %s", traceback.format_exc()) chainWithPos = e.freeVarChainWithPos varLine = chainWithPos.pos.lineno varName = chainWithPos.var[0] raise UnresolvedFreeVariableExceptionWithTrace( '''unable to resolve free variable '%s' for pyfora conversion''' % varName, [Exceptions.makeTraceElement(sourceFileName, varLine)] )
def _classOrFunctionDefinition(self, pyObject, classOrFunction): """ `_classOrFunctionDefinition: create a `_FunctionDefinition` or `_ClassDefinition` out of a python class or function, recursively visiting the resolvable free variable member access chains in `pyObject` as well as the source file object. Args: `pyObject`: a python class or function. `classOrFunction`: should either be `_FunctionDefinition` or `_ClassDefinition`. Returns: a `_FunctionDefinition` or `_ClassDefinition`. """ if pyObject.__name__ == '__inline_fora': raise Exceptions.PythonToForaConversionError( "in pyfora, '__inline_fora' is a reserved word" ) sourceFileText, sourceFileName = PyAstUtil.getSourceFilenameAndText(pyObject) _, sourceLine = PyAstUtil.getSourceLines(pyObject) sourceAst = PyAstUtil.pyAstFromText(sourceFileText) if classOrFunction is _FunctionDefinition: pyAst = PyAstUtil.functionDefOrLambdaAtLineNumber(sourceAst, sourceLine) else: assert classOrFunction is _ClassDefinition pyAst = PyAstUtil.classDefAtLineNumber(sourceAst, sourceLine) assert sourceLine == pyAst.lineno try: freeVariableMemberAccessChainResolutions = \ self._computeAndResolveFreeVariableMemberAccessChainsInAst( pyObject, pyAst ) except UnresolvedFreeVariableException as e: _convertUnresolvedFreeVariableExceptionAndRaise(e, sourceFileName) try: processedFreeVariableMemberAccessChainResolutions = {} for chain, (resolution, location) in \ freeVariableMemberAccessChainResolutions.iteritems(): processedFreeVariableMemberAccessChainResolutions['.'.join(chain)] = \ self.walkPyObject(resolution) except UnresolvedFreeVariableExceptionWithTrace as e: e.addToTrace( Exceptions.makeTraceElement( path=sourceFileName, lineNumber=location[0] ) ) raise sourceFileId = self.walkPyObject( _FileDescription.cachedFromArgs( fileName=sourceFileName, fileText=sourceFileText ) ) return classOrFunction( sourceFileId=sourceFileId, lineNumber=sourceLine, freeVariableMemberAccessChainsToId=\ processedFreeVariableMemberAccessChainResolutions )
def _registerWithBlock(self, objectId, pyObject): """ `_registerWithBlock`: register a `PyforaWithBlock.PyforaWithBlock` with `self.objectRegistry`. Recursively call `walkPyObject` on the resolvable free variable member access chains in the block and on the file object. """ lineNumber = pyObject.lineNumber sourceTree = PyAstUtil.pyAstFromText(pyObject.sourceText) withBlockAst = PyAstUtil.withBlockAtLineNumber(sourceTree, lineNumber) withBlockFun = ast.FunctionDef( name="", args=ast.arguments(args=[], defaults=[], kwarg=None, vararg=None), body=withBlockAst.body, decorator_list=[], lineno=lineNumber, col_offset=0 ) if PyAstUtil.hasReturnInOuterScope(withBlockFun): raise Exceptions.BadWithBlockError( "return statement not supported in pyfora with-block (line %s)" % PyAstUtil.getReturnLocationsInOuterScope(withBlockFun)[0]) if PyAstUtil.hasYieldInOuterScope(withBlockFun): raise Exceptions.BadWithBlockError( "yield expression not supported in pyfora with-block (line %s)" % PyAstUtil.getYieldLocationsInOuterScope(withBlockFun)[0]) freeVariableMemberAccessChainsWithPositions = \ self._freeMemberAccessChainsWithPositions(withBlockFun) boundValuesInScopeWithPositions = \ PyAstFreeVariableAnalyses.collectBoundValuesInScope( withBlockFun, getPositions=True) for boundValueWithPosition in boundValuesInScopeWithPositions: val, pos = boundValueWithPosition if val not in pyObject.unboundLocals and val in pyObject.boundVariables: freeVariableMemberAccessChainsWithPositions.add( PyAstFreeVariableAnalyses.VarWithPosition(var=(val,), pos=pos) ) try: freeVariableMemberAccessChainResolutions = \ self._resolveFreeVariableMemberAccessChains( freeVariableMemberAccessChainsWithPositions, pyObject.boundVariables ) except UnresolvedFreeVariableException as e: _convertUnresolvedFreeVariableExceptionAndRaise(e, pyObject.sourceFileName) try: processedFreeVariableMemberAccessChainResolutions = {} for chain, (resolution, position) in \ freeVariableMemberAccessChainResolutions.iteritems(): processedFreeVariableMemberAccessChainResolutions['.'.join(chain)] = \ self.walkPyObject(resolution) except UnresolvedFreeVariableExceptionWithTrace as e: e.addToTrace( Exceptions.makeTraceElement( path=pyObject.sourceFileName, lineNumber=position.lineno ) ) raise sourceFileId = self.walkPyObject( _FileDescription.cachedFromArgs( fileName=pyObject.sourceFileName ) ) self._objectRegistry.defineWithBlock( objectId=objectId, freeVariableMemberAccessChainsToId=\ processedFreeVariableMemberAccessChainResolutions, sourceFileId=sourceFileId, lineNumber=lineNumber )
def _classOrFunctionDefinition(self, pyObject, classOrFunction): """ `_classOrFunctionDefinition: create a `_FunctionDefinition` or `_ClassDefinition` out of a python class or function, recursively visiting the resolvable free variable member access chains in `pyObject` as well as the source file object. Args: `pyObject`: a python class or function. `classOrFunction`: should either be `_FunctionDefinition` or `_ClassDefinition`. Returns: a `_FunctionDefinition` or `_ClassDefinition`. """ if pyObject.__name__ == '__inline_fora': raise Exceptions.PythonToForaConversionError( "in pyfora, '__inline_fora' is a reserved word") try: sourceFileText, sourceFileName = PyAstUtil.getSourceFilenameAndText( pyObject) except Exceptions.CantGetSourceTextError: self._raiseConversionErrorForSourceTextError(pyObject) except: logging.error('Failed on %s (of type %s)', pyObject, type(pyObject)) raise _, sourceLine = PyforaInspect.getsourcelines(pyObject) sourceAst = PyAstUtil.pyAstFromText(sourceFileText) if classOrFunction is _FunctionDefinition: pyAst = PyAstUtil.functionDefOrLambdaAtLineNumber( sourceAst, sourceLine) else: assert classOrFunction is _ClassDefinition pyAst = PyAstUtil.classDefAtLineNumber(sourceAst, sourceLine) try: freeVariableMemberAccessChainResolutions = \ self._computeAndResolveFreeVariableMemberAccessChainsInAst( pyObject, pyAst ) except UnresolvedFreeVariableException as e: _convertUnresolvedFreeVariableExceptionAndRaise(e, sourceFileName) try: processedFreeVariableMemberAccessChainResolutions = {} for chain, (resolution, location) in \ freeVariableMemberAccessChainResolutions.iteritems(): processedFreeVariableMemberAccessChainResolutions['.'.join(chain)] = \ self.walkPyObject(resolution) except UnresolvedFreeVariableExceptionWithTrace as e: e.addToTrace( Exceptions.makeTraceElement(path=sourceFileName, lineNumber=location[0])) raise sourceFileId = self.walkPyObject( _FileDescription.cachedFromArgs(fileName=sourceFileName, fileText=sourceFileText)) return classOrFunction( sourceFileId=sourceFileId, lineNumber=sourceLine, freeVariableMemberAccessChainsToId=\ processedFreeVariableMemberAccessChainResolutions )
def _registerWithBlock(self, objectId, pyObject): """ `_registerWithBlock`: register a `PyforaWithBlock.PyforaWithBlock` with `self.objectRegistry`. Recursively call `walkPyObject` on the resolvable free variable member access chains in the block and on the file object. """ lineNumber = pyObject.lineNumber sourceTree = PyAstUtil.pyAstFromText(pyObject.sourceText) withBlockAst = PyAstUtil.withBlockAtLineNumber(sourceTree, lineNumber) withBlockFun = ast.FunctionDef(name="", args=ast.arguments(args=[], defaults=[], kwarg=None, vararg=None), body=withBlockAst.body, decorator_list=[], lineno=lineNumber, col_offset=0) if PyAstUtil.hasReturnInOuterScope(withBlockFun): raise Exceptions.InvalidPyforaOperation( "return statement not supported in pyfora with-block (line %s)" % PyAstUtil.getReturnLocationsInOuterScope(withBlockFun)[0]) if PyAstUtil.hasYieldInOuterScope(withBlockFun): raise Exceptions.InvalidPyforaOperation( "yield expression not supported in pyfora with-block (line %s)" % PyAstUtil.getYieldLocationsInOuterScope(withBlockFun)[0]) freeVariableMemberAccessChainsWithPositions = \ self._freeMemberAccessChainsWithPositions(withBlockFun) boundValuesInScopeWithPositions = \ PyAstFreeVariableAnalyses.collectBoundValuesInScope( withBlockFun, getPositions=True) for boundValueWithPosition in boundValuesInScopeWithPositions: val, pos = boundValueWithPosition if val not in pyObject.unboundLocals and val in pyObject.boundVariables: freeVariableMemberAccessChainsWithPositions.add( PyAstFreeVariableAnalyses.VarWithPosition(var=(val, ), pos=pos)) try: freeVariableMemberAccessChainResolutions = \ self._resolveFreeVariableMemberAccessChains( freeVariableMemberAccessChainsWithPositions, pyObject.boundVariables ) except UnresolvedFreeVariableException as e: _convertUnresolvedFreeVariableExceptionAndRaise( e, pyObject.sourceFileName) try: processedFreeVariableMemberAccessChainResolutions = {} for chain, (resolution, position) in \ freeVariableMemberAccessChainResolutions.iteritems(): processedFreeVariableMemberAccessChainResolutions['.'.join(chain)] = \ self.walkPyObject(resolution) except UnresolvedFreeVariableExceptionWithTrace as e: e.addToTrace( Exceptions.makeTraceElement(path=pyObject.sourceFileName, lineNumber=position.lineno)) raise sourceFileId = self.walkPyObject( _FileDescription.cachedFromArgs(fileName=pyObject.sourceFileName)) self._objectRegistry.defineWithBlock( objectId=objectId, freeVariableMemberAccessChainsToId=\ processedFreeVariableMemberAccessChainResolutions, sourceFileId=sourceFileId, lineNumber=lineNumber )