Exemple #1
0
    def buildVariableReferenceNode(provider, node, source_ref):
        # Shortcut for Python3, which gives syntax errors for assigning these.
        if node.id in quick_names:
            return makeConstantRefNode(constant=quick_names[node.id],
                                       source_ref=source_ref)

        return ExpressionVariableNameRef(
            provider=provider,
            variable_name=mangleName(node.id, provider),
            source_ref=source_ref,
        )
Exemple #2
0
def _buildInplaceAssignVariableNode(variable_name, operator, expression,
                                    source_ref):
    inplace_node = makeExpressionOperationBinaryInplace(
        operator=operator,
        left=ExpressionVariableNameRef(variable_name=variable_name,
                                       source_ref=source_ref),
        right=expression,
        source_ref=source_ref)

    inplace_node.markAsInplaceSuspect()

    return (StatementAssignmentVariableName(variable_name=variable_name,
                                            source=inplace_node,
                                            source_ref=source_ref), )
Exemple #3
0
def createImporterCacheAssignment(package, source_ref):
    return StatementDictOperationSet(
        dict_arg=ExpressionImportModuleNameHard(
            module_name="sys", import_name="path_importer_cache", source_ref=source_ref
        ),
        key=ExpressionSubscriptLookup(
            expression=ExpressionVariableNameRef(
                provider=package, variable_name="__path__", source_ref=source_ref
            ),
            subscript=makeConstantRefNode(constant=0, source_ref=source_ref),
            source_ref=source_ref,
        ),
        value=ExpressionNuitkaLoaderCreation(provider=package, source_ref=source_ref),
        source_ref=source_ref,
    )
def _wrapFunctionWithSpecialNestedArgs(
    name, outer_body, parameters, special_args, source_ref
):
    inner_name = name.strip("<>") + "$inner"
    iter_vars = []

    values = []

    statements = []

    def unpackFrom(source, arg_names):
        accesses = []

        sub_special_index = 0

        iter_var = outer_body.allocateTempVariable(None, "arg_iter_%d" % len(iter_vars))
        iter_vars.append(iter_var)

        statements.append(
            StatementAssignmentVariable(
                variable=iter_var,
                source=ExpressionBuiltinIter1(value=source, source_ref=source_ref),
                source_ref=source_ref,
            )
        )

        for element_index, arg_name in enumerate(arg_names):
            if getKind(arg_name) == "Name":
                arg_var = outer_body.createProvidedVariable(arg_name.id)
                outer_body.getLocalsScope().registerProvidedVariable(arg_var)

                statements.append(
                    StatementAssignmentVariable(
                        variable=arg_var,
                        source=ExpressionSpecialUnpack(
                            value=ExpressionTempVariableRef(
                                variable=iter_var, source_ref=source_ref
                            ),
                            count=element_index + 1,
                            expected=len(arg_names),
                            starred=False,
                            source_ref=source_ref,
                        ),
                        source_ref=source_ref,
                    )
                )

                accesses.append(
                    ExpressionVariableRef(variable=arg_var, source_ref=source_ref)
                )
            elif getKind(arg_name) == "Tuple":
                accesses.extend(
                    unpackFrom(
                        source=ExpressionSpecialUnpack(
                            value=ExpressionTempVariableRef(
                                variable=iter_var, source_ref=source_ref
                            ),
                            count=element_index + 1,
                            expected=len(arg_names),
                            starred=False,
                            source_ref=source_ref,
                        ),
                        arg_names=arg_name.elts,
                    )
                )

                sub_special_index += 1
            else:
                assert False, arg_name

        statements.append(
            StatementSpecialUnpackCheck(
                iterator=ExpressionTempVariableRef(
                    variable=iter_var, source_ref=source_ref
                ),
                count=len(arg_names),
                source_ref=source_ref,
            )
        )

        return accesses

    for arg_name in parameters.getParameterNames():
        if arg_name.startswith("."):
            source = ExpressionVariableNameRef(
                provider=outer_body, variable_name=arg_name, source_ref=source_ref
            )

            values.extend(unpackFrom(source, special_args[arg_name]))
        else:
            values.append(
                ExpressionVariableNameRef(
                    provider=outer_body, variable_name=arg_name, source_ref=source_ref
                )
            )

    code_body = ExpressionOutlineFunction(
        provider=outer_body, name=inner_name, source_ref=source_ref
    )

    statements.append(StatementReturn(expression=code_body, source_ref=source_ref))

    outer_body.setChild(
        "body",
        makeStatementsSequenceFromStatement(
            statement=makeTryFinallyStatement(
                provider=outer_body,
                tried=statements,
                final=[
                    StatementReleaseVariable(variable=variable, source_ref=source_ref)
                    for variable in sorted(
                        outer_body.getTempVariables(),
                        key=lambda variable: variable.getName(),
                    )
                ],
                source_ref=source_ref,
                public_exc=False,
            )
        ),
    )

    return code_body
Exemple #5
0
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)
Exemple #6
0
def buildVariableReferenceNode(provider, node, source_ref):
    return ExpressionVariableNameRef(variable_name=mangleName(
        node.id, provider),
                                     provider=provider,
                                     source_ref=source_ref)
Exemple #7
0
def buildParseTree(provider, source_code, source_ref, is_module, is_main):
    # There are a bunch of branches here, mostly to deal with version
    # differences for module default variables. pylint: disable=too-many-branches

    pushFutureSpec()
    if is_module:
        provider.future_spec = getFutureSpec()

    body = parseSourceCodeToAst(
        source_code=source_code,
        filename=source_ref.getFilename(),
        line_offset=source_ref.getLineNumber() - 1,
    )

    body, doc = extractDocFromBody(body)

    if is_module and is_main and python_version >= 360:
        provider.markAsNeedsAnnotationsDictionary()

    result = buildStatementsNode(provider=provider, nodes=body, source_ref=source_ref)

    checkFutureImportsOnlyAtStart(body)

    internal_source_ref = source_ref.atInternal()

    statements = []

    if is_module:
        # Add import of "site" module of main programs visibly in the node tree,
        # so recursion and optimization can pick it up, checking its effects.
        if is_main and "no_site" not in Options.getPythonFlags():
            for path_imported_name in getPthImportedPackages():
                statements.append(
                    StatementExpressionOnly(
                        expression=makeAbsoluteImportNode(
                            module_name=path_imported_name, source_ref=source_ref
                        ),
                        source_ref=source_ref,
                    )
                )

            statements.append(
                StatementExpressionOnly(
                    expression=makeAbsoluteImportNode(
                        module_name="site", source_ref=source_ref
                    ),
                    source_ref=source_ref,
                )
            )

        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__doc__",
                source=makeConstantRefNode(
                    constant=doc, source_ref=internal_source_ref, user_provided=True
                ),
                source_ref=internal_source_ref,
            )
        )

        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__file__",
                source=ExpressionModuleAttributeFileRef(
                    variable=provider.getVariableForReference("__file__"),
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref,
            )
        )

        if provider.isCompiledPythonPackage():
            # This assigns "__path__" value.
            statements.append(createPathAssignment(provider, internal_source_ref))
            statements.append(
                createImporterCacheAssignment(provider, internal_source_ref)
            )

        if python_version >= 340 and not is_main:
            statements += (
                StatementAssignmentAttribute(
                    expression=ExpressionModuleAttributeSpecRef(
                        variable=provider.getVariableForReference("__spec__"),
                        source_ref=internal_source_ref,
                    ),
                    attribute_name="origin",
                    source=ExpressionModuleAttributeFileRef(
                        variable=provider.getVariableForReference("__file__"),
                        source_ref=internal_source_ref,
                    ),
                    source_ref=internal_source_ref,
                ),
                StatementAssignmentAttribute(
                    expression=ExpressionModuleAttributeSpecRef(
                        variable=provider.getVariableForReference("__spec__"),
                        source_ref=internal_source_ref,
                    ),
                    attribute_name="has_location",
                    source=makeConstantRefNode(True, internal_source_ref),
                    source_ref=internal_source_ref,
                ),
            )

            if provider.isCompiledPythonPackage():
                statements.append(
                    StatementAssignmentAttribute(
                        expression=ExpressionModuleAttributeSpecRef(
                            variable=provider.getVariableForReference("__spec__"),
                            source_ref=internal_source_ref,
                        ),
                        attribute_name="submodule_search_locations",
                        source=ExpressionVariableNameRef(
                            provider=provider,
                            variable_name="__path__",
                            source_ref=internal_source_ref,
                        ),
                        source_ref=internal_source_ref,
                    )
                )

    if python_version >= 300:
        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__cached__",
                source=ExpressionConstantNoneRef(source_ref=internal_source_ref),
                source_ref=internal_source_ref,
            )
        )

    needs__initializing__ = not provider.isMainModule() and 300 <= python_version < 340

    if needs__initializing__:
        # Set "__initializing__" at the beginning to True
        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__initializing__",
                source=makeConstantRefNode(
                    constant=True, source_ref=internal_source_ref, user_provided=True
                ),
                source_ref=internal_source_ref,
            )
        )

    if provider.needsAnnotationsDictionary():
        # Set "__annotations__" on module level to {}
        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__annotations__",
                source=makeConstantRefNode(
                    constant={}, source_ref=internal_source_ref, user_provided=True
                ),
                source_ref=internal_source_ref,
            )
        )

    # Now the module body if there is any at all.
    if result is not None:
        statements.extend(result.getStatements())

    if needs__initializing__:
        # Set "__initializing__" at the end to False
        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__initializing__",
                source=makeConstantRefNode(
                    constant=False, source_ref=internal_source_ref, user_provided=True
                ),
                source_ref=internal_source_ref,
            )
        )

    if is_module:
        result = makeModuleFrame(
            module=provider, statements=statements, source_ref=source_ref
        )

        popFutureSpec()

        return result
    else:
        assert False
def buildFunctionWithParsing(provider, function_kind, name, function_doc,
                             flags, node, source_ref):
    # This contains a complex re-formulation for nested parameter functions.
    # pylint: disable=too-many-locals

    kind = getKind(node)
    assert kind in ("FunctionDef", "Lambda",
                    "AsyncFunctionDef"), "unsupported for kind " + kind

    def extractArg(arg):
        if arg is None:
            return None
        elif type(arg) is str:
            return mangleName(arg, provider)
        elif getKind(arg) == "Name":
            return mangleName(arg.id, provider)
        elif getKind(arg) == "arg":
            return mangleName(arg.arg, provider)
        elif getKind(arg) == "Tuple":
            # These are to be re-formulated on the outside.
            assert False
        else:
            assert False, getKind(arg)

    special_args = {}

    def extractNormalArgs(args):
        normal_args = []

        for arg in args:
            if type(arg) is not str and getKind(arg) == "Tuple":
                special_arg_name = ".%d" % (len(special_args) + 1)

                special_args[special_arg_name] = arg.elts
                normal_args.append(special_arg_name)
            else:
                normal_args.append(extractArg(arg))

        return normal_args

    normal_args = extractNormalArgs(node.args.args)

    parameters = ParameterSpec(
        ps_name=name,
        ps_normal_args=normal_args,
        ps_kw_only_args=[extractArg(arg) for arg in node.args.kwonlyargs]
        if python_version >= 300 else [],
        ps_list_star_arg=extractArg(node.args.vararg),
        ps_dict_star_arg=extractArg(node.args.kwarg),
        ps_default_count=len(node.args.defaults))

    message = parameters.checkParametersValid()

    if message is not None:
        raiseSyntaxError(
            message,
            source_ref.atColumnNumber(node.col_offset),
        )

    parent_module = provider.getParentModule()

    code_object = CodeObjectSpec(
        co_name=name,
        co_kind=function_kind,
        co_varnames=parameters.getParameterNames(),
        co_argcount=parameters.getArgumentCount(),
        co_kwonlyargcount=parameters.getKwOnlyParameterCount(),
        co_has_starlist=parameters.getStarListArgumentName() is not None,
        co_has_stardict=parameters.getStarDictArgumentName() is not None,
        co_filename=parent_module.getRunTimeFilename(),
        co_lineno=source_ref.getLineNumber(),
        future_spec=parent_module.getFutureSpec())

    outer_body = ExpressionFunctionBody(provider=provider,
                                        name=name,
                                        flags=flags,
                                        doc=function_doc,
                                        parameters=parameters,
                                        source_ref=source_ref)

    if special_args:
        inner_name = name.strip("<>") + "$inner"
        iter_vars = []

        values = []

        statements = []

        def unpackFrom(source, arg_names):
            accesses = []

            sub_special_index = 0

            iter_var = outer_body.allocateTempVariable(
                None, "arg_iter_%d" % len(iter_vars))
            iter_vars.append(iter_var)

            statements.append(
                StatementAssignmentVariable(variable=iter_var,
                                            source=ExpressionBuiltinIter1(
                                                value=source,
                                                source_ref=source_ref),
                                            source_ref=source_ref))

            for element_index, arg_name in enumerate(arg_names):
                if getKind(arg_name) == "Name":
                    arg_var = outer_body.createProvidedVariable(arg_name.id)
                    outer_body.registerProvidedVariable(arg_var)

                    statements.append(
                        StatementAssignmentVariable(
                            variable=arg_var,
                            source=ExpressionSpecialUnpack(
                                value=ExpressionTempVariableRef(
                                    variable=iter_var, source_ref=source_ref),
                                count=element_index + 1,
                                expected=len(arg_names),
                                source_ref=source_ref),
                            source_ref=source_ref))

                    accesses.append(
                        ExpressionVariableRef(variable=arg_var,
                                              source_ref=source_ref))
                elif getKind(arg_name) == "Tuple":
                    accesses.extend(
                        unpackFrom(source=ExpressionSpecialUnpack(
                            value=ExpressionTempVariableRef(
                                variable=iter_var, source_ref=source_ref),
                            count=element_index + 1,
                            expected=len(arg_names),
                            source_ref=source_ref),
                                   arg_names=arg_name.elts))

                    sub_special_index += 1
                else:
                    assert False, arg_name

            statements.append(
                StatementSpecialUnpackCheck(iterator=ExpressionTempVariableRef(
                    variable=iter_var, source_ref=source_ref),
                                            count=len(arg_names),
                                            source_ref=source_ref))

            return accesses

        for arg_name in parameters.getParameterNames():
            if arg_name.startswith('.'):
                source = ExpressionVariableNameRef(provider=outer_body,
                                                   variable_name=arg_name,
                                                   source_ref=source_ref)

                values.extend(unpackFrom(source, special_args[arg_name]))
            else:
                values.append(
                    ExpressionVariableNameRef(provider=outer_body,
                                              variable_name=arg_name,
                                              source_ref=source_ref))

        code_body = ExpressionOutlineFunction(provider=outer_body,
                                              name=inner_name,
                                              source_ref=source_ref)

        statements.append(
            StatementReturn(expression=code_body, source_ref=source_ref))

        outer_body.setBody(
            makeStatementsSequenceFromStatement(
                statement=makeTryFinallyStatement(
                    provider=outer_body,
                    tried=statements,
                    final=[
                        StatementReleaseVariable(variable=variable,
                                                 source_ref=source_ref)
                        for variable in sorted(
                            outer_body.getTempVariables(),
                            key=lambda variable: variable.getName())
                    ],
                    source_ref=source_ref,
                    public_exc=False)))
    else:
        code_body = outer_body

    return outer_body, code_body, code_object
Exemple #9
0
def buildParseTree(provider, ast_tree, source_ref, is_module, is_main):
    # There are a bunch of branches here, mostly to deal with version
    # differences for module default variables. pylint: disable=too-many-branches

    # Maybe one day, we do exec inlining again, that is what this is for,
    # then is_module won't be True, for now it always is.
    pushFutureSpec()
    if is_module:
        provider.setFutureSpec(getFutureSpec())

    body, doc = extractDocFromBody(ast_tree)

    if is_module and is_main and python_version >= 0x360:
        provider.markAsNeedsAnnotationsDictionary()

    result = buildStatementsNode(provider=provider,
                                 nodes=body,
                                 source_ref=source_ref)

    # After building, we can verify that all future statements were where they
    # belong, namely at the start of the module.
    checkFutureImportsOnlyAtStart(body)

    internal_source_ref = source_ref.atInternal()

    statements = []

    if is_module:
        # Add import of "site" module of main programs visibly in the node tree,
        # so recursion and optimization can pick it up, checking its effects.
        if is_main and not Options.hasPythonFlagNoSite():
            statements.append(
                StatementExpressionOnly(
                    expression=makeExpressionImportModuleFixed(
                        module_name="site", source_ref=source_ref),
                    source_ref=source_ref,
                ))

            for path_imported_name in getPthImportedPackages():
                if isHardModuleWithoutSideEffect(path_imported_name):
                    continue

                statements.append(
                    StatementExpressionOnly(
                        expression=makeExpressionImportModuleFixed(
                            module_name=path_imported_name,
                            source_ref=source_ref),
                        source_ref=source_ref,
                    ))

        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__doc__",
                source=makeConstantRefNode(constant=doc,
                                           source_ref=internal_source_ref,
                                           user_provided=True),
                source_ref=internal_source_ref,
            ))

        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__file__",
                source=ExpressionModuleAttributeFileRef(
                    variable=provider.getVariableForReference("__file__"),
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref,
            ))

        if provider.isCompiledPythonPackage():
            # This assigns "__path__" value.
            statements.append(
                createPathAssignment(provider, internal_source_ref))
            statements.append(
                createImporterCacheAssignment(provider, internal_source_ref))

        if python_version >= 0x340 and not is_main:
            statements += (
                StatementAssignmentAttribute(
                    expression=ExpressionModuleAttributeSpecRef(
                        variable=provider.getVariableForReference("__spec__"),
                        source_ref=internal_source_ref,
                    ),
                    attribute_name="origin",
                    source=ExpressionModuleAttributeFileRef(
                        variable=provider.getVariableForReference("__file__"),
                        source_ref=internal_source_ref,
                    ),
                    source_ref=internal_source_ref,
                ),
                StatementAssignmentAttribute(
                    expression=ExpressionModuleAttributeSpecRef(
                        variable=provider.getVariableForReference("__spec__"),
                        source_ref=internal_source_ref,
                    ),
                    attribute_name="has_location",
                    source=makeConstantRefNode(True, internal_source_ref),
                    source_ref=internal_source_ref,
                ),
            )

            if provider.isCompiledPythonPackage():
                statements.append(
                    StatementAssignmentAttribute(
                        expression=ExpressionModuleAttributeSpecRef(
                            variable=provider.getVariableForReference(
                                "__spec__"),
                            source_ref=internal_source_ref,
                        ),
                        attribute_name="submodule_search_locations",
                        source=ExpressionVariableNameRef(
                            provider=provider,
                            variable_name="__path__",
                            source_ref=internal_source_ref,
                        ),
                        source_ref=internal_source_ref,
                    ))

    if python_version >= 0x300:
        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__cached__",
                source=ExpressionConstantNoneRef(
                    source_ref=internal_source_ref),
                source_ref=internal_source_ref,
            ))

    needs__initializing__ = (not provider.isMainModule()
                             and 0x300 <= python_version < 0x340)

    if needs__initializing__:
        # Set "__initializing__" at the beginning to True
        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__initializing__",
                source=makeConstantRefNode(constant=True,
                                           source_ref=internal_source_ref,
                                           user_provided=True),
                source_ref=internal_source_ref,
            ))

    if provider.needsAnnotationsDictionary():
        # Set "__annotations__" on module level to {}
        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__annotations__",
                source=makeConstantRefNode(constant={},
                                           source_ref=internal_source_ref,
                                           user_provided=True),
                source_ref=internal_source_ref,
            ))

    # Now the module body if there is any at all.
    if result is not None:
        statements.extend(result.subnode_statements)

    if needs__initializing__:
        # Set "__initializing__" at the end to False
        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__initializing__",
                source=makeConstantRefNode(constant=False,
                                           source_ref=internal_source_ref,
                                           user_provided=True),
                source_ref=internal_source_ref,
            ))

    if is_module:
        result = makeModuleFrame(module=provider,
                                 statements=statements,
                                 source_ref=source_ref)

        popFutureSpec()

        return result
    else:
        assert False
def buildAnnAssignNode(provider, node, source_ref):
    """ Python3.6 annotation assignment.

    """

    if provider.isCompiledPythonModule() or provider.isExpressionClassBody():
        provider.markAsNeedsAnnotationsDictionary()

    # Evaluate the right hand side first, so it can get names provided
    # before the left hand side exists.
    statements = []

    if node.value is not None:
        source = buildNode(provider, node.value, source_ref)

        statements.append(
            buildAssignmentStatements(provider=provider,
                                      node=node.target,
                                      source=source,
                                      source_ref=source_ref))

        # Only name referencing annotations are effective right now.
        if statements[-1].isStatementAssignmentVariableName():
            variable_name = statements[-1].getVariableName()
        else:
            variable_name = None
    else:
        # Only name referencing annotations are effective right now.
        kind, detail = decodeAssignTarget(provider=provider,
                                          node=node.target,
                                          source_ref=source_ref)

        if kind == "Name":
            variable_name = detail
        else:
            variable_name = None

    # Only annotations for modules and classes are really made, for functions
    # they are ignored like comments.
    if variable_name is not None:
        if provider.isExpressionFunctionBody():
            if node.simple:
                provider.getVariableForAssignment(variable_name)
        else:
            annotation = buildNode(provider, node.annotation, source_ref)

            statements.append(
                StatementAssignmentSubscript(
                    # TODO: Use ExpressionVariableLocalNameRef once they work better.
                    expression=ExpressionVariableNameRef(
                        provider=provider,
                        variable_name="__annotations__",
                        source_ref=source_ref),
                    subscript=makeConstantRefNode(constant=variable_name,
                                                  source_ref=source_ref),
                    source=annotation,
                    source_ref=source_ref))

    return makeStatementsSequence(statements=statements,
                                  allow_none=True,
                                  source_ref=source_ref)