Example #1
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]
Example #2
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)
        )
Example #5
0
    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
            )
Example #6
0
    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
            )