Example #1
0
 def __init__(self,
              test_file: FunctionalTestFile,
              config: Optional[Config] = None) -> None:
     _test_reporter = FunctionalTestReporter()
     self._linter = PyLinter()
     self._linter.set_reporter(_test_reporter)
     self._linter.config.persistent = 0
     checkers.initialize(self._linter)
     self._linter.disable("suppressed-message")
     self._linter.disable("locally-disabled")
     self._linter.disable("useless-suppression")
     try:
         self._linter.read_config_file(test_file.option_file)
         if self._linter.cfgfile_parser.has_option("MASTER",
                                                   "load-plugins"):
             plugins = utils._splitstrip(
                 self._linter.cfgfile_parser.get("MASTER", "load-plugins"))
             self._linter.load_plugin_modules(plugins)
         self._linter.load_config_file()
     except NoFileError:
         pass
     self._test_file = test_file
     self._config = config
     self._check_end_position = (
         sys.version_info >=
         self._test_file.options["min_pyver_end_position"])
Example #2
0
    def test_generate_config_disable_symbolic_names(self):
        # Test that --generate-rcfile puts symbolic names in the --disable
        # option.

        out = StringIO()
        self._run_pylint(["--generate-rcfile", "--rcfile="], out=out)

        output = out.getvalue()
        # Get rid of the pesky messages that pylint emits if the
        # configuration file is not found.
        pattern = rf"\[{MAIN_CHECKER_NAME.upper()}"
        master = re.search(pattern, output)
        assert master is not None, f"{pattern} not found in {output}"
        out = StringIO(output[master.start() :])
        parser = configparser.RawConfigParser()
        parser.read_file(out)
        messages = utils._splitstrip(parser.get("MESSAGES CONTROL", "disable"))
        assert "suppressed-message" in messages
Example #3
0
    def __init__(self, args, reporter=None, exit=True):  # pylint: disable=redefined-builtin
        self._rcfile = None
        self._plugins = []
        self.verbose = None
        try:
            preprocess_options(
                args,
                {
                    # option: (callback, takearg)
                    "init-hook": (cb_init_hook, True),
                    "rcfile": (self.cb_set_rcfile, True),
                    "load-plugins": (self.cb_add_plugins, True),
                    "verbose": (self.cb_verbose_mode, False),
                },
            )
        except ArgumentPreprocessingError as ex:
            print(ex, file=sys.stderr)
            sys.exit(32)

        self.linter = linter = self.LinterClass(
            (
                (
                    "rcfile",
                    {
                        "action": "callback",
                        "callback": Run._return_one,
                        "group": "Commands",
                        "type": "string",
                        "metavar": "<file>",
                        "help": "Specify a configuration file to load.",
                    },
                ),
                (
                    "init-hook",
                    {
                        "action":
                        "callback",
                        "callback":
                        Run._return_one,
                        "type":
                        "string",
                        "metavar":
                        "<code>",
                        "level":
                        1,
                        "help":
                        "Python code to execute, usually for sys.path "
                        "manipulation such as pygtk.require().",
                    },
                ),
                (
                    "help-msg",
                    {
                        "action":
                        "callback",
                        "type":
                        "string",
                        "metavar":
                        "<msg-id>",
                        "callback":
                        self.cb_help_message,
                        "group":
                        "Commands",
                        "help":
                        "Display a help message for the given message id and "
                        "exit. The value may be a comma separated list of message ids.",
                    },
                ),
                (
                    "list-msgs",
                    {
                        "action": "callback",
                        "metavar": "<msg-id>",
                        "callback": self.cb_list_messages,
                        "group": "Commands",
                        "level": 1,
                        "help": "Generate pylint's messages.",
                    },
                ),
                (
                    "list-msgs-enabled",
                    {
                        "action":
                        "callback",
                        "metavar":
                        "<msg-id>",
                        "callback":
                        self.cb_list_messages_enabled,
                        "group":
                        "Commands",
                        "level":
                        1,
                        "help":
                        "Display a list of what messages are enabled "
                        "and disabled with the given configuration.",
                    },
                ),
                (
                    "list-groups",
                    {
                        "action": "callback",
                        "metavar": "<msg-id>",
                        "callback": self.cb_list_groups,
                        "group": "Commands",
                        "level": 1,
                        "help": "List pylint's message groups.",
                    },
                ),
                (
                    "list-conf-levels",
                    {
                        "action": "callback",
                        "callback": cb_list_confidence_levels,
                        "group": "Commands",
                        "level": 1,
                        "help": "Generate pylint's confidence levels.",
                    },
                ),
                (
                    "list-extensions",
                    {
                        "action": "callback",
                        "callback": cb_list_extensions,
                        "group": "Commands",
                        "level": 1,
                        "help": "List available extensions.",
                    },
                ),
                (
                    "full-documentation",
                    {
                        "action": "callback",
                        "metavar": "<msg-id>",
                        "callback": self.cb_full_documentation,
                        "group": "Commands",
                        "level": 1,
                        "help": "Generate pylint's full documentation.",
                    },
                ),
                (
                    "generate-rcfile",
                    {
                        "action":
                        "callback",
                        "callback":
                        self.cb_generate_config,
                        "group":
                        "Commands",
                        "help":
                        "Generate a sample configuration file according to "
                        "the current configuration. You can put other options "
                        "before this one to get them in the generated "
                        "configuration.",
                    },
                ),
                (
                    "generate-man",
                    {
                        "action": "callback",
                        "callback": self.cb_generate_manpage,
                        "group": "Commands",
                        "help": "Generate pylint's man page.",
                        "hide": True,
                    },
                ),
                (
                    "errors-only",
                    {
                        "action":
                        "callback",
                        "callback":
                        self.cb_error_mode,
                        "short":
                        "E",
                        "help":
                        "In error mode, checkers without error messages are "
                        "disabled and for others, only the ERROR messages are "
                        "displayed, and no reports are done by default.",
                    },
                ),
                (
                    "py3k",
                    {
                        "action":
                        "callback",
                        "callback":
                        self.cb_python3_porting_mode,
                        "help":
                        "In Python 3 porting mode, all checkers will be "
                        "disabled and only messages emitted by the porting "
                        "checker will be displayed.",
                    },
                ),
                (
                    "verbose",
                    {
                        "action":
                        "callback",
                        "callback":
                        self.cb_verbose_mode,
                        "short":
                        "v",
                        "help":
                        "In verbose mode, extra non-checker-related info "
                        "will be displayed.",
                    },
                ),
            ),
            option_groups=self.option_groups,
            pylintrc=self._rcfile,
        )
        # register standard checkers
        linter.load_default_plugins()
        # load command line plugins
        linter.load_plugin_modules(self._plugins)
        # add some help section
        linter.add_help_section("Environment variables",
                                config.ENV_HELP,
                                level=1)
        # pylint: disable=bad-continuation
        linter.add_help_section(
            "Output",
            "Using the default text output, the message format is :                          \n"
            "                                                                                \n"
            "        MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE                                \n"
            "                                                                                \n"
            "There are 5 kind of message types :                                             \n"
            "    * (C) convention, for programming standard violation                        \n"
            "    * (R) refactor, for bad code smell                                          \n"
            "    * (W) warning, for python specific problems                                 \n"
            "    * (E) error, for probable bugs in the code                                  \n"
            "    * (F) fatal, if an error occurred which prevented pylint from doing further\n"
            "processing.\n",
            level=1,
        )
        linter.add_help_section(
            "Output status code",
            "Pylint should leave with following status code:                                 \n"
            "    * 0 if everything went fine                                                 \n"
            "    * 1 if a fatal message was issued                                           \n"
            "    * 2 if an error message was issued                                          \n"
            "    * 4 if a warning message was issued                                         \n"
            "    * 8 if a refactor message was issued                                        \n"
            "    * 16 if a convention message was issued                                     \n"
            "    * 32 on usage error                                                         \n"
            "                                                                                \n"
            "status 1 to 16 will be bit-ORed so you can know which different categories has\n"
            "been issued by analysing pylint output status code\n",
            level=1,
        )
        # read configuration
        linter.disable("I")
        linter.enable("c-extension-no-member")
        linter.read_config_file(verbose=self.verbose)
        config_parser = linter.cfgfile_parser
        # run init hook, if present, before loading plugins
        if config_parser.has_option("MASTER", "init-hook"):
            cb_init_hook(
                "init-hook",
                utils._unquote(config_parser.get("MASTER", "init-hook")))
        # is there some additional plugins in the file configuration, in
        if config_parser.has_option("MASTER", "load-plugins"):
            plugins = utils._splitstrip(
                config_parser.get("MASTER", "load-plugins"))
            linter.load_plugin_modules(plugins)
        # now we can load file config and command line, plugins (which can
        # provide options) have been registered
        linter.load_config_file()

        if reporter:
            # if a custom reporter is provided as argument, it may be overridden
            # by file parameters, so re-set it here, but before command line
            # parsing so it's still overrideable by command line option
            linter.set_reporter(reporter)
        try:
            args = linter.load_command_line_configuration(args)
        except SystemExit as exc:
            if exc.code == 2:  # bad options
                exc.code = 32
            raise
        if not args:
            print(linter.help())
            sys.exit(32)

        if linter.config.jobs < 0:
            print(
                "Jobs number (%d) should be greater than or equal to 0" %
                linter.config.jobs,
                file=sys.stderr,
            )
            sys.exit(32)
        if linter.config.jobs > 1 or linter.config.jobs == 0:
            if multiprocessing is None:
                print(
                    "Multiprocessing library is missing, "
                    "fallback to single process",
                    file=sys.stderr,
                )
                linter.set_option("jobs", 1)
            elif linter.config.jobs == 0:
                linter.config.jobs = _cpu_count()

        # We have loaded configuration from config file and command line. Now, we can
        # load plugin specific configuration.
        linter.load_plugin_configuration()

        linter.check(args)
        score_value = linter.generate_reports()
        if exit:
            if linter.config.exit_zero:
                sys.exit(0)
            else:
                if score_value and score_value > linter.config.fail_under:
                    sys.exit(0)
                sys.exit(self.linter.msg_status)
Example #4
0
 def cb_help_message(self, option, optname, value, parser):
     """optik callback for printing some help about a particular message"""
     self.linter.msgs_store.help_message(utils._splitstrip(value))
     sys.exit(0)
Example #5
0
 def cb_add_plugins(self, name, value):
     """callback for option preprocessing (i.e. before option parsing)"""
     self._plugins.extend(utils._splitstrip(value))
Example #6
0
def _config_initialization(
    linter: "PyLinter",
    args_list: List[str],
    reporter: Union[reporters.BaseReporter, reporters.MultiReporter, None] = None,
    config_file: Union[None, str, Path] = None,
    verbose_mode: bool = False,
) -> List[str]:
    """Parse all available options, read config files and command line arguments and
    set options accordingly.
    """
    config_file = Path(config_file) if config_file else None

    # Set the current module to the configuration file
    # to allow raising messages on the configuration file.
    linter.set_current_module(str(config_file) if config_file else None)

    # Read the configuration file
    config_file_parser = config._ConfigurationFileParser(verbose_mode, linter)
    try:
        config_data, config_args = config_file_parser.parse_config_file(
            file_path=config_file
        )
    except OSError as ex:
        print(ex, file=sys.stderr)
        sys.exit(32)

    # Run init hook, if present, before loading plugins
    if "init-hook" in config_data:
        exec(utils._unquote(config_data["init-hook"]))  # pylint: disable=exec-used

    # Load plugins if specified in the config file
    if "load-plugins" in config_data:
        linter.load_plugin_modules(utils._splitstrip(config_data["load-plugins"]))

    # pylint: disable-next=fixme
    # TODO: Remove everything until set_reporter once the optparse
    # implementation is no longer needed
    # Load optparse command line arguments
    try:
        # The parser is stored on linter.cfgfile_parser
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", category=DeprecationWarning)
            linter.read_config_file(config_file=config_file, verbose=verbose_mode)
    except OSError as ex:
        print(ex, file=sys.stderr)
        sys.exit(32)

    # Now we can load file config, plugins (which can
    # provide options) have been registered
    with warnings.catch_warnings():
        warnings.filterwarnings("ignore", category=DeprecationWarning)
        linter.load_config_file()

    # pylint: disable-next=fixme
    # TODO: Optparse: This has been disabled pre-maturely because it interferes with
    # argparse option parsing for 'disable' and 'enable'.
    # try:
    #     with warnings.catch_warnings():
    #         warnings.filterwarnings("ignore", category=DeprecationWarning)
    #         linter.load_command_line_configuration(args_list)
    # except SystemExit as exc:
    #     if exc.code == 2:  # bad options
    #         exc.code = 32
    #     raise

    # First we parse any options from a configuration file
    linter._parse_configuration_file(config_args)

    # Then, if a custom reporter is provided as argument, it may be overridden
    # by file parameters, so we re-set it here. We do this before command line
    # parsing, so it's still overridable by command line options
    if reporter:
        linter.set_reporter(reporter)

    # Now we parse any options from the command line, so they can override
    # the configuration file
    parsed_args_list = linter._parse_command_line_configuration(args_list)

    # We have loaded configuration from config file and command line. Now, we can
    # load plugin specific configuration.
    linter.load_plugin_configuration()

    # parsed_args_list should now only be a list of files/directories to lint.
    # All other options have been removed from the list.
    if not parsed_args_list:
        print(linter.help())
        sys.exit(32)

    # Now that plugins are loaded, get list of all fail_on messages, and enable them
    linter.enable_fail_on_messages()

    linter._parse_error_mode()

    return parsed_args_list
Example #7
0
def _config_initialization(
    linter: PyLinter,
    args_list: list[str],
    reporter: reporters.BaseReporter | reporters.MultiReporter | None = None,
    config_file: None | str | Path = None,
    verbose_mode: bool = False,
) -> list[str]:
    """Parse all available options, read config files and command line arguments and
    set options accordingly.
    """
    config_file = Path(config_file) if config_file else None

    # Set the current module to the configuration file
    # to allow raising messages on the configuration file.
    linter.set_current_module(str(config_file) if config_file else "")

    # Read the configuration file
    config_file_parser = _ConfigurationFileParser(verbose_mode, linter)
    try:
        config_data, config_args = config_file_parser.parse_config_file(
            file_path=config_file)
    except OSError as ex:
        print(ex, file=sys.stderr)
        sys.exit(32)

    # Run init hook, if present, before loading plugins
    if "init-hook" in config_data:
        exec(utils._unquote(config_data["init-hook"]))  # pylint: disable=exec-used

    # Load plugins if specified in the config file
    if "load-plugins" in config_data:
        linter.load_plugin_modules(
            utils._splitstrip(config_data["load-plugins"]))

    unrecognized_options_message = None
    # First we parse any options from a configuration file
    try:
        linter._parse_configuration_file(config_args)
    except _UnrecognizedOptionError as exc:
        unrecognized_options_message = ", ".join(exc.options)

    # Then, if a custom reporter is provided as argument, it may be overridden
    # by file parameters, so we re-set it here. We do this before command line
    # parsing, so it's still overridable by command line options
    if reporter:
        linter.set_reporter(reporter)

    # Set the current module to the command line
    # to allow raising messages on it
    linter.set_current_module("Command line")

    # Now we parse any options from the command line, so they can override
    # the configuration file
    parsed_args_list = linter._parse_command_line_configuration(args_list)

    # Check if there are any options that we do not recognize
    unrecognized_options: list[str] = []
    for opt in parsed_args_list:
        if opt.startswith("--"):
            unrecognized_options.append(opt[2:])
        elif opt.startswith("-"):
            unrecognized_options.append(opt[1:])
    if unrecognized_options:
        msg = ", ".join(unrecognized_options)
        linter._arg_parser.error(f"Unrecognized option found: {msg}")

    # Now that config file and command line options have been loaded
    # with all disables, it is safe to emit messages
    if unrecognized_options_message is not None:
        linter.set_current_module(str(config_file) if config_file else "")
        linter.add_message("unrecognized-option",
                           args=unrecognized_options_message,
                           line=0)

    linter._emit_stashed_messages()

    # Set the current module to configuration as we don't know where
    # the --load-plugins key is coming from
    linter.set_current_module("Command line or configuration file")

    # We have loaded configuration from config file and command line. Now, we can
    # load plugin specific configuration.
    linter.load_plugin_configuration()

    # Now that plugins are loaded, get list of all fail_on messages, and enable them
    linter.enable_fail_on_messages()

    linter._parse_error_mode()

    # Link the base Namespace object on the current directory
    linter._directory_namespaces[Path(".").resolve()] = (linter.config, {})

    # parsed_args_list should now only be a list of files/directories to lint.
    # All other options have been removed from the list.
    return parsed_args_list
Example #8
0
def _config_initialization(
    linter: "PyLinter",
    args_list: List[str],
    reporter: Union[reporters.BaseReporter, reporters.MultiReporter,
                    None] = None,
    config_file: Union[None, str, Path] = None,
    verbose_mode: Optional[bool] = None,
) -> List[str]:
    """Parse all available options, read config files and command line arguments and
    set options accordingly.
    """

    # Read the config file. The parser is stored on linter.cfgfile_parser
    try:
        linter.read_config_file(config_file=config_file, verbose=verbose_mode)
    except OSError as ex:
        print(ex, file=sys.stderr)
        sys.exit(32)
    config_parser = linter.cfgfile_parser

    # Run init hook, if present, before loading plugins
    if config_parser.has_option("MASTER", "init-hook"):
        exec(  # pylint: disable=exec-used
            utils._unquote(config_parser.get("MASTER", "init-hook")))

    # Load plugins if specified in the config file
    if config_parser.has_option("MASTER", "load-plugins"):
        plugins = utils._splitstrip(config_parser.get("MASTER",
                                                      "load-plugins"))
        linter.load_plugin_modules(plugins)

    # Now we can load file config, plugins (which can
    # provide options) have been registered
    linter.load_config_file()

    if reporter:
        # If a custom reporter is provided as argument, it may be overridden
        # by file parameters, so re-set it here, but before command line
        # parsing, so it's still overridable by command line option
        linter.set_reporter(reporter)

    # Load command line arguments
    try:
        args_list = linter.load_command_line_configuration(args_list)
    except SystemExit as exc:
        if exc.code == 2:  # bad options
            exc.code = 32
        raise

    # args_list should now only be a list of files/directories to lint. All options have
    # been removed from the list
    if not args_list:
        print(linter.help())
        sys.exit(32)

    # We have loaded configuration from config file and command line. Now, we can
    # load plugin specific configuration.
    linter.load_plugin_configuration()

    # Now that plugins are loaded, get list of all fail_on messages, and enable them
    linter.enable_fail_on_messages()

    return args_list
Example #9
0
    def __init__(
        self,
        args,
        reporter=None,
        exit=True,
        do_exit=UNUSED_PARAM_SENTINEL,
    ):  # pylint: disable=redefined-builtin
        self._rcfile = None
        self._output = None
        self._version_asked = False
        self._plugins = []
        self.verbose = None
        try:
            preprocess_options(
                args,
                {
                    # option: (callback, takearg)
                    "version": (self.version_asked, False),
                    "init-hook": (cb_init_hook, True),
                    "rcfile": (self.cb_set_rcfile, True),
                    "load-plugins": (self.cb_add_plugins, True),
                    "enable-all-extensions":
                    (self.cb_enable_all_extensions, False),
                    "verbose": (self.cb_verbose_mode, False),
                    "output": (self.cb_set_output, True),
                },
            )
        except ArgumentPreprocessingError as ex:
            print(ex, file=sys.stderr)
            sys.exit(32)

        self.linter = linter = self.LinterClass(
            (
                (
                    "rcfile",
                    {
                        "action": "callback",
                        "callback": Run._return_one,
                        "group": "Commands",
                        "type": "string",
                        "metavar": "<file>",
                        "help": "Specify a configuration file to load.",
                    },
                ),
                (
                    "output",
                    {
                        "action": "callback",
                        "callback": Run._return_one,
                        "group": "Commands",
                        "type": "string",
                        "metavar": "<file>",
                        "help": "Specify an output file.",
                    },
                ),
                (
                    "init-hook",
                    {
                        "action":
                        "callback",
                        "callback":
                        Run._return_one,
                        "type":
                        "string",
                        "metavar":
                        "<code>",
                        "level":
                        1,
                        "help":
                        "Python code to execute, usually for sys.path "
                        "manipulation such as pygtk.require().",
                    },
                ),
                (
                    "help-msg",
                    {
                        "action":
                        "callback",
                        "type":
                        "string",
                        "metavar":
                        "<msg-id>",
                        "callback":
                        self.cb_help_message,
                        "group":
                        "Commands",
                        "help":
                        "Display a help message for the given message id and "
                        "exit. The value may be a comma separated list of message ids.",
                    },
                ),
                (
                    "list-msgs",
                    {
                        "action":
                        "callback",
                        "metavar":
                        "<msg-id>",
                        "callback":
                        self.cb_list_messages,
                        "group":
                        "Commands",
                        "level":
                        1,
                        "help":
                        "Display a list of all pylint's messages divided by whether "
                        "they are emittable with the given interpreter.",
                    },
                ),
                (
                    "list-msgs-enabled",
                    {
                        "action":
                        "callback",
                        "metavar":
                        "<msg-id>",
                        "callback":
                        self.cb_list_messages_enabled,
                        "group":
                        "Commands",
                        "level":
                        1,
                        "help":
                        "Display a list of what messages are enabled, "
                        "disabled and non-emittable with the given configuration.",
                    },
                ),
                (
                    "list-groups",
                    {
                        "action": "callback",
                        "metavar": "<msg-id>",
                        "callback": self.cb_list_groups,
                        "group": "Commands",
                        "level": 1,
                        "help": "List pylint's message groups.",
                    },
                ),
                (
                    "list-conf-levels",
                    {
                        "action": "callback",
                        "callback": cb_list_confidence_levels,
                        "group": "Commands",
                        "level": 1,
                        "help": "Generate pylint's confidence levels.",
                    },
                ),
                (
                    "list-extensions",
                    {
                        "action": "callback",
                        "callback": cb_list_extensions,
                        "group": "Commands",
                        "level": 1,
                        "help": "List available extensions.",
                    },
                ),
                (
                    "full-documentation",
                    {
                        "action": "callback",
                        "metavar": "<msg-id>",
                        "callback": self.cb_full_documentation,
                        "group": "Commands",
                        "level": 1,
                        "help": "Generate pylint's full documentation.",
                    },
                ),
                (
                    "generate-rcfile",
                    {
                        "action":
                        "callback",
                        "callback":
                        self.cb_generate_config,
                        "group":
                        "Commands",
                        "help":
                        "Generate a sample configuration file according to "
                        "the current configuration. You can put other options "
                        "before this one to get them in the generated "
                        "configuration.",
                    },
                ),
                (
                    "generate-man",
                    {
                        "action": "callback",
                        "callback": self.cb_generate_manpage,
                        "group": "Commands",
                        "help": "Generate pylint's man page.",
                        "hide": True,
                    },
                ),
                (
                    "errors-only",
                    {
                        "action":
                        "callback",
                        "callback":
                        self.cb_error_mode,
                        "short":
                        "E",
                        "help":
                        "In error mode, checkers without error messages are "
                        "disabled and for others, only the ERROR messages are "
                        "displayed, and no reports are done by default.",
                    },
                ),
                (
                    "verbose",
                    {
                        "action":
                        "callback",
                        "callback":
                        self.cb_verbose_mode,
                        "short":
                        "v",
                        "help":
                        "In verbose mode, extra non-checker-related info "
                        "will be displayed.",
                    },
                ),
                (
                    "enable-all-extensions",
                    {
                        "action":
                        "callback",
                        "callback":
                        self.cb_enable_all_extensions,
                        "help":
                        "Load and enable all available extensions. "
                        "Use --list-extensions to see a list all available extensions.",
                    },
                ),
            ),
            option_groups=self.option_groups,
            pylintrc=self._rcfile,
        )
        # register standard checkers
        if self._version_asked:
            print(full_version)
            sys.exit(0)
        linter.load_default_plugins()
        # load command line plugins
        linter.load_plugin_modules(self._plugins)
        # add some help section
        linter.add_help_section(
            "Environment variables",
            f"""
The following environment variables are used:
    * PYLINTHOME
    Path to the directory where persistent data for the run will be stored. If
not found, it defaults to '{DEFAULT_PYLINT_HOME}' or '{OLD_DEFAULT_PYLINT_HOME}'
(in the current working directory).
    * PYLINTRC
    Path to the configuration file. See the documentation for the method used
to search for configuration file.
""",
            level=1,
        )
        linter.add_help_section(
            "Output",
            "Using the default text output, the message format is :                          \n"
            "                                                                                \n"
            "        MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE                                \n"
            "                                                                                \n"
            "There are 5 kind of message types :                                             \n"
            "    * (C) convention, for programming standard violation                        \n"
            "    * (R) refactor, for bad code smell                                          \n"
            "    * (W) warning, for python specific problems                                 \n"
            "    * (E) error, for probable bugs in the code                                  \n"
            "    * (F) fatal, if an error occurred which prevented pylint from doing further\n"
            "processing.\n",
            level=1,
        )
        linter.add_help_section(
            "Output status code",
            "Pylint should leave with following status code:                                 \n"
            "    * 0 if everything went fine                                                 \n"
            "    * 1 if a fatal message was issued                                           \n"
            "    * 2 if an error message was issued                                          \n"
            "    * 4 if a warning message was issued                                         \n"
            "    * 8 if a refactor message was issued                                        \n"
            "    * 16 if a convention message was issued                                     \n"
            "    * 32 on usage error                                                         \n"
            "                                                                                \n"
            "status 1 to 16 will be bit-ORed so you can know which different categories has\n"
            "been issued by analysing pylint output status code\n",
            level=1,
        )
        # read configuration
        linter.disable("I")
        linter.enable("c-extension-no-member")
        try:
            linter.read_config_file(verbose=self.verbose)
        except OSError as ex:
            print(ex, file=sys.stderr)
            sys.exit(32)

        config_parser = linter.cfgfile_parser
        # run init hook, if present, before loading plugins
        if config_parser.has_option("MASTER", "init-hook"):
            cb_init_hook(
                "init-hook",
                utils._unquote(config_parser.get("MASTER", "init-hook")))
        # is there some additional plugins in the file configuration, in
        if config_parser.has_option("MASTER", "load-plugins"):
            plugins = utils._splitstrip(
                config_parser.get("MASTER", "load-plugins"))
            linter.load_plugin_modules(plugins)
        # now we can load file config and command line, plugins (which can
        # provide options) have been registered
        linter.load_config_file()

        if reporter:
            # if a custom reporter is provided as argument, it may be overridden
            # by file parameters, so re-set it here, but before command line
            # parsing so it's still overrideable by command line option
            linter.set_reporter(reporter)
        try:
            args = linter.load_command_line_configuration(args)
        except SystemExit as exc:
            if exc.code == 2:  # bad options
                exc.code = 32
            raise
        if not args:
            print(linter.help())
            sys.exit(32)

        if linter.config.jobs < 0:
            print(
                f"Jobs number ({linter.config.jobs}) should be greater than or equal to 0",
                file=sys.stderr,
            )
            sys.exit(32)
        if linter.config.jobs > 1 or linter.config.jobs == 0:
            if multiprocessing is None:
                print(
                    "Multiprocessing library is missing, fallback to single process",
                    file=sys.stderr,
                )
                linter.set_option("jobs", 1)
            elif linter.config.jobs == 0:
                linter.config.jobs = _cpu_count()

        # We have loaded configuration from config file and command line. Now, we can
        # load plugin specific configuration.
        linter.load_plugin_configuration()

        # Now that plugins are loaded, get list of all fail_on messages, and enable them
        linter.enable_fail_on_messages()

        if self._output:
            try:
                with open(self._output, "w", encoding="utf-8") as output:
                    linter.reporter.out = output
                    linter.check(args)
                    score_value = linter.generate_reports()
            except OSError as ex:
                print(ex, file=sys.stderr)
                sys.exit(32)
        else:
            linter.check(args)
            score_value = linter.generate_reports()

        if do_exit is not UNUSED_PARAM_SENTINEL:
            warnings.warn(
                "do_exit is deprecated and it is going to be removed in a future version.",
                DeprecationWarning,
            )
            exit = do_exit

        if exit:
            if linter.config.exit_zero:
                sys.exit(0)
            elif linter.any_fail_on_issues():
                # We need to make sure we return a failing exit code in this case.
                # So we use self.linter.msg_status if that is non-zero, otherwise we just return 1.
                sys.exit(self.linter.msg_status or 1)
            elif score_value is not None:
                if score_value >= linter.config.fail_under:
                    sys.exit(0)
                else:
                    # We need to make sure we return a failing exit code in this case.
                    # So we use self.linter.msg_status if that is non-zero, otherwise we just return 1.
                    sys.exit(self.linter.msg_status or 1)
            else:
                sys.exit(self.linter.msg_status)