<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<tt>This isn't trivial. It could be hacked together, but the hack
I'm thinking of will not work in the general case.</tt><tt><br>
<br>
</tt><tt>The module that defines a function has a reference to it,
and so does every module that imports it from the defining module:<br>
<br>
</tt><tt> defining.py:<br>
</tt><tt> def funcname():<br>
</tt><tt> pass<br>
<br>
</tt><tt> importing.py:<br>
</tt><tt> from defining import funcname<br>
<br>
<br>
'funcname' in the 'defining' module's namespace is a different
variable than 'funcname' in the 'importing' module's namespace,
even though they both point to the same function object. If you
want to mock out both variables, then you have to mock out both
variables separately.<br>
<br>
If you wanted to get clever, you could write some code to search
for all the modules in your project, and introspect them to find
all module-level variables that reference a particular function.
Then you could mock out each of them in turn. However, this is
likely to be a bit flaky.<br>
Any unusual cases, such as imports happening inside a function,
will not be found by this method, and so if it's critical that you
patch out ALL references to 'funcname' no matter where they occur,
this won't work in the general case. Perhaps you have enough
control over the codebase that you can manually ensure that none
of these corner cases actually arise in practice.<br>
<br>
Use 'inspect' to do the introspection. Use something a bit like:<br>
<br>
import inspect<br>
<br>
def get_functions(module):<br>
'''<br>
Return name:fn dict of all functions and lambdas defined
in 'module'<br>
'''<br>
return dict(<br>
inspect.getmembers(<br>
module,<br>
lambda item: inspect.isfunction(item)<br>
)<br>
)<br>
<br>
def get_modules(package):<br>
'''<br>
Return {name:module} dict of modules in the given package<br>
'''<br>
return dict(inspect.getmembers(package, inspect.ismodule))<br>
<br>
...plus some other part to find all the packages in the project.<br>
<br>
And use 'mock.patch' to do the patching out of the functions. It
is clever about restoring the original values correctly when
you're done.<br>
<br>
Overall, this sounds like more trouble than it's worth, but
perhaps you are cleverer or more persistent than I.<br>
<br>
Best regards,<br>
<br>
Jonathan<br>
<br>
<br>
</tt><tt>On 15/03/2012 19:45, Mathieu Drapeau wrote:</tt>
<blockquote
cite="mid:CAPar9tYyD=SY65L_g8sb+HTupn1=3OzmUgP_0C_pDuvccqk6Sw@mail.gmail.com"
type="cite"><tt>This is exactly what I wanted to highlight, is how
can I also mock functions that have been previously defined?<br>
I wanted to skim off the code but sometimes in libs, a function
can be namespaced or not... and I would like to trap every
possible uses of such function.<br>
<br>
Is it possible?
</tt><tt><br>
<br>
Thanks,<br>
Mathieu<br>
<br>
</tt>
<div class="gmail_quote"><tt>Le 15 mars 2012 15:37, Jonathan
Hartley <span dir="ltr"><<a moz-do-not-send="true"
href="mailto:tartley@tartley.com">tartley@tartley.com</a>></span>
a écrit :<br>
</tt>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000">
<div>
<div class="h5"><tt> On 15/03/2012 18:30, Mathieu Drapeau
wrote: </tt></div>
</div>
<blockquote type="cite">
<div>
<div class="h5"><tt>Hi all,<br>
I am fairly new to mock and I would like to know how
to fix an issue during module imports and scope of
functions.<br>
Here is a snippet that explain problem I am dealing
with:<br>
<br>
from mock import MagicMock </tt><tt><br>
import sys<br>
sys.func = lambda: 'x'<br>
from sys import func<br>
print func()<br>
# outputs 'x'<br>
sys.func = MagicMock(return_value='mocked_x')<br>
print func()<br>
# outputs 'x', it is not mocked<br>
<br>
How could I fix this? </tt><tt><br>
<br>
Thanks, </tt><tt><br>
Mat<br>
<br>
</tt>
<fieldset></fieldset>
<tt><br>
</tt> </div>
</div>
<tt>_______________________________________________
testing-in-python mailing list
<a moz-do-not-send="true"
href="mailto:testing-in-python@lists.idyll.org"
target="_blank">testing-in-python@lists.idyll.org</a>
<a moz-do-not-send="true"
href="http://lists.idyll.org/listinfo/testing-in-python"
target="_blank">http://lists.idyll.org/listinfo/testing-in-python</a>
</tt> </blockquote>
<tt><br>
Hey Mathieu,<br>
<br>
Your 7th line changes the value of sys.func (the 'func'
attribute on local variable 'sys') but you haven't changed
the value of local variable 'func'. Modifying one won't
affect the other. You'd see the same behaviour even if
MagicMock wasn't involved (e.g assigning 'sys.func' to 0
will not affect the value of 'func' either.) </tt><tt><br>
<br>
From the code you've posted, it's not clear to me what
you're trying to achieve. </tt><tt><br>
<br>
Perhaps you meant to write: </tt><tt><br>
<br>
>>> func = Mock(return_value='mocked') </tt><tt><br>
>>> func()<br>
mocked<br>
<br>
or </tt><tt><br>
<br>
>>> sys.func = Mock(return_value='mocked') </tt><tt><br>
>>> sys.func()<br>
mocked<br>
<br>
Best regards, </tt><tt><br>
<br>
</tt><tt> Jonathan<span class="HOEnZb"><font
color="#888888"><br>
<br>
<pre cols="72">--
Jonathan Hartley <a moz-do-not-send="true" href="mailto:tartley@tartley.com" target="_blank">tartley@tartley.com</a> <a moz-do-not-send="true" href="http://tartley.com" target="_blank">http://tartley.com</a>
Made of meat. <a moz-do-not-send="true" href="tel:%2B44%207737%20062%20225" value="+447737062225" target="_blank">+44 7737 062 225</a> twitter/skype: tartley
</pre>
</font></span></tt></div>
</blockquote>
</div>
<tt><br>
</tt>
</blockquote>
<tt><br>
<br>
<br>
</tt><tt>-- Jonathan Hartley <a class="moz-txt-link-abbreviated" href="mailto:tartley@tartley.com">tartley@tartley.com</a> <a class="moz-txt-link-freetext" href="http://tartley.com">http://tartley.com</a>
Made of meat. +44 7737 062 225 twitter/skype: tartley
</tt>
</body>
</html>