From 6bd8712a14a1a11d348354318fdbad3fd9bbdb78 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 21 Mar 2024 16:45:05 -0300 Subject: [PATCH] Drop pre-Python 3.8 support code pytest-mock only supports Python 3.8+ since version 3.12. --- src/pytest_mock/plugin.py | 23 +++++++--------------- tests/test_pytest_mock.py | 40 ++++++++------------------------------- 2 files changed, 15 insertions(+), 48 deletions(-) diff --git a/src/pytest_mock/plugin.py b/src/pytest_mock/plugin.py index 354752b..0d1e188 100644 --- a/src/pytest_mock/plugin.py +++ b/src/pytest_mock/plugin.py @@ -2,7 +2,6 @@ import builtins import functools import inspect -import sys import unittest.mock import warnings from dataclasses import dataclass @@ -30,16 +29,12 @@ _T = TypeVar("_T") -if sys.version_info >= (3, 8): - AsyncMockType = unittest.mock.AsyncMock - MockType = Union[ - unittest.mock.MagicMock, - unittest.mock.AsyncMock, - unittest.mock.NonCallableMagicMock, - ] -else: - AsyncMockType = Any - MockType = Union[unittest.mock.MagicMock, unittest.mock.NonCallableMagicMock] +AsyncMockType = unittest.mock.AsyncMock +MockType = Union[ + unittest.mock.MagicMock, + unittest.mock.AsyncMock, + unittest.mock.NonCallableMagicMock, +] class PytestMockWarning(UserWarning): @@ -271,17 +266,13 @@ def _start_patch( # check if `mocked` is actually a mock object, as depending on autospec or target # parameters `mocked` can be anything if hasattr(mocked, "__enter__") and warn_on_mock_enter: - if sys.version_info >= (3, 8): - depth = 5 - else: - depth = 4 mocked.__enter__.side_effect = lambda: warnings.warn( "Mocks returned by pytest-mock do not need to be used as context managers. " "The mocker fixture automatically undoes mocking at the end of a test. " "This warning can be ignored if it was triggered by mocking a context manager. " "https://pytest-mock.readthedocs.io/en/latest/remarks.html#usage-as-context-manager", PytestMockWarning, - stacklevel=depth, + stacklevel=5, ) return mocked diff --git a/tests/test_pytest_mock.py b/tests/test_pytest_mock.py index 1d43d9e..61b75d8 100644 --- a/tests/test_pytest_mock.py +++ b/tests/test_pytest_mock.py @@ -9,6 +9,7 @@ from typing import Generator from typing import Tuple from typing import Type +from unittest.mock import AsyncMock from unittest.mock import MagicMock import pytest @@ -22,14 +23,9 @@ platform.python_implementation() == "PyPy", reason="could not make it work on pypy" ) -# Python 3.8 changed the output formatting (bpo-35500), which has been ported to mock 3.0 -NEW_FORMATTING = sys.version_info >= (3, 8) # Python 3.11.7 changed the output formatting, https://github.com/python/cpython/issues/111019 NEWEST_FORMATTING = sys.version_info >= (3, 11, 7) -if sys.version_info[:2] >= (3, 8): - from unittest.mock import AsyncMock - @pytest.fixture def needs_assert_rewrite(pytestconfig): @@ -173,12 +169,7 @@ def test_mock_patch_dict_resetall(mocker: MockerFixture) -> None: "NonCallableMock", "PropertyMock", "sentinel", - pytest.param( - "seal", - marks=pytest.mark.skipif( - sys.version_info < (3, 7), reason="seal is present on 3.7 and above" - ), - ), + "seal", ], ) def test_mocker_aliases(name: str, pytestconfig: Any) -> None: @@ -243,10 +234,8 @@ def __test_failure_message(self, mocker: MockerFixture, **kwargs: Any) -> None: expected_name = kwargs.get("name") or "mock" if NEWEST_FORMATTING: msg = "expected call not found.\nExpected: {0}()\n Actual: not called." - elif NEW_FORMATTING: - msg = "expected call not found.\nExpected: {0}()\nActual: not called." else: - msg = "Expected call: {0}()\nNot called" + msg = "expected call not found.\nExpected: {0}()\nActual: not called." expected_message = msg.format(expected_name) stub = mocker.stub(**kwargs) with pytest.raises(AssertionError, match=re.escape(expected_message)): @@ -259,10 +248,6 @@ def test_failure_message_with_no_name(self, mocker: MagicMock) -> None: def test_failure_message_with_name(self, mocker: MagicMock, name: str) -> None: self.__test_failure_message(mocker, name=name) - @pytest.mark.skipif( - sys.version_info[:2] < (3, 8), - reason="This Python version doesn't have `AsyncMock`.", - ) def test_async_stub_type(self, mocker: MockerFixture) -> None: assert isinstance(mocker.async_stub(), AsyncMock) @@ -892,17 +877,11 @@ def test(mocker): """ ) result = testdir.runpytest("-s") - if NEW_FORMATTING: - expected_lines = [ - "*AssertionError: expected call not found.", - "*Expected: mock('', bar=4)", - "*Actual: mock('fo')", - ] - else: - expected_lines = [ - "*AssertionError: Expected call: mock('', bar=4)*", - "*Actual call: mock('fo')*", - ] + expected_lines = [ + "*AssertionError: expected call not found.", + "*Expected: mock('', bar=4)", + "*Actual: mock('fo')", + ] expected_lines += [ "*pytest introspection follows:*", "*Args:", @@ -918,9 +897,6 @@ def test(mocker): result.stdout.fnmatch_lines(expected_lines) -@pytest.mark.skipif( - sys.version_info < (3, 8), reason="AsyncMock is present on 3.8 and above" -) @pytest.mark.usefixtures("needs_assert_rewrite") def test_detailed_introspection_async(testdir: Any) -> None: """Check that the "mock_use_standalone" is being used."""