Exemplo n.º 1
0
 def onFailure(result):
     if isinstance(result, Exception):
         onExpanded(result)
     else:
         onExpanded(
             Exceptions.PyforaError(
                 "Unknown error translating to dictionary of proxies: %s"
                 + str(result)))
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)])
Exemplo n.º 3
0
 def statusChanged(jsonStatus):
     if not self.closed:
         if jsonStatus is not None:
             if jsonStatus['status'] == 'failure':
                 onFailedCallback(
                     Exceptions.PyforaError(jsonStatus['message']))
             else:
                 onCompletedCallback(None)
Exemplo n.º 4
0
    def _translate_download_result(self, jsonResult):
        if 'foraToPythonConversionError' in jsonResult:
            return Exceptions.ForaToPythonConversionError(
                str(jsonResult['foraToPythonConversionError']))

        if not jsonResult['isException']:
            if 'maxBytesExceeded' in jsonResult:
                return Exceptions.ResultExceededBytecountThreshold()
            else:
                return self.objectRehydrator.convertEncodedStringToPythonObject(
                    base64.b64decode(jsonResult['result']['data']),
                    jsonResult['result']['root_id'])

        result = self.objectRehydrator.convertEncodedStringToPythonObject(
            base64.b64decode(jsonResult['result']['data']),
            jsonResult['result']['root_id'])
        return Exceptions.ComputationError(result, jsonResult['trace'])
 def mapPythonInstanceToPyforaInstance(self, instance):
     assert instance is self.instance
     if self.pureClass is None:
         raise Exceptions.PyforaNotImplementedError(
             "conversion of '%s' not yet implemented" %
             (instance.__name__
              if hasattr(instance, "__name__") else instance))
     return self.pureClass()
Exemplo n.º 6
0
    def convertJsonResultToPythonObject(self, jsonResult):
        if 'primitive' in jsonResult:
            res = jsonResult['primitive']
            if isinstance(res, unicode):
                return intern(str(res))
            else:
                return res

        if 'tuple' in jsonResult:
            return tuple([self.convertJsonResultToPythonObject(x) for x in jsonResult['tuple']])
        if 'list' in jsonResult:
            return [self.convertJsonResultToPythonObject(x) for x in jsonResult['list']]
        if 'dict' in jsonResult:
            return {
                self.convertJsonResultToPythonObject(key): self.convertJsonResultToPythonObject(val) \
                for key, val in zip(jsonResult['dict']['keys'], jsonResult['dict']['values'])
                }
        if 'untranslatableException' in jsonResult:
            return Exceptions.ForaToPythonConversionError(
                "untranslatable FORA exception: %s" % jsonResult['untranslatableException']
                )
        if 'singleton' in jsonResult:
            singletonName = jsonResult['singleton']
            return NamedSingletons.singletonNameToObject[singletonName]
        if 'InvalidPyforaOperation' in jsonResult:
            return Exceptions.InvalidPyforaOperation(jsonResult['InvalidPyforaOperation'])
        if 'builtinException' in jsonResult:
            builtinExceptionTypeName = jsonResult['builtinException']
            builtinExceptionType = NamedSingletons.singletonNameToObject[builtinExceptionTypeName]
            args = self.convertJsonResultToPythonObject(jsonResult['args'])
            return builtinExceptionType(*args)
        if 'classInstance' in jsonResult:
            members = {k:self.convertJsonResultToPythonObject(v) for k,v in jsonResult['members'].iteritems()}
            classObject = self.convertJsonResultToPythonObject(jsonResult['classInstance'])
            return self._invertPureClassInstanceIfNecessary(self._instantiateClass(classObject, members))
        if 'functionInstance' in jsonResult:
            members = {k:self.convertJsonResultToPythonObject(v) for k,v in jsonResult['members'].iteritems()}
            return self._instantiateFunction(jsonResult['functionInstance'][0], jsonResult['functionInstance'][1], members)
        if 'classObject' in jsonResult:
            members = {k:self.convertJsonResultToPythonObject(v) for k,v in jsonResult['members'].iteritems()}
            return self._classObjectFromFilenameAndLine(jsonResult['classObject'][0], jsonResult['classObject'][1], members)
        if 'stacktrace' in jsonResult:
            return jsonResult['stacktrace']
        
        raise Exceptions.ForaToPythonConversionError("not implemented: cant convert %s" % jsonResult)
Exemplo n.º 7
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)))
Exemplo n.º 8
0
    def getPurePythonTypes(self):
        """Return the pure-python type that this mapping converts to.

        This should return a list of python classes that this mapper knows how to invert.
        """
        #subclasses should implement
        raise Exceptions.PyforaNotImplementedError(
            "'%s' not implemented yet for type '%s'" %
            (self.getPurePythonTypes.__name__, type(self).__name__))
Exemplo n.º 9
0
    def toLocal(self):
        """Downloads the remote object.

        Returns:
            A :class:`~pyfora.Future.Future` that resolves to the python
            object that this :class:`RemotePythonObject` represents.
        """
        raise Exceptions.PyforaNotImplementedError(
            "'%s' not implemented yet for type '%s'" %
            (self.toLocal.__name__, type(self).__name__))
Exemplo n.º 10
0
    def _subchainAndResolutionOrNone(self, pyObject, chainWithPosition):
        if PyforaInspect.isfunction(pyObject):
            return self._lookupChainInFunction(pyObject, chainWithPosition)

        if PyforaInspect.isclass(pyObject):
            return self._lookupChainInClass(pyObject, chainWithPosition)

        raise Exceptions.PythonToForaConversionError(
            "don't know how to resolve %s in %s (line:%s)" %
            (chainWithPosition.var, pyObject, chainWithPosition.pos.lineno))
Exemplo n.º 11
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()
Exemplo n.º 12
0
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)])
Exemplo n.º 13
0
    def getMappablePythonTypes(self):
        """Return the python type that this mapping knows how to convert.

        This should return a list of python types and classes. Any time the
        converter sees an instance of one of these types, Pyfora will invoke
        this class to provide an alternate, translatable form of the instance.
        """
        #subclasses should implement
        raise Exceptions.PyforaNotImplementedError(
            "'%s' not implemented yet for type '%s'" %
            (self.getMappablePythonTypes.__name__, type(self).__name__))
Exemplo n.º 14
0
def getSourceFilenameAndText(pyObject):
    try:
        sourceFile = PyforaInspect.getsourcefile(pyObject)
    except TypeError as e:
        raise Exceptions.CantGetSourceTextError(e.message)

    if sourceFile not in sourceFileCache_:
        sourceFileCache_[sourceFile] = "".join(
            PyforaInspect.getlines(sourceFile))

    return sourceFileCache_[sourceFile], sourceFile
Exemplo n.º 15
0
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)]
        )
Exemplo n.º 16
0
def getSourceText(pyObject):
    try:
        source, lineno = PyforaInspect.getsourcelines(pyObject)
    except TypeError as e:
        raise Exceptions.CantGetSourceTextError(e.message)
    # Create a prefix of (lineno-1) blank lines to keep track of line numbers for error reporting
    blankLines = os.linesep * (lineno - 1)
    # We don't know how to avoid the use of `textwrap.dedent to get the code
    # though `ast.parse, which means that the computed column_numbers may be
    # off and we shouldn't report them.
    return textwrap.dedent(blankLines + "".join(source))
Exemplo n.º 17
0
    def _computeSubchainAndTerminalValueAlongModules(self, rootValue, chain):
        ix = 1

        subchain, terminalValue = chain[:ix], rootValue

        while PyforaInspect.ismodule(terminalValue):
            if ix >= len(chain):
                #we're terminating at a module
                raise Exceptions.PythonToForaConversionError(
                    "Can't convert the module %s" % str(terminalValue))

            if not hasattr(terminalValue, chain[ix]):
                raise Exceptions.PythonToForaConversionError(
                    "Module %s has no member %s" %
                    (str(terminalValue), chain[ix]))

            terminalValue = getattr(terminalValue, chain[ix])
            ix += 1
            subchain = chain[:ix]

        return subchain, terminalValue
Exemplo n.º 18
0
def _collectDataMembersSetInInitAst(initAst):
    _assertOnlySimpleStatements(initAst)

    if len(initAst.args.args) == 0:
        raise Exceptions.PythonToForaConversionError(
            "the `__init__ method is missing a first, positional, " \
            "`self argument (line %s)."
            % (initAst.lineno)
            )

    selfArg = initAst.args.args[0]

    if not isinstance(selfArg, ast.Name):
        raise Exceptions.InternalError(
            "the `self argument to the `__init__ method" \
            " is not of type `ast.Name (line %s)."
            % (initAst.lineno)
            )

    return _extractSimpleSelfMemberAssignments(initFunctionDef=initAst,
                                               selfName=selfArg.id)
Exemplo n.º 19
0
            def extractVectorContents(vectorIVC):
                if len(vectorIVC) == 0:
                    return {'listContents': []}
                vec = ComputedValue.ComputedValueVector(
                    vectorImplVal=vectorIVC)
                vecSlice = vec.entireSlice

                res = None
                preventPythonArrayExtraction = False

                #see if it's a string. This is the only way to be holding a Vector of char
                if vectorIVC.isVectorOfChar():
                    res = vecSlice.extractVectorDataAsNumpyArray()
                    if res is not None:
                        res = {'string': res.tostring()}

                #see if it's simple enough to transmit as numpy data
                if res is None and len(vectorIVC.getVectorElementsJOR()
                                       ) == 1 and len(vectorIVC) > 1:
                    res = vecSlice.extractVectorDataAsNumpyArrayInChunks()

                    if res is not None:
                        firstElement = vecSlice.extractVectorItemAsIVC(0)
                        if firstElement is None:
                            #note we can't import this at the top of the file because this file gets imported
                            #during the build process, which doesn't have pyfora installed.
                            import pyfora.Exceptions as Exceptions
                            raise Exceptions.ForaToPythonConversionError(
                                "Shouldn't be possible to download data as numpy, and then not get the first value"
                            )

                        res = {
                            'firstElement': firstElement,
                            'contentsAsNumpyArrays': res
                        }
                    else:
                        if not vecSlice.vdmThinksIsLoaded():
                            #there's a race condition where the data could be loaded between now and
                            #the call to 'extractVectorDataAsPythonArray'. This prevents it.
                            preventPythonArrayExtraction = True

                #see if we can extract the data as a regular pythonlist
                if not preventPythonArrayExtraction and res is None:
                    res = vecSlice.extractVectorDataAsPythonArray()
                    if res is not None:
                        res = {'listContents': res}

                if res is None:
                    vecSlice.increaseRequestCount()
                    return None

                return res
Exemplo n.º 20
0
def getSourceFilenameAndText(pyObject):
    try:
        sourceFile = PyforaInspect.getsourcefile(pyObject)
    except TypeError as e:
        raise Exceptions.CantGetSourceTextError(e.message)

    if sourceFile in sourceFileCache_:
        return sourceFileCache_[sourceFile], sourceFile
    with open(sourceFile, "r") as f:
        tr = f.read()
    sourceFileCache_[sourceFile] = tr

    return tr, sourceFile
Exemplo n.º 21
0
 def _cachedCompute(self):
     if not self._isComputed:
         if isScopeNode(self._root):
             if isinstance(self._root, ast.FunctionDef) and hasattr(
                     self._root, 'arguments'):
                 self._root.arguments.lineno = self._root.lineno
                 self._root.arguments.col_offset = self._root.col_offset
             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)))
Exemplo n.º 22
0
def getSourceFilenameAndText(pyObject):
    try:
        sourceFile = PyforaInspect.getsourcefile(pyObject)
    except TypeError as e:
        raise Exceptions.CantGetSourceTextError(e.message)

    if sourceFile is None:
        raise Exceptions.CantGetSourceTextError(
            "can't get source lines for file %s" % sourceFile
            )

    linesOrNone = PyforaInspect.getlines(sourceFile)

    if linesOrNone is None:
        raise Exceptions.CantGetSourceTextError(
            "can't get source lines for file %s" % sourceFile
            )

    if sourceFile not in sourceFileCache_:
        sourceFileCache_[sourceFile] = "".join(linesOrNone)

    return sourceFileCache_[sourceFile], sourceFile
Exemplo n.º 23
0
 def onExpanded(jsonResult):
     result = jsonResult
     if not isinstance(jsonResult, Exception):
         if jsonResult['isException']:
             result = Exceptions.ComputationError(
                 self.objectRehydrator.convertJsonResultToPythonObject(
                     jsonResult['result']), jsonResult['trace'])
         else:
             assert isinstance(jsonResult['dictOfProxies'], dict)
             result = {
                 k: RemotePythonObject.ComputedRemotePythonObject(
                     v, self, False)
                 for k, v in jsonResult['dictOfProxies'].iteritems()
             }
     self._resolve_future(future, result)
Exemplo n.º 24
0
        def onExpanded(jsonResult):
            result = jsonResult
            if not isinstance(jsonResult, Exception):
                if jsonResult['isException']:
                    result = Exceptions.ComputationError(
                        self.objectRehydrator.convertJsonResultToPythonObject(
                            jsonResult['result']), jsonResult['trace'])
                else:
                    assert isinstance(jsonResult['tupleOfComputedValues'],
                                      tuple)
                    result = tuple(
                        RemotePythonObject.ComputedRemotePythonObject(
                            val, self, False)
                        for val in jsonResult['tupleOfComputedValues'])

            self._resolve_future(future, result)
Exemplo n.º 25
0
    def populateModuleMembers(self, path):
        if path in self.moduleClassesAndFunctionsByPath:
            return

        res = self.moduleClassesAndFunctionsByPath[path] = {}
        module = self.moduleForFile(path)

        if module is not None and self.canPopulateForPath(path):
            for leafItemName in module.__dict__:
                leafItemValue = module.__dict__[leafItemName]

                if PyforaInspect.isclass(
                        leafItemValue) or PyforaInspect.isfunction(
                            leafItemValue):
                    try:
                        sourcePath = PyforaInspect.getsourcefile(leafItemValue)

                        if sourcePath is not None:
                            if os.path.samefile(path, sourcePath):
                                _, lineNumber = PyforaInspect.findsource(
                                    leafItemValue)

                                lineNumberToUse = lineNumber + 1

                                if lineNumberToUse in res and res[
                                        lineNumberToUse] is not leafItemValue:
                                    raise Exceptions.ForaToPythonConversionError(
                                        ("PythonObjectRehydratorHelpers got a line number collision at lineNumber %s"
                                         ", between %s and %s"),
                                        lineNumberToUse, leafItemValue,
                                        res[lineNumber + 1])

                                res[lineNumberToUse] = leafItemValue
                            else:
                                self.populateModuleMembers(sourcePath)

                    except Exceptions.ForaToPythonConversionError:
                        raise
                    except PyforaInspect.PyforaInspectError:
                        pass
                    except IOError:
                        #this gets raised when PyforaInspect can't find a file it needs
                        pass
                    except Exception as e:
                        logging.critical(
                            "PyforaInspect threw an exception: %s. tb = %s", e,
                            traceback.format_exc())
Exemplo n.º 26
0
    def _resolveChainByDict(self, chain, boundVariables):
        freeVariable = chain[0]

        if freeVariable in boundVariables:
            rootValue = boundVariables[freeVariable]
            subchain, terminalValue = self._computeSubchainAndTerminalValueAlongModules(
                rootValue, chain)
            return subchain, terminalValue

        if hasattr(__builtin__, freeVariable):
            rootValue = getattr(__builtin__, freeVariable)

            return self._computeSubchainAndTerminalValueAlongModules(
                rootValue, chain)

        raise Exceptions.PythonToForaConversionError(
            "don't know how to resolve free variable `%s`" % freeVariable)
Exemplo n.º 27
0
    def submit(self, fn, *args, **kwargs):
        """Submits a callable to be executed on the server with the provided arguments 'args'.
        kwargs are not currently supported.

        Returns:
            A Future representing the given call. The future will eventually resolve to a
            RemotePythonObject instance.
        """
        self._raiseIfClosed()
        if len(kwargs) > 0:
            raise Exceptions.PyforaNotImplementedError(
                "Keyword arguments not supported yet")

        # TODO: make this truly async
        #       don't block on the 'define' calls
        futures = [self.define(fn)] + [self.define(arg) for arg in args]
        results = [f.result() for f in futures]
        return results[0](*results[1:])
Exemplo n.º 28
0
        def onExpanded(jsonResult):
            if isinstance(jsonResult, Exception):
                future.set_exception(jsonResult)
                return

            if jsonResult['isException']:
                result = self.objectRehydrator.convertJsonResultToPythonObject(
                    jsonResult['result'])
                future.set_exception(
                    Exceptions.ComputationError(result, jsonResult['trace']))
                return

            assert isinstance(jsonResult['tupleOfComputedValues'], tuple)

            tupleOfProxies = \
                tuple([
                    RemotePythonObject.ComputedRemotePythonObject(val, self) \
                    for val in jsonResult['tupleOfComputedValues']
                    ])

            future.set_result(tupleOfProxies)
Exemplo n.º 29
0
    def _resolveChainInPyObject(self, chain, pyObject):
        """
        This name could be improved.

        Returns a `subchain, terminalPyValue` pair: this represents the deepest value 
        we can get to in the member chain `chain` on `pyObject` taking members only
        along modules (or "empty" modules)

        """
        subchainAndResolutionOrNone = self._subchainAndResolutionOrNone(
            pyObject, chain)
        if subchainAndResolutionOrNone is None:
            raise Exceptions.PythonToForaConversionError(
                "don't know how to resolve %s in %s" % (chain, pyObject))

        subchain, terminalValue = subchainAndResolutionOrNone

        if id(terminalValue) in self._convertedObjectCache:
            terminalValue = self._convertedObjectCache[id(terminalValue)][1]

        return subchain, terminalValue
Exemplo n.º 30
0
        def onExpanded(jsonResult):
            if isinstance(jsonResult, Exception):
                future.set_exception(jsonResult)
                return

            if jsonResult['isException']:
                result = self.objectRehydrator.convertJsonResultToPythonObject(
                    jsonResult['result'])
                future.set_exception(
                    Exceptions.ComputationError(result, jsonResult['trace']))
                return

            assert isinstance(jsonResult['dictOfProxies'], dict)

            dictOfProxies = {}
            for k, v in jsonResult['dictOfProxies'].iteritems():
                dictOfProxies[
                    k] = RemotePythonObject.ComputedRemotePythonObject(
                        v, self)

            future.set_result(dictOfProxies)
Exemplo n.º 31
0
        def onResultCallback(jsonResult):
            result = jsonResult
            try:
                if not isinstance(jsonResult, Exception):
                    result = self._translate_download_result(jsonResult)
            except Exception as e:
                # TODO need a better way of wrapping exceptions.
                # Alexandros has some ideas here, but this is
                # better than the experience without the wrapping
                # (which is hanging)
                def clip(s):
                    if len(s) > 250:
                        return s[:250] + "... (" + str(
                            len(s) - 250) + " characters remaining)"
                    return s

                logging.error(
                    "Rehydration failed: %s\nResult was %s of type %s",
                    traceback.format_exc(), clip(repr(jsonResult)),
                    type(jsonResult))
                result = Exceptions.ForaToPythonConversionError(e)
            self._resolve_future(future, result)
Exemplo n.º 32
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
            )
Exemplo n.º 33
0
    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
            )
Exemplo n.º 34
0
 def addToTrace(self, elmt):
     Exceptions.checkTraceElement(elmt)
     self.trace.insert(0, elmt)