def onSuccess(message): if 'isException' not in message: callback(objectId) else: callback( Exceptions.PythonToForaConversionError( str(message['message']), message['trace']))
def computeSubchainAndTerminalValueAlongModules(self, rootValue, chainWithPosition): """ Return a ResultionResult or raise a PythonToForaConversionError """ ix = 1 chain = chainWithPosition.var position = chainWithPosition.pos subchain, terminalValue = chain[:ix], rootValue while PyforaInspect.ismodule( terminalValue) and self.terminal_value_filter(terminalValue): if ix >= len(chain): #we're terminating at a module terminalValue = Unconvertible(terminalValue) break 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 ResolutionResult.resolution(subchain=subchain, resolution=terminalValue, position=position)
def convert(self, objectId, objectRegistry, callback): dependencyGraph = objectRegistry.computeDependencyGraph(objectId) objectIdToObjectDefinition = { objId: objectRegistry.getDefinition(objId)._asdict() for objId in dependencyGraph.iterkeys() } def onSuccess(message): if 'isException' not in message: callback(objectId) else: callback( Exceptions.PythonToForaConversionError( str(message['message']), message['trace'])) self.remoteConverter.convert( { 'objectId': objectId, 'objectIdToObjectDefinition': objectIdToObjectDefinition }, { 'onSuccess': onSuccess, 'onFailure': lambda err: callback( Exceptions.PythonToForaConversionError(err)) })
def define(self, obj): """Create a remote representation of an object. Sends the specified object to the server and return a Future that resolves to a RemotePythonObject representing the object on the server. Args: obj: A python object to send Returns: A :class:`~Future.Future` that resolves to a :class:`~RemotePythonObject.RemotePythonObject` representing the object on the server. """ self._raiseIfClosed() try: objectId = PyObjectWalker.PyObjectWalker( purePythonClassMapping=self.pureImplementationMappings, objectRegistry=self.objectRegistry).walkPyObject(obj) except PyObjectWalker.UnresolvedFreeVariableExceptionWithTrace as e: logging.error( "Converting UnresolvedFreeVariableExceptionWithTrace to PythonToForaConversionError:\n%s", traceback.format_exc()) raise Exceptions.PythonToForaConversionError(e.message, e.trace) future = self._create_future() def onConverted(result): if not isinstance(result, Exception): result = RemotePythonObject.DefinedRemotePythonObject( objectId, self) self._resolve_future(future, result) self.connection.convertObject(objectId, self.objectRegistry, onConverted) return future
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))
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
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)
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)
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
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 convert(self, objectId, binaryObjectRegistry, callback): binaryObjectRegistry.defineEndOfStream() newData = binaryObjectRegistry.str() binaryObjectRegistry.clear() def onSuccess(message): if 'isException' not in message: callback(objectId) else: callback( Exceptions.PythonToForaConversionError( str(message['message']), message['trace'])) self.remoteConverter.convert( { 'objectId': objectId, 'serializedBinaryObjectDefinition': base64.b64encode(newData) }, { 'onSuccess': onSuccess, 'onFailure': lambda err: callback( Exceptions.PythonToForaConversionError(err)) })
def _computeSubchainAndTerminalValueAlongModules(rootValue, chainWithPosition): ix = 1 chain = chainWithPosition.var position = chainWithPosition.pos subchain, terminalValue = chain[:ix], rootValue while PyforaInspect.ismodule(terminalValue): if ix >= len(chain): #we're terminating at a module terminalValue = _Unconvertible() break 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, position
def visit_Global(self, node): raise Exceptions.PythonToForaConversionError( "'global' statement not supported in Python to Fora translation (line %s)." % node.lineno)
def visit_Global(self, _): raise Exceptions.PythonToForaConversionError( "Illegal 'global' statement: not supported in Python to Fora translation." )
def visit_ClassDef(self, node): raise Exceptions.PythonToForaConversionError( "classes in `__init__ method may rebind `self argument, " \ "so we're not allowing them (line %s)." % node.lineno )
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 )
def _raiseConversionErrorForSourceTextError(self, pyObject): raise Exceptions.PythonToForaConversionError( "can't convert %s (of type %s) since we can't get its source code" % (pyObject, type(pyObject)))