[issue23661] Setting a exception side_effect on a mock from create_autospec does not work

2015-03-13 Thread Ignacio Rossi

New submission from Ignacio Rossi:

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 "", line 1, in 
  File "", 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 "", line 1, in 
  File "", 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

--
components: Library (Lib)
messages: 238064
nosy: Ignacio Rossi
priority: normal
severity: normal
status: open
title: Setting a exception side_effect on a mock from create_autospec does not 
work
type: behavior
versions: Python 3.4, Python 3.5

___
Python tracker 
<http://bugs.python.org/issue23661>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue23661] Setting a exception side_effect on a mock from create_autospec does not work

2015-03-13 Thread Ignacio Rossi

Ignacio Rossi added the comment:

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 :)

--
keywords: +patch
Added file: http://bugs.python.org/file38479/autospec_exception.patch

___
Python tracker 
<http://bugs.python.org/issue23661>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com