def makeDictCreationOrConstant(keys, values, lazy_order, source_ref): # Create dictionary node. Tries to avoid it for constant values that are not # mutable. assert len(keys) == len(values) for key, value in zip(keys, values): if not key.isExpressionConstantRef(): constant = False break if not value.isExpressionConstantRef(): constant = False break else: constant = True # Note: This would happen in optimization instead, but lets just do it # immediately to save some time. if constant: # Unless told otherwise, create the dictionary in its full size, so # that no growing occurs and the constant becomes as similar as possible # before being marshaled. result = ExpressionConstantRef( constant = Constants.createConstantDict( lazy_order = not lazy_order, keys = [ key.getConstant() for key in keys ], values = [ value.getConstant() for value in values ] ), source_ref = source_ref, user_provided = True ) else: result = ExpressionMakeDict( pairs = [ ExpressionKeyValuePair( key = key, value = value, source_ref = key.getSourceReference() ) for key, value in zip(keys, values) ], lazy_order = lazy_order, source_ref = source_ref ) if values: result.setCompatibleSourceReference( source_ref = values[-1].getCompatibleSourceReference() ) return result
def makeDictCreationOrConstant(keys, values, lazy_order, source_ref): # Create dictionary node. Tries to avoid it for constant values that are not # mutable. assert len(keys) == len(values) for key, value in zip(keys, values): if not key.isExpressionConstantRef(): constant = False break if not value.isExpressionConstantRef(): constant = False break else: constant = True # Note: This would happen in optimization instead, but lets just do it # immediately to save some time. if constant: # Unless told otherwise, create the dictionary in its full size, so # that no growing occurs and the constant becomes as similar as possible # before being marshaled. result = ExpressionConstantRef( constant = Constants.createConstantDict( lazy_order = not lazy_order, keys = [ key.getConstant() for key in keys ], values = [ value.getConstant() for value in values ] ), source_ref = source_ref, user_provided = True ) else: result = ExpressionMakeDict( pairs = [ ExpressionKeyValuePair( key = key, value = value, source_ref = key.getSourceReference() ) for key, value in zip(keys, values) ], lazy_order = lazy_order, source_ref = source_ref ) if values: result.setCompatibleSourceReference( source_ref = values[-1].getCompatibleSourceReference() ) return result
def makeTryExceptNoRaise(provider, temp_scope, tried, handling, no_raise, public_exc, source_ref): # This helper executes the core re-formulation of "no_raise" blocks, which # are the "else" blocks of "try"/"except" statements. In order to limit the # execution, we use an indicator variable instead, which will signal that # the tried block executed up to the end. And then we make the else block be # a conditional statement checking that. assert no_raise is not None tmp_handler_indicator_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="unhandled_indicator") statements = mergeStatements((StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_handler_indicator_variable.makeReference(provider), source_ref=source_ref.atInternal()), source=ExpressionConstantRef(constant=False, source_ref=source_ref), source_ref=no_raise.getSourceReference().atInternal()), handling), allow_none=True) handling = StatementsSequence(statements=statements, source_ref=source_ref) tried = (StatementTryExcept(tried=tried, handling=handling, public_exc=public_exc, source_ref=source_ref), StatementConditional(condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_handler_indicator_variable.makeReference( provider), source_ref=source_ref), right=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref), yes_branch=no_raise, no_branch=None, source_ref=source_ref)) final = StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_handler_indicator_variable.makeReference(provider), source_ref=source_ref.atInternal()), tolerant=False, source_ref=source_ref.atInternal()), return StatementsSequence(statements=(StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_handler_indicator_variable.makeReference(provider), source_ref=source_ref.atInternal()), source=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref.atInternal()), makeTryFinallyStatement( tried=tried, final=final, source_ref=source_ref)), source_ref=source_ref)
def makeTryExceptNoRaise(provider, temp_scope, tried, handlers, no_raise, source_ref): # This helper executes the core re-formulation of "no_raise" blocks, which # are the "else" blocks of "try"/"except" statements. In order to limit the # execution, we use an indicator variable instead, which will signal that # the tried block executed up to the end. And then we make the else block be # a conditional statement checking that. # This is a separate function, so it can be re-used in other # re-formulations, e.g. with statements. assert no_raise is not None assert len(handlers) > 0 tmp_handler_indicator_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="unhandled_indicator") for handler in handlers: statements = (StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_handler_indicator_variable.makeReference( provider), source_ref=source_ref.atInternal()), source=ExpressionConstantRef(constant=False, source_ref=source_ref), source_ref=no_raise.getSourceReference().atInternal()), handler.getExceptionBranch()) handler.setExceptionBranch( makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref)) statements = (StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_handler_indicator_variable.makeReference(provider), source_ref=source_ref.atInternal()), source=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref), StatementTryExcept(tried=tried, handlers=handlers, source_ref=source_ref), StatementConditional(condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_handler_indicator_variable. makeReference(provider), source_ref=source_ref), right=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref), yes_branch=no_raise, no_branch=None, source_ref=source_ref)) return StatementsSequence(statements=statements, source_ref=source_ref)
def _insertFinalReturnStatement(function_statements_body, source_ref): if function_statements_body is None: function_statements_body = makeStatementsSequenceFromStatement( statement=StatementReturn(expression=ExpressionConstantRef( constant=None, user_provided=True, source_ref=source_ref), source_ref=source_ref)) elif not function_statements_body.isStatementAborting(): function_statements_body.setStatements( function_statements_body.getStatements() + (StatementReturn(expression=ExpressionConstantRef( constant=None, user_provided=True, source_ref=source_ref), source_ref=source_ref), )) return function_statements_body
def wrapExpressionBuiltinExecfileCreation(filename, globals, locals, source_ref): provider = node.getParentVariableProvider() # TODO: Can't really be true, can it? if provider.isExpressionFunctionBody(): provider.markAsExecContaining() if provider.isClassDictCreation(): provider.markAsUnqualifiedExecContaining(source_ref) globals_wrap, locals_wrap = wrapEvalGlobalsAndLocals( provider=provider, globals_node=globals, locals_node=locals, exec_mode=False, source_ref=source_ref) return ExpressionBuiltinExecfile(source_code=ExpressionCallEmpty( called=ExpressionAttributeLookup( expression=ExpressionBuiltinOpen( filename=filename, mode=ExpressionConstantRef(constant="rU", source_ref=source_ref), buffering=None, source_ref=source_ref), attribute_name="read", source_ref=source_ref), source_ref=source_ref), globals_arg=globals_wrap, locals_arg=locals_wrap, source_ref=source_ref)
def buildReturnNode(provider, node, source_ref): if not provider.isExpressionFunctionBody() or \ provider.isClassDictCreation(): SyntaxErrors.raiseSyntaxError( "'return' outside function", source_ref, None if Utils.python_version < 300 else ( node.col_offset if provider.isPythonModule() else node.col_offset+4 ) ) expression = buildNode(provider, node.value, source_ref, allow_none = True) if expression is None: expression = ExpressionConstantRef( constant = None, source_ref = source_ref, user_provided = True ) return makeTryFinallyIndicator( statement = StatementReturn( expression = expression, source_ref = source_ref ), is_loop_exit = False )
def buildCallNode(provider, node, source_ref): positional_args = buildNodeList( provider, node.args, source_ref ) # Only the values of keyword pairs have a real source ref, and those only # really matter, so that makes sense. keys = [] values = [] for keyword in node.keywords: keys.append( ExpressionConstantRef( constant = keyword.arg, source_ref = source_ref, user_provided = True ) ) values.append( buildNode( provider, keyword.value, source_ref ) ) list_star_arg = buildNode( provider, node.starargs, source_ref, True ) dict_star_arg = buildNode( provider, node.kwargs, source_ref, True ) return _makeCallNode( called = buildNode( provider, node.func, source_ref ), positional_args = positional_args, keys = keys, values = values, list_star_arg = list_star_arg, dict_star_arg = dict_star_arg, source_ref = source_ref, )
def wrapExpressionBuiltinExecfileCreation(filename, globals_arg, locals_arg, source_ref): provider = node.getParentVariableProvider() temp_scope = provider.allocateTempScope("execfile") globals_ref, locals_ref, tried, final = wrapEvalGlobalsAndLocals( provider=provider, globals_node=globals_arg, locals_node=locals_arg, temp_scope=temp_scope, source_ref=source_ref) return ExpressionTryFinally( tried=tried, final=final, expression=ExpressionBuiltinExecfile( source_code=ExpressionCallEmpty( called=ExpressionAttributeLookup( source=ExpressionBuiltinOpen( filename=filename, mode=ExpressionConstantRef( constant="rU", source_ref=source_ref), buffering=None, source_ref=source_ref), attribute_name="read", source_ref=source_ref), source_ref=source_ref), globals_arg=globals_ref, locals_arg=locals_ref, source_ref=source_ref), source_ref=source_ref)
def buildReturnNode(provider, node, source_ref): if provider.isExpressionClassBody() or provider.isCompiledPythonModule(): SyntaxErrors.raiseSyntaxError( "'return' outside function", source_ref, None if python_version < 300 else (node.col_offset if provider.isCompiledPythonModule() else node.col_offset + 4)) expression = buildNode(provider, node.value, source_ref, allow_none=True) if provider.isExpressionGeneratorObjectBody(): if expression is not None and python_version < 330: SyntaxErrors.raiseSyntaxError( "'return' with argument inside generator", source_ref=source_ref, ) if expression is None: expression = ExpressionConstantRef(constant=None, source_ref=source_ref, user_provided=True) if provider.isExpressionGeneratorObjectBody(): return StatementGeneratorReturn(expression=expression, source_ref=source_ref) else: return StatementReturn(expression=expression, source_ref=source_ref)
def buildDictionaryUnpackingArgs(provider, keys, values, source_ref): result = [] for key, value in zip(keys, values): # TODO: We could be a lot cleverer about the dictionaries for non-starred # arguments, but lets get this to work first. if key is None: result.append(buildNode(provider, value, source_ref), ) elif type(key) is str: result.append( ExpressionMakeDict(pairs=(ExpressionKeyValuePair( key=ExpressionConstantRef(constant=key, source_ref=source_ref), value=buildNode(provider, value, source_ref), source_ref=source_ref), ), source_ref=source_ref)) else: result.append( ExpressionMakeDict(pairs=(ExpressionKeyValuePair( key=buildNode(provider, key, source_ref), value=buildNode(provider, value, source_ref), source_ref=source_ref), ), source_ref=source_ref)) return result
def __init__(self, value, source_ref): if value is None: value = ExpressionConstantRef(constant=b"", source_ref=source_ref) ExpressionBuiltinTypeBase.__init__(self, value=value, source_ref=source_ref)
def buildExtSliceNode(provider, node, source_ref): elements = [] for dim in node.slice.dims: dim_kind = getKind(dim) if dim_kind == "Slice": lower = buildNode(provider, dim.lower, source_ref, True) upper = buildNode(provider, dim.upper, source_ref, True) step = buildNode(provider, dim.step, source_ref, True) element = ExpressionBuiltinSlice(start=lower, stop=upper, step=step, source_ref=source_ref) elif dim_kind == "Ellipsis": element = ExpressionConstantRef(constant=Ellipsis, source_ref=source_ref, user_provided=True) elif dim_kind == "Index": element = buildNode(provider=provider, node=dim.value, source_ref=source_ref) else: assert False, dim elements.append(element) return makeSequenceCreationOrConstant(sequence_kind="tuple", elements=elements, source_ref=source_ref)
def buildParameterKwDefaults( provider, node, function_body, source_ref ): # Build keyword only arguments default values. We are hiding here, that it is a # Python3 only feature. if Utils.python_version >= 300: kw_only_names = function_body.getParameters().getKwOnlyParameterNames() pairs = [] for kw_name, kw_default in zip( kw_only_names, node.args.kw_defaults ): if kw_default is not None: pairs.append( ExpressionKeyValuePair( key = ExpressionConstantRef( constant = kw_name, source_ref = source_ref ), value = buildNode( provider, kw_default, source_ref ), source_ref = source_ref ) ) if pairs: kw_defaults = ExpressionMakeDict( pairs = pairs, source_ref = source_ref ) else: kw_defaults = None else: kw_defaults = None return kw_defaults
def makeTryFinallyIndicator(statement, is_loop_exit): statements = [] indicator_variables = getIndicatorVariables() source_ref = statement.getSourceReference() indicator_value = True for indicator_variable in reversed(indicator_variables): if indicator_variable is Ellipsis: break elif indicator_variable is not None: statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=indicator_variable, source_ref=source_ref.atInternal()), source=ExpressionConstantRef(constant=indicator_value, source_ref=source_ref), source_ref=source_ref.atInternal())) elif is_loop_exit: indicator_value = False statements.append(statement) return makeStatementsSequenceOrStatement(statements=statements, source_ref=source_ref)
def createPython3NamespacePath(package_name, module_relpath, source_ref): return StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = "__path__", source_ref = source_ref ), source = ExpressionCallNoKeywords( called = ExpressionImportName( module = ExpressionImportModule( module_name = "_frozen_importlib", import_list = (), level = 0, source_ref = source_ref ), import_name = "_NamespacePath", source_ref = source_ref ), args = ExpressionConstantRef( constant = ( package_name, [module_relpath], None ), source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref )
def wrapExpressionBuiltinExecfileCreation(filename, globals_arg, locals_arg, source_ref): outline_body = ExpressionOutlineBody( provider = node.getParentVariableProvider(), name = "execfile_call", source_ref = source_ref ) globals_ref, locals_ref, tried, final = wrapEvalGlobalsAndLocals( provider = node.getParentVariableProvider(), globals_node = globals_arg, locals_node = locals_arg, temp_scope = outline_body.getOutlineTempScope(), source_ref = source_ref ) tried = makeStatementsSequence( statements = ( tried, StatementReturn( expression = ExpressionBuiltinExecfile( source_code = ExpressionCallEmpty( called = ExpressionAttributeLookup( source = ExpressionBuiltinOpen( filename = filename, mode = ExpressionConstantRef( constant = "rU", source_ref = source_ref ), buffering = None, source_ref = source_ref ), attribute_name = "read", source_ref = source_ref ), source_ref = source_ref ), globals_arg = globals_ref, locals_arg = locals_ref, source_ref = source_ref ), source_ref = source_ref ) ), allow_none = False, source_ref = source_ref ) outline_body.setBody( makeStatementsSequenceFromStatement( statement = makeTryFinallyStatement( provider = outline_body, tried = tried, final = final, source_ref = source_ref ) ) ) return outline_body
def buildReturnNode(provider, node, source_ref): if not provider.isExpressionFunctionBody() or \ provider.isClassDictCreation(): SyntaxErrors.raiseSyntaxError( "'return' outside function", source_ref, None if Utils.python_version < 300 else ( node.col_offset if provider.isPythonModule() else node.col_offset+4 ) ) if node.value is not None: return StatementReturn( expression = buildNode( provider, node.value, source_ref ), source_ref = source_ref ) else: return StatementReturn( expression = ExpressionConstantRef( constant = None, source_ref = source_ref, user_provided = True ), source_ref = source_ref )
def buildExtSliceNode(provider, node, source_ref): elements = [] for dim in node.slice.dims: dim_kind = getKind(dim) if dim_kind == "Slice": lower = buildNode(provider, dim.lower, source_ref, True) upper = buildNode(provider, dim.upper, source_ref, True) step = buildNode(provider, dim.step, source_ref, True) element = ExpressionSliceObject(lower=lower, upper=upper, step=step, source_ref=source_ref) elif dim_kind == "Ellipsis": element = ExpressionConstantRef(constant=Ellipsis, source_ref=source_ref) elif dim_kind == "Index": element = buildNode(provider=provider, node=dim.value, source_ref=source_ref) else: assert False, dim elements.append(element) return ExpressionMakeTuple(elements=elements, source_ref=source_ref)
def buildCallNode( provider, node, source_ref ): positional_args = buildNodeList( provider, node.args, source_ref ) # Only the values of keyword pairs have a real source ref, and those only really # matter, so that makes sense. pairs = [ ExpressionKeyValuePair( key = ExpressionConstantRef( constant = keyword.arg, source_ref = source_ref ), value = buildNode( provider, keyword.value, source_ref ), source_ref = source_ref ) for keyword in node.keywords ] list_star_arg = buildNode( provider, node.starargs, source_ref, True ) dict_star_arg = buildNode( provider, node.kwargs, source_ref, True ) return _makeCallNode( provider = provider, called = buildNode( provider, node.func, source_ref ), positional_args = positional_args, pairs = pairs, list_star_arg = list_star_arg, dict_star_arg = dict_star_arg, source_ref = source_ref, )
def buildParameterKwDefaults(provider, node, function_body, source_ref): # Build keyword only arguments default values. We are hiding here, that it # is a Python3 only feature. if Utils.python_version >= 300: kw_only_names = function_body.getParameters().getKwOnlyParameterNames() if kw_only_names: keys = [] values = [] for kw_only_name, kw_default in \ zip( kw_only_names, node.args.kw_defaults ): if kw_default is not None: keys.append( ExpressionConstantRef(constant=kw_only_name, source_ref=source_ref)) values.append(buildNode(provider, kw_default, source_ref)) kw_defaults = makeDictCreationOrConstant(keys=keys, values=values, lazy_order=False, source_ref=source_ref) else: kw_defaults = None else: kw_defaults = None return kw_defaults
def createPathAssignment(source_ref): if Options.getFileReferenceMode() == "original": path_value = ExpressionConstantRef( constant=[dirname(source_ref.getFilename())], source_ref=source_ref, user_provided=True) else: path_value = ExpressionMakeList(elements=(ExpressionCallNoKeywords( called=ExpressionAttributeLookup(source=ExpressionImportModuleHard( module_name="os", import_name="path", source_ref=source_ref), attribute_name="dirname", source_ref=source_ref), args=ExpressionMakeTuple( elements=(ExpressionModuleFileAttributeRef( source_ref=source_ref, ), ), source_ref=source_ref, ), source_ref=source_ref, ), ), source_ref=source_ref) return StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef(variable_name="__path__", source_ref=source_ref), source=path_value, source_ref=source_ref)
def makeSequenceCreationOrConstant(sequence_kind, elements, source_ref): # Sequence creation. Tries to avoid creations with only constant # elements. Would be caught by optimization, but would be useless churn. For # mutable constants we cannot do it though. # Due to the many sequence types, there is a lot of cases here # pylint: disable=R0912 for element in elements: if not element.isExpressionConstantRef(): constant = False break else: constant = True sequence_kind = sequence_kind.upper() if Options.isFullCompat() and elements: source_ref = elements[-1].getSourceReference() # Note: This would happen in optimization instead, but lets just do it # immediately to save some time. if constant: if sequence_kind == "TUPLE": const_type = tuple elif sequence_kind == "LIST": const_type = list elif sequence_kind == "SET": const_type = set else: assert False, sequence_kind return ExpressionConstantRef( constant = const_type( element.getConstant() for element in elements ), source_ref = source_ref, user_provided = True ) else: if sequence_kind == "TUPLE": return ExpressionMakeTuple( elements = elements, source_ref = source_ref ) elif sequence_kind == "LIST": return ExpressionMakeList( elements = elements, source_ref = source_ref ) elif sequence_kind == "SET": return ExpressionMakeSet( elements = elements, source_ref = source_ref ) else: assert False, sequence_kind
def buildNumberNode(node, source_ref): assert type(node.n) in (int, long, float, complex), type(node.n) return ExpressionConstantRef( constant = node.n, source_ref = source_ref, user_provided = True )
def buildStringNode(node, source_ref): assert type(node.s) in (str, unicode) return ExpressionConstantRef( constant = node.s, source_ref = source_ref, user_provided = True )
def addAnnotation(key, value): keys.append( ExpressionConstantRef( constant = mangle(key), source_ref = source_ref, user_provided = True ) ) values.append(value)
def buildCallNode(provider, node, source_ref): if python_version >= 350: list_star_arg = None dict_star_arg = None positional_args = [] # For Python3.5 compatibility, the error handling with star argument last # is the old one, only with for node_arg in node.args[:-1]: if getKind(node_arg) == "Starred": assert python_version >= 350 list_star_arg = buildListUnpacking(provider, node.args, source_ref) positional_args = [] break else: if node.args and getKind(node.args[-1]) == "Starred": list_star_arg = buildNode(provider, node.args[-1].value, source_ref) positional_args = buildNodeList(provider, node.args[:-1], source_ref) else: positional_args = buildNodeList(provider, node.args, source_ref) # Only the values of keyword pairs have a real source ref, and those only # really matter, so that makes sense. keys = [] values = [] for keyword in node.keywords: if keyword.arg is None: assert python_version >= 350 dict_star_arg = buildNode(provider, keyword.value, source_ref) continue keys.append( ExpressionConstantRef(constant=keyword.arg, source_ref=source_ref, user_provided=True)) values.append(buildNode(provider, keyword.value, source_ref)) if python_version < 350: list_star_arg = buildNode(provider, node.starargs, source_ref, True) dict_star_arg = buildNode(provider, node.kwargs, source_ref, True) return _makeCallNode( called=buildNode(provider, node.func, source_ref), positional_args=positional_args, keys=keys, values=values, list_star_arg=list_star_arg, dict_star_arg=dict_star_arg, source_ref=source_ref, )
def createNamespacePackage(package_name, module_relpath): parts = package_name.split('.') source_ref = SourceCodeReference.fromFilenameAndLine( filename = module_relpath, line = 1, future_spec = FutureSpec(), ) source_ref = source_ref.atInternal() package_package_name = '.'.join(parts[:-1]) or None package = PythonPackage( name = parts[-1], package_name = package_package_name, source_ref = source_ref, ) package.setBody( makeStatementsSequenceFromStatement( statement = ( StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = "__path__", source_ref = source_ref ), source = ExpressionCallNoKeywords( called = ExpressionImportName( module = ExpressionImportModule( module_name = "_frozen_importlib", import_list = (), level = 0, source_ref = source_ref ), import_name = "_NamespacePath", source_ref = source_ref ), args = ExpressionConstantRef( constant = ( package_name, [module_relpath], None ), source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ) ) ) ) completeVariableClosures(package) return source_ref, package
def buildExecNode(provider, node, source_ref): # "exec" statements, should only occur with Python2. exec_globals = node.globals exec_locals = node.locals body = node.body orig_globals = exec_globals # Handle exec(a,b,c) to be same as exec a, b, c if exec_locals is None and exec_globals is None and getKind( body) == "Tuple": parts = body.elts body = parts[0] if len(parts) > 1: exec_globals = parts[1] if len(parts) > 2: exec_locals = parts[2] else: return StatementRaiseException( exception_type=ExpressionBuiltinExceptionRef( exception_name="TypeError", source_ref=source_ref), exception_value=ExpressionConstantRef( constant= "exec: arg 1 must be a string, file, or code object", source_ref=source_ref), exception_trace=None, exception_cause=None, source_ref=source_ref) globals_node = buildNode(provider, exec_globals, source_ref, True) locals_node = buildNode(provider, exec_locals, source_ref, True) if provider.isExpressionFunctionBody(): provider.markAsExecContaining() if orig_globals is None: provider.markAsUnqualifiedExecContaining(source_ref) if locals_node is not None and locals_node.isExpressionConstantRef( ) and locals_node.getConstant() is None: locals_node = None if locals_node is None and globals_node is not None: if globals_node.isExpressionConstantRef( ) and globals_node.getConstant() is None: globals_node = None return StatementExec(source_code=buildNode(provider, body, source_ref), globals_arg=globals_node, locals_arg=locals_node, source_ref=source_ref)
def buildDictContractionNode(provider, node, source_ref): # Dict contractions are dealt with by general code. return _buildContractionNode(provider=provider, node=node, name="<dictcontraction>", emit_class=ExpressionDictOperationSet, start_value=ExpressionConstantRef( constant={}, source_ref=source_ref), assign_provider=False, source_ref=source_ref)
def buildYieldNode(provider, node, source_ref): _markAsGenerator(provider, node, source_ref) if node.value is not None: return ExpressionYield(expression=buildNode(provider, node.value, source_ref), source_ref=source_ref) else: return ExpressionYield(expression=ExpressionConstantRef( constant=None, source_ref=source_ref, user_provided=True), source_ref=source_ref)
def buildReturnNode(provider, node, source_ref): if not provider.isExpressionFunctionBody() or \ provider.isClassDictCreation(): SyntaxErrors.raiseSyntaxError( "'return' outside function", source_ref, None if Utils.python_version < 300 else ( node.col_offset if provider.isPythonModule() else node.col_offset+4 ) ) expression = buildNode(provider, node.value, source_ref, allow_none = True) if expression is None: expression = ExpressionConstantRef( constant = None, source_ref = source_ref, user_provided = True ) # Indicate exceptions to potentially try/finally structures. indicator_statements = makeTryFinallyIndicatorStatements( is_loop_exit = False, source_ref = source_ref ) if indicator_statements and expression.mayRaiseException(BaseException): tmp_variable = provider.allocateTempVariable( temp_scope = provider.allocateTempScope("return"), name = "value" ) statements = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable, source_ref = expression.getSourceReference() ), source = expression, source_ref = source_ref ) ] + indicator_statements + [ StatementReturn( expression = ExpressionTempVariableRef( variable = tmp_variable, source_ref = expression.getSourceReference() ), source_ref = source_ref ) ] return makeTryFinallyStatement( tried = statements, final = StatementReleaseVariable( variable = tmp_variable, tolerant = True, source_ref = source_ref ), source_ref = source_ref ) else: return makeStatementsSequenceOrStatement( statements = indicator_statements + [ StatementReturn( expression = expression, source_ref = source_ref ) ], source_ref = source_ref )
def wrapEvalGlobalsAndLocals(provider, globals_node, locals_node, temp_scope, source_ref): """ Wrap the locals and globals arguments for "eval". This is called from the outside, and when the node tree already exists. """ globals_keeper_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "globals" ) locals_keeper_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "locals" ) if locals_node is None: locals_node = ExpressionConstantRef( constant = None, source_ref = source_ref ) if globals_node is None: globals_node = ExpressionConstantRef( constant = None, source_ref = source_ref ) post_statements = [] if provider.isExpressionClassBody(): post_statements.append( StatementLocalsDictSync( locals_arg = ExpressionTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref, ), source_ref = source_ref.atInternal() ) ) post_statements += [ StatementReleaseVariable( variable = globals_keeper_variable, source_ref = source_ref ), StatementReleaseVariable( variable = locals_keeper_variable, source_ref = source_ref ) ] # The locals default is dependent on exec_mode, globals or locals. locals_default = ExpressionConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), right = ExpressionConstantRef( constant = None, source_ref = source_ref ), source_ref = source_ref ), expression_no = ExpressionTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), expression_yes = _getLocalsClassNode(provider)( source_ref = source_ref ), source_ref = source_ref ) pre_statements = [ # First assign globals and locals temporary the values given. StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), source = globals_node, source_ref = source_ref, ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref ), source = locals_node, source_ref = source_ref, ), StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref ), right = ExpressionConstantRef( constant = None, source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref ), source = locals_default, source_ref = source_ref, ) ), no_branch = None, source_ref = source_ref ), StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), right = ExpressionConstantRef( constant = None, source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), source = ExpressionBuiltinGlobals( source_ref = source_ref ), source_ref = source_ref, ) ), no_branch = None, source_ref = source_ref ) ] return ( ExpressionTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref if globals_node is None else globals_node.getSourceReference() ), ExpressionTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref if locals_node is None else locals_node.getSourceReference() ), makeStatementsSequence(pre_statements, False, source_ref), makeStatementsSequence(post_statements, False, source_ref) )
def makeSequenceCreationOrConstant(sequence_kind, elements, source_ref): # Sequence creation. Tries to avoid creations with only constant # elements. Would be caught by optimization, but would be useless churn. For # mutable constants we cannot do it though. # Due to the many sequence types, there is a lot of cases here # pylint: disable=R0912 for element in elements: if not element.isExpressionConstantRef(): constant = False break else: constant = True sequence_kind = sequence_kind.upper() # Note: This would happen in optimization instead, but lets just do it # immediately to save some time. if constant: if sequence_kind == "TUPLE": const_type = tuple elif sequence_kind == "LIST": const_type = list elif sequence_kind == "SET": const_type = set else: assert False, sequence_kind result = ExpressionConstantRef( constant = const_type( element.getConstant() for element in elements ), source_ref = source_ref, user_provided = True ) else: if sequence_kind == "TUPLE": result = ExpressionMakeTuple( elements = elements, source_ref = source_ref ) elif sequence_kind == "LIST": result = ExpressionMakeList( elements = elements, source_ref = source_ref ) elif sequence_kind == "SET": result = ExpressionMakeSet( elements = elements, source_ref = source_ref ) else: assert False, sequence_kind if elements: result.setCompatibleSourceReference( source_ref = elements[-1].getCompatibleSourceReference() ) return result
def wrapEvalGlobalsAndLocals(provider, globals_node, locals_node, temp_scope, source_ref): """ Wrap the locals and globals arguments for eval and exec. For eval, this is called from the outside, and when the node tree already exists. """ globals_keeper_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "globals" ) locals_keeper_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "locals" ) if locals_node is None: locals_node = ExpressionConstantRef( constant = None, source_ref = source_ref ) if globals_node is None: globals_node = ExpressionConstantRef( constant = None, source_ref = source_ref ) post_statements = [ StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = globals_keeper_variable.makeReference( provider ), source_ref = globals_node.getSourceReference() ), tolerant = False, source_ref = source_ref ), StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = locals_keeper_variable.makeReference( provider ), source_ref = locals_node.getSourceReference() ), tolerant = False, source_ref = source_ref ) ] # The locals default is dependant on exec_mode, globals or locals. locals_default = ExpressionConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = globals_keeper_variable.makeReference( provider ), source_ref = source_ref ), right = ExpressionConstantRef( constant = None, source_ref = source_ref ), source_ref = source_ref ), no_expression = ExpressionTempVariableRef( variable = globals_keeper_variable.makeReference( provider ), source_ref = source_ref ), yes_expression = ExpressionBuiltinLocals( source_ref = source_ref ), source_ref = source_ref ) pre_statements = [ # First assign globals and locals temporary the values given. StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = globals_keeper_variable.makeReference( provider ), source_ref = source_ref ), source = globals_node, source_ref = source_ref, ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = locals_keeper_variable.makeReference( provider ), source_ref = source_ref ), source = locals_node, source_ref = source_ref, ), StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = locals_keeper_variable.makeReference( provider ), source_ref = source_ref ), right = ExpressionConstantRef( constant = None, source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = locals_keeper_variable.makeReference( provider ), source_ref = source_ref ), source = locals_default, source_ref = source_ref, ) ), no_branch = None, source_ref = source_ref ), StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = globals_keeper_variable.makeReference( provider ), source_ref = source_ref ), right = ExpressionConstantRef( constant = None, source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = globals_keeper_variable.makeReference( provider ), source_ref = source_ref ), source = ExpressionBuiltinGlobals( source_ref = source_ref ), source_ref = source_ref, ) ), no_branch = None, source_ref = source_ref ) ] return ( ExpressionTempVariableRef( variable = globals_keeper_variable.makeReference( provider ), source_ref = source_ref if globals_node is None else globals_node.getSourceReference() ), ExpressionTempVariableRef( variable = locals_keeper_variable.makeReference( provider ), source_ref = source_ref if locals_node is None else locals_node.getSourceReference() ), makeStatementsSequence(pre_statements, False, source_ref), makeStatementsSequence(post_statements, False, source_ref) )