Esempio n. 1
0
def buildImportModulesNode(provider, node, source_ref):
    # Import modules statement. As described in the developer manual, these
    # statements can be treated as several ones.

    import_names = [(import_desc.name, import_desc.asname)
                    for import_desc in node.names]

    import_nodes = []

    for import_desc in import_names:
        module_name, local_name = import_desc

        module_topname = module_name.split('.')[0]

        # Note: The "level" of import is influenced by the future absolute
        # imports.
        level = 0 if source_ref.getFutureSpec().isAbsoluteImport() else -1

        if local_name:
            # If is gets a local name, the real name must be used as a
            # temporary value only, being looked up recursively.

            import_node = ExpressionImportModule(module_name=module_name,
                                                 import_list=None,
                                                 level=level,
                                                 source_ref=source_ref)

            for import_name in module_name.split('.')[1:]:
                import_node = ExpressionImportName(module=import_node,
                                                   import_name=import_name,
                                                   source_ref=source_ref)
        else:
            import_node = ExpressionImportModule(module_name=module_name,
                                                 import_list=None,
                                                 level=level,
                                                 source_ref=source_ref)

        # If a name was given, use the one provided, otherwise the import gives
        # the top level package name given for assignment of the imported
        # module.

        import_nodes.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetVariableRef(
                    variable_name=mangleName(
                        local_name if local_name is not None else
                        module_topname, provider),
                    source_ref=source_ref),
                source=import_node,
                source_ref=source_ref))

    # Note: Each import is sequential. It will potentially succeed, and the
    # failure of a later one is not changing that one bit . We can therefore
    # have a sequence of imports that only import one thing therefore.
    return makeStatementsSequenceOrStatement(statements=import_nodes,
                                             source_ref=source_ref)
Esempio n. 2
0
def buildImportModulesNode(node, source_ref):
    # Import modules statement. As described in the developer manual, these statements can
    # be treated as several ones.

    import_names = [(import_desc.name, import_desc.asname)
                    for import_desc in node.names]

    import_nodes = []

    for import_desc in import_names:
        module_name, local_name = import_desc

        module_topname = module_name.split(".")[0]

        # Note: The "level" of import is influenced by the future absolute imports.
        level = 0 if source_ref.getFutureSpec().isAbsoluteImport() else -1

        if local_name:
            import_node = ExpressionImportModule(module_name=module_name,
                                                 import_list=None,
                                                 level=level,
                                                 source_ref=source_ref)

            for import_name in module_name.split(".")[1:]:
                import_node = ExpressionImportName(module=import_node,
                                                   import_name=import_name,
                                                   source_ref=source_ref)
        else:
            import_node = ExpressionImportModule(module_name=module_name,
                                                 import_list=None,
                                                 level=level,
                                                 source_ref=source_ref)

        # If a name was given, use the one provided, otherwise the import gives the top
        # level package name given for assignment of the imported module.

        import_nodes.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetVariableRef(
                    variable_name=local_name
                    if local_name is not None else module_topname,
                    source_ref=source_ref),
                source=import_node,
                source_ref=source_ref))

    # Note: Each import is sequential. It can succeed, and the failure of a later one is
    # not changing one. We can therefore have a sequence of imports that only import one
    # thing therefore.
    return makeStatementsSequenceOrStatement(statements=import_nodes,
                                             source_ref=source_ref)
Esempio n. 3
0
def createPython3NamespacePath(package_name, module_relpath, source_ref):
    return StatementAssignmentVariable(
        variable_ref = ExpressionTargetVariableRef(
            variable_name = "__path__",
            source_ref    = source_ref
        ),
        source       = ExpressionCallNoKeywords(
            called     = ExpressionImportName(
                module      = ExpressionImportModule(
                    module_name = "_frozen_importlib"
                                    if python_version < 350 else
                                  "_frozen_importlib_external",
                    import_list = (),
                    level       = 0,
                    source_ref  = source_ref
                ),
                import_name = "_NamespacePath",
                source_ref  = source_ref
            ),
            args       = makeConstantRefNode(
                constant   = (
                    package_name,
                    [module_relpath],
                    None
                ),
                source_ref =  source_ref
            ),
            source_ref =  source_ref
        ),
        source_ref   = source_ref
    )
Esempio n. 4
0
def createNamespacePackage(package_name, module_relpath):
    parts = package_name.split('.')

    source_ref = SourceCodeReference.fromFilenameAndLine(
        filename    = module_relpath,
        line        = 1,
        future_spec = FutureSpec(),
    )
    source_ref = source_ref.atInternal()

    package_package_name = '.'.join(parts[:-1]) or None
    package = PythonPackage(
        name         = parts[-1],
        package_name = package_package_name,
        source_ref   = source_ref,
    )

    package.setBody(
        makeStatementsSequenceFromStatement(
            statement = (
                StatementAssignmentVariable(
                    variable_ref = ExpressionTargetVariableRef(
                        variable_name = "__path__",
                        source_ref    = source_ref
                    ),
                    source       = ExpressionCallNoKeywords(
                        called     = ExpressionImportName(
                            module      = ExpressionImportModule(
                                module_name = "_frozen_importlib",
                                import_list = (),
                                level       = 0,
                                source_ref  = source_ref
                            ),
                            import_name = "_NamespacePath",
                            source_ref  = source_ref
                        ),
                        args       = ExpressionConstantRef(
                            constant   = (
                                package_name,
                                [module_relpath],
                                None
                            ),
                            source_ref =  source_ref
                        ),
                        source_ref =  source_ref
                    ),
                    source_ref   = source_ref
                )
            )
        )
    )

    completeVariableClosures(package)

    return source_ref, package
 def makeImportName(import_name):
     if module_name == "__future__":
         return ExpressionImportModuleHard(module_name="__future__",
                                           import_name=import_name,
                                           source_ref=source_ref)
     else:
         return ExpressionImportName(module=ExpressionImportModule(
             module_name=module_name,
             import_list=tuple(import_names),
             level=level,
             source_ref=source_ref),
                                     import_name=import_name,
                                     source_ref=source_ref)
Esempio n. 6
0
        def makeImportName(import_name):
            if module_name == "__future__":
                return ExpressionImportModuleHard(module_name="__future__",
                                                  import_name=import_name,
                                                  source_ref=source_ref)
            else:
                # TODO: This ought to use a temporary variable for multiple
                # names, instead of importing multiple times.

                return ExpressionImportName(module=ExpressionImportModule(
                    module_name=module_name,
                    import_list=tuple(import_names),
                    level=level,
                    source_ref=source_ref),
                                            import_name=import_name,
                                            source_ref=source_ref)
Esempio n. 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=R0912

    # Workaround: ast.parse cannot cope with some situations where a file is not
    # terminated by a new line.
    if not source_code.endswith('\n'):
        source_code = source_code + '\n'

    try:
        body = ast.parse(source_code, source_ref.getFilename())
    except SyntaxError as e:
        _makeSyntaxErrorCompatible(e)

        raise e

    assert getKind(body) == "Module"

    line_offset = source_ref.getLineNumber() - 1

    if line_offset > 0:
        for created_node in ast.walk(body):
            if hasattr(created_node, "lineno"):
                created_node.lineno += line_offset

    body, doc = extractDocFromBody(body)

    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 not sys.flags.no_site:
            statements.append(
                StatementExpressionOnly(
                    expression = ExpressionImportModule(
                        module_name = "site",
                        import_list = (),
                        level       = 0,
                        source_ref  = source_ref,
                    ),
                    source_ref = source_ref
                )
            )

        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__doc__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = doc,
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )

        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__file__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionModuleFileAttributeRef(
                    source_ref = internal_source_ref,
                ),
                source_ref   = internal_source_ref
            )
        )

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

    if Utils.python_version >= 300:
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__cached__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = None,
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )


    if Utils.python_version >= 330:
        # For Python3.3, it's set for both packages and non-packages.
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__package__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = provider.getFullName()
                                      if provider.isPythonPackage() else
                                    provider.getPackage(),
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )

    needs__initializing__ = not provider.isMainModule() and \
      (Utils.python_version >= 330 and Utils.python_version < 340)

    if needs__initializing__:
        # Set "__initializing__" at the beginning to True
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__initializing__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = True,
                    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(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__initializing__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    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
        )

        applyLaterWrappers()

        return result
    else:
        assert False
Esempio n. 8
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.

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

    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 = ExpressionImportModule(
                            module_name = path_imported_name,
                            import_list = (),
                            level       = 0,
                            source_ref  = source_ref,
                        ),
                        source_ref = source_ref
                    )
                )

            statements.append(
                StatementExpressionOnly(
                    expression = ExpressionImportModule(
                        module_name = "site",
                        import_list = (),
                        level       = 0,
                        source_ref  = source_ref,
                    ),
                    source_ref = source_ref
                )
            )

        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__doc__",
                    source_ref    = internal_source_ref
                ),
                source       = makeConstantRefNode(
                    constant      = doc,
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )

        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__file__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionModuleFileAttributeRef(
                    source_ref = internal_source_ref,
                ),
                source_ref   = internal_source_ref
            )
        )

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

    if python_version >= 300:
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__cached__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantNoneRef(
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )


    if python_version >= 330:
        # For Python3.3, it's set for both packages and non-packages.
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__package__",
                    source_ref    = internal_source_ref
                ),
                source       = makeConstantRefNode(
                    constant      = provider.getFullName()
                                      if provider.isCompiledPythonPackage() else
                                    provider.getPackage(),
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )

    needs__initializing__ = not provider.isMainModule() and \
      (python_version >= 330 and python_version < 340)

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

    if python_version >= 360:
        # Set "__annotations__" on module level to {}
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__annotations__",
                    source_ref    = internal_source_ref
                ),
                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(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__initializing__",
                    source_ref    = internal_source_ref
                ),
                source       = makeConstantRefNode(
                    constant      = False,
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )


    if is_module:
        return makeModuleFrame(
            module     = provider,
            statements = statements,
            source_ref = source_ref
        )
    else:
        assert False
Esempio n. 9
0
def buildImportFromNode(provider, node, source_ref):
    # "from .. import .." statements. This may trigger a star import, or multiple names
    # being looked up from the given module variable name.

    module_name = node.module if node.module is not None else ""
    level = node.level

    # Importing from "__future__" module may enable flags.
    if module_name == "__future__":
        assert provider.isPythonModule() or source_ref.isExecReference()

        for import_desc in node.names:
            object_name, _local_name = import_desc.name, import_desc.asname

            enableFutureFeature(object_name=object_name,
                                future_spec=source_ref.getFutureSpec(),
                                source_ref=source_ref)

        # Remember it for checks to be applied once module is complete.
        node.source_ref = source_ref
        _future_import_nodes.append(node)

    target_names = []
    import_names = []

    for import_desc in node.names:
        object_name, local_name = import_desc.name, import_desc.asname

        if object_name == "*":
            target_names.append(None)
        else:
            target_names.append(
                local_name if local_name is not None else object_name)

        import_names.append(object_name)

    if None in target_names:
        # More than "*" is a syntax error in Python, need not care about this at
        # all, it's only allowed value for import list in  this case.
        assert target_names == [None]

        # Python3 made this a syntax error unfortunately.
        if not provider.isPythonModule() and Utils.python_version >= 300:
            SyntaxErrors.raiseSyntaxError(
                "import * only allowed at module level",
                provider.getSourceReference())

        if provider.isExpressionFunctionBody():
            provider.markAsStarImportContaining()

        return StatementImportStar(module_import=ExpressionImportModule(
            module_name=module_name,
            import_list=("*", ),
            level=level,
            source_ref=source_ref),
                                   source_ref=source_ref)
    else:
        import_nodes = []

        for target_name, import_name in zip(target_names, import_names):
            import_nodes.append(
                StatementAssignmentVariable(
                    variable_ref=ExpressionTargetVariableRef(
                        variable_name=target_name, source_ref=source_ref),
                    source=ExpressionImportName(module=ExpressionImportModule(
                        module_name=module_name,
                        import_list=import_names,
                        level=level,
                        source_ref=source_ref),
                                                import_name=import_name,
                                                source_ref=source_ref),
                    source_ref=source_ref))

        # Note: Each import is sequential. It can succeed, and the failure of a later one is
        # not changing one. We can therefore have a sequence of imports that only import one
        # thing therefore.
        return StatementsSequence(statements=import_nodes,
                                  source_ref=source_ref)
Esempio n. 10
0
def buildImportFromNode(provider, node, source_ref):
    # "from .. import .." statements. This may trigger a star import, or
    # multiple names being looked up from the given module variable name.
    # This is pretty complex, pylint: disable=R0912,R0914

    module_name = node.module if node.module is not None else ""
    level = node.level

    # Importing from "__future__" module may enable flags to the parser,
    # that we need to know about, handle that.
    if module_name == "__future__":
        _handleFutureImport(provider, node, source_ref)

    target_names = []
    import_names = []

    # Mapping imported "fromlist" to assigned "fromlist" if any, handling the
    # star case as well.
    for import_desc in node.names:
        object_name, local_name = import_desc.name, import_desc.asname

        if object_name == '*':
            target_names.append(None)
            assert local_name is None
        else:
            target_names.append(
                local_name
                  if local_name is not None else
                object_name
            )

        import_names.append(object_name)

    # Star imports get special treatment.
    if None in target_names:
        # More than "*" is a syntax error in Python, need not care about this at
        # all, it's only allowed value for import list in  this case.
        assert target_names == [None]

        # Python3 made it so that these can only occur on the module level,
        # so this a syntax error if not there. For Python2 it is OK to
        # occur everywhere though.
        if not provider.isCompiledPythonModule() and python_version >= 300:
            SyntaxErrors.raiseSyntaxError(
                "import * only allowed at module level",
                provider.getSourceReference()
            )

        # Functions with star imports get a marker.
        if provider.isExpressionFunctionBody():
            provider.markAsStarImportContaining()

        return StatementImportStar(
            module_import = ExpressionImportModule(
                module_name = module_name,
                import_list = ('*',),
                level       = level,
                source_ref  = source_ref
            ),
            source_ref    = source_ref
        )
    else:
        def makeImportName(import_name):
            if module_name == "__future__":
                # Make "__future__" imports tie hard immediately, they cannot be
                # any other way.
                return ExpressionImportModuleHard(
                    module_name = "__future__",
                    import_name = import_name,
                    source_ref  = source_ref
                )
            else:
                # Refer to be module, or a clone of the reference if need be.
                return ExpressionImportName(
                    module      = imported_from_module,
                    import_name = import_name,
                    source_ref  = source_ref
                )

        imported_from_module = ExpressionImportModule(
            module_name = module_name,
            import_list = tuple(import_names),
            level       = level,
            source_ref  = source_ref
        )

        # If we have multiple names to import, consider each.
        multi_names = len(target_names) > 1

        statements = []

        if multi_names:
            tmp_import_from = provider.allocateTempVariable(
                temp_scope = provider.allocateTempScope("import_from"),
                name       = "module"
            )

            statements.append(
                StatementAssignmentVariable(
                    variable_ref = ExpressionTargetTempVariableRef(
                        variable   = tmp_import_from,
                        source_ref = source_ref
                    ),
                    source       = imported_from_module,
                    source_ref   = source_ref
                )
            )

            imported_from_module = ExpressionTempVariableRef(
                variable   = tmp_import_from,
                source_ref = source_ref
            )

        import_statements = []
        first = True

        for target_name, import_name in zip(target_names, import_names):
            # Make a clone of the variable reference, if we are going to use
            # another one.
            if not first:
                imported_from_module = imported_from_module.makeClone()
            first = False

            import_statements.append(
                StatementAssignmentVariable(
                    variable_ref = ExpressionTargetVariableRef(
                        variable_name = mangleName(target_name, provider),
                        source_ref    = source_ref
                    ),
                    source       = makeImportName(
                        import_name = import_name,
                    ),
                    source_ref   = source_ref
                )
            )

        # Release the temporary module value as well.
        if multi_names:
            statements.append(
                makeTryFinallyStatement(
                    provider   = provider,
                    tried      = import_statements,
                    final      = (
                        StatementReleaseVariable(
                            variable   = tmp_import_from,
                            source_ref = source_ref
                        ),
                    ),
                    source_ref = source_ref
                )
            )
        else:
            statements.extend(import_statements)

        # Note: Each import is sequential. It can succeed, and the failure of a
        # later one is not undoing previous ones. We can therefore have a
        # sequence of imports that each only import one thing therefore.
        return StatementsSequence(
            statements = mergeStatements(statements),
            source_ref = source_ref
        )
Esempio n. 11
0
def buildImportFromNode(provider, node, source_ref):
    # "from .. import .." statements. This may trigger a star import, or
    # multiple names being looked up from the given module variable name.

    module_name = node.module if node.module is not None else ""
    level = node.level

    # Importing from "__future__" module may enable flags to the parser,
    # that we need to know.
    if module_name == "__future__":
        # Future imports we see are all legal, and known to work.

        if not provider.isCompiledPythonModule():
            SyntaxErrors.raiseSyntaxError(
                reason     = """\
from __future__ imports must occur at the beginning of the file""",
                col_offset = 8
                  if Utils.python_version >= 300 or \
                  not Options.isFullCompat()
                else None,
                source_ref = source_ref
            )

        for import_desc in node.names:
            object_name, _local_name = import_desc.name, import_desc.asname

            enableFutureFeature(object_name=object_name,
                                future_spec=source_ref.getFutureSpec(),
                                source_ref=source_ref)

        # Remember it for checks to be applied once module is complete.
        node.source_ref = source_ref
        _future_import_nodes.append(node)

    target_names = []
    import_names = []

    for import_desc in node.names:
        object_name, local_name = import_desc.name, import_desc.asname

        if object_name == '*':
            target_names.append(None)
        else:
            target_names.append(
                local_name if local_name is not None else object_name)

        import_names.append(object_name)

    if None in target_names:
        # More than "*" is a syntax error in Python, need not care about this at
        # all, it's only allowed value for import list in  this case.
        assert target_names == [None]

        # Python3 made this a syntax error unfortunately.
        if not provider.isCompiledPythonModule(
        ) and Utils.python_version >= 300:
            SyntaxErrors.raiseSyntaxError(
                "import * only allowed at module level",
                provider.getSourceReference())

        if provider.isExpressionFunctionBody():
            provider.markAsStarImportContaining()

        return StatementImportStar(module_import=ExpressionImportModule(
            module_name=module_name,
            import_list=('*', ),
            level=level,
            source_ref=source_ref),
                                   source_ref=source_ref)
    else:
        # Make __future__ imports "hard" immediately, they cannot be any other
        # way.
        def makeImportName(import_name):
            if module_name == "__future__":
                return ExpressionImportModuleHard(module_name="__future__",
                                                  import_name=import_name,
                                                  source_ref=source_ref)
            else:
                # TODO: This ought to use a temporary variable for multiple
                # names, instead of importing multiple times.

                return ExpressionImportName(module=ExpressionImportModule(
                    module_name=module_name,
                    import_list=tuple(import_names),
                    level=level,
                    source_ref=source_ref),
                                            import_name=import_name,
                                            source_ref=source_ref)

        import_nodes = []

        for target_name, import_name in zip(target_names, import_names):
            import_nodes.append(
                StatementAssignmentVariable(
                    variable_ref=ExpressionTargetVariableRef(
                        variable_name=mangleName(target_name, provider),
                        source_ref=source_ref),
                    source=makeImportName(import_name=import_name, ),
                    source_ref=source_ref))

        # Note: Each import is sequential. It can succeed, and the failure of a
        # later one is not changing one. We can therefore have a sequence of
        # imports that only import one thing therefore.
        return StatementsSequence(statements=import_nodes,
                                  source_ref=source_ref)
Esempio n. 12
0
def buildImportFromNode(provider, node, source_ref):
    # "from .. import .." statements. This may trigger a star import, or
    # multiple names being looked up from the given module variable name.
    # This is pretty complex, pylint: disable=R0912,R0914

    module_name = node.module if node.module is not None else ""
    level = node.level

    # Importing from "__future__" module may enable flags to the parser,
    # that we need to know about, handle that.
    if module_name == "__future__":
        _handleFutureImport(provider, node, source_ref)

    target_names = []
    import_names = []

    # Mapping imported "fromlist" to assigned "fromlist" if any, handling the
    # star case as well.
    for import_desc in node.names:
        object_name, local_name = import_desc.name, import_desc.asname

        if object_name == '*':
            target_names.append(None)
            assert local_name is None
        else:
            target_names.append(
                local_name if local_name is not None else object_name)

        import_names.append(object_name)

    # Star imports get special treatment.
    if None in target_names:
        # More than "*" is a syntax error in Python, need not care about this at
        # all, it's only allowed value for import list in  this case.
        assert target_names == [None]

        # Python3 made it so that these can only occur on the module level,
        # so this a syntax error if not there. For Python2 it is OK to
        # occur everywhere though.
        if not provider.isCompiledPythonModule() and python_version >= 300:
            SyntaxErrors.raiseSyntaxError(
                "import * only allowed at module level",
                provider.getSourceReference())

        # Functions with star imports get a marker.
        if provider.isExpressionFunctionBody():
            provider.markAsStarImportContaining()

        return StatementImportStar(module_import=ExpressionImportModule(
            module_name=module_name,
            import_list=('*', ),
            level=level,
            source_ref=source_ref),
                                   source_ref=source_ref)
    else:

        def makeImportName(import_name):
            if module_name == "__future__":
                # Make "__future__" imports tie hard immediately, they cannot be
                # any other way.
                return ExpressionImportModuleHard(module_name="__future__",
                                                  import_name=import_name,
                                                  source_ref=source_ref)
            else:
                # Refer to be module, or a clone of the reference if need be.
                return ExpressionImportName(module=imported_from_module,
                                            import_name=import_name,
                                            source_ref=source_ref)

        imported_from_module = ExpressionImportModule(
            module_name=module_name,
            import_list=tuple(import_names),
            level=level,
            source_ref=source_ref)

        # If we have multiple names to import, consider each.
        multi_names = len(target_names) > 1

        statements = []

        if multi_names:
            tmp_import_from = provider.allocateTempVariable(
                temp_scope=provider.allocateTempScope("import_from"),
                name="module")

            statements.append(
                StatementAssignmentVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=tmp_import_from, source_ref=source_ref),
                    source=imported_from_module,
                    source_ref=source_ref))

            imported_from_module = ExpressionTempVariableRef(
                variable=tmp_import_from, source_ref=source_ref)

        import_statements = []
        first = True

        for target_name, import_name in zip(target_names, import_names):
            # Make a clone of the variable reference, if we are going to use
            # another one.
            if not first:
                imported_from_module = imported_from_module.makeClone()
            first = False

            import_statements.append(
                StatementAssignmentVariable(
                    variable_ref=ExpressionTargetVariableRef(
                        variable_name=mangleName(target_name, provider),
                        source_ref=source_ref),
                    source=makeImportName(import_name=import_name, ),
                    source_ref=source_ref))

        # Release the temporary module value as well.
        if multi_names:
            statements.append(
                makeTryFinallyStatement(provider=provider,
                                        tried=import_statements,
                                        final=(StatementReleaseVariable(
                                            variable=tmp_import_from,
                                            source_ref=source_ref), ),
                                        source_ref=source_ref))
        else:
            statements.extend(import_statements)

        # Note: Each import is sequential. It can succeed, and the failure of a
        # later one is not undoing previous ones. We can therefore have a
        # sequence of imports that each only import one thing therefore.
        return StatementsSequence(statements=mergeStatements(statements),
                                  source_ref=source_ref)
Esempio n. 13
0
def buildParseTree( provider, source_code, source_ref, is_module,
                    is_main ):
    # Workaround: ast.parse cannot cope with some situations where a file is not
    # terminated by a new line.
    if not source_code.endswith( "\n" ):
        source_code = source_code + "\n"

    body = ast.parse( source_code, source_ref.getFilename() )
    assert getKind( body ) == "Module"

    line_offset = source_ref.getLineNumber() - 1

    if line_offset > 0:
        for created_node in ast.walk( body ):
            if hasattr( created_node, "lineno" ):
                created_node.lineno += line_offset

    body, doc = extractDocFromBody( body )

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

    # Check if a __future__ imports really were at the beginning of the file.
    for node in body:
        if node in _future_import_nodes:
            _future_import_nodes.remove( node )
        else:
            if _future_import_nodes:
                SyntaxErrors.raiseSyntaxError(
                    reason     = """\
from __future__ imports must occur at the beginning of the file""",
                    col_offset = 1
                      if Utils.python_version >= 300 or \
                      not Options.isFullCompat() else
                    None,
                    source_ref = _future_import_nodes[0].source_ref
                )

    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 sys.flags.no_site:
            statements.append(
                StatementExpressionOnly(
                    expression = ExpressionImportModule(
                        module_name    = "site",
                        import_list    = (),
                        level          = 0,
                        source_ref     = source_ref,
                    ),
                    source_ref  = source_ref
                )
            )

        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__doc__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = doc,
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )

        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__file__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = source_ref.getFilename(),
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )

        if provider.isPythonPackage():
            # TODO: __package__ is not set here, but automatically, which makes
            # it invisible though
            statements.append(
                StatementAssignmentVariable(
                    variable_ref = ExpressionTargetVariableRef(
                        variable_name = "__path__",
                        source_ref    = internal_source_ref
                    ),
                    source       = ExpressionConstantRef(
                        constant      = [
                            Utils.dirname( source_ref.getFilename() )
                        ],
                        source_ref    = internal_source_ref,
                        user_provided = True
                    ),
                    source_ref   = internal_source_ref
                )
            )

    if Utils.python_version >= 300:
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__cached__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = None,
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )


    if Utils.python_version >= 330:
        # For Python3.3, it's set for both packages and non-packages.
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__package__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = provider.getFullName()
                                      if provider.isPythonPackage() else
                                    provider.getPackage(),
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )

    if Utils.python_version >= 330 and not provider.isMainModule():
        # Set initialzing at the beginning to True
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__initializing__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = True,
                    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 Utils.python_version >= 330 and not provider.isMainModule():
        # Set initialzing at the beginning to True
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__initializing__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = False,
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )


    if is_module:
        return makeModuleFrame(
            module = provider,
            statements = statements,
            source_ref = source_ref
        )
    else:
        assert False