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

mock raises exception when using a spec with an attribute that raises exception on access #89917

Closed
kjamieson mannequin opened this issue Nov 8, 2021 · 4 comments
Closed
Labels
3.8 (EOL) end of life 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes type-bug An unexpected behavior, bug, or error

Comments

@kjamieson
Copy link
Mannequin

kjamieson mannequin commented Nov 8, 2021

BPO 45756
Nosy @ambv, @hongweipeng, @tirkarthi, @sobolevn, @jaap3
PRs
  • bpo-45756: do not execute @property descrs while creating mock autospecs #29901
  • bpo-45756: Fix mock triggers dynamic lookup via the descriptor protocol. #31348
  • 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 = None
    created_at = <Date 2021-11-08.19:47:53.494>
    labels = ['type-bug', '3.8', '3.9', '3.10', '3.11']
    title = 'mock raises exception when using a spec with an attribute that raises exception on access'
    updated_at = <Date 2022-02-15.06:36:26.841>
    user = 'https://bugs.python.org/kjamieson'

    bugs.python.org fields:

    activity = <Date 2022-02-15.06:36:26.841>
    actor = 'hongweipeng'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = []
    creation = <Date 2021-11-08.19:47:53.494>
    creator = 'kjamieson'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 45756
    keywords = ['patch']
    message_count = 3.0
    messages = ['405982', '406284', '406452']
    nosy_count = 6.0
    nosy_names = ['lukasz.langa', 'hongweipeng', 'xtreak', 'sobolevn', 'kjamieson', 'jaap3']
    pr_nums = ['29901', '31348']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue45756'
    versions = ['Python 3.8', 'Python 3.9', 'Python 3.10', 'Python 3.11']

    @kjamieson
    Copy link
    Mannequin Author

    kjamieson mannequin commented Nov 8, 2021

    In Python 3.8 and later creating a mock with a spec specifying an object containing a property that happens to raise an exception when accessed will fail, because _mock_add_spec calls getattr() on every attribute of the spec. This did not happen in Python 3.6/3.7.

    This is likely a fairly unusual scenario (and in the particular case where I encountered this I could just use a class instead of an instance for the spec), but it was surprising.

    For example:

    # cat test.py
    from unittest import mock
    
    class Foo:
        @property
        def bar(self) -> str:
            raise Exception('xxx')
    
    m = mock.MagicMock(spec=Foo())
    # python3.11 test.py
    Traceback (most recent call last):
      File "/root/test.py", line 8, in <module>
        m = mock.MagicMock(spec=Foo())
            ^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3.11/unittest/mock.py", line 2069, in __init__
        _safe_super(MagicMixin, self).__init__(*args, **kw)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3.11/unittest/mock.py", line 1087, in __init__
        _safe_super(CallableMixin, self).__init__(
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3.11/unittest/mock.py", line 442, in __init__
        self._mock_add_spec(spec, spec_set, _spec_as_instance, _eat_self)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3.11/unittest/mock.py", line 497, in _mock_add_spec
        if iscoroutinefunction(getattr(spec, attr, None)):
                               ^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/root/test.py", line 6, in bar
        raise Exception('xxx')
        ^^^^^^^^^^^^^^^^^^^^^^
    Exception: xxx

    @kjamieson kjamieson mannequin added 3.8 (EOL) end of life 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes type-bug An unexpected behavior, bug, or error labels Nov 8, 2021
    @jaap3
    Copy link
    Mannequin

    jaap3 mannequin commented Nov 13, 2021

    I think I encountered this when trying to mock requests.Response: psf/requests#5944

    @tirkarthi
    Copy link
    Member

    This seems to be similar to https://bugs.python.org/issue41768 .

    @carljm
    Copy link
    Member

    carljm commented May 5, 2023

    Closing as duplicate of #85934

    @carljm carljm closed this as not planned Won't fix, can't repro, duplicate, stale May 5, 2023
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.8 (EOL) end of life 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes type-bug An unexpected behavior, bug, or error
    Projects
    Status: Done
    Development

    No branches or pull requests

    2 participants