8 @contextlib.contextmanager
10 """Uncache a module from sys.modules.
12 A basic sanity check is performed to prevent uncaching modules that either
13 cannot/shouldn't be uncached.
17 if name
in ('sys', 'marshal', 'imp'):
19 "cannot uncache {0} as it will break _importlib".format(name
))
34 @contextlib.contextmanager
35 def import_state(**kwargs
):
36 """Context manager to manage the various importers and stored state in the
39 The 'modules' attribute is not supported as the interpreter state stores a
40 pointer to the dict that the interpreter uses internally;
41 reassigning to sys.modules does not have the desired effect.
46 for attr
, default
in (('meta_path', []), ('path', []),
48 ('path_importer_cache', {})):
49 originals
[attr
] = getattr(sys
, attr
)
51 new_value
= kwargs
[attr
]
55 setattr(sys
, attr
, new_value
)
58 'unrecognized arguments: {0}'.format(kwargs
.keys()))
61 for attr
, value
in originals
.items():
62 setattr(sys
, attr
, value
)
65 class mock_modules(object):
67 """A mock importer/loader."""
69 def __init__(self
, *names
):
72 if not name
.endswith('.__init__'):
75 import_name
= name
[:-len('.__init__')]
78 elif import_name
== name
:
79 package
= name
.rsplit('.', 1)[0]
82 module
= imp
.new_module(import_name
)
83 module
.__loader
__ = self
84 module
.__file
__ = '<mock __file__>'
85 module
.__package
__ = package
87 if import_name
!= name
:
88 module
.__path
__ = ['<mock __path__>']
89 self
.modules
[import_name
] = module
91 def __getitem__(self
, name
):
92 return self
.modules
[name
]
94 def find_module(self
, fullname
, path
=None):
95 if fullname
not in self
.modules
:
100 def load_module(self
, fullname
):
101 if fullname
not in self
.modules
:
104 sys
.modules
[fullname
] = self
.modules
[fullname
]
105 return self
.modules
[fullname
]
108 self
._uncache
= uncache(*self
.modules
.keys())
109 self
._uncache
.__enter
__()
112 def __exit__(self
, *exc_info
):
113 self
._uncache
.__exit
__(None, None, None)
117 class ImportModuleTests(unittest
.TestCase
):
119 """Test importlib.import_module."""
121 def test_module_import(self
):
122 # Test importing a top-level module.
123 with
mock_modules('top_level') as mock
:
124 with
import_state(meta_path
=[mock
]):
125 module
= importlib
.import_module('top_level')
126 self
.assertEqual(module
.__name
__, 'top_level')
128 def test_absolute_package_import(self
):
129 # Test importing a module from a package with an absolute name.
131 pkg_long_name
= '{0}.__init__'.format(pkg_name
)
132 name
= '{0}.mod'.format(pkg_name
)
133 with
mock_modules(pkg_long_name
, name
) as mock
:
134 with
import_state(meta_path
=[mock
]):
135 module
= importlib
.import_module(name
)
136 self
.assertEqual(module
.__name
__, name
)
138 def test_shallow_relative_package_import(self
):
139 modules
= ['a.__init__', 'a.b.__init__', 'a.b.c.__init__', 'a.b.c.d']
140 with
mock_modules(*modules
) as mock
:
141 with
import_state(meta_path
=[mock
]):
142 module
= importlib
.import_module('.d', 'a.b.c')
143 self
.assertEqual(module
.__name
__, 'a.b.c.d')
145 def test_deep_relative_package_import(self
):
146 # Test importing a module from a package through a relatve import.
147 modules
= ['a.__init__', 'a.b.__init__', 'a.c']
148 with
mock_modules(*modules
) as mock
:
149 with
import_state(meta_path
=[mock
]):
150 module
= importlib
.import_module('..c', 'a.b')
151 self
.assertEqual(module
.__name
__, 'a.c')
153 def test_absolute_import_with_package(self
):
154 # Test importing a module from a package with an absolute name with
155 # the 'package' argument given.
157 pkg_long_name
= '{0}.__init__'.format(pkg_name
)
158 name
= '{0}.mod'.format(pkg_name
)
159 with
mock_modules(pkg_long_name
, name
) as mock
:
160 with
import_state(meta_path
=[mock
]):
161 module
= importlib
.import_module(name
, pkg_name
)
162 self
.assertEqual(module
.__name
__, name
)
164 def test_relative_import_wo_package(self
):
165 # Relative imports cannot happen without the 'package' argument being
167 self
.assertRaises(TypeError, importlib
.import_module
, '.support')
171 from test
.test_support
import run_unittest
172 run_unittest(ImportModuleTests
)
175 if __name__
== '__main__':