This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author xtreak
Recipients cjw296, michael.foord, xtreak
Date 2018-11-13.09:53:22
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1542102802.7.0.788709270274.issue35226@psf.upfronthosting.co.za>
In-reply-to
Content
I think this is due to the fact that when an attribute of a call object is accessed a new call object is returned with the parent as self.parent [0] but the original information regarding the parent is lost during representation and no check for self.parent equality while the call objects are compared [1]

./python.exe
Python 3.8.0a0 (heads/master:0dc1e45dfd, Nov 13 2018, 11:19:49)
[Clang 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from unittest.mock import call
>>> call(x=2).foo
call().foo
>>> call(x=1).foo
call().foo
>>> # Comparison returns true since it's similar to call().foo == call().foo though parents are set
>>> call(x=1).foo == call(x=2).foo
True
>>> call(x=1).foo.parent
call(x=1)
>>> call(x=2).foo.parent
call(x=2)
>>> call(x=2).foo(x=2).bar
call().foo().bar
>>> call(x=4).foo(x=3).bar
call().foo().bar
>>> # Comparison returns true since it's similar to call().foo().bar == call().foo().bar
>>> call(x=2).foo(x=2).bar == call(x=4).foo(x=3).bar 
True
>>> call(x=4).foo(x=3).bar.parent
call().foo(x=3)

Maybe we can add a check for parent to be equal if present? 

diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index a9c82dcb5d..a7565d5f60 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -2054,6 +2054,10 @@ class _Call(tuple):
         else:
             self_name, self_args, self_kwargs = self

+        if (getattr(self, 'parent', None) and getattr(other, 'parent', None)
+            and self.parent != other.parent):
+            return False
+
         other_name = ''
         if len_other == 0:
             other_args, other_kwargs = (), {}

With patch the checks return False and there is no test suite failure but I am not sure if I need to put this inside a while loop to check for nested parents and there maybe other cases that my code doesn't handle.

➜  cpython git:(master) ✗ ./python.exe -c 'from unittest.mock import call; print(call(x=2).foo.bar == call(x=1).foo.bar)'
False
➜  cpython git:(master) ✗ ./python.exe -c 'from unittest.mock import call; print(call(x=2).foo == call(x=1).foo)'
False


[0] https://github.com/python/cpython/blob/0d12672b30b8c6c992bef7564581117ae83e11ad/Lib/unittest/mock.py#L2109
[1] https://github.com/python/cpython/blob/0d12672b30b8c6c992bef7564581117ae83e11ad/Lib/unittest/mock.py#L2043
History
Date User Action Args
2018-11-13 09:53:22xtreaksetrecipients: + xtreak, cjw296, michael.foord
2018-11-13 09:53:22xtreaksetmessageid: <1542102802.7.0.788709270274.issue35226@psf.upfronthosting.co.za>
2018-11-13 09:53:22xtreaklinkissue35226 messages
2018-11-13 09:53:22xtreakcreate