derwiki-adroll / mock

Automatically exported from code.google.com/p/mock
BSD 2-Clause "Simplified" License
0 stars 0 forks source link

Incorrect call arguments list, arguments must be deepcopied. #140

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

Execute this code with version 0.8.0 python 2.7

from mock import patch

orig_dict = {'some': 'thing'}

class A(object):
    def method(self, a_dict):
        return a_dict

with patch.dict(orig_dict, clear=True) as mock_dict:
    with patch.object(A, 'method') as mock_method:
        a = A()

        a.method(orig_dict)

        orig_dict['thing'] = 'some'
        a.method(orig_dict)

        print mock_method.call_args_list

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

The list 'call_args_list' must be:
[call({}), call({'thing': 'some'})]

But it is actaully:
[call({'thing': 'some'}), call({'thing': 'some'})]

The arguments must be deep copied not just copy the reference.

What version of the product are you using? On what operating system?
Debian SID/Python2.7/Mock0.8.0

Original issue reported on code.google.com by jorgeeca...@gmail.com on 13 Mar 2012 at 5:12

GoogleCodeExporter commented 9 years ago
I just add a test for this, and the code that fix it, I imagine is hard to 
decide what to copy to not have strange results. What I did is copy the args 
and kwargs objects but only the members that are lists and dicts, a simple 
deepcopy wont work because of some objects that are checked for reference in 
the tests. If this can be avoided the deepcopy can be coded.

Original comment by jorgeeca...@gmail.com on 13 Mar 2012 at 7:01

GoogleCodeExporter commented 9 years ago
Here is the commit for the fix: 
https://code.google.com/r/jorgeecardona-copyargs/source/detail?r=9fc0174b7c51a85
c722bfd5ebed6688d0bb22547

Original comment by jorgeeca...@gmail.com on 13 Mar 2012 at 7:02

GoogleCodeExporter commented 9 years ago
This is by design. Deep copying is fragile. You can't deepcopy arbitrary 
objects, and it would also break identity based equality.

See this example from the docs for coping with mutable arguments (including a 
CopyingMock class you can just use):

http://www.voidspace.org.uk/python/mock/examples.html#coping-with-mutable-argume
nts

There's also an issue for potentially including CopyingMock in mock at some 
future point:

https://code.google.com/p/mock/issues/detail?id=127

Original comment by fuzzyman on 13 Mar 2012 at 7:08