Reputation: 2195
I observe a strange behaviour with Python 3 unittest. Following Testcase tests in function testValue
a module that does not exist.
import sys
import unittest
class ModuleTest(unittest.TestCase):
def testValue(self):
import unknown_module
result = unknown_module.value
self.assertEqual(0.0, result)
if __name__ == "__main__":
print(sys.version)
unittest.main()
Python2 gives correctly following output:
2.7.5 (default, May 15 2013, 22:44:16) [MSC v.1500 64 bit (AMD64)]
E
======================================================================
ERROR: testValue (__main__.ModuleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\bin\WinPython-64bit-2.7.5.1\workspace\unknown_module_test.py", line 7, in testValue
import unknown_module
ImportError: No module named unknown_module
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
But Python 3 claims an AttributeError when the unknown_module.value
is referenced.
3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (Intel)]
E
======================================================================
ERROR: testValue (__main__.ModuleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "unknown_module_test.py", line 8, in testValue
result = unknown_module.value
AttributeError: 'module' object has no attribute 'value'
----------------------------------------------------------------------
Ran 1 test in 0.016s
FAILED (errors=1)
Why doesn't throw Python 3 an ImportError
as Python 2 does?
Upvotes: 1
Views: 1629
Reputation: 1124798
You are importing an implicit namespace package. Quoting from the Python 3.3 What's New page:
Native support for package directories that don’t require __init__.py marker files and can automatically span multiple path segments (inspired by various third party approaches to namespace packages, as described in PEP 420)
and PEP 420 Implicit Namespace Packages:
If the scan completes without returning a module or package, and at least one directory was recorded, then a namespace package is created. The new namespace package:
- Has a
__path__
attribute set to an iterable of the path strings that were found and recorded during the scan.- Does not have a
__file__
attribute.
and
Namespace packages and regular packages are very similar. The differences are:
- Portions of namespace packages need not all come from the same directory structure, or even from the same loader. Regular packages are self-contained: all parts live in the same directory hierarchy.
- Namespace packages have no
__file__
attribute.- Namespace packages'
__path__
attribute is a read-only iterable of strings, which is automatically updated when the parent path is modified.- Namespace packages have no
__init__.py
module.- Namespace packages have a different type of object for their
__loader__
attribute.
Remove the unknown_module
directory from your sys.path
and your test will fail the way it did in earlier Python versions.
Upvotes: 3