From f1d51ba1f57619e71cdf787ff1507be59a057c73 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Sun, 29 Mar 2020 20:30:16 +0200 Subject: [PATCH] deprecate the pytest.collect module changelog minimal unittest for collect module deprecations \!fixup - changelog typo --- changelog/6981.deprecation.rst | 1 + src/_pytest/compat.py | 24 --------------------- src/_pytest/deprecated.py | 6 ++++++ src/pytest/__init__.py | 8 ++----- src/pytest/collect.py | 38 ++++++++++++++++++++++++++++++++++ testing/deprecated_test.py | 7 +++++++ 6 files changed, 54 insertions(+), 30 deletions(-) create mode 100644 changelog/6981.deprecation.rst create mode 100644 src/pytest/collect.py diff --git a/changelog/6981.deprecation.rst b/changelog/6981.deprecation.rst new file mode 100644 index 000000000..ac32706fa --- /dev/null +++ b/changelog/6981.deprecation.rst @@ -0,0 +1 @@ +Deprecate the ``pytest.collect`` module as it's just aliases into ``pytest``. diff --git a/src/_pytest/compat.py b/src/_pytest/compat.py index 1845d9d91..8aff8d57d 100644 --- a/src/_pytest/compat.py +++ b/src/_pytest/compat.py @@ -336,30 +336,6 @@ def safe_isclass(obj: object) -> bool: return False -COLLECT_FAKEMODULE_ATTRIBUTES = ( - "Collector", - "Module", - "Function", - "Instance", - "Session", - "Item", - "Class", - "File", - "_fillfuncargs", -) - - -def _setup_collect_fakemodule() -> None: - from types import ModuleType - import pytest - - # Types ignored because the module is created dynamically. - pytest.collect = ModuleType("pytest.collect") # type: ignore - pytest.collect.__all__ = [] # type: ignore # used for setns - for attr_name in COLLECT_FAKEMODULE_ATTRIBUTES: - setattr(pytest.collect, attr_name, getattr(pytest, attr_name)) # type: ignore - - class CaptureIO(io.TextIOWrapper): def __init__(self) -> None: super().__init__(io.BytesIO(), encoding="UTF-8", newline="", write_through=True) diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index ee27b20ec..d84864618 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -56,6 +56,12 @@ COLLECT_DIRECTORY_HOOK = PytestDeprecationWarning( "Please use collect_ignore in conftests or pytest_collection_modifyitems." ) +PYTEST_COLLECT_MODULE = UnformattedWarning( + PytestDeprecationWarning, + "pytest.collect.{name} was moved to pytest.{name}\n" + "Please update to the new name.", +) + TERMINALWRITER_WRITER = PytestDeprecationWarning( "The TerminalReporter.writer attribute is deprecated, use TerminalReporter._tw instead at your own risk.\n" diff --git a/src/pytest/__init__.py b/src/pytest/__init__.py index 33bc3d0fb..5c93decc3 100644 --- a/src/pytest/__init__.py +++ b/src/pytest/__init__.py @@ -2,9 +2,9 @@ """ pytest: unit and functional testing with Python. """ +from . import collect from _pytest import __version__ from _pytest.assertion import register_assert_rewrite -from _pytest.compat import _setup_collect_fakemodule from _pytest.config import cmdline from _pytest.config import ExitCode from _pytest.config import hookimpl @@ -46,7 +46,6 @@ from _pytest.warning_types import PytestUnhandledCoroutineWarning from _pytest.warning_types import PytestUnknownMarkWarning from _pytest.warning_types import PytestWarning - set_trace = __pytestPDB.set_trace __all__ = [ @@ -55,6 +54,7 @@ __all__ = [ "approx", "Class", "cmdline", + "collect", "Collector", "deprecated_call", "exit", @@ -93,7 +93,3 @@ __all__ = [ "xfail", "yield_fixture", ] - - -_setup_collect_fakemodule() -del _setup_collect_fakemodule diff --git a/src/pytest/collect.py b/src/pytest/collect.py new file mode 100644 index 000000000..73c9d35a0 --- /dev/null +++ b/src/pytest/collect.py @@ -0,0 +1,38 @@ +import sys +import warnings +from types import ModuleType + +import pytest +from _pytest.deprecated import PYTEST_COLLECT_MODULE + + +COLLECT_FAKEMODULE_ATTRIBUTES = [ + "Collector", + "Module", + "Function", + "Instance", + "Session", + "Item", + "Class", + "File", + "_fillfuncargs", +] + + +class FakeCollectModule(ModuleType): + def __init__(self): + super().__init__("pytest.collect") + self.__all__ = list(COLLECT_FAKEMODULE_ATTRIBUTES) + self.__pytest = pytest + + def __dir__(self): + return dir(super()) + self.__all__ + + def __getattr__(self, name): + if name not in self.__all__: + raise AttributeError(name) + warnings.warn(PYTEST_COLLECT_MODULE.format(name=name), stacklevel=2) + return getattr(pytest, name) + + +sys.modules["pytest.collect"] = FakeCollectModule() diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index ce54783f4..93601d0a9 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -25,6 +25,13 @@ def test_resultlog_is_deprecated(testdir): ) +@pytest.mark.parametrize("attribute", pytest.collect.__all__) # type: ignore +# false positive due to dynamic attribute +def test_pytest_collect_module_deprecated(attribute): + with pytest.warns(DeprecationWarning, match=attribute): + getattr(pytest.collect, attribute) + + def test_terminal_reporter_writer_attr(pytestconfig): """Check that TerminalReporter._tw is also available as 'writer' (#2984) This attribute has been deprecated in 5.4.