Exemplo n.º 1
0
 def test_lint_should_analyze_file(self):
     self.linter.set_reporter(text.TextReporter())
     self.linter.config.files_output = True
     self.linter.should_analyze_file = lambda *args: False
     self.linter.check('logilab')
     self.assertTrue(os.path.exists('pylint_logilab.txt'))
     self.assertFalse(os.path.exists('pylint_logilab_common.txt'))
Exemplo n.º 2
0
    def lint_py_files_for_python3_compatibility(self):
        """Prints a list of Python 3 compatibility errors in the given list of
        Python files.

        Returns:
            TaskResult. A TaskResult object representing the result of the lint
            check.
        """
        files_to_lint = self.all_filepaths
        any_errors = False
        error_messages = []
        full_error_messages = []
        name = 'Pylint for Python 3 compatibility'

        files_to_lint_for_python3_compatibility = [
            file_name for file_name in files_to_lint
            if not re.match(r'^.*python_utils.*\.py$', file_name)
        ]
        if not files_to_lint_for_python3_compatibility:
            return [
                concurrent_task_utils.TaskResult(name, False, [], [
                    'There are no Python files to lint for Python 3 '
                    'compatibility.'
                ])
            ]

        _batch_size = 50
        current_batch_start_index = 0

        while current_batch_start_index < len(
                files_to_lint_for_python3_compatibility):
            # Note that this index is an exclusive upper bound -- i.e.,
            # the current batch of files ranges from 'start_index' to
            # 'end_index - 1'.
            current_batch_end_index = min(
                current_batch_start_index + _batch_size,
                len(files_to_lint_for_python3_compatibility))
            current_files_to_lint = files_to_lint_for_python3_compatibility[
                current_batch_start_index:current_batch_end_index]

            pylint_report = python_utils.string_io()
            pylinter_for_python3 = lint.Run(
                current_files_to_lint + ['--py3k'],
                reporter=text.TextReporter(pylint_report),
                exit=False).linter

            if pylinter_for_python3.msg_status != 0:
                lint_message = pylint_report.getvalue()
                pylint_error_messages = (
                    self.get_trimmed_error_output(lint_message))
                error_messages.append(pylint_error_messages)
                full_error_messages.append('Messages for Python 3 support:')
                full_error_messages.append(lint_message)
                any_errors = True

            current_batch_start_index = current_batch_end_index

        return concurrent_task_utils.TaskResult(name, any_errors,
                                                error_messages,
                                                full_error_messages)
Exemplo n.º 3
0
def run_pylint(filename, rcfile=None):
    """run pylint check."""
    disable = ["E1103",  # maybe-no-member
               "W0142",  # star-args
               "W1201",  # logging-not-lazy
               "I0011",  # locally-disabled
               "I0012",  # locally-enabled
               "R0801",  # duplicate-code
               "R0901",  # too-many-ancestors
               "R0902",  # too-many-instance-attributes
               "R0903",  # too-few-public-methods
               "R0904",  # too-many-public-methods
               "R0921",  # abstract-class-not-used
               "R0922"]  # abstract-class-little-used
    enable = ["W0511"]  # fixme
    args = [
        "-r", "n", "--persistent=n",
        "-d", ",".join(disable),
        "-e", ",".join(enable)]
    if rcfile:
        args.append("--rcfile=%s" % rcfile)

    kwargs = dict(exit=False)
    try:
        kwargs['reporter'] = text.TextReporter(sys.stdout)
        kwargs['reporter'].line_format  # pylint: disable=pointless-statement
        args += ["--msg-template",
                 "{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}"]
    except AttributeError:
        kwargs['reporter'] = text.ParseableTextReporter(sys.stdout)
        args += ["-f", "parseable", "-i", "y"]

    lint.Run(args + [filename], **kwargs)
Exemplo n.º 4
0
 def test_pylint(self):
     stdout = StringIO()
     reporter = text.TextReporter(stdout)
     opts = ["--score=no", "chatwatch"]
     pylint.Run(opts, reporter=reporter, do_exit=False)
     out = reporter.out.getvalue()
     failed = bool(out)
     assert not failed, "Pylint found violations"
Exemplo n.º 5
0
def run(config, *args):
    """ Run pylint """
    try:
        from pylint import lint
        from pylint.reporters import text
    except ImportError:
        return 2

    if config is None:
        config = _shell.native('pylintrc')
    argv = [
        '--rcfile',
        config,
        '--reports',
        'no',
    ]

    stream = FilterStream(_term.terminfo())

    old_stderr = _sys.stderr
    try:
        # pylint: disable = E1101
        _sys.stderr = stream
        from pylint import __pkginfo__
        if __pkginfo__.numversion >= (1, 0, 0):
            reporter = text.TextReporter(stream)
            argv.extend([
                '--msg-template',
                '{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}'
            ])
        else:
            argv.extend(
                ['--output-format', 'parseable', '--include-ids', 'yes'])
            if __pkginfo__.numversion < (0, 13):
                lint.REPORTER_OPT_MAP['parseable'] = \
                    lambda: text.TextReporter2(stream)
                reporter = text.TextReporter2(stream)
            else:
                reporter = text.ParseableTextReporter(stream)
                lint.REPORTER_OPT_MAP['parseable'] = lambda: reporter

        for path in args:
            try:
                try:
                    lint.Run(argv + [path], reporter=reporter)
                except SystemExit:
                    pass  # don't accept the exit. strange errors happen...

                if stream.written:
                    print()
                    stream.written = False
            except KeyboardInterrupt:
                print()
                raise
    finally:
        _sys.stderr = old_stderr

    return 0
Exemplo n.º 6
0
def run_pylint():
    buff = six.StringIO()
    reporter = text.TextReporter(output=buff)
    args = [
        "--msg-template='{path}:{line}: [{msg_id}i({symbol}), {obj}] {msg}'",
        "-E", "manila"]
    lint.Run(args, reporter=reporter, exit=False)
    val = buff.getvalue()
    buff.close()
    return val
Exemplo n.º 7
0
def run_pylint():
    buff = StringIO()
    reporter = text.TextReporter(output=buff)
    args = [
        "--msg-template='{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}'",
        "-j",
        "%s" % multiprocessing.cpu_count(), "-E", "cinder"
    ]
    lint.Run(args, reporter=reporter, exit=False)
    val = buff.getvalue()
    buff.close()
    return val
Exemplo n.º 8
0
def test_pylint_visit_method_taken_in_account(linter: PyLinter) -> None:
    class CustomChecker(checkers.BaseChecker):
        name = "custom"
        msgs = {"W9999": ("", "custom", "")}

        @only_required_for_messages("custom")
        def visit_class(self, _):
            pass

    linter.register_checker(CustomChecker(linter))
    linter.open()
    out = StringIO()
    linter.set_reporter(text.TextReporter(out))
    linter.check(["abc"])
Exemplo n.º 9
0
def test_pylint_visit_method_taken_in_account(linter):
    class CustomChecker(checkers.BaseChecker):
        __implements__ = interfaces.IAstroidChecker
        name = "custom"
        msgs = {"W9999": ("", "custom", "")}

        @check_messages("custom")
        def visit_class(self, _):
            pass

    linter.register_checker(CustomChecker(linter))
    linter.open()
    out = StringIO()
    linter.set_reporter(text.TextReporter(out))
    linter.check("abc")
Exemplo n.º 10
0
def test_pylint():
    stdout = StringIO()
    reporter = text.TextReporter(stdout)
    opts = ['--max-line-length=150', '--score=no', '--disable=missing-docstring, wildcard-import, '
                                                   'attribute-defined-outside-init, too-few-public-methods, '
                                                   'old-style-class,import-error,invalid-name,no-init,'
                                                   'too-many-instance-attributes,protected-access,too-many-arguments,'
                                                   'too-many-public-methods,logging-format-interpolation,'
                                                   'too-many-branches', 'ksoftapi']
    pylint.Run(opts, reporter=reporter, do_exit=False)
    out = reporter.out.getvalue()

    failed = bool(out)

    return failed
Exemplo n.º 11
0
    def test_pylint_visit_method_taken_in_account(self):
        class CustomChecker(checkers.BaseChecker):
            __implements__ = interfaces.IAstroidChecker
            name = 'custom'
            msgs = {'W9999': ('', 'custom', '')}

            @check_messages('custom')
            def visit_class(self, _):
               pass

        self.linter.register_checker(CustomChecker(self.linter))
        self.linter.open()
        out = six.moves.StringIO()
        self.linter.set_reporter(text.TextReporter(out))
        self.linter.check('abc')
Exemplo n.º 12
0
    def test_lint_ext_module_with_file_output(self):
        self.linter.set_reporter(text.TextReporter())
        if sys.version_info < (3, 0):
            strio = 'StringIO'
        else:
            strio = 'io'
        self.linter.config.files_output = True
        pylint_strio = 'pylint_%s.txt' % strio
        files = [pylint_strio, 'pylint_global.txt']
        for file in files:
            self.addCleanup(remove, file)

        self.linter.check(strio)
        self.linter.generate_reports()
        for f in files:
            self.assertTrue(os.path.exists(f))
Exemplo n.º 13
0
 def test_lint_ext_module_with_file_output(self):
     self.linter.set_reporter(text.TextReporter())
     if sys.version_info < (3, 0):
         strio = 'StringIO'
     else:
         strio = 'io'
     self.linter.config.files_output = True
     pylint_strio = 'pylint_%s.txt' % strio
     try:
         self.linter.check(strio)
         self.assertTrue(os.path.exists(pylint_strio))
         self.assertTrue(os.path.exists('pylint_global.txt'))
     finally:
         try:
             os.remove(pylint_strio)
             os.remove('pylint_global.txt')
         except:
             pass
Exemplo n.º 14
0
    __implements__ = interfaces.IAstroidChecker
    msgs = {
        'R9991': (
            "Consider Using %s.extend(%s)",
            "consider-using-extend",
            "Consider using list.extend instead of '+=' "
            "will allow you to use",
        ),
    }

    def visit_augassign(self, node):
        try:
            for inferred in node.target.infer():
                if inferred.qname() == 'builtins.list':
                    args = (node.target.name, node.value.as_string())
                    self.add_message('consider-using-extend',
                                     node=node,
                                     args=args)
        except astroid.InferenceError:
            pass


linter = lint.PyLinter()
linter.register_checker(MyChecker(linter))
args = linter.load_command_line_configuration()
linter.set_reporter(text.TextReporter())
linter.disable('bad-option-value')
with lint.fix_import_path(args):
    linter.check(args)
linter.generate_reports()
Exemplo n.º 15
0
    def lint_py_files(self):
        """Prints a list of lint errors in the given list of Python files.

        Returns:
            TaskResult. A TaskResult object representing the result of the lint
            check.
        """
        pylintrc_path = os.path.join(os.getcwd(), '.pylintrc')
        config_pylint = '--rcfile=%s' % pylintrc_path
        config_pycodestyle = os.path.join(os.getcwd(), 'tox.ini')

        files_to_lint = self.all_filepaths
        errors_found = False
        error_messages = []
        full_error_messages = []
        name = 'Pylint'

        _batch_size = 50
        current_batch_start_index = 0
        stdout = io.StringIO()

        while current_batch_start_index < len(files_to_lint):
            # Note that this index is an exclusive upper bound -- i.e.,
            # the current batch of files ranges from 'start_index' to
            # 'end_index - 1'.
            current_batch_end_index = min(
                current_batch_start_index + _batch_size, len(files_to_lint))
            current_files_to_lint = files_to_lint[
                current_batch_start_index:current_batch_end_index]

            pylint_report = io.StringIO()
            pylinter = lint.Run(current_files_to_lint + [config_pylint],
                                reporter=text.TextReporter(pylint_report),
                                exit=False).linter

            if pylinter.msg_status != 0:
                lint_message = pylint_report.getvalue()
                full_error_messages.append(lint_message)

                pylint_error_messages = (
                    self.get_trimmed_error_output(lint_message))
                error_messages.append(pylint_error_messages)
                errors_found = True

            with linter_utils.redirect_stdout(stdout):
                # These lines invoke Pycodestyle and print its output
                # to the target stdout.
                style_guide = pycodestyle.StyleGuide(
                    config_file=config_pycodestyle)
                pycodestyle_report = style_guide.check_files(
                    paths=current_files_to_lint)

            if pycodestyle_report.get_count() != 0:
                error_message = stdout.getvalue()
                full_error_messages.append(error_message)
                error_messages.append(error_message)
                errors_found = True

            current_batch_start_index = current_batch_end_index

        return concurrent_task_utils.TaskResult(name, errors_found,
                                                error_messages,
                                                full_error_messages)
Exemplo n.º 16
0
    def _lint_py_files_for_python3_compatibility(self):
        """Prints a list of Python 3 compatibility errors in the given list of
        Python files.

        Returns:
            summary_messages: list(str). Summary of lint check.
        """
        files_to_lint = self.all_filepaths
        start_time = time.time()
        any_errors = False
        stdout = python_utils.string_io()
        summary_messages = []

        files_to_lint_for_python3_compatibility = [
            file_name for file_name in files_to_lint
            if not re.match(r'^.*python_utils.*\.py$', file_name)
        ]
        num_py_files = len(files_to_lint_for_python3_compatibility)
        if not files_to_lint_for_python3_compatibility:
            python_utils.PRINT('')
            python_utils.PRINT(
                'There are no Python files to lint for Python 3 compatibility.'
            )
            return []

        python_utils.PRINT(
            'Linting %s Python files for Python 3 compatibility.' %
            (num_py_files))

        _batch_size = 50
        current_batch_start_index = 0

        while current_batch_start_index < len(
                files_to_lint_for_python3_compatibility):
            # Note that this index is an exclusive upper bound -- i.e.,
            # the current batch of files ranges from 'start_index' to
            # 'end_index - 1'.
            current_batch_end_index = min(
                current_batch_start_index + _batch_size,
                len(files_to_lint_for_python3_compatibility))
            current_files_to_lint = files_to_lint_for_python3_compatibility[
                current_batch_start_index:current_batch_end_index]
            if self.verbose_mode_enabled:
                python_utils.PRINT(
                    'Linting Python files for Python 3 compatibility %s to %s..'
                    % (current_batch_start_index + 1, current_batch_end_index))

            with linter_utils.redirect_stdout(stdout):
                # This line invokes Pylint and prints its output
                # to the target stdout.
                python_utils.PRINT('Messages for Python 3 support:')
                pylint_report = StringMessageStream()
                pylinter_for_python3 = lint.Run(
                    current_files_to_lint + ['--py3k'],
                    reporter=text.TextReporter(pylint_report),
                    exit=False).linter

            if pylinter_for_python3.msg_status != 0:
                summary_message = stdout.getvalue()
                pylint_error_messages = (self._get_trimmed_error_output(
                    pylint_report.read()))
                summary_messages.append(pylint_error_messages)
                for message in pylint_report.read():
                    python_utils.PRINT(message)
                any_errors = True

            current_batch_start_index = current_batch_end_index

        if any_errors:
            summary_message = (
                '%s Python linting for Python 3 compatibility failed' %
                linter_utils.FAILED_MESSAGE_PREFIX)
        else:
            summary_message = (
                '%s %s Python files linted for Python 3 compatibility '
                '(%.1f secs)' %
                (linter_utils.SUCCESS_MESSAGE_PREFIX, num_py_files,
                 (time.time() - start_time)))

        python_utils.PRINT(summary_message)
        summary_messages.append(summary_message)

        python_utils.PRINT(
            'Python linting for Python 3 compatibility finished.')
        return summary_messages
Exemplo n.º 17
0
    def _lint_py_files(self, config_pylint, config_pycodestyle):
        """Prints a list of lint errors in the given list of Python files.

        Args:
            config_pylint: str. Path to the .pylintrc file.
            config_pycodestyle: str. Path to the tox.ini file.

        Returns:
            summary_messages: list(str). Summary messages of lint check.
        """
        files_to_lint = self.all_filepaths
        start_time = time.time()
        are_there_errors = False
        summary_messages = []

        num_py_files = len(files_to_lint)

        python_utils.PRINT('Linting %s Python files' % num_py_files)

        _batch_size = 50
        current_batch_start_index = 0
        stdout = python_utils.string_io()

        while current_batch_start_index < len(files_to_lint):
            # Note that this index is an exclusive upper bound -- i.e.,
            # the current batch of files ranges from 'start_index' to
            # 'end_index - 1'.
            current_batch_end_index = min(
                current_batch_start_index + _batch_size, len(files_to_lint))
            current_files_to_lint = files_to_lint[
                current_batch_start_index:current_batch_end_index]
            if self.verbose_mode_enabled:
                python_utils.PRINT(
                    'Linting Python files %s to %s...' %
                    (current_batch_start_index + 1, current_batch_end_index))

            with linter_utils.redirect_stdout(stdout):
                # This line invokes Pylint and prints its output
                # to the target stdout.
                pylint_report = StringMessageStream()
                pylinter = lint.Run(current_files_to_lint + [config_pylint],
                                    reporter=text.TextReporter(pylint_report),
                                    exit=False).linter
                # These lines invoke Pycodestyle and print its output
                # to the target stdout.
                style_guide = pycodestyle.StyleGuide(
                    config_file=config_pycodestyle)
                pycodestyle_report = style_guide.check_files(
                    paths=current_files_to_lint)

            if pylinter.msg_status != 0 or pycodestyle_report.get_count() != 0:
                summary_message = stdout.getvalue()
                for message in pylint_report.read():
                    python_utils.PRINT(message)
                pylint_error_messages = (self._get_trimmed_error_output(
                    pylint_report.read()))
                summary_messages.append(pylint_error_messages)
                python_utils.PRINT(summary_message)
                are_there_errors = True

            current_batch_start_index = current_batch_end_index

        if are_there_errors:
            summary_message = ('%s Python linting failed' %
                               (linter_utils.FAILED_MESSAGE_PREFIX))
        else:
            summary_message = ('%s %s Python files linted (%.1f secs)' %
                               (linter_utils.SUCCESS_MESSAGE_PREFIX,
                                num_py_files, time.time() - start_time))

        python_utils.PRINT(summary_message)
        summary_messages.append(summary_message)

        python_utils.PRINT('Python linting finished.')
        return summary_messages
Exemplo n.º 18
0
def main():
    usage = """ %prog [options] target

    Django Lint is a tool that statically analyses Django projects and
    applications, checking for programming errors and bad code smells. For
    example, it reports nullable "CharField" fields, as well as reporting for
    unspecified options in settings.py.

    The `target` argument is mandatory and can specify either a directory
    containing a Django project, a single application or a single file.
    """.rstrip()

    parser = OptionParser(usage=usage)
    parser.add_option(
        '-r',
        '--reports',
        dest='report',
        action='store_true',
        default=False,
        help='generate report',
    )
    parser.add_option(
        '-p',
        '--pylint',
        dest='pylint',
        action='store_true',
        default=False,
        help='run normal PyLint checks',
    )
    parser.add_option(
        '-e',
        '--errors',
        dest='errors',
        action='store_true',
        default=False,
        help='only show errors',
    )
    parser.add_option(
        '-f',
        '--format',
        dest='outputformat',
        metavar='OUTPUT',
        default='text',
        help='Set the output format. Available formats are text,'
        'parseable, colorized, msvs (visual studio) and html',
    )

    options, args = parser.parse_args()

    try:
        args[0]
    except IndexError:
        args = ['.']

    targets = [os.path.abspath(arg) for arg in args]

    for target in targets:
        if not os.path.exists(target):
            try:
                # Is target a module?
                x = __import__(args[0], locals(), globals(), [], -1)
                target = sys.modules[args[0]].__path__[0]
            except:
                pass

        if not os.path.exists(target):
            raise parser.error(
                "The specified target (%r) does not exist" \
                    % target
            )

        path = target
        while True:
            flag = False
            for django_file in ('manage.py', 'models.py', 'urls.py'):
                if os.path.exists(os.path.join(path, django_file)):
                    sys.path.insert(0, os.path.dirname(path))
                    flag = True
                    break
            if flag:
                break

            path = os.path.dirname(path)

            if path == '/':
                raise parser.error(
                    "The specified target (%r) does not appear to be part of a " \
                    "Django application" % target
                )

    try:
        import django
    except ImportError:
        print >>sys.stderr, "E: Cannot import `django' module, exiting.."
        return 1

    linter = lint.PyLinter()
    linter.set_reporter(text_reporter.TextReporter())
    linter.set_option('reports', options.report)
    linter.set_option('output-format', options.outputformat)

    if options.pylint:
        checkers.initialize(linter)
        for msg in ('C0111', 'C0301'):
            linter.disable(msg)

    AstCheckers.register(linter)

    if options.errors:
        linter.set_option('disable-msg-cat', 'WCRI')
        linter.set_option('reports', False)
        linter.set_option('persistent', False)

    linter.check(targets)

    return linter.msg_status