classification
Title: mock could be smarter and inspect the spec's signature
Type: enhancement Stage: committed/rejected
Components: Library (Lib) Versions: Python 3.4
process
Status: closed Resolution: fixed
Dependencies: 17071 Superseder:
Assigned To: Nosy List: eric.araujo, ezio.melotti, michael.foord, pitrou, python-dev
Priority: normal Keywords: patch

Created on 2013-01-22 12:44 by pitrou, last changed 2013-02-02 23:29 by pitrou. This issue is now closed.

Files
File name Uploaded Description Edit
issue17015.patch pitrou, 2013-01-28 22:28 review
issue17015-3.patch pitrou, 2013-01-29 20:27 review
Messages (9)
msg180381 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-01-22 12:44
This is a bit annoying:

>>> def f(a, b): pass
... 
>>> mock = Mock(spec=f)
>>> mock(1, 2)
<Mock name='mock()' id='140654219634288'>
>>> mock.assert_called_with(1, 2)
>>> mock.assert_called_with(a=1, b=2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/antoine/cpython/default/Lib/unittest/mock.py", line 726, in assert_called_with
    raise AssertionError(msg)
AssertionError: Expected call: mock(b=2, a=1)
Actual call: mock(1, 2)

This means your test assertions will depend unduly on some code style details (whether some function is called using positional or keyword arguments).
Note: if this is fixed, it should be made to work with method calls too.
msg180382 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-01-22 12:45
(note: also fails if I use `mock = Mock(wraps=f)` instead of `mock = Mock(spec=f)`)
msg180886 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-01-28 22:28
Proof-of-concept patch. mock is ugly!
msg180945 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-01-29 20:27
Here is a new patch, making all assert_*_call methods work as well as autospeccing, and adding tests. Not sure I'm forgetting something else.
msg180976 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2013-01-30 17:49
Wow, impressive work Antoine - thanks. I am a little concerned that this relies on Python 3 only features of inspect, and *in fact* relies on bug fixes in Python 3.4 to work. That means it would be hard / impossible for the backport "mock" to have the new feature. That may be solveable (there is a backport of function signatures which mock could use for example).
msg180981 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-01-30 18:13
> I am a little concerned that this relies on Python 3 only features of
> inspect, and *in fact* relies on bug fixes in Python 3.4 to work.

The bug fix has landed in 3.3 as well ;-)
(see 49fd1c8aeca5)
I guess a backport of inspect.signature() would allow it to work on previous Pythons, too.
msg180982 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2013-01-30 18:15
Ah, well if the bugfix exists everywhere that function signatures exist then it shouldn't be a problem. (I think there is already a backport of inspect.signature() by Nick Coghlan.)
msg181229 - (view) Author: Roundup Robot (python-dev) Date: 2013-02-02 23:28
New changeset b888c9043566 by Antoine Pitrou in branch 'default':
Issue #17015: When it has a spec, a Mock object now inspects its signature when matching calls, so that arguments can be matched positionally or by name.
http://hg.python.org/cpython/rev/b888c9043566
msg181230 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-02-02 23:29
Committed!
History
Date User Action Args
2013-02-02 23:29:01pitrousetstatus: open -> closed
resolution: fixed
messages: + msg181230

stage: committed/rejected
2013-02-02 23:28:26python-devsetnosy: + python-dev
messages: + msg181229
2013-01-30 18:15:49michael.foordsetmessages: + msg180982
2013-01-30 18:13:36pitrousetmessages: + msg180981
2013-01-30 17:49:14michael.foordsetmessages: + msg180976
2013-01-29 20:27:21pitrousetfiles: + issue17015-3.patch

messages: + msg180945
2013-01-29 13:10:35pitrousetdependencies: + Signature.bind() fails with a keyword argument named "self"
2013-01-28 22:28:52pitrousetfiles: + issue17015.patch
keywords: + patch
messages: + msg180886
2013-01-26 00:04:07eric.araujosetnosy: + eric.araujo
2013-01-22 12:55:36ezio.melottisetnosy: + ezio.melotti
2013-01-22 12:45:19pitrousetmessages: + msg180382
2013-01-22 12:44:11pitroucreate