classification
Title: mock: Crash on comparing call_args with long strings
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.6, Python 3.4, Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Wilfred.Hughes, akaptur, berker.peksag, michael.foord, python-dev, r.david.murray
Priority: normal Keywords: easy, patch

Created on 2015-08-13 08:34 by Wilfred.Hughes, last changed 2015-09-09 20:45 by berker.peksag. This issue is now closed.

Files
File name Uploaded Description Edit
issue24857.patch akaptur, 2015-09-04 04:38 review
Messages (11)
msg248504 - (view) Author: Wilfred Hughes (Wilfred.Hughes) * Date: 2015-08-13 08:34
What steps will reproduce the problem?

>>> from mock import Mock
>>> m = Mock()
>>> m(1, 2)
<Mock name='mock()' id='139781492681104'>
>>> m.call_args == "foob"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/wilfred/.py_envs/trifle/lib/python2.7/site-packages/mock.py", line 2061, in __eq__
    first, second = other
ValueError: too many values to unpack

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

Expected False, got an error instead.

(Migrated from https://github.com/testing-cabal/mock/issues/232 )
msg248508 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2015-08-13 09:07
call_args is not user settable! It is set for you by the mock when it is called. Arguably it could be a property instead.
msg248509 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2015-08-13 09:08
Oops, I misunderstood the bug report - however, call_args is a tuple, so you can't compare it directly to a string like that. Please refer to the docs on using call_args.
msg248510 - (view) Author: Wilfred Hughes (Wilfred.Hughes) * Date: 2015-08-13 09:13
This caught me by surprise and I spent a while debugging due to this issue. Isn't it reasonable that I can compare two values in Python without exceptions being raised?

>>> (1, 2) == "foob"
False

I'm happy to write a patch.
msg248511 - (view) Author: Wilfred Hughes (Wilfred.Hughes) * Date: 2015-08-13 09:15
This bug is particularly subtle because it only applies to *long* strings.

>>> m.call_args == "f"
False
>>> m.call_args == "fo"
False
>>> m.call_args == "foo"
False
>>> m.call_args == "foob"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "build/bdist.linux-x86_64/egg/mock.py", line 2061, in __eq__
ValueError: too many values to unpack
msg248512 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2015-08-13 09:28
Ok, fair enough.
msg248517 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-08-13 12:09
Yeah, if it isn't comparable it should return either False or NotImplemented, not raise an exception.  False would be better here, I think.
msg249709 - (view) Author: A Kaptur (akaptur) * (Python triager) Date: 2015-09-04 04:24
It looks like there's a related bug in call_args around __ne__:

>>> m = Mock()
>>> m(1,2)
<Mock name='mock()' id='4483976016'>
>>> m.call_args
call(1, 2)
>>> m.call_args == call(1,2)
True
>>> m.call_args != call(1,2)
True

Any reason not to define __ne__ as not __eq__? Otherwise it looks like you fall back to tuple.__ne__, which does the wrong thing here.
msg249710 - (view) Author: A Kaptur (akaptur) * (Python triager) Date: 2015-09-04 04:38
Here's a simple patch + test for the original bug. I'll file the __ne__ question separately.
msg250333 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2015-09-09 20:40
New changeset 83ea55a1204a by Berker Peksag in branch '3.4':
Issue #24857: Comparing call_args to a long sequence now correctly returns a
https://hg.python.org/cpython/rev/83ea55a1204a

New changeset df91c1879e56 by Berker Peksag in branch '3.5':
Issue #24857: Comparing call_args to a long sequence now correctly returns a
https://hg.python.org/cpython/rev/df91c1879e56

New changeset 6853b4bc0b22 by Berker Peksag in branch 'default':
Issue #24857: Comparing call_args to a long sequence now correctly returns a
https://hg.python.org/cpython/rev/6853b4bc0b22
msg250334 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2015-09-09 20:45
Thanks!

For the record, the __ne__ issue created by A Kaptur is issue 24997.
History
Date User Action Args
2015-09-09 20:45:21berker.peksagsetstatus: open -> closed

nosy: + berker.peksag
messages: + msg250334

resolution: fixed
stage: patch review -> resolved
2015-09-09 20:40:42python-devsetnosy: + python-dev
messages: + msg250333
2015-09-04 04:38:32akaptursetfiles: + issue24857.patch
keywords: + patch
messages: + msg249710

stage: needs patch -> patch review
2015-09-04 04:24:09akaptursetnosy: + akaptur
messages: + msg249709
2015-08-13 12:09:03r.david.murraysetkeywords: + easy
nosy: + r.david.murray
messages: + msg248517

2015-08-13 09:28:42michael.foordsetstatus: closed -> open
resolution: not a bug -> (no value)
messages: + msg248512
2015-08-13 09:15:44Wilfred.Hughessetmessages: + msg248511
2015-08-13 09:13:16Wilfred.Hughessetmessages: + msg248510
2015-08-13 09:09:34Wilfred.Hughessettitle: Crash on comparing call_args with long strings -> mock: Crash on comparing call_args with long strings
2015-08-13 09:08:10michael.foordsetmessages: + msg248509
2015-08-13 09:07:12michael.foordsetstatus: open -> closed
resolution: not a bug
messages: + msg248508
2015-08-13 08:50:22serhiy.storchakasetnosy: + michael.foord
stage: needs patch
type: crash -> behavior

versions: + Python 3.4, Python 3.5, Python 3.6
2015-08-13 08:34:40Wilfred.Hughescreate