Fri Jul 21 11:52:39 2006

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

  • package.tar.gz (409 bytes) - Package that causes nose importer error., added by constant.beta@gmail.com on Fri Jul 21 11:54:19 2006.
  • package.tar.2.gz (1 kB) - Revised package with init.py files and absolute imports that fixes the import issue, added by jpellerin on Thu Jul 27 10:50:16 2006.

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

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.

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.