Question: if hasattr(module, "load_configuration"):                 module.load_configuration(self)     def _load_reporter(self):        name = self._reporter_name.lower()        if name in self._reporters:            self.set_reporter(self._reporters[name]())    def _load_reporters(self) -> None:        sub_reporters = []        output_files = []        with contextlib.ExitStack() as stack:            for reporter_name in self._reporter_names.split(","):                reporter_name, *reporter_output = reporter_name.split(":", 1)                reporter = self._load_reporter_by_name(reporter_name)                sub_reporters.append(reporter)                if reporter_output:                    (reporter_output,) = reporter_output                    # pylint: disable=consider-using-with                    output_file = stack.enter_context(open(reporter_output, "w"))                    reporter.set_output(output_file)                    output_files.append(output_file)            # Extend the lifetime of all opened output files            close_output_files = stack.pop_all().close        if len(sub_reporters) > 1 or output_files:            self.set_reporter(                reporters.MultiReporter(                    sub_reporters,                    close_output_files,                )            )         else:            try:                reporter_class = self._load_reporter_class()            except (ImportError, AttributeError) as e:                raise exceptions.InvalidReporterError(name) from e            else:                self.set_reporter(reporter_class())            self.set_reporter(sub_reporters[0])     def _load_reporter_class(self):        qname = self._reporter_name        module_part = astroid.modutils.get_module_part(qname)        module = astroid.modutils.load_module_from_name(module_part)        class_name = qname.split(".")[-1]        reporter_class = getattr(module, class_name)        return reporter_class    def _load_reporter_by_name(self, reporter_name: str) -> reporters.BaseReporter:        name = reporter_name.lower()        if name in self._reporters:            return self._reporters[name]()        try:            reporter_class = _load_reporter_by_class(reporter_name)        except (ImportError, AttributeError) as e:            raise exceptions.InvalidReporterError(name) from e        else:            return reporter_class()      def set_reporter(self, reporter):         """set the reporter used to display messages and reports"""


Question: meth(value)                 return  # no need to call set_option, disable/enable methods do it         elif optname == "output-format":            self._reporter_name = value            self._reporter_names = value             # If the reporters are already available, load             # the reporter class.             if self._reporters:                self._load_reporter()                self._load_reporters()          try:             checkers.BaseTokenChecker.set_option(self, optname, value, action, optdict)diff --git a/pylint/reporters/__init__.py b/pylint/reporters/__init__.py-- a/pylint/reporters/__init__.py++ b/pylint/reporters/__init__.py

Allow parseable output in parallel of human-readable output Currently, when selecting a format like JSON using the argument, it will replace the "normal" output. It would be nice to have it generate an output-file instead so the normal human-readable output is still there. This makes sens in a CI environment like travis or gitlab where you can see the stdout and stderr of each job but where you also want to parse the output. Allowing multiple output formats would solve this. Maybe with a new CLI argument? Or by adding a separator to the current value? For example: pylint -f # Would redirect the JSON data to and still write the normal report to stdout pylint 1.8.1, astroid 1.6.0 Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 ]


Question: from pylint.reporters.base_reporter import BaseReporter from pylint.reporters.collecting_reporter import CollectingReporter from pylint.reporters.json_reporter import JSONReporter<ins>from pylint.reporters.multi_reporter import MultiReporter</ins> from pylint.reporters.reports_handler_mix_in import ReportsHandlerMixIn


Question: utils.register_plugins(linter, __path__[0])  __all__ = ["BaseReporter", "ReportsHandlerMixIn", "JSONReporter", "CollectingReporter"]__all__ = [    "BaseReporter",    "ReportsHandlerMixIn",    "JSONReporter",    "CollectingReporter",    "MultiReporter",]diff --git a/pylint/reporters/multi_reporter.py b/pylint/reporters/multi_reporter.pynew file mode 100644-- /dev/null++ b/pylint/reporters/multi_reporter.py


Question: <ins># Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html# For details: https://github.com/PyCQA/pylint/blob/master/LICENSEimport osfrom typing import IO, Any, AnyStr, Callable, List, Mapping, Optional, Unionfrom pylint.interfaces import IReporterfrom pylint.reporters.base_reporter import BaseReporterfrom pylint.reporters.ureports.nodes import BaseLayoutAnyFile = IO[AnyStr]AnyPath = Union[str, bytes, os.PathLike]PyLinter = Anyclass MultiReporter:    """Reports messages and layouts in plain text"""    __implements__ = IReporter    name = "_internal_multi_reporter"    # Note: do not register this reporter with linter.register_reporter as it is    #       not intended to be used directly like a regular reporter, but is    #       instead used to implement the    #       `--output-format=json:somefile.json,colorized`    #       multiple output formats feature    extension = ""    def __init__(        self,        sub_reporters: List[BaseReporter],        close_output_files: Callable[[], None],        output: Optional[AnyFile] = None,    ):        self._sub_reporters = sub_reporters        self.close_output_files = close_output_files        self._path_strip_prefix = os.getcwd() + os.sep        self._linter: Optional[PyLinter] = None        self.set_output(output)    def __del__(self):        self.close_output_files()    @property    def path_strip_prefix(self) -> str:        return self._path_strip_prefix    @property    def linter(self) -> Optional[PyLinter]:        return self._linter    @linter.setter    def linter(self, value: PyLinter) -> None:        self._linter = value        for rep in self._sub_reporters:            rep.linter = value    def handle_message(self, msg: str) -> None:        """Handle a new message triggered on the current file."""        for rep in self._sub_reporters:            rep.handle_message(msg)    # pylint: disable=no-self-use    def set_output(self, output: Optional[AnyFile] = None) -> None:        """set output stream"""        # MultiReporter doesn't have it's own output. This method is only        # provided for API parity with BaseReporter and should not be called        # with non-None values for 'output'.        if output is not None:            raise NotImplementedError("MultiReporter does not support direct output.")    def writeln(self, string: str = "") -> None:        """write a line in the output buffer"""        for rep in self._sub_reporters:            rep.writeln(string)    def display_reports(self, layout: BaseLayout) -> None:        """display results encapsulated in the layout tree"""        for rep in self._sub_reporters:            rep.display_reports(layout)    def display_messages(self, layout: BaseLayout) -> None:        """hook for displaying the messages of the reporter"""        for rep in self._sub_reporters:            rep.display_messages(layout)    def on_set_current_module(self, module: str, filepath: Optional[AnyPath]) -> None:        """hook called when a module starts to be analysed"""        for rep in self._sub_reporters:            rep.on_set_current_module(module, filepath)    def on_close(        self,        stats: Mapping[Any, Any],        previous_stats: Mapping[Any, Any],    ) -> None:        """hook called when a module finished analyzing"""        for rep in self._sub_reporters:            rep.on_close(stats, previous_stats)</ins>


Question: import os import sys<ins>from typing import List, Pattern, Tuple</ins>  from astroid import modutils

Ignore clause not ignoring directories This is a different issue to . a directory and within that a directory . files and . Put syntax errors in both. , run . Pylint does not ignore , producing the message Pylint ignores the file . ignore-patterns does not skip non-top-level directories. <!-- Hi there! Thank you for discovering and submitting an issue. Before you submit this, make sure that the issue doesn't already exist or if it is not closed. Is your issue fixed on the preview release?: pip install pylint astroid --pre -U --create a (where c.py will generate a pylint message, so that we get output) (along with the appropriate \init\.py files) Run pylint: pylint --ignore-patterns=b Run pylint: pylint --ignore-patterns=a c.py is skipped for ignore-patterns=a, but not for ignore-patterns=b c.py should be skipped for both pylint 2.1.1 astroid 2.1.0-dev Python 3.6.3 (v3.6.3:, Oct 3 2017, 17:26:49) [MSC v.1900 32 bit (Intel)]


Question: return os.getcwd()  def _basename_in_ignore_list_re(base_name, ignore_list_re):    """Determines if the basename is matched in a regex ignorelist    :param str base_name: The basename of the file    :param list ignore_list_re: A collection of regex patterns to match against.        Successful matches are ignored.    :returns: `True` if the basename is ignored, `False` otherwise.    :rtype: bool    """def _is_in_ignore_list_re(element: str, ignore_list_re: List[Pattern]) -> bool:    """determines if the element is matched in a regex ignore-list"""     for file_pattern in ignore_list_re:        if file_pattern.match(base_name):        if file_pattern.match(element):             return True     return False  def expand_modules(files_or_modules, ignore_list, ignore_list_re):    """Take a list of files/modules/packages and return the list of tuple    (file, module name) which have to be actually checked."""def expand_modules(    files_or_modules: List[str],    ignore_list: List[str],    ignore_list_re: List[Pattern],    ignore_list_paths_re: List[Pattern],) -> Tuple[List[dict], List[dict]]:    """take a list of files/modules/packages and return the list of tuple    (file, module name) which have to be actually checked    """     result = []     errors = []     path = sys.path.copy()     for something in files_or_modules:         basename = os.path.basename(something)        if basename in ignore_list or _basename_in_ignore_list_re(            basename, ignore_list_re        if (            basename in ignore_list            or _is_in_ignore_list_re(os.path.basename(something), ignore_list_re)            or _is_in_ignore_list_re(something, ignore_list_paths_re)         ):             continue         module_path = get_python_path(something)


Question: ):                 if filepath == subfilepath:                     continue                if _basename_in_ignore_list_re(                if _is_in_ignore_list_re(                     os.path.basename(subfilepath), ignore_list_re                ):                ) or _is_in_ignore_list_re(subfilepath, ignore_list_paths_re):                     continue                 modpath = _modpath_from_file(                     subfilepath, is_namespace, path=additional_search_path                 )diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py-- a/pylint/lint/pylinter.py++ b/pylint/lint/pylinter.py


Question: " skipped. The regex matches against base names, not paths.",                 },             ),<ins>            (                "ignore-paths",                {                    "type": "regexp_csv",                    "metavar": "<pattern>[,<pattern>...]",                    "dest": "ignore_list_paths_re",                    "default": (),                    "help": "Add files or directories matching the regex patterns to the"                    " ignore-list. The regex matches against paths.",                },            ),</ins>             (                 "persistent",                 {


Question: def _expand_files(self, modules):         """get modules and errors from a list of modules and handle errors"""         result, errors = expand_modules(            modules, self.config.black_list, self.config.black_list_re            modules,            self.config.black_list,            self.config.black_list_re,            self.config.ignore_list_paths_re,         )         for error in errors:             message = modname = error["mod"]


Question: if isinstance(node, astroid.Instance):                 node = node._proxied             if (                isinstance(node, astroid.ClassDef)                isinstance(node, (astroid.ClassDef, astroid.Name, astroid.Subscript))                 and hasattr(node, "name")                 and not self.has_node(node)             ):diff --git a/pylint/pyreverse/inspector.py b/pylint/pyreverse/inspector.py-- a/pylint/pyreverse/inspector.py++ b/pylint/pyreverse/inspector.py

Use Python type hints for UML generation It seems that pyreverse does not read python type hints (as defined by ), and this does not help when you use as a default value : Output of pyreverse : ! I would like to see something like : in the output. pylint- 1.6.5, astroid 1.4.9 Python 3.6.0 (default, Dec 23 2016, 11:57:41) [MSC v.1900 64 bit (AMD64)]


Question: # the name has been defined as 'global' in the frame and belongs             # there.             frame = node.root()        try:            if not hasattr(frame, "locals_type"):                # If the frame doesn't have a locals_type yet,                # it means it wasn't yet visited. Visit it now                # to add what's missing from it.                if isinstance(frame, astroid.ClassDef):                    self.visit_classdef(frame)                elif isinstance(frame, astroid.FunctionDef):                    self.visit_functiondef(frame)                else:                    self.visit_module(frame)            current = frame.locals_type[node.name]            values = set(node.infer())            frame.locals_type[node.name] = list(set(current) | values)        except astroid.InferenceError:            pass        if not hasattr(frame, "locals_type"):            # If the frame doesn't have a locals_type yet,            # it means it wasn't yet visited. Visit it now            # to add what's missing from it.            if isinstance(frame, astroid.ClassDef):                self.visit_classdef(frame)            elif isinstance(frame, astroid.FunctionDef):                self.visit_functiondef(frame)            else:                self.visit_module(frame)        current = frame.locals_type[node.name]        frame.locals_type[node.name] = list(set(current) | utils.infer_node(node))      @staticmethod     def handle_assignattr_type(node, parent):


Question: handle instance_attrs_type         """        try:            values = set(node.infer())            current = set(parent.instance_attrs_type[node.attrname])            parent.instance_attrs_type[node.attrname] = list(current | values)        except astroid.InferenceError:            pass        current = set(parent.instance_attrs_type[node.attrname])        parent.instance_attrs_type[node.attrname] = list(            current | utils.infer_node(node)        )      def visit_import(self, node):         """visit an astroid.Import nodediff --git a/pylint/pyreverse/utils.py b/pylint/pyreverse/utils.py-- a/pylint/pyreverse/utils.py++ b/pylint/pyreverse/utils.py


Question: import os import re import sys<ins>from typing import Optional, Unionimport astroid</ins>  RCFILE = ".pyreverserc"


Question: if methods[1] is not None:             return methods[1](node)         return Nonedef get_annotation_label(ann: Union[astroid.Name, astroid.Subscript]) -> str:    label = ""    if isinstance(ann, astroid.Subscript):        label = ann.as_string()    elif isinstance(ann, astroid.Name):        label = ann.name    return labeldef get_annotation(    node: Union[astroid.AssignAttr, astroid.AssignName]) -> Optional[Union[astroid.Name, astroid.Subscript]]:    """return the annotation for `node`"""    ann = None    if isinstance(node.parent, astroid.AnnAssign):        ann = node.parent.annotation    elif isinstance(node, astroid.AssignAttr):        init_method = node.parent.parent        try:            annotations = dict(zip(init_method.locals, init_method.args.annotations))            ann = annotations.get(node.parent.value.name)        except AttributeError:            pass    else:        return ann    try:        default, *_ = node.infer()    except astroid.InferenceError:        default = ""    label = get_annotation_label(ann)    if ann:        label = (            rf"Optional[{label}]"            if getattr(default, "value", "value") is None            and not label.startswith("Optional")            else label        )    if label:        ann.name = label    return anndef infer_node(node: Union[astroid.AssignAttr, astroid.AssignName]) -> set:    """Return a set containing the node annotation if it exists    otherwise return a set of the inferred types using the NodeNG.infer method"""    ann = get_annotation(node)    if ann:        return {ann}    try:        return set(node.infer())    except astroid.InferenceError:        return set()diff --git a/pylint/pyreverse/writer.py b/pylint/pyreverse/writer.py-- a/pylint/pyreverse/writer.py++ b/pylint/pyreverse/writer.py


Question: import os  from pylint.graph import DotBackendfrom pylint.pyreverse.utils import is_exceptionfrom pylint.pyreverse.utils import get_annotation_label, is_exception from pylint.pyreverse.vcgutils import VCGPrinter


Question: if not self.config.only_classnames:             label = r"{}|{}\l|".format(label, r"\l".join(obj.attrs))             for func in obj.methods:                return_type = (                    f": {get_annotation_label(func.returns)}" if func.returns else ""                )                 if func.args.args:                    args = [arg.name for arg in func.args.args if arg.name != "self"]                    args = [arg for arg in func.args.args if arg.name != "self"]                 else:                     args = []                label = r"{}{}({})\l".format(label, func.name, ", ".join(args))                annotations = dict(zip(args, func.args.annotations[1:]))                for arg in args:                    annotation_label = ""                    ann = annotations.get(arg)                    if ann:                        annotation_label = get_annotation_label(ann)                    annotations[arg] = annotation_label                args = ", ".join(                    f"{arg.name}: {ann}" if ann else f"{arg.name}"                    for arg, ann in annotations.items()                )                label = fr"{label}{func.name}({args}){return_type}\l"             label = "{%s}" % label         if is_exception(obj.node):             return dict(fontcolor="red", label=label, shape="record")


Question: self._type_annotation_names.append(type_annotation.name)             return         if isinstance(type_annotation, astroid.Attribute):            self._store_type_annotation_node(type_annotation.expr)            return         if not isinstance(type_annotation, astroid.Subscript):             return diff --git a/pylint/constants.py b/pylint/constants.py-- a/pylint/constants.py++ b/pylint/constants.py

unused-import false positive for a module used in a type comment should not be emitted. Result of output: This is a follow up to .


Question: # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html # For details: https://github.com/PyCQA/pylint/blob/master/LICENSE <ins>import platform</ins> import sys  import astroid


Question: PY39_PLUS = sys.version_info[:2] >= (3, 9) PY310_PLUS = sys.version_info[:2] >= (3, 10) <ins>IS_PYPY = platform.python_implementation() == "PyPy"</ins>  PY_EXTS = (".py", ".pyc", ".pyo", ".pyw", ".so", ".dll")


Question: import pickle import sys <ins>import appdirs</ins> from pylint.config.configuration_mixin import ConfigurationMixIn from pylint.config.find_default_config_files import find_default_config_files from pylint.config.man_help_formatter import _ManHelpFormatter

Make pylint XDG Base Directory Specification compliant I have this really annoying directory in my home folder. From what I can tell (I don't do C or C++), this directory is storing data. The problem with this is, quite simply, that data storage has a designated spot. The folder. This is a part of the . A system that designates the folders for specific things like cached files (), configuration files (), and data files (), among other things. The point is to keep user home directories clean and the user sane. This should be pretty easy to implement. Simply change the variables/constants for where these files are made and stored to the appropriate directory. Simple as that, even for a large codebase (if it was done right).


Question: elif USER_HOME == "~":     PYLINT_HOME = ".pylint.d" else:    PYLINT_HOME = os.path.join(USER_HOME, ".pylint.d")    PYLINT_HOME = appdirs.user_cache_dir("pylint")    old_home = os.path.join(USER_HOME, ".pylint.d")    if os.path.exists(old_home):        print(            f"PYLINTHOME is now '{PYLINT_HOME}' but obsolescent '{old_home}' is found; "            "you can safely remove the latter",            file=sys.stderr,        )   def _get_pdata_path(base_name, recurs):


Question: signature_lines = set(             chain(                 *(                    range(func.fromlineno, func.body[0].lineno)                    range(                        func.fromlineno,                        func.body[0].lineno if func.body else func.tolineno + 1,                    )                     for func in functions                    if func.body                 )             )         )

Similarities checker with "ignore-signatures" option enabled ignores functions with docstring-only bodies follow-up. Given multiple files: : : Result of : error shouldn't be reported in this case. Note: if functions have bodies everything works correctly. You could add to the example functions above and no error would be reported. Result of output:


Question: self.add_message("import-error", args=repr(dotted_modname), node=importnode)         return None     def _add_imported_module(self, node, importedmodname):    def _add_imported_module(        self, node: Union[astroid.Import, astroid.ImportFrom], importedmodname: str    ) -> None:         """notify an imported module, used to analyze dependencies"""         module_file = node.root().file         context_name = node.root().name

Imports within TYPECHECKING can induce "cyclic-import" Suppose you have two modules: a.py and b.py. imports , but needs in order to do type annotations, then this is usually done by importing within a block. Unfortunately, this causes pylint to report . Possibly related to


Question: except ImportError:             pass <ins>        in_type_checking_block = (            isinstance(node.parent, astroid.If) and node.parent.is_typing_guard()        )</ins>         if context_name == importedmodname:             self.add_message("import-self", node=node)


Question: # update import graph             self.import_graph[context_name].add(importedmodname)            if not self.linter.is_message_enabled("cyclic-import", line=node.lineno):            if (                not self.linter.is_message_enabled("cyclic-import", line=node.lineno)                or in_type_checking_block            ):                 self._excluded_edges[context_name].add(importedmodname)      def _check_preferred_module(self, node, mod_path):


Question: if config_file is None:             config_file = self.config_file         if config_file is not None:            config_file = os.path.expanduser(config_file)            config_file = os.path.expandvars(os.path.expanduser(config_file))             if not os.path.exists(config_file):                 raise OSError(f"The config file {config_file} doesn't exist!")

Config File Does not Expand Environment Variables If a config file is provided that has an environment variable, such as "%AppData%", it fails. This can be fixed by changing from to


Question: )  import astroid<ins>from astroid.node_classes import NodeNG</ins>  from pylint.checkers import BaseChecker, MapReduceMixin, table_lines_from_stats from pylint.interfaces import IRawChecker

Ignore class methods signatures with similarities "ignore-signatures" option enabled Initial already closed issue . One more related closed question with examples . Similarities "ignore-signatures" option currently only ignores functions' signatures. Class methods won't be ignored with the current implementation which would be very useful to avoid false-negative errors for classes. With similarities "ignore-signatures" option enabled, class methods' signatures are ignored the same way as functions'.


Question: }         current_line_is_import = False     if ignore_signatures:        functions = [            n            for n in tree.body            if isinstance(n, (astroid.FunctionDef, astroid.AsyncFunctionDef))        ]        def _get_functions(functions: List[NodeNG], tree: NodeNG) -> List[NodeNG]:            """Recursively get all functions including nested in the classes from the tree."""            for node in tree.body:                if isinstance(node, (astroid.FunctionDef, astroid.AsyncFunctionDef)):                    functions.append(node)                if isinstance(                    node,                    (astroid.ClassDef, astroid.FunctionDef, astroid.AsyncFunctionDef),                ):                    _get_functions(functions, node)            return functions        functions = _get_functions([], tree)         signature_lines = set(             chain(                 *(


Question: def run(self) -> None:         """start looking for similarities and display results on stdout"""<ins>        if self.min_lines == 0:            return</ins>         self._display_sims(self._compute_sims())      def _compute_sims(self) -> List[Tuple[int, Set[LinesChunkLimits_T]]]:

Setting to should stop pylint from checking duplicate code Setting to in the rcfile doesn't disable checking for duplicate code, it instead treats every line of code as duplicate and raises many errors. Setting to should disable the duplicate code check. It works that way in many other linters (like flake8). Setting a numerical value in flake8 to (e.g. ) disables that check. requests being able to disable , but it is still open


Question: \s+         )?         (\w+)                   # Parameter name        (\*{{0,2}}\w+)          # Parameter name with potential asterisks         \s*                     # whitespace         :                       # final colon         """

args is considered as missing in documentation Hi, I met an issue with the following code: ` Return this warning: W9015: "args" missing in parameter documentation (missing-param-doc) No warning must be returned as there is a documentation concerning args pylint 2.5.3 astroid 2.4.2 Python 3.7.2 (default, Feb 25 2019, 14:07:05) [GCC 4.8.5 (Red Hat 4.8.5-36)]


Question: re_param_line = re.compile(         fr"""        \s*  \*{{0,2}}(\w+)             # identifier potentially with asterisks        \s*  (\*{{0,2}}\w+)             # identifier potentially with asterisks         \s*  ( [(]             {re_multiple_type}             (?:,\s+optional)?


Question: re_param_line = re.compile(         fr"""        \s*  (\w+)                                                          # identifier        \s*  (\*{{0,2}}\w+)                                                 # identifier with potential asterisks         \s*  :         \s*  (?:({GoogleDocstring.re_multiple_type})(?:,\s+optional)?)?     # optional type declaration         \s* (.*)                                                            # optional descriptiondiff --git a/pylint/extensions/docparams.py b/pylint/extensions/docparams.py-- a/pylint/extensions/docparams.py++ b/pylint/extensions/docparams.py


Question: }          if arguments_node.vararg is not None:            expected_argument_names.add(arguments_node.vararg)            not_needed_type_in_docstring.add(arguments_node.vararg)            expected_argument_names.add(f"*{arguments_node.vararg}")            not_needed_type_in_docstring.add(f"*{arguments_node.vararg}")         if arguments_node.kwarg is not None:            expected_argument_names.add(arguments_node.kwarg)            not_needed_type_in_docstring.add(arguments_node.kwarg)            expected_argument_names.add(f"**{arguments_node.kwarg}")            not_needed_type_in_docstring.add(f"**{arguments_node.kwarg}")         params_with_doc, params_with_type = doc.match_param_docs()         # Tolerate no parameter documentation at all.         if not params_with_doc and not params_with_type and accept_no_param_doc:diff --git a/pylint/reporters/text.py b/pylint/reporters/text.py-- a/pylint/reporters/text.py++ b/pylint/reporters/text.py


Question: :param style: the message's style elements, this will be deprecated     :param kwargs: used to accept `color` parameter while it is being deprecated    :param **kwargs: used to accept `color` parameter while it is being deprecated      :return: the ansi escaped string     """


Question: """Utility methods for docstring checking."""  import refrom typing import Listfrom typing import List, Set, Tuple  import astroid from astroid import nodes

False positive missing-param-doc on numpy style when omitted Would not have expected either or checks to have failed. VS Code 1.61.2 Windows 10 Pro 21H1 No response False positive missing-param-doc on numpy style when omitted Would not have expected either or checks to have failed. VS Code 1.61.2 Windows 10 Pro 21H1 No response


Question: re_param_line = re.compile(         fr"""        \s*  (\*{{0,2}}\w+)                                                 # identifier with potential asterisks        \s*  :        \s*  (?:({GoogleDocstring.re_multiple_type})(?:,\s+optional)?)?     # optional type declaration        \s*  (\*{{0,2}}\w+)(\s?(:|\n))                                      # identifier with potential asterisks        \s*  (?:({GoogleDocstring.re_multiple_type})(?:,\s+optional)?\n)?   # optional type declaration         \s* (.*)                                                            # optional description     """,         re.X | re.S,


Question: supports_yields = True <ins>    def match_param_docs(self) -> Tuple[Set[str], Set[str]]:        """Matches parameter documentation section to parameter documentation rules"""        params_with_doc = set()        params_with_type = set()        entries = self._parse_section(self.re_param_section)        print(entries)        entries.extend(self._parse_section(self.re_keyword_param_section))        for entry in entries:            match = self.re_param_line.match(entry)            if not match:                continue            # check if parameter has description only            re_only_desc = re.match(r"\s*  (\*{0,2}\w+)\s*:?\n", entry)            if re_only_desc:                param_name = match.group(1)                param_desc = match.group(2)                param_type = None            else:                param_name = match.group(1)                param_type = match.group(3)                param_desc = match.group(4)            if param_type:                params_with_type.add(param_name)            if param_desc:                params_with_doc.add(param_name)        return params_with_doc, params_with_type</ins>     @staticmethod     def min_section_indent(section_match):         return len(section_match.group(1))


Question: else:             readlines = stream.readlines  # type: ignore[assignment] # hint parameter is incorrectly typed as non-optional         try:            active_lines: List[str] = []            if hasattr(self, "linter"):                # Remove those lines that should be ignored because of disables                for index, line in enumerate(readlines()):                    if self.linter._is_one_message_enabled("R0801", index + 1):  # type: ignore[attr-defined]                        active_lines.append(line)            else:                active_lines = readlines()             self.linesets.append(                 LineSet(                     streamid,                    readlines(),                    active_lines,                     self.ignore_comments,                     self.ignore_docstrings,                     self.ignore_imports,

The duplicate-code (R0801) can't be disabled Originally reported by: Anonymous It's seems like it's not possible to disable the duplicate code check on portions of a file. Looking at the source, I can see why as it's not a trivial thing to do (if you want to maintain the same scope semantics as other #pylint:enable/disable comments. This would be nice to have though (or I guess I could just cleanup my duplicate code). Bitbucket:


Question: "metavar": "<python_expression>",                     "group": "Reports",                     "level": 1,                    "default": "0 if fatal else 10.0 - ((float(5 * error + warning + refactor + "                    "convention) / statement) * 10)",                    "default": "max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + "                    "convention) / statement) * 10))",                     "help": "Python expression which should return a score less "                     "than or equal to 10. You have access to the variables 'fatal', "                     "'error', 'warning', 'refactor', 'convention', and 'info' which "

The negative score is not very beginner friendly For the past months I've been under the impression that the negative score is not very friendly for beginners. It somewhat demotivating to run over your project just to get a as a score, which would make look like a super drastic tool, that's super nitpicky about everything. I think we could do a better job here at welcoming everyone to using . Instead of having a score, we could check if other tools are doing something different and see what works best in general. The negative score is not very beginner friendly For the past months I've been under the impression that the negative score is not very friendly for beginners. It somewhat demotivating to run over your project just to get a as a score, which would make look like a super drastic tool, that's super nitpicky about everything. I think we could do a better job here at welcoming everyone to using . Instead of having a score, we could check if other tools are doing something different and see what works best in general.


Question: import os import sysfrom typing import List, Optional  from pylint.__pkginfo__ import __version__  # pylint: disable=import-outside-toplevel  def run_pylint():def run_pylint(*, arguments: Optional[List[str]] = None):    """Run pylint    Arguments can be a list of strings normally supplied as arguments on the command line    """     from pylint.lint import Run as PylintRun      try:        PylintRun(sys.argv[1:])        PylintRun(arguments or sys.argv[1:])     except KeyboardInterrupt:         sys.exit(1)

Please provide a better entry point to pyreverse Currently, I have to do: I would like to do something like:


Question: EpylintRun()  def run_pyreverse():    """run pyreverse"""def run_pyreverse(*, arguments: Optional[List[str]] = None):    """Run pyreverse    Arguments can be a list of strings normally supplied as arguments on the command line    """     from pylint.pyreverse.main import Run as PyreverseRun     PyreverseRun(sys.argv[1:])    PyreverseRun(arguments or sys.argv[1:]) def run_symilar(*, arguments: Optional[List[str]] = None):    """Run symilar def run_symilar():    """run symilar"""    Arguments can be a list of strings normally supplied as arguments on the command line    """     from pylint.checkers.similar import Run as SimilarRun     SimilarRun(sys.argv[1:])    SimilarRun(arguments or sys.argv[1:])   def modify_sys_path() -> None:


Question: from pylint.lint import PyLinter from pylint.utils import get_rst_title <del># Some modules have been renamed and deprecated under their old names.# Skip documenting these modules since:# 1) They are deprecated, why document them moving forward?# 2) We can't load the deprecated module and the newly renamed module at the# same time without getting naming conflictsDEPRECATED_MODULES = ["check_docs"]  # ==> docparams</del>  def builder_inited(app):     """Output full documentation in ReST format for all extension modules"""

[crash] doc params extension: --accept-no-param-doc: conflicting option string(s) There is a crash when using the doc_params extension. No crash.


Question: doc_files = {}     for filename in os.listdir(ext_path):         name, ext = os.path.splitext(filename)        if name[0] == "_" or name in DEPRECATED_MODULES:        if name[0] == "_":             continue         if ext == ".py":             modules.append(f"pylint.extensions.{name}")diff --git a/pylint/extensions/check_docs.py b/pylint/extensions/check_docs.pydeleted file mode 100644-- a/pylint/extensions/check_docs.py++ /dev/null


Question: # Copyright (c) 2014-2015 Bruno Daniel <bruno.daniel@blue-yonder.com># Copyright (c) 2015-2016, 2018, 2020 Claudiu Popa <pcmanticore@gmail.com># Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk># Copyright (c) 2020 hippo91 <guillaume.peillex@gmail.com># Copyright (c) 2021 Pierre Sassoulas <pierre.sassoulas@gmail.com># Copyright (c) 2021 Marc Mueller <30130371+cdce8p@users.noreply.github.com># Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html# For details: https://github.com/PyCQA/pylint/blob/main/LICENSEimport warningsfrom typing import TYPE_CHECKINGfrom pylint.extensions import docparamsif TYPE_CHECKING:    from pylint.lint import PyLinterdef register(linter: "PyLinter") -> None:    warnings.warn(        "This plugin is deprecated, use pylint.extensions.docparams instead.",        DeprecationWarning,    )    linter.register_checker(docparams.DocstringParameterChecker(linter))diff --git a/pylint/lint/run.py b/pylint/lint/run.py-- a/pylint/lint/run.py++ b/pylint/lint/run.py


Question: def cb_enable_all_extensions(self, option_name: str, value: None) -> None:         """Callback to load and enable all available extensions"""         for filename in os.listdir(os.path.dirname(extensions.__file__)):            # pylint: disable=fixme            # TODO: Remove the check for deprecated check_docs after the extension has been removed            if (                filename.endswith(".py")                and not filename.startswith("_")                and not filename.startswith("check_docs")            ):            if filename.endswith(".py") and not filename.startswith("_"):                 extension_name = f"pylint.extensions.{filename[:-3]}"                 if extension_name not in self._plugins:                     self._plugins.append(extension_name)


Question: 13: string_format 14: string_constant 15: stdlib16: python316: python3 (This one was deleted but needs to be reserved for consistency with old messages) 17: refactoring . . . 24: non-ascii-names 25: unicode26-50: not yet used: reserved for future internal checkers.26: unsupported_version27-50: not yet used: reserved for future internal checkers. This file is not updated. Use    script/get_unused_message_id_category.py to get the next free checker id.diff --git a/pylint/checkers/unsupported_version.py b/pylint/checkers/unsupported_version.py-- a/pylint/checkers/unsupported_version.py++ b/pylint/checkers/unsupported_version.py

Pylint needs to forbid to re-use the msgid or symbol of old deleted msgid/symbol Right now it's possible to reuse old msgid that were removed, for example, everything from the python 3 checker (the problem was detected with `), or mixed-indentation, bad-whitespace, bad-continuation... maybe other that I don't remember that we deleted. We have a mechanism in place for renamed message with old_name, but nothing for removed message. Related to and This is going to cause occasional bug, but more than that confusion and inconsistencies when searching for the msgid online. Impossible to use an old message id or symbol.


Question: __implements__ = (IAstroidChecker,)     name = "unsupported_version"     msgs = {        "W1601": (        "W2601": (             "F-strings are not supported by all versions included in the py-version setting",             "using-f-string-in-unsupported-version",             "Used when the py-version set by the user is lower than 3.6 and pylint encounters "             "a f-string.",         ),        "W1602": (        "W2602": (             "typing.final is not supported by all versions included in the py-version setting",             "using-final-decorator-in-unsupported-version",             "Used when the py-version set by the user is lower than 3.8 and pylint encounters "diff --git a/pylint/constants.py b/pylint/constants.py-- a/pylint/constants.py++ b/pylint/constants.py


Question: # For details: https://github.com/PyCQA/pylint/blob/main/LICENSE import platform import sysfrom typing import Dictfrom typing import Dict, List, NamedTuple, Tuple  import astroid import platformdirs


Question: "class_const": "class constant",     "inlinevar": "inline iteration", }class DeletedMessage(NamedTuple):    msgid: str    symbol: str    old_names: List[Tuple[str, str]] = []DELETED_MSGID_PREFIXES = [    16,  # the PY3K+ checker, see https://github.com/PyCQA/pylint/pull/4942]DELETED_MESSAGES = [    # Everything until the next comment is from the    # PY3K+ checker, see https://github.com/PyCQA/pylint/pull/4942    DeletedMessage("W1601", "apply-builtin"),    DeletedMessage("E1601", "print-statement"),    DeletedMessage("E1602", "parameter-unpacking"),    DeletedMessage(        "E1603", "unpacking-in-except", [("W0712", "old-unpacking-in-except")]    ),    DeletedMessage("E1604", "old-raise-syntax", [("W0121", "old-old-raise-syntax")]),    DeletedMessage("E1605", "backtick", [("W0333", "old-backtick")]),    DeletedMessage("E1609", "import-star-module-level"),    DeletedMessage("W1601", "apply-builtin"),    DeletedMessage("W1602", "basestring-builtin"),    DeletedMessage("W1603", "buffer-builtin"),    DeletedMessage("W1604", "cmp-builtin"),    DeletedMessage("W1605", "coerce-builtin"),    DeletedMessage("W1606", "execfile-builtin"),    DeletedMessage("W1607", "file-builtin"),    DeletedMessage("W1608", "long-builtin"),    DeletedMessage("W1609", "raw_input-builtin"),    DeletedMessage("W1610", "reduce-builtin"),    DeletedMessage("W1611", "standarderror-builtin"),    DeletedMessage("W1612", "unicode-builtin"),    DeletedMessage("W1613", "xrange-builtin"),    DeletedMessage("W1614", "coerce-method"),    DeletedMessage("W1615", "delslice-method"),    DeletedMessage("W1616", "getslice-method"),    DeletedMessage("W1617", "setslice-method"),    DeletedMessage("W1618", "no-absolute-import"),    DeletedMessage("W1619", "old-division"),    DeletedMessage("W1620", "dict-iter-method"),    DeletedMessage("W1621", "dict-view-method"),    DeletedMessage("W1622", "next-method-called"),    DeletedMessage("W1623", "metaclass-assignment"),    DeletedMessage(        "W1624", "indexing-exception", [("W0713", "old-indexing-exception")]    ),    DeletedMessage("W1625", "raising-string", [("W0701", "old-raising-string")]),    DeletedMessage("W1626", "reload-builtin"),    DeletedMessage("W1627", "oct-method"),    DeletedMessage("W1628", "hex-method"),    DeletedMessage("W1629", "nonzero-method"),    DeletedMessage("W1630", "cmp-method"),    DeletedMessage("W1632", "input-builtin"),    DeletedMessage("W1633", "round-builtin"),    DeletedMessage("W1634", "intern-builtin"),    DeletedMessage("W1635", "unichr-builtin"),    DeletedMessage(        "W1636", "map-builtin-not-iterating", [("W1631", "implicit-map-evaluation")]    ),    DeletedMessage("W1637", "zip-builtin-not-iterating"),    DeletedMessage("W1638", "range-builtin-not-iterating"),    DeletedMessage("W1639", "filter-builtin-not-iterating"),    DeletedMessage("W1640", "using-cmp-argument"),    DeletedMessage("W1641", "eq-without-hash"),    DeletedMessage("W1642", "div-method"),    DeletedMessage("W1643", "idiv-method"),    DeletedMessage("W1644", "rdiv-method"),    DeletedMessage("W1645", "exception-message-attribute"),    DeletedMessage("W1646", "invalid-str-codec"),    DeletedMessage("W1647", "sys-max-int"),    DeletedMessage("W1648", "bad-python3-import"),    DeletedMessage("W1649", "deprecated-string-function"),    DeletedMessage("W1650", "deprecated-str-translate-call"),    DeletedMessage("W1651", "deprecated-itertools-function"),    DeletedMessage("W1652", "deprecated-types-field"),    DeletedMessage("W1653", "next-method-defined"),    DeletedMessage("W1654", "dict-items-not-iterating"),    DeletedMessage("W1655", "dict-keys-not-iterating"),    DeletedMessage("W1656", "dict-values-not-iterating"),    DeletedMessage("W1657", "deprecated-operator-function"),    DeletedMessage("W1658", "deprecated-urllib-function"),    DeletedMessage("W1659", "xreadlines-attribute"),    DeletedMessage("W1660", "deprecated-sys-function"),    DeletedMessage("W1661", "exception-escape"),    DeletedMessage("W1662", "comprehension-escape"),    # https://github.com/PyCQA/pylint/pull/3578    DeletedMessage("W0312", "mixed-indentation"),    # https://github.com/PyCQA/pylint/pull/3577    DeletedMessage(        "C0326",        "bad-whitespace",        [            ("C0323", "no-space-after-operator"),            ("C0324", "no-space-after-comma"),            ("C0322", "no-space-before-operator"),        ],    ),    # https://github.com/PyCQA/pylint/pull/3571    DeletedMessage("C0330", "bad-continuation"),]diff --git a/script/get_unused_message_id_category.py b/script/get_unused_message_id_category.py-- a/script/get_unused_message_id_category.py++ b/script/get_unused_message_id_category.py


Question: from typing import List  from pylint.checkers import initialize as initialize_checkers<ins>from pylint.constants import DELETED_MSGID_PREFIXES</ins> from pylint.extensions import initialize as initialize_extensions from pylint.lint.pylinter import PyLinter


Question: def get_next_code_category(message_ids: List[str]) -> int:     categories = sorted({int(i[:2]) for i in message_ids})<ins>    # We add the prefixes for deleted checkers    categories += DELETED_MSGID_PREFIXES</ins>     for i in categories:         if i + 1 not in categories:             return i + 1


Question: notes = "|".join(re.escape(note) for note in self.config.notes)         if self.config.notes_rgx:            regex_string = rf"#\s*({notes}|{self.config.notes_rgx})\b"            regex_string = rf"#\s*({notes}|{self.config.notes_rgx})(?=(:|\s|\Z))"         else:            regex_string = rf"#\s*({notes})\b"            regex_string = rf"#\s*({notes})(?=(:|\s|\Z))"          self._fixme_pattern = re.compile(regex_string, re.I)

"--notes" option ignores note tags that are entirely punctuation If a note tag specified with the option is entirely punctuation, pylint won't report a fixme warning (W0511). will return a fixme warning (W0511) for the first line, but not the second. macOS 11.6.1 No response


Question: from astroid import nodes  from pylint.pyreverse.printer import EdgeType, Layout, NodeProperties, NodeType, Printerfrom pylint.pyreverse.utils import check_graphviz_availability, get_annotation_labelfrom pylint.pyreverse.utils import get_annotation_label  ALLOWED_CHARSETS: FrozenSet[str] = frozenset(("utf-8", "iso-8859-1", "latin1")) SHAPES: Dict[NodeType, str] = {

DOC: pyreverse supported format not recognized missing puml, plantuml, mmd, etc Some supported formats are not listed in the error messaging: Here, I have made the mistake of prepending a to . The error output should list (and and and ) as . Without the preceding , the command runs as expected. All supported formats are listed when user makes a typo in the format argument OpenSUSE Tumbleweed


Question: with open(dot_sourcepath, "w", encoding="utf8") as outfile:             outfile.writelines(self.lines)         if target not in graphviz_extensions:            check_graphviz_availability()             use_shell = sys.platform == "win32"             subprocess.call(                 ["dot", "-T", target, dot_sourcepath, "-o", outputfile],diff --git a/pylint/pyreverse/main.py b/pylint/pyreverse/main.py-- a/pylint/pyreverse/main.py++ b/pylint/pyreverse/main.py


Question: from pylint.pyreverse import writer from pylint.pyreverse.diadefslib import DiadefsHandler from pylint.pyreverse.inspector import Linker, project_from_filesfrom pylint.pyreverse.utils import check_graphviz_availability, insert_default_optionsfrom pylint.pyreverse.utils import (    check_graphviz_availability,    check_if_graphviz_supports_format,    insert_default_options,)DIRECTLY_SUPPORTED_FORMATS = (    "dot",    "vcg",    "puml",    "plantuml",    "mmd",    "html",)  OPTIONS = (     (


Question: action="store",             default="dot",             metavar="<format>",            help="create a *.<format> output file if format available.",            help=(                f"create a *.<format> output file if format is available. Available formats are: {', '.join(DIRECTLY_SUPPORTED_FORMATS)}. "                f"Any other format will be tried to create by means of the 'dot' command line tool, which requires a graphviz installation."            ),         ),     ),     (


Question: super().__init__(usage=__doc__)         insert_default_options()         args = self.load_command_line_configuration(args)        if self.config.output_format not in (            "dot",            "vcg",            "puml",            "plantuml",            "mmd",            "html",        ):        if self.config.output_format not in DIRECTLY_SUPPORTED_FORMATS:             check_graphviz_availability()            print(                f"Format {self.config.output_format} is not supported natively. Pyreverse will try to generate it using Graphviz..."            )            check_if_graphviz_supports_format(self.config.output_format)          sys.exit(self.run(args)) diff --git a/pylint/pyreverse/utils.py b/pylint/pyreverse/utils.py-- a/pylint/pyreverse/utils.py++ b/pylint/pyreverse/utils.py


Question: import os import re import shutil<ins>import subprocess</ins> import sys from typing import Optional, Union


Question: from *.dot or *.gv into the final output format.     """     if shutil.which("dot") is None:        print("'Graphviz' needs to be installed for your chosen output format.")        sys.exit(32)def check_if_graphviz_supports_format(output_format: str) -> None:    """Check if the ``dot`` command supports the requested output format.    This is needed if image output is desired and ``dot`` is used to convert    from *.gv into the final output format.    """    dot_output = subprocess.run(        ["dot", "-T?"], capture_output=True, check=False, encoding="utf-8"    )    match = re.match(        pattern=r".*Use one of: (?P<formats>(\S*\s?)+)",        string=dot_output.stderr.strip(),    )    if not match:        print(            "Unable to determine Graphviz supported output formats. "            "Pyreverse will continue, but subsequent error messages "            "regarding the output format may come from Graphviz directly."        )        return    supported_formats = match.group("formats")    if output_format not in supported_formats.split():         print(            "The requested output format is currently not available.\n"            "Please install 'Graphviz' to have other output formats "            "than 'dot' or 'vcg'."            f"Format {output_format} is not supported by Graphviz. It supports: {supported_formats}"         )         sys.exit(32)


Question: def __gt__(self, other):         """Permit to sort a list of Checker by name."""        return f"{self.name}{self.msgs}" > (f"{other.name}{other.msgs}")        return f"{self.name}{self.msgs}" > f"{other.name}{other.msgs}"    def __eq__(self, other):        """Permit to assert Checkers are equal."""        return f"{self.name}{self.msgs}" == f"{other.name}{other.msgs}"    def __hash__(self):        """Make Checker hashable."""        return hash(f"{self.name}{self.msgs}")      def __repr__(self):         status = "Checker" if self.enabled else "Disabled checker"

Is required As noted by ,  is not currently covered. If this required then we should add a unit test, otherwise we can remove this method. N/A No response No response


Question: import re import string import warningsfrom collections.abc import Callable, Iterablefrom collections.abc import Iterable from functools import lru_cache, partial from re import Matchfrom typing import TypeVarfrom typing import Callable, TypeVar  import _string import astroid.objects from astroid import TooManyLevelsError, nodes from astroid.context import InferenceContext from pylint.checkers.base_checker import BaseChecker from pylint.constants import TYPING_TYPE_CHECKS_GUARDS  COMP_NODE_TYPES = (

Use, misuse and confusion of decorator The work on showed that specifically enabling just a single message is sometimes not working as expected. This is due to either missing message declaration in a checkers decorator. Ideally I would like to implement a new, optional checker aimed at Pylint core development and custom checker development. This checker would focus on correct message declaration and handling. I already started working on it, but noticed that there is especially quite some problems with the decorator. I totally understand that, because while being extensively used across all checker classes, there is not a single word on its purpose and effect in the documentation. Its docstring is also not really helpful, you have to dig deeper into the codebase to understand what it does. Before continuing my work on the new checker, I want to address and clarify some questions about the intended use of. After that this issue can be closed with a PR that extends the documentation, and if necessary some code changes. A brief explanation on what does: It helps the decide whether a callback for the current node type should be called or not. This is done by adding the list of messages passed in as a attribute on method object. When a checker is to the attribute: if the attribute does not exist, this method will be to the list of callbacks if it exists and at least one message of the list is enabled, this method will be to the list of callbacks otherwise, it will not be to the list of callbacks and will therefore not be executed Essentially this means: main (and only) intent of the decorator is to improve performance the does not have any effect to apply the decorator has no negative functional consequences, it only affects performance (which, of course, is always an issue) the decorator but forgetting to add messages that are emitted from this callback can lead to false negatives: if none of the messages actually included in the decorator are enabled, it will not be called the decorator to a callback that not only emits messages but also does other things can have nasty side effects (false positives, false negatives, crashes) What I want to gain a consensus on: we want to keep the name ? I don't think it really conveys the effect it has on the decorated method. shall we regard as best practice for this decorator?


Question: import re import string import warningsfrom collections.abc import Callable, Iterablefrom collections.abc import Iterable from functools import lru_cache, partial from re import Matchfrom typing import TypeVarfrom typing import Callable, TypeVar  import _string import astroid.objects from astroid import TooManyLevelsError, nodes from astroid.context import InferenceContext from pylint.checkers.base_checker import BaseChecker from pylint.constants import TYPING_TYPE_CHECKS_GUARDS  COMP_NODE_TYPES = (

Should every callback be decorated and the list of messages must always be correct and consistent, or should we rather advise to use it only in cases where we expect a significant speedup when this callback is omitted? we want to keep the restriction that this decorator only has an effect on the "top level callbacks"? Seeing that a lot of those callbacks can emit quite a lot of messages and the logic for the checks is often split up into several subfunctions, it would be more flexible and also more robust (as it is easier to keep track of the messages that need to be included in the decorator) if one could apply it on the subfunctions rather than on the top level callback. Looking over the code base there are quite a lot of places where the decorator is not used correctly: used with simply passing in all messages (which has the same effect as just omitting it): used on methods that are not a callback (which has no effect) Used, but not including all messages possibly emitted by the callback No response_


Question: )  T_Node = TypeVar("T_Node", bound=nodes.NodeNG)<ins>CheckerT = TypeVar("CheckerT", bound=BaseChecker)AstCallback = Callable[[CheckerT, T_Node], None]</ins>   class NoSuchArgumentError(Exception):


Question: )  T_Node = TypeVar("T_Node", bound=nodes.NodeNG)<ins>CheckerT = TypeVar("CheckerT", bound=BaseChecker)AstCallback = Callable[[CheckerT, T_Node], None]</ins>   class NoSuchArgumentError(Exception):


Question: return False  def check_messages(*messages: str) -> Callable:    """Decorator to store messages that are handled by a checker method."""def only_required_for_messages(*messages: str) -> Callable[[AstCallback], AstCallback]:    """Decorator to store messages that are handled by a checker method as an    attribute of the function object.    This information is used by ``ASTWalker`` to decide whether to call the decorated    method or not. If none of the messages is enabled, the method will be skipped.    Therefore, the list of messages must be well maintained at all times!    This decorator only has an effect on ``visit_*`` and ``leave_*`` methods    of a class inheriting from ``BaseChecker`` and implementing ``IAstroidChecker``.    """      def store_messages(func):         func.checks_msgs = messages


Question: return False  def check_messages(*messages: str) -> Callable:    """Decorator to store messages that are handled by a checker method."""def only_required_for_messages(*messages: str) -> Callable[[AstCallback], AstCallback]:    """Decorator to store messages that are handled by a checker method as an    attribute of the function object.    This information is used by ``ASTWalker`` to decide whether to call the decorated    method or not. If none of the messages is enabled, the method will be skipped.    Therefore, the list of messages must be well maintained at all times!    This decorator only has an effect on ``visit_*`` and ``leave_*`` methods    of a class inheriting from ``BaseChecker`` and implementing ``IAstroidChecker``.    """      def store_messages(func):         func.checks_msgs = messages


Question: return store_messages  <ins>def check_messages(*messages: str) -> Callable[[AstCallback], AstCallback]:    """Kept for backwards compatibility, deprecated.    Use only_required_for_messages instead, which conveys the intent of the decorator much clearer.    """    warnings.warn(        "utils.check_messages will be removed in favour of calling "        "utils.only_required_for_messages in pylint 3.0",        DeprecationWarning,    )    return only_required_for_messages(*messages)</ins> class IncompleteFormatString(Exception):     """A format string ended in the middle of a format specifier."""


Question: return store_messages  <ins>def check_messages(*messages: str) -> Callable[[AstCallback], AstCallback]:    """Kept for backwards compatibility, deprecated.    Use only_required_for_messages instead, which conveys the intent of the decorator much clearer.    """    warnings.warn(        "utils.check_messages will be removed in favour of calling "        "utils.only_required_for_messages in pylint 3.0",        DeprecationWarning,    )    return only_required_for_messages(*messages)</ins> class IncompleteFormatString(Exception):     """A format string ended in the middle of a format specifier."""


Question: import sys import warnings from collections import defaultdictfrom collections.abc import Generator, Iterablefrom collections.abc import Callable, Generator, Iterable from getopt import getopt from io import BufferedIOBase, BufferedReader, BytesIO from itertools import chain, groupby

Crash When parsing the following file: <!-- If sharing the code is not an option, please state so, but providing only the stacktrace would still be helpful. --pylint crashed with a and with the following stacktrace: If I remove the comment, things work as expected. If I call without , things work as expected. If I downgrade (and ) to astroid-2.9.3 pylint-2.12.2, things work as expected. No response no astroid error ;-) Fedora 35 astroid==2.11.2 dill==0.3.4 flake8==4.0.1 isort==4.3.21 lazy-object-proxy==1.7.1 mccabe==0.6.1 platformdirs==2.5.1 pycodestyle==2.8.0 pyflakes==2.4.0 pylint==2.13.5 toml==0.10.2 tomli==2.0.1 wrapt==1.13.3


Question: readlines = decoding_stream(stream, encoding).readlines         else:             readlines = stream.readlines  # type: ignore[assignment] # hint parameter is incorrectly typed as non-optional         try:            active_lines: list[str] = []            if hasattr(self, "linter"):                # Remove those lines that should be ignored because of disables                for index, line in enumerate(readlines()):                    if self.linter._is_one_message_enabled("R0801", index + 1):  # type: ignore[attr-defined]                        active_lines.append(line)            else:                active_lines = readlines()            self.linesets.append(                LineSet(                    streamid,                    active_lines,                    self.namespace.ignore_comments,                    self.namespace.ignore_docstrings,                    self.namespace.ignore_imports,                    self.namespace.ignore_signatures,                )            )            lines = readlines()         except UnicodeDecodeError:            pass            lines = []        self.linesets.append(            LineSet(                streamid,                lines,                self.namespace.ignore_comments,                self.namespace.ignore_docstrings,                self.namespace.ignore_imports,                self.namespace.ignore_signatures,                line_enabled_callback=self.linter._is_one_message_enabled  # type: ignore[attr-defined]                if hasattr(self, "linter")                else None,            )        )      def run(self) -> None:         """Start looking for similarities and display results on stdout."""


Question: ignore_docstrings: bool,     ignore_imports: bool,     ignore_signatures: bool,<ins>    line_enabled_callback: Callable[[str, int], bool] | None = None,</ins> ) -> list[LineSpecifs]:     """Return tuples of line/line number/line type with leading/trailing whitespace and any ignored code features removed.


Question: :param ignore_docstrings: if true, any line that is a docstring is removed from the result     :param ignore_imports: if true, any line that is an import is removed from the result     :param ignore_signatures: if true, any line that is part of a function signature is removed from the result<ins>    :param line_enabled_callback: If called with "R0801" and a line number, a return value of False will disregard the line</ins>     :return: the collection of line/line number/line type tuples     """     if ignore_imports or ignore_signatures:


Question: strippedlines = []     docstring = None     for lineno, line in enumerate(lines, start=1):<ins>        if line_enabled_callback is not None and not line_enabled_callback(            "R0801", lineno        ):            continue</ins>         line = line.strip()         if ignore_docstrings:             if not docstring:


Question: ignore_docstrings: bool = False,         ignore_imports: bool = False,         ignore_signatures: bool = False,        line_enabled_callback: Callable[[str, int], bool] | None = None,     ) -> None:         self.name = name         self._real_lines = lines         self._stripped_lines = stripped_lines(            lines, ignore_comments, ignore_docstrings, ignore_imports, ignore_signatures            lines,            ignore_comments,            ignore_docstrings,            ignore_imports,            ignore_signatures,            line_enabled_callback=line_enabled_callback,         )      def __str__(self):


Question: from __future__ import annotations <ins>import argparse</ins> import copy import functools import itertools

option ignored The option is ignored in 2.14. Place two files that both read like this (ideally in their own dir so you can just run that dir): Proper output in 2.12: Caused in No response No response


Question: from pylint.checkers import BaseChecker, MapReduceMixin, table_lines_from_stats from pylint.interfaces import IRawChecker from pylint.reporters.ureports.nodes import Tablefrom pylint.typing import OptionDict, Optionsfrom pylint.typing import Options from pylint.utils import LinterStats, decoding_stream  if TYPE_CHECKING:


Question: ignore_imports: bool = False,         ignore_signatures: bool = False,     ) -> None:        self.min_lines = min_lines        self.ignore_comments = ignore_comments        self.ignore_docstrings = ignore_docstrings        self.ignore_imports = ignore_imports        self.ignore_signatures = ignore_signatures        # If we run in pylint mode we link the namespace objects        if isinstance(self, BaseChecker):            self.namespace = self.linter.config        else:            self.namespace = argparse.Namespace()        self.namespace.min_similarity_lines = min_lines        self.namespace.ignore_comments = ignore_comments        self.namespace.ignore_docstrings = ignore_docstrings        self.namespace.ignore_imports = ignore_imports        self.namespace.ignore_signatures = ignore_signatures         self.linesets: list[LineSet] = []      def append_stream(


Question: LineSet(                     streamid,                     active_lines,                    self.ignore_comments,                    self.ignore_docstrings,                    self.ignore_imports,                    self.ignore_signatures,                    self.namespace.ignore_comments,                    self.namespace.ignore_docstrings,                    self.namespace.ignore_imports,                    self.namespace.ignore_signatures,                 )             )         except UnicodeDecodeError:


Question: def run(self) -> None:         """Start looking for similarities and display results on stdout."""        if self.min_lines == 0:        if self.namespace.min_similarity_lines == 0:             return         self._display_sims(self._compute_sims())


Question: hash_to_index_2: HashToIndex_T         index_to_lines_1: IndexToLines_T         index_to_lines_2: IndexToLines_T        hash_to_index_1, index_to_lines_1 = hash_lineset(lineset1, self.min_lines)        hash_to_index_2, index_to_lines_2 = hash_lineset(lineset2, self.min_lines)        hash_to_index_1, index_to_lines_1 = hash_lineset(            lineset1, self.namespace.min_similarity_lines        )        hash_to_index_2, index_to_lines_2 = hash_lineset(            lineset2, self.namespace.min_similarity_lines        )          hash_1: frozenset[LinesChunk] = frozenset(hash_to_index_1.keys())         hash_2: frozenset[LinesChunk] = frozenset(hash_to_index_2.keys())


Question: ] = CplSuccessiveLinesLimits(                     copy.copy(index_to_lines_1[index_1]),                     copy.copy(index_to_lines_2[index_2]),                    effective_cmn_lines_nb=self.min_lines,                    effective_cmn_lines_nb=self.namespace.min_similarity_lines,                 )          remove_successives(all_couples)


Question: lineset1, start_index_1, lineset2, start_index_2, nb_common_lines             )             if eff_cmn_nb > self.min_lines:            if eff_cmn_nb > self.namespace.min_similarity_lines:                 yield com      def _iter_sims(self) -> Generator[Commonality, None, None]:


Question: # reports     reports = (("RP0801", "Duplication", report_similarities),)     def __init__(self, linter=None) -> None:    def __init__(self, linter: PyLinter) -> None:         BaseChecker.__init__(self, linter)         Similar.__init__(             self,


Question: ignore_signatures=self.linter.config.ignore_signatures,         ) <del>    def set_option(        self,        optname: str,        value: Any,        action: str | None = "default_value",        optdict: None | str | OptionDict = "default_value",    ) -> None:        """Method called to set an option (registered in the options list).        Overridden to report options setting to Similar        """        # TODO: 3.0: Remove deprecated arguments. # pylint: disable=fixme        if action != "default_value":            warnings.warn(                "The 'action' argument has been deprecated. You can use set_option "                "without the 'action' or 'optdict' arguments.",                DeprecationWarning,            )        if optdict != "default_value":            warnings.warn(                "The 'optdict' argument has been deprecated. You can use set_option "                "without the 'action' or 'optdict' arguments.",                DeprecationWarning,            )        self.linter.set_option(optname, value)        if optname == "min-similarity-lines":            self.min_lines = self.linter.config.min_similarity_lines        elif optname == "ignore-comments":            self.ignore_comments = self.linter.config.ignore_comments        elif optname == "ignore-docstrings":            self.ignore_docstrings = self.linter.config.ignore_docstrings        elif optname == "ignore-imports":            self.ignore_imports = self.linter.config.ignore_imports        elif optname == "ignore-signatures":            self.ignore_signatures = self.linter.config.ignore_signatures</del>     def open(self):         """Init the checkers: reset linesets and statistics information."""         self.linesets = []


Question: kwargs: dict[str, Any],         hide_help: bool,         section: str | None,<ins>        metavar: str,</ins>     ) -> None:         super().__init__(             flags=flags, arg_help=arg_help, hide_help=hide_help, section=section

Argument expected for short verbose option The short option of the option expects an argument. Also, the help message for the option suggests a value should be provided. The long option works ok & doesn't expect an argument: Similar behaviour to the long option.


Question: self.kwargs = kwargs         """Any additional arguments passed to the action."""        self.metavar = metavar        """The metavar of the argument.        See:        https://docs.python.org/3/library/argparse.html#metavar        """diff --git a/pylint/config/arguments_manager.py b/pylint/config/arguments_manager.py-- a/pylint/config/arguments_manager.py++ b/pylint/config/arguments_manager.py


Question: **argument.kwargs,                 action=argument.action,                 help=argument.help,                metavar=argument.metavar,             )         elif isinstance(argument, _ExtendArgument):             section_group.add_argument(diff --git a/pylint/config/utils.py b/pylint/config/utils.py-- a/pylint/config/utils.py++ b/pylint/config/utils.py


Question: kwargs=optdict.get("kwargs", {}),             hide_help=optdict.get("hide", False),             section=optdict.get("group", None),<ins>            metavar=optdict.get("metavar", None),</ins>         )     try:         default = optdict["default"]


Question: "--output": (True, _set_output),     "--load-plugins": (True, _add_plugins),     "--verbose": (False, _set_verbose_mode),<ins>    "-v": (False, _set_verbose_mode),</ins>     "--enable-all-extensions": (False, _enable_all_extensions), }


Question: i = 0     while i < len(args):         argument = args[i]        if not argument.startswith("--"):        if not argument.startswith("-"):             processed_args.append(argument)             i += 1             continuediff --git a/pylint/lint/base_options.py b/pylint/lint/base_options.py-- a/pylint/lint/base_options.py++ b/pylint/lint/base_options.py


Question: "help": "In verbose mode, extra non-checker-related info "                 "will be displayed.",                 "hide_from_config_file": True,<ins>                "metavar": "",</ins>             },         ),         (


Question: "help": "Load and enable all available extensions. "                 "Use --list-extensions to see a list all available extensions.",                 "hide_from_config_file": True,<ins>                "metavar": "",</ins>             },         ),         (


Question: def __init__(self, linter: PyLinter) -> None:         """Checker instances should have the linter as argument."""<ins>        if getattr(self, "__implements__", None):            warnings.warn(                "Using the __implements__ inheritance pattern for BaseChecker is no "                "longer supported. Child classes should only inherit BaseChecker or any "                "of the other checker types from pylint.checkers.",                DeprecationWarning,            )</ins>         if self.name is not None:             self.name = self.name.lower()         self.linter = linter

Support isinstance checks through ABCMeta for checkers and reporters Currently the PyLinter categorizes checkers through the class attribute. This is not very standard, and is one more barrier for others to write plugins. I propose Changing the interfaces to have a metaclass Change PyLinter to do isinstance checks to categorize checkers/reporters in addition to keeping the old checks


Question: warnings.filterwarnings("ignore", category=DeprecationWarning)             if isinstance(self, (BaseTokenChecker, BaseRawFileChecker)):                 default_scope = WarningScope.LINE            # TODO: Interfaces: Deprecate looking for implements here # pylint: disable=fixme            # TODO: 3.0: Remove deprecated if-statement # pylint: disable=fixme             elif implements(self, (IRawChecker, ITokenChecker)):                default_scope = WarningScope.LINE                warnings.warn(  # pragma: no cover                    "Checkers should subclass BaseTokenChecker or BaseRawFileChecker"                    "instead of using the __implements__ mechanism. Use of __implements__"                    "will no longer be supported in pylint 3.0",                    DeprecationWarning,                )                default_scope = WarningScope.LINE  # pragma: no cover             else:                 default_scope = WarningScope.NODE         options = {}diff --git a/pylint/interfaces.py b/pylint/interfaces.py-- a/pylint/interfaces.py++ b/pylint/interfaces.py


Question: class Interface:     """Base class for interfaces."""     def __init__(self) -> None:        warnings.warn(            "Interface and all of its subclasses have been deprecated "            "and will be removed in pylint 3.0.",            DeprecationWarning,        )     @classmethod     def is_implemented_by(cls, instance):         with warnings.catch_warnings():diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py-- a/pylint/lint/pylinter.py++ b/pylint/lint/pylinter.py


Question: """         walker = ASTWalker(self)         _checkers = self.prepare_checkers()        with warnings.catch_warnings():            warnings.filterwarnings("ignore", category=DeprecationWarning)            tokencheckers = [                c                for c in _checkers        tokencheckers = [            c            for c in _checkers            if isinstance(c, checkers.BaseTokenChecker) and c is not self        ]        # TODO: 3.0: Remove deprecated for-loop # pylint: disable=fixme        for c in _checkers:            with warnings.catch_warnings():                warnings.filterwarnings("ignore", category=DeprecationWarning)                 if (                     interfaces.implements(c, interfaces.ITokenChecker)                    or isinstance(c, checkers.BaseTokenChecker)                )                and c is not self            ]        with warnings.catch_warnings():            warnings.filterwarnings("ignore", category=DeprecationWarning)            rawcheckers = [                c                for c in _checkers                if interfaces.implements(c, interfaces.IRawChecker)                or isinstance(c, checkers.BaseRawFileChecker)            ]                    and c not in tokencheckers                    and c is not self                ):                    tokencheckers.append(c)  # pragma: no cover                    warnings.warn(  # pragma: no cover                        "Checkers should subclass BaseTokenChecker "                        "instead of using the __implements__ mechanism. Use of __implements__ "                        "will no longer be supported in pylint 3.0",                        DeprecationWarning,                    )        rawcheckers = [            c for c in _checkers if isinstance(c, checkers.BaseRawFileChecker)        ]        # TODO: 3.0: Remove deprecated if-statement # pylint: disable=fixme        for c in _checkers:            with warnings.catch_warnings():                warnings.filterwarnings("ignore", category=DeprecationWarning)                if (                    interfaces.implements(c, interfaces.IRawChecker)                    and c not in rawcheckers                ):                    rawcheckers.append(c)  # pragma: no cover                    warnings.warn(  # pragma: no cover                        "Checkers should subclass BaseRawFileChecker "                        "instead of using the __implements__ mechanism. Use of __implements__ "                        "will no longer be supported in pylint 3.0",                        DeprecationWarning,                    )         # notify global begin         for checker in _checkers:             checker.open()diff --git a/pylint/reporters/base_reporter.py b/pylint/reporters/base_reporter.py-- a/pylint/reporters/base_reporter.py++ b/pylint/reporters/base_reporter.py


Question: import os import sys<ins>import warnings</ins> from typing import TYPE_CHECKING, TextIO from warnings import warn


Question: """Name of the reporter."""      def __init__(self, output: TextIO | None = None) -> None:<ins>        if getattr(self, "__implements__", None):            warnings.warn(                "Using the __implements__ inheritance pattern for BaseReporter is no "                "longer supported. Child classes should only inherit BaseReporter",                DeprecationWarning,            )</ins>         self.linter: PyLinter         self.section = 0         self.out: TextIO = output or sys.stdout


Question: unrecognized_options.append(opt[1:])     if unrecognized_options:         msg = ", ".join(unrecognized_options)        linter.add_message("unrecognized-option", line=0, args=msg)        raise _UnrecognizedOptionError(options=unrecognized_options)        linter._arg_parser.error(f"Unrecognized option found: {msg}")      # Set the current module to configuration as we don't know where     # the --load-plugins key is coming from

Traceback printed for unrecognized option A traceback is printed when an unrecognized option is passed to pylint. No response The top part of the current output is handy: The traceback I don't think is expected & not user-friendly. A usage tip, for example: No response No response


Question: def _confidence_transformer(value: str) -> Sequence[str]:     """Transforms a comma separated string of confidence values."""<ins>    if not value:        return interfaces.CONFIDENCE_LEVEL_NAMES</ins>     values = pylint_utils._check_csv(value)     for confidence in values:         if confidence not in interfaces.CONFIDENCE_LEVEL_NAMES:

Pylint runs unexpectedly pass if in pylintrc Runs unexpectedly pass in 2.14 if a pylintrc file has . (Default pylintrc files have . 's own config was fixed in to comment it out, but this might bite existing projects.) No response No response


Question: def _get_pdata_path(     base_name: Path, recurs: int, pylint_home: Path = Path(PYLINT_HOME) ) -> Path:    underscored_name = "_".join(str(p) for p in base_name.parts)    # We strip all characters that can't be used in a filename    # Also strip '/' and '\\' because we want to create a single file, not sub-directories    underscored_name = "_".join(        str(p.replace(":", "_").replace("/", "_").replace("\\", "_"))        for p in base_name.parts    )     return pylint_home / f"{underscored_name}_{recurs}.stats"

How does pylint decide where it should put stat files? I am from the VS Code python extension team, working on building an extension for VS Code using pylint. We have pre-release version out. An issue was reported on the extension that it creates pylint stat files in the project directory. We are not specifically passing anything to change the stat file location (see issue here ). Generally, the stat files go into pre-set directory like %USERPROFILE%/AppData/Local/pylint on windows. What can cause these to be written to the current working directory. We use pass the source code into pylint via stdin, and the only two arguments we use are , . Any clue to debug this would be helpful. I could not find fall back location for the stat files and when would the fallback location be used. We use to run pylint, and we send source to pylint via stdin. Relevant code here:


Question: return any(file_pattern.match(element) for file_pattern in ignore_list_re)  <ins>def _is_ignored_file(    element: str,    ignore_list: list[str],    ignore_list_re: list[Pattern[str]],    ignore_list_paths_re: list[Pattern[str]],) -> bool:    basename = os.path.basename(element)    return (        basename in ignore_list        or _is_in_ignore_list_re(basename, ignore_list_re)        or _is_in_ignore_list_re(element, ignore_list_paths_re)    )</ins> def expand_modules(     files_or_modules: Sequence[str],     ignore_list: list[str],

Pylint does not respect ignores in mode Pylint does not respect the , , or setting when running in recursive mode. This contradicts the documentation and seriously compromises the usefulness of recursive mode. No response All of these commands give the same output: should be ignored by all of the above commands, because it is in an ignored directory (even the first command with no ignore setting should skip it, since the default value of is . For reference, the docs for the various ignore settings from : No response No response


Question: for something in files_or_modules:         basename = os.path.basename(something)        if (            basename in ignore_list            or _is_in_ignore_list_re(os.path.basename(something), ignore_list_re)            or _is_in_ignore_list_re(something, ignore_list_paths_re)        if _is_ignored_file(            something, ignore_list, ignore_list_re, ignore_list_paths_re         ):             continue         module_path = get_python_path(something)diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py-- a/pylint/lint/pylinter.py++ b/pylint/lint/pylinter.py


Question: ) from pylint.lint.base_options import _make_linter_options from pylint.lint.caching import load_results, save_resultsfrom pylint.lint.expand_modules import expand_modulesfrom pylint.lint.expand_modules import _is_ignored_file, expand_modules from pylint.lint.message_state_handler import _MessageStateHandler from pylint.lint.parallel import check_parallel from pylint.lint.report_functions import (


Question: if not msg.may_be_emitted():                 self._msgs_state[msg.msgid] = False     @staticmethod    def _discover_files(files_or_modules: Sequence[str]) -> Iterator[str]:    def _discover_files(self, files_or_modules: Sequence[str]) -> Iterator[str]:         """Discover python modules and packages in sub-directory.          Returns iterator of paths to discovered modules and packages.


Question: if any(root.startswith(s) for s in skip_subtrees):                         # Skip subtree of already discovered package.                         continue<ins>                    if _is_ignored_file(                        root,                        self.config.ignore,                        self.config.ignore_patterns,                        self.config.ignore_paths,                    ):                        skip_subtrees.append(root)                        continue</ins>                     if "__init__.py" in files:                         skip_subtrees.append(root)                         yield root


Question: self.process_tokens(tokens)             if self._ignore_file:                 return False            # walk ast to collect line numbers            self.file_state.collect_block_lines(self.msgs_store, node)             # run raw and tokens checkers             for raw_checker in rawcheckers:                 raw_checker.process_module(node)diff --git a/pylint/utils/file_state.py b/pylint/utils/file_state.py-- a/pylint/utils/file_state.py++ b/pylint/utils/file_state.py

Can't disable bad-option-value code on a computer with a somewhat new pylint (2.4.3 in my example). Get a warning like that I want to ignore, as I'm writing code compatible with python2 and python3. said warning with . a "Bad option value" when other people run their pylint version (example: 2.3.1; and by people, sometimes I mean docker instances ran from Jenkins that I would rather not rebuild or that depend on other people and I can't modify) to disable said error with a global is ignored is ignored To be able to write code that works on several versions of pylint and not having to make sure every computer in the company and every docker container has the same pylint version.


Question: self, msgs_store: MessageDefinitionStore, module_node: nodes.Module     ) -> None:         """Walk the AST to collect block level options line numbers."""        warnings.warn(            "'collect_block_lines' has been deprecated and will be removed in pylint 3.0.",            DeprecationWarning,        )         for msg, lines in self._module_msgs_state.items():             self._raw_module_msgs_state[msg] = lines.copy()         orig_state = self._module_msgs_state.copy()         self._module_msgs_state = {}         self._suppression_mapping = {}         self._effective_max_line_number = module_node.tolineno        self._collect_block_lines(msgs_store, module_node, orig_state)        for msgid, lines in orig_state.items():            for msgdef in msgs_store.get_message_definitions(msgid):                self._set_state_on_block_lines(msgs_store, module_node, msgdef, lines)     def _collect_block_lines(    def _set_state_on_block_lines(         self,         msgs_store: MessageDefinitionStore,         node: nodes.NodeNG,        msg_state: MessageStateDict,        msg: MessageDefinition,        msg_state: dict[int, bool],     ) -> None:         """Recursively walk (depth first) AST to collect block level options        line numbers.        line numbers and set the state correctly.         """         for child in node.get_children():            self._collect_block_lines(msgs_store, child, msg_state)            self._set_state_on_block_lines(msgs_store, child, msg, msg_state)         # first child line number used to distinguish between disable         # which are the first child of scoped node with those defined later.         # For instance in the code below:


Question: firstchildlineno = node.body[0].fromlineno         else:             firstchildlineno = node.tolineno        for msgid, lines in msg_state.items():            for msg in msgs_store.get_message_definitions(msgid):                self._set_message_state_in_block(msg, lines, node, firstchildlineno)        self._set_message_state_in_block(msg, msg_state, node, firstchildlineno)      def _set_message_state_in_block(         self,


Question: if lineno > firstchildlineno:                     state = True                 first_, last_ = node.block_range(lineno)                # pylint: disable=useless-suppression                # For block nodes first_ is their definition line. For example, we                # set the state of line zero for a module to allow disabling                # invalid-name for the module. For example:                # 1. # pylint: disable=invalid-name                # 2. ...                # OR                # 1. """Module docstring"""                # 2. # pylint: disable=invalid-name                # 3. ...                #                # But if we already visited line 0 we don't need to set its state again                # 1. # pylint: disable=invalid-name                # 2. # pylint: enable=invalid-name                # 3. ...                # The state should come from line 1, not from line 2                # Therefore, if the 'fromlineno' is already in the states we just start                # with the lineno we were originally visiting.                # pylint: enable=useless-suppression                if (                    first_ == node.fromlineno                    and first_ >= firstchildlineno                    and node.fromlineno in self._module_msgs_state.get(msg.msgid, ())                ):                    first_ = lineno             else:                 first_ = lineno                 last_ = last             for line in range(first_, last_ + 1):                # do not override existing entries                if line in self._module_msgs_state.get(msg.msgid, ()):                # Do not override existing entries. This is especially important                # when parsing the states for a scoped node where some line-disables                # have already been parsed.                if (                    (                        isinstance(node, nodes.Module)                        and node.fromlineno <= line < lineno                    )                    or (                        not isinstance(node, nodes.Module)                        and node.fromlineno < line < lineno                    )                ) and line in self._module_msgs_state.get(msg.msgid, ()):                     continue                 if line in lines:  # state change in the same block                     state = lines[line]                     original_lineno = line                # Update suppression mapping                 if not state:                     self._suppression_mapping[(msg.msgid, line)] = original_lineno                else:                    self._suppression_mapping.pop((msg.msgid, line), None)                # Update message state for respective line                 try:                     self._module_msgs_state[msg.msgid][line] = state                 except KeyError:


Question: def set_msg_status(self, msg: MessageDefinition, line: int, status: bool) -> None:         """Set status (enabled/disable) for a given message at a given line."""         assert line > 0        assert self._module        # TODO: 3.0: Remove unnecessary assertion        assert self._msgs_store        # Expand the status to cover all relevant block lines        self._set_state_on_block_lines(            self._msgs_store, self._module, msg, {line: status}        )        # Store the raw value         try:            self._module_msgs_state[msg.msgid][line] = status            self._raw_module_msgs_state[msg.msgid][line] = status         except KeyError:            self._module_msgs_state[msg.msgid] = {line: status}            self._raw_module_msgs_state[msg.msgid] = {line: status}      def handle_ignored_message(         self, state_scope: Literal[0, 1, 2] | None, msgid: str, line: int | None


Question: PREPROCESSABLE_OPTIONS: dict[    str, tuple[bool, Callable[[Run, str | None], None]]    str, tuple[bool, Callable[[Run, str | None], None], int] ] = {  # pylint: disable=consider-using-namedtuple-or-dataclass    "--init-hook": (True, _init_hook),    "--rcfile": (True, _set_rcfile),    "--output": (True, _set_output),    "--load-plugins": (True, _add_plugins),    "--verbose": (False, _set_verbose_mode),    "-v": (False, _set_verbose_mode),    "--enable-all-extensions": (False, _enable_all_extensions),    # pylint: disable=wrong-spelling-in-comment    # Argparse by default allows abbreviations. It behaves differently    # if you turn this off, so we also turn it on. We mimick this    # by allowing some abbreviations or incorrect spelling here.    # The integer at the end of the tuple indicates how many letters    # should match, include the '-'. 0 indicates a full match.    #    # Clashes with --init-(import)    "--init-hook": (True, _init_hook, 8),    # Clashes with --r(ecursive)    "--rcfile": (True, _set_rcfile, 4),    # Clashes with --output(-format)    "--output": (True, _set_output, 0),    # Clashes with --lo(ng-help)    "--load-plugins": (True, _add_plugins, 5),    # Clashes with --v(ariable-rgx)    "--verbose": (False, _set_verbose_mode, 4),    "-v": (False, _set_verbose_mode, 2),    # Clashes with --enable    "--enable-all-extensions": (False, _enable_all_extensions, 9), }# pylint: enable=wrong-spelling-in-comment   def _preprocess_options(run: Run, args: Sequence[str]) -> list[str]:

Using in CLI silently fail to load the plugin See Warning that load-plugin is not the right argument.


Question: except ValueError:             option, value = argument, None         if option not in PREPROCESSABLE_OPTIONS:        matched_option = None        for option_name, data in PREPROCESSABLE_OPTIONS.items():            to_match = data[2]            if to_match == 0:                if option == option_name:                    matched_option = option_name            elif option.startswith(option_name[:to_match]):                matched_option = option_name        if matched_option is None:             processed_args.append(argument)             i += 1             continue         takearg, cb = PREPROCESSABLE_OPTIONS[option]        takearg, cb, _ = PREPROCESSABLE_OPTIONS[matched_option]          if takearg and value is None:             i += 1


Question: cpu_shares = int(file.read().rstrip())         # For AWS, gives correct value * 1024.         avail_cpu = int(cpu_shares / 1024)<ins>    # In K8s Pods also a fraction of a single core could be available    # As multiprocessing is not able to run only a "fraction" of process    # assume we have 1 CPU available    if avail_cpu == 0:        avail_cpu = 1</ins>     return avail_cpu

Running pylint in Kubernetes Pod with --jobs=0 fails I run pylint in multiple parallel stages with Jenkins at a Kubernets agent with . The newly introduced function is called to determine the number of cpus to use and returns 0 in this case. This leads to a crash of pylint because the multiprocessing needs a value 0. I checked the function and found out the following values from the files that are read in above mentioned function: This leads to the calculation then in line which is cast to an and therefore 0 then. No response I expect pylint to not crash if the number of available cpu is misscalculated in this special case. The calculated number should never be 0. A possible solution would be to append a at the end of this line. I'm not sure if the same can happen for the calculation in line though, as I don't know the exact backgrounds of that files. Ubuntu 20.04 Kubernetes Version: v1.18.6 Python 3.9.12 No response


Question: "action": _ErrorsOnlyModeAction,                 "kwargs": {"Run": self},                 "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.",                "help": "In error mode, messages with a category besides "                "ERROR or FATAL are suppressed, and no reports are done by default. "                "Error mode is compatible with disabling specific errors. ",                 "hide_from_config_file": True,             },         ),diff --git a/pylint/lint/message_state_handler.py b/pylint/lint/message_state_handler.py-- a/pylint/lint/message_state_handler.py++ b/pylint/lint/message_state_handler.py

--disable ignored when --errors-only specified a python file () with a single line import notfoundpackage --disable=E0401 --errors-only test.py_ reports *** Module test E0401: Unable to import 'notfoundpackage' (import-error) Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00) 11.5


Question: self._register_by_id_managed_msg(msgid, line, is_disabled=False)      def disable_noerror_messages(self) -> None:        for msgcat, msgids in self.linter.msgs_store._msgs_by_category.items():            # enable only messages with 'error' severity and above ('fatal')        """Disable message categories other than `error` and `fatal`."""        for msgcat in self.linter.msgs_store._msgs_by_category:             if msgcat in {"E", "F"}:                for msgid in msgids:                    self.enable(msgid)            else:                for msgid in msgids:                    self.disable(msgid)                continue            self.disable(msgcat)      def list_messages_enabled(self) -> None:         emittable, non_emittable = self.linter.msgs_store.find_emittable_messages()


Question: ignore_list_re: list[Pattern[str]],     ignore_list_paths_re: list[Pattern[str]], ) -> bool:<ins>    element = os.path.normpath(element)</ins>     basename = os.path.basename(element)     return (         basename in ignore_list

ignores When running recursively, it seems in my settings in is completely ignored src\gen* should not be checked Windows 10.0. No response


Question: continue         module_path = get_python_path(something)         additional_search_path = [".", module_path] + path        if os.path.exists(something):            # this is a file or a directory        if os.path.isfile(something) or os.path.exists(            os.path.join(something, "__init__.py")        ):            # this is a file or a directory with an explicit __init__.py             try:                 modname = ".".join(                     modutils.modpath_from_file(something, path=additional_search_path)

Linting fails if module contains module of the same name Given multiple files: Which are all empty, running fails: However, if I rename , succeeds: Alternatively, I can also , but that shouldn't be necessary anymore. Running if is present fails while searching for an file. Running if is present should succeed. Result of output: This also has some side-effects in module resolution. For example, if I create another file : With the content: Running will run fine, but will fail. Not just for module a, but for module r as well. Again, if I rename to , will work perfectly.


Question: )                 if filepath is None:                     continue            except (ImportError, SyntaxError) as ex:                # The SyntaxError is a Python bug and should be                # removed once we move away from imp.find_module: https://bugs.python.org/issue10588            except ImportError as ex:                 errors.append({"key": "fatal", "mod": modname, "ex": ex})                 continue         filepath = os.path.normpath(filepath)