summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorinfohash <46137868+infohash@users.noreply.github.com>2024-05-02 17:36:35 (GMT)
committerGitHub <noreply@github.com>2024-05-02 17:36:35 (GMT)
commitb28a3339e4c63ea3a801dba9bbbc6af5af42c3a0 (patch)
tree59596b2a6485be23e5e4af72198816d97ed93495
parent6bcbee09df9f6fa6496fb7f68b6d655f190903a7 (diff)
downloadcpython-b28a3339e4c63ea3a801dba9bbbc6af5af42c3a0.zip
cpython-b28a3339e4c63ea3a801dba9bbbc6af5af42c3a0.tar.gz
cpython-b28a3339e4c63ea3a801dba9bbbc6af5af42c3a0.tar.bz2
gh-90848: Fixed create_autospec ignoring configure_mock style kwargs (#118163)
-rw-r--r--Lib/test/test_unittest/testmock/testmock.py13
-rw-r--r--Lib/unittest/mock.py20
-rw-r--r--Misc/NEWS.d/next/Library/2024-04-22-21-54-12.gh-issue-90848.5jHEEc.rst1
3 files changed, 26 insertions, 8 deletions
diff --git a/Lib/test/test_unittest/testmock/testmock.py b/Lib/test/test_unittest/testmock/testmock.py
index b81b304..77f6f1e 100644
--- a/Lib/test/test_unittest/testmock/testmock.py
+++ b/Lib/test/test_unittest/testmock/testmock.py
@@ -115,6 +115,19 @@ class MockTest(unittest.TestCase):
with self.assertRaises(TypeError):
mock()
+ def test_create_autospec_should_be_configurable_by_kwargs(self):
+ """If kwargs are given to configure mock, the function must configure
+ the parent mock during initialization."""
+ mocked_result = 'mocked value'
+ class_mock = create_autospec(spec=Something, **{
+ 'return_value.meth.side_effect': [ValueError, DEFAULT],
+ 'return_value.meth.return_value': mocked_result})
+ with self.assertRaises(ValueError):
+ class_mock().meth(a=None, b=None, c=None)
+ self.assertEqual(class_mock().meth(a=None, b=None, c=None), mocked_result)
+ # Only the parent mock should be configurable because the user will
+ # pass kwargs with respect to the parent mock.
+ self.assertEqual(class_mock().return_value.meth.side_effect, None)
def test_repr(self):
mock = Mock(name='foo')
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 1799e9b..a2634b6 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -2788,8 +2788,8 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
if _parent is not None and not instance:
_parent._mock_children[_name] = mock
- wrapped = kwargs.get('wraps')
-
+ # Pop wraps from kwargs because it must not be passed to configure_mock.
+ wrapped = kwargs.pop('wraps', None)
if is_type and not instance and 'return_value' not in kwargs:
mock.return_value = create_autospec(spec, spec_set, instance=True,
_name='()', _parent=mock,
@@ -2814,12 +2814,12 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
except AttributeError:
continue
- kwargs = {'spec': original}
+ child_kwargs = {'spec': original}
# Wrap child attributes also.
if wrapped and hasattr(wrapped, entry):
- kwargs.update(wraps=original)
+ child_kwargs.update(wraps=original)
if spec_set:
- kwargs = {'spec_set': original}
+ child_kwargs = {'spec_set': original}
if not isinstance(original, FunctionTypes):
new = _SpecState(original, spec_set, mock, entry, instance)
@@ -2830,14 +2830,13 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
parent = mock.mock
skipfirst = _must_skip(spec, entry, is_type)
- kwargs['_eat_self'] = skipfirst
+ child_kwargs['_eat_self'] = skipfirst
if iscoroutinefunction(original):
child_klass = AsyncMock
else:
child_klass = MagicMock
new = child_klass(parent=parent, name=entry, _new_name=entry,
- _new_parent=parent,
- **kwargs)
+ _new_parent=parent, **child_kwargs)
mock._mock_children[entry] = new
new.return_value = child_klass()
_check_signature(original, new, skipfirst=skipfirst)
@@ -2848,6 +2847,11 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
# setting as an instance attribute?
if isinstance(new, FunctionTypes):
setattr(mock, entry, new)
+ # kwargs are passed with respect to the parent mock so, they are not used
+ # for creating return_value of the parent mock. So, this condition
+ # should be true only for the parent mock if kwargs are given.
+ if _is_instance_mock(mock) and kwargs:
+ mock.configure_mock(**kwargs)
return mock
diff --git a/Misc/NEWS.d/next/Library/2024-04-22-21-54-12.gh-issue-90848.5jHEEc.rst b/Misc/NEWS.d/next/Library/2024-04-22-21-54-12.gh-issue-90848.5jHEEc.rst
new file mode 100644
index 0000000..adbca01
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-04-22-21-54-12.gh-issue-90848.5jHEEc.rst
@@ -0,0 +1 @@
+Fixed :func:`unittest.mock.create_autospec` to configure parent mock with keyword arguments.