Skip to content

Commit ec4ca59

Browse files
authored
Merge pull request #5631 from RonnyPfannschmidt/fix-5606
use identity checks for the mock sentinels
2 parents 13d8577 + 8c7d912 commit ec4ca59

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

changelog/5606.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed internal error when test functions were patched with objects that cannot be compared
2+
for truth values against others, like ``numpy`` arrays.

src/_pytest/compat.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,18 @@ def num_mock_patch_args(function):
6464
patchings = getattr(function, "patchings", None)
6565
if not patchings:
6666
return 0
67-
mock_modules = [sys.modules.get("mock"), sys.modules.get("unittest.mock")]
68-
if any(mock_modules):
69-
sentinels = [m.DEFAULT for m in mock_modules if m is not None]
70-
return len(
71-
[p for p in patchings if not p.attribute_name and p.new in sentinels]
72-
)
73-
return len(patchings)
67+
68+
mock_sentinel = getattr(sys.modules.get("mock"), "DEFAULT", object())
69+
ut_mock_sentinel = getattr(sys.modules.get("unittest.mock"), "DEFAULT", object())
70+
71+
return len(
72+
[
73+
p
74+
for p in patchings
75+
if not p.attribute_name
76+
and (p.new is mock_sentinel or p.new is ut_mock_sentinel)
77+
]
78+
)
7479

7580

7681
def getfuncargnames(function, is_method=False, cls=None):

testing/python/integration.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,34 @@ def test_hello_mock(self, abspath):
178178
reprec = testdir.inline_run()
179179
reprec.assertoutcome(passed=2)
180180

181+
def test_mock_sentinel_check_against_numpy_like(self, testdir):
182+
"""Ensure our function that detects mock arguments compares against sentinels using
183+
identity to circumvent objects which can't be compared with equality against others
184+
in a truth context, like with numpy arrays (#5606).
185+
"""
186+
testdir.makepyfile(
187+
dummy="""
188+
class NumpyLike:
189+
def __init__(self, value):
190+
self.value = value
191+
def __eq__(self, other):
192+
raise ValueError("like numpy, cannot compare against others for truth")
193+
FOO = NumpyLike(10)
194+
"""
195+
)
196+
testdir.makepyfile(
197+
"""
198+
from unittest.mock import patch
199+
import dummy
200+
class Test(object):
201+
@patch("dummy.FOO", new=dummy.NumpyLike(50))
202+
def test_hello(self):
203+
assert dummy.FOO.value == 50
204+
"""
205+
)
206+
reprec = testdir.inline_run()
207+
reprec.assertoutcome(passed=1)
208+
181209
def test_mock(self, testdir):
182210
pytest.importorskip("mock", "1.0.1")
183211
testdir.makepyfile(

0 commit comments

Comments
 (0)