예제 #1
0
    def test_computeDataMembers_error_2(self):
        class E2:
            def __init__(*args):
                self.x = 0

        with self.assertRaises(Exceptions.PythonToForaConversionError):
            PyAstUtil.computeDataMembers(E2)
예제 #2
0
    def test_computeDataMembers_error_2(self):
        class E2:
            def __init__(*args):
                self.x = 0

        with self.assertRaises(Exceptions.PythonToForaConversionError):
            PyAstUtil.computeDataMembers(E2)
예제 #3
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]
예제 #4
0
    def _classObjectFromFilenameAndLine(self, filename, lineNumber, members):
        """Construct a class object given its textual definition."""
        objectOrNone = self.moduleLevelObject(filename, lineNumber)
        if objectOrNone is not None:
            return objectOrNone

        sourceAst = PyAstUtil.getAstFromFilePath(filename)
        classAst = PyAstUtil.classDefAtLineNumber(sourceAst, lineNumber)

        outputLocals = {}
        globalScope = {}
        globalScope.update(members)

        self.importModuleMagicVariables(globalScope, filename)

        try:
            code = compile(ast.Module([classAst]), filename, 'exec')

            exec code in globalScope, outputLocals
        except:
            logging.error("Failed to instantiate class at %s:%s\n%s", filename, lineNumber, traceback.format_exc())
            raise Exceptions.PyforaError("Failed to instantiate class at %s:%s" % (filename, lineNumber))

        assert len(outputLocals) == 1

        return list(outputLocals.values())[0]
예제 #5
0
    def test_computeDataMembers_error_3(self):
        class E3:
            def __init__(self):
                self.x = 0
                def f(x):
                    return x

        with self.assertRaises(Exceptions.PythonToForaConversionError):
            PyAstUtil.computeDataMembers(E3)
예제 #6
0
    def test_computeDataMembers_error_4(self):
        class E4:
            def __init__(self):
                self.x = 0
                class c(object):
                    def __init__(self):
                        self.z = 0

        with self.assertRaises(Exceptions.PythonToForaConversionError):
            PyAstUtil.computeDataMembers(E4)
예제 #7
0
    def test_computeDataMembers_error_3(self):
        class E3:
            def __init__(self):
                self.x = 0

                def f(x):
                    return x

        with self.assertRaises(Exceptions.PythonToForaConversionError):
            PyAstUtil.computeDataMembers(E3)
예제 #8
0
    def test_computeDataMembers_error_4(self):
        class E4:
            def __init__(self):
                self.x = 0

                class c(object):
                    def __init__(self):
                        self.z = 0

        with self.assertRaises(Exceptions.PythonToForaConversionError):
            PyAstUtil.computeDataMembers(E4)
예제 #9
0
def augmentRaiseFunction(raiseFunction, path, line, col):
    enclosingFunctionVisitor = PyAstUtil.FindEnclosingFunctionVisitor(line)
    codeAst = PyAstUtil.getAstFromFilePath(path)
    enclosingFunctionName = enclosingFunctionVisitor.find(codeAst)
    vis = AugmentRaiseFunctionModificationVisitor(line, col,
                                                  enclosingFunctionName)
    module = ast.parse(augmentRaiseFunctionTemplate)
    vis.visit(module)

    code = compile(module, path, 'exec')
    exec code in globals(), locals()

    return _augmentRaiseFunctionTempl(raiseFunction)
예제 #10
0
    def test_computeDataMembers_3(self):
        class C3:
            def __init__(self):
                self.x = self.y = 0

        dataMembers = PyAstUtil.computeDataMembers(C3)

        self.assertEqual(dataMembers, set(['x', 'y']))
예제 #11
0
    def test_computeDataMembers_4(self):
        class C4:
            def __init__(self, arg):
                (self.x, self.y), self.z = arg

        dataMembers = PyAstUtil.computeDataMembers(C4)

        self.assertEqual(dataMembers, set(['x', 'y', 'z']))
예제 #12
0
 def _cachedCompute(self):
     if not self._isComputed:
         if PyAstUtil.isScopeNode(self._root):
             self.generic_visit(self._root)
             self._isComputed = True
         else:
             raise Exceptions.InternalError(
                 "'%s' called on unsupported node-type (%s)" %
                 (self.__class__.__name__, type(self._root)))
예제 #13
0
    def test_computeDataMembers_1(self):
        class C:
            def __init__(self, x):
                self.x = x
                self.y = x**2.0

        dataMembers = PyAstUtil.computeDataMembers(C)

        self.assertEqual(dataMembers, set(['x', 'y']))
예제 #14
0
 def _cachedCompute(self):
     if not self._isComputed:
         if PyAstUtil.isScopeNode(self._root):
             self.generic_visit(self._root)
             self._isComputed = True
         else:
             raise Exceptions.InternalError(
                     "'%s' called on unsupported node-type (%s)"
                     % (self.__class__.__name__, type(self._root))
                 )
예제 #15
0
def collectPossiblyUninitializedLocalVariables(pyAstNode):
    """Returns the possibly free local variables of the code rooted at `pyAstNode."""
    # Context doesn't play a role below, but we reuse the code for checking `pyAstNode
    if not PyAstUtil.isScopeNode(pyAstNode):
        raise Exceptions.InternalError(
            "Unsupported type of root node in Analysis (%s)" % type(pyAstNode))
    possiblyUninitVisitor = _PossiblyUninitializedScopedVisitor()
    possiblyUninitVisitor.visit(pyAstNode)

    return possiblyUninitVisitor.getPossiblyUninitializedLocalVariables()
예제 #16
0
    def test_computeDataMembers_2(self):
        class C2:
            def __init__(self, x):
                if x > 0:
                    self.x = x

        dataMembers = PyAstUtil.computeDataMembers(C2)

        # in our translation, we're _always_ producing an x member
        self.assertEqual(dataMembers, set(['x']))
예제 #17
0
    def test_computeDataMembers_3(self):
        class C3:
            def __init__(self):
                self.x = self.y = 0

        dataMembers = PyAstUtil.computeDataMembers(C3)

        self.assertEqual(
            dataMembers,
            set(['x', 'y'])
            )
def collectPossiblyUninitializedLocalVariables(pyAstNode):
    """Returns the possibly free local variables of the code rooted at `pyAstNode."""
    # Context doesn't play a role below, but we reuse the code for checking `pyAstNode
    if not PyAstUtil.isScopeNode(pyAstNode):
        raise Exceptions.InternalError(
            "Unsupported type of root node in Analysis (%s)"
            % type(pyAstNode))
    possiblyUninitVisitor = _PossiblyUninitializedScopedVisitor()
    possiblyUninitVisitor.visit(pyAstNode)

    return possiblyUninitVisitor.getPossiblyUninitializedLocalVariables()
예제 #19
0
    def test_computeDataMembers_4(self):
        class C4:
            def __init__(self, arg):
                (self.x, self.y), self.z = arg

        dataMembers = PyAstUtil.computeDataMembers(C4)

        self.assertEqual(
            dataMembers,
            set(['x', 'y', 'z'])
            )
예제 #20
0
def augmentRaiseFunction(raiseFunction, path, line, col):
    enclosingFunctionVisitor = PyAstUtil.FindEnclosingFunctionVisitor(line)
    codeAst = PyAstUtil.getAstFromFilePath(path)
    enclosingFunctionName = enclosingFunctionVisitor.find(codeAst)
    vis = AugmentRaiseFunctionModificationVisitor(line, col, enclosingFunctionName)
    module = ast.parse(augmentRaiseFunctionTemplate)
    vis.visit(module)

    code = compile(module, path, 'exec')
    exec code in globals(), locals()

    return _augmentRaiseFunctionTempl(raiseFunction)
예제 #21
0
    def test_computeDataMembers_1(self):
        class C:
            def __init__(self, x):
                self.x = x
                self.y = x ** 2.0

        dataMembers = PyAstUtil.computeDataMembers(C)
            
        self.assertEqual(
            dataMembers,
            set(['x', 'y'])
            )
예제 #22
0
    def _pyObjectNodeForWithBlock(self, pyObject):
        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=[]
            )

        freeVariableMemberAccessChains = \
            self._freeOrUninitializedMemberAccesChains(withBlockFun)

        freeVariableMemberAccessChainResolutions = \
            self._resolveFreeVariableMemberAccesChains(
                freeVariableMemberAccessChains, pyObject.boundVariables
                )

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

        if pyObject.sourceFileName in self._fileTextCache:
            fileObject = self._fileTextCache[pyObject.sourceFileName]
        else:
            with open(pyObject.sourceFileName, "r") as sourceFile:
                sourceFileText = sourceFile.read()
            fileObject = PyObjectNodes.File(pyObject.sourceFileName, sourceFileText)
            self._fileTextCache[pyObject.sourceFileName] = fileObject

        return PyObjectNodes.WithBlock(
            pyObject, 
            fileObject,
            lineNumber,
            processedFreeVariableMemberAccessChainResolutions
            )
예제 #23
0
    def _pyObjectNodeForWithBlock(self, pyObject):
        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=[])

        freeVariableMemberAccessChains = \
            self._freeOrUninitializedMemberAccesChains(withBlockFun)

        freeVariableMemberAccessChainResolutions = \
            self._resolveFreeVariableMemberAccesChains(
                freeVariableMemberAccessChains, pyObject.boundVariables
                )

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

        if pyObject.sourceFileName in self._fileTextCache:
            fileObject = self._fileTextCache[pyObject.sourceFileName]
        else:
            with open(pyObject.sourceFileName, "r") as sourceFile:
                sourceFileText = sourceFile.read()
            fileObject = PyObjectNodes.File(pyObject.sourceFileName,
                                            sourceFileText)
            self._fileTextCache[pyObject.sourceFileName] = fileObject

        return PyObjectNodes.WithBlock(
            pyObject, fileObject, lineNumber,
            processedFreeVariableMemberAccessChainResolutions)
예제 #24
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
            )
예제 #25
0
    def test_computeDataMembers_2(self):
        class C2:
            def __init__(self, x):
                if x > 0:
                    self.x = x
                

        dataMembers = PyAstUtil.computeDataMembers(C2)
        
        # in our translation, we're _always_ producing an x member
        self.assertEqual(
            dataMembers,
            set(['x'])
            )
예제 #26
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)
예제 #27
0
    def _classInstanceDescriptionFromClassInstance(self, pyObject):
        try:
            classObject = pyObject.__class__

            dataMemberNames = PyAstUtil.computeDataMembers(classObject)
            classMemberNameToMemberValue = {}

            for dataMemberName in dataMemberNames:
                memberValue = getattr(pyObject, dataMemberName)
                classMemberNameToMemberValue[dataMemberName] = memberValue

            return PyObjectNodes.ClassInstanceDescription(
                pyObject, classObject, classMemberNameToMemberValue)
        except:
            logging.error('Failed on %s (of type %s)', pyObject,
                          type(pyObject))
            raise
    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))
예제 #29
0
    def _classInstanceDescriptionFromClassInstance(self, pyObject):
        try:
            classObject = pyObject.__class__

            dataMemberNames = PyAstUtil.computeDataMembers(classObject)
            classMemberNameToMemberValue = {}

            for dataMemberName in dataMemberNames:
                memberValue = getattr(pyObject, dataMemberName)
                classMemberNameToMemberValue[dataMemberName] = memberValue

            return PyObjectNodes.ClassInstanceDescription(
                    pyObject,
                    classObject,
                    classMemberNameToMemberValue
                    )
        except:
            logging.error('Failed on %s (of type %s)', pyObject, type(pyObject))
            raise
예제 #30
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 getFreeVariableMemberAccessChains(pyAstNode, isClassContext=None):
    pyAstNode = PyAstUtil.getRootInContext(pyAstNode, isClassContext)
    freeVariableMemberAccessChainsVisitor = _FreeVariableMemberAccessChainsVisitor()
    freeVariableMemberAccessChainsVisitor.visit(pyAstNode)

    return freeVariableMemberAccessChainsVisitor.freeVariableMemberAccessChains
def getFreeVariables(pyAstNode, isClassContext=None):
    pyAstNode = PyAstUtil.getRootInContext(pyAstNode, isClassContext)
    freeVarsVisitor = _FreeVarsVisitor()
    freeVarsVisitor.visit(pyAstNode)
    return freeVarsVisitor.getFreeVars()