• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from test.test_importlib import abc, util
2
3machinery = util.import_importlib('importlib.machinery')
4
5from test.support import captured_stdout, import_helper, STDLIB_DIR
6import contextlib
7import os.path
8import types
9import unittest
10import warnings
11
12
13@contextlib.contextmanager
14def deprecated():
15    with warnings.catch_warnings():
16        warnings.simplefilter('ignore', DeprecationWarning)
17        yield
18
19
20@contextlib.contextmanager
21def fresh(name, *, oldapi=False):
22    with util.uncache(name):
23        with import_helper.frozen_modules():
24            if oldapi:
25                with deprecated():
26                    yield
27            else:
28                yield
29
30
31def resolve_stdlib_file(name, ispkg=False):
32    assert name
33    if ispkg:
34        return os.path.join(STDLIB_DIR, *name.split('.'), '__init__.py')
35    else:
36        return os.path.join(STDLIB_DIR, *name.split('.')) + '.py'
37
38
39class ExecModuleTests(abc.LoaderTests):
40
41    def exec_module(self, name, origname=None):
42        with import_helper.frozen_modules():
43            is_package = self.machinery.FrozenImporter.is_package(name)
44        spec = self.machinery.ModuleSpec(
45            name,
46            self.machinery.FrozenImporter,
47            origin='frozen',
48            is_package=is_package,
49            loader_state=types.SimpleNamespace(
50                origname=origname or name,
51                filename=resolve_stdlib_file(origname or name, is_package),
52            ),
53        )
54        module = types.ModuleType(name)
55        module.__spec__ = spec
56        assert not hasattr(module, 'initialized')
57
58        with fresh(name):
59            self.machinery.FrozenImporter.exec_module(module)
60        with captured_stdout() as stdout:
61            module.main()
62
63        self.assertTrue(module.initialized)
64        self.assertTrue(hasattr(module, '__spec__'))
65        self.assertEqual(module.__spec__.origin, 'frozen')
66        return module, stdout.getvalue()
67
68    def test_module(self):
69        name = '__hello__'
70        module, output = self.exec_module(name)
71        check = {'__name__': name}
72        for attr, value in check.items():
73            self.assertEqual(getattr(module, attr), value)
74        self.assertEqual(output, 'Hello world!\n')
75        self.assertTrue(hasattr(module, '__spec__'))
76        self.assertEqual(module.__spec__.loader_state.origname, name)
77
78    def test_package(self):
79        name = '__phello__'
80        module, output = self.exec_module(name)
81        check = {'__name__': name}
82        for attr, value in check.items():
83            attr_value = getattr(module, attr)
84            self.assertEqual(attr_value, value,
85                        'for {name}.{attr}, {given!r} != {expected!r}'.format(
86                                 name=name, attr=attr, given=attr_value,
87                                 expected=value))
88        self.assertEqual(output, 'Hello world!\n')
89        self.assertEqual(module.__spec__.loader_state.origname, name)
90
91    def test_lacking_parent(self):
92        name = '__phello__.spam'
93        with util.uncache('__phello__'):
94            module, output = self.exec_module(name)
95        check = {'__name__': name}
96        for attr, value in check.items():
97            attr_value = getattr(module, attr)
98            self.assertEqual(attr_value, value,
99                    'for {name}.{attr}, {given} != {expected!r}'.format(
100                             name=name, attr=attr, given=attr_value,
101                             expected=value))
102        self.assertEqual(output, 'Hello world!\n')
103
104    def test_module_repr_indirect_through_spec(self):
105        name = '__hello__'
106        module, output = self.exec_module(name)
107        self.assertEqual(repr(module),
108                         "<module '__hello__' (frozen)>")
109
110    # No way to trigger an error in a frozen module.
111    test_state_after_failure = None
112
113    def test_unloadable(self):
114        with import_helper.frozen_modules():
115            assert self.machinery.FrozenImporter.find_spec('_not_real') is None
116        with self.assertRaises(ImportError) as cm:
117            self.exec_module('_not_real')
118        self.assertEqual(cm.exception.name, '_not_real')
119
120
121(Frozen_ExecModuleTests,
122 Source_ExecModuleTests
123 ) = util.test_both(ExecModuleTests, machinery=machinery)
124
125
126class InspectLoaderTests:
127
128    """Tests for the InspectLoader methods for FrozenImporter."""
129
130    def test_get_code(self):
131        # Make sure that the code object is good.
132        name = '__hello__'
133        with import_helper.frozen_modules():
134            code = self.machinery.FrozenImporter.get_code(name)
135            mod = types.ModuleType(name)
136            exec(code, mod.__dict__)
137        with captured_stdout() as stdout:
138            mod.main()
139        self.assertTrue(hasattr(mod, 'initialized'))
140        self.assertEqual(stdout.getvalue(), 'Hello world!\n')
141
142    def test_get_source(self):
143        # Should always return None.
144        with import_helper.frozen_modules():
145            result = self.machinery.FrozenImporter.get_source('__hello__')
146        self.assertIsNone(result)
147
148    def test_is_package(self):
149        # Should be able to tell what is a package.
150        test_for = (('__hello__', False), ('__phello__', True),
151                    ('__phello__.spam', False))
152        for name, is_package in test_for:
153            with import_helper.frozen_modules():
154                result = self.machinery.FrozenImporter.is_package(name)
155            self.assertEqual(bool(result), is_package)
156
157    def test_failure(self):
158        # Raise ImportError for modules that are not frozen.
159        for meth_name in ('get_code', 'get_source', 'is_package'):
160            method = getattr(self.machinery.FrozenImporter, meth_name)
161            with self.assertRaises(ImportError) as cm:
162                with import_helper.frozen_modules():
163                    method('importlib')
164            self.assertEqual(cm.exception.name, 'importlib')
165
166(Frozen_ILTests,
167 Source_ILTests
168 ) = util.test_both(InspectLoaderTests, machinery=machinery)
169
170
171if __name__ == '__main__':
172    unittest.main()
173