Ticket #77 (Closed: invalid)
Importer bug for modules starting with underscore
| Priority: | normal | Reporter: | constant.beta@gmail.com |
|---|---|---|---|
| Severity: | normal | Assigned to: | jpellerin |
| Component: | nose:importer | Status: | closed |
| Version: | 0.9.1 | Resolution: | invalid |
| Milestone: | Keywords: |
Description by constant.beta@gmail.com:
I will paste the session dump that presents the issue here. Files needed to reproduce this in attachement.
$ nosetests --verbose --include \(unit\)\|\(functional\)
No handlers could be found for logger "nose.plugins"
test_from_functional.TestFunctional.test_functional ... ok
ERROR
======================================================================
ERROR: test module test_from_unit in /tmp/blah/tests/unit
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python2.3/site-packages/nose-0.9.1.dev_r77-py2.3.egg/nose/suite.py", line 44, in run
self.setUp()
File "/usr/lib/python2.3/site-packages/nose-0.9.1.dev_r77-py2.3.egg/nose/suite.py", line 187, in setUp
self.module = _import(self.moduleName, [self.path], self.conf)
File "/usr/lib/python2.3/site-packages/nose-0.9.1.dev_r77-py2.3.egg/nose/importer.py", line 96, in _import
mod = load_module(fqname, fh, filename, desc)
File "/tmp/blah/tests/unit/test_from_unit.py", line 1, in ?
from _helper import fun1
ImportError: cannot import name fun1
----------------------------------------------------------------------
Ran 1 test in 0.006s
FAILED (errors=1)
$ nosetests --verbose --include unit
No handlers could be found for logger "nose.plugins"
test_from_unit.TestUnit.test_unit ... ok
----------------------------------------------------------------------
Ran 1 test in 0.004s
OK
$ nosetests --verbose --include functional
No handlers could be found for logger "nose.plugins"
test_from_functional.TestFunctional.test_functional ... ok
----------------------------------------------------------------------
Ran 1 test in 0.004s
OK
Attachments
Changelog
Fri Jul 21 11:54:19 2006: Modified by constant.beta@gmail.com
- attachment added: package.tar.gz
Thu Jul 27 10:48:54 2006: Modified by jpellerin
- resolution set to invalid
- status changed from new to closed
Thu Jul 27 10:50:16 2006: Modified by jpellerin
- attachment added: package.tar.2.gz
Fri Aug 4 10:16:32 2006: Modified by constant.beta@gmail.com
I still think this is a bug in nose. What the default Python behavior is doesn't matter - the fact is that tests are not fully separated from each other. My view on this is that running:
$ nosetests --verbose --include \(unit\)\|\(functional\)
should be equivalent to running:
$ nosetests --verbose --include unit $ nosetests --verbose --include functional
Nose should make sure that no single test from unit/ will affect a test from functional/, just like it should do that for each single test. Separation of unit tests is very important IMHO.
Fri Aug 4 10:20:32 2006: Modified by constant.beta@gmail.com
- resolution cleared
- status changed from closed to reopened
Oh, and renaming _helper.py to helper.py in both unit/ and functional/ directories doesn't cause nosetest to fail anymore. So, in some way it is certainly a bug, thus I'm reopening the ticket.
Fri Aug 4 22:29:34 2006: Modified by jpellerin
- resolution set to invalid
- status changed from reopened to closed
Nose runs all tests in a single python process, so running "include A and B" can never be the same as running "include A" and then "include B". This is not likely ever to change. It would be prohibitively slow to run each test in a separate interpreter, which is the only way to accomplish full automatic test isolation.
The issue you are seeing is normal python import behavior and is not related to the names of the modules. If foo.bar is imported as 'import bar' first (from within package foo) and then you later attempt to import baz.bar as 'import bar' (from within package baz), you will instead get foo.bar. The solution to this is to always use absolute imports, as in the example I posted.
I'm closing this ticket as invalid. If you want to reopen it, please email me first so we can discuss the issues. Thanks.

This isn't due to the underscores, but to the fact that the two _helper modules have the same name, so once one is loaded, sys.modules['_helper'] is pointing to the first, and the 2nd import of _helper won't cause a load of the local _helper.py. That's just normal python import behavior, unfortunately.
As a workaround, I'd suggest adding init.py files to each directory, from test on down, and using fully-qualified imports. This will also remove the need to use the --include switch, since nose descends into all packages by default.
A revised package is attached (or will be in a few minutes).
Closing as invalid.