Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting a exception side_effect on a mock from create_autospec does not work #67849

Closed
IgnacioRossi mannequin opened this issue Mar 14, 2015 · 7 comments
Closed

Setting a exception side_effect on a mock from create_autospec does not work #67849

IgnacioRossi mannequin opened this issue Mar 14, 2015 · 7 comments
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@IgnacioRossi
Copy link
Mannequin

IgnacioRossi mannequin commented Mar 14, 2015

BPO 23661
Nosy @rbtcollins, @voidspace, @berkerpeksag
Files
  • autospec_exception.patch: Test and fix for autospeccing functions with exceptions
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2015-07-16.01:55:59.296>
    created_at = <Date 2015-03-14.00:45:40.133>
    labels = ['type-bug', 'library']
    title = 'Setting a exception side_effect on a mock from create_autospec does not work'
    updated_at = <Date 2015-11-18.11:13:20.690>
    user = 'https://bugs.python.org/IgnacioRossi'

    bugs.python.org fields:

    activity = <Date 2015-11-18.11:13:20.690>
    actor = 'and'
    assignee = 'none'
    closed = True
    closed_date = <Date 2015-07-16.01:55:59.296>
    closer = 'berker.peksag'
    components = ['Library (Lib)']
    creation = <Date 2015-03-14.00:45:40.133>
    creator = 'Ignacio Rossi'
    dependencies = []
    files = ['38479']
    hgrepos = []
    issue_num = 23661
    keywords = ['patch']
    message_count = 7.0
    messages = ['238064', '238071', '246707', '246708', '246709', '246716', '254842']
    nosy_count = 6.0
    nosy_names = ['rbcollins', 'michael.foord', 'python-dev', 'berker.peksag', 'and', 'Ignacio Rossi']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue23661'
    versions = ['Python 3.4', 'Python 3.5', 'Python 3.6']

    @IgnacioRossi
    Copy link
    Mannequin Author

    IgnacioRossi mannequin commented Mar 14, 2015

    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

    @IgnacioRossi IgnacioRossi mannequin added stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Mar 14, 2015
    @IgnacioRossi
    Copy link
    Mannequin Author

    IgnacioRossi mannequin commented Mar 14, 2015

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

    @rbtcollins
    Copy link
    Member

    Also reported in the mock project as testing-cabal/mock#264

    @rbtcollins
    Copy link
    Member

    This looks fine to me, I'm going to apply it.

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Jul 14, 2015

    New changeset db825807ab04 by Robert Collins in branch 'default':
    Issue bpo-23661: unittest.mock side_effects can now be exceptions again.
    https://hg.python.org/cpython/rev/db825807ab04

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Jul 14, 2015

    New changeset 7021d46c490e by Robert Collins in branch '3.5':
    Issue bpo-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':
    bpo-23661: null-merge with 3.5.
    https://hg.python.org/cpython/rev/231bf0840f8f

    @and
    Copy link
    Mannequin

    and mannequin commented Nov 18, 2015

    python 3.4.3 is also affected. Is it possible to fix this in branch 3.4?

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants