def _buildSetUnpacking(provider, elements, source_ref): helper_args = [] for element in elements: # We could be a lot cleverer about the tuples for non-starred # arguments, but lets get this to work first. And then rely on # future optimization to inline the list unpacking helper in a # way that has the same effect. if getKind(element) == "Starred": helper_args.append(buildNode(provider, element.value, source_ref)) else: helper_args.append( ExpressionMakeTuple( elements=(buildNode(provider, element, source_ref), ), source_ref=source_ref, )) result = ExpressionFunctionCall( function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef( function_body=getSetUnpackingHelper(), source_ref=source_ref), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref, ), values=(ExpressionMakeTuple(helper_args, source_ref), ), source_ref=source_ref, ) result.setCompatibleSourceReference( helper_args[-1].getCompatibleSourceReference()) return result
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=too-many-branches for element in elements: if not element.isExpressionConstantRef(): constant = False break else: constant = True sequence_kind = sequence_kind.lower() # 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 if needsSetLiteralReverseInsertion(): elements = tuple(reversed(elements)) else: assert False, sequence_kind result = makeConstantRefNode( 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 = ExpressionMakeSetLiteral(elements=elements, source_ref=source_ref) else: assert False, sequence_kind if elements: result.setCompatibleSourceReference( source_ref=elements[-1].getCompatibleSourceReference() ) return result
def createPathAssignment(package, source_ref): if Options.getFileReferenceMode() == "original": path_value = makeConstantRefNode( constant=[os.path.dirname(source_ref.getFilename())], source_ref=source_ref, user_provided=True) else: elements = [ ExpressionCallNoKeywords( called=ExpressionAttributeLookup( source=ExpressionImportModuleNameHard( module_name="os", import_name="path", source_ref=source_ref), attribute_name="dirname", source_ref=source_ref), args=ExpressionMakeTuple( elements=(ExpressionModuleAttributeFileRef( variable=package.getVariableForReference("__file__"), source_ref=source_ref, ), ), source_ref=source_ref, ), source_ref=source_ref, ) ] if package.canHaveExternalImports(): parts = package.getFullName().split('.') for count in range(len(parts)): path_part = _makeCall( "os", "environ", "get", source_ref, makeConstantRefNode( constant="NUITKA_PACKAGE_%s" % '_'.join(parts[:count + 1]), source_ref=source_ref, ), makeConstantRefNode( constant="/notexist", source_ref=source_ref, )) if parts[count + 1:]: path_part = _makeCall( "os", "path", "join", source_ref, path_part, makeConstantRefNode( constant=os.path.join(*parts[count + 1:]), source_ref=source_ref, )) elements.append(path_part) path_value = ExpressionMakeList(elements=elements, source_ref=source_ref) return StatementAssignmentVariableName(provider=package, variable_name="__path__", source=path_value, source_ref=source_ref)
def buildDictionaryUnpacking(provider, node, source_ref): helper_args = buildDictionaryUnpackingArgs(provider, node.keys, node.values, source_ref) result = ExpressionFunctionCall( function = ExpressionFunctionCreation( function_ref = ExpressionFunctionRef( function_body = getDictUnpackingHelper(), source_ref = source_ref ), code_object = None, defaults = (), kw_defaults = None, annotations = None, source_ref = source_ref ), values = ( ExpressionMakeTuple( helper_args, source_ref ), ), source_ref = source_ref, ) result.setCompatibleSourceReference(helper_args[-1].getCompatibleSourceReference()) return result
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 buildDictionaryUnpacking(provider, node, source_ref): helper_args = [] for key, value in zip(node.keys, node.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: helper_args.append(buildNode(provider, value, source_ref), ) else: helper_args.append( ExpressionMakeDict( pairs=(ExpressionKeyValuePair( key=buildNode(provider, key, source_ref), value=buildNode(provider, value, source_ref), source_ref=source_ref), ), source_ref=source_ref, lazy_order=False, )) result = ExpressionFunctionCall( function=ExpressionFunctionCreation(function_ref=ExpressionFunctionRef( function_body=getDictUnpackingHelper(), source_ref=source_ref), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(ExpressionMakeTuple(helper_args, source_ref), ), source_ref=source_ref, ) result.setCompatibleSourceReference( helper_args[-1].getCompatibleSourceReference()) return result
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 _buildSetUnpacking(provider, elements, source_ref): helper_args = [] for element in elements: # TODO: We could be a lot cleverer about the tuples for non-starred # arguments, but lets get this to work first. if getKind(element) == "Starred": helper_args.append( buildNode(provider, element.value, source_ref), ) else: helper_args.append( ExpressionMakeTuple( elements = ( buildNode(provider, element, source_ref), ), source_ref = source_ref ) ) result = ExpressionFunctionCall( function = ExpressionFunctionCreation( function_ref = ExpressionFunctionRef( function_body = getSetUnpackingHelper(), source_ref = source_ref ), code_object = None, defaults = (), kw_defaults = None, annotations = None, source_ref = source_ref ), values = ( ExpressionMakeTuple( helper_args, source_ref ), ), source_ref = source_ref, ) result.setCompatibleSourceReference(helper_args[-1].getCompatibleSourceReference()) return result
def _makeCall(module_name, import_name, attribute_name, source_ref, *args): return ExpressionCallNoKeywords(called=ExpressionAttributeLookup( source=ExpressionImportModuleNameHard(module_name=module_name, import_name=import_name, source_ref=source_ref), attribute_name=attribute_name, source_ref=source_ref), args=ExpressionMakeTuple( elements=args, source_ref=source_ref), source_ref=source_ref)
def buildAssertNode(provider, node, source_ref): # Build assert statements. These are re-formulated as described in the # developer manual too. They end up as conditional statement with raises of # AssertionError exceptions. # Underlying assumption: # # Assert x, y is the same as: # if not x: # raise AssertionError, y # Therefore assert statements are really just conditional statements with a # static raise contained. # exception_value = buildNode(provider, node.msg, source_ref, True) if "no_asserts" in getPythonFlags(): return None if exception_value is not None and python_version > 272: exception_value = ExpressionMakeTuple( elements = (exception_value,), source_ref = source_ref ) raise_statement = StatementRaiseException( exception_type = ExpressionBuiltinExceptionRef( exception_name = "AssertionError", source_ref = source_ref ), exception_value = exception_value, exception_trace = None, exception_cause = None, source_ref = source_ref ) return StatementConditional( condition = ExpressionOperationNOT( operand = buildNode(provider, node.test, source_ref), source_ref = source_ref ), yes_branch = StatementsSequence( statements = ( raise_statement, ), source_ref = source_ref ), no_branch = None, 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=too-many-branches for element in elements: if not element.isExpressionConstantRef(): constant = False break else: constant = True sequence_kind = sequence_kind.lower() # 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 if needsSetLiteralReverseInsertion(): elements = tuple(reversed(elements)) else: assert False, sequence_kind result = makeConstantRefNode( 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 = ExpressionMakeSetLiteral(elements=elements, source_ref=source_ref) else: assert False, sequence_kind if elements: result.setCompatibleSourceReference( source_ref=elements[-1].getCompatibleSourceReference()) return result
def buildSequenceCreationNode(provider, node, 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. elements = buildNodeList(provider, node.elts, source_ref) for element in elements: if not element.isExpressionConstantRef() or element.isMutable(): constant = False break else: constant = True sequence_kind = getKind(node).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 return ExpressionConstantRef(constant=const_type( element.getConstant() for element in elements), source_ref=source_ref) 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 buildCallNode(provider, node, source_ref): called = buildNode(provider, node.func, 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 a starred argument before that, things use the # new unpacking code. 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": assert python_version >= 350 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[:-1]: if keyword.arg is None: assert python_version >= 350 outline_body = ExpressionOutlineBody(provider=provider, name="dict_unpacking_call", source_ref=source_ref) tmp_called = outline_body.allocateTempVariable(temp_scope=None, name="called") helper_args = [ ExpressionTempVariableRef(variable=tmp_called, source_ref=source_ref), ExpressionMakeTuple( elements=buildDictionaryUnpackingArgs( provider=provider, keys=(keyword.arg for keyword in node.keywords), values=(keyword.value for keyword in node.keywords), source_ref=source_ref, ), source_ref=source_ref, ), ] dict_star_arg = ExpressionFunctionCall( function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef( function_body=getFunctionCallHelperDictionaryUnpacking( ), source_ref=source_ref, ), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref, ), values=helper_args, source_ref=source_ref, ) outline_body.setBody( makeStatementsSequenceFromStatements( StatementAssignmentVariable(variable=tmp_called, source=called, source_ref=source_ref), StatementReturn( expression=_makeCallNode( called=ExpressionTempVariableRef( variable=tmp_called, source_ref=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, ), source_ref=source_ref, ), )) return outline_body # For Python3.5 compatibility, the error handling with star argument last # is the old one, only with a starred argument before that, things use the # new unpacking code. if node.keywords and node.keywords[-1].arg is None: assert python_version >= 350 dict_star_arg = buildNode(provider, node.keywords[-1].value, source_ref) keywords = node.keywords[:-1] else: keywords = node.keywords for keyword in keywords: keys.append( makeConstantRefNode(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=called, 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 buildFunctionNode(provider, node, source_ref): # Functions have way too many details, pylint: disable=R0912,R0914 assert getKind(node) == "FunctionDef" function_statement_nodes, function_doc = extractDocFromBody(node) function_kind, flags, _written_variables, _non_local_declarations, _global_declarations = \ detectFunctionBodyKind( nodes = function_statement_nodes ) outer_body, function_body, code_object = buildFunctionWithParsing( provider=provider, function_kind=function_kind, name=node.name, function_doc=function_doc, flags=flags, node=node, source_ref=source_ref) if function_kind == "Function": code_body = function_body elif function_kind == "Generator": code_body = ExpressionGeneratorObjectBody(provider=function_body, name=node.name, flags=flags, source_ref=source_ref) for variable in function_body.getVariables(): code_body.getVariableForReference(variable.getName()) else: assert False, function_kind if function_kind == "Generator": function_body.setBody( makeStatementsSequenceFromStatement(statement=StatementReturn( expression=ExpressionMakeGeneratorObject( generator_ref=ExpressionFunctionRef( function_body=code_body, source_ref=source_ref), code_object=code_object, source_ref=source_ref), source_ref=source_ref))) decorators = buildNodeList(provider=provider, nodes=reversed(node.decorator_list), source_ref=source_ref) defaults = buildNodeList(provider=provider, nodes=node.args.defaults, source_ref=source_ref) kw_defaults = buildParameterKwDefaults(provider=provider, node=node, function_body=function_body, source_ref=source_ref) function_statements_body = buildFrameNode(provider=code_body, nodes=function_statement_nodes, code_object=code_object, source_ref=source_ref) if function_kind == "Function": # TODO: Generators might have to raise GeneratorExit instead. function_statements_body = _insertFinalReturnStatement( function_statements_body=function_statements_body, return_class=StatementReturn, source_ref=source_ref) if function_statements_body.isStatementsFrame(): function_statements_body = makeStatementsSequenceFromStatement( statement=function_statements_body) code_body.setBody(function_statements_body) annotations = buildParameterAnnotations(provider, node, source_ref) function_creation = ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=outer_body, source_ref=source_ref), code_object=code_object, defaults=defaults, kw_defaults=kw_defaults, annotations=annotations, source_ref=source_ref) # Add the "staticmethod" decorator to __new__ methods if not provided. # CPython made these optional, but secretly applies them when it does # "class __new__". We add them earlier, so our optimization will see it. if node.name == "__new__" and \ provider.isExpressionClassBody(): for decorator in decorators: if decorator.isExpressionVariableRef() and \ decorator.getVariableName() == "staticmethod": break else: decorators.append( ExpressionBuiltinRef(builtin_name="staticmethod", source_ref=source_ref)) if python_version >= 360 and \ node.name == "__init_subclass__" and \ provider.isExpressionClassBody(): for decorator in decorators: if decorator.isExpressionVariableRef() and \ decorator.getVariableName() == "classmethod": break else: decorators.append( ExpressionBuiltinRef(builtin_name="classmethod", source_ref=source_ref)) decorated_function = function_creation for decorator in decorators: decorated_function = ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple(elements=(decorated_function, ), source_ref=source_ref), source_ref=decorator.getSourceReference()) result = StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef(variable_name=mangleName( node.name, provider), source_ref=source_ref), source=decorated_function, source_ref=source_ref) if python_version >= 340: function_body.qualname_setup = result.getTargetVariableRef() return result
def buildAsyncFunctionNode(provider, node, source_ref): # We are creating a function here that creates coroutine objects, with # many details each, pylint: disable=R0914 assert getKind(node) == "AsyncFunctionDef" function_statement_nodes, function_doc = extractDocFromBody(node) creator_function_body, _, code_object = buildFunctionWithParsing( provider=provider, function_kind="Coroutine", name=node.name, flags=set(), function_doc=function_doc, node=node, source_ref=source_ref) function_body = ExpressionCoroutineObjectBody( provider=creator_function_body, name=node.name, flags=set(), source_ref=source_ref) decorators = buildNodeList(provider=provider, nodes=reversed(node.decorator_list), source_ref=source_ref) defaults = buildNodeList(provider=provider, nodes=node.args.defaults, source_ref=source_ref) function_statements_body = buildFrameNode(provider=function_body, nodes=function_statement_nodes, code_object=code_object, source_ref=source_ref) function_statements_body = _insertFinalReturnStatement( function_statements_body=function_statements_body, return_class=StatementGeneratorReturn, source_ref=source_ref) if function_statements_body.isStatementsFrame(): function_statements_body = makeStatementsSequenceFromStatement( statement=function_statements_body) function_body.setBody(function_statements_body) annotations = buildParameterAnnotations(provider, node, source_ref) kw_defaults = buildParameterKwDefaults(provider=provider, node=node, function_body=creator_function_body, source_ref=source_ref) creator_function_body.setBody( makeStatementsSequenceFromStatement( statement=StatementReturn(expression=ExpressionMakeCoroutineObject( coroutine_ref=ExpressionFunctionRef( function_body=function_body, source_ref=source_ref), code_object=code_object, source_ref=source_ref), source_ref=source_ref))) function_creation = ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=creator_function_body, source_ref=source_ref), code_object=code_object, defaults=defaults, kw_defaults=kw_defaults, annotations=annotations, source_ref=source_ref) decorated_function = function_creation for decorator in decorators: decorated_function = ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple(elements=(decorated_function, ), source_ref=source_ref), source_ref=decorator.getSourceReference()) result = StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef(variable_name=mangleName( node.name, provider), source_ref=source_ref), source=decorated_function, source_ref=source_ref) function_body.qualname_setup = result.getTargetVariableRef() return result
def buildFunctionNode(provider, node, source_ref): assert getKind(node) == "FunctionDef" function_statements, function_doc = extractDocFromBody(node) function_body = ExpressionFunctionBody( provider = provider, name = node.name, doc = function_doc, parameters = buildParameterSpec(node.name, node, source_ref), source_ref = source_ref ) # Hack: function_body.parent = provider decorators = buildNodeList( provider = provider, nodes = reversed(node.decorator_list), source_ref = source_ref ) defaults = buildNodeList( provider = provider, nodes = node.args.defaults, source_ref = source_ref ) kw_defaults = buildParameterKwDefaults( provider, node, function_body, source_ref ) pushIndicatorVariable(Ellipsis) function_statements_body = buildStatementsNode( provider = function_body, nodes = function_statements, frame = True, source_ref = source_ref ) popIndicatorVariable() if function_body.isGenerator(): # TODO: raise generator exit? pass elif function_statements_body is None: function_statements_body = makeStatementsSequenceFromStatement( statement = StatementReturn( expression = ExpressionConstantRef( constant = None, source_ref = source_ref.atInternal() ), source_ref = source_ref.atInternal() ) ) elif not function_statements_body.isStatementAborting(): function_statements_body.setStatements( function_statements_body.getStatements() + ( StatementReturn( expression = ExpressionConstantRef( constant = None, source_ref = source_ref ), source_ref = source_ref.atInternal() ), ) ) function_body.setBody( function_statements_body ) annotations = buildParameterAnnotations(provider, node, source_ref) function_creation = ExpressionFunctionCreation( function_ref = ExpressionFunctionRef( function_body, source_ref = source_ref ), defaults = defaults, kw_defaults = kw_defaults, annotations = annotations, source_ref = source_ref ) # Add the staticmethod decorator to __new__ methods if not provided. # CPython made these optional, but applies them to every class __new__. We # add them early, so our optimization will see it. if node.name == "__new__" and not decorators and \ provider.isExpressionFunctionBody() and provider.isClassDictCreation(): decorators = ( ExpressionBuiltinRef( builtin_name = "staticmethod", source_ref = source_ref ), ) decorated_function = function_creation for decorator in decorators: decorated_function = ExpressionCallNoKeywords( called = decorator, args = ExpressionMakeTuple( elements = (decorated_function,), source_ref = source_ref ), source_ref = decorator.getSourceReference() ) result = StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = node.name, source_ref = source_ref ), source = decorated_function, source_ref = source_ref ) if Utils.python_version >= 340: function_body.qualname_setup = result.getTargetVariableRef() return result
def getDictUnpackingHelper(): helper_name = "_unpack_dict" result = ExpressionFunctionBody( provider = getInternalModule(), name = helper_name, doc = None, parameters = ParameterSpec( ps_name = helper_name, ps_normal_args = (), ps_list_star_arg = "args", ps_dict_star_arg = None, ps_default_count = 0, ps_kw_only_args = () ), flags = set(), source_ref = internal_source_ref ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "dict") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "keys") loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried = StatementAssignmentVariable( variable = tmp_item_variable, source = ExpressionBuiltinNext1( value = ExpressionTempVariableRef( variable = tmp_iter_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), exception_name = "StopIteration", handler_body = StatementLoopBreak( source_ref = internal_source_ref ), source_ref = internal_source_ref ), makeTryExceptSingleHandlerNode( tried = StatementDictOperationUpdate( dict_arg = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), value = ExpressionTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), exception_name = "AttributeError", handler_body = StatementRaiseException( exception_type = ExpressionBuiltinMakeException( exception_name = "TypeError", args = ( makeBinaryOperationNode( operator = "Mod", left = makeConstantRefNode( constant = """\ '%s' object is not a mapping""", source_ref = internal_source_ref, user_provided = True ), right = ExpressionMakeTuple( elements = ( ExpressionAttributeLookup( source = ExpressionBuiltinType1( value = ExpressionTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), attribute_name = "__name__", source_ref = internal_source_ref ), ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), ), source_ref = internal_source_ref ), exception_value = None, exception_trace = None, exception_cause = None, source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) args_variable = result.getVariableForAssignment( variable_name = "args" ) final = ( StatementReleaseVariable( variable = tmp_result_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_iter_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_item_variable, source_ref = internal_source_ref ), # We get handed our args responsibility. StatementDelVariable( variable = args_variable, tolerant = False, source_ref = internal_source_ref ) ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable = tmp_iter_variable, source = ExpressionBuiltinIter1( value = ExpressionVariableRef( variable = args_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementAssignmentVariable( variable = tmp_result_variable, source = makeConstantRefNode( constant = {}, source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementLoop( body = loop_body, source_ref = internal_source_ref ), StatementReturn( expression = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) result.setBody( makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider = result, tried = tried, final = final, source_ref = internal_source_ref ) ) ) return result
def buildFunctionNode(provider, node, source_ref): assert getKind(node) == "FunctionDef" function_statements, function_doc = extractDocFromBody(node) function_body = ExpressionFunctionBody(provider=provider, name=node.name, doc=function_doc, parameters=buildParameterSpec( provider, node.name, node, source_ref), is_class=False, source_ref=source_ref) decorators = buildNodeList(provider=provider, nodes=reversed(node.decorator_list), source_ref=source_ref) defaults = buildNodeList(provider=provider, nodes=node.args.defaults, source_ref=source_ref) kw_defaults = buildParameterKwDefaults(provider=provider, node=node, function_body=function_body, source_ref=source_ref) function_statements_body = buildStatementsNode(provider=function_body, nodes=function_statements, frame=True, source_ref=source_ref) if function_body.isGenerator(): # TODO: raise generator exit? pass else: function_statements_body = _insertFinalReturnStatement( function_statements_body=function_statements_body, source_ref=source_ref) if function_statements_body.isStatementsFrame(): function_statements_body = makeStatementsSequenceFromStatement( statement=function_statements_body) function_body.setBody(function_statements_body) annotations = buildParameterAnnotations(provider, node, source_ref) function_creation = ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=function_body, source_ref=source_ref), defaults=defaults, kw_defaults=kw_defaults, annotations=annotations, source_ref=source_ref) # Add the "staticmethod" decorator to __new__ methods if not provided. # CPython made these optional, but secretly applies them when it does # "class __new__". We add them earlier, so our optimization will see it. if node.name == "__new__" and \ not decorators and \ provider.isExpressionClassBody(): decorators = (ExpressionBuiltinRef(builtin_name="staticmethod", source_ref=source_ref), ) decorated_function = function_creation for decorator in decorators: decorated_function = ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple(elements=(decorated_function, ), source_ref=source_ref), source_ref=decorator.getSourceReference()) result = StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef(variable_name=mangleName( node.name, provider), source_ref=source_ref), source=decorated_function, source_ref=source_ref) if Utils.python_version >= 340: function_body.qualname_setup = result.getTargetVariableRef() return result
def buildClassNode3(provider, node, source_ref): # Many variables, due to the huge re-formulation that is going on here, # which just has the complexity and optimization checks: # pylint: disable=I0021,too-many-branches,too-many-locals,too-many-statements # This function is the Python3 special case with special re-formulation as # according to developer manual. class_statement_nodes, class_doc = extractDocFromBody(node) # We need a scope for the temporary variables, and they might be closured. temp_scope = provider.allocateTempScope(name="class_creation") tmp_class_decl_dict = provider.allocateTempVariable(temp_scope=temp_scope, name="class_decl_dict") tmp_metaclass = provider.allocateTempVariable(temp_scope=temp_scope, name="metaclass") tmp_prepared = provider.allocateTempVariable(temp_scope=temp_scope, name="prepared") class_creation_function = ExpressionClassBody(provider=provider, name=node.name, doc=class_doc, source_ref=source_ref) class_variable = class_creation_function.getVariableForAssignment( "__class__") class_variable_ref = ExpressionVariableRef(variable=class_variable, source_ref=source_ref) parent_module = provider.getParentModule() code_object = CodeObjectSpec( co_name=node.name, co_kind="Class", co_varnames=(), co_argcount=0, co_posonlyargcount=0, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False, co_filename=parent_module.getRunTimeFilename(), co_lineno=source_ref.getLineNumber(), future_spec=parent_module.getFutureSpec(), ) body = buildFrameNode( provider=class_creation_function, nodes=class_statement_nodes, code_object=code_object, source_ref=source_ref, ) source_ref_orig = source_ref if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref locals_scope = class_creation_function.getFunctionLocalsScope() statements = [ StatementSetLocals( locals_scope=locals_scope, new_locals=ExpressionTempVariableRef(variable=tmp_prepared, source_ref=source_ref), source_ref=source_ref, ), StatementAssignmentVariableName( provider=class_creation_function, variable_name="__module__", source=ExpressionModuleAttributeNameRef( variable=provider.getParentModule().getVariableForReference( "__name__"), source_ref=source_ref, ), source_ref=source_ref, ), ] if class_doc is not None: statements.append( StatementAssignmentVariableName( provider=class_creation_function, variable_name="__doc__", source=makeConstantRefNode(constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref, )) # The "__qualname__" attribute is new in Python 3.3. if python_version >= 300: qualname = class_creation_function.getFunctionQualname() if python_version < 340: qualname_ref = makeConstantRefNode(constant=qualname, source_ref=source_ref, user_provided=True) else: qualname_ref = ExpressionFunctionQualnameRef( function_body=class_creation_function, source_ref=source_ref) statements.append( StatementLocalsDictOperationSet( locals_scope=locals_scope, variable_name="__qualname__", value=qualname_ref, source_ref=source_ref, )) if python_version >= 340: qualname_assign = statements[-1] if python_version >= 360 and class_creation_function.needsAnnotationsDictionary( ): statements.append( StatementLocalsDictOperationSet( locals_scope=locals_scope, variable_name="__annotations__", value=makeConstantRefNode(constant={}, source_ref=source_ref, user_provided=True), source_ref=source_ref, )) statements.append(body) if node.bases: tmp_bases = provider.allocateTempVariable(temp_scope=temp_scope, name="bases") if python_version >= 370: tmp_bases_orig = provider.allocateTempVariable( temp_scope=temp_scope, name="bases_orig") def makeBasesRef(): return ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref) else: def makeBasesRef(): return makeConstantRefNode(constant=(), source_ref=source_ref) if python_version >= 370 and node.bases: statements.append( makeStatementConditional( condition=makeComparisonExpression( comparator="NotEq", left=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), right=ExpressionTempVariableRef(variable=tmp_bases_orig, source_ref=source_ref), source_ref=source_ref, ), yes_branch=StatementLocalsDictOperationSet( locals_scope=locals_scope, variable_name="__orig_bases__", value=ExpressionTempVariableRef(variable=tmp_bases_orig, source_ref=source_ref), source_ref=source_ref, ), no_branch=None, source_ref=source_ref, )) statements += [ StatementAssignmentVariable( variable=class_variable, source=makeExpressionCall( called=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), args=makeSequenceCreationOrConstant( sequence_kind="tuple", elements=( makeConstantRefNode( constant=node.name, source_ref=source_ref, user_provided=True, ), makeBasesRef(), ExpressionBuiltinLocalsRef(locals_scope=locals_scope, source_ref=source_ref), ), source_ref=source_ref, ), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), StatementReturn(expression=class_variable_ref, source_ref=source_ref), ] body = makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement( provider=class_creation_function, tried=mergeStatements(statements, True), final=StatementReleaseLocals(locals_scope=locals_scope, source_ref=source_ref), source_ref=source_ref, )) # The class body is basically a function that implicitly, at the end # returns its locals and cannot have other return statements contained. class_creation_function.setBody(body) # The class body is basically a function that implicitly, at the end # returns its created class and cannot have other return statements # contained. decorated_body = class_creation_function for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): decorated_body = makeExpressionCall( called=decorator, args=ExpressionMakeTuple(elements=(decorated_body, ), source_ref=source_ref), kw=None, source_ref=decorator.getSourceReference(), ) if node.keywords and node.keywords[-1].arg is None: keywords = node.keywords[:-1] else: keywords = node.keywords statements = [] if node.bases: statements.append( StatementAssignmentVariable( variable=tmp_bases if python_version < 370 else tmp_bases_orig, source=buildTupleCreationNode(provider=provider, elements=node.bases, source_ref=source_ref), source_ref=source_ref, )) if python_version >= 370: bases_conversion = ExpressionFunctionCall( function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef( function_body=getClassBasesMroConversionHelper(), source_ref=source_ref, ), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref, ), values=(ExpressionTempVariableRef(variable=tmp_bases_orig, source_ref=source_ref), ), source_ref=source_ref, ) statements.append( StatementAssignmentVariable(variable=tmp_bases, source=bases_conversion, source_ref=source_ref)) statements.append( StatementAssignmentVariable( variable=tmp_class_decl_dict, source=makeDictCreationOrConstant2( keys=[keyword.arg for keyword in keywords], values=[ buildNode(provider, keyword.value, source_ref) for keyword in keywords ], source_ref=source_ref, ), source_ref=source_ref, )) if node.keywords and node.keywords[-1].arg is None: statements.append( StatementDictOperationUpdate( dict_arg=ExpressionVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), value=buildNode(provider, node.keywords[-1].value, source_ref), source_ref=source_ref, )) # Check if there are bases, and if there are, go with the type of the # first base class as a metaclass unless it was specified in the class # decl dict of course. if node.bases: unspecified_metaclass_expression = ExpressionBuiltinType1( value=ExpressionSubscriptLookup( subscribed=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), subscript=makeConstantRefNode(constant=0, source_ref=source_ref, user_provided=True), source_ref=source_ref, ), source_ref=source_ref, ) # Might become empty behind our back during conversion, therefore make the # check at run time for 3.7 or higher. if python_version >= 370: unspecified_metaclass_expression = ExpressionConditional( condition=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), expression_yes=unspecified_metaclass_expression, expression_no=makeExpressionBuiltinRef(builtin_name="type", source_ref=source_ref), source_ref=source_ref, ) else: unspecified_metaclass_expression = makeExpressionBuiltinRef( builtin_name="type", source_ref=source_ref) call_prepare = StatementAssignmentVariable( variable=tmp_prepared, source=makeExpressionCall( called=ExpressionAttributeLookup( source=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), attribute_name="__prepare__", source_ref=source_ref, ), args=ExpressionMakeTuple( elements=( makeConstantRefNode(constant=node.name, source_ref=source_ref, user_provided=True), makeBasesRef(), ), source_ref=source_ref, ), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ) if python_version >= 364: call_prepare = makeStatementsSequenceFromStatements( call_prepare, makeStatementConditional( condition=ExpressionAttributeCheck( object_arg=ExpressionTempVariableRef( variable=tmp_prepared, source_ref=source_ref), attribute_name="__getitem__", source_ref=source_ref, ), yes_branch=None, no_branch=makeRaiseExceptionExpressionFromTemplate( exception_type="TypeError", template="%s.__prepare__() must return a mapping, not %s", template_args=( ExpressionBuiltinGetattr( object_arg=ExpressionTempVariableRef( variable=tmp_metaclass, source_ref=source_ref), name=makeConstantRefNode(constant="__name__", source_ref=source_ref), default=makeConstantRefNode(constant="<metaclass>", source_ref=source_ref), source_ref=source_ref, ), ExpressionAttributeLookup( source=ExpressionBuiltinType1( value=ExpressionTempVariableRef( variable=tmp_prepared, source_ref=source_ref), source_ref=source_ref, ), attribute_name="__name__", source_ref=source_ref, ), ), source_ref=source_ref, ).asStatement(), source_ref=source_ref, ), ) statements += [ StatementAssignmentVariable( variable=tmp_metaclass, source=ExpressionSelectMetaclass( metaclass=ExpressionConditional( condition=ExpressionDictOperationIn( key=makeConstantRefNode( constant="metaclass", source_ref=source_ref, user_provided=True, ), dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref, ), expression_yes=ExpressionDictOperationGet( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=makeConstantRefNode( constant="metaclass", source_ref=source_ref, user_provided=True, ), source_ref=source_ref, ), expression_no=unspecified_metaclass_expression, source_ref=source_ref, ), bases=makeBasesRef(), source_ref=source_ref, ), source_ref=source_ref_orig, ), makeStatementConditional( condition=ExpressionDictOperationIn( key=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref, ), no_branch=None, yes_branch=StatementDictOperationRemove( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref, ), source_ref=source_ref, ), makeStatementConditional( condition=ExpressionAttributeCheck( object_arg=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), attribute_name="__prepare__", source_ref=source_ref, ), yes_branch=call_prepare, no_branch=StatementAssignmentVariable( variable=tmp_prepared, source=makeConstantRefNode(constant={}, source_ref=source_ref, user_provided=True), source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariableName( provider=provider, variable_name=mangleName(node.name, provider), source=decorated_body, source_ref=source_ref, ), ] if python_version >= 340: class_creation_function.qualname_setup = node.name, qualname_assign final = [tmp_class_decl_dict, tmp_metaclass, tmp_prepared] if node.bases: final.insert(0, tmp_bases) if python_version >= 370: final.insert(0, tmp_bases_orig) return makeTryFinallyStatement( provider=provider, tried=statements, final=tuple( StatementReleaseVariable(variable=variable, source_ref=source_ref) for variable in final), source_ref=source_ref, )
def _buildWithNode(provider, context_expr, assign_target, body, source_ref): with_source = buildNode(provider, context_expr, source_ref) temp_scope = provider.allocateTempScope("with") tmp_source_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="source") tmp_exit_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="exit") tmp_enter_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="enter") tmp_indicator_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="indicator") statements = (buildAssignmentStatements(provider=provider, node=assign_target, allow_none=True, source=ExpressionTempVariableRef( variable=tmp_enter_variable, source_ref=source_ref), source_ref=source_ref), body) with_body = makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref) if Options.isFullCompat() and with_body is not None: with_exit_source_ref = with_body.getStatements()[-1].\ getSourceReference() else: with_exit_source_ref = source_ref # The "__enter__" and "__exit__" were normal attribute lookups under # CPython2.6, but that changed with CPython2.7. if Utils.python_version < 270: attribute_lookup_class = ExpressionAttributeLookup else: attribute_lookup_class = ExpressionSpecialAttributeLookup statements = [ # First assign the with context to a temporary variable. StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_source_variable, source_ref=source_ref), source=with_source, source_ref=source_ref), # Next, assign "__enter__" and "__exit__" attributes to temporary # variables. StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_exit_variable, source_ref=source_ref), source=attribute_lookup_class(source=ExpressionTempVariableRef( variable=tmp_source_variable, source_ref=source_ref), attribute_name="__exit__", source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_enter_variable, source_ref=source_ref), source=ExpressionCallEmpty(called=attribute_lookup_class( source=ExpressionTempVariableRef(variable=tmp_source_variable, source_ref=source_ref), attribute_name="__enter__", source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_indicator_variable, source_ref=source_ref), source=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref), ] source_ref = source_ref.atInternal() statements += [ makeTryFinallyStatement( tried=makeTryExceptSingleHandlerNode( tried=with_body, exception_name="BaseException", handler_body=StatementsSequence( statements=( # Prevents final block from calling __exit__ as # well. StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_indicator_variable, source_ref=source_ref), source=ExpressionConstantRef( constant=False, source_ref=source_ref), source_ref=source_ref), StatementConditional( condition=ExpressionCallNoKeywords( called=ExpressionTempVariableRef( variable=tmp_exit_variable, source_ref=source_ref), args=ExpressionMakeTuple( elements=( ExpressionCaughtExceptionTypeRef( source_ref=source_ref), ExpressionCaughtExceptionValueRef( source_ref=source_ref), ExpressionCaughtExceptionTracebackRef( source_ref=source_ref), ), source_ref=source_ref), source_ref=source_ref), no_branch=makeStatementsSequenceFromStatement( statement=StatementRaiseException( exception_type=None, exception_value=None, exception_trace=None, exception_cause=None, source_ref=source_ref)), yes_branch=None, source_ref=source_ref), ), source_ref=source_ref), public_exc=Utils.python_version >= 270, source_ref=source_ref), final=StatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_indicator_variable, source_ref=source_ref), right=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=StatementExpressionOnly( expression=ExpressionCallNoKeywords( called=ExpressionTempVariableRef( variable=tmp_exit_variable, source_ref=source_ref), args=ExpressionConstantRef(constant=(None, None, None), source_ref=source_ref), source_ref=with_exit_source_ref), source_ref=source_ref)), no_branch=None, source_ref=source_ref), source_ref=source_ref) ] return makeTryFinallyStatement( tried=statements, final=( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_source_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_enter_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_exit_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_indicator_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), ), source_ref=source_ref)
def _buildClassNode3(provider, node, source_ref): # Many variables, due to the huge re-formulation that is going on here, # which just has the complexity, pylint: disable=R0914 # This function is the Python3 special case with special re-formulation as # according to developer manual. class_statements, class_doc = extractDocFromBody(node) # We need a scope for the temporary variables, and they might be closured. temp_scope = provider.allocateTempScope(name="class_creation", allow_closure=True) tmp_bases = provider.allocateTempVariable(temp_scope=temp_scope, name="bases") tmp_class_decl_dict = provider.allocateTempVariable(temp_scope=temp_scope, name="class_decl_dict") tmp_metaclass = provider.allocateTempVariable(temp_scope=temp_scope, name="metaclass") tmp_prepared = provider.allocateTempVariable(temp_scope=temp_scope, name="prepared") class_creation_function = ExpressionFunctionBody( provider=provider, is_class=True, parameters=make_class_parameters, name=node.name, doc=class_doc, source_ref=source_ref) # Hack: This allows some APIs to work although this is not yet officially a # child yet. class_creation_function.parent = provider body = buildStatementsNode(provider=class_creation_function, nodes=class_statements, frame=True, source_ref=source_ref) source_ref_orig = source_ref if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref module_variable = class_creation_function.getVariableForAssignment( "__module__") statements = [ StatementSetLocals(new_locals=ExpressionTempVariableRef( variable=tmp_prepared.makeReference(provider), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__module__", variable=module_variable, source_ref=source_ref), source=ExpressionConstantRef( constant=provider.getParentModule().getFullName(), source_ref=source_ref, user_provided=True), source_ref=source_ref) ] if class_doc is not None: doc_variable = class_creation_function.getVariableForAssignment( "__doc__") statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__doc__", variable=doc_variable, source_ref=source_ref), source=ExpressionConstantRef(constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref)) # The "__qualname__" attribute is new in Python 3.3. if Utils.python_version >= 330: qualname = class_creation_function.getFunctionQualname() qualname_variable = class_creation_function.getVariableForAssignment( "__qualname__") statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__qualname__", variable=qualname_variable, source_ref=source_ref), source=ExpressionConstantRef(constant=qualname, source_ref=source_ref, user_provided=True), source_ref=source_ref)) if Utils.python_version >= 340 and False: # TODO: Temporarily reverted: tmp_class = class_creation_function.allocateTempVariable( temp_scope=None, name="__class__") class_target_variable_ref = ExpressionTargetTempVariableRef( variable=tmp_class.makeReference(class_creation_function), source_ref=source_ref) class_variable_ref = ExpressionTempVariableRef( variable=tmp_class.makeReference(class_creation_function), source_ref=source_ref) else: class_variable = class_creation_function.getVariableForAssignment( "__class__") class_target_variable_ref = ExpressionTargetVariableRef( variable_name="__class__", variable=class_variable, source_ref=source_ref) class_variable_ref = ExpressionVariableRef(variable_name="__class__", variable=class_variable, source_ref=source_ref) statements += [ body, StatementAssignmentVariable( variable_ref=class_target_variable_ref, source=ExpressionCall( called=ExpressionTempVariableRef( variable=tmp_metaclass.makeReference(provider), source_ref=source_ref), args=makeSequenceCreationOrConstant( sequence_kind="tuple", elements=(ExpressionConstantRef(constant=node.name, source_ref=source_ref, user_provided=True), ExpressionTempVariableRef( variable=tmp_bases.makeReference(provider), source_ref=source_ref), ExpressionBuiltinLocals(source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementReturn(expression=class_variable_ref, source_ref=source_ref) ] body = makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref) # The class body is basically a function that implicitely, at the end # returns its locals and cannot have other return statements contained. class_creation_function.setBody(body) # The class body is basically a function that implicitely, at the end # returns its created class and cannot have other return statements # contained. decorated_body = ExpressionFunctionCall( function=ExpressionFunctionCreation(function_ref=ExpressionFunctionRef( function_body=class_creation_function, source_ref=source_ref), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(), source_ref=source_ref) for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): decorated_body = ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple(elements=(decorated_body, ), source_ref=source_ref), source_ref=decorator.getSourceReference()) statements = ( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_bases.makeReference(provider), source_ref=source_ref), source=makeSequenceCreationOrConstant(sequence_kind="tuple", elements=buildNodeList( provider, node.bases, source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), source=makeDictCreationOrConstant(keys=[ ExpressionConstantRef(constant=keyword.arg, source_ref=source_ref, user_provided=True) for keyword in node.keywords ], values=[ buildNode( provider, keyword.value, source_ref) for keyword in node.keywords ], lazy_order=False, source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_metaclass.makeReference(provider), source_ref=source_ref), source=ExpressionSelectMetaclass(metaclass=ExpressionConditional( condition=ExpressionComparison( comparator="In", left=ExpressionConstantRef(constant="metaclass", source_ref=source_ref, user_provided=True), right=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), source_ref=source_ref), yes_expression=ExpressionDictOperationGet( dicte=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), key=ExpressionConstantRef(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref), no_expression=ExpressionConditional( condition=ExpressionTempVariableRef( variable=tmp_bases.makeReference(provider), source_ref=source_ref), no_expression=ExpressionBuiltinRef(builtin_name="type", source_ref=source_ref), yes_expression=ExpressionBuiltinType1( value=ExpressionSubscriptLookup( expression=ExpressionTempVariableRef( variable=tmp_bases.makeReference(provider), source_ref=source_ref), subscript=ExpressionConstantRef( constant=0, source_ref=source_ref, user_provided=True), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), bases=ExpressionTempVariableRef( variable=tmp_bases. makeReference(provider), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref_orig), StatementConditional( condition=ExpressionComparison( comparator="In", left=ExpressionConstantRef(constant="metaclass", source_ref=source_ref, user_provided=True), right=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), source_ref=source_ref), no_branch=None, yes_branch=makeStatementsSequenceFromStatement( statement=StatementDictOperationRemove( dicte=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), key=ExpressionConstantRef(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref)), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_prepared.makeReference(provider), source_ref=source_ref), source=ExpressionConditional( condition=ExpressionBuiltinHasattr( object=ExpressionTempVariableRef( variable=tmp_metaclass.makeReference(provider), source_ref=source_ref), name=ExpressionConstantRef(constant="__prepare__", source_ref=source_ref, user_provided=True), source_ref=source_ref), no_expression=ExpressionConstantRef(constant={}, source_ref=source_ref, user_provided=True), yes_expression=ExpressionCall( called=ExpressionAttributeLookup( expression=ExpressionTempVariableRef( variable=tmp_metaclass.makeReference(provider), source_ref=source_ref), attribute_name="__prepare__", source_ref=source_ref), args=ExpressionMakeTuple(elements=( ExpressionConstantRef(constant=node.name, source_ref=source_ref, user_provided=True), ExpressionTempVariableRef( variable=tmp_bases.makeReference(provider), source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable(variable_ref=ExpressionTargetVariableRef( variable_name=node.name, source_ref=source_ref), source=decorated_body, source_ref=source_ref), ) final = (StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_bases.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_metaclass.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_prepared.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref)) return makeTryFinallyStatement(tried=statements, final=final, source_ref=source_ref)
def _buildClassNode2(provider, node, source_ref): class_statements, class_doc = extractDocFromBody(node) # This function is the Python3 special case with special re-formulation as according # to developer manual. # The result will be a temp block that holds the temporary variables. result = StatementTempBlock(source_ref=source_ref) tmp_bases = result.getTempVariable("bases") tmp_class_dict = result.getTempVariable("class_dict") tmp_metaclass = result.getTempVariable("metaclass") tmp_class = result.getTempVariable("class") class_creation_function = ExpressionFunctionBody( provider=provider, is_class=True, parameters=make_class_parameters, name=node.name, doc=class_doc, source_ref=source_ref) body = buildStatementsNode(provider=class_creation_function, nodes=class_statements, frame=True, source_ref=source_ref) if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref.atInternal() # The class body is basically a function that implicitely, at the end returns its # locals and cannot have other return statements contained, and starts out with a # variables "__module__" and potentially "__doc__" set. statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__module__", source_ref=source_ref), source=ExpressionConstantRef( constant=provider.getParentModule().getName(), source_ref=source_ref), source_ref=source_ref.atInternal()) ] if class_doc is not None: statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__doc__", source_ref=source_ref), source=ExpressionConstantRef(constant=class_doc, source_ref=source_ref), source_ref=source_ref.atInternal())) statements += [ body, StatementReturn( expression=ExpressionBuiltinLocals(source_ref=source_ref), source_ref=source_ref.atInternal()) ] body = makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref) # The class body is basically a function that implicitely, at the end returns its # locals and cannot have other return statements contained. class_creation_function.setBody(body) statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref), source=ExpressionMakeTuple(elements=buildNodeList( provider, node.bases, source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class_dict.makeReference(result), source_ref=source_ref), source=ExpressionFunctionCall(function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef( function_body=class_creation_function, source_ref=source_ref), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_metaclass.makeReference(result), source_ref=source_ref), source=ExpressionConditional( condition=ExpressionComparison( comparator="In", left=ExpressionConstantRef(constant="__metaclass__", source_ref=source_ref), right=ExpressionTempVariableRef( variable=tmp_class_dict.makeReference(result), source_ref=source_ref), source_ref=source_ref), yes_expression=ExpressionDictOperationGet( dicte=ExpressionTempVariableRef( variable=tmp_class_dict.makeReference(result), source_ref=source_ref), key=ExpressionConstantRef(constant="__metaclass__", source_ref=source_ref), source_ref=source_ref), no_expression=ExpressionSelectMetaclass( metaclass=None, bases=ExpressionTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class.makeReference(result), source_ref=source_ref), source=ExpressionCallNoKeywords( called=ExpressionTempVariableRef( variable=tmp_metaclass.makeReference(result), source_ref=source_ref), args=ExpressionMakeTuple(elements=( ExpressionConstantRef(constant=node.name, source_ref=source_ref), ExpressionTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref), ExpressionTempVariableRef( variable=tmp_class_dict.makeReference(result), source_ref=source_ref)), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref) ] for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class.makeReference(result), source_ref=source_ref), source=ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple( elements=(ExpressionTempVariableRef( variable=tmp_class.makeReference(result), source_ref=source_ref), ), source_ref=source_ref), source_ref=decorator.getSourceReference()), source_ref=decorator.getSourceReference())) statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef(variable_name=node.name, source_ref=source_ref), source=ExpressionTempVariableRef( variable=tmp_class.makeReference(result), source_ref=source_ref), source_ref=source_ref)) result.setBody( StatementsSequence(statements=statements, source_ref=source_ref)) return result
def _buildClassNode2(provider, node, source_ref): # This function is the Python2 special case with special re-formulation as # according to developer manual, and it's very detailed, pylint: disable=R0914 class_statement_nodes, class_doc = extractDocFromBody(node) function_body = ExpressionClassBody(provider=provider, name=node.name, doc=class_doc, flags=set(), source_ref=source_ref) code_object = CodeObjectSpec(co_name=node.name, co_kind="Class", co_varnames=(), co_argcount=0, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False) body = buildFrameNode(provider=function_body, nodes=class_statement_nodes, code_object=code_object, source_ref=source_ref) if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref.atInternal() # The class body is basically a function that implicitly, at the end # returns its locals and cannot have other return statements contained, and # starts out with a variables "__module__" and potentially "__doc__" set. statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__module__", source_ref=source_ref), source=makeConstantRefNode( constant=provider.getParentModule().getFullName(), source_ref=source_ref, user_provided=True), source_ref=source_ref.atInternal()) ] if class_doc is not None: statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__doc__", source_ref=source_ref), source=makeConstantRefNode(constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref.atInternal())) statements += [ body, StatementReturn( expression=ExpressionBuiltinLocals(source_ref=source_ref), source_ref=source_ref.atInternal()) ] body = makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref) # The class body is basically a function that implicitly, at the end # returns its locals and cannot have other return statements contained. function_body.setBody(body) temp_scope = provider.allocateTempScope("class_creation") tmp_bases = provider.allocateTempVariable(temp_scope, "bases") tmp_class_dict = provider.allocateTempVariable(temp_scope, "class_dict") tmp_metaclass = provider.allocateTempVariable(temp_scope, "metaclass") tmp_class = provider.allocateTempVariable(temp_scope, "class") statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_bases, source_ref=source_ref), source=makeSequenceCreationOrConstant(sequence_kind="tuple", elements=buildNodeList( provider, node.bases, source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class_dict, source_ref=source_ref), source=ExpressionFunctionCall(function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=function_body, source_ref=source_ref), code_object=None, defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_metaclass, source_ref=source_ref), source=ExpressionConditional( condition=ExpressionComparisonIn( left=makeConstantRefNode(constant="__metaclass__", source_ref=source_ref, user_provided=True), right=ExpressionTempVariableRef(variable=tmp_class_dict, source_ref=source_ref), source_ref=source_ref), expression_yes=ExpressionDictOperationGet( dict_arg=ExpressionTempVariableRef(variable=tmp_class_dict, source_ref=source_ref), key=makeConstantRefNode(constant="__metaclass__", source_ref=source_ref, user_provided=True), source_ref=source_ref), expression_no=ExpressionSelectMetaclass( metaclass=None, bases=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class, source_ref=source_ref), source=ExpressionCallNoKeywords( called=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), args=ExpressionMakeTuple( elements=(makeConstantRefNode(constant=node.name, source_ref=source_ref, user_provided=True), ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), ExpressionTempVariableRef( variable=tmp_class_dict, source_ref=source_ref)), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), ] for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class, source_ref=source_ref), source=ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple( elements=(ExpressionTempVariableRef( variable=tmp_class, source_ref=source_ref), ), source_ref=source_ref), source_ref=decorator.getSourceReference()), source_ref=decorator.getSourceReference())) statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef(variable_name=node.name, source_ref=source_ref), source=ExpressionTempVariableRef(variable=tmp_class, source_ref=source_ref), source_ref=source_ref)) final = (StatementReleaseVariable(variable=tmp_class, source_ref=source_ref), StatementReleaseVariable(variable=tmp_bases, source_ref=source_ref), StatementReleaseVariable(variable=tmp_class_dict, source_ref=source_ref), StatementReleaseVariable(variable=tmp_metaclass, source_ref=source_ref)) return makeTryFinallyStatement(provider=function_body, tried=statements, final=final, source_ref=source_ref)
def getClassBasesMroConversionHelper(): helper_name = "_mro_entries_conversion" result = makeInternalHelperFunctionBody( name=helper_name, parameters=ParameterSpec( ps_name=helper_name, ps_normal_args=("bases", ), ps_pos_only_args=(), ps_list_star_arg=None, ps_dict_star_arg=None, ps_default_count=0, ps_kw_only_args=(), ), ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "list") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "base") args_variable = result.getVariableForAssignment(variable_name="bases") non_type_case = makeStatementConditional( condition=ExpressionAttributeCheck( object_arg=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), attribute_name="__mro_entries__", source_ref=internal_source_ref, ), yes_branch=StatementExpressionOnly( expression=ExpressionListOperationExtend( list_arg=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), value=makeExpressionCall( called=ExpressionAttributeLookup( source=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), attribute_name="__mro_entries__", source_ref=internal_source_ref, ), args=ExpressionMakeTuple( elements=(ExpressionVariableRef( variable=args_variable, source_ref=internal_source_ref), ), source_ref=internal_source_ref, ), kw=None, source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), no_branch=StatementListOperationAppend( list_arg=ExpressionTempVariableRef(variable=tmp_result_variable, source_ref=internal_source_ref), value=ExpressionTempVariableRef(variable=tmp_item_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ) type_case = StatementListOperationAppend( list_arg=ExpressionTempVariableRef(variable=tmp_result_variable, source_ref=internal_source_ref), value=ExpressionTempVariableRef(variable=tmp_item_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ) loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried=StatementAssignmentVariable( variable=tmp_item_variable, source=ExpressionBuiltinNext1( value=ExpressionTempVariableRef( variable=tmp_iter_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), exception_name="StopIteration", handler_body=StatementLoopBreak(source_ref=internal_source_ref), source_ref=internal_source_ref, ), makeStatementConditional( condition=ExpressionBuiltinIsinstance( instance=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), classes=makeConstantRefNode(constant=type, source_ref=internal_source_ref), source_ref=internal_source_ref, ), yes_branch=type_case, no_branch=non_type_case, source_ref=internal_source_ref, ), ) final = ( StatementReleaseVariable(variable=args_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_result_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_iter_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_item_variable, source_ref=internal_source_ref), ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable=tmp_iter_variable, source=ExpressionBuiltinIter1( value=ExpressionVariableRef(variable=args_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), StatementAssignmentVariable( variable=tmp_result_variable, source=makeConstantRefNode(constant=[], source_ref=internal_source_ref), source_ref=internal_source_ref, ), StatementLoop(body=loop_body, source_ref=internal_source_ref), StatementReturn( expression=ExpressionBuiltinTuple( value=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), ) result.setBody( makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider=result, tried=tried, final=final, source_ref=internal_source_ref, ))) return result
def _buildClassNode3(provider, node, source_ref): # Many variables, due to the huge re-formulation that is going on here, # which just has the complexity, pylint: disable=R0914,R0915 # This function is the Python3 special case with special re-formulation as # according to developer manual. class_statement_nodes, class_doc = extractDocFromBody(node) # We need a scope for the temporary variables, and they might be closured. temp_scope = provider.allocateTempScope(name="class_creation", allow_closure=True) tmp_bases = provider.allocateTempVariable(temp_scope=temp_scope, name="bases") tmp_class_decl_dict = provider.allocateTempVariable(temp_scope=temp_scope, name="class_decl_dict") tmp_metaclass = provider.allocateTempVariable(temp_scope=temp_scope, name="metaclass") tmp_prepared = provider.allocateTempVariable(temp_scope=temp_scope, name="prepared") class_creation_function = ExpressionClassBody(provider=provider, name=node.name, doc=class_doc, flags=set(), source_ref=source_ref) if python_version >= 340 and False: # TODO: Temporarily reverted: tmp_class = class_creation_function.allocateTempVariable( temp_scope=None, name="__class__") class_target_variable_ref = ExpressionTargetTempVariableRef( variable=tmp_class, source_ref=source_ref) class_variable_ref = ExpressionTempVariableRef(variable=tmp_class, source_ref=source_ref) else: class_variable = class_creation_function.getVariableForAssignment( "__class__") class_target_variable_ref = ExpressionTargetVariableRef( variable_name="__class__", variable=class_variable, source_ref=source_ref) class_variable_ref = ExpressionVariableRef(variable_name="__class__", variable=class_variable, source_ref=source_ref) code_object = CodeObjectSpec(co_name=node.name, co_kind="Class", co_varnames=(), co_argcount=0, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False) body = buildFrameNode(provider=class_creation_function, nodes=class_statement_nodes, code_object=code_object, source_ref=source_ref) source_ref_orig = source_ref if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref module_variable = class_creation_function.getVariableForAssignment( "__module__") statements = [ StatementSetLocals(new_locals=ExpressionTempVariableRef( variable=tmp_prepared, source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__module__", variable=module_variable, source_ref=source_ref), source=makeConstantRefNode( constant=provider.getParentModule().getFullName(), source_ref=source_ref, user_provided=True), source_ref=source_ref) ] if class_doc is not None: doc_variable = class_creation_function.getVariableForAssignment( "__doc__") statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__doc__", variable=doc_variable, source_ref=source_ref), source=makeConstantRefNode(constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref)) # The "__qualname__" attribute is new in Python 3.3. if python_version >= 330: qualname = class_creation_function.getFunctionQualname() qualname_variable = class_creation_function.getVariableForAssignment( "__qualname__") if python_version < 340: qualname_ref = makeConstantRefNode(constant=qualname, source_ref=source_ref, user_provided=True) else: qualname_ref = ExpressionFunctionQualnameRef( function_body=class_creation_function, source_ref=source_ref, ) statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__qualname__", variable=qualname_variable, source_ref=source_ref), source=qualname_ref, source_ref=source_ref)) if python_version >= 340: qualname_assign = statements[-1] if python_version >= 360 and \ class_creation_function.needsAnnotationsDictionary(): annotations_variable = class_creation_function.getVariableForAssignment( "__annotations__") statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__annotations__", variable=annotations_variable, source_ref=source_ref), source=makeConstantRefNode(constant={}, source_ref=source_ref, user_provided=True), source_ref=source_ref)) statements.append(body) statements += [ StatementAssignmentVariable( variable_ref=class_target_variable_ref, source=ExpressionCall( called=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), args=makeSequenceCreationOrConstant( sequence_kind="tuple", elements=(makeConstantRefNode(constant=node.name, source_ref=source_ref, user_provided=True), ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), ExpressionBuiltinLocals(source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementReturn(expression=class_variable_ref, source_ref=source_ref) ] body = makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref) # The class body is basically a function that implicitly, at the end # returns its locals and cannot have other return statements contained. class_creation_function.setBody(body) class_creation_function.registerProvidedVariable(tmp_bases) class_creation_function.registerProvidedVariable(tmp_class_decl_dict) class_creation_function.registerProvidedVariable(tmp_metaclass) class_creation_function.registerProvidedVariable(tmp_prepared) # The class body is basically a function that implicitly, at the end # returns its created class and cannot have other return statements # contained. decorated_body = ExpressionFunctionCall( function=ExpressionFunctionCreation(function_ref=ExpressionFunctionRef( function_body=class_creation_function, source_ref=source_ref), code_object=code_object, defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(), source_ref=source_ref) for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): decorated_body = ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple(elements=(decorated_body, ), source_ref=source_ref), source_ref=decorator.getSourceReference()) statements = ( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_bases, source_ref=source_ref), source=makeSequenceCreationOrConstant(sequence_kind="tuple", elements=buildNodeList( provider, node.bases, source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), source=makeDictCreationOrConstant(keys=[ makeConstantRefNode(constant=keyword.arg, source_ref=source_ref, user_provided=True) for keyword in node.keywords ], values=[ buildNode( provider, keyword.value, source_ref) for keyword in node.keywords ], source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_metaclass, source_ref=source_ref), source=ExpressionSelectMetaclass(metaclass=ExpressionConditional( condition=ExpressionComparisonIn( left=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), right=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), expression_yes=ExpressionDictOperationGet( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref), expression_no=ExpressionConditional( condition=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), expression_no=ExpressionBuiltinRef(builtin_name="type", source_ref=source_ref), expression_yes=ExpressionBuiltinType1( value=ExpressionSubscriptLookup( subscribed=ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref), subscript=makeConstantRefNode( constant=0, source_ref=source_ref, user_provided=True), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), bases=ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref_orig), StatementConditional( condition=ExpressionComparisonIn( left=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), right=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), no_branch=None, yes_branch=makeStatementsSequenceFromStatement( statement=StatementDictOperationRemove( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref)), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_prepared, source_ref=source_ref), source=ExpressionConditional( condition=ExpressionBuiltinHasattr( # pylint: disable=E1120,E1123 object=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), name=makeConstantRefNode(constant="__prepare__", source_ref=source_ref, user_provided=True), source_ref=source_ref), expression_no=makeConstantRefNode(constant={}, source_ref=source_ref, user_provided=True), expression_yes=ExpressionCall( called=ExpressionAttributeLookup( source=ExpressionTempVariableRef( variable=tmp_metaclass, source_ref=source_ref), attribute_name="__prepare__", source_ref=source_ref), args=ExpressionMakeTuple( elements=(makeConstantRefNode(constant=node.name, source_ref=source_ref, user_provided=True), ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable(variable_ref=ExpressionTargetVariableRef( variable_name=node.name, source_ref=source_ref), source=decorated_body, source_ref=source_ref), ) if python_version >= 340: class_assign = statements[-1] class_creation_function.qualname_setup = class_assign, qualname_assign final = (StatementReleaseVariable(variable=tmp_bases, source_ref=source_ref), StatementReleaseVariable(variable=tmp_class_decl_dict, source_ref=source_ref), StatementReleaseVariable(variable=tmp_metaclass, source_ref=source_ref), StatementReleaseVariable(variable=tmp_prepared, source_ref=source_ref)) return makeTryFinallyStatement(provider=provider, tried=statements, final=final, source_ref=source_ref)
def buildAsyncFunctionNode(provider, node, source_ref): # We are creating a function here that creates coroutine objects, with # many details each, pylint: disable=too-many-locals assert getKind(node) == "AsyncFunctionDef" function_statement_nodes, function_doc = extractDocFromBody(node) function_kind, flags = detectFunctionBodyKind( nodes=function_statement_nodes, start_value="Coroutine") creator_function_body, _, code_object = buildFunctionWithParsing( provider=provider, function_kind=function_kind, name=node.name, flags=(), function_doc=function_doc, node=node, source_ref=source_ref) if function_kind == "Coroutine": function_body = ExpressionCoroutineObjectBody( provider=creator_function_body, name=node.name, flags=flags, source_ref=source_ref) else: function_body = ExpressionAsyncgenObjectBody( provider=creator_function_body, name=node.name, flags=flags, source_ref=source_ref) for variable in creator_function_body.getVariables(): function_body.getVariableForReference(variable.getName()) decorators = buildNodeList(provider=provider, nodes=reversed(node.decorator_list), source_ref=source_ref) defaults = buildNodeList(provider=provider, nodes=node.args.defaults, source_ref=source_ref) function_statements_body = buildFrameNode(provider=function_body, nodes=function_statement_nodes, code_object=code_object, source_ref=source_ref) function_statements_body = _insertFinalReturnStatement( function_statements_body=function_statements_body, return_statement=StatementGeneratorReturnNone(source_ref=source_ref)) if function_statements_body.isStatementsFrame(): function_statements_body = makeStatementsSequenceFromStatement( statement=function_statements_body) function_body.setBody(function_statements_body) annotations = buildParameterAnnotations(provider, node, source_ref) kw_defaults = buildParameterKwDefaults(provider=provider, node=node, function_body=creator_function_body, source_ref=source_ref) if function_kind == "Coroutine": creation_node = ExpressionMakeCoroutineObject( coroutine_ref=ExpressionFunctionRef(function_body=function_body, source_ref=source_ref), code_object=code_object, source_ref=source_ref) else: creation_node = ExpressionMakeAsyncgenObject( asyncgen_ref=ExpressionFunctionRef(function_body=function_body, source_ref=source_ref), code_object=code_object, source_ref=source_ref) creator_function_body.setBody( makeStatementsSequenceFromStatement(statement=StatementReturn( expression=creation_node, source_ref=source_ref))) function_creation = ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=creator_function_body, source_ref=source_ref), code_object=code_object, defaults=defaults, kw_defaults=kw_defaults, annotations=annotations, source_ref=source_ref) decorated_function = function_creation for decorator in decorators: decorated_function = ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple(elements=(decorated_function, ), source_ref=source_ref), source_ref=decorator.getSourceReference()) result = StatementAssignmentVariableName(variable_name=mangleName( node.name, provider), source=decorated_function, source_ref=source_ref) function_body.qualname_setup = result.getVariableName() # Share the non-local declarations. TODO: This may also apply to generators # and async generators. creator_function_body.non_local_declarations = function_body.non_local_declarations return result
def buildClassNode2(provider, node, source_ref): # This function is the Python2 special case with special re-formulation as # according to developer manual, and it's very detailed, pylint: disable=too-many-locals class_statement_nodes, class_doc = extractDocFromBody(node) function_body = ExpressionClassBody(provider=provider, name=node.name, doc=class_doc, source_ref=source_ref) parent_module = provider.getParentModule() code_object = CodeObjectSpec( co_name=node.name, co_kind="Class", co_varnames=(), co_argcount=0, co_posonlyargcount=0, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False, co_filename=parent_module.getRunTimeFilename(), co_lineno=source_ref.getLineNumber(), future_spec=parent_module.getFutureSpec(), ) body = buildFrameNode( provider=function_body, nodes=class_statement_nodes, code_object=code_object, source_ref=source_ref, ) if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref.atInternal() locals_scope = function_body.getLocalsScope() # The class body is basically a function that implicitly, at the end # returns its locals and cannot have other return statements contained, and # starts out with a variables "__module__" and potentially "__doc__" set. statements = [ StatementSetLocalsDictionary(locals_scope=locals_scope, source_ref=source_ref), StatementAssignmentVariableName( provider=function_body, variable_name="__module__", source=ExpressionModuleAttributeNameRef( variable=provider.getParentModule().getVariableForReference( "__name__"), source_ref=source_ref, ), source_ref=source_ref.atInternal(), ), ] if class_doc is not None: statements.append( StatementAssignmentVariableName( provider=function_body, variable_name="__doc__", source=makeConstantRefNode(constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref.atInternal(), )) statements += ( body, StatementReturn( expression=ExpressionBuiltinLocalsRef(locals_scope=locals_scope, source_ref=source_ref), source_ref=source_ref, ), ) body = makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement( provider=function_body, tried=mergeStatements(statements, True), final=StatementReleaseLocals(locals_scope=locals_scope, source_ref=source_ref), source_ref=source_ref, )) # The class body is basically a function that implicitly, at the end # returns its locals and cannot have other return statements contained. function_body.setBody(body) temp_scope = provider.allocateTempScope("class_creation") tmp_bases = provider.allocateTempVariable(temp_scope, "bases") tmp_class_dict = provider.allocateTempVariable(temp_scope, "class_dict") tmp_metaclass = provider.allocateTempVariable(temp_scope, "metaclass") tmp_class = provider.allocateTempVariable(temp_scope, "class") select_metaclass = ExpressionOutlineBody(provider=provider, name="select_metaclass", body=None, source_ref=source_ref) if node.bases: tmp_base = select_metaclass.allocateTempVariable(temp_scope=None, name="base") statements = ( StatementAssignmentVariable( variable=tmp_base, source=ExpressionSubscriptLookup( expression=ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref), subscript=makeConstantRefNode(constant=0, source_ref=source_ref, user_provided=True), source_ref=source_ref, ), source_ref=source_ref, ), makeTryFinallyStatement( provider, tried=StatementTry( tried=makeStatementsSequenceFromStatement( statement=StatementReturn( expression=ExpressionAttributeLookup( expression=ExpressionTempVariableRef( variable=tmp_base, source_ref=source_ref), attribute_name="__class__", source_ref=source_ref, ), source_ref=source_ref, )), except_handler=makeStatementsSequenceFromStatement( statement=StatementReturn( expression=ExpressionBuiltinType1( value=ExpressionTempVariableRef( variable=tmp_base, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, )), break_handler=None, continue_handler=None, return_handler=None, source_ref=source_ref, ), final=StatementReleaseVariable(variable=tmp_base, source_ref=source_ref), source_ref=source_ref, public_exc=False, ), ) else: statements = ( StatementTry( tried=makeStatementsSequenceFromStatement( statement=StatementReturn( # TODO: Should avoid checking __builtins__ for this. expression=ExpressionVariableNameRef( variable_name="__metaclass__", provider=parent_module, source_ref=source_ref, ), source_ref=source_ref, )), except_handler=makeStatementsSequenceFromStatement( statement=StatementReturn( expression=ExpressionBuiltinAnonymousRef( builtin_name="classobj", source_ref=source_ref), source_ref=source_ref, )), break_handler=None, continue_handler=None, return_handler=None, source_ref=source_ref, ), ) select_metaclass.setBody( makeStatementsSequence(statements=statements, allow_none=False, source_ref=source_ref)) statements = [ StatementAssignmentVariable( variable=tmp_bases, source=makeSequenceCreationOrConstant( sequence_kind="tuple", elements=buildNodeList(provider=provider, nodes=node.bases, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariable(variable=tmp_class_dict, source=function_body, source_ref=source_ref), StatementAssignmentVariable( variable=tmp_metaclass, source=ExpressionConditional( condition=ExpressionDictOperationIn( key=makeConstantRefNode( constant="__metaclass__", source_ref=source_ref, user_provided=True, ), dict_arg=ExpressionTempVariableRef(variable=tmp_class_dict, source_ref=source_ref), source_ref=source_ref, ), expression_yes=ExpressionDictOperationGet( dict_arg=ExpressionTempVariableRef(variable=tmp_class_dict, source_ref=source_ref), key=makeConstantRefNode( constant="__metaclass__", source_ref=source_ref, user_provided=True, ), source_ref=source_ref, ), expression_no=select_metaclass, source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariable( variable=tmp_class, source=makeExpressionCall( called=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), args=ExpressionMakeTuple( elements=( makeConstantRefNode( constant=node.name, source_ref=source_ref, user_provided=True, ), ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), ExpressionTempVariableRef(variable=tmp_class_dict, source_ref=source_ref), ), source_ref=source_ref, ), kw=None, source_ref=source_ref, ), source_ref=source_ref, ), ] for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): statements.append( StatementAssignmentVariable( variable=tmp_class, source=makeExpressionCall( called=decorator, args=ExpressionMakeTuple( elements=(ExpressionTempVariableRef( variable=tmp_class, source_ref=source_ref), ), source_ref=source_ref, ), kw=None, source_ref=decorator.getSourceReference(), ), source_ref=decorator.getSourceReference(), )) statements.append( StatementAssignmentVariableName( provider=provider, variable_name=mangleName(node.name, provider), source=ExpressionTempVariableRef(variable=tmp_class, source_ref=source_ref), source_ref=source_ref, )) final = ( StatementReleaseVariable(variable=tmp_class, source_ref=source_ref), StatementReleaseVariable(variable=tmp_bases, source_ref=source_ref), StatementReleaseVariable(variable=tmp_class_dict, source_ref=source_ref), StatementReleaseVariable(variable=tmp_metaclass, source_ref=source_ref), ) return makeTryFinallyStatement(provider=function_body, tried=statements, final=final, source_ref=source_ref)
def _buildClassNode3(provider, node, source_ref): # Many variables, due to the huge re-formulation that is going on here, which just has # the complexity, pylint: disable=R0914 # This function is the Python3 special case with special re-formulation as according # to developer manual. class_statements, class_doc = extractDocFromBody(node) # The result will be a temp block that holds the temporary variables. result = StatementTempBlock(source_ref=source_ref) tmp_bases = result.getTempVariable("bases") tmp_class_decl_dict = result.getTempVariable("class_decl_dict") tmp_metaclass = result.getTempVariable("metaclass") tmp_prepared = result.getTempVariable("prepared") class_creation_function = ExpressionFunctionBody( provider=provider, is_class=True, parameters=make_class_parameters, name=node.name, doc=class_doc, source_ref=source_ref) # Hack: class_creation_function.parent = provider body = buildStatementsNode(provider=class_creation_function, nodes=class_statements, frame=True, source_ref=source_ref) if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref.atInternal() statements = [ StatementSetLocals(new_locals=ExpressionTempVariableRef( variable=tmp_prepared.makeReference(result), source_ref=source_ref), source_ref=source_ref.atInternal()), StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__module__", source_ref=source_ref), source=ExpressionConstantRef( constant=provider.getParentModule().getName(), source_ref=source_ref), source_ref=source_ref.atInternal()) ] if class_doc is not None: statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__doc__", source_ref=source_ref), source=ExpressionConstantRef(constant=class_doc, source_ref=source_ref), source_ref=source_ref.atInternal())) if Utils.python_version >= 330: if provider.isExpressionFunctionBody(): qualname = provider.getName() + ".<locals>." + node.name else: qualname = node.name statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__qualname__", source_ref=source_ref), source=ExpressionConstantRef(constant=qualname, source_ref=source_ref), source_ref=source_ref.atInternal())) statements += [ body, StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef(variable_name="__class__", source_ref=source_ref), source=ExpressionCall( called=ExpressionTempVariableRef( variable=tmp_metaclass.makeReference(result), source_ref=source_ref), args=ExpressionMakeTuple( elements=(ExpressionConstantRef(constant=node.name, source_ref=source_ref), ExpressionTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref), ExpressionBuiltinLocals(source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref.atInternal()), StatementReturn(expression=ExpressionVariableRef( variable_name="__class__", source_ref=source_ref), source_ref=source_ref.atInternal()) ] body = makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref) # The class body is basically a function that implicitely, at the end returns its # locals and cannot have other return statements contained. class_creation_function.setBody(body) # The class body is basically a function that implicitely, at the end returns its # created class and cannot have other return statements contained. decorated_body = ExpressionFunctionCall( function=ExpressionFunctionCreation(function_ref=ExpressionFunctionRef( function_body=class_creation_function, source_ref=source_ref), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(), source_ref=source_ref) for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): decorated_body = ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple(elements=(decorated_body, ), source_ref=source_ref), source_ref=decorator.getSourceReference()) statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref), source=ExpressionMakeTuple(elements=buildNodeList( provider, node.bases, source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), source=ExpressionMakeDict(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 ], source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_metaclass.makeReference(result), source_ref=source_ref), source=ExpressionSelectMetaclass( metaclass=ExpressionConditional( condition=ExpressionComparison( comparator="In", left=ExpressionConstantRef(constant="metaclass", source_ref=source_ref), right=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), source_ref=source_ref), yes_expression=ExpressionDictOperationGet( dicte=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), key=ExpressionConstantRef(constant="metaclass", source_ref=source_ref), source_ref=source_ref), no_expression=ExpressionConditional( condition=ExpressionTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref), no_expression=ExpressionBuiltinRef( builtin_name="type", source_ref=source_ref), yes_expression=ExpressionBuiltinType1( value=ExpressionSubscriptLookup( expression=ExpressionTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref), subscript=ExpressionConstantRef( constant=0, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), bases=ExpressionTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementConditional( condition=ExpressionComparison( comparator="In", left=ExpressionConstantRef(constant="metaclass", source_ref=source_ref), right=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), source_ref=source_ref), no_branch=None, yes_branch=makeStatementsSequenceFromStatement( statement=StatementDictOperationRemove( dicte=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), key=ExpressionConstantRef(constant="metaclass", source_ref=source_ref), source_ref=source_ref)), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_prepared.makeReference(result), source_ref=source_ref), source=ExpressionConditional( condition=ExpressionBuiltinHasattr( object=ExpressionTempVariableRef( variable=tmp_metaclass.makeReference(result), source_ref=source_ref), name=ExpressionConstantRef(constant="__prepare__", source_ref=source_ref), source_ref=source_ref), no_expression=ExpressionConstantRef(constant={}, source_ref=source_ref), yes_expression=ExpressionCall( called=ExpressionAttributeLookup( expression=ExpressionTempVariableRef( variable=tmp_metaclass.makeReference(result), source_ref=source_ref), attribute_name="__prepare__", source_ref=source_ref), args=ExpressionMakeTuple( elements=(ExpressionConstantRef(constant=node.name, source_ref=source_ref), ExpressionTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable(variable_ref=ExpressionTargetVariableRef( variable_name=node.name, source_ref=source_ref), source=decorated_body, source_ref=source_ref) ] result.setBody( StatementsSequence(statements=statements, source_ref=source_ref)) return result
def _buildWithNode(provider, context_expr, assign_target, body, body_lineno, sync, source_ref): # Many details, pylint: disable=too-many-locals with_source = buildNode(provider, context_expr, source_ref) if Options.isFullCompat(): source_ref = with_source.getCompatibleSourceReference() temp_scope = provider.allocateTempScope("with") tmp_source_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "source" ) tmp_exit_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "exit" ) tmp_enter_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "enter" ) tmp_indicator_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "indicator" ) statements = ( buildAssignmentStatements( provider = provider, node = assign_target, allow_none = True, source = ExpressionTempVariableRef( variable = tmp_enter_variable, source_ref = source_ref ), source_ref = source_ref ), body ) with_body = makeStatementsSequence( statements = statements, allow_none = True, source_ref = source_ref ) if Options.isFullCompat(): if body: deepest = body while deepest.getVisitableNodes(): deepest = deepest.getVisitableNodes()[-1] body_lineno = deepest.getCompatibleSourceReference().getLineNumber() with_exit_source_ref = source_ref.atLineNumber(body_lineno) else: with_exit_source_ref = source_ref # The "__enter__" and "__exit__" were normal attribute lookups under # CPython2.6, but that changed with CPython2.7. if python_version < 270: attribute_lookup_class = ExpressionAttributeLookup else: attribute_lookup_class = ExpressionAttributeLookupSpecial enter_value = ExpressionCallEmpty( called = attribute_lookup_class( source = ExpressionTempVariableRef( variable = tmp_source_variable, source_ref = source_ref ), attribute_name = "__enter__" if sync else "__aenter__", source_ref = source_ref ), source_ref = source_ref ) exit_value_exception = ExpressionCallNoKeywords( called = ExpressionTempVariableRef( variable = tmp_exit_variable, source_ref = with_exit_source_ref ), args = ExpressionMakeTuple( elements = ( ExpressionCaughtExceptionTypeRef( source_ref = with_exit_source_ref ), ExpressionCaughtExceptionValueRef( source_ref = with_exit_source_ref ), ExpressionCaughtExceptionTracebackRef( source_ref = source_ref ), ), source_ref = source_ref ), source_ref = with_exit_source_ref ) exit_value_no_exception = ExpressionCallNoKeywords( called = ExpressionTempVariableRef( variable = tmp_exit_variable, source_ref = source_ref ), args = makeConstantRefNode( constant = (None, None, None), source_ref = source_ref ), source_ref = with_exit_source_ref ) # For "async with", await the entered value and exit value must be awaited. if not sync: enter_value = ExpressionAsyncWait( expression = enter_value, source_ref = source_ref ) exit_value_exception = ExpressionAsyncWait( expression = exit_value_exception, source_ref = source_ref ) exit_value_no_exception = ExpressionAsyncWait( expression = exit_value_no_exception, source_ref = source_ref ) statements = [ # First assign the with context to a temporary variable. StatementAssignmentVariable( variable = tmp_source_variable, source = with_source, source_ref = source_ref ) ] attribute_assignments = [ # Next, assign "__enter__" and "__exit__" attributes to temporary # variables. StatementAssignmentVariable( variable = tmp_exit_variable, source = attribute_lookup_class( source = ExpressionTempVariableRef( variable = tmp_source_variable, source_ref = source_ref ), attribute_name = "__exit__" if sync else "__aexit__", source_ref = source_ref ), source_ref = source_ref ), StatementAssignmentVariable( variable = tmp_enter_variable, source = enter_value, source_ref = source_ref ) ] if python_version >= 360 and sync: attribute_assignments.reverse() statements += attribute_assignments statements.append( StatementAssignmentVariable( variable = tmp_indicator_variable, source = makeConstantRefNode( constant = True, source_ref = source_ref ), source_ref = source_ref ) ) statements += [ makeTryFinallyStatement( provider = provider, tried = makeTryExceptSingleHandlerNodeWithPublish( provider = provider, tried = with_body, exception_name = "BaseException", handler_body = StatementsSequence( statements = ( # Prevents final block from calling __exit__ as # well. StatementAssignmentVariable( variable = tmp_indicator_variable, source = makeConstantRefNode( constant = False, source_ref = source_ref ), source_ref = source_ref ), makeConditionalStatement( condition = exit_value_exception, no_branch = makeReraiseExceptionStatement( source_ref = with_exit_source_ref ), yes_branch = None, source_ref = with_exit_source_ref ), ), source_ref = source_ref ), public_exc = python_version >= 270, source_ref = source_ref ), final = StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = tmp_indicator_variable, source_ref = source_ref ), right = makeConstantRefNode( constant = True, source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( statement = StatementExpressionOnly( expression = exit_value_no_exception, source_ref = source_ref ) ), no_branch = None, source_ref = source_ref ), source_ref = source_ref ) ] return makeTryFinallyStatement( provider = provider, tried = statements, final = ( StatementReleaseVariable( variable = tmp_source_variable, source_ref = with_exit_source_ref ), StatementReleaseVariable( variable = tmp_enter_variable, source_ref = with_exit_source_ref ), StatementReleaseVariable( variable = tmp_exit_variable, source_ref = with_exit_source_ref ), StatementReleaseVariable( variable = tmp_indicator_variable, source_ref = with_exit_source_ref ), ), source_ref = source_ref )
def _makeCallNode( provider, called, positional_args, pairs, list_star_arg, dict_star_arg, source_ref ): # Many variables, but only to cover the many complex call cases. # pylint: disable=R0914 if list_star_arg is None and dict_star_arg is None: return ExpressionCall( called = called, args = ExpressionMakeTuple( elements = positional_args, source_ref = source_ref ), kw = ExpressionMakeDict( pairs = pairs, source_ref = source_ref ), source_ref = source_ref, ) else: # Dispatch to complex helper function for each case. These do # re-formulation of complex calls according to developer manual. key = len( positional_args ) > 0, len( pairs ) > 0, list_star_arg is not None, dict_star_arg is not None from .ComplexCallHelperFunctions import ( getFunctionCallHelperPosKeywordsStarList, getFunctionCallHelperPosStarList, getFunctionCallHelperKeywordsStarList, getFunctionCallHelperStarList, getFunctionCallHelperPosKeywordsStarDict, getFunctionCallHelperPosStarDict, getFunctionCallHelperKeywordsStarDict, getFunctionCallHelperStarDict, getFunctionCallHelperPosKeywordsStarListStarDict, getFunctionCallHelperPosStarListStarDict, getFunctionCallHelperKeywordsStarListStarDict, getFunctionCallHelperStarListStarDict, ) table = { ( True, True, True, False ) : getFunctionCallHelperPosKeywordsStarList, ( True, False, True, False ) : getFunctionCallHelperPosStarList, ( False, True, True, False ) : getFunctionCallHelperKeywordsStarList, ( False, False, True, False ) : getFunctionCallHelperStarList, ( True, True, False, True ) : getFunctionCallHelperPosKeywordsStarDict, ( True, False, False, True ) : getFunctionCallHelperPosStarDict, ( False, True, False, True ) : getFunctionCallHelperKeywordsStarDict, ( False, False, False, True ) : getFunctionCallHelperStarDict, ( True, True, True, True ) : getFunctionCallHelperPosKeywordsStarListStarDict, ( True, False, True, True ) : getFunctionCallHelperPosStarListStarDict, ( False, True, True, True ) : getFunctionCallHelperKeywordsStarListStarDict, ( False, False, True, True ) : getFunctionCallHelperStarListStarDict, } get_helper = table[ key ] helper_args = [ called ] if positional_args: helper_args.append( ExpressionMakeTuple( elements = positional_args, source_ref = source_ref ) ) if pairs: helper_args.append( ExpressionMakeDict( pairs = pairs, source_ref = source_ref ) ) if list_star_arg is not None: helper_args.append( list_star_arg ) if dict_star_arg is not None: helper_args.append( dict_star_arg ) return ExpressionFunctionCall( function = ExpressionFunctionCreation( function_ref = ExpressionFunctionRef( function_body = get_helper(), source_ref = source_ref ), defaults = (), kw_defaults = None, annotations = None, source_ref = source_ref ), values = helper_args, source_ref = source_ref, )