Note that there are some explanatory texts on larger screens.

plurals
  1. POMocking ImportError in Python
    primarykey
    data
    text
    <p>I'm trying this for almost two hours now, without any luck.</p> <p>I have a module that looks like this:</p> <pre><code>try: from zope.component import queryUtility # and things like this except ImportError: # do some fallback operations &lt;-- how to test this? </code></pre> <p>Later in the code:</p> <pre><code>try: queryUtility(foo) except NameError: # do some fallback actions &lt;-- this one is easy with mocking # zope.component.queryUtility to raise a NameError </code></pre> <p>Any ideas?</p> <p><strong>EDIT:</strong></p> <p>Alex's suggestion doesn't seem to work:</p> <pre><code>&gt;&gt;&gt; import __builtin__ &gt;&gt;&gt; realimport = __builtin__.__import__ &gt;&gt;&gt; def fakeimport(name, *args, **kw): ... if name == 'zope.component': ... raise ImportError ... realimport(name, *args, **kw) ... &gt;&gt;&gt; __builtin__.__import__ = fakeimport </code></pre> <p>When running the tests:</p> <pre><code>aatiis@aiur ~/work/ao.shorturl $ ./bin/test --coverage . Running zope.testing.testrunner.layer.UnitTests tests: Set up zope.testing.testrunner.layer.UnitTests in 0.000 seconds. Error in test /home/aatiis/work/ao.shorturl/src/ao/shorturl/shorturl.txt Traceback (most recent call last): File "/usr/lib64/python2.5/unittest.py", line 260, in run testMethod() File "/usr/lib64/python2.5/doctest.py", line 2123, in runTest test, out=new.write, clear_globs=False) File "/usr/lib64/python2.5/doctest.py", line 1361, in run return self.__run(test, compileflags, out) File "/usr/lib64/python2.5/doctest.py", line 1282, in __run exc_info) File "/usr/lib64/python2.5/doctest.py", line 1148, in report_unexpected_exception 'Exception raised:\n' + _indent(_exception_traceback(exc_info))) File "/usr/lib64/python2.5/doctest.py", line 1163, in _failure_header out.append(_indent(source)) File "/usr/lib64/python2.5/doctest.py", line 224, in _indent return re.sub('(?m)^(?!$)', indent*' ', s) File "/usr/lib64/python2.5/re.py", line 150, in sub return _compile(pattern, 0).sub(repl, string, count) File "/usr/lib64/python2.5/re.py", line 239, in _compile p = sre_compile.compile(pattern, flags) File "/usr/lib64/python2.5/sre_compile.py", line 507, in compile p = sre_parse.parse(p, flags) AttributeError: 'NoneType' object has no attribute 'parse' Error in test BaseShortUrlHandler (ao.shorturl) Traceback (most recent call last): File "/usr/lib64/python2.5/unittest.py", line 260, in run testMethod() File "/usr/lib64/python2.5/doctest.py", line 2123, in runTest test, out=new.write, clear_globs=False) File "/usr/lib64/python2.5/doctest.py", line 1351, in run self.debugger = _OutputRedirectingPdb(save_stdout) File "/usr/lib64/python2.5/doctest.py", line 324, in __init__ pdb.Pdb.__init__(self, stdout=out) File "/usr/lib64/python2.5/pdb.py", line 57, in __init__ cmd.Cmd.__init__(self, completekey, stdin, stdout) File "/usr/lib64/python2.5/cmd.py", line 90, in __init__ import sys File "&lt;doctest shorturl.txt[10]&gt;", line 4, in fakeimport NameError: global name 'realimport' is not defined </code></pre> <p>However, it <strong>does</strong> work when I run the same code from the python interactive console.</p> <p><strong>MORE EDIT:</strong></p> <p>I'm using <code>zope.testing</code> and a test file, <code>shorturl.txt</code> that has all the tests specific to this part of my module. First I'm importing the module with <code>zope.component</code> available, to demonstrate &amp; test the usual usage. The absence of <code>zope.*</code> packages is considered an edge-case, so I'm testing it later. Thus, I have to <code>reload()</code> my module, after making <code>zope.*</code> unavailable, somehow.</p> <p>So far I've even tried using <code>tempfile.mktempdir()</code> and empty <code>zope/__init__.py</code> and <code>zope/component/__init__.py</code> files in the tempdir, then inserting tempdir to <code>sys.path[0]</code>, and removing the old <code>zope.*</code> packages from <code>sys.modules</code>.</p> <p>Didn't work either.</p> <p><strong>EVEN MORE EDIT:</strong></p> <p>In the meantime, I've tried this:</p> <pre><code>&gt;&gt;&gt; class NoZope(object): ... def find_module(self, fullname, path): ... if fullname.startswith('zope'): ... raise ImportError ... &gt;&gt;&gt; import sys &gt;&gt;&gt; sys.path.insert(0, NoZope()) </code></pre> <p>And it works well for the namespace of the test suite (= for all imports in <code>shorturl.txt</code>), but it is not executed in my main module, <code>ao.shorturl</code>. Not even when I <code>reload()</code> it. Any idea why?</p> <pre><code>&gt;&gt;&gt; import zope # ok, this raises an ImportError &gt;&gt;&gt; reload(ao.shorturl) &lt;module ...&gt; </code></pre> <p>Importing <code>zope.interfaces</code> raises an <code>ImportError</code>, so it doesn't get to the part where I import <code>zope.component</code>, and <strong>it remains in the ao.shorturl namespace</strong>. Why?!</p> <pre><code>&gt;&gt;&gt; ao.shorturl.zope.component # why?! &lt;module ...&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload