Skip to content

doc: PropertyMock refuses to raise AttributeErrror as a side effect #65453

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

Closed
voidspace opened this issue Apr 16, 2014 · 7 comments
Closed

doc: PropertyMock refuses to raise AttributeErrror as a side effect #65453

voidspace opened this issue Apr 16, 2014 · 7 comments
Assignees
Labels
3.8 (EOL) end of life 3.9 only security fixes 3.10 only security fixes docs Documentation in the Doc dir easy stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@voidspace
Copy link
Contributor

voidspace commented Apr 16, 2014

BPO 21254
Nosy @rbtcollins, @voidspace, @ericsnowcurrently, @kushaldas, @s-t-e-v-e-n-k

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 = 'https://github.com/voidspace'
closed_at = None
created_at = <Date 2014-04-16.16:15:17.468>
labels = ['easy', 'type-bug', '3.8', '3.9', '3.10', 'library', 'docs']
title = 'doc: PropertyMock refuses to raise AttributeErrror as a side effect'
updated_at = <Date 2021-03-28.22:54:36.893>
user = 'https://github.com/voidspace'

bugs.python.org fields:

activity = <Date 2021-03-28.22:54:36.893>
actor = 'iritkatriel'
assignee = 'michael.foord'
closed = False
closed_date = None
closer = None
components = ['Documentation', 'Library (Lib)']
creation = <Date 2014-04-16.16:15:17.468>
creator = 'michael.foord'
dependencies = []
files = []
hgrepos = []
issue_num = 21254
keywords = ['easy']
message_count = 5.0
messages = ['216487', '216503', '275934', '275937', '275938']
nosy_count = 5.0
nosy_names = ['rbcollins', 'michael.foord', 'eric.snow', 'kushal.das', 'stevenk']
pr_nums = []
priority = 'normal'
resolution = None
stage = 'needs patch'
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue21254'
versions = ['Python 3.8', 'Python 3.9', 'Python 3.10']

Linked PRs

@voidspace
Copy link
Contributor Author

What steps will reproduce the problem?

>> import mock
>> a_mock = mock.MagicMock()
>> no_attribute = mock.PropertyMock(side_effect=AttributeError)
>> type(a_mock).property = no_attribute

What is the expected output? What do you see instead?

I would expect the above to raise an AttributeError. Instead it returns a MagicMock instance.

>>> a_mock.property
<MagicMock name='mock.property' id='140165240345424'>

I would expect it to have the same effect as calling a PropertyMock with any other exception as a side effect:

>>> mock_value_error = mock.PropertyMock(side_effect=ValueError)
>>> type(a_mock).other_property = mock_value_error
>>> a_mock.other_property
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/ahammel/bin/python/mock-1.0.1-py2.6.egg/mock.py", line 2365, in __get__
    return self()
  File "/home/ahammel/bin/python/mock-1.0.1-py2.6.egg/mock.py", line 955, in __call__
    return _mock_self._mock_call(*args, **kwargs)
  File "/home/ahammel/bin/python/mock-1.0.1-py2.6.egg/mock.py", line 1010, in _mock_call
    raise effect
ValueError

What version of the product are you using? On what operating system?

Using version mock-1.0.1-py2.6 on CentOS 6.4

Please provide any additional information below.

PropertyMock objects apparently won't raise sublcasses of AttributeError either:

>>> class MockAttributeError(AttributeError): pass
... 
>>> no_attr = mock.PropertyMock(side_effect=MockAttributeError)
>>> type(a_mock).property = no_attr
>>> a_mock.property
<MagicMock name='mock.property' id='140165240345424'>

Works fine for subclasses of other Exceptions:

>>> class MockKeyError(KeyError): pass
... 
>>> no_key = mock.PropertyMock(side_effect=MockKeyError)
>>> type(a_mock).property = no_key
>>> a_mock.property
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/ahammel/bin/python/mock-1.0.1-py2.6.egg/mock.py", line 2365, in __get__
    return self()
  File "/home/ahammel/bin/python/mock-1.0.1-py2.6.egg/mock.py", line 955, in __call__
    return _mock_self._mock_call(*args, **kwargs)
  File "/home/ahammel/bin/python/mock-1.0.1-py2.6.egg/mock.py", line 1010, in _mock_call
    raise effect
__main__.MockKeyError

@voidspace voidspace self-assigned this Apr 16, 2014
@voidspace voidspace added easy type-bug An unexpected behavior, bug, or error labels Apr 16, 2014
@ericsnowcurrently
Copy link
Member

Perhaps related to bpo-1615?

@rbtcollins
Copy link
Member

We're poking at this at the kiwipycon sprints

@s-t-e-v-e-n-k
Copy link
Mannequin

s-t-e-v-e-n-k mannequin commented Sep 12, 2016

This is in fact, working entirely as expected.

If we define a property that raises an AttributeError, then __getattr__() will be called, since the descriptor protocol says that an attribute error is a missing descriptor.

>>> class Foo(object):
...   def __getattr__(self, attr):
...     return 42
...   @property
...   def bacon(self):
...     print(1)
...     return int.lala
... 
>>> Foo().bacon
1
42

If we then follow a similar pattern using mock:

>>> from unittest import mock
>>> a_mock = mock.MagicMock()
>>> def foo():
...   print(1)
...   raise AttributeError()
... 
>>> no_attribute = mock.PropertyMock(side_effect=foo)
>>> type(a_mock).property = no_attribute
>>> a_mock.property
1
<MagicMock name='mock.property' id='139971099507232'>

You can see that the method is called, since we print one, but then what is going on is that MagicMock.__getattr__ is called, which has the behavior to return a new mock, like so:

>>> a_mock.b
<MagicMock name='mock.b' id='139971099646776'>

@rbtcollins
Copy link
Member

I could imagine doing some complex things to let you get at the AttributeError in this case but *not* when a different descriptor was added to type(a_mock), but I think it would confusing overall. This might be worth a doc tweak to cover it?

@rbtcollins rbtcollins added the 3.7 (EOL) end of life label Sep 12, 2016
@iritkatriel iritkatriel added 3.8 (EOL) end of life 3.9 only security fixes 3.10 only security fixes docs Documentation in the Doc dir stdlib Python modules in the Lib dir and removed 3.7 (EOL) end of life labels Mar 28, 2021
@iritkatriel iritkatriel changed the title PropertyMock refuses to raise AttributeErrror as a side effect doc: PropertyMock refuses to raise AttributeErrror as a side effect Mar 28, 2021
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@ziima
Copy link
Contributor

ziima commented Jul 13, 2024

Problem still exists in 3.14. I'm updating the docs on EuroPython 24 sprints.

ziima added a commit to ziima/cpython that referenced this issue Jul 13, 2024
encukou pushed a commit that referenced this issue Jul 18, 2024
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jul 18, 2024
…ck (pythonGH-121666)

Fixed at EuroPython 24 sprints.
(cherry picked from commit 94e6644)

Co-authored-by: Vlastimil Zíma <[email protected]>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jul 18, 2024
…ck (pythonGH-121666)

Fixed at EuroPython 24 sprints.
(cherry picked from commit 94e6644)

Co-authored-by: Vlastimil Zíma <[email protected]>
encukou pushed a commit that referenced this issue Jul 19, 2024
…ock (GH-121666) (GH-121968)

Fixed at EuroPython 24 sprints.
(cherry picked from commit 94e6644)

Co-authored-by: Vlastimil Zíma <[email protected]>
encukou pushed a commit that referenced this issue Jul 19, 2024
…ock (GH-121666) (GH-121969)

Fixed at EuroPython 24 sprints.
(cherry picked from commit 94e6644)

Co-authored-by: Vlastimil Zíma <[email protected]>
@encukou
Copy link
Member

encukou commented Jul 19, 2024

Thank you for the fix!

@encukou encukou closed this as completed Jul 19, 2024
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 docs Documentation in the Doc dir easy stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
Status: Done
Development

No branches or pull requests

7 participants
@voidspace @encukou @ziima @rbtcollins @iritkatriel @ericsnowcurrently and others