Example #1
0
def hacking_import_rules(logical_line, filename, noqa):
    r"""Check for imports.

    OpenStack HACKING guide recommends one import per line:
    Do not import more than one module per line

    Examples:
    Okay: from nova.compute import api
    H301: from nova.compute import api, utils


    Do not use wildcard import

    Do not make relative imports

    Examples:
    Okay: from os import path
    Okay: from os import path as p
    Okay: from os import (path as p)
    Okay: import os.path
    Okay: from nova.compute import rpcapi
    Okay: from six.moves.urllib import parse
    H303: from os.path import *
    H304: from .compute import rpcapi
    """
    # TODO(jogo): make the following doctests pass:
    #            H301: import os, sys
    # TODO(mordred: We need to split this into different checks so that they
    # can be disabled by command line switches properly

    if noqa:
        return

    split_line = logical_line.split()
    split_line_len = len(split_line)
    if (split_line_len > 1 and split_line[0] in ('import', 'from') and
            not core.is_import_exception(split_line[1])):
        pos = logical_line.find(',')
        if pos != -1:
            if split_line[0] == 'from':
                yield pos, "H301: one import per line"
        pos = logical_line.find('*')
        if pos != -1:
            yield pos, "H303: No wildcard (*) import."
            return

        if split_line_len in (2, 4, 6) and split_line[1] != "__future__":
            if 'from' == split_line[0] and split_line_len > 3:
                mod = '.'.join((split_line[1], split_line[3]))
                if core.is_import_exception(mod):
                    return
                if RE_RELATIVE_IMPORT.search(logical_line):
                    yield logical_line.find('.'), (
                        "H304: No relative imports. '%s' is a relative import"
                        % logical_line)
                    return
Example #2
0
def hacking_import_rules(logical_line, physical_line, filename, noqa):
    r"""Check for imports.

    OpenStack HACKING guide recommends one import per line:
    Do not import more than one module per line

    Examples:
    Okay: from nova.compute import api
    H301: from nova.compute import api, utils


    Do not use wildcard import

    Do not make relative imports

    Examples:
    Okay: from os import path
    Okay: from os import path as p
    Okay: from os import (path as p)
    Okay: import os.path
    Okay: from nova.compute import rpcapi
    Okay: from six.moves.urllib import parse
    H303: from os.path import *
    H304: from .compute import rpcapi
    """
    # TODO(jogo): make the following doctests pass:
    #            H301: import os, sys
    # TODO(mordred: We need to split this into different checks so that they
    # can be disabled by command line switches properly

    if noqa:
        return

    split_line = logical_line.split()
    split_line_len = len(split_line)
    if (split_line_len > 1 and split_line[0] in ('import', 'from') and
            not core.is_import_exception(split_line[1])):
        pos = logical_line.find(',')
        if pos != -1:
            if split_line[0] == 'from':
                yield pos, "H301: one import per line"
        pos = logical_line.find('*')
        if pos != -1:
            yield pos, "H303: No wildcard (*) import."
            return

        if split_line_len in (2, 4, 6) and split_line[1] != "__future__":
            if 'from' == split_line[0] and split_line_len > 3:
                mod = '.'.join((split_line[1], split_line[3]))
                if core.is_import_exception(mod):
                    return
                if RE_RELATIVE_IMPORT.search(logical_line):
                    yield logical_line.find('.'), (
                        "H304: No relative imports. '%s' is a relative import"
                        % logical_line)
                    return
Example #3
0
def get_alias(logical_line):

    parts = logical_line.split()

    if (len(parts) > 3 and parts[0] == 'from' and parts[1] != '__future__'
            and not core.is_import_exception(parts[1])):

        # from path.to.module import module
        if len(parts) == 4:
            return '.'.join([parts[1], parts[3]]), None

        # from path.to.module import module as alias
        if len(parts) > 5 and parts[4] == 'as':
            return '.'.join([parts[1], parts[3]]), parts[5]

    return None
def check_module_only(logical_line, physical_line, filename, noqa):
    """Check imports.

    Imports should be modules only.

    Examples:
    Okay: from orquesta import conducting
    Okay: from orquesta import states
    Okay: from orquesta.utils import date
    O101: from orquesta.conducting import WorkflowConductor
    O101: from orquesta.states import REQUESTED
    O101: from orquesta.utils.date import parse
    """

    if noqa:
        return

    def check_is_module(mod, search_path=sys.path):
        mod = mod.replace('(', '')  # Ignore parentheses

        for finder in sys.meta_path:
            if finder.find_module(mod) is not None:
                return True

        try:
            mod_name = mod

            while '.' in mod_name:
                pack_name, _sep, mod_name = mod_name.partition('.')
                f, p, d = imp.find_module(pack_name, search_path)
                search_path = [p]

            imp.find_module(mod_name, search_path)
        except ImportError:
            try:
                # Handle namespace modules
                if '.' in mod:
                    pack_name, mod_name = mod.rsplit('.', 1)
                    __import__(pack_name, fromlist=[mod_name])
                else:
                    __import__(mod)
            except ImportError:
                # Import error here means the thing is not importable in
                # current environment, either because of missing dependency,
                # typo in code being checked, or any other reason. Anyway, we
                # have no means to know if it is module or not, so we return
                # True to avoid false positives.
                return True
            except Exception:
                # Skip stack trace on unexpected import error,
                # log and continue.
                traceback.print_exc()
                return False
            else:
                # The line was imported. If it is a module, it must be there.
                # If it is not there under its own name, look to see if it is
                # a module redirection import..
                if mod in sys.modules:
                    return True
                else:
                    pack_name, _sep, mod_name = mod.rpartition('.')
                    if pack_name in sys.modules:
                        _mod = getattr(sys.modules[pack_name], mod_name, None)
                        return inspect.ismodule(_mod)
                    return False

        return True

    def is_module(mod):
        if mod not in MODULES_CACHE:
            MODULES_CACHE[mod] = check_is_module(mod)

        return MODULES_CACHE[mod]

    parts = logical_line.split()

    if (len(parts) > 3 and parts[0] == 'from' and parts[1] != '__future__'
            and not core.is_import_exception(parts[1])
            and not is_module('.'.join([parts[1], parts[3]]))):
        yield 0, 'O101 import must be module only'
Example #5
0
def hacking_import_rules(logical_line, physical_line, filename, noqa):
    r"""Check for imports.

    OpenStack HACKING guide recommends one import per line:
    Do not import more than one module per line

    Examples:
    Okay: from nova.compute import api
    H301: from nova.compute import api, utils


    Imports should usually be on separate lines.

    OpenStack HACKING guide recommends importing only modules:
    Do not import objects, only modules

    Examples:
    Okay: from os import path
    Okay: from os import path as p
    Okay: from os import (path as p)
    Okay: import os.path
    Okay: from nova.compute import rpcapi
    Okay: from os.path import dirname as dirname2  # noqa
    H302: from os.path import dirname as dirname2
    H302: from os.path import (dirname as dirname2)
    H303: from os.path import *
    H304: from .compute import rpcapi
    """
    # TODO(jogo): make the following doctests pass:
    #            H301: import os, sys
    # NOTE(afazekas): An old style relative import example will not be able to
    # pass the doctest, since the relativity depends on the file's locality
    # TODO(mordred: We need to split this into 4 different checks so that they
    # can be disabled by command line switches properly

    if noqa:
        return

    def is_module_for_sure(mod, search_path=sys.path):
        mod = mod.replace('(', '')  # Ignore parentheses
        try:
            mod_name = mod
            while '.' in mod_name:
                pack_name, _sep, mod_name = mod.partition('.')
                f, p, d = imp.find_module(pack_name, search_path)
                search_path = [p]
            imp.find_module(mod_name, search_path)
        except ImportError:
            try:
                # NOTE(vish): handle namespace modules
                if '.' in mod:
                    pack_name, mod_name = mod.rsplit('.', 1)
                    __import__(pack_name, fromlist=[mod_name])
                else:
                    __import__(mod)
            except ImportError:
                # NOTE(imelnikov): import error here means the thing is
                # not importable in current environment, either because
                # of missing dependency, typo in code being checked, or
                # any other reason. Anyway, we have no means to know if
                # it is module or not, so we return True to avoid
                # false positives.
                return True
            except Exception:
                # NOTE(jogo) don't stack trace if unexpected import error,
                # log and continue.
                traceback.print_exc()
                return False
            else:
                # NOTE(imelnikov): we imported the thing; if it was module,
                # it must be there:
                return mod in sys.modules
        return True

    def is_module(mod):
        """Checks for non module imports."""
        if mod in modules_cache:
            return modules_cache[mod]
        res = is_module_for_sure(mod)
        modules_cache[mod] = res
        return res

    current_path = os.path.dirname(filename)
    current_mod = os.path.basename(filename)
    if current_mod[-3:] == ".py":
        current_mod = current_mod[:-3]

    split_line = logical_line.split()
    split_line_len = len(split_line)
    if (split_line_len > 1 and split_line[0] in ('import', 'from') and
            not core.is_import_exception(split_line[1])):
        pos = logical_line.find(',')
        if pos != -1:
            if split_line[0] == 'from':
                yield pos, "H301: one import per line"
            return  # ',' is not supported by the H302 checker yet
        pos = logical_line.find('*')
        if pos != -1:
            yield pos, "H303: No wildcard (*) import."
            return

        if split_line_len in (2, 4, 6) and split_line[1] != "__future__":
            if 'from' == split_line[0] and split_line_len > 3:
                mod = '.'.join((split_line[1], split_line[3]))
                if core.is_import_exception(mod):
                        return
                if RE_RELATIVE_IMPORT.search(logical_line):
                    yield logical_line.find('.'), (
                        "H304: No relative imports. '%s' is a relative import"
                        % logical_line)
                    return

                if not is_module(mod):
                    yield 0, ("H302: import only modules."
                              "'%s' does not import a module" % logical_line)
                return

        # NOTE(afazekas): import searches first in the package
        # The import keyword just imports modules
        # The guestfs module now imports guestfs
        mod = split_line[1]
        if (current_mod != mod and not is_module(mod) and
                is_module_for_sure(mod, [current_path])):
            yield 0, ("H304: No relative imports."
                      " '%s' is a relative import" % logical_line)
Example #6
0
def hacking_import_rules(logical_line, physical_line, filename, noqa):
    r"""Check for imports.

    OpenStack HACKING guide recommends one import per line:
    Do not import more than one module per line

    Examples:
    Okay: from nova.compute import api
    H301: from nova.compute import api, utils


    Imports should usually be on separate lines.

    OpenStack HACKING guide recommends importing only modules:
    Do not import objects, only modules

    Examples:
    Okay: from os import path
    Okay: from os import path as p
    Okay: from os import (path as p)
    Okay: import os.path
    Okay: from nova.compute import rpcapi
    Okay: from os.path import dirname as dirname2  # noqa
    Okay: from six.moves.urllib import parse
    H302: from os.path import dirname as dirname2
    H302: from os.path import (dirname as dirname2)
    H303: from os.path import *
    H304: from .compute import rpcapi
    """
    # TODO(jogo): make the following doctests pass:
    #            H301: import os, sys
    # NOTE(afazekas): An old style relative import example will not be able to
    # pass the doctest, since the relativity depends on the file's locality
    # TODO(mordred: We need to split this into 4 different checks so that they
    # can be disabled by command line switches properly

    if noqa:
        return

    def is_module_for_sure(mod, search_path=sys.path):
        mod = mod.replace('(', '')  # Ignore parentheses
        for finder in sys.meta_path:
            if finder.find_module(mod) is not None:
                return True
        try:
            mod_name = mod
            while '.' in mod_name:
                pack_name, _sep, mod_name = mod.partition('.')
                f, p, d = imp.find_module(pack_name, search_path)
                search_path = [p]
            imp.find_module(mod_name, search_path)
        except ImportError:
            try:
                # NOTE(vish): handle namespace modules
                if '.' in mod:
                    pack_name, mod_name = mod.rsplit('.', 1)
                    __import__(pack_name, fromlist=[mod_name])
                else:
                    __import__(mod)
            except ImportError:
                # NOTE(imelnikov): import error here means the thing is
                # not importable in current environment, either because
                # of missing dependency, typo in code being checked, or
                # any other reason. Anyway, we have no means to know if
                # it is module or not, so we return True to avoid
                # false positives.
                return True
            except Exception:
                # NOTE(jogo) don't stack trace if unexpected import error,
                # log and continue.
                traceback.print_exc()
                return False
            else:
                # NOTE(imelnikov): we imported the thing; if it was module,
                # it must be there:
                return mod in sys.modules
        return True

    def is_module(mod):
        """Checks for non module imports."""
        if mod in modules_cache:
            return modules_cache[mod]
        res = is_module_for_sure(mod)
        modules_cache[mod] = res
        return res

    current_path = os.path.dirname(filename)
    current_mod = os.path.basename(filename)
    if current_mod[-3:] == ".py":
        current_mod = current_mod[:-3]

    split_line = logical_line.split()
    split_line_len = len(split_line)
    if (split_line_len > 1 and split_line[0] in ('import', 'from')
            and not core.is_import_exception(split_line[1])):
        pos = logical_line.find(',')
        if pos != -1:
            if split_line[0] == 'from':
                yield pos, "H301: one import per line"
            return  # ',' is not supported by the H302 checker yet
        pos = logical_line.find('*')
        if pos != -1:
            yield pos, "H303: No wildcard (*) import."
            return

        if split_line_len in (2, 4, 6) and split_line[1] != "__future__":
            if 'from' == split_line[0] and split_line_len > 3:
                mod = '.'.join((split_line[1], split_line[3]))
                if core.is_import_exception(mod):
                    return
                if RE_RELATIVE_IMPORT.search(logical_line):
                    yield logical_line.find('.'), (
                        "H304: No relative imports. '%s' is a relative import"
                        % logical_line)
                    return

                if not is_module(mod):
                    yield 0, ("H302: import only modules."
                              "'%s' does not import a module" % logical_line)
                return

        # NOTE(afazekas): import searches first in the package
        # The import keyword just imports modules
        # The guestfs module now imports guestfs
        mod = split_line[1]
        if (current_mod != mod and not is_module(mod)
                and is_module_for_sure(mod, [current_path])):
            yield 0, ("H304: No relative imports."
                      " '%s' is a relative import" % logical_line)