] = 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)


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]:


# 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,


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 = []


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


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


**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


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"]


"--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), }


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


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


"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>             },         ),         (


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


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


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


"""         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


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


"""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


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


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:


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"


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],


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


) 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 (


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.


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


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


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:


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,


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:


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


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]:


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


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


"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


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()


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


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)


)                 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)


return version  def _regex_transformer(value: str) -> Pattern[str]:    """Return `re.compile(value)`."""    try:        return re.compile(value)    except re.error as e:        msg = f"Error in provided regular expression: {value} beginning at index {e.pos}: {e.msg}"        raise argparse.ArgumentTypeError(msg) def _regexp_csv_transfomer(value: str) -> Sequence[Pattern[str]]:     """Transforms a comma separated list of regular expressions."""     patterns: list[Pattern[str]] = []     for pattern in _csv_transformer(value):        patterns.append(re.compile(pattern))        patterns.append(_regex_transformer(pattern))     return patterns


"non_empty_string": _non_empty_string_transformer,     "path": _path_transformer,     "py_version": _py_version_transformer,    "regexp": re.compile,    "regexp": _regex_transformer,     "regexp_csv": _regexp_csv_transfomer,     "regexp_paths_csv": _regexp_paths_csv_transfomer,     "string": pylint_utils._unquote,


if pylint is installed in an editable configuration (as the last item).       https://github.com/PyCQA/pylint/issues/4161     """    sys.path.pop(0)    env_pythonpath = os.environ.get("PYTHONPATH", "")     cwd = os.getcwd()    if sys.path[0] in ("", ".", cwd):        sys.path.pop(0)    env_pythonpath = os.environ.get("PYTHONPATH", "")     if env_pythonpath.startswith(":") and env_pythonpath not in (f":{cwd}", ":."):         sys.path.pop(0)     elif env_pythonpath.endswith(":") and env_pythonpath not in (f"{cwd}:", ".:"):


self._template = template          # Check to see if all parameters in the template are attributes of the Message        arguments = re.findall(r"\{(.+?)(:.*)?\}", template)        arguments = re.findall(r"\{(\w+?)(:.*)?\}", template)         for argument in arguments:             if argument[0] not in MESSAGE_FIELDS:                 warnings.warn(


"help": "Allow wildcard imports from modules that define __all__.",             },         ),<ins>        (            "allow-reexport-from-package",            {                "default": False,                "type": "yn",                "metavar": "<y or n>",                "help": "Allow explicit reexports by alias from a package __init__.",            },        ),</ins>     )      def __init__(self, linter: PyLinter) -> None:


self.linter.stats = self.linter.stats         self.import_graph = defaultdict(set)         self._module_pkg = {}  # mapping of modules to the pkg they belong in<ins>        self._current_module_package = False</ins>         self._excluded_edges: defaultdict[str, set[str]] = defaultdict(set)         self._ignored_modules: Sequence[str] = self.linter.config.ignored_modules         # Build a mapping {'module': 'preferred-module'}


if ":" in module         )         self._allow_any_import_level = set(self.linter.config.allow_any_import_level)<ins>        self._allow_reexport_package = self.linter.config.allow_reexport_from_package</ins>      def _import_graph_without_ignored_edges(self) -> defaultdict[str, set[str]]:         filtered_graph = copy.deepcopy(self.import_graph)


all_deprecated_modules = all_deprecated_modules.union(mod_set)         return all_deprecated_modules <ins>    def visit_module(self, node: nodes.Module) -> None:        """Store if current module is a package, i.e. an __init__ file."""        self._current_module_package = node.package</ins>     def visit_import(self, node: nodes.Import) -> None:         """Triggered when an import statement is seen."""         self._check_reimport(node)


if import_name != aliased_name:                 continue             if len(splitted_packages) == 1:                self.add_message("useless-import-alias", node=node)            if len(splitted_packages) == 1 and (                self._allow_reexport_package is False                or self._current_module_package is False            ):                self.add_message("useless-import-alias", node=node, confidence=HIGH)             elif len(splitted_packages) == 2:                 self.add_message(                     "consider-using-from-import",


break             try:                 module = next(module.getattr(name)[0].infer())                if module is astroid.Uninferable:                if not isinstance(module, nodes.Module):                     return None             except astroid.NotFoundError:                 if module.name in self._ignored_modules:


import re import sys from collections.abc import Callable<ins>from glob import glob</ins> from typing import Any, Pattern, Sequence, Tuple, Union  from pylint import interfaces


return os.path.expandvars(os.path.expanduser(value))  def _paths_csv_transformer(value: str) -> Sequence[str]:def _glob_paths_csv_transformer(value: str) -> Sequence[str]:     """Transforms a comma separated list of paths while expanding user and    variables.    variables and glob patterns.     """     paths: list[str] = []     for path in _csv_transformer(value):        paths.append(os.path.expandvars(os.path.expanduser(path)))        paths.extend(glob(_path_transformer(path), recursive=True))     return paths


"confidence": _confidence_transformer,     "non_empty_string": _non_empty_string_transformer,     "path": _path_transformer,    "paths_csv": _paths_csv_transformer,    "glob_paths_csv": _glob_paths_csv_transformer,     "py_version": _py_version_transformer,     "regexp": _regex_transformer,     "regexp_csv": _regexp_csv_transfomer,diff --git a/pylint/config/option.py b/pylint/config/option.py-- a/pylint/config/option.py++ b/pylint/config/option.py


"string": utils._unquote,     "int": int,     "float": float,    "paths_csv": _csv_validator,    "glob_paths_csv": _csv_validator,     "regexp": lambda pattern: re.compile(pattern or ""),     "regexp_csv": _regexp_csv_validator,     "regexp_paths_csv": _regexp_paths_csv_validator,


# pylint: disable=no-member class Option(optparse.Option):     TYPES = optparse.Option.TYPES + (        "paths_csv",        "glob_paths_csv",         "regexp",         "regexp_csv",         "regexp_paths_csv",


)     ATTRS = optparse.Option.ATTRS + ["hide", "level"]     TYPE_CHECKER = copy.copy(optparse.Option.TYPE_CHECKER)    TYPE_CHECKER["paths_csv"] = _csv_validator    TYPE_CHECKER["glob_paths_csv"] = _csv_validator     TYPE_CHECKER["regexp"] = _regexp_validator     TYPE_CHECKER["regexp_csv"] = _regexp_csv_validator     TYPE_CHECKER["regexp_paths_csv"] = _regexp_paths_csv_validatordiff --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


(             "source-roots",             {                "type": "paths_csv",                "type": "glob_paths_csv",                 "metavar": "<path>[,<path>...]",                 "default": (),                "help": "Add paths to the list of the source roots. The source root is an absolute "                "path or a path relative to the current working directory used to "                "determine a package namespace for modules located under the source root.",                "help": "Add paths to the list of the source roots. Supports globbing patterns. "                "The source root is an absolute path or a path relative to the current working "                "directory used to determine a package namespace for modules located under the "                "source root.",             },         ),         (diff --git a/pylint/pyreverse/main.py b/pylint/pyreverse/main.py-- a/pylint/pyreverse/main.py++ b/pylint/pyreverse/main.py


(         "source-roots",         {            "type": "paths_csv",            "type": "glob_paths_csv",             "metavar": "<path>[,<path>...]",             "default": (),            "help": "Add paths to the list of the source roots. The source root is an absolute "            "path or a path relative to the current working directory used to "            "determine a package namespace for modules located under the source root.",            "help": "Add paths to the list of the source roots. Supports globbing patterns. The "            "source root is an absolute path or a path relative to the current working directory "            "used to determine a package namespace for modules located under the source root.",         },     ), )


from __future__ import annotations  import sys<ins>from glob import globfrom itertools import chain</ins> from pathlib import Path from typing import TYPE_CHECKING


# Link the base Namespace object on the current directory     linter._directory_namespaces[Path(".").resolve()] = (linter.config, {})     # parsed_args_list should now only be a list of files/directories to lint.    # parsed_args_list should now only be a list of inputs to lint.     # All other options have been removed from the list.    return parsed_args_list    return list(        chain.from_iterable(            # NOTE: 'or [arg]' is needed in the case the input file or directory does not exist and 'glob(arg)' cannot            # find anything. Without this we would not be able to output the fatal import error for this module later            # on, as it would get silently ignored.            glob(arg, recursive=True) or [arg]            for arg in parsed_args_list        )    )


_worker_linter.set_reporter(reporters.CollectingReporter())     _worker_linter.open()     # Re-register dynamic plugins, since the pool does not have access to the    # astroid module that existed when the linter was pickled.    _worker_linter.load_plugin_modules(_worker_linter._dynamic_plugins, force=True)    _worker_linter.load_plugin_configuration()     if extra_packages_paths:         _augment_sys_path(extra_packages_paths) diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py-- a/pylint/lint/pylinter.py++ b/pylint/lint/pylinter.py


import tokenize import traceback from collections import defaultdictfrom collections.abc import Callable, Iterator, Sequencefrom collections.abc import Callable, Iterable, Iterator, Sequence from io import TextIOWrapper from pathlib import Path from re import Pattern


checkers.initialize(self)         reporters.initialize(self)     def load_plugin_modules(self, modnames: list[str]) -> None:    def load_plugin_modules(self, modnames: Iterable[str], force: bool = False) -> None:         """Check a list of pylint plugins modules, load and register them.          If a module cannot be loaded, never try to load it again and instead         store the error message for later use in ``load_plugin_configuration``         below.        If `force` is True (useful when multiprocessing), then the plugin is        reloaded regardless if an entry exists in self._dynamic_plugins.         """         for modname in modnames:            if modname in self._dynamic_plugins:            if modname in self._dynamic_plugins and not force:                 continue             try:                 module = astroid.modutils.load_module_from_name(modname)


"""Reduces and recombines data into a format that we can report on.          The partner function of get_map_data()        Calls self.close() to actually calculate and report duplicate code.         """         Similar.combine_mapreduce_data(self, linesets_collection=data)        self.close()   def register(linter: PyLinter) -> None:diff --git a/pylint/lint/parallel.py b/pylint/lint/parallel.py-- a/pylint/lint/parallel.py++ b/pylint/lint/parallel.py


"""Use the given linter to lint the files with given amount of workers (jobs).      This splits the work filestream-by-filestream. If you need to do work across    multiple files, as in the similarity-checker, then implement the map/reduce mixin functionality.    multiple files, as in the similarity-checker, then implement the map/reduce functionality.     """     # The linter is inherited by all the pool's workers, i.e. the linter     # is identical to the linter object here. This is required so that


sys.exit(code)             return         # Display help messages if there are no files to lint        if not args:            print(linter.help())        # Display help if there are no files to lint or no checks enabled        if not args or len(linter.config.disable) == len(            linter.msgs_store._messages_definitions        ):            print("No files to lint: exiting.")             sys.exit(32)          if linter.config.jobs < 0:


from pylint import reporters from pylint.config.config_file_parser import _ConfigurationFileParserfrom pylint.config.exceptions import _UnrecognizedOptionErrorfrom pylint.config.exceptions import (    ArgumentPreprocessingError,    _UnrecognizedOptionError,) from pylint.utils import utils  if TYPE_CHECKING:


print(ex, file=sys.stderr)         sys.exit(32) <ins>    # Order --enable=all or --disable=all to come first.    config_args = _order_all_first(config_args, joined=False)</ins>     # Run init hook, if present, before loading plugins     if "init-hook" in config_data:         exec(utils._unquote(config_data["init-hook"]))  # pylint: disable=exec-used


# Now we parse any options from the command line, so they can override     # the configuration file<ins>    args_list = _order_all_first(args_list, joined=True)</ins>     parsed_args_list = linter._parse_command_line_configuration(args_list)      # Remove the positional arguments separator from the list of arguments if it exists


for arg in parsed_args_list         )     )<ins>def _order_all_first(config_args: list[str], *, joined: bool) -> list[str]:    """Reorder config_args such that --enable=all or --disable=all comes first.    Raise if both are given.    If joined is True, expect args in the form '--enable=all,for-any-all'.    If joined is False, expect args in the form '--enable', 'all,for-any-all'.    """    indexes_to_prepend = []    all_action = ""    for i, arg in enumerate(config_args):        if joined and (arg.startswith("--enable=") or arg.startswith("--disable=")):            value = arg.split("=")[1]        elif arg in {"--enable", "--disable"}:            value = config_args[i + 1]        else:            continue        if "all" not in (msg.strip() for msg in value.split(",")):            continue        arg = arg.split("=")[0]        if all_action and (arg != all_action):            raise ArgumentPreprocessingError(                "--enable=all and --disable=all are incompatible."            )        all_action = arg        indexes_to_prepend.append(i)        if not joined:            indexes_to_prepend.append(i + 1)    returned_args = []    for i in indexes_to_prepend:        returned_args.append(config_args[i])    for i, arg in enumerate(config_args):        if i in indexes_to_prepend:            continue        returned_args.append(arg)    return returned_args</ins>


def _regexp_csv_transfomer(value: str) -> Sequence[Pattern[str]]:     """Transforms a comma separated list of regular expressions."""     patterns: list[Pattern[str]] = []    for pattern in _csv_transformer(value):    for pattern in pylint_utils._check_regexp_csv(value):         patterns.append(_regex_transformer(pattern))     return patterns diff --git a/pylint/utils/__init__.py b/pylint/utils/__init__.py-- a/pylint/utils/__init__.py++ b/pylint/utils/__init__.py


HAS_ISORT_5,     IsortDriver,     _check_csv,<ins>    _check_regexp_csv,</ins>     _splitstrip,     _unquote,     decoding_stream,


"HAS_ISORT_5",     "IsortDriver",     "_check_csv",    "_check_regexp_csv",     "_splitstrip",     "_unquote",     "decoding_stream",diff --git a/pylint/utils/utils.py b/pylint/utils/utils.py-- a/pylint/utils/utils.py++ b/pylint/utils/utils.py


import textwrap import tokenize import warningsfrom collections.abc import Sequencefrom collections import dequefrom collections.abc import Iterable, Sequence from io import BufferedReader, BytesIO from typing import (     TYPE_CHECKING,


return _splitstrip(value)  <ins>def _check_regexp_csv(value: list[str] | tuple[str] | str) -> Iterable[str]:    r"""Split a comma-separated list of regexps, taking care to avoid splitting    a regex employing a comma as quantifier, as in `\d{1,2}`."""    if isinstance(value, (list, tuple)):        yield from value    else:        # None is a sentinel value here        regexps: deque[deque[str] | None] = deque([None])        open_braces = False        for char in value:            if char == "{":                open_braces = True            elif char == "}" and open_braces:                open_braces = False            if char == "," and not open_braces:                regexps.append(None)            elif regexps[-1] is None:                regexps.pop()                regexps.append(deque([char]))            else:                regexps[-1].append(char)        yield from ("".join(regexp).strip() for regexp in regexps if regexp is not None)</ins> def _comment(string: str) -> str:     """Return string as a comment."""     lines = [line.strip() for line in string.splitlines()]


CONFIDENCE_LEVELS = [HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, UNDEFINED] CONFIDENCE_LEVEL_NAMES = [i.name for i in CONFIDENCE_LEVELS]CONFIDENCE_MAP = {i.name: i for i in CONFIDENCE_LEVELS}diff --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


"metavar": "<format>",                 "short": "f",                 "group": "Reports",                "help": "Set the output format. Available formats are text,"                " parseable, colorized, json and msvs (visual studio)."                " You can also give a reporter class, e.g. mypackage.mymodule."                "help": "Set the output format. Available formats are: text, "                "parseable, colorized, json2 (improved json format), json "                "(old json format) and msvs (visual studio). "                "You can also give a reporter class, e.g. mypackage.mymodule."                 "MyReporterClass.",                 "kwargs": {"linter": linter},             },diff --git a/pylint/reporters/__init__.py b/pylint/reporters/__init__.py-- a/pylint/reporters/__init__.py++ b/pylint/reporters/__init__.py


from pylint import utils from pylint.reporters.base_reporter import BaseReporter from pylint.reporters.collecting_reporter import CollectingReporterfrom pylint.reporters.json_reporter import JSONReporterfrom pylint.reporters.json_reporter import JSON2Reporter, JSONReporter from pylint.reporters.multi_reporter import MultiReporter from pylint.reporters.reports_handler_mix_in import ReportsHandlerMixIn


"BaseReporter",     "ReportsHandlerMixIn",     "JSONReporter",    "JSON2Reporter",     "CollectingReporter",     "MultiReporter", ]diff --git a/pylint/reporters/json_reporter.py b/pylint/reporters/json_reporter.py-- a/pylint/reporters/json_reporter.py++ b/pylint/reporters/json_reporter.py


import json from typing import TYPE_CHECKING, Optional, TypedDict from pylint.interfaces import UNDEFINEDfrom pylint.interfaces import CONFIDENCE_MAP, UNDEFINED from pylint.message import Message from pylint.reporters.base_reporter import BaseReporter from pylint.typing import MessageLocationTuple


)  class BaseJSONReporter(BaseReporter):    """Report messages and layouts in JSON."""class JSONReporter(BaseReporter):    """Report messages and layouts in JSON.    Consider using JSON2Reporter instead, as it is superior and this reporter    is no longer maintained.    """      name = "json"     extension = "json"


def _display(self, layout: Section) -> None:         """Do nothing.""" <del>    @staticmethod    def serialize(message: Message) -> OldJsonExport:        raise NotImplementedError    @staticmethod    def deserialize(message_as_json: OldJsonExport) -> Message:        raise NotImplementedErrorclass JSONReporter(BaseJSONReporter):    """    TODO: 3.0: Remove this JSONReporter in favor of the new one handling abs-path    and confidence.    TODO: 3.0: Add a new JSONReporter handling abs-path, confidence and scores.    (Ultimately all other breaking change related to json for 3.0).    """</del>     @staticmethod     def serialize(message: Message) -> OldJsonExport:         return {


symbol=message_as_json["symbol"],             msg=message_as_json["message"],             location=MessageLocationTuple(<del>                # TODO: 3.0: Add abs-path and confidence in a new JSONReporter</del>                 abspath=message_as_json["path"],                 path=message_as_json["path"],                 module=message_as_json["module"],


end_line=message_as_json["endLine"],                 end_column=message_as_json["endColumn"],             ),            # TODO: 3.0: Make confidence available in a new JSONReporter             confidence=UNDEFINED,         )  class JSONMessage(TypedDict):    type: str    message: str    messageId: str    symbol: str    confidence: str    module: str    path: str    absolutePath: str    line: int    endLine: int | None    column: int    endColumn: int | None    obj: strclass JSON2Reporter(BaseReporter):    name = "json2"    extension = "json2"    def display_reports(self, layout: Section) -> None:        """Don't do anything in this reporter."""    def _display(self, layout: Section) -> None:        """Do nothing."""    def display_messages(self, layout: Section | None) -> None:        """Launch layouts display."""        output = {            "messages": [self.serialize(message) for message in self.messages],            "statistics": self.serialize_stats(),        }        print(json.dumps(output, indent=4), file=self.out)    @staticmethod    def serialize(message: Message) -> JSONMessage:        return JSONMessage(            type=message.category,            symbol=message.symbol,            message=message.msg or "",            messageId=message.msg_id,            confidence=message.confidence.name,            module=message.module,            obj=message.obj,            line=message.line,            column=message.column,            endLine=message.end_line,            endColumn=message.end_column,            path=message.path,            absolutePath=message.abspath,        )    @staticmethod    def deserialize(message_as_json: JSONMessage) -> Message:        return Message(            msg_id=message_as_json["messageId"],            symbol=message_as_json["symbol"],            msg=message_as_json["message"],            location=MessageLocationTuple(                abspath=message_as_json["absolutePath"],                path=message_as_json["path"],                module=message_as_json["module"],                obj=message_as_json["obj"],                line=message_as_json["line"],                column=message_as_json["column"],                end_line=message_as_json["endLine"],                end_column=message_as_json["endColumn"],            ),            confidence=CONFIDENCE_MAP[message_as_json["confidence"]],        )    def serialize_stats(self) -> dict[str, str | int | dict[str, int]]:        """Serialize the linter stats into something JSON dumpable."""        stats = self.linter.stats        counts_dict = {            "fatal": stats.fatal,            "error": stats.error,            "warning": stats.warning,            "refactor": stats.refactor,            "convention": stats.convention,            "info": stats.info,        }        # Calculate score based on the evaluation option        evaluation = self.linter.config.evaluation        try:            note: int = eval(  # pylint: disable=eval-used                evaluation, {}, {**counts_dict, "statement": stats.statement or 1}            )        except Exception as ex:  # pylint: disable=broad-except            score: str | int = f"An exception occurred while rating: {ex}"        else:            score = round(note, 2)        return {            "messageTypeCount": counts_dict,            "modulesLinted": len(stats.by_module),            "score": score,        } def register(linter: PyLinter) -> None:     linter.register_reporter(JSONReporter)    linter.register_reporter(JSON2Reporter)diff --git a/pylint/testutils/_primer/primer_run_command.py b/pylint/testutils/_primer/primer_run_command.py-- a/pylint/testutils/_primer/primer_run_command.py++ b/pylint/testutils/_primer/primer_run_command.py


from pylint.lint import Run from pylint.message import Messagefrom pylint.reporters import JSONReporterfrom pylint.reporters.json_reporter import OldJsonExportfrom pylint.reporters.json_reporter import JSONReporter, OldJsonExport from pylint.testutils._primer.package_to_lint import PackageToLint from pylint.testutils._primer.primer_command import (     PackageData,


else:     logging_StreamHandler = logging.StreamHandler <del></del> DEFAULT_LOG_FORMAT = "%(levelname)-8s %(name)s:%(filename)s:%(lineno)d %(message)s" DEFAULT_LOG_DATE_FORMAT = "%H:%M:%S" _ANSI_ESCAPE_SEQ = re.compile(r"\x1b\[[\d;]+m")


self.records = []         self.stream = StringIO() <ins>    def clear(self) -> None:        self.records.clear()        self.stream = StringIO()</ins>     def handleError(self, record: logging.LogRecord) -> None:         if logging.raiseExceptions:             # Fail the test if the log message is bad (emit failed).


def clear(self) -> None:         """Reset the list of log records and the captured log text."""        self.handler.reset()        self.handler.clear()      def set_level(self, level: Union[int, str], logger: Optional[str] = None) -> None:         """Set the level of a logger for the duration of a test.


# Arguably we could always postpone tearDown(), but this changes the moment where the             # TestCase instance interacts with the results object, so better to only do it             # when absolutely needed.            if self.config.getoption("usepdb") and not _is_skipped(self.obj):            # We need to consider if the test itself is skipped, or the whole class.            assert isinstance(self.parent, UnitTestCase)            skipped = _is_skipped(self.obj) or _is_skipped(self.parent.obj)            if self.config.getoption("usepdb") and not skipped:                 self._explicit_tearDown = self._testcase.tearDown                 setattr(self._testcase, "tearDown", lambda *args: None)


fp.write(marshal.dumps(co))  if sys.platform == "win32":    from atomicwrites import atomic_write    def _write_pyc(        state: "AssertionState",        co: types.CodeType,        source_stat: os.stat_result,        pyc: Path,    ) -> bool:        try:            with atomic_write(os.fspath(pyc), mode="wb", overwrite=True) as fp:                _write_pyc_fp(fp, source_stat, co)        except OSError as e:            state.trace(f"error writing pyc file at {pyc}: {e}")            # we ignore any failure to write the cache file            # there are many reasons, permission-denied, pycache dir being a            # file etc.            return False        return Trueelse:    def _write_pyc(        state: "AssertionState",        co: types.CodeType,        source_stat: os.stat_result,        pyc: Path,    ) -> bool:        proc_pyc = f"{pyc}.{os.getpid()}"        try:            fp = open(proc_pyc, "wb")        except OSError as e:            state.trace(f"error writing pyc file at {proc_pyc}: errno={e.errno}")            return False        try:def _write_pyc(    state: "AssertionState",    co: types.CodeType,    source_stat: os.stat_result,    pyc: Path,) -> bool:    proc_pyc = f"{pyc}.{os.getpid()}"    try:        with open(proc_pyc, "wb") as fp:             _write_pyc_fp(fp, source_stat, co)            os.rename(proc_pyc, pyc)        except OSError as e:            state.trace(f"error writing pyc file at {pyc}: {e}")            # we ignore any failure to write the cache file            # there are many reasons, permission-denied, pycache dir being a            # file etc.            return False        finally:            fp.close()        return True    except OSError as e:        state.trace(f"error writing pyc file at {proc_pyc}: errno={e.errno}")        return False    try:        os.replace(proc_pyc, pyc)    except OSError as e:        state.trace(f"error writing pyc file at {pyc}: {e}")        # we ignore any failure to write the cache file        # there are many reasons, permission-denied, pycache dir being a        # file etc.        return False    return True   def _rewrite_test(fn: Path, config: Config) -> Tuple[os.stat_result, types.CodeType]:


filename = inspect.getfile(method)     module = method.__module__     mod_globals = method.__globals__    warnings.warn_explicit(        message,        type(message),        filename=filename,        module=module,        registry=mod_globals.setdefault("__warningregistry__", {}),        lineno=lineno,    )    try:        warnings.warn_explicit(            message,            type(message),            filename=filename,            module=module,            registry=mod_globals.setdefault("__warningregistry__", {}),            lineno=lineno,        )    except Warning as w:        # If warnings are errors (e.g. -Werror), location information gets lost, so we add it to the message.        raise type(w)(f"{w}\n at {filename}:{lineno}") from None


return self.with_args(*args, **kwargs)  def get_unpacked_marks(obj: object) -> Iterable[Mark]:    """Obtain the unpacked marks that are stored on an object."""    mark_list = getattr(obj, "pytestmark", [])    if not isinstance(mark_list, list):        mark_list = [mark_list]    return normalize_mark_list(mark_list)def get_unpacked_marks(    obj: Union[object, type],    *,    consider_mro: bool = True,) -> List[Mark]:    """Obtain the unpacked marks that are stored on an object.    If obj is a class and consider_mro is true, return marks applied to    this class and all of its super-classes in MRO order. If consider_mro    is false, only return marks applied directly to this class.    """    if isinstance(obj, type):        if not consider_mro:            mark_lists = [obj.__dict__.get("pytestmark", [])]        else:            mark_lists = [x.__dict__.get("pytestmark", []) for x in obj.__mro__]        mark_list = []        for item in mark_lists:            if isinstance(item, list):                mark_list.extend(item)            else:                mark_list.append(item)    else:        mark_attribute = getattr(obj, "pytestmark", [])        if isinstance(mark_attribute, list):            mark_list = mark_attribute        else:            mark_list = [mark_attribute]    return list(normalize_mark_list(mark_list))   def normalize_mark_list(


assert isinstance(mark, Mark), mark     # Always reassign name to avoid updating pytestmark in a reference that     # was only borrowed.    obj.pytestmark = [*get_unpacked_marks(obj), mark]    obj.pytestmark = [*get_unpacked_marks(obj, consider_mro=False), mark]   # Typing for builtin pytest marks. This is cheating; it gives builtin marks


default=None,         help="Auto-indent multiline messages passed to the logging module. Accepts true|on, false|off or an integer.",     )<ins>    group.addoption(        "--log-disable",        action="append",        default=[],        dest="logger_disable",        help="Disable a logger by name. Can be passed multipe times.",    )</ins>   _HandlerType = TypeVar("_HandlerType", bound=logging.Handler)


get_option_ini(config, "log_auto_indent"),         )         self.log_cli_handler.setFormatter(log_cli_formatter)<ins>        self._disable_loggers(loggers_to_disable=config.option.logger_disable)    def _disable_loggers(self, loggers_to_disable: List[str]) -> None:        if not loggers_to_disable:            return        for name in loggers_to_disable:            logger = logging.getLogger(name)            logger.disabled = True</ins>      def _create_formatter(self, log_format, log_date_format, auto_indent):         # Color option doesn't exist if terminal plugin is disabled.


yield path  def cleanup_dead_symlink(root: Path):    for left_dir in root.iterdir():        if left_dir.is_symlink():            if not left_dir.resolve().exists():                left_dir.unlink() def cleanup_numbered_dir(     root: Path, prefix: str, keep: int, consider_lock_dead_if_created_before: float ) -> None:     """Cleanup for lock driven numbered directories."""    if not root.exists():        return     for path in cleanup_candidates(root, prefix, keep):         try_cleanup(path, consider_lock_dead_if_created_before)     for path in root.glob("garbage-*"):         try_cleanup(path, consider_lock_dead_if_created_before)     cleanup_dead_symlink(root)  def make_numbered_dir_with_cleanup(     root: Path,


for i in range(10):         try:             p = make_numbered_dir(root, prefix, mode)            lock_path = create_cleanup_lock(p)            register_cleanup_lock_removal(lock_path)            # Only lock the current dir when keep is not 0            if keep != 0:                lock_path = create_cleanup_lock(p)                register_cleanup_lock_removal(lock_path)         except Exception as exc:             e = exc         else:diff --git a/src/_pytest/tmpdir.py b/src/_pytest/tmpdir.py-- a/src/_pytest/tmpdir.py++ b/src/_pytest/tmpdir.py


import sys import tempfile from pathlib import Pathfrom shutil import rmtreefrom typing import Generator from typing import Optionalfrom typing import TYPE_CHECKINGfrom typing import Unionif TYPE_CHECKING:    from typing_extensions import Literal    RetentionType = Literal["all", "failed", "none"]  import attrfrom _pytest.config.argparsing import Parser  from .pathlib import LOCK_TIMEOUT from .pathlib import make_numbered_dir from .pathlib import make_numbered_dir_with_cleanup from .pathlib import rm_rffrom .pathlib import cleanup_dead_symlink from _pytest.compat import final from _pytest.config import Configfrom _pytest.config import ExitCodefrom _pytest.config import hookimpl from _pytest.deprecated import check_ispytest from _pytest.fixtures import fixture from _pytest.fixtures import FixtureRequest


_given_basetemp = attr.ib(type=Optional[Path])     _trace = attr.ib()     _basetemp = attr.ib(type=Optional[Path])    _retention_count = attr.ib(type=int)    _retention_policy = attr.ib(type="RetentionType")      def __init__(         self,         given_basetemp: Optional[Path],        retention_count: int,        retention_policy: "RetentionType",         trace,         basetemp: Optional[Path] = None,         *,


# Path.absolute() exists, but it is not public (see https://bugs.python.org/issue25012).             self._given_basetemp = Path(os.path.abspath(str(given_basetemp)))         self._trace = trace<ins>        self._retention_count = retention_count        self._retention_policy = retention_policy</ins>         self._basetemp = basetemp      @classmethod


:meta private:         """         check_ispytest(_ispytest)        count = int(config.getini("tmp_path_retention_count"))        if count < 0:            raise ValueError(                f"tmp_path_retention_count must be >= 0. Current input: {count}."            )        policy = config.getini("tmp_path_retention_policy")        if policy not in ("all", "failed", "none"):            raise ValueError(                f"tmp_path_retention_policy must be either all, failed, none. Current intput: {policy}."            )         return cls(             given_basetemp=config.option.basetemp,             trace=config.trace.get("tmpdir"),            retention_count=count,            retention_policy=policy,             _ispytest=True,         )


)                     if (rootdir_stat.st_mode & 0o077) != 0:                         os.chmod(rootdir, rootdir_stat.st_mode & ~0o077)            keep = self._retention_count            if self._retention_policy == "none":                keep = 0             basetemp = make_numbered_dir_with_cleanup(                 prefix="pytest-",                 root=rootdir,                keep=3,                keep=keep,                 lock_timeout=LOCK_TIMEOUT,                 mode=0o700,             )


mp.setattr(config, "_tmp_path_factory", _tmp_path_factory, raising=False)  <ins>def pytest_addoption(parser: Parser) -> None:    parser.addini(        "tmp_path_retention_count",        help="How many sessions should we keep the `tmp_path` directories, according to `tmp_path_retention_policy`.",        default=3,    )    parser.addini(        "tmp_path_retention_policy",        help="Controls which directories created by the `tmp_path` fixture are kept around, based on test outcome. "        "(all/failed/none)",        default="failed",    )</ins> @fixture(scope="session") def tmp_path_factory(request: FixtureRequest) -> TempPathFactory:     """Return a :class:`pytest.TempPathFactory` instance for the test session."""


@fixturedef tmp_path(request: FixtureRequest, tmp_path_factory: TempPathFactory) -> Path:def tmp_path(    request: FixtureRequest, tmp_path_factory: TempPathFactory) -> Generator[Path, None, None]:     """Return a temporary directory path object which is unique to each test     function invocation, created as a sub directory of the base temporary     directory.


The returned object is a :class:`pathlib.Path` object.     """     return _mk_tmp(request, tmp_path_factory)    path = _mk_tmp(request, tmp_path_factory)    yield path    # Remove the tmpdir if the policy is "failed" and the test passed.    tmp_path_factory: TempPathFactory = request.session.config._tmp_path_factory  # type: ignore    policy = tmp_path_factory._retention_policy    if policy == "failed" and request.node._tmp_path_result_call.passed:        # We do a "best effort" to remove files, but it might not be possible due to some leaked resource,        # permissions, etc, in which case we ignore it.        rmtree(path, ignore_errors=True)    # remove dead symlink    basetemp = tmp_path_factory._basetemp    if basetemp is None:        return    cleanup_dead_symlink(basetemp)def pytest_sessionfinish(session, exitstatus: Union[int, ExitCode]):    """After each session, remove base directory if all the tests passed,    the policy is "failed", and the basetemp is not specified by a user.    """    tmp_path_factory: TempPathFactory = session.config._tmp_path_factory    if tmp_path_factory._basetemp is None:        return    policy = tmp_path_factory._retention_policy    if (        exitstatus == 0        and policy == "failed"        and tmp_path_factory._given_basetemp is None    ):        passed_dir = tmp_path_factory._basetemp        if passed_dir.exists():            # We do a "best effort" to remove files, but it might not be possible due to some leaked resource,            # permissions, etc, in which case we ignore it.            rmtree(passed_dir, ignore_errors=True)@hookimpl(tryfirst=True, hookwrapper=True)def pytest_runtest_makereport(item, call):    outcome = yield    result = outcome.get_result()    setattr(item, "_tmp_path_result_" + result.when, result)


from _pytest.mark import ParameterSet from _pytest.mark.structures import MarkDecorator from _pytest.outcomes import fail<ins>from _pytest.outcomes import skip</ins> from _pytest.outcomes import TEST_OUTCOME from _pytest.pathlib import absolutepath from _pytest.pathlib import bestrelpath


except TEST_OUTCOME:         exc_info = sys.exc_info()         assert exc_info[0] is not None<ins>        if isinstance(            exc_info[1], skip.Exception        ) and not fixturefunc.__name__.startswith("xunit_setup"):            exc_info[1]._use_item_location = True  # type: ignore[attr-defined]</ins>         fixturedef.cached_result = (None, my_cache_key, exc_info)         raise     fixturedef.cached_result = (result, my_cache_key, None)


def istestfunction(self, obj: object, name: str) -> bool:         if self.funcnamefilter(name) or self.isnosetest(obj):            if isinstance(obj, staticmethod):                # staticmethods need to be unwrapped.            if isinstance(obj, (staticmethod, classmethod)):                # staticmethods and classmethods need to be unwrapped.                 obj = safe_getattr(obj, "__func__", False)             return callable(obj) and fixtures.getfixturemarker(obj) is None         else:


max_abs_diff = max(                     max_abs_diff, abs(approx_value.expected - other_value)                 )                max_rel_diff = max(                    max_rel_diff,                    abs((approx_value.expected - other_value) / approx_value.expected),                )                if approx_value.expected == 0.0:                    max_rel_diff = math.inf                else:                    max_rel_diff = max(                        max_rel_diff,                        abs(                            (approx_value.expected - other_value)                            / approx_value.expected                        ),                    )                 different_ids.append(approx_key)          message_data = [


if TYPE_CHECKING:     from _pytest.assertion import AssertionState if sys.version_info >= (3, 8):    namedExpr = ast.NamedExprelse:    namedExpr = ast.Expr assertstate_key = StashKey["AssertionState"]() assertstate_key = StashKey["AssertionState"]()  # pytest caches rewritten pycs in pycache dirs PYTEST_TAG = f"{sys.implementation.cache_tag}-pytest-{version}"


.push_format_context() and .pop_format_context() which allows        to build another %-formatted string while already building one.     This state is reset on every new assert statement visited and used    by the other visitors.    :variables_overwrite: A dict filled with references to variables       that change value within an assert. This happens when a variable is       reassigned with the walrus operator    This state, except the variables_overwrite,  is reset on every new assert    statement visited and used by the other visitors.     """      def __init__(


else:             self.enable_assertion_pass_hook = False         self.source = source<ins>        self.variables_overwrite: Dict[str, str] = {}</ins>      def run(self, mod: ast.Module) -> None:         """Find all assert statements in *mod* and rewrite them."""


if doc is not None and self.is_rewrite_disabled(doc):             return         pos = 0        lineno = 1        item = None         for item in mod.body:             if (                 expect_docstring


ast.copy_location(node, assert_)         return self.statements <ins>    def visit_NamedExpr(self, name: namedExpr) -> Tuple[namedExpr, str]:        # This method handles the 'walrus operator' repr of the target        # name if it's a local variable or _should_repr_global_name()        # thinks it's acceptable.        locs = ast.Call(self.builtin("locals"), [], [])        target_id = name.target.id  # type: ignore[attr-defined]        inlocs = ast.Compare(ast.Str(target_id), [ast.In()], [locs])        dorepr = self.helper("_should_repr_global_name", name)        test = ast.BoolOp(ast.Or(), [inlocs, dorepr])        expr = ast.IfExp(test, self.display(name), ast.Str(target_id))        return name, self.explanation_param(expr)</ins>     def visit_Name(self, name: ast.Name) -> Tuple[ast.Name, str]:         # Display the repr of the name if it's a local variable or         # _should_repr_global_name() thinks it's acceptable.


# cond is set in a prior loop iteration below                 self.expl_stmts.append(ast.If(cond, fail_inner, []))  # noqa                 self.expl_stmts = fail_inner<ins>                # Check if the left operand is a namedExpr and the value has already been visited                if (                    isinstance(v, ast.Compare)                    and isinstance(v.left, namedExpr)                    and v.left.target.id                    in [                        ast_expr.id                        for ast_expr in boolop.values[:i]                        if hasattr(ast_expr, "id")                    ]                ):                    pytest_temp = self.variable()                    self.variables_overwrite[v.left.target.id] = pytest_temp                    v.left.target.id = pytest_temp</ins>             self.push_format_context()             res, expl = self.visit(v)             body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))


def visit_Compare(self, comp: ast.Compare) -> Tuple[ast.expr, str]:         self.push_format_context()<ins>        # We first check if we have overwritten a variable in the previous assert        if isinstance(comp.left, ast.Name) and comp.left.id in self.variables_overwrite:            comp.left.id = self.variables_overwrite[comp.left.id]</ins>         left_res, left_expl = self.visit(comp.left)         if isinstance(comp.left, (ast.Compare, ast.BoolOp)):             left_expl = f"({left_expl})"


syms = []         results = [left_res]         for i, op, next_operand in it:<ins>            if (                isinstance(next_operand, namedExpr)                and isinstance(left_res, ast.Name)                and next_operand.target.id == left_res.id            ):                next_operand.target.id = self.variable()                self.variables_overwrite[left_res.id] = next_operand.target.id</ins>             next_res, next_expl = self.visit(next_operand)             if isinstance(next_operand, (ast.Compare, ast.BoolOp)):                 next_expl = f"({next_expl})"


res: ast.expr = ast.BoolOp(ast.And(), load_names)         else:             res = load_names[0]<ins></ins>         return res, self.explanation_param(self.pop_format_context(expl_call))


import os import shutil import sys<ins>import types</ins> import uuid import warnings from enum import Enum


from typing import Iterator from typing import Optional from typing import Set<ins>from typing import Tuplefrom typing import Type</ins> from typing import TypeVar from typing import Union


return path.joinpath(".lock")  def on_rm_rf_error(func, path: str, exc, *, start_path: Path) -> bool:def on_rm_rf_error(    func,    path: str,    excinfo: Union[        BaseException,        Tuple[Type[BaseException], BaseException, Optional[types.TracebackType]],    ],    *,    start_path: Path,) -> bool:     """Handle known read-only errors during rmtree.      The returned value is used only by our own tests.     """    exctype, excvalue = exc[:2]    if isinstance(excinfo, BaseException):        exc = excinfo    else:        exc = excinfo[1]      # Another process removed the file in the middle of the "rm_rf" (xdist for example).     # More context: https://github.com/pytest-dev/pytest/issues/5974#issuecomment-543799018    if isinstance(excvalue, FileNotFoundError):    if isinstance(exc, FileNotFoundError):         return False     if not isinstance(excvalue, PermissionError):    if not isinstance(exc, PermissionError):         warnings.warn(            PytestWarning(f"(rm_rf) error removing {path}\n{exctype}: {excvalue}")            PytestWarning(f"(rm_rf) error removing {path}\n{type(exc)}: {exc}")         )         return False


warnings.warn(                 PytestWarning(                     "(rm_rf) unknown function {} when removing {}:\n{}: {}".format(                        func, path, exctype, excvalue                        func, path, type(exc), exc                     )                 )             )


are read-only."""     path = ensure_extended_length_path(path)     onerror = partial(on_rm_rf_error, start_path=path)    shutil.rmtree(str(path), onerror=onerror)    if sys.version_info >= (3, 12):        shutil.rmtree(str(path), onexc=onerror)    else:        shutil.rmtree(str(path), onerror=onerror)   def find_prefixed(root: Path, prefix: str) -> Iterator[Path]:diff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py-- a/src/_pytest/unittest.py++ b/src/_pytest/unittest.py


def stopTest(self, testcase: "unittest.TestCase") -> None:         pass <ins>    def addDuration(self, testcase: "unittest.TestCase", elapsed: float) -> None:        pass</ins>     def runtest(self) -> None:         from _pytest.debugging import maybe_wrap_pytest_function_for_tracing


# Internal API for local conftest plugin handling.     #     def _set_initial_conftests(        self, namespace: argparse.Namespace, rootpath: Path        self,        namespace: argparse.Namespace,        rootpath: Path,        testpaths_ini: Sequence[str],     ) -> None:         """Load initial conftest files given a preparsed "namespace".


)         self._noconftest = namespace.noconftest         self._using_pyargs = namespace.pyargs        testpaths = namespace.file_or_dir        testpaths = namespace.file_or_dir + testpaths_ini         foundanchor = False         for testpath in testpaths:             path = str(testpath)


if i != -1:                 path = path[:i]             anchor = absolutepath(current / path)            if anchor.exists():  # we found some file object            # Ensure we do not break if what appears to be an anchor            # is in fact a very long option (#10169).            try:                anchor_exists = anchor.exists()            except OSError:  # pragma: no cover                anchor_exists = False            if anchor_exists:                 self._try_load_conftest(anchor, namespace.importmode, rootpath)                 foundanchor = True         if not foundanchor:


@hookimpl(trylast=True)     def pytest_load_initial_conftests(self, early_config: "Config") -> None:         self.pluginmanager._set_initial_conftests(            early_config.known_args_namespace, rootpath=early_config.rootpath            early_config.known_args_namespace,            rootpath=early_config.rootpath,            testpaths_ini=self.getini("testpaths"),         )      def _initini(self, args: Sequence[str]) -> None:


]                 ):                     pytest_temp = self.variable()                    self.variables_overwrite[v.left.target.id] = pytest_temp                    self.variables_overwrite[                        v.left.target.id                    ] = v.left  # type:ignore[assignment]                     v.left.target.id = pytest_temp             self.push_format_context()             res, expl = self.visit(v)


new_args = []         new_kwargs = []         for arg in call.args:            if isinstance(arg, ast.Name) and arg.id in self.variables_overwrite:                arg = self.variables_overwrite[arg.id]  # type:ignore[assignment]             res, expl = self.visit(arg)             arg_expls.append(expl)             new_args.append(res)         for keyword in call.keywords:            if (                isinstance(keyword.value, ast.Name)                and keyword.value.id in self.variables_overwrite            ):                keyword.value = self.variables_overwrite[                    keyword.value.id                ]  # type:ignore[assignment]             res, expl = self.visit(keyword.value)             new_kwargs.append(ast.keyword(keyword.arg, res))             if keyword.arg:


self.push_format_context()         # We first check if we have overwritten a variable in the previous assert         if isinstance(comp.left, ast.Name) and comp.left.id in self.variables_overwrite:            comp.left.id = self.variables_overwrite[comp.left.id]            comp.left = self.variables_overwrite[                comp.left.id            ]  # type:ignore[assignment]        if isinstance(comp.left, namedExpr):            self.variables_overwrite[                comp.left.target.id            ] = comp.left  # type:ignore[assignment]         left_res, left_expl = self.visit(comp.left)         if isinstance(comp.left, (ast.Compare, ast.BoolOp)):             left_expl = f"({left_expl})"


and next_operand.target.id == left_res.id             ):                 next_operand.target.id = self.variable()                self.variables_overwrite[left_res.id] = next_operand.target.id                self.variables_overwrite[                    left_res.id                ] = next_operand  # type:ignore[assignment]             next_res, next_expl = self.visit(next_operand)             if isinstance(next_operand, (ast.Compare, ast.BoolOp)):                 next_expl = f"({next_expl})"


args = []                         for path in testpaths:                             args.extend(sorted(glob.iglob(path, recursive=True)))<ins>                        if testpaths and not args:                            warning_text = (                                "No files were found in testpaths; "                                "consider removing or adjusting your testpaths configuration. "                                "Searching recursively from the current directory instead."                            )                            self.issue_config_time_warning(                                PytestConfigWarning(warning_text), stacklevel=3                            )</ins>                 if not args:                     source = Config.ArgsSource.INCOVATION_DIR                     args = [str(self.invocation_params.dir)]


import re from contextlib import contextmanager from contextlib import nullcontextfrom datetime import datetimefrom datetime import timedeltafrom datetime import timezone from io import StringIOfrom logging import LogRecord from pathlib import Path from typing import AbstractSet from typing import Dict


return _ANSI_ESCAPE_SEQ.sub("", text)  class ColoredLevelFormatter(logging.Formatter):class DatetimeFormatter(logging.Formatter):    """A logging formatter which formats record with    :func:`datetime.datetime.strftime` formatter instead of    :func:`time.strftime` in case of microseconds in format string.    """    def formatTime(self, record: LogRecord, datefmt=None) -> str:        if datefmt and "%f" in datefmt:            ct = self.converter(record.created)            tz = timezone(timedelta(seconds=ct.tm_gmtoff), ct.tm_zone)            # Construct `datetime.datetime` object from `struct_time`            # and msecs information from `record`            dt = datetime(*ct[0:6], microsecond=round(record.msecs * 1000), tzinfo=tz)            return dt.strftime(datefmt)        # Use `logging.Formatter` for non-microsecond formats        return super().formatTime(record, datefmt)class ColoredLevelFormatter(DatetimeFormatter):     """A logging formatter which colorizes the %(levelname)..s part of the     log format passed to __init__."""


config, "log_file_date_format", "log_date_format"         )         log_file_formatter = logging.Formatter(        log_file_formatter = DatetimeFormatter(             log_file_format, datefmt=log_file_date_format         )         self.log_file_handler.setFormatter(log_file_formatter)


create_terminal_writer(self._config), log_format, log_date_format             )         else:            formatter = logging.Formatter(log_format, log_date_format)            formatter = DatetimeFormatter(log_format, log_date_format)          formatter._style = PercentStyleMultiline(             formatter._style._fmt, auto_indent=auto_indent


#     def _set_initial_conftests(         self,        namespace: argparse.Namespace,        args: Sequence[Union[str, Path]],        pyargs: bool,        noconftest: bool,         rootpath: Path,        testpaths_ini: Sequence[str],        confcutdir: Optional[Path],        importmode: Union[ImportMode, str],     ) -> None:         """Load initial conftest files given a preparsed "namespace".


common options will not confuse our logic here.         """         current = Path.cwd()        self._confcutdir = (            absolutepath(current / namespace.confcutdir)            if namespace.confcutdir            else None        )        self._noconftest = namespace.noconftest        self._using_pyargs = namespace.pyargs        testpaths = namespace.file_or_dir + testpaths_ini        self._confcutdir = absolutepath(current / confcutdir) if confcutdir else None        self._noconftest = noconftest        self._using_pyargs = pyargs         foundanchor = False        for testpath in testpaths:            path = str(testpath)        for intitial_path in args:            path = str(intitial_path)             # remove node-id syntax             i = path.find("::")             if i != -1:


except OSError:  # pragma: no cover                 anchor_exists = False             if anchor_exists:                self._try_load_conftest(anchor, namespace.importmode, rootpath)                self._try_load_conftest(anchor, importmode, rootpath)                 foundanchor = True         if not foundanchor:            self._try_load_conftest(current, namespace.importmode, rootpath)            self._try_load_conftest(current, importmode, rootpath)      def _is_in_confcutdir(self, path: Path) -> bool:         """Whether a path is within the confcutdir.


@hookimpl(trylast=True)     def pytest_load_initial_conftests(self, early_config: "Config") -> None:        # We haven't fully parsed the command line arguments yet, so        # early_config.args it not set yet. But we need it for        # discovering the initial conftests. So "pre-run" the logic here.        # It will be done for real in `parse()`.        args, args_source = early_config._decide_args(            args=early_config.known_args_namespace.file_or_dir,            pyargs=early_config.known_args_namespace.pyargs,            testpaths=early_config.getini("testpaths"),            invocation_dir=early_config.invocation_params.dir,            rootpath=early_config.rootpath,            warn=False,        )         self.pluginmanager._set_initial_conftests(            early_config.known_args_namespace,            args=args,            pyargs=early_config.known_args_namespace.pyargs,            noconftest=early_config.known_args_namespace.noconftest,             rootpath=early_config.rootpath,            testpaths_ini=self.getini("testpaths"),            confcutdir=early_config.known_args_namespace.confcutdir,            importmode=early_config.known_args_namespace.importmode,         )      def _initini(self, args: Sequence[str]) -> None:


return args <ins>    def _decide_args(        self,        *,        args: List[str],        pyargs: List[str],        testpaths: List[str],        invocation_dir: Path,        rootpath: Path,        warn: bool,    ) -> Tuple[List[str], ArgsSource]:        """Decide the args (initial paths/nodeids) to use given the relevant inputs.        :param warn: Whether can issue warnings.        """        if args:            source = Config.ArgsSource.ARGS            result = args        else:            if invocation_dir == rootpath:                source = Config.ArgsSource.TESTPATHS                if pyargs:                    result = testpaths                else:                    result = []                    for path in testpaths:                        result.extend(sorted(glob.iglob(path, recursive=True)))                    if testpaths and not result:                        if warn:                            warning_text = (                                "No files were found in testpaths; "                                "consider removing or adjusting your testpaths configuration. "                                "Searching recursively from the current directory instead."                            )                            self.issue_config_time_warning(                                PytestConfigWarning(warning_text), stacklevel=3                            )            else:                result = []            if not result:                source = Config.ArgsSource.INCOVATION_DIR                result = [str(invocation_dir)]        return result, source</ins>     def _preparse(self, args: List[str], addopts: bool = True) -> None:         if addopts:             env_addopts = os.environ.get("PYTEST_ADDOPTS", "")


self.hook.pytest_cmdline_preparse(config=self, args=args)         self._parser.after_preparse = True  # type: ignore         try:            source = Config.ArgsSource.ARGS             args = self._parser.parse_setoption(                 args, self.option, namespace=self.option             )            if not args:                if self.invocation_params.dir == self.rootpath:                    source = Config.ArgsSource.TESTPATHS                    testpaths: List[str] = self.getini("testpaths")                    if self.known_args_namespace.pyargs:                        args = testpaths                    else:                        args = []                        for path in testpaths:                            args.extend(sorted(glob.iglob(path, recursive=True)))                        if testpaths and not args:                            warning_text = (                                "No files were found in testpaths; "                                "consider removing or adjusting your testpaths configuration. "                                "Searching recursively from the current directory instead."                            )                            self.issue_config_time_warning(                                PytestConfigWarning(warning_text), stacklevel=3                            )                if not args:                    source = Config.ArgsSource.INCOVATION_DIR                    args = [str(self.invocation_params.dir)]            self.args = args            self.args_source = source            self.args, self.args_source = self._decide_args(                args=args,                pyargs=self.known_args_namespace.pyargs,                testpaths=self.getini("testpaths"),                invocation_dir=self.invocation_params.dir,                rootpath=self.rootpath,                warn=True,            )         except PrintHelp:             pass


expect_docstring                 and isinstance(item, ast.Expr)                 and isinstance(item.value, ast.Constant)<ins>                and isinstance(item.value.value, str)</ins>             ):                 doc = item.value.value                 if self.is_rewrite_disabled(doc):


if mode is ImportMode.importlib:         module_name = module_name_from_path(path, root)<ins>        with contextlib.suppress(KeyError):            return sys.modules[module_name]</ins>          for meta_importer in sys.meta_path:             spec = meta_importer.find_spec(module_name, [str(path.parent)])


return len(self._list)      def pop(self, cls: Type[Warning] = Warning) -> "warnings.WarningMessage":        """Pop the first recorded warning, raise exception if not exists."""        """Pop the first recorded warning which is an instance of ``cls``,        but not an instance of a child class of any other match.        Raises ``AssertionError`` if there is no match.        """        best_idx: Optional[int] = None         for i, w in enumerate(self._list):            if issubclass(w.category, cls):                return self._list.pop(i)            if w.category == cls:                return self._list.pop(i)  # exact match, stop looking            if issubclass(w.category, cls) and (                best_idx is None                or not issubclass(w.category, self._list[best_idx].category)            ):                best_idx = i        if best_idx is not None:            return self._list.pop(best_idx)         __tracebackhide__ = True         raise AssertionError(f"{cls!r} not found in warning list")


approx_side_as_map.items(), other_side.values()         ):             if approx_value != other_value:                max_abs_diff = max(                    max_abs_diff, abs(approx_value.expected - other_value)                )                if approx_value.expected == 0.0:                    max_rel_diff = math.inf                else:                    max_rel_diff = max(                        max_rel_diff,                        abs(                            (approx_value.expected - other_value)                            / approx_value.expected                        ),                if approx_value.expected is not None and other_value is not None:                    max_abs_diff = max(                        max_abs_diff, abs(approx_value.expected - other_value)                     )                    if approx_value.expected == 0.0:                        max_rel_diff = math.inf                    else:                        max_rel_diff = max(                            max_rel_diff,                            abs(                                (approx_value.expected - other_value)                                / approx_value.expected                            ),                        )                 different_ids.append(approx_key)          message_data = [


try:         result = call_fixture_func(fixturefunc, request, kwargs)     except TEST_OUTCOME as e:        if isinstance(e, skip.Exception) and not fixturefunc.__name__.startswith(            "xunit_setup"        ):        if isinstance(e, skip.Exception):            # The test requested a fixture which caused a skip.            # Don't show the fixture as the skip location, as then the user            # wouldn't know which test skipped.             e._use_item_location = True         fixturedef.cached_result = (None, my_cache_key, e)         raise


"""         visit `ast.Call` nodes on Python3.5 and after         """<ins>        if isinstance(call.func, ast.Name) and call.func.id == "all":            return self._visit_all(call)</ins>         new_func, func_expl = self.visit(call.func)         arg_expls = []         new_args = []


outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl)         return res, outer_expl <ins>    def _visit_all(self, call):        """Special rewrite for the builtin all function, see #5062"""        if not isinstance(call.args[0], (ast.GeneratorExp, ast.ListComp)):            return        gen_exp = call.args[0]        assertion_module = ast.Module(            body=[ast.Assert(test=gen_exp.elt, lineno=1, msg="", col_offset=1)]        )        AssertionRewriter(module_path=None, config=None).run(assertion_module)        for_loop = ast.For(            iter=gen_exp.generators[0].iter,            target=gen_exp.generators[0].target,            body=assertion_module.body,            orelse=[],        )        self.statements.append(for_loop)        return (            ast.Num(n=1),            "",        )  # Return an empty expression, all the asserts are in the for_loop</ins>     def visit_Starred(self, starred):         # From Python 3.5, a Starred node can appear in a function call         res, expl = self.visit(starred.value)


"""         visit `ast.Call nodes on 3.4 and below`         """<ins>        if isinstance(call.func, ast.Name) and call.func.id == "all":            return self._visit_all(call)</ins>         new_func, func_expl = self.visit(call.func)         arg_expls = []         new_args = []


return attr_func  <ins>def _check_record_param_type(param, v):    """Used by record_testsuite_property to check that the given parameter name is of the proper    type"""    __tracebackhide__ = True    if not isinstance(v, six.string_types):        msg = "{param} parameter needs to be a string, but {g} given"        raise TypeError(msg.format(param=param, g=type(v).__name__))@pytest.fixture(scope="session")def record_testsuite_property(request):    """    Records a new ``<property>`` tag as child of the root ``<testsuite>``. This is suitable to    writing global information regarding the entire test suite, and is compatible with ``xunit2`` JUnit family.    This is a ``session``-scoped fixture which is called with ``(name, value)``. Example:    .. code-block:: python        def test_foo(record_testsuite_property):            record_testsuite_property("ARCH", "PPC")            record_testsuite_property("STORAGE_TYPE", "CEPH")    ``name`` must be a string, ``value`` will be converted to a string and properly xml-escaped.    """    __tracebackhide__ = True    def record_func(name, value):        """noop function in case --junitxml was not passed in the command-line"""        __tracebackhide__ = True        _check_record_param_type("name", name)    xml = getattr(request.config, "_xml", None)    if xml is not None:        record_func = xml.add_global_property  # noqa    return record_func</ins> def pytest_addoption(parser):     group = parser.getgroup("terminal reporting")     group.addoption(


self.node_reporters = {}  # nodeid -> _NodeReporter         self.node_reporters_ordered = []         self.global_properties = []<ins></ins>         # List of reports that failed on call but teardown is pending.         self.open_reports = []         self.cnt_double_fail_tests = 0


terminalreporter.write_sep("-", "generated xml file: %s" % (self.logfile))      def add_global_property(self, name, value):        self.global_properties.append((str(name), bin_xml_escape(value)))        __tracebackhide__ = True        _check_record_param_type("name", name)        self.global_properties.append((name, bin_xml_escape(value)))      def _get_global_properties_node(self):         """Return a Junit node containing custom properties, if any.


currentmodule = module         if verbose <= 0 and argname[0] == "_":             continue        tw.write(argname, green=True)        if fixturedef.scope != "function":            tw.write(" [%s scope]" % fixturedef.scope, cyan=True)         if verbose > 0:            funcargspec = "%s -- %s" % (argname, bestrel)        else:            funcargspec = argname        tw.line(funcargspec, green=True)            tw.write(" -- %s" % bestrel, yellow=True)        tw.write("\n")         loc = getlocation(fixturedef.func, curdir)         doc = fixturedef.func.__doc__ or ""         if doc:             write_docstring(tw, doc)         else:             tw.line("    %s: no docstring available" % (loc,), red=True)        tw.line()   def write_docstring(tw, doc, indent="    "):


from _pytest.config import create_terminal_writer from _pytest.pathlib import Path DEFAULT_LOG_FORMAT = "%(filename)-25s %(lineno)4d %(levelname)-8s %(message)s"DEFAULT_LOG_FORMAT = "%(levelname)-8s %(name)s:%(filename)s:%(lineno)d %(message)s" DEFAULT_LOG_DATE_FORMAT = "%H:%M:%S"


self._nodeid_and_autousenames = [("", self.config.getini("usefixtures"))]         session.config.pluginmanager.register(self, "funcmanage")     def _get_direct_parametrize_args(self, node):        """This function returns all the direct parametrization        arguments of a node, so we don't mistake them for fixtures        Check https://github.com/pytest-dev/pytest/issues/5036        This things are done later as well when dealing with parametrization        so this could be improved        """        from _pytest.mark import ParameterSet        parametrize_argnames = []        for marker in node.iter_markers(name="parametrize"):            if not marker.kwargs.get("indirect", False):                p_argnames, _ = ParameterSet._parse_parametrize_args(                    *marker.args, **marker.kwargs                )                parametrize_argnames.extend(p_argnames)        return parametrize_argnames     def getfixtureinfo(self, node, func, cls, funcargs=True):         if funcargs and not getattr(node, "nofuncargs", False):             argnames = getfuncargnames(func, cls=cls)         else:             argnames = ()         usefixtures = itertools.chain.from_iterable(             mark.args for mark in node.iter_markers(name="usefixtures")         )         initialnames = tuple(usefixtures) + argnames         fm = node.session._fixturemanager         initialnames, names_closure, arg2fixturedefs = fm.getfixtureclosure(            initialnames, node            initialnames, node, ignore_args=self._get_direct_parametrize_args(node)         )         return FuncFixtureInfo(argnames, initialnames, names_closure, arg2fixturedefs)


autousenames.extend(basenames)         return autousenames     def getfixtureclosure(self, fixturenames, parentnode):    def getfixtureclosure(self, fixturenames, parentnode, ignore_args=()):         # collect the closure of all fixtures , starting with the given         # fixturenames as the initial set.  As we have to visit all         # factory definitions anyway, we also return an arg2fixturedefs


while lastlen != len(fixturenames_closure):             lastlen = len(fixturenames_closure)             for argname in fixturenames_closure:                if argname in ignore_args:                    continue                 if argname in arg2fixturedefs:                     continue                 fixturedefs = self.getfixturedefs(argname, parentid)diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py-- a/src/_pytest/mark/structures.py++ b/src/_pytest/mark/structures.py


else:             return cls(parameterset, marks=[], id=None)     @classmethod    def _for_parametrize(cls, argnames, argvalues, func, config, function_definition):    @staticmethod    def _parse_parametrize_args(argnames, argvalues, **_):        """It receives an ignored _ (kwargs) argument so this function can        take also calls from parametrize ignoring scope, indirect, and other        arguments..."""         if not isinstance(argnames, (tuple, list)):             argnames = [x.strip() for x in argnames.split(",") if x.strip()]             force_tuple = len(argnames) == 1


parameters = [             ParameterSet.extract_from(x, force_tuple=force_tuple) for x in argvalues         ]<ins>        return argnames, parameters    @classmethod    def _for_parametrize(cls, argnames, argvalues, func, config, function_definition):        argnames, parameters = cls._parse_parametrize_args(argnames, argvalues)</ins>         del argvalues          if parameters:


"""Ensure that file.name is a string."""         return repr(self.buffer) <ins>    @property    def mode(self):        return self.buffer.mode.replace("b", "")</ins>     def __getattr__(self, name):         return getattr(object.__getattribute__(self, "buffer"), name)