def _instantiateFunction(self, filename, lineNumber, memberDictionary): """Instantiate a function instance.""" objectOrNone = self.moduleLevelObject(filename, lineNumber) if objectOrNone is not None: return objectOrNone sourceAst = PyAstUtil.getAstFromFilePath(filename) functionAst = PyAstUtil.functionDefOrLambdaAtLineNumber(sourceAst, lineNumber) outputLocals = {} globalScope = {} globalScope.update(memberDictionary) self.importModuleMagicVariables(globalScope, filename) if isinstance(functionAst, ast.Lambda): expr = ast.Expression() expr.body = functionAst expr.lineno = functionAst.lineno expr.col_offset = functionAst.col_offset code = compile(expr, filename, 'eval') return eval(code, globalScope, outputLocals) else: code = compile(ast.Module([functionAst]), filename, 'exec') exec code in globalScope, outputLocals assert len(outputLocals) == 1 return list(outputLocals.values())[0]
def _instantiateFunction(self, filename, lineNumber, memberDictionary): """Instantiate a function instance.""" objectOrNone = self.moduleLevelObject(filename, lineNumber) if objectOrNone is not None: return objectOrNone sourceAst = PyAstUtil.getAstFromFilePath(filename) functionAst = PyAstUtil.functionDefOrLambdaAtLineNumber( sourceAst, lineNumber) outputLocals = {} globalScope = {} globalScope.update(memberDictionary) self.importModuleMagicVariables(globalScope, filename) if isinstance(functionAst, ast.Lambda): expr = ast.Expression() expr.body = functionAst expr.lineno = functionAst.lineno expr.col_offset = functionAst.col_offset code = compile(expr, filename, 'eval') return eval(code, globalScope, outputLocals) else: code = compile(ast.Module([functionAst]), filename, 'exec') exec code in globalScope, outputLocals assert len(outputLocals) == 1 return list(outputLocals.values())[0]
def test_freeVariablesMemberAccessChain_onFunctionDefNode(self): tree1 = ast.parse( textwrap.dedent(""" def g(arg): if arg < 0: return x + arg return x * h(arg - 1, g) """)) res = PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains( tree1) self.assertEqual(set([('h', ), ('x', )]), res) tree2 = PyAstUtil.functionDefOrLambdaAtLineNumber(tree1, 2) self.assertEqual( set([('h', ), ('x', )]), PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains( tree2, False))
def test_freeVariablesMemberAccessChain_onFunctionDefNode(self): tree1 = ast.parse( textwrap.dedent( """ def g(arg): if arg < 0: return x + arg return x * h(arg - 1, g) """ ) ) res = PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains(tree1) self.assertEqual(set([("h",), ("x",)]), res) tree2 = PyAstUtil.functionDefOrLambdaAtLineNumber(tree1, 2) self.assertEqual( set([("h",), ("x",)]), PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains(tree2, False) )
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 _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 )