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

Michael Foord michael at voidspace.org.uk
Fri Jul 29 09:42:15 PDT 2011


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).

Can you add this as a feature request:

     https://code.google.com/p/mock/issues/list

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 blessing http://www.sqlite.org/different.html

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


More information about the testing-in-python mailing list