[TIP] Issue with "mock" package and isinstance()

Tom Davis tom at recursivedream.com
Fri Jul 29 10:03:38 PDT 2011


On 07/29/2011 12:42 PM, Michael Foord wrote:
> On 29/07/2011 17:31, Tom Davis wrote:
>> Hey all,
>>
>> I've been using Michael Foord's awesome /mock/ package and I've loved 
>> it... now I'm running into an issue. I'm patching a class, pretty simple:
>>
>>     from my.module.path import Class
>>     patch = mock.patch('my.module.path.Class', spec=Class)
>>     mocked = patch.start()
>>     mocked.return_value = MyReplacementClass()
>>
>> I'm doing things this way because I need to mock out a class, but 
>> provide an alternate implementation that uses similar logic to the 
>> real class (basically mocking an external API by turning it into a 
>> memory-mapped API).
>>
>> Somewhere else, my code gets this mock client and a function calls:
>>
>>     isinstance(client, my.module.path.Class): ...
>>
>> This call fails with:
>>
>>     TypeError: isinstance() arg 2 must be a class, type, or tuple of
>>     classes and type
>>
>> This was confusing to me, so I did a bit of digging to figure out 
>> what /Class/ really was, but all was well. Here's what I got:
>>
>>     <MagicMock spec='Class' id='50389456'>
>>
>
> Well yes - what you have here is a mock *instance* - it isn't a class 
> it's a mock of a class. So you can't use this as the second argument 
> to isinstance. This is one of the problems with type checking (not 
> that it's always wrong - just that it causes this kind of difficulty).
>
> Actually it *would* be possible to make a mock object behave like a 
> class, by providing __bases__ = (type,) on mock instances (or whatever 
> the appropriate bases would be).
First off, thanks for the super fast reply! I'm trying to wrap up this 
project and the intricacies of the final patching stage are confusing me 
a bit. So if I understand this correctly, you're saying that 
isinstance() is actually calling (or otherwise obtaining what i set as 
"return_value") the mock? The result would make sense, then, though I 
thought it just checked its type? This is a bit above my meta-Python 
experience.
>
> Can you add this as a feature request:
>
> https://code.google.com/p/mock/issues/list
>
Provided I actually understand what it is (see above), I certainly will.

Thanks again!

-Tom
> All the best,
>
> Michael Foord
>>
>> Seems right to me! Additionally, if I change the instance check in 
>> the production code to:
>>
>>     isinstance(client, my.module.path.Class._spec_class): ...
>>
>> It works just fine! I can't do this for obvious reasons, but it seems 
>> to prove that the MagicMock at least has the correct information 
>> somewhere, it's just not being properly inspected by isinstance().
>>
>> Any thoughts? I really need this to work.
>>
>>
>> _______________________________________________
>> testing-in-python mailing list
>> testing-in-python at lists.idyll.org
>> http://lists.idyll.org/listinfo/testing-in-python
>
>
> -- 
> 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 blessinghttp://www.sqlite.org/different.html

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.idyll.org/pipermail/testing-in-python/attachments/20110729/e0282217/attachment.htm>


More information about the testing-in-python mailing list