Question: Symlinked directories not collected since pytest 6.1.0 When there is a symlink to a directory in a test directory, is is just skipped over, but it should be followed and collected as usual. This regressed in (included in 6.1.0). For some reason I a in there, I don't remember why, but it does not match the previous behavior and should be removed. PR for this is coming up.

entries = sorted(os.scandir(path), key=lambda entry: entry.name)     yield from entries     for entry in entries:        if entry.is_dir(follow_symlinks=False) and recurse(entry):        if entry.is_dir() and recurse(entry):             yield from visit(entry.path, recurse)


Question: Deprecate I don't see the point in removing it in a release just to reintroduce it again, that just makes things more confusing for everyone. Originally posted by in

self._validate_plugins()         self._warn_about_skipped_plugins()         if self.known_args_namespace.strict:            self.issue_config_time_warning(                _pytest.deprecated.STRICT_OPTION, stacklevel=2            )         if self.known_args_namespace.confcutdir is None and self.inipath is not None:             confcutdir = str(self.inipath.parent)             self.known_args_namespace.confcutdir = confcutdirdiff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py-- a/src/_pytest/deprecated.py++ b/src/_pytest/deprecated.py


Question: Deprecate I don't see the point in removing it in a release just to reintroduce it again, that just makes things more confusing for everyone. Originally posted by in

"The gethookproxy() and isinitpath() methods of FSCollector and Package are deprecated; "     "use self.session.gethookproxy() and self.session.isinitpath() instead. " )STRICT_OPTION = PytestDeprecationWarning(    "The --strict option is deprecated, use --strict-markers instead.")diff --git a/src/_pytest/main.py b/src/_pytest/main.py-- a/src/_pytest/main.py++ b/src/_pytest/main.py


Question: Deprecate I don't see the point in removing it in a release just to reintroduce it again, that just makes things more confusing for everyone. Originally posted by in

)     group._addoption(         "--strict-markers",        "--strict",         action="store_true",         help="markers not registered in the `markers` section of the configuration file raise errors.",     )    group._addoption(        "--strict", action="store_true", help="(deprecated) alias to --strict-markers.",    )     group._addoption(         "-c",         metavar="file",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


Question: Deprecate I don't see the point in removing it in a release just to reintroduce it again, that just makes things more confusing for everyone. Originally posted by in

# If the name is not in the set of known marks after updating,             # then it really is time to issue a warning or an error.             if name not in self._markers:                if self._config.option.strict_markers:                if self._config.option.strict_markers or self._config.option.strict:                     fail(                         f"{name!r} not found in `markers` configuration option",                         pytrace=False,


Question: Doctest collection only returns single test for <!-- Thanks for submitting an issue! Quick check-list while reporting bugs: --will only collect a single doctest because of this: Introduced a while back by here: See failing tests: Failing doctest collection When the module is an the doctest collection only picks up 1 doctest.

self._notfound.append((report_arg, col))                     continue                 # If __init__.py was the only file requested, then the matched node will be                # the corresponding Package, and the first yielded item will be the __init__                # Module itself, so just use that. If this special case isn't taken, then all                # the files in the package will be yielded.                if argpath.basename == "__init__.py":                    assert isinstance(matching[0], nodes.Collector)                # If __init__.py was the only file requested, then the matched                # node will be the corresponding Package (by default), and the                # first yielded item will be the __init__ Module itself, so                # just use that. If this special case isn't taken, then all the                # files in the package will be yielded.                if argpath.basename == "__init__.py" and isinstance(                    matching[0], Package                ):                     try:                         yield next(iter(matching[0].collect()))                     except StopIteration:


Question: Class cleanups in Python 3.8+ are not called Did not see mentioned anywhere in this repo, which is the method that should be called. See Repo: With unittest: With Pytest:

"""Injects a hidden auto-use fixture to invoke setUpClass/setup_method and corresponding         teardown functions (#517)."""         class_fixture = _make_xunit_fixture(            cls, "setUpClass", "tearDownClass", scope="class", pass_self=False            cls,            "setUpClass",            "tearDownClass",            "doClassCleanups",            scope="class",            pass_self=False,         )         if class_fixture:             cls.__pytest_class_setup = class_fixture  # type: ignore[attr-defined]          method_fixture = _make_xunit_fixture(            cls, "setup_method", "teardown_method", scope="function", pass_self=True            cls,            "setup_method",            "teardown_method",            None,            scope="function",            pass_self=True,         )         if method_fixture:             cls.__pytest_method_setup = method_fixture  # type: ignore[attr-defined]   def _make_xunit_fixture(    obj: type, setup_name: str, teardown_name: str, scope: "_Scope", pass_self: bool    obj: type,    setup_name: str,    teardown_name: str,    cleanup_name: Optional[str],    scope: "_Scope",    pass_self: bool, ):     setup = getattr(obj, setup_name, None)     teardown = getattr(obj, teardown_name, None)     if setup is None and teardown is None:         return None     if cleanup_name:        cleanup = getattr(obj, cleanup_name, lambda *args: None)    else:        def cleanup(*args):            pass     @pytest.fixture(         scope=scope,         autouse=True,


Question: Class cleanups in Python 3.8+ are not called Did not see mentioned anywhere in this repo, which is the method that should be called. See Repo: With unittest: With Pytest:

reason = self.__unittest_skip_why__             pytest.skip(reason)         if setup is not None:            if pass_self:                setup(self, request.function)            else:                setup()            try:                if pass_self:                    setup(self, request.function)                else:                    setup()            # unittest does not call the cleanup function for every BaseException, so we            # follow this here.            except Exception:                if pass_self:                    cleanup(self)                else:                    cleanup()                raise         yield        if teardown is not None:        try:            if teardown is not None:                if pass_self:                    teardown(self, request.function)                else:                    teardown()        finally:             if pass_self:                teardown(self, request.function)                cleanup(self)             else:                teardown()                cleanup()      return fixture


Question: set sys.unraisablehook (py38) Python 3.8 has a new hook: sys.unraisablehook Pytest should set this to be able to associate unraisable exceptions with tests

"warnings",     "logging",     "reports",    *(["unraisableexception", "threadexception"] if sys.version_info >= (3, 8) else []),     "faulthandler", ) diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py-- a/src/_pytest/pytester.py++ b/src/_pytest/pytester.py


Question: set sys.unraisablehook (py38) Python 3.8 has a new hook: sys.unraisablehook Pytest should set this to be able to associate unraisable exceptions with tests

stderr=f2,                 close_fds=(sys.platform != "win32"),             )            if isinstance(stdin, bytes):            if popen.stdin is not None:                 popen.stdin.close()              def handle_timeout() -> None:diff --git a/src/_pytest/threadexception.py b/src/_pytest/threadexception.pynew file mode 100644-- /dev/null++ b/src/_pytest/threadexception.py


Question: set sys.unraisablehook (py38) Python 3.8 has a new hook: sys.unraisablehook Pytest should set this to be able to associate unraisable exceptions with tests

import threadingimport tracebackimport warningsfrom types import TracebackTypefrom typing import Anyfrom typing import Callablefrom typing import Generatorfrom typing import Optionalfrom typing import Typeimport pytest# Copied from cpython/Lib/test/support/threading_helper.py, with modifications.class catch_threading_exception:    """Context manager catching threading.Thread exception using    threading.excepthook.    Storing exc_value using a custom hook can create a reference cycle. The    reference cycle is broken explicitly when the context manager exits.    Storing thread using a custom hook can resurrect it if it is set to an    object which is being finalized. Exiting the context manager clears the    stored object.    Usage:        with threading_helper.catch_threading_exception() as cm:            # code spawning a thread which raises an exception            ...            # check the thread exception: use cm.args            ...        # cm.args attribute no longer exists at this point        # (to break a reference cycle)    """    def __init__(self) -> None:        # See https://github.com/python/typeshed/issues/4767 regarding the underscore.        self.args: Optional["threading._ExceptHookArgs"] = None        self._old_hook: Optional[Callable[["threading._ExceptHookArgs"], Any]] = None    def _hook(self, args: "threading._ExceptHookArgs") -> None:        self.args = args    def __enter__(self) -> "catch_threading_exception":        self._old_hook = threading.excepthook        threading.excepthook = self._hook        return self    def __exit__(        self,        exc_type: Optional[Type[BaseException]],        exc_val: Optional[BaseException],        exc_tb: Optional[TracebackType],    ) -> None:        assert self._old_hook is not None        threading.excepthook = self._old_hook        self._old_hook = None        del self.argsdef thread_exception_runtest_hook() -> Generator[None, None, None]:    with catch_threading_exception() as cm:        yield        if cm.args:            if cm.args.thread is not None:                thread_name = cm.args.thread.name            else:                thread_name = "<unknown>"            msg = f"Exception in thread {thread_name}\n\n"            msg += "".join(                traceback.format_exception(                    cm.args.exc_type, cm.args.exc_value, cm.args.exc_traceback,                )            )            warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))@pytest.hookimpl(hookwrapper=True, trylast=True)def pytest_runtest_setup() -> Generator[None, None, None]:    yield from thread_exception_runtest_hook()@pytest.hookimpl(hookwrapper=True, tryfirst=True)def pytest_runtest_call() -> Generator[None, None, None]:    yield from thread_exception_runtest_hook()@pytest.hookimpl(hookwrapper=True, tryfirst=True)def pytest_runtest_teardown() -> Generator[None, None, None]:    yield from thread_exception_runtest_hook()diff --git a/src/_pytest/unraisableexception.py b/src/_pytest/unraisableexception.pynew file mode 100644-- /dev/null++ b/src/_pytest/unraisableexception.py


Question: set sys.unraisablehook (py38) Python 3.8 has a new hook: sys.unraisablehook Pytest should set this to be able to associate unraisable exceptions with tests

import sysimport tracebackimport warningsfrom types import TracebackTypefrom typing import Anyfrom typing import Callablefrom typing import Generatorfrom typing import Optionalfrom typing import Typeimport pytest# Copied from cpython/Lib/test/support/__init__.py, with modifications.class catch_unraisable_exception:    """Context manager catching unraisable exception using sys.unraisablehook.    Storing the exception value (cm.unraisable.exc_value) creates a reference    cycle. The reference cycle is broken explicitly when the context manager    exits.    Storing the object (cm.unraisable.object) can resurrect it if it is set to    an object which is being finalized. Exiting the context manager clears the    stored object.    Usage:        with catch_unraisable_exception() as cm:            # code creating an "unraisable exception"            ...            # check the unraisable exception: use cm.unraisable            ...        # cm.unraisable attribute no longer exists at this point        # (to break a reference cycle)    """    def __init__(self) -> None:        self.unraisable: Optional["sys.UnraisableHookArgs"] = None        self._old_hook: Optional[Callable[["sys.UnraisableHookArgs"], Any]] = None    def _hook(self, unraisable: "sys.UnraisableHookArgs") -> None:        # Storing unraisable.object can resurrect an object which is being        # finalized. Storing unraisable.exc_value creates a reference cycle.        self.unraisable = unraisable    def __enter__(self) -> "catch_unraisable_exception":        self._old_hook = sys.unraisablehook        sys.unraisablehook = self._hook        return self    def __exit__(        self,        exc_type: Optional[Type[BaseException]],        exc_val: Optional[BaseException],        exc_tb: Optional[TracebackType],    ) -> None:        assert self._old_hook is not None        sys.unraisablehook = self._old_hook        self._old_hook = None        del self.unraisabledef unraisable_exception_runtest_hook() -> Generator[None, None, None]:    with catch_unraisable_exception() as cm:        yield        if cm.unraisable:            if cm.unraisable.err_msg is not None:                err_msg = cm.unraisable.err_msg            else:                err_msg = "Exception ignored in"            msg = f"{err_msg}: {cm.unraisable.object!r}\n\n"            msg += "".join(                traceback.format_exception(                    cm.unraisable.exc_type,                    cm.unraisable.exc_value,                    cm.unraisable.exc_traceback,                )            )            warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))@pytest.hookimpl(hookwrapper=True, tryfirst=True)def pytest_runtest_setup() -> Generator[None, None, None]:    yield from unraisable_exception_runtest_hook()@pytest.hookimpl(hookwrapper=True, tryfirst=True)def pytest_runtest_call() -> Generator[None, None, None]:    yield from unraisable_exception_runtest_hook()@pytest.hookimpl(hookwrapper=True, tryfirst=True)def pytest_runtest_teardown() -> Generator[None, None, None]:    yield from unraisable_exception_runtest_hook()diff --git a/src/_pytest/warning_types.py b/src/_pytest/warning_types.py-- a/src/_pytest/warning_types.py++ b/src/_pytest/warning_types.py


Question: set sys.unraisablehook (py38) Python 3.8 has a new hook: sys.unraisablehook Pytest should set this to be able to associate unraisable exceptions with tests

__module__ = "pytest"  @finalclass PytestUnraisableExceptionWarning(PytestWarning):    """An unraisable exception was reported.    Unraisable exceptions are exceptions raised in :meth:`__del__ <object.__del__>`    implementations and similar situations when the exception cannot be raised    as normal.    """    __module__ = "pytest"@finalclass PytestUnhandledThreadExceptionWarning(PytestWarning):    """An unhandled exception occurred in a :class:`~threading.Thread`.    Such exceptions don't propagate normally.    """    __module__ = "pytest" _W = TypeVar("_W", bound=PytestWarning)  diff --git a/src/pytest/__init__.py b/src/pytest/__init__.py-- a/src/pytest/__init__.py++ b/src/pytest/__init__.py


Question: set sys.unraisablehook (py38) Python 3.8 has a new hook: sys.unraisablehook Pytest should set this to be able to associate unraisable exceptions with tests

from _pytest.warning_types import PytestDeprecationWarning from _pytest.warning_types import PytestExperimentalApiWarning from _pytest.warning_types import PytestUnhandledCoroutineWarningfrom _pytest.warning_types import PytestUnhandledThreadExceptionWarning from _pytest.warning_types import PytestUnknownMarkWarningfrom _pytest.warning_types import PytestUnraisableExceptionWarning from _pytest.warning_types import PytestWarning  set_trace = __pytestPDB.set_trace


Question: set sys.unraisablehook (py38) Python 3.8 has a new hook: sys.unraisablehook Pytest should set this to be able to associate unraisable exceptions with tests

"PytestDeprecationWarning",     "PytestExperimentalApiWarning",     "PytestUnhandledCoroutineWarning",    "PytestUnhandledThreadExceptionWarning",     "PytestUnknownMarkWarning",    "PytestUnraisableExceptionWarning",     "PytestWarning",     "raises",     "register_assert_rewrite",


Question: Allow contibuting additional global variables for skipif/xfail [ ] Include documentation when adding new features. [x] Include new tests or update existing tests when applicable. [X] Allow maintainers to push and squash when merging my commits. Please uncheck this if you prefer to squash the commits yourself. for details.

"""  # -------------------------------------------------------------------------# Hooks for influencing skipping# -------------------------------------------------------------------------def pytest_markeval_namespace(config: "Config") -> Dict[str, Any]:    """Called when constructing the globals dictionary used for    evaluating string conditions in xfail/skipif markers.    This is useful when the condition for a marker requires    objects that are expensive or impossible to obtain during    collection time, which is required by normal boolean    conditions.    .. versionadded:: 6.2    :param _pytest.config.Config config: The pytest config object.    :returns: A dictionary of additional globals to add.    """ # ------------------------------------------------------------------------- # error handling and internal debugging hooks # -------------------------------------------------------------------------diff --git a/src/_pytest/skipping.py b/src/_pytest/skipping.py-- a/src/_pytest/skipping.py++ b/src/_pytest/skipping.py


Question: Allow contibuting additional global variables for skipif/xfail [ ] Include documentation when adding new features. [x] Include new tests or update existing tests when applicable. [X] Allow maintainers to push and squash when merging my commits. Please uncheck this if you prefer to squash the commits yourself. for details.

import platform import sys import traceback<ins>from collections.abc import Mapping</ins> from typing import Generator from typing import Optional from typing import Tuple


Question: Allow contibuting additional global variables for skipif/xfail [ ] Include documentation when adding new features. [x] Include new tests or update existing tests when applicable. [X] Allow maintainers to push and squash when merging my commits. Please uncheck this if you prefer to squash the commits yourself. for details.

"platform": platform,             "config": item.config,         }<ins>        for dictionary in reversed(            item.ihook.pytest_markeval_namespace(config=item.config)        ):            if not isinstance(dictionary, Mapping):                raise ValueError(                    "pytest_markeval_namespace() needs to return a dict, got {!r}".format(                        dictionary                    )                )            globals_.update(dictionary)</ins>         if hasattr(item, "obj"):             globals_.update(item.obj.__globals__)  # type: ignore[attr-defined]         try:


Question: Problem with faulthandler when used with Twisted Logger and "pytest --capture=no" Dear developers, thanks a stack for conceiving and maintaining this excellent package. I never expected to file an issue or submit a patch here, but here we go. On behalf of , we are currently in the progress of finally upgrading to Python 3. Kotori is based on Twisted and uses for testing. Within , we tried hard to apply some magic to make everything work together on all occasions with respect to appropriately configuring to our needs. We are on macOS 10.13.6. The background on this is that the Twisted Logger intercepts the logging by providing a file-like wrapper around the stream, which is obviously not an actual stream. In this case, when running with , 's fails when trying to restore the stream through at [1] as this will actually return , in turn signaling an invalid file descriptor [2]. It will a) raise the exception outlined below and b) won't stop the process on teardown. [1] [2] This problem is mitigated by . With kind regards, Andreas.

@staticmethod     def _get_stderr_fileno():         try:            return sys.stderr.fileno()            fileno = sys.stderr.fileno()            # The Twisted Logger will return an invalid file descriptor since it is not backed            # by an FD. So, let's also forward this to the same code path as with pytest-xdist.            if fileno == -1:                raise AttributeError()            return fileno         except (AttributeError, io.UnsupportedOperation):             # pytest-xdist monkeypatches sys.stderr with an object that is not an actual file.             # https://docs.python.org/3/library/faulthandler.html#issue-with-file-descriptors


Question: tmpdir creation fails when the username contains illegal characters for directory names , and rely on for determining the directory. I found that the user name returned by may return characters that are not allowed for directory names. This may lead to errors while creating the temporary directory. The situation in which I reproduced this issue was while being logged in through an ssh connection into my Windows 10 x64 Enterprise version (1909) using an OpenSSHforWindows7.7p1 server. In this configuration the command returns my domain username e.g. instead of as when logged in regularly using a local session. When trying to create a temp directory in pytest through e.g. this fails with the following error message: I could also reproduce this without the complicated ssh/windows setup with pytest 6.2.2 using the following commands from a : Thanks for having a look at this!

# use a sub-directory in the temproot to speed-up             # make_numbered_dir() call             rootdir = temproot.joinpath(f"pytest-of-{user}")            rootdir.mkdir(exist_ok=True)            try:                rootdir.mkdir(exist_ok=True)            except OSError:                # getuser() likely returned illegal characters for the platform, use unknown back off mechanism                rootdir = temproot.joinpath("pytest-of-unknown")                rootdir.mkdir(exist_ok=True)             basetemp = make_numbered_dir_with_cleanup(                 prefix="pytest-", root=rootdir, keep=3, lock_timeout=LOCK_TIMEOUT             )


Question: Starting v6.2.0, unittest setUpClass fixtures are no longer "private" <!-- Thanks for submitting an issue! Quick check-list while reporting bugs: --Minimal example: The expected (and previously implemented behavior) is that this fixture's name would start with an underscore, and would therefore only get printed if the additional flag was used. As it stands, I don't see a way to hide such generated fixtures which will not have a docstring. This breaks a code-quality CI script that makes sure we don't have undocumented pytest fixtures (and the code-base has many legacy tests that use unittest, and that will not get upgraded).

autouse=True,             scope="module",             # Use a unique name to speed up lookup.            name=f"xunit_setup_module_fixture_{self.obj.__name__}",            name=f"_xunit_setup_module_fixture_{self.obj.__name__}",         )         def xunit_setup_module_fixture(request) -> Generator[None, None, None]:             if setup_module is not None:


Question: Starting v6.2.0, unittest setUpClass fixtures are no longer "private" <!-- Thanks for submitting an issue! Quick check-list while reporting bugs: --Minimal example: The expected (and previously implemented behavior) is that this fixture's name would start with an underscore, and would therefore only get printed if the additional flag was used. As it stands, I don't see a way to hide such generated fixtures which will not have a docstring. This breaks a code-quality CI script that makes sure we don't have undocumented pytest fixtures (and the code-base has many legacy tests that use unittest, and that will not get upgraded).

autouse=True,             scope="function",             # Use a unique name to speed up lookup.            name=f"xunit_setup_function_fixture_{self.obj.__name__}",            name=f"_xunit_setup_function_fixture_{self.obj.__name__}",         )         def xunit_setup_function_fixture(request) -> Generator[None, None, None]:             if request.instance is not None:


Question: Starting v6.2.0, unittest setUpClass fixtures are no longer "private" <!-- Thanks for submitting an issue! Quick check-list while reporting bugs: --Minimal example: The expected (and previously implemented behavior) is that this fixture's name would start with an underscore, and would therefore only get printed if the additional flag was used. As it stands, I don't see a way to hide such generated fixtures which will not have a docstring. This breaks a code-quality CI script that makes sure we don't have undocumented pytest fixtures (and the code-base has many legacy tests that use unittest, and that will not get upgraded).

autouse=True,             scope="class",             # Use a unique name to speed up lookup.            name=f"xunit_setup_class_fixture_{self.obj.__qualname__}",            name=f"_xunit_setup_class_fixture_{self.obj.__qualname__}",         )         def xunit_setup_class_fixture(cls) -> Generator[None, None, None]:             if setup_class is not None:


Question: Starting v6.2.0, unittest setUpClass fixtures are no longer "private" <!-- Thanks for submitting an issue! Quick check-list while reporting bugs: --Minimal example: The expected (and previously implemented behavior) is that this fixture's name would start with an underscore, and would therefore only get printed if the additional flag was used. As it stands, I don't see a way to hide such generated fixtures which will not have a docstring. This breaks a code-quality CI script that makes sure we don't have undocumented pytest fixtures (and the code-base has many legacy tests that use unittest, and that will not get upgraded).

autouse=True,             scope="function",             # Use a unique name to speed up lookup.            name=f"xunit_setup_method_fixture_{self.obj.__qualname__}",            name=f"_xunit_setup_method_fixture_{self.obj.__qualname__}",         )         def xunit_setup_method_fixture(self, request) -> Generator[None, None, None]:             method = request.functiondiff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py-- a/src/_pytest/unittest.py++ b/src/_pytest/unittest.py


Question: Starting v6.2.0, unittest setUpClass fixtures are no longer "private" <!-- Thanks for submitting an issue! Quick check-list while reporting bugs: --Minimal example: The expected (and previously implemented behavior) is that this fixture's name would start with an underscore, and would therefore only get printed if the additional flag was used. As it stands, I don't see a way to hide such generated fixtures which will not have a docstring. This breaks a code-quality CI script that makes sure we don't have undocumented pytest fixtures (and the code-base has many legacy tests that use unittest, and that will not get upgraded).

scope=scope,         autouse=True,         # Use a unique name to speed up lookup.        name=f"unittest_{setup_name}_fixture_{obj.__qualname__}",        name=f"_unittest_{setup_name}_fixture_{obj.__qualname__}",     )     def fixture(self, request: FixtureRequest) -> Generator[None, None, None]:         if _is_skipped(self):


Question: approx: Better handle Decimal in sequences and mappings <!-- Thanks for suggesting a feature! Quick check-list while suggesting features: --Right now handles Decimal comparisons gracefully, thanks to We can do this: also knows how to handle sequences and mappings: doesn't handle Decimal within sequences and mappings: Both of these tests fail with <!-- A clear and concise description of what you want to happen. --I would like these kind of tests to be passing :) A linked PR should be following shortly :eyes: <!-- Provide examples of real-world use cases that this would enable and how it solves the problem described above. --<!-- Have you tried to workaround the problem using a pytest plugin or other tools? Or a different approach to solving this issue? Please elaborate here. --<!-- Add any other context, links, etc. about the feature here. --

return not (actual == self)      def _approx_scalar(self, x) -> "ApproxScalar":<ins>        if isinstance(x, Decimal):            return ApproxDecimal(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok)</ins>         return ApproxScalar(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok)      def _yield_comparisons(self, actual):


Question: Generate an error when a mark is applied to a fixture Follow up from . We should generate an error if a is applied to a fixture. There is a warning in about this problem which should be updated once this issue is dealt with.

"#configuring-hook-specs-impls-using-markers", ) MARKED_FIXTURE = PytestRemovedIn8Warning(    "Marks applied to fixtures have no effect\n"    "See docs: https://docs.pytest.org/en/stable/deprecations.html#applying-a-mark-to-a-fixture-function") # You want to make some `__init__` or function "private". # #   def my_private_function(some, args):diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py-- a/src/_pytest/fixtures.py++ b/src/_pytest/fixtures.py


Question: Generate an error when a mark is applied to a fixture Follow up from . We should generate an error if a is applied to a fixture. There is a warning in about this problem which should be updated once this issue is dealt with.

from _pytest.config import Config from _pytest.config.argparsing import Parser from _pytest.deprecated import check_ispytest<ins>from _pytest.deprecated import MARKED_FIXTURE</ins> from _pytest.deprecated import YIELD_FIXTURE from _pytest.mark import Mark from _pytest.mark import ParameterSet


Question: Generate an error when a mark is applied to a fixture Follow up from . We should generate an error if a is applied to a fixture. There is a warning in about this problem which should be updated once this issue is dealt with.

"fixture is being applied more than once to the same function"             )         if hasattr(function, "pytestmark"):            warnings.warn(MARKED_FIXTURE, stacklevel=2)         function = wrap_function_to_error_out_if_called_directly(function, self)          name = self.name or function.__name__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


Question: Generate an error when a mark is applied to a fixture Follow up from . We should generate an error if a is applied to a fixture. There is a warning in about this problem which should be updated once this issue is dealt with.

from ..compat import NotSetType from _pytest.config import Config from _pytest.deprecated import check_ispytest<ins>from _pytest.deprecated import MARKED_FIXTURE</ins> from _pytest.outcomes import fail from _pytest.warning_types import PytestUnknownMarkWarning


Question: Generate an error when a mark is applied to a fixture Follow up from . We should generate an error if a is applied to a fixture. There is a warning in about this problem which should be updated once this issue is dealt with.

This is used to implement the Mark declarations/decorators correctly.     """     assert isinstance(mark, Mark), mark<ins>    from ..fixtures import getfixturemarker    if getfixturemarker(obj) is not None:        warnings.warn(MARKED_FIXTURE, stacklevel=2)</ins>     # Always reassign name to avoid updating pytestmark in a reference that     # was only borrowed.     obj.pytestmark = [*get_unpacked_marks(obj, consider_mro=False), mark]


Question: Unexpected keyword argument 'path' from plugins While troubleshooting , I stumbled onto a new error, a that occurs when using pytest-black against the current main HEAD (), easily reproducible with an empty test file and pip-run: Same problem happens with pytest-checkdocs:

@classmethod     def from_config(cls, config: Config) -> "Session":        session: Session = cls._create(config)        session: Session = cls._create(config=config)         return session      def __repr__(self) -> str:diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py-- a/src/_pytest/nodes.py++ b/src/_pytest/nodes.py


Question: Unexpected keyword argument 'path' from plugins While troubleshooting , I stumbled onto a new error, a that occurs when using pytest-black against the current main HEAD (), easily reproducible with an empty test file and pip-run: Same problem happens with pytest-checkdocs:

import os import warningsfrom inspect import signature from pathlib import Path from typing import Any from typing import Callablefrom typing import cast from typing import Iterable from typing import Iterator from typing import List


Question: Unexpected keyword argument 'path' from plugins While troubleshooting , I stumbled onto a new error, a that occurs when using pytest-black against the current main HEAD (), easily reproducible with an empty test file and pip-run: Same problem happens with pytest-checkdocs:

from _pytest.pathlib import absolutepath from _pytest.pathlib import commonpath from _pytest.store import Store<ins>from _pytest.warning_types import PytestWarning</ins>  if TYPE_CHECKING:     # Imported here due to circular import.


Question: Unexpected keyword argument 'path' from plugins While troubleshooting , I stumbled onto a new error, a that occurs when using pytest-black against the current main HEAD (), easily reproducible with an empty test file and pip-run: Same problem happens with pytest-checkdocs:

fail(msg, pytrace=False)      def _create(self, *k, **kw):        return super().__call__(*k, **kw)        try:            return super().__call__(*k, **kw)        except TypeError:            sig = signature(getattr(self, "__init__"))            known_kw = {k: v for k, v in kw.items() if k in sig.parameters}            from .warning_types import PytestDeprecationWarning            warnings.warn(                PytestDeprecationWarning(                    f"{self} is not using a cooperative constructor and only takes {set(known_kw)}"                )            )            return super().__call__(*k, **known_kw)   class Node(metaclass=NodeMeta):


Question: Unexpected keyword argument 'path' from plugins While troubleshooting , I stumbled onto a new error, a that occurs when using pytest-black against the current main HEAD (), easily reproducible with an empty test file and pip-run: Same problem happens with pytest-checkdocs:

class FSCollector(Collector):     def __init__(         self,        fspath: Optional[LEGACY_PATH],        path: Optional[Path],        parent=None,        fspath: Optional[LEGACY_PATH] = None,        path_or_parent: Optional[Union[Path, Node]] = None,        path: Optional[Path] = None,        name: Optional[str] = None,        parent: Optional[Node] = None,         config: Optional[Config] = None,         session: Optional["Session"] = None,         nodeid: Optional[str] = None,     ) -> None:        if path_or_parent:            if isinstance(path_or_parent, Node):                assert parent is None                parent = cast(FSCollector, path_or_parent)            elif isinstance(path_or_parent, Path):                assert path is None                path = path_or_parent         path, fspath = _imply_path(path, fspath=fspath)        name = path.name        if parent is not None and parent.path != path:            try:                rel = path.relative_to(parent.path)            except ValueError:                pass            else:                name = str(rel)            name = name.replace(os.sep, SEP)        if name is None:            name = path.name            if parent is not None and parent.path != path:                try:                    rel = path.relative_to(parent.path)                except ValueError:                    pass                else:                    name = str(rel)                name = name.replace(os.sep, SEP)         self.path = path         session = session or parent.session        if session is None:            assert parent is not None            session = parent.session          if nodeid is None:             try:


Question: Unexpected keyword argument 'path' from plugins While troubleshooting , I stumbled onto a new error, a that occurs when using pytest-black against the current main HEAD (), easily reproducible with an empty test file and pip-run: Same problem happens with pytest-checkdocs:

nodeid = nodeid.replace(os.sep, SEP)          super().__init__(            name, parent, config, session, nodeid=nodeid, fspath=fspath, path=path            name=name,            parent=parent,            config=config,            session=session,            nodeid=nodeid,            path=path,         )      @classmethod


Question: Unexpected keyword argument 'path' from plugins While troubleshooting , I stumbled onto a new error, a that occurs when using pytest-black against the current main HEAD (), easily reproducible with an empty test file and pip-run: Same problem happens with pytest-checkdocs:

nextitem = None <ins>    def __init_subclass__(cls) -> None:        problems = ", ".join(            base.__name__ for base in cls.__bases__ if issubclass(base, Collector)        )        if problems:            warnings.warn(                f"{cls.__name__} is an Item subclass and should not be a collector, "                f"however its bases {problems} are collectors.\n"                "Please split the Collectors and the Item into separate node types.\n"                "Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html\n"                "example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/",                PytestWarning,            )</ins>     def __init__(         self,         name,


Question: Unexpected keyword argument 'path' from plugins While troubleshooting , I stumbled onto a new error, a that occurs when using pytest-black against the current main HEAD (), easily reproducible with an empty test file and pip-run: Same problem happens with pytest-checkdocs:

config: Optional[Config] = None,         session: Optional["Session"] = None,         nodeid: Optional[str] = None,        **kw,     ) -> None:        super().__init__(name, parent, config, session, nodeid=nodeid)        super().__init__(            name=name,            parent=parent,            config=config,            session=session,            nodeid=nodeid,            **kw,        )         self._report_sections: List[Tuple[str, str, str]] = []          #: A list of tuples (name, value) that holds user defined properties


Question: Minor temporary directory security issue in pytest versions before 6.2.3 A minor temporary directory security issue was found in pytest versions before 6.2.3. This issue is fixed in pytest 6.2.3. pytest used to create directories under with world-readable permissions. This means that any user in the system was able to read information written by tests in temporary directories (such as those created by the fixture). Now the directories are created with private permissions. pytest used to silenty use a pre-existing ` directory, even if owned by another user. This means another user could pre-create such a directory and gain control of another user's temporary directory. Now such a condition results in an error.

return path.joinpath(".lock")  <del>def ensure_reset_dir(path: Path) -> None:    """Ensure the given path is an empty directory."""    if path.exists():        rm_rf(path)    path.mkdir()</del> def on_rm_rf_error(func, path: str, exc, *, start_path: Path) -> bool:     """Handle known read-only errors during rmtree.


Question: Minor temporary directory security issue in pytest versions before 6.2.3 A minor temporary directory security issue was found in pytest versions before 6.2.3. This issue is fixed in pytest 6.2.3. pytest used to create directories under with world-readable permissions. This means that any user in the system was able to read information written by tests in temporary directories (such as those created by the fixture). Now the directories are created with private permissions. pytest used to silenty use a pre-existing ` directory, even if owned by another user. This means another user could pre-create such a directory and gain control of another user's temporary directory. Now such a condition results in an error.

pass  def make_numbered_dir(root: Path, prefix: str) -> Path:def make_numbered_dir(root: Path, prefix: str, mode: int = 0o700) -> Path:     """Create a directory with an increased number as suffix for the given prefix."""     for i in range(10):         # try up to 10 times to create the folder


Question: Minor temporary directory security issue in pytest versions before 6.2.3 A minor temporary directory security issue was found in pytest versions before 6.2.3. This issue is fixed in pytest 6.2.3. pytest used to create directories under with world-readable permissions. This means that any user in the system was able to read information written by tests in temporary directories (such as those created by the fixture). Now the directories are created with private permissions. pytest used to silenty use a pre-existing ` directory, even if owned by another user. This means another user could pre-create such a directory and gain control of another user's temporary directory. Now such a condition results in an error.

new_number = max_existing + 1         new_path = root.joinpath(f"{prefix}{new_number}")         try:            new_path.mkdir()            new_path.mkdir(mode=mode)         except Exception:             pass         else:


Question: Minor temporary directory security issue in pytest versions before 6.2.3 A minor temporary directory security issue was found in pytest versions before 6.2.3. This issue is fixed in pytest 6.2.3. pytest used to create directories under with world-readable permissions. This means that any user in the system was able to read information written by tests in temporary directories (such as those created by the fixture). Now the directories are created with private permissions. pytest used to silenty use a pre-existing ` directory, even if owned by another user. This means another user could pre-create such a directory and gain control of another user's temporary directory. Now such a condition results in an error.

def make_numbered_dir_with_cleanup(    root: Path, prefix: str, keep: int, lock_timeout: float    root: Path,    prefix: str,    keep: int,    lock_timeout: float,    mode: int, ) -> Path:     """Create a numbered dir with a cleanup lock and remove old ones."""     e = None     for i in range(10):         try:            p = make_numbered_dir(root, prefix)            p = make_numbered_dir(root, prefix, mode)             lock_path = create_cleanup_lock(p)             register_cleanup_lock_removal(lock_path)         except Exception as exc:diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py-- a/src/_pytest/pytester.py++ b/src/_pytest/pytester.py


Question: Minor temporary directory security issue in pytest versions before 6.2.3 A minor temporary directory security issue was found in pytest versions before 6.2.3. This issue is fixed in pytest 6.2.3. pytest used to create directories under with world-readable permissions. This means that any user in the system was able to read information written by tests in temporary directories (such as those created by the fixture). Now the directories are created with private permissions. pytest used to silenty use a pre-existing ` directory, even if owned by another user. This means another user could pre-create such a directory and gain control of another user's temporary directory. Now such a condition results in an error.

:py:class:`Pytester.TimeoutExpired`.         """         __tracebackhide__ = True        p = make_numbered_dir(root=self.path, prefix="runpytest-")        p = make_numbered_dir(root=self.path, prefix="runpytest-", mode=0o700)         args = ("--basetemp=%s" % p,) + args         plugins = [x for x in self.plugins if isinstance(x, str)]         if plugins:


Question: Minor temporary directory security issue in pytest versions before 6.2.3 A minor temporary directory security issue was found in pytest versions before 6.2.3. This issue is fixed in pytest 6.2.3. pytest used to create directories under with world-readable permissions. This means that any user in the system was able to read information written by tests in temporary directories (such as those created by the fixture). Now the directories are created with private permissions. pytest used to silenty use a pre-existing ` directory, even if owned by another user. This means another user could pre-create such a directory and gain control of another user's temporary directory. Now such a condition results in an error.

The pexpect child is returned.         """         basetemp = self.path / "temp-pexpect"        basetemp.mkdir()        basetemp.mkdir(mode=0o700)         invoke = " ".join(map(str, self._getpytestargs()))         cmd = f"{invoke} --basetemp={basetemp} {string}"         return self.spawn(cmd, expect_timeout=expect_timeout)diff --git a/src/_pytest/tmpdir.py b/src/_pytest/tmpdir.py-- a/src/_pytest/tmpdir.py++ b/src/_pytest/tmpdir.py


Question: Minor temporary directory security issue in pytest versions before 6.2.3 A minor temporary directory security issue was found in pytest versions before 6.2.3. This issue is fixed in pytest 6.2.3. pytest used to create directories under with world-readable permissions. This means that any user in the system was able to read information written by tests in temporary directories (such as those created by the fixture). Now the directories are created with private permissions. pytest used to silenty use a pre-existing ` directory, even if owned by another user. This means another user could pre-create such a directory and gain control of another user's temporary directory. Now such a condition results in an error.

import attr from .pathlib import ensure_reset_dir from .pathlib import LOCK_TIMEOUT from .pathlib import make_numbered_dir from .pathlib import make_numbered_dir_with_cleanupfrom .pathlib import rm_rf from _pytest.compat import final from _pytest.compat import LEGACY_PATH from _pytest.compat import legacy_path


Question: Minor temporary directory security issue in pytest versions before 6.2.3 A minor temporary directory security issue was found in pytest versions before 6.2.3. This issue is fixed in pytest 6.2.3. pytest used to create directories under with world-readable permissions. This means that any user in the system was able to read information written by tests in temporary directories (such as those created by the fixture). Now the directories are created with private permissions. pytest used to silenty use a pre-existing ` directory, even if owned by another user. This means another user could pre-create such a directory and gain control of another user's temporary directory. Now such a condition results in an error.

basename = self._ensure_relative_to_basetemp(basename)         if not numbered:             p = self.getbasetemp().joinpath(basename)            p.mkdir()            p.mkdir(mode=0o700)         else:            p = make_numbered_dir(root=self.getbasetemp(), prefix=basename)            p = make_numbered_dir(root=self.getbasetemp(), prefix=basename, mode=0o700)             self._trace("mktemp", p)         return p      def getbasetemp(self) -> Path:        """Return base temporary directory."""        """Return the base temporary directory, creating it if needed."""         if self._basetemp is not None:             return self._basetemp          if self._given_basetemp is not None:             basetemp = self._given_basetemp            ensure_reset_dir(basetemp)            if basetemp.exists():                rm_rf(basetemp)            basetemp.mkdir(mode=0o700)             basetemp = basetemp.resolve()         else:             from_env = os.environ.get("PYTEST_DEBUG_TEMPROOT")


Question: Minor temporary directory security issue in pytest versions before 6.2.3 A minor temporary directory security issue was found in pytest versions before 6.2.3. This issue is fixed in pytest 6.2.3. pytest used to create directories under with world-readable permissions. This means that any user in the system was able to read information written by tests in temporary directories (such as those created by the fixture). Now the directories are created with private permissions. pytest used to silenty use a pre-existing ` directory, even if owned by another user. This means another user could pre-create such a directory and gain control of another user's temporary directory. Now such a condition results in an error.

# make_numbered_dir() call             rootdir = temproot.joinpath(f"pytest-of-{user}")             try:                rootdir.mkdir(exist_ok=True)                rootdir.mkdir(mode=0o700, exist_ok=True)             except OSError:                 # getuser() likely returned illegal characters for the platform, use unknown back off mechanism                 rootdir = temproot.joinpath("pytest-of-unknown")                rootdir.mkdir(exist_ok=True)                rootdir.mkdir(mode=0o700, exist_ok=True)            # Because we use exist_ok=True with a predictable name, make sure            # we are the owners, to prevent any funny business (on unix, where            # temproot is usually shared).            # Also, to keep things private, fixup any world-readable temp            # rootdir's permissions. Historically 0o755 was used, so we can't            # just error out on this, at least for a while.            if hasattr(os, "getuid"):                rootdir_stat = rootdir.stat()                uid = os.getuid()                # getuid shouldn't fail, but cpython defines such a case.                # Let's hope for the best.                if uid != -1:                    if rootdir_stat.st_uid != uid:                        raise OSError(                            f"The temporary directory {rootdir} is not owned by the current user. "                            "Fix this and try again."                        )                    if (rootdir_stat.st_mode & 0o077) != 0:                        os.chmod(rootdir, rootdir_stat.st_mode & ~0o077)             basetemp = make_numbered_dir_with_cleanup(                prefix="pytest-", root=rootdir, keep=3, lock_timeout=LOCK_TIMEOUT                prefix="pytest-",                root=rootdir,                keep=3,                lock_timeout=LOCK_TIMEOUT,                mode=0o700,             )         assert basetemp is not None, basetemp        self._basetemp = t = basetemp        self._trace("new basetemp", t)        return t        self._basetemp = basetemp        self._trace("new basetemp", basetemp)        return basetemp   @final


Question: No color output when specifying log format string with precision-formatted levelname <!-- Thanks for submitting an issue! Quick check-list while reporting bugs: --Pytest fails to output colorfully with the following log format string in This is due to  fails to match the format string due to the presence of precision bit.

logging.DEBUG: {"purple"},         logging.NOTSET: set(),     }    LEVELNAME_FMT_REGEX = re.compile(r"%\(levelname\)([+-.]?\d*s)")    LEVELNAME_FMT_REGEX = re.compile(r"%\(levelname\)([+-.]?\d*(?:\.\d+)?s)")      def __init__(self, terminalwriter: TerminalWriter, *args, **kwargs) -> None:         super().__init__(*args, **kwargs)


Question: Internal error when adding a skip mark to a doctest inside a contextmanager To reproduce: This is a simplified issue from a real use case in the scikit-learn repo. We sometimes want to skip doctests, for example when matplotlib (an optional dependency) is not installed. If there is be a better way to do it with pytest than using , let me know. <details<summaryconda list output</summary</details

def _find_lineno(self, obj, source_lines):                 """Doctest code does not take into account `@property`, this                is a hackish way to fix it.                is a hackish way to fix it. https://bugs.python.org/issue17446                 https://bugs.python.org/issue17446                Wrapped Doctests will need to be unwrapped so the correct                line number is returned. This will be reported upstream. #8796                 """                 if isinstance(obj, property):                     obj = getattr(obj, "fget", obj)                if hasattr(obj, "__wrapped__"):                    # Get the main obj in case of it being wrapped                    obj = inspect.unwrap(obj)                 # Type ignored because this is a private function.                 return doctest.DocTestFinder._find_lineno(  # type: ignore                     self,


Question: Improve handling of skip for module level This is potentially about updating docs, updating error messages or introducing a new API. Consider the following scenario: is using Python 3,8 syntax: It should not be tested under Python 3.6 and 3.7. This is a proper way to skip the test in Python older than 3.8: My actual test involves parameterize and a 3.8 only class, so skipping the test itself is not sufficient because the 3.8 class was used in the parameterization. A naive user will try to initially skip the module like: This issues this error: Using outside of a test is not allowed. To decorate a test function, use the or decorators instead, and to skip a module use `pytestmark = {skip,skipif}. The proposed solution , does not work in my case: pytest continues to process the file and fail when it hits the 3.8 syntax (when running with an older version of Python). The correct solution, to use skip as a function is actively discouraged by the error message. This area feels a bit unpolished. A few ideas to improve: skip with in the error message. this seems in conflict with the spirit of the message. an alternative API to skip a module to make things easier: , which can call .

if e.allow_module_level:                 raise             raise self.CollectError(<del>                "Using pytest.skip outside of a test is not allowed. "                "To decorate a test function, use the @pytest.mark.skip "                "or @pytest.mark.skipif decorators instead, and to skip a "                "module use `pytestmark = pytest.mark.{skip,skipif}."</del><ins>                "Using pytest.skip outside of a test will skip the entire module. "                "If that's your intention, pass `allow_module_level=True`. "                "If you want to skip a specific test or an entire class, "                "use the @pytest.mark.skip or @pytest.mark.skipif decorators."</ins>             ) from e         self.config.pluginmanager.consider_module(mod)         return mod


Question: Enhance warning assertion capabilities while writing some other bits and pieces, I had a use case for checking the omitted, has a that doesn't quite offer yet the information is already available in there, I suspect there is a good reason why we don't have so I propose some additional capabilities on to handle warnings in isolation. With the full dict comparison may get a bit intrusive as far as warning capture is concerned. something simple like: Thoughts?

errors: int = 0,         xpassed: int = 0,         xfailed: int = 0,<ins>        warnings: int = 0,</ins>     ) -> None:         """Assert that the specified outcomes appear with the respective         numbers (0 means it didn't occur) in the text output from a test run."""


Question: Enhance warning assertion capabilities while writing some other bits and pieces, I had a use case for checking the omitted, has a that doesn't quite offer yet the information is already available in there, I suspect there is a good reason why we don't have so I propose some additional capabilities on to handle warnings in isolation. With the full dict comparison may get a bit intrusive as far as warning capture is concerned. something simple like: Thoughts?

errors=errors,             xpassed=xpassed,             xfailed=xfailed,            warnings=warnings,         )  diff --git a/src/_pytest/pytester_assertions.py b/src/_pytest/pytester_assertions.py-- a/src/_pytest/pytester_assertions.py++ b/src/_pytest/pytester_assertions.py


Question: Enhance warning assertion capabilities while writing some other bits and pieces, I had a use case for checking the omitted, has a that doesn't quite offer yet the information is already available in there, I suspect there is a good reason why we don't have so I propose some additional capabilities on to handle warnings in isolation. With the full dict comparison may get a bit intrusive as far as warning capture is concerned. something simple like: Thoughts?

errors: int = 0,     xpassed: int = 0,     xfailed: int = 0,<ins>    warnings: int = 0,</ins> ) -> None:     """Assert that the specified outcomes appear with the respective     numbers (0 means it didn't occur) in the text output from a test run."""


Question: Enhance warning assertion capabilities while writing some other bits and pieces, I had a use case for checking the omitted, has a that doesn't quite offer yet the information is already available in there, I suspect there is a good reason why we don't have so I propose some additional capabilities on to handle warnings in isolation. With the full dict comparison may get a bit intrusive as far as warning capture is concerned. something simple like: Thoughts?

"errors": outcomes.get("errors", 0),         "xpassed": outcomes.get("xpassed", 0),         "xfailed": outcomes.get("xfailed", 0),<ins>        "warnings": outcomes.get("warnings", 0),</ins>     }     expected = {         "passed": passed,


Question: Enhance warning assertion capabilities while writing some other bits and pieces, I had a use case for checking the omitted, has a that doesn't quite offer yet the information is already available in there, I suspect there is a good reason why we don't have so I propose some additional capabilities on to handle warnings in isolation. With the full dict comparison may get a bit intrusive as far as warning capture is concerned. something simple like: Thoughts?

"errors": errors,         "xpassed": xpassed,         "xfailed": xfailed,<ins>        "warnings": warnings,</ins>     }     assert obtained == expected


Question: pytest -k doesn't work with "\"? <div type='discussions-op-text'<supOriginally posted by nguydavi August 7, 2021</supHey! I've been trying to use passing the name I got by parametrizing my test. For example, Note the error message I tried escaping the but that didn't work, the only way I can make it work is to remove the backslashes completely, Is just not supported by ? Or am I missing something ? Thanks! EDIT: A possible test case Which is then referred by as . Essentially a new line character in the string brings the issue (or any escaped character probably)</div

expr:       and_expr ('or' and_expr)* and_expr:   not_expr ('and' not_expr)* not_expr:   'not' not_expr | '(' expr ')' | identident:      (\w|:|\+|-|\.|\[|\])+ident:      (\w|:|\+|-|\.|\[|\]|\\)+  The semantics are:


Question: pytest -k doesn't work with "\"? <div type='discussions-op-text'<supOriginally posted by nguydavi August 7, 2021</supHey! I've been trying to use passing the name I got by parametrizing my test. For example, Note the error message I tried escaping the but that didn't work, the only way I can make it work is to remove the backslashes completely, Is just not supported by ? Or am I missing something ? Thanks! EDIT: A possible test case Which is then referred by as . Essentially a new line character in the string brings the issue (or any escaped character probably)</div

yield Token(TokenType.RPAREN, ")", pos)                 pos += 1             else:                match = re.match(r"(:?\w|:|\+|-|\.|\[|\])+", input[pos:])                match = re.match(r"(:?\w|:|\+|-|\.|\[|\]|\\)+", input[pos:])                 if match:                     value = match.group(0)                     if value == "or":


Question: has no effect without [x] a detailed description of the bug or problem you are having The flag will "exit on test failure and continue from last failing test". The flag is supposed to "ignore the first failing test but stop on the next failing test". However, it does nothing unless used in conjunction with . The combo requirement is not mentioned in the help text, seems redundant, and is surprising behavior. I recommend that should act the same as . [x] output of from the virtual environment you are using [x] pytest and operating system versions MacOS, Python 3.9.5, pytest-6.2.4 [x] minimal example if possible Example three failures: has no effect: works as expected, stopping after first failure: only works with to stop after second failure: I believe the above behavior, the combo of the flags, should work like that even if only is used.

action="store_true",         default=False,         dest="stepwise_skip",        help="ignore the first failing test but stop on the next failing test",        help="ignore the first failing test but stop on the next failing test.\n"        "implicitly enables --stepwise.",     )   @pytest.hookimpl def pytest_configure(config: Config) -> None:    # We should always have a cache as cache provider plugin uses tryfirst=True    if config.option.stepwise_skip:        # allow --stepwise-skip to work on it's own merits.        config.option.stepwise = True     if config.getoption("stepwise"):         config.pluginmanager.register(StepwisePlugin(config), "stepwiseplugin")


Question: Show full qualified name on direct Node construction warning In , running pytest with many plugins installed gives this error: And is not clear which plugin is the culprit, I had to look at the source code of to figure it out. We might consider at least show the full qualified name of the offending class in that message, so users would see , which is a nudge in the right direction. Originally posted by in

"See "             "https://docs.pytest.org/en/stable/deprecations.html#node-construction-changed-to-node-from-parent"             " for more details."        ).format(name=self.__name__)        ).format(name=f"{self.__module__}.{self.__name__}")         fail(msg, pytrace=False)      def _create(self, *k, **kw):


Question: Add a parameter to <!-- Thanks for suggesting a feature! Quick check-list while suggesting features: --<!-- What are you trying to do, that you are unable to achieve with pytest as it currently stands? --I'd like to be able to use to check deselected count. <!-- A clear and concise description of what you want to happen. --Add a parameter to <!-- Provide examples of real-world use cases that this would enable and how it solves the problem described above. --Plugins that use to change the and add change the deselected items need to be tested. Using to check the deselected count would be helpful. <!-- Have you tried to workaround the problem using a pytest plugin or other tools? Or a different approach to solving this issue? Please elaborate here. --Use instead of . returns a dictionary that includes , if there are any. However, if we have a series of tests, some that care about deselected, and some that don't, then we may have some tests using and some using , which is slightly annoying. <!-- Add any other context, links, etc. about the feature here. --

xpassed: int = 0,         xfailed: int = 0,         warnings: int = 0,<ins>        deselected: int = 0,</ins>     ) -> None:         """Assert that the specified outcomes appear with the respective         numbers (0 means it didn't occur) in the text output from a test run."""


Question: Add a parameter to <!-- Thanks for suggesting a feature! Quick check-list while suggesting features: --<!-- What are you trying to do, that you are unable to achieve with pytest as it currently stands? --I'd like to be able to use to check deselected count. <!-- A clear and concise description of what you want to happen. --Add a parameter to <!-- Provide examples of real-world use cases that this would enable and how it solves the problem described above. --Plugins that use to change the and add change the deselected items need to be tested. Using to check the deselected count would be helpful. <!-- Have you tried to workaround the problem using a pytest plugin or other tools? Or a different approach to solving this issue? Please elaborate here. --Use instead of . returns a dictionary that includes , if there are any. However, if we have a series of tests, some that care about deselected, and some that don't, then we may have some tests using and some using , which is slightly annoying. <!-- Add any other context, links, etc. about the feature here. --

xpassed=xpassed,             xfailed=xfailed,             warnings=warnings,            deselected=deselected,         )  diff --git a/src/_pytest/pytester_assertions.py b/src/_pytest/pytester_assertions.py-- a/src/_pytest/pytester_assertions.py++ b/src/_pytest/pytester_assertions.py


Question: Add a parameter to <!-- Thanks for suggesting a feature! Quick check-list while suggesting features: --<!-- What are you trying to do, that you are unable to achieve with pytest as it currently stands? --I'd like to be able to use to check deselected count. <!-- A clear and concise description of what you want to happen. --Add a parameter to <!-- Provide examples of real-world use cases that this would enable and how it solves the problem described above. --Plugins that use to change the and add change the deselected items need to be tested. Using to check the deselected count would be helpful. <!-- Have you tried to workaround the problem using a pytest plugin or other tools? Or a different approach to solving this issue? Please elaborate here. --Use instead of . returns a dictionary that includes , if there are any. However, if we have a series of tests, some that care about deselected, and some that don't, then we may have some tests using and some using , which is slightly annoying. <!-- Add any other context, links, etc. about the feature here. --

xpassed: int = 0,     xfailed: int = 0,     warnings: int = 0,<ins>    deselected: int = 0,</ins> ) -> None:     """Assert that the specified outcomes appear with the respective     numbers (0 means it didn't occur) in the text output from a test run."""


Question: Add a parameter to <!-- Thanks for suggesting a feature! Quick check-list while suggesting features: --<!-- What are you trying to do, that you are unable to achieve with pytest as it currently stands? --I'd like to be able to use to check deselected count. <!-- A clear and concise description of what you want to happen. --Add a parameter to <!-- Provide examples of real-world use cases that this would enable and how it solves the problem described above. --Plugins that use to change the and add change the deselected items need to be tested. Using to check the deselected count would be helpful. <!-- Have you tried to workaround the problem using a pytest plugin or other tools? Or a different approach to solving this issue? Please elaborate here. --Use instead of . returns a dictionary that includes , if there are any. However, if we have a series of tests, some that care about deselected, and some that don't, then we may have some tests using and some using , which is slightly annoying. <!-- Add any other context, links, etc. about the feature here. --

"xpassed": outcomes.get("xpassed", 0),         "xfailed": outcomes.get("xfailed", 0),         "warnings": outcomes.get("warnings", 0),<ins>        "deselected": outcomes.get("deselected", 0),</ins>     }     expected = {         "passed": passed,


Question: Add a parameter to <!-- Thanks for suggesting a feature! Quick check-list while suggesting features: --<!-- What are you trying to do, that you are unable to achieve with pytest as it currently stands? --I'd like to be able to use to check deselected count. <!-- A clear and concise description of what you want to happen. --Add a parameter to <!-- Provide examples of real-world use cases that this would enable and how it solves the problem described above. --Plugins that use to change the and add change the deselected items need to be tested. Using to check the deselected count would be helpful. <!-- Have you tried to workaround the problem using a pytest plugin or other tools? Or a different approach to solving this issue? Please elaborate here. --Use instead of . returns a dictionary that includes , if there are any. However, if we have a series of tests, some that care about deselected, and some that don't, then we may have some tests using and some using , which is slightly annoying. <!-- Add any other context, links, etc. about the feature here. --

"xpassed": xpassed,         "xfailed": xfailed,         "warnings": warnings,<ins>        "deselected": deselected,</ins>     }     assert obtained == expected


Question: test ids with s cannot be selected with By default pytest 6.2.2 parametrize does user arguments to generate IDs, but some of these ids cannot be used with option because you endup with errors like when trying to do so. The solution for this bug is to assure that auto-generated IDs are sanitized so they can be used with -k option. Example: As you can see the first parameter includes a slash, and for good reasons. It is far from practical to have to add custom "ids" for all of these, as you can have LOTS of them. There is another annoyance related to the -k selecting for parameterized tests, is the fact that square braces have special meanings for some shells and in order to use it you must remember to quote the strings. It would be much easier if the display and selecting of parametrized tests would use only shell-safe format, so we can easily copy/paste a failed test in run it. For example I think that using colon would be safe and arguably even easier to read: .

expr:       and_expr ('or' and_expr)* and_expr:   not_expr ('and' not_expr)* not_expr:   'not' not_expr | '(' expr ')' | identident:      (\w|:|\+|-|\.|\[|\]|\\)+ident:      (\w|:|\+|-|\.|\[|\]|\\|/)+  The semantics are:


Question: test ids with s cannot be selected with By default pytest 6.2.2 parametrize does user arguments to generate IDs, but some of these ids cannot be used with option because you endup with errors like when trying to do so. The solution for this bug is to assure that auto-generated IDs are sanitized so they can be used with -k option. Example: As you can see the first parameter includes a slash, and for good reasons. It is far from practical to have to add custom "ids" for all of these, as you can have LOTS of them. There is another annoyance related to the -k selecting for parameterized tests, is the fact that square braces have special meanings for some shells and in order to use it you must remember to quote the strings. It would be much easier if the display and selecting of parametrized tests would use only shell-safe format, so we can easily copy/paste a failed test in run it. For example I think that using colon would be safe and arguably even easier to read: .

yield Token(TokenType.RPAREN, ")", pos)                 pos += 1             else:                match = re.match(r"(:?\w|:|\+|-|\.|\[|\]|\\)+", input[pos:])                match = re.match(r"(:?\w|:|\+|-|\.|\[|\]|\\|/)+", input[pos:])                 if match:                     value = match.group(0)                     if value == "or":


Question: Unexpected keyword argument 'path' from plugins While troubleshooting , I stumbled onto a new error, a that occurs when using pytest-black against the current main HEAD (), easily reproducible with an empty test file and pip-run: Same problem happens with pytest-checkdocs:

nodeid: Optional[str] = None,         **kw,     ) -> None:        # The first two arguments are intentionally passed positionally,        # to keep plugins who define a node type which inherits from        # (pytest.Item, pytest.File) working (see issue #8435).        # They can be made kwargs when the deprecation above is done.         super().__init__(            name=name,            parent=parent,            name,            parent,             config=config,             session=session,             nodeid=nodeid,


Question: Error message prints extra code line when using assert in python3.9 <!-- Thanks for submitting an issue! Quick check-list while reporting bugs: --- [x] a detailed description of the bug or problem you are having [x] output of from the virtual environment you are using [x] pytest and operating system versions [ ] minimal example if possible I have a test like this: The test "testrightstatement" fails at the first assertion,but print extra code (the "t" decorator) in error details, like this: And the same thing did not happen when using python3.7.10 Is there some problems when calculate the statement lineno? pytest 6.2.5 Windows 10 Seems to happen in python 3.9,not 3.7

values: List[int] = []     for x in ast.walk(node):         if isinstance(x, (ast.stmt, ast.ExceptHandler)):<ins>            # Before Python 3.8, the lineno of a decorated class or function pointed at the decorator.            # Since Python 3.8, the lineno points to the class/def, so need to include the decorators.            if isinstance(x, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):                for d in x.decorator_list:                    values.append(d.lineno - 1)</ins>             values.append(x.lineno - 1)             for name in ("finalbody", "orelse"):                 val: Optional[List[ast.stmt]] = getattr(x, name, None)


Question: [prerelease] addition to is backwards-incompatible a new parameter to , cc However, this actually is an incompatible change: Doing e.g. followed by worked fine before, but now fails because the now included does not equal . This breaks pytest-bdd: - I could swear I also saw another project in fail after fixing the initial issue it had, but then Christmas and stuff came along and now I don't remember which one it was, and of course can't find it anymore. A (quite) reveals that more projects might be affected by this (excludes to avoid matches in copies of pytest's source code). Some examples I could dig up (but haven't verified): (maybe) I think the change in itself makes sense, but at the same time fixes like are a bit cumbersome. Two questions: What should we do about this for 7.0? (even if the answer just is "live with it and document it as backwards-incompatible in the changelog) What (if anything) should we do about this so that it doesn't happen again for future releases? I guess not much we can do, as long as we want to assume 0 for outcomes which have not been given...

errors: int = 0,         xpassed: int = 0,         xfailed: int = 0,        warnings: int = 0,        deselected: int = 0,        warnings: Optional[int] = None,        deselected: Optional[int] = None,     ) -> None:        """Assert that the specified outcomes appear with the respective        numbers (0 means it didn't occur) in the text output from a test run."""        """        Assert that the specified outcomes appear with the respective        numbers (0 means it didn't occur) in the text output from a test run.        ``warnings`` and ``deselected`` are only checked if not None.        """         __tracebackhide__ = True         from _pytest.pytester_assertions import assert_outcomes diff --git a/src/_pytest/pytester_assertions.py b/src/_pytest/pytester_assertions.py-- a/src/_pytest/pytester_assertions.py++ b/src/_pytest/pytester_assertions.py


Question: [prerelease] addition to is backwards-incompatible a new parameter to , cc However, this actually is an incompatible change: Doing e.g. followed by worked fine before, but now fails because the now included does not equal . This breaks pytest-bdd: - I could swear I also saw another project in fail after fixing the initial issue it had, but then Christmas and stuff came along and now I don't remember which one it was, and of course can't find it anymore. A (quite) reveals that more projects might be affected by this (excludes to avoid matches in copies of pytest's source code). Some examples I could dig up (but haven't verified): (maybe) I think the change in itself makes sense, but at the same time fixes like are a bit cumbersome. Two questions: What should we do about this for 7.0? (even if the answer just is "live with it and document it as backwards-incompatible in the changelog) What (if anything) should we do about this so that it doesn't happen again for future releases? I guess not much we can do, as long as we want to assume 0 for outcomes which have not been given...

# hence cannot be subject to assertion rewriting, which requires a # module to not be already imported. from typing import Dict<ins>from typing import Optional</ins> from typing import Sequence from typing import Tuple from typing import Union


Question: [prerelease] addition to is backwards-incompatible a new parameter to , cc However, this actually is an incompatible change: Doing e.g. followed by worked fine before, but now fails because the now included does not equal . This breaks pytest-bdd: - I could swear I also saw another project in fail after fixing the initial issue it had, but then Christmas and stuff came along and now I don't remember which one it was, and of course can't find it anymore. A (quite) reveals that more projects might be affected by this (excludes to avoid matches in copies of pytest's source code). Some examples I could dig up (but haven't verified): (maybe) I think the change in itself makes sense, but at the same time fixes like are a bit cumbersome. Two questions: What should we do about this for 7.0? (even if the answer just is "live with it and document it as backwards-incompatible in the changelog) What (if anything) should we do about this so that it doesn't happen again for future releases? I guess not much we can do, as long as we want to assume 0 for outcomes which have not been given...

errors: int = 0,     xpassed: int = 0,     xfailed: int = 0,    warnings: int = 0,    deselected: int = 0,    warnings: Optional[int] = None,    deselected: Optional[int] = None, ) -> None:     """Assert that the specified outcomes appear with the respective     numbers (0 means it didn't occur) in the text output from a test run."""


Question: [prerelease] addition to is backwards-incompatible a new parameter to , cc However, this actually is an incompatible change: Doing e.g. followed by worked fine before, but now fails because the now included does not equal . This breaks pytest-bdd: - I could swear I also saw another project in fail after fixing the initial issue it had, but then Christmas and stuff came along and now I don't remember which one it was, and of course can't find it anymore. A (quite) reveals that more projects might be affected by this (excludes to avoid matches in copies of pytest's source code). Some examples I could dig up (but haven't verified): (maybe) I think the change in itself makes sense, but at the same time fixes like are a bit cumbersome. Two questions: What should we do about this for 7.0? (even if the answer just is "live with it and document it as backwards-incompatible in the changelog) What (if anything) should we do about this so that it doesn't happen again for future releases? I guess not much we can do, as long as we want to assume 0 for outcomes which have not been given...

"errors": outcomes.get("errors", 0),         "xpassed": outcomes.get("xpassed", 0),         "xfailed": outcomes.get("xfailed", 0),<del>        "warnings": outcomes.get("warnings", 0),        "deselected": outcomes.get("deselected", 0),</del>     }     expected = {         "passed": passed,


Question: [prerelease] addition to is backwards-incompatible a new parameter to , cc However, this actually is an incompatible change: Doing e.g. followed by worked fine before, but now fails because the now included does not equal . This breaks pytest-bdd: - I could swear I also saw another project in fail after fixing the initial issue it had, but then Christmas and stuff came along and now I don't remember which one it was, and of course can't find it anymore. A (quite) reveals that more projects might be affected by this (excludes to avoid matches in copies of pytest's source code). Some examples I could dig up (but haven't verified): (maybe) I think the change in itself makes sense, but at the same time fixes like are a bit cumbersome. Two questions: What should we do about this for 7.0? (even if the answer just is "live with it and document it as backwards-incompatible in the changelog) What (if anything) should we do about this so that it doesn't happen again for future releases? I guess not much we can do, as long as we want to assume 0 for outcomes which have not been given...

"errors": errors,         "xpassed": xpassed,         "xfailed": xfailed,        "warnings": warnings,        "deselected": deselected,     }    if warnings is not None:        obtained["warnings"] = outcomes.get("warnings", 0)        expected["warnings"] = warnings    if deselected is not None:        obtained["deselected"] = outcomes.get("deselected", 0)        expected["deselected"] = deselected     assert obtained == expected


Question: INTERNALERRORTypeError: init() missing 1 required positional argument: 'testmethod' [ ] a detailed description of the bug or problem you are having [ ] output of from the virtual environment you are using [ ] pytest and operating system versions pytest-7.0.0 CentOS Stream 8 [ ] minimal example if possible Issue happened only once, as far as I know. I will update this issue if it happens multiple times and if I manage to reproduce it outside of GitHub Actions CI.

_excinfo: Optional[List[_pytest._code.ExceptionInfo[BaseException]]] = None     _testcase: Optional["unittest.TestCase"] = None <ins>    def _getobj(self):        assert self.parent is not None        # Unlike a regular Function in a Class, where `item.obj` returns        # a *bound* method (attached to an instance), TestCaseFunction's        # `obj` returns an *unbound* method (not attached to an instance).        # This inconsistency is probably not desirable, but needs some        # consideration before changing.        return getattr(self.parent.obj, self.originalname)  # type: ignore[attr-defined]</ins>     def setup(self) -> None:         # A bound method to be called during teardown() if set (see 'runtest()').         self._explicit_tearDown: Optional[Callable[[], None]] = None


Question: Pytest 7 not ignoring warnings as instructed on <!-- Thanks for submitting an issue! Quick check-list while reporting bugs: --- [x] a detailed description of the bug or problem you are having [x] output of from the virtual environment you are using [x] pytest and operating system versions [x] minimal example if possible Hello, with the latest version of Pytest a series of new issues has started to pop-up to warn users (and plugin maintainers) about future changes on how Pytest will work. This is a great work done by Pytest maintainers, and pushes the community towards a better future. However, after informing plugin maintainers about the upcoming changes, I would like to silence these warnings so I can focus in fixing the errors detected on the tests (otherwise the output is too big and difficult to scroll through to find useful information). To solve this, I naturally tried to modify my file with a filter for these warnings, however Pytest is still printing some of them even after I the warning filters. The following script can be used to reproduce the problem: Relevant output: (The warnings seem to be shown only once per worker per plugin, but considering you have 32 workers with and 4 plugins that haven't adapted to the changes yet, the output can be very verbose and difficult to navigate) Pytest should not print the warnings: -

nextitem = None <del>    def __init_subclass__(cls) -> None:        problems = ", ".join(            base.__name__ for base in cls.__bases__ if issubclass(base, Collector)        )        if problems:            warnings.warn(                f"{cls.__name__} is an Item subclass and should not be a collector, "                f"however its bases {problems} are collectors.\n"                "Please split the Collectors and the Item into separate node types.\n"                "Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html\n"                "example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/",                PytestWarning,            )</del>     def __init__(         self,         name,


Question: Pytest 7 not ignoring warnings as instructed on <!-- Thanks for submitting an issue! Quick check-list while reporting bugs: --- [x] a detailed description of the bug or problem you are having [x] output of from the virtual environment you are using [x] pytest and operating system versions [x] minimal example if possible Hello, with the latest version of Pytest a series of new issues has started to pop-up to warn users (and plugin maintainers) about future changes on how Pytest will work. This is a great work done by Pytest maintainers, and pushes the community towards a better future. However, after informing plugin maintainers about the upcoming changes, I would like to silence these warnings so I can focus in fixing the errors detected on the tests (otherwise the output is too big and difficult to scroll through to find useful information). To solve this, I naturally tried to modify my file with a filter for these warnings, however Pytest is still printing some of them even after I the warning filters. The following script can be used to reproduce the problem: Relevant output: (The warnings seem to be shown only once per worker per plugin, but considering you have 32 workers with and 4 plugins that haven't adapted to the changes yet, the output can be very verbose and difficult to navigate) Pytest should not print the warnings: -

#: for this test.         self.user_properties: List[Tuple[str, object]] = [] <ins>        self._check_item_and_collector_diamond_inheritance()    def _check_item_and_collector_diamond_inheritance(self) -> None:        """        Check if the current type inherits from both File and Collector        at the same time, emitting a warning accordingly (#8447).        """        cls = type(self)        # We inject an attribute in the type to avoid issuing this warning        # for the same class more than once, which is not helpful.        # It is a hack, but was deemed acceptable in order to avoid        # flooding the user in the common case.        attr_name = "_pytest_diamond_inheritance_warning_shown"        if getattr(cls, attr_name, False):            return        setattr(cls, attr_name, True)        problems = ", ".join(            base.__name__ for base in cls.__bases__ if issubclass(base, Collector)        )        if problems:            warnings.warn(                f"{cls.__name__} is an Item subclass and should not be a collector, "                f"however its bases {problems} are collectors.\n"                "Please split the Collectors and the Item into separate node types.\n"                "Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html\n"                "example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/",                PytestWarning,            )</ins>     def runtest(self) -> None:         """Run the test case for this item.


Question: 0 regression: Existence of messes up package discovery with importlib + pythonpath mode (ModuleNotFoundError: No module named 'tests.<test-packages') Consider the following demo project: (existence of this file breaks package discovery) pytest (version 7.0.0) errors with: What's particularly surprising: The example works, when renaming the to e.g. . I.e., it seems that the existence of the implies that it is no longer possible to import from . Imports like this used to work with pre 7 pytest versions in mode despite the existence of a .

module_parts = module_name.split(".")     while module_name:         if module_name not in modules:            module = ModuleType(                module_name,                doc="Empty module created by pytest's importmode=importlib.",            )            modules[module_name] = module            try:                # If sys.meta_path is empty, calling import_module will issue                # a warning and raise ModuleNotFoundError. To avoid the                # warning, we check sys.meta_path explicitly and raise the error                # ourselves to fall back to creating a dummy module.                if not sys.meta_path:                    raise ModuleNotFoundError                importlib.import_module(module_name)            except ModuleNotFoundError:                module = ModuleType(                    module_name,                    doc="Empty module created by pytest's importmode=importlib.",                )                modules[module_name] = module         module_parts.pop(-1)         module_name = ".".join(module_parts)


Question: Current implementation of cannot be used to compare sets The current implementation of yields incorrect results when used to compare sets. Consider the following self-explanatory code comparing two (equal as by ) sets: Although the two sets are obviously the same, the last equality check using approx is failing. A quick view into the implementation of makes it obvious why this is the case: In , only is used (in ), but since sets are unordered, so is the resulting iterator. This means, for sets such an implementation cannot work. What makes things worse is the confusion that seems to exist here between the different abstract base classes: In the method, clearly is mentioned, explicitly. However, a set is not a sequence type, but only a collection type (because of the missing order). It is, however, iterable and since this is the only thing that is actually checked in the implementation, the code seems to work for sets, where, in fact, it does not. As a first step, I would suggest one could keep the current implementation, but explicitly check for sequence types (i.e. classes having a method) and delete all mentions of in the code as well as on the documentation page and make it crystal clear that there is only an implementation for sequence types. But what would be way better would, of course, be an implementation for arbitrary container comparisons. Tested with pytest version 7.0.1.

import math import pprint<ins>from collections.abc import Collection</ins> from collections.abc import Sized from decimal import Decimal from numbers import Complex


Question: Current implementation of cannot be used to compare sets The current implementation of yields incorrect results when used to compare sets. Consider the following self-explanatory code comparing two (equal as by ) sets: Although the two sets are obviously the same, the last equality check using approx is failing. A quick view into the implementation of makes it obvious why this is the case: In , only is used (in ), but since sets are unordered, so is the resulting iterator. This means, for sets such an implementation cannot work. What makes things worse is the confusion that seems to exist here between the different abstract base classes: In the method, clearly is mentioned, explicitly. However, a set is not a sequence type, but only a collection type (because of the missing order). It is, however, iterable and since this is the only thing that is actually checked in the implementation, the code seems to work for sets, where, in fact, it does not. As a first step, I would suggest one could keep the current implementation, but explicitly check for sequence types (i.e. classes having a method) and delete all mentions of in the code as well as on the documentation page and make it crystal clear that there is only an implementation for sequence types. But what would be way better would, of course, be an implementation for arbitrary container comparisons. Tested with pytest version 7.0.1.

from typing import Callable from typing import cast from typing import Generic<del>from typing import Iterable</del> from typing import List from typing import Mapping from typing import Optional


Question: Current implementation of cannot be used to compare sets The current implementation of yields incorrect results when used to compare sets. Consider the following self-explanatory code comparing two (equal as by ) sets: Although the two sets are obviously the same, the last equality check using approx is failing. A quick view into the implementation of makes it obvious why this is the case: In , only is used (in ), but since sets are unordered, so is the resulting iterator. This means, for sets such an implementation cannot work. What makes things worse is the confusion that seems to exist here between the different abstract base classes: In the method, clearly is mentioned, explicitly. However, a set is not a sequence type, but only a collection type (because of the missing order). It is, however, iterable and since this is the only thing that is actually checked in the implementation, the code seems to work for sets, where, in fact, it does not. As a first step, I would suggest one could keep the current implementation, but explicitly check for sequence types (i.e. classes having a method) and delete all mentions of in the code as well as on the documentation page and make it crystal clear that there is only an implementation for sequence types. But what would be way better would, of course, be an implementation for arbitrary container comparisons. Tested with pytest version 7.0.1.

raise TypeError(msg.format(key, value, pprint.pformat(self.expected)))  class ApproxSequencelike(ApproxBase):class ApproxSequenceLike(ApproxBase):     """Perform approximate comparisons where the expected value is a sequence of numbers."""      def __repr__(self) -> str:         seq_type = type(self.expected)        if seq_type not in (tuple, list, set):        if seq_type not in (tuple, list):             seq_type = list         return "approx({!r})".format(             seq_type(self._approx_scalar(x) for x in self.expected)


Question: Current implementation of cannot be used to compare sets The current implementation of yields incorrect results when used to compare sets. Consider the following self-explanatory code comparing two (equal as by ) sets: Although the two sets are obviously the same, the last equality check using approx is failing. A quick view into the implementation of makes it obvious why this is the case: In , only is used (in ), but since sets are unordered, so is the resulting iterator. This means, for sets such an implementation cannot work. What makes things worse is the confusion that seems to exist here between the different abstract base classes: In the method, clearly is mentioned, explicitly. However, a set is not a sequence type, but only a collection type (because of the missing order). It is, however, iterable and since this is the only thing that is actually checked in the implementation, the code seems to work for sets, where, in fact, it does not. As a first step, I would suggest one could keep the current implementation, but explicitly check for sequence types (i.e. classes having a method) and delete all mentions of in the code as well as on the documentation page and make it crystal clear that there is only an implementation for sequence types. But what would be way better would, of course, be an implementation for arbitrary container comparisons. Tested with pytest version 7.0.1.

def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase:    """Assert that two numbers (or two sets of numbers) are equal to each other    """Assert that two numbers (or two ordered sequences of numbers) are equal to each other     within some tolerance.      Due to the :std:doc:`tutorial/floatingpoint`, numbers that we


Question: Current implementation of cannot be used to compare sets The current implementation of yields incorrect results when used to compare sets. Consider the following self-explanatory code comparing two (equal as by ) sets: Although the two sets are obviously the same, the last equality check using approx is failing. A quick view into the implementation of makes it obvious why this is the case: In , only is used (in ), but since sets are unordered, so is the resulting iterator. This means, for sets such an implementation cannot work. What makes things worse is the confusion that seems to exist here between the different abstract base classes: In the method, clearly is mentioned, explicitly. However, a set is not a sequence type, but only a collection type (because of the missing order). It is, however, iterable and since this is the only thing that is actually checked in the implementation, the code seems to work for sets, where, in fact, it does not. As a first step, I would suggest one could keep the current implementation, but explicitly check for sequence types (i.e. classes having a method) and delete all mentions of in the code as well as on the documentation page and make it crystal clear that there is only an implementation for sequence types. But what would be way better would, of course, be an implementation for arbitrary container comparisons. Tested with pytest version 7.0.1.

>>> 0.1 + 0.2 == approx(0.3)         True     The same syntax also works for sequences of numbers::    The same syntax also works for ordered sequences of numbers::          >>> (0.1 + 0.2, 0.2 + 0.4) == approx((0.3, 0.6))         True     Dictionary *values*::        >>> {'a': 0.1 + 0.2, 'b': 0.2 + 0.4} == approx({'a': 0.3, 'b': 0.6})        True     ``numpy`` arrays::          >>> import numpy as np                                                          # doctest: +SKIP