예제 #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]
    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))
예제 #3
0
    def _pyObjectNodeForClassOrFunction(self, pyObject, classOrFunction):
        try:
            sourceFileText, sourceFileName = PyAstUtil.getSourceFilenameAndText(pyObject)
        except Exceptions.CantGetSourceTextError as e:
            raise Exceptions.PythonToForaConversionError(e.message)

        _, sourceLine = PyforaInspect.getsourcelines(pyObject)

        sourceAst = PyAstUtil.getSourceFileAst(pyObject)

        if classOrFunction is PyObjectNodes.FunctionDefinition:
            pyAst = PyAstUtil.functionDefOrLambdaAtLineNumber(sourceAst, sourceLine)
        else:
            assert classOrFunction is PyObjectNodes.ClassDefinition
            pyAst = PyAstUtil.classDefAtLineNumber(sourceAst, sourceLine)

        freeVariableMemberAccessChainResolutions = \
            self._resolveFreeVariableMemberAccessChains(
                pyObject, pyAst
                )

        processedFreeVariableMemberAccessChainResolutions = { \
            '.'.join(chain): resolution for chain, resolution in \
            freeVariableMemberAccessChainResolutions.iteritems()
            }

        if sourceFileName in self._fileTextCache:
            fileObject = self._fileTextCache[sourceFileName]
        else:
            fileObject = PyObjectNodes.File(sourceFileName, sourceFileText)
            self._fileTextCache[sourceFileName] = fileObject
        
        return classOrFunction(
            pyObject,
            fileObject,
            sourceLine,
            processedFreeVariableMemberAccessChainResolutions
            )
예제 #4
0
    def _pyObjectNodeForClassOrFunction(self, pyObject, classOrFunction):
        try:
            sourceFileText, sourceFileName = PyAstUtil.getSourceFilenameAndText(
                pyObject)
        except Exceptions.CantGetSourceTextError as e:
            raise Exceptions.PythonToForaConversionError(e.message)

        _, sourceLine = PyforaInspect.getsourcelines(pyObject)

        sourceAst = PyAstUtil.getSourceFileAst(pyObject)

        if classOrFunction is PyObjectNodes.FunctionDefinition:
            pyAst = PyAstUtil.functionDefOrLambdaAtLineNumber(
                sourceAst, sourceLine)
        else:
            assert classOrFunction is PyObjectNodes.ClassDefinition
            pyAst = PyAstUtil.classDefAtLineNumber(sourceAst, sourceLine)

        freeVariableMemberAccessChainResolutions = \
            self._resolveFreeVariableMemberAccessChains(
                pyObject, pyAst
                )

        processedFreeVariableMemberAccessChainResolutions = { \
            '.'.join(chain): resolution for chain, resolution in \
            freeVariableMemberAccessChainResolutions.iteritems()
            }

        if sourceFileName in self._fileTextCache:
            fileObject = self._fileTextCache[sourceFileName]
        else:
            fileObject = PyObjectNodes.File(sourceFileName, sourceFileText)
            self._fileTextCache[sourceFileName] = fileObject

        return classOrFunction(
            pyObject, fileObject, sourceLine,
            processedFreeVariableMemberAccessChainResolutions)
    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)
            )