mirror of
https://github.com/python/cpython.git
synced 2025-11-09 18:11:38 +00:00
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r74584 | brett.cannon | 2009-08-29 20:47:36 -0700 (Sat, 29 Aug 2009) | 3 lines Have importlib raise ImportError if None is found in sys.modules. This matches current import semantics. ........
86 lines
3.4 KiB
Python
86 lines
3.4 KiB
Python
"""Test that sys.modules is used properly by import."""
|
|
from .. import util
|
|
from . import util as import_util
|
|
import sys
|
|
from types import MethodType
|
|
import unittest
|
|
|
|
|
|
class UseCache(unittest.TestCase):
|
|
|
|
"""When it comes to sys.modules, import prefers it over anything else.
|
|
|
|
Once a name has been resolved, sys.modules is checked to see if it contains
|
|
the module desired. If so, then it is returned [use cache]. If it is not
|
|
found, then the proper steps are taken to perform the import, but
|
|
sys.modules is still used to return the imported module (e.g., not what a
|
|
loader returns) [from cache on return]. This also applies to imports of
|
|
things contained within a package and thus get assigned as an attribute
|
|
[from cache to attribute] or pulled in thanks to a fromlist import
|
|
[from cache for fromlist]. But if sys.modules contains None then
|
|
ImportError is raised [None in cache].
|
|
|
|
"""
|
|
def test_using_cache(self):
|
|
# [use cache]
|
|
module_to_use = "some module found!"
|
|
with util.uncache(module_to_use):
|
|
sys.modules['some_module'] = module_to_use
|
|
module = import_util.import_('some_module')
|
|
self.assertEqual(id(module_to_use), id(module))
|
|
|
|
def test_None_in_cache(self):
|
|
#[None in cache]
|
|
name = 'using_None'
|
|
with util.uncache(name):
|
|
sys.modules[name] = None
|
|
with self.assertRaises(ImportError):
|
|
import_util.import_(name)
|
|
|
|
def create_mock(self, *names, return_=None):
|
|
mock = util.mock_modules(*names)
|
|
original_load = mock.load_module
|
|
def load_module(self, fullname):
|
|
original_load(fullname)
|
|
return return_
|
|
mock.load_module = MethodType(load_module, mock)
|
|
return mock
|
|
|
|
# __import__ inconsistent between loaders and built-in import when it comes
|
|
# to when to use the module in sys.modules and when not to.
|
|
@import_util.importlib_only
|
|
def test_using_cache_after_loader(self):
|
|
# [from cache on return]
|
|
with self.create_mock('module') as mock:
|
|
with util.import_state(meta_path=[mock]):
|
|
module = import_util.import_('module')
|
|
self.assertEquals(id(module), id(sys.modules['module']))
|
|
|
|
# See test_using_cache_after_loader() for reasoning.
|
|
@import_util.importlib_only
|
|
def test_using_cache_for_assigning_to_attribute(self):
|
|
# [from cache to attribute]
|
|
with self.create_mock('pkg.__init__', 'pkg.module') as importer:
|
|
with util.import_state(meta_path=[importer]):
|
|
module = import_util.import_('pkg.module')
|
|
self.assertTrue(hasattr(module, 'module'))
|
|
self.assertTrue(id(module.module), id(sys.modules['pkg.module']))
|
|
|
|
# See test_using_cache_after_loader() for reasoning.
|
|
@import_util.importlib_only
|
|
def test_using_cache_for_fromlist(self):
|
|
# [from cache for fromlist]
|
|
with self.create_mock('pkg.__init__', 'pkg.module') as importer:
|
|
with util.import_state(meta_path=[importer]):
|
|
module = import_util.import_('pkg', fromlist=['module'])
|
|
self.assertTrue(hasattr(module, 'module'))
|
|
self.assertEquals(id(module.module),
|
|
id(sys.modules['pkg.module']))
|
|
|
|
|
|
def test_main():
|
|
from test.support import run_unittest
|
|
run_unittest(UseCache)
|
|
|
|
if __name__ == '__main__':
|
|
test_main()
|