Example #1
0
    def test_frozentable(self):
        # Python exports a PyImport_FrozenModules symbol. This is a
        # pointer to an array of struct _frozen entries.  The end of the
        # array is marked by an entry containing a NULL name and zero
        # size.

        # In standard Python, this table contains a __hello__
        # module, and a __phello__ package containing a spam
        # module.
        class struct_frozen(Structure):
            _fields_ = [
                ("name", c_char_p),
                ("code", POINTER(c_ubyte)),
                ("size", c_int),
                ("is_package", c_bool),
                ("get_code", POINTER(c_ubyte)),  # Function ptr
            ]

        FrozenTable = POINTER(struct_frozen)

        modules = []
        for group in ["Bootstrap", "Stdlib", "Test"]:
            ft = FrozenTable.in_dll(pythonapi, f"_PyImport_Frozen{group}")
            # ft is a pointer to the struct_frozen entries:
            for entry in ft:
                # This is dangerous. We *can* iterate over a pointer, but
                # the loop will not terminate (maybe with an access
                # violation;-) because the pointer instance has no size.
                if entry.name is None:
                    break
                modname = entry.name.decode("ascii")
                modules.append(modname)
                with self.subTest(modname):
                    if entry.size != 0:
                        # Do a sanity check on entry.size and entry.code.
                        self.assertGreater(abs(entry.size), 10)
                        self.assertTrue(
                            [entry.code[i] for i in range(abs(entry.size))])
                    # Check the module's package-ness.
                    with import_helper.frozen_modules():
                        spec = importlib.util.find_spec(modname)
                    if entry.is_package:
                        # It's a package.
                        self.assertIsNotNone(spec.submodule_search_locations)
                    else:
                        self.assertIsNone(spec.submodule_search_locations)

        with import_helper.frozen_modules():
            expected = _imp._frozen_module_names()
        self.maxDiff = None
        self.assertEqual(
            modules, expected, "_PyImport_FrozenBootstrap example "
            "in Doc/library/ctypes.rst may be out of date")

        from ctypes import _pointer_type_cache
        del _pointer_type_cache[struct_frozen]
Example #2
0
 def test_frozen_submodule_in_unfrozen_package(self):
     with import_helper.CleanImport('__phello__', '__phello__.spam'):
         with import_helper.frozen_modules(enabled=False):
             import __phello__
         with import_helper.frozen_modules(enabled=True):
             import __phello__.spam as spam
     self.assertIs(spam, __phello__.spam)
     self.assertIsNot(__phello__.__spec__.loader,
                      importlib.machinery.FrozenImporter)
     self.assertIs(spam.__spec__.loader, importlib.machinery.FrozenImporter)
Example #3
0
    def exec_module(self, name, origname=None):
        with import_helper.frozen_modules():
            is_package = self.machinery.FrozenImporter.is_package(name)
        spec = self.machinery.ModuleSpec(
            name,
            self.machinery.FrozenImporter,
            origin='frozen',
            is_package=is_package,
            loader_state=types.SimpleNamespace(
                origname=origname or name,
                filename=resolve_stdlib_file(origname or name, is_package),
            ),
        )
        module = types.ModuleType(name)
        module.__spec__ = spec
        assert not hasattr(module, 'initialized')

        with fresh(name):
            self.machinery.FrozenImporter.exec_module(module)
        with captured_stdout() as stdout:
            module.main()

        self.assertTrue(module.initialized)
        self.assertTrue(hasattr(module, '__spec__'))
        self.assertEqual(module.__spec__.origin, 'frozen')
        return module, stdout.getvalue()
Example #4
0
 def test_unloadable(self):
     with import_helper.frozen_modules():
         with deprecated():
             assert self.machinery.FrozenImporter.find_module('_not_real') is None
         with self.assertRaises(ImportError) as cm:
             self.load_module('_not_real')
         self.assertEqual(cm.exception.name, '_not_real')
Example #5
0
    def exec_module(self, name):
        with import_helper.frozen_modules():
            is_package = self.machinery.FrozenImporter.is_package(name)
            code = _imp.get_frozen_object(name)
        data = marshal.dumps(code)
        spec = self.machinery.ModuleSpec(
            name,
            self.machinery.FrozenImporter,
            origin='frozen',
            is_package=is_package,
            loader_state=data,
        )
        module = types.ModuleType(name)
        module.__spec__ = spec
        assert not hasattr(module, 'initialized')

        with fresh(name):
            self.machinery.FrozenImporter.exec_module(module)
        with captured_stdout() as stdout:
            module.main()

        self.assertTrue(module.initialized)
        self.assertTrue(hasattr(module, '__spec__'))
        self.assertEqual(module.__spec__.origin, 'frozen')
        return module, stdout.getvalue()
Example #6
0
 def test_failure(self):
     # Raise ImportError for modules that are not frozen.
     for meth_name in ('get_code', 'get_source', 'is_package'):
         method = getattr(self.machinery.FrozenImporter, meth_name)
         with self.assertRaises(ImportError) as cm:
             with import_helper.frozen_modules():
                 method('importlib')
         self.assertEqual(cm.exception.name, 'importlib')
Example #7
0
 def test_is_package(self):
     # Should be able to tell what is a package.
     test_for = (('__hello__', False), ('__phello__', True),
                 ('__phello__.spam', False))
     for name, is_package in test_for:
         with import_helper.frozen_modules():
             result = self.machinery.FrozenImporter.is_package(name)
         self.assertEqual(bool(result), is_package)
Example #8
0
def fresh(name, *, oldapi=False):
    with util.uncache(name):
        with import_helper.frozen_modules():
            if oldapi:
                with deprecated():
                    yield
            else:
                yield
Example #9
0
 def check_data(self, spec):
     with import_helper.frozen_modules():
         expected = _imp.get_frozen_object(spec.name)
     data = spec.loader_state
     # We can't compare the marshaled data directly because
     # marshal.dumps() would mark "expected" as a ref, which slightly
     # changes the output.  (See https://bugs.python.org/issue34093.)
     code = marshal.loads(data)
     self.assertEqual(code, expected)
Example #10
0
 def test_not_using_frozen(self):
     finder = self.machinery.FrozenImporter
     with import_helper.frozen_modules(enabled=False):
         # both frozen and not frozen
         spec1 = finder.find_spec('__hello__')
         # only frozen
         spec2 = finder.find_spec('__hello_only__')
     self.assertIsNone(spec1)
     self.assertIsNone(spec2)
Example #11
0
 def test_frozen(self):
     name = '__hello__'
     if name in sys.modules:
         del sys.modules[name]
     with import_helper.frozen_modules():
         import __hello__
     with captured_stdout() as out:
         __hello__.main()
     self.assertEqual(out.getvalue(), 'Hello world!\n')
Example #12
0
 def test_get_code(self):
     # Make sure that the code object is good.
     name = '__hello__'
     with import_helper.frozen_modules():
         code = self.machinery.FrozenImporter.get_code(name)
         mod = types.ModuleType(name)
         exec(code, mod.__dict__)
     with captured_stdout() as stdout:
         mod.main()
     self.assertTrue(hasattr(mod, 'initialized'))
     self.assertEqual(stdout.getvalue(), 'Hello world!\n')
Example #13
0
    def check_loader_state(self, spec, origname=None, filename=None):
        if not filename:
            if not origname:
                origname = spec.name

        actual = dict(vars(spec.loader_state))

        # Check the code object used to import the frozen module.
        # We can't compare the marshaled data directly because
        # marshal.dumps() would mark "expected" (below) as a ref,
        # which slightly changes the output.
        # (See https://bugs.python.org/issue34093.)
        data = actual.pop('data')
        with import_helper.frozen_modules():
            expected = _imp.get_frozen_object(spec.name)
        code = marshal.loads(data)
        self.assertEqual(code, expected)

        # Check the rest of spec.loader_state.
        expected = dict(origname=origname, )
        self.assertDictEqual(actual, expected)
Example #14
0
 def find(self, name, **kwargs):
     finder = self.machinery.FrozenImporter
     with import_helper.frozen_modules():
         return finder.find_spec(name, **kwargs)
Example #15
0
 def find(self, name, path=None):
     finder = self.machinery.FrozenImporter
     with warnings.catch_warnings():
         warnings.simplefilter("ignore", DeprecationWarning)
         with import_helper.frozen_modules():
             return finder.find_module(name, path)
Example #16
0
 def test_get_source(self):
     # Should always return None.
     with import_helper.frozen_modules():
         result = self.machinery.FrozenImporter.get_source('__hello__')
     self.assertIsNone(result)