[TIP] weirdity with identity of Mock

Michael Foord michael at voidspace.org.uk
Thu Jan 26 05:01:31 PST 2012


On 25/01/2012 21:59, Michael Foord wrote:
> On 25/01/2012 19:56, Chris Withers wrote:
>> So, this won't come as much surprise:
>>
>> >> class MyClass(object): pass
>> ...
>> >>> obj1 = MyClass()
>> >>> obj2 = MyClass()
>> >>> obj1 == obj2
>> False
>> >>> type(obj1) is type(obj2)
>> True
>>
>> ...but this certainly surprised me:
>>
>> >>> from mock import Mock
>> >>> obj1 = Mock()
>> >>> obj2 = Mock()
>> >>> type(obj1) is type(obj2)
>> False
>>
>> Wuh?
>>
>> >>> Mock is Mock
>> True
>>
>> Mmmmkay...
>>
>> *backs away slightly scared*
>
> Best not to look too closely at how the sausage is made. ;-)
>
> It's part of the magic that allows you to attach a magic method to one 
> mock (and magic methods are looked up on the class remember) without 
> it affecting other mocks... Look inside __new__ for the gory details.
>
Specifically, this is what it enables you to do:

 >>> from mock import Mock
 >>> class Foo(object): pass
...
 >>> foo1 = Foo()
 >>> foo2 = Foo()
 >>> def __int__(self):
...     return 3
...
 >>> int(foo1)
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: int() argument must be a string or a number, not 'Foo'
 >>> foo1.__int__ = __int__
 >>> int(foo1)
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: int() argument must be a string or a number, not 'Foo'
 >>> Foo.__int__ = __int__
 >>> int(foo1)
3
 >>> int(foo2)
3
 >>> m1 = Mock()
 >>> m2 = Mock()
 >>> int(m1)
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: int() argument must be a string or a number, not 'Mock'
 >>> m1.__int__ = __int__
 >>> int(m1)
3
 >>> int(m2)
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: int() argument must be a string or a number, not 'Mock'

To make int(x) work you *normally* have to attach an __int__ method to 
type(x) - which affects all instances. You can't attach magic methods to 
instances (barring a few bugs in Python itself - mostly all fixed in 
Python 2.7).

With Mock you can attach the magic method to the instance. Under the 
hood each Mock instance has their own type and the magic method is 
promoted to the type - without affecting any other mock object.

All the best,

Michael

> Michael
>
>
>
>>
>> Chris
>>
>
>


-- 
http://www.voidspace.org.uk/

May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing http://www.sqlite.org/different.html




More information about the testing-in-python mailing list