简体   繁体   中英

Testing not known module in unittest with Python 3

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM