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

unittest.mock.Mock.parent is broken or undocumented #83403

Closed
torfsen mannequin opened this issue Jan 5, 2020 · 9 comments
Closed

unittest.mock.Mock.parent is broken or undocumented #83403

torfsen mannequin opened this issue Jan 5, 2020 · 9 comments
Labels
3.11 only security fixes 3.12 bugs and security fixes docs Documentation in the Doc dir stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@torfsen
Copy link
Mannequin

torfsen mannequin commented Jan 5, 2020

BPO 39222
Nosy @cjw296, @voidspace, @lisroach, @mariocj89, @tirkarthi, @torfsen

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 2020-01-05.14:58:31.979>
labels = ['type-bug', '3.8', '3.9', '3.7', 'library', 'docs']
title = 'unittest.mock.Mock.parent is broken or undocumented'
updated_at = <Date 2020-01-15.12:00:36.437>
user = 'https://github.com/torfsen'

bugs.python.org fields:

activity = <Date 2020-01-15.12:00:36.437>
actor = 'mariocj89'
assignee = 'docs@python'
closed = False
closed_date = None
closer = None
components = ['Documentation', 'Library (Lib)']
creation = <Date 2020-01-05.14:58:31.979>
creator = 'florian.brucker'
dependencies = []
files = []
hgrepos = []
issue_num = 39222
keywords = []
message_count = 7.0
messages = ['359348', '359578', '359724', '359725', '359726', '359890', '360044']
nosy_count = 7.0
nosy_names = ['cjw296', 'michael.foord', 'docs@python', 'lisroach', 'mariocj89', 'xtreak', 'florian.brucker']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue39222'
versions = ['Python 3.7', 'Python 3.8', 'Python 3.9']

Linked PRs

@torfsen
Copy link
Mannequin Author

torfsen mannequin commented Jan 5, 2020

The "parent" attribute of unittest.mock.Mock is either broken or undocumented.

For example, on Python 3.7.4:

>>> from unittest.mock import Mock
>>> m = Mock(x=1, parent=2)
>>> m.x
1
>>> m.parent
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.7/unittest/mock.py", line 659, in __repr__
    name = self._extract_mock_name()
  File "/usr/local/lib/python3.7/unittest/mock.py", line 638, in _extract_mock_name
    _name_list.append(_parent._mock_new_name + dot)
AttributeError: 'int' object has no attribute '_mock_new_name'
>>> parent = Mock()
>>> child = Mock(parent=parent)
>>> child.parent is parent
False

I stumbled upon this while trying to mock an object that has a "parent" attribute.

From the documentation I understand that mocks have built-in parents. However, the documentation never mentions the "parent" attribute specifically, so I always assumed that the built-in parent-child relationship was handled using private or name-mangled attributes. And since the "parent" attribute is not mentioned in the docs, I assumed I could set it by passing an additional kwarg to Mock.

I would have expected one of the following, in order of personal preference:

a) That a private or name-mangled attribute is used for the built-in parent-child relationship, so that I can mock objects which themselves have a "parent" attribute

b) That the special meaning of the "parent" attribute is documented, and that trying to set it directly (via the constructor or via attribute assignment, and without going through attach_mock) triggers a warning.

@torfsen torfsen mannequin added the 3.7 (EOL) end of life label Jan 5, 2020
@torfsen torfsen mannequin assigned docspython Jan 5, 2020
@torfsen torfsen mannequin added docs Documentation in the Doc dir stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error 3.7 (EOL) end of life labels Jan 5, 2020
@torfsen torfsen mannequin assigned docspython Jan 5, 2020
@torfsen torfsen mannequin added docs Documentation in the Doc dir stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Jan 5, 2020
@tirkarthi
Copy link
Member

It's a similar situation to name argument conflict [0] except that it's parent here. You can use configure_mock or attribute setting to do the same thing like below. parent is discussed in the docs to indicate the attributes being children like "a" being the child of parent "m" as you have mentioned. Adding others for thoughts.

>>> from unittest.mock import Mock
>>> m = Mock()
>>> m.configure_mock(parent=2)
>>> m.parent
2
>>> m.a()
<Mock name='mock.a()' id='4367727104'>

>>> m = Mock()
>>> m.parent = 2
>>> m.parent
2

[0] https://docs.python.org/3/library/unittest.mock.html#mock-names-and-the-name-attribute

@tirkarthi tirkarthi added 3.8 only security fixes 3.9 only security fixes labels Jan 8, 2020
@mariocj89
Copy link
Mannequin

mariocj89 mannequin commented Jan 10, 2020

@cjw296 or @michael.foord might know why the attribute was exposed as plain "parent". It was added more than 8 years ago and I am unnable to follow the git commit history.

They should then decide whether this is intenteded to be used by the users (which I never have used on the init TBH) and therefore document it or whether it is a private name on the init and if in that case it would be worth trying to mangle it.

In the meantime, xtreak suggested workflow is probably the best to go.

@cjw296
Copy link
Contributor

cjw296 commented Jan 10, 2020

I thought we'd already changed this to _mock_parent in the last year or so?

@mariocj89
Copy link
Mannequin

mariocj89 mannequin commented Jan 10, 2020

If you refer to https://bugs.python.org/issue35357, this issue refers to parent at the time of creation of the mock. In the init it is still referenced as "parent".

The question is whether we want to also mangle "parent" in the __init__, as it seems it is not expected to be part of the API.

@cjw296
Copy link
Contributor

cjw296 commented Jan 13, 2020

Ah right. Well, it's called parent in the init as that's what the attribute used to be called.

My suggestion would be to add parent to the docs @XTreak links to as a way to resolve this issue.

@mariocj89
Copy link
Mannequin

mariocj89 mannequin commented Jan 15, 2020

My suggestion would be to add parent to the docs @XTreak links to as a way to resolve this issue.

+1, we should probably add it on the docs of the constructor here https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock as it is done for name and having a section like the on for name.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
sobolevn added a commit to sobolevn/cpython that referenced this issue Apr 19, 2023
@sobolevn
Copy link
Member

I've sent a PR with the test and doc fix. Please, share your feedback :)

@sobolevn sobolevn added 3.12 bugs and security fixes 3.11 only security fixes and removed 3.9 only security fixes 3.8 only security fixes 3.7 (EOL) end of life labels Apr 19, 2023
@hugovk
Copy link
Member

hugovk commented Jan 11, 2024

Thanks for the report and PR, let's close this now :)

@hugovk hugovk closed this as completed Jan 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.11 only security fixes 3.12 bugs and security fixes docs Documentation in the Doc dir stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
Status: Done
Development

No branches or pull requests

4 participants