homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Setting a exception side_effect on a mock from create_autospec does not work
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.6, Python 3.4, Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Ignacio Rossi, and, berker.peksag, michael.foord, python-dev, rbcollins
Priority: normal Keywords: patch

Created on 2015年03月14日 00:45 by Ignacio Rossi, last changed 2022年04月11日 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
autospec_exception.patch Ignacio Rossi, 2015年03月14日 04:19 Test and fix for autospeccing functions with exceptions review
Messages (7)
msg238064 - (view) Author: Ignacio Rossi (Ignacio Rossi) * Date: 2015年03月14日 00:45
The following fails on python 3.4.2, 3.4.3 and 3.5.0a2 (downloaded from python.org and compiled on Ubuntu 14.04). 
The same happens when using mock.patch with autospec=True.
>>> from unittest.mock import create_autospec
>>> def function():
... pass
... 
>>> mock = create_autospec(function)
>>> mock.side_effect = ValueError('MyError')
>>> mock()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<string>", line 3, in function
 File "/usr/local/lib/python3.5/unittest/mock.py", line 910, in __call__
 return _mock_self._mock_call(*args, **kwargs)
 File "/usr/local/lib/python3.5/unittest/mock.py", line 963, in _mock_call
 effect = self.side_effect
 File "/usr/local/lib/python3.5/unittest/mock.py", line 510, in __get_side_effect
 sf = _MockIter(sf)
 File "/usr/local/lib/python3.5/unittest/mock.py", line 351, in __init__
 self.obj = iter(obj)
TypeError: 'ValueError' object is not iterable
But, on Python 3.3.5, 3.4.0, or when the mock is created via Mock(), for instance, the exception is raised as expected:
[...]
>>> mock()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<string>", line 3, in function
 File "/usr/lib/python3.4/unittest/mock.py", line 885, in __call__
 return _mock_self._mock_call(*args, **kwargs)
 File "/usr/lib/python3.4/unittest/mock.py", line 941, in _mock_call
 raise effect
ValueError: MyError
msg238071 - (view) Author: Ignacio Rossi (Ignacio Rossi) * Date: 2015年03月14日 04:19
The problem only affects autospecced functions.
Apparently, the problem lies here (all code excerpts from Lib/unittest/mock.py):
- When autospeccing functions, the Mock._mock_delegate field is populated at the end of _setup_func (and its the only place I found where the delegate is set):
197 def _setup_func(funcopy, mock):
[...]
237 mock._mock_delegate = funcopy
- Mock.side_effect is a property, and proxies the get/set to _mock_delegate when it exists, and on the way out does not detect the exception and tries to make an _IterMock out of it and everything explodes.
 504 def __get_side_effect(self):
 505 delegated = self._mock_delegate
 506 if delegated is None:
 507 return self._mock_side_effect
 508 sf = delegated.side_effect
 509 if sf is not None and not callable(sf) and not isinstance(sf, _MockIter):
 510 sf = _MockIter(sf)
I've attached a patch which adds a test for this use case, and a proposed fix. Hope it helps :)
msg246707 - (view) Author: Robert Collins (rbcollins) * (Python committer) Date: 2015年07月14日 01:17
Also reported in the mock project as https://github.com/testing-cabal/mock/issues/264 
msg246708 - (view) Author: Robert Collins (rbcollins) * (Python committer) Date: 2015年07月14日 01:19
This looks fine to me, I'm going to apply it.
msg246709 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2015年07月14日 01:59
New changeset db825807ab04 by Robert Collins in branch 'default':
Issue #23661: unittest.mock side_effects can now be exceptions again.
https://hg.python.org/cpython/rev/db825807ab04 
msg246716 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2015年07月14日 04:48
New changeset 7021d46c490e by Robert Collins in branch '3.5':
Issue #23661: unittest.mock side_effects can now be exceptions again.
https://hg.python.org/cpython/rev/7021d46c490e
New changeset 231bf0840f8f by Robert Collins in branch 'default':
Issue 23661: null-merge with 3.5.
https://hg.python.org/cpython/rev/231bf0840f8f 
msg254842 - (view) Author: Dmitry Andreychuk (and) Date: 2015年11月18日 11:13
python 3.4.3 is also affected. Is it possible to fix this in branch 3.4?
History
Date User Action Args
2022年04月11日 14:58:13adminsetgithub: 67849
2015年11月18日 11:13:20andsetnosy: + and

messages: + msg254842
versions: + Python 3.4
2015年07月16日 01:55:59berker.peksagsetstatus: open -> closed
stage: resolved
resolution: fixed
versions: + Python 3.6, - Python 3.4
2015年07月14日 04:48:41python-devsetmessages: + msg246716
2015年07月14日 01:59:09python-devsetnosy: + python-dev
messages: + msg246709
2015年07月14日 01:19:20rbcollinssetmessages: + msg246708
2015年07月14日 01:17:53rbcollinssetnosy: + rbcollins
messages: + msg246707
2015年03月14日 22:32:58ned.deilysetnosy: + michael.foord, berker.peksag
2015年03月14日 04:19:33Ignacio Rossisetfiles: + autospec_exception.patch
keywords: + patch
messages: + msg238071
2015年03月14日 00:45:40Ignacio Rossicreate

AltStyle によって変換されたページ (->オリジナル) /