Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repos:
language: python
additional_dependencies: [pygments, restructuredtext_lint]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.21
rev: v0.16.0
hooks:
- id: ruff
args: ["--fix"]
Expand Down
10 changes: 5 additions & 5 deletions src/pytest_mock/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@

__all__ = [
"AsyncMockType",
"MockerFixture",
"MockFixture",
"MockType",
"MockerFixture",
"PytestMockWarning",
"SpyType",
"class_mocker",
"mocker",
"module_mocker",
"package_mocker",
"pytest_addoption",
"pytest_configure",
"session_mocker",
"package_mocker",
"module_mocker",
"class_mocker",
"mocker",
]
6 changes: 2 additions & 4 deletions src/pytest_mock/_util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import Union

_mock_module = None


Expand All @@ -15,7 +13,7 @@ def get_mock_module(config):
config.getini("mock_use_standalone_module")
)
if use_standalone_module:
import mock
from unittest import mock

_mock_module = mock
else:
Expand All @@ -26,7 +24,7 @@ def get_mock_module(config):
return _mock_module


def parse_ini_boolean(value: Union[bool, str]) -> bool:
def parse_ini_boolean(value: bool | str) -> bool:
if isinstance(value, bool):
return value
if value.lower() == "true":
Expand Down
69 changes: 34 additions & 35 deletions src/pytest_mock/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
import itertools
import unittest.mock
import warnings
from collections.abc import Callable
from collections.abc import Generator
from collections.abc import Iterable
from collections.abc import Iterator
from collections.abc import Mapping
from dataclasses import dataclass
from dataclasses import field
from typing import Any
from typing import Callable
from typing import Optional
from typing import TypeVar
from typing import Union
from typing import cast
Expand All @@ -39,9 +38,9 @@ class SpyType(unittest.mock.Mock):
"""

spy_return: Any
spy_return_iter: Optional[Iterator[Any]]
spy_return_iter: Iterator[Any] | None
spy_return_list: list[Any]
spy_exception: Optional[BaseException]
spy_exception: BaseException | None


class PytestMockWarning(UserWarning):
Expand All @@ -51,7 +50,7 @@ class PytestMockWarning(UserWarning):
@dataclass
class MockCacheItem:
mock: MockType
patch: Optional[Any] = None
patch: Any | None = None


@dataclass
Expand Down Expand Up @@ -229,7 +228,7 @@ async def async_wrapper(*args, **kwargs):
spy_obj.spy_exception = None
return spy_obj

def stub(self, name: Optional[str] = None) -> unittest.mock.MagicMock:
def stub(self, name: str | None = None) -> unittest.mock.MagicMock:
"""
Create a stub method. It accepts any arguments. Ideal to register to
callbacks in tests.
Expand All @@ -242,7 +241,7 @@ def stub(self, name: Optional[str] = None) -> unittest.mock.MagicMock:
self.mock_module.MagicMock(spec=lambda *args, **kwargs: None, name=name),
)

def async_stub(self, name: Optional[str] = None) -> AsyncMockType:
def async_stub(self, name: str | None = None) -> AsyncMockType:
"""
Create a async stub method. It accepts any arguments. Ideal to register to
callbacks in tests.
Expand Down Expand Up @@ -296,10 +295,10 @@ def object(
target: object,
attribute: str,
new: object = DEFAULT,
spec: Optional[object] = None,
spec: object | None = None,
create: bool = False,
spec_set: Optional[object] = None,
autospec: Optional[object] = None,
spec_set: object | None = None,
autospec: object | None = None,
new_callable: object = None,
**kwargs: Any,
) -> MockType:
Expand All @@ -325,10 +324,10 @@ def context_manager(
target: builtins.object,
attribute: str,
new: builtins.object = DEFAULT,
spec: Optional[builtins.object] = None,
spec: builtins.object | None = None,
create: bool = False,
spec_set: Optional[builtins.object] = None,
autospec: Optional[builtins.object] = None,
spec_set: builtins.object | None = None,
autospec: builtins.object | None = None,
new_callable: builtins.object = None,
**kwargs: Any,
) -> MockType:
Expand All @@ -353,11 +352,11 @@ def context_manager(
def multiple(
self,
target: builtins.object,
spec: Optional[builtins.object] = None,
spec: builtins.object | None = None,
create: bool = False,
spec_set: Optional[builtins.object] = None,
autospec: Optional[builtins.object] = None,
new_callable: Optional[builtins.object] = None,
spec_set: builtins.object | None = None,
autospec: builtins.object | None = None,
new_callable: builtins.object | None = None,
**kwargs: Any,
) -> dict[str, MockType]:
"""API to mock.patch.multiple"""
Expand All @@ -375,8 +374,8 @@ def multiple(

def dict(
self,
in_dict: Union[Mapping[Any, Any], str],
values: Union[Mapping[Any, Any], Iterable[tuple[Any, Any]]] = (),
in_dict: Mapping[Any, Any] | str,
values: Mapping[Any, Any] | Iterable[tuple[Any, Any]] = (),
clear: bool = False,
**kwargs: Any,
) -> Any:
Expand All @@ -395,10 +394,10 @@ def __call__(
self,
target: str,
new: None = ...,
spec: Optional[builtins.object] = ...,
spec: builtins.object | None = ...,
create: bool = ...,
spec_set: Optional[builtins.object] = ...,
autospec: Optional[builtins.object] = ...,
spec_set: builtins.object | None = ...,
autospec: builtins.object | None = ...,
new_callable: None = ...,
**kwargs: Any,
) -> MockType: ...
Expand All @@ -408,10 +407,10 @@ def __call__(
self,
target: str,
new: _T,
spec: Optional[builtins.object] = ...,
spec: builtins.object | None = ...,
create: bool = ...,
spec_set: Optional[builtins.object] = ...,
autospec: Optional[builtins.object] = ...,
spec_set: builtins.object | None = ...,
autospec: builtins.object | None = ...,
new_callable: None = ...,
**kwargs: Any,
) -> _T: ...
Expand All @@ -421,10 +420,10 @@ def __call__(
self,
target: str,
new: None,
spec: Optional[builtins.object],
spec: builtins.object | None,
create: bool,
spec_set: Optional[builtins.object],
autospec: Optional[builtins.object],
spec_set: builtins.object | None,
autospec: builtins.object | None,
new_callable: Callable[[], _T],
**kwargs: Any,
) -> _T: ...
Expand All @@ -434,10 +433,10 @@ def __call__(
self,
target: str,
new: None = ...,
spec: Optional[builtins.object] = ...,
spec: builtins.object | None = ...,
create: bool = ...,
spec_set: Optional[builtins.object] = ...,
autospec: Optional[builtins.object] = ...,
spec_set: builtins.object | None = ...,
autospec: builtins.object | None = ...,
*,
new_callable: Callable[[], _T],
**kwargs: Any,
Expand All @@ -447,11 +446,11 @@ def __call__(
self,
target: str,
new: builtins.object = DEFAULT,
spec: Optional[builtins.object] = None,
spec: builtins.object | None = None,
create: bool = False,
spec_set: Optional[builtins.object] = None,
autospec: Optional[builtins.object] = None,
new_callable: Optional[Callable[[], Any]] = None,
spec_set: builtins.object | None = None,
autospec: builtins.object | None = None,
new_callable: Callable[[], Any] | None = None,
**kwargs: Any,
) -> Any:
"""API to mock.patch"""
Expand Down
28 changes: 16 additions & 12 deletions tests/test_pytest_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import re
import sys
import warnings
from collections.abc import Callable
from collections.abc import Generator
from collections.abc import Iterable
from collections.abc import Iterator
from contextlib import contextmanager
from typing import Any
from typing import Callable
from unittest.mock import AsyncMock
from unittest.mock import MagicMock

Expand Down Expand Up @@ -50,7 +50,7 @@ def needs_assert_rewrite(pytestconfig):
if option != "rewrite":
pytest.skip(
"this test needs assertion rewrite to work but current option "
'is "{}"'.format(option)
f'is "{option}"'
)


Expand Down Expand Up @@ -1134,11 +1134,13 @@ def doIt(self):
"https://pytest-mock.readthedocs.io/en/latest/usage.html#usage-as-context-manager"
)

with pytest.warns(
PytestMockWarning, match=re.escape(expected_warning_msg)
) as warn_record:
with mocker.patch.object(a, "doIt", return_value=True):
assert a.doIt() is True
with (
pytest.warns(
PytestMockWarning, match=re.escape(expected_warning_msg)
) as warn_record,
mocker.patch.object(a, "doIt", return_value=True),
):
assert a.doIt() is True

assert warn_record[0].filename == __file__

Expand All @@ -1151,11 +1153,13 @@ def test_warn_patch_context_manager(mocker: MockerFixture) -> None:
"https://pytest-mock.readthedocs.io/en/latest/usage.html#usage-as-context-manager"
)

with pytest.warns(
PytestMockWarning, match=re.escape(expected_warning_msg)
) as warn_record:
with mocker.patch("json.loads"):
pass
with (
pytest.warns(
PytestMockWarning, match=re.escape(expected_warning_msg)
) as warn_record,
mocker.patch("json.loads"),
):
pass

assert warn_record[0].filename == __file__

Expand Down
Loading