Skip to content

Commit 5257e3c

Browse files
committed
Refactor MockCache to have a narrow interface
It should also be responsible for stopping the patchers, instead of acting merely as storage. Follow up the previous commit.
1 parent 4faf92a commit 5257e3c

File tree

1 file changed

+15
-17
lines changed

1 file changed

+15
-17
lines changed

src/pytest_mock/plugin.py

+15-17
Original file line numberDiff line numberDiff line change
@@ -49,33 +49,37 @@ class MockCacheItem:
4949

5050
@dataclass
5151
class MockCache:
52+
"""
53+
Cache MagicMock and Patcher instances so we can undo them later.
54+
"""
55+
5256
cache: List[MockCacheItem] = field(default_factory=list)
5357

54-
def find(self, mock: MockType) -> MockCacheItem:
55-
the_mock = next(
56-
(mock_item for mock_item in self.cache if mock_item.mock == mock), None
57-
)
58-
if the_mock is None:
59-
raise ValueError("This mock object is not registered")
60-
return the_mock
58+
def _find(self, mock: MockType) -> MockCacheItem:
59+
for mock_item in self.cache:
60+
if mock_item.mock is mock:
61+
return mock_item
62+
raise ValueError("This mock object is not registered")
6163

6264
def add(self, mock: MockType, **kwargs: Any) -> MockCacheItem:
6365
self.cache.append(MockCacheItem(mock=mock, **kwargs))
6466
return self.cache[-1]
6567

6668
def remove(self, mock: MockType) -> None:
67-
mock_item = self.find(mock)
69+
mock_item = self._find(mock)
70+
if mock_item.patch:
71+
mock_item.patch.stop()
6872
self.cache.remove(mock_item)
6973

7074
def clear(self) -> None:
75+
for mock_item in reversed(self.cache):
76+
if mock_item.patch is not None:
77+
mock_item.patch.stop()
7178
self.cache.clear()
7279

7380
def __iter__(self) -> Iterator[MockCacheItem]:
7481
return iter(self.cache)
7582

76-
def __reversed__(self) -> Iterator[MockCacheItem]:
77-
return reversed(self.cache)
78-
7983

8084
class MockerFixture:
8185
"""
@@ -146,19 +150,13 @@ def stopall(self) -> None:
146150
Stop all patchers started by this fixture. Can be safely called multiple
147151
times.
148152
"""
149-
for mock_item in reversed(self._mock_cache):
150-
if mock_item.patch is not None:
151-
mock_item.patch.stop()
152153
self._mock_cache.clear()
153154

154155
def stop(self, mock: unittest.mock.MagicMock) -> None:
155156
"""
156157
Stops a previous patch or spy call by passing the ``MagicMock`` object
157158
returned by it.
158159
"""
159-
mock_item = self._mock_cache.find(mock)
160-
if mock_item.patch:
161-
mock_item.patch.stop()
162160
self._mock_cache.remove(mock)
163161

164162
def spy(self, obj: object, name: str) -> MockType:

0 commit comments

Comments
 (0)