Issue #20383: Introduce importlib.util.module_from_spec().

Along the way, dismantle importlib._bootstrap._SpecMethods as it was
no longer relevant and constructing the new function required
partially dismantling the class anyway.
diff --git a/Lib/test/test_importlib/test_spec.py b/Lib/test/test_importlib/test_spec.py
index 0cb14ee..418b4c0 100644
--- a/Lib/test/test_importlib/test_spec.py
+++ b/Lib/test/test_importlib/test_spec.py
@@ -242,152 +242,14 @@
                                                   origin=self.path)
         self.loc_spec._set_fileattr = True
 
-    # init_module_attrs
-
-    def test_init_module_attrs(self):
-        module = type(sys)(self.name)
-        spec = self.machinery.ModuleSpec(self.name, self.loader)
-        self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
-        self.assertEqual(module.__name__, spec.name)
-        self.assertIs(module.__loader__, spec.loader)
-        self.assertEqual(module.__package__, spec.parent)
-        self.assertIs(module.__spec__, spec)
-        self.assertFalse(hasattr(module, '__path__'))
-        self.assertFalse(hasattr(module, '__file__'))
-        self.assertFalse(hasattr(module, '__cached__'))
-
-    def test_init_module_attrs_package(self):
-        module = type(sys)(self.name)
-        spec = self.machinery.ModuleSpec(self.name, self.loader)
-        spec.submodule_search_locations = ['spam', 'ham']
-        self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
-        self.assertEqual(module.__name__, spec.name)
-        self.assertIs(module.__loader__, spec.loader)
-        self.assertEqual(module.__package__, spec.parent)
-        self.assertIs(module.__spec__, spec)
-        self.assertIs(module.__path__, spec.submodule_search_locations)
-        self.assertFalse(hasattr(module, '__file__'))
-        self.assertFalse(hasattr(module, '__cached__'))
-
-    def test_init_module_attrs_location(self):
-        module = type(sys)(self.name)
-        spec = self.loc_spec
-        self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
-        self.assertEqual(module.__name__, spec.name)
-        self.assertIs(module.__loader__, spec.loader)
-        self.assertEqual(module.__package__, spec.parent)
-        self.assertIs(module.__spec__, spec)
-        self.assertFalse(hasattr(module, '__path__'))
-        self.assertEqual(module.__file__, spec.origin)
-        self.assertEqual(module.__cached__,
-                         self.util.cache_from_source(spec.origin))
-
-    def test_init_module_attrs_different_name(self):
-        module = type(sys)('eggs')
-        spec = self.machinery.ModuleSpec(self.name, self.loader)
-        self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
-        self.assertEqual(module.__name__, spec.name)
-
-    def test_init_module_attrs_different_spec(self):
-        module = type(sys)(self.name)
-        module.__spec__ = self.machinery.ModuleSpec('eggs', object())
-        spec = self.machinery.ModuleSpec(self.name, self.loader)
-        self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
-        self.assertEqual(module.__name__, spec.name)
-        self.assertIs(module.__loader__, spec.loader)
-        self.assertEqual(module.__package__, spec.parent)
-        self.assertIs(module.__spec__, spec)
-
-    def test_init_module_attrs_already_set(self):
-        module = type(sys)('ham.eggs')
-        module.__loader__ = object()
-        module.__package__ = 'ham'
-        module.__path__ = ['eggs']
-        module.__file__ = 'ham/eggs/__init__.py'
-        module.__cached__ = self.util.cache_from_source(module.__file__)
-        original = vars(module).copy()
-        spec = self.loc_spec
-        spec.submodule_search_locations = ['']
-        self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
-        self.assertIs(module.__loader__, original['__loader__'])
-        self.assertEqual(module.__package__, original['__package__'])
-        self.assertIs(module.__path__, original['__path__'])
-        self.assertEqual(module.__file__, original['__file__'])
-        self.assertEqual(module.__cached__, original['__cached__'])
-
-    def test_init_module_attrs_immutable(self):
-        module = object()
-        spec = self.loc_spec
-        spec.submodule_search_locations = ['']
-        self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
-        self.assertFalse(hasattr(module, '__name__'))
-        self.assertFalse(hasattr(module, '__loader__'))
-        self.assertFalse(hasattr(module, '__package__'))
-        self.assertFalse(hasattr(module, '__spec__'))
-        self.assertFalse(hasattr(module, '__path__'))
-        self.assertFalse(hasattr(module, '__file__'))
-        self.assertFalse(hasattr(module, '__cached__'))
-
-    # create()
-
-    def test_create(self):
-        created = self.bootstrap._SpecMethods(self.spec).create()
-
-        self.assertEqual(created.__name__, self.spec.name)
-        self.assertIs(created.__loader__, self.spec.loader)
-        self.assertEqual(created.__package__, self.spec.parent)
-        self.assertIs(created.__spec__, self.spec)
-        self.assertFalse(hasattr(created, '__path__'))
-        self.assertFalse(hasattr(created, '__file__'))
-        self.assertFalse(hasattr(created, '__cached__'))
-
-    def test_create_from_loader(self):
-        module = type(sys.implementation)()
-        class CreatingLoader(TestLoader):
-            def create_module(self, spec):
-                return module
-        self.spec.loader = CreatingLoader()
-        created = self.bootstrap._SpecMethods(self.spec).create()
-
-        self.assertIs(created, module)
-        self.assertEqual(created.__name__, self.spec.name)
-        self.assertIs(created.__loader__, self.spec.loader)
-        self.assertEqual(created.__package__, self.spec.parent)
-        self.assertIs(created.__spec__, self.spec)
-        self.assertFalse(hasattr(created, '__path__'))
-        self.assertFalse(hasattr(created, '__file__'))
-        self.assertFalse(hasattr(created, '__cached__'))
-
-    def test_create_from_loader_not_handled(self):
-        class CreatingLoader(TestLoader):
-            def create_module(self, spec):
-                return None
-        self.spec.loader = CreatingLoader()
-        created = self.bootstrap._SpecMethods(self.spec).create()
-
-        self.assertEqual(created.__name__, self.spec.name)
-        self.assertIs(created.__loader__, self.spec.loader)
-        self.assertEqual(created.__package__, self.spec.parent)
-        self.assertIs(created.__spec__, self.spec)
-        self.assertFalse(hasattr(created, '__path__'))
-        self.assertFalse(hasattr(created, '__file__'))
-        self.assertFalse(hasattr(created, '__cached__'))
-
     # exec()
 
     def test_exec(self):
         self.spec.loader = NewLoader()
-        module = self.bootstrap._SpecMethods(self.spec).create()
+        module = self.util.module_from_spec(self.spec)
         sys.modules[self.name] = module
         self.assertFalse(hasattr(module, 'eggs'))
-        self.bootstrap._SpecMethods(self.spec).exec(module)
+        self.bootstrap._exec(self.spec, module)
 
         self.assertEqual(module.eggs, 1)
 
@@ -396,7 +258,7 @@
     def test_load(self):
         self.spec.loader = NewLoader()
         with CleanImport(self.spec.name):
-            loaded = self.bootstrap._SpecMethods(self.spec).load()
+            loaded = self.bootstrap._load(self.spec)
             installed = sys.modules[self.spec.name]
 
         self.assertEqual(loaded.eggs, 1)
@@ -409,7 +271,7 @@
                 sys.modules[module.__name__] = replacement
         self.spec.loader = ReplacingLoader()
         with CleanImport(self.spec.name):
-            loaded = self.bootstrap._SpecMethods(self.spec).load()
+            loaded = self.bootstrap._load(self.spec)
             installed = sys.modules[self.spec.name]
 
         self.assertIs(loaded, replacement)
@@ -422,7 +284,7 @@
         self.spec.loader = FailedLoader()
         with CleanImport(self.spec.name):
             with self.assertRaises(RuntimeError):
-                loaded = self.bootstrap._SpecMethods(self.spec).load()
+                loaded = self.bootstrap._load(self.spec)
             self.assertNotIn(self.spec.name, sys.modules)
 
     def test_load_failed_removed(self):
@@ -433,20 +295,20 @@
         self.spec.loader = FailedLoader()
         with CleanImport(self.spec.name):
             with self.assertRaises(RuntimeError):
-                loaded = self.bootstrap._SpecMethods(self.spec).load()
+                loaded = self.bootstrap._load(self.spec)
             self.assertNotIn(self.spec.name, sys.modules)
 
     def test_load_legacy(self):
         self.spec.loader = LegacyLoader()
         with CleanImport(self.spec.name):
-            loaded = self.bootstrap._SpecMethods(self.spec).load()
+            loaded = self.bootstrap._load(self.spec)
 
         self.assertEqual(loaded.ham, -1)
 
     def test_load_legacy_attributes(self):
         self.spec.loader = LegacyLoader()
         with CleanImport(self.spec.name):
-            loaded = self.bootstrap._SpecMethods(self.spec).load()
+            loaded = self.bootstrap._load(self.spec)
 
         self.assertIs(loaded.__loader__, self.spec.loader)
         self.assertEqual(loaded.__package__, self.spec.parent)
@@ -460,7 +322,7 @@
                 return module
         self.spec.loader = ImmutableLoader()
         with CleanImport(self.spec.name):
-            loaded = self.bootstrap._SpecMethods(self.spec).load()
+            loaded = self.bootstrap._load(self.spec)
 
             self.assertIs(sys.modules[self.spec.name], module)
 
@@ -469,8 +331,8 @@
     def test_reload(self):
         self.spec.loader = NewLoader()
         with CleanImport(self.spec.name):
-            loaded = self.bootstrap._SpecMethods(self.spec).load()
-            reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded)
+            loaded = self.bootstrap._load(self.spec)
+            reloaded = self.bootstrap._exec(self.spec, loaded)
             installed = sys.modules[self.spec.name]
 
         self.assertEqual(loaded.eggs, 1)
@@ -480,9 +342,9 @@
     def test_reload_modified(self):
         self.spec.loader = NewLoader()
         with CleanImport(self.spec.name):
-            loaded = self.bootstrap._SpecMethods(self.spec).load()
+            loaded = self.bootstrap._load(self.spec)
             loaded.eggs = 2
-            reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded)
+            reloaded = self.bootstrap._exec(self.spec, loaded)
 
         self.assertEqual(loaded.eggs, 1)
         self.assertIs(reloaded, loaded)
@@ -490,9 +352,9 @@
     def test_reload_extra_attributes(self):
         self.spec.loader = NewLoader()
         with CleanImport(self.spec.name):
-            loaded = self.bootstrap._SpecMethods(self.spec).load()
+            loaded = self.bootstrap._load(self.spec)
             loaded.available = False
-            reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded)
+            reloaded = self.bootstrap._exec(self.spec, loaded)
 
         self.assertFalse(loaded.available)
         self.assertIs(reloaded, loaded)
@@ -500,12 +362,12 @@
     def test_reload_init_module_attrs(self):
         self.spec.loader = NewLoader()
         with CleanImport(self.spec.name):
-            loaded = self.bootstrap._SpecMethods(self.spec).load()
+            loaded = self.bootstrap._load(self.spec)
             loaded.__name__ = 'ham'
             del loaded.__loader__
             del loaded.__package__
             del loaded.__spec__
-            self.bootstrap._SpecMethods(self.spec).exec(loaded)
+            self.bootstrap._exec(self.spec, loaded)
 
         self.assertEqual(loaded.__name__, self.spec.name)
         self.assertIs(loaded.__loader__, self.spec.loader)
@@ -518,8 +380,8 @@
     def test_reload_legacy(self):
         self.spec.loader = LegacyLoader()
         with CleanImport(self.spec.name):
-            loaded = self.bootstrap._SpecMethods(self.spec).load()
-            reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded)
+            loaded = self.bootstrap._load(self.spec)
+            reloaded = self.bootstrap._exec(self.spec, loaded)
             installed = sys.modules[self.spec.name]
 
         self.assertEqual(loaded.ham, -1)
@@ -778,13 +640,14 @@
     # spec_from_file_location()
 
     def test_spec_from_file_location_default(self):
-        if self.machinery is machinery['Source']:
-            raise unittest.SkipTest('not sure why this is breaking...')
         spec = self.util.spec_from_file_location(self.name, self.path)
 
         self.assertEqual(spec.name, self.name)
+        # Need to use a circuitous route to get at importlib.machinery to make
+        # sure the same class object is used in the isinstance() check as
+        # would have been used to create the loader.
         self.assertIsInstance(spec.loader,
-                              self.machinery.SourceFileLoader)
+                              self.util.abc.machinery.SourceFileLoader)
         self.assertEqual(spec.loader.name, self.name)
         self.assertEqual(spec.loader.path, self.path)
         self.assertEqual(spec.origin, self.path)
@@ -941,3 +804,7 @@
 (Frozen_FactoryTests,
  Source_FactoryTests
  ) = test_util.test_both(FactoryTests, util=util, machinery=machinery)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py
index 9428471..cd9344c 100644
--- a/Lib/test/test_importlib/test_util.py
+++ b/Lib/test/test_importlib/test_util.py
@@ -1,8 +1,8 @@
-import importlib.util
-from . import util as test_util
-init = test_util.import_importlib('importlib')
-machinery = test_util.import_importlib('importlib.machinery')
-util = test_util.import_importlib('importlib.util')
+from . import util
+abc = util.import_importlib('importlib.abc')
+init = util.import_importlib('importlib')
+machinery = util.import_importlib('importlib.machinery')
+importlib_util = util.import_importlib('importlib.util')
 
 import os
 import sys
@@ -35,7 +35,85 @@
 
 (Frozen_DecodeSourceBytesTests,
  Source_DecodeSourceBytesTests
- ) = test_util.test_both(DecodeSourceBytesTests, util=util)
+ ) = util.test_both(DecodeSourceBytesTests, util=importlib_util)
+
+
+class ModuleFromSpecTests:
+
+    def test_no_create_module(self):
+        class Loader(self.abc.Loader):
+            pass
+        spec = self.machinery.ModuleSpec('test', Loader())
+        module = self.util.module_from_spec(spec)
+        self.assertIsInstance(module, types.ModuleType)
+        self.assertEqual(module.__name__, spec.name)
+
+    def test_create_module_returns_None(self):
+        class Loader(self.abc.Loader):
+            def create_module(self, spec):
+                return None
+        spec = self.machinery.ModuleSpec('test', Loader())
+        module = self.util.module_from_spec(spec)
+        self.assertIsInstance(module, types.ModuleType)
+        self.assertEqual(module.__name__, spec.name)
+
+    def test_create_module(self):
+        name = 'already set'
+        class CustomModule(types.ModuleType):
+            pass
+        class Loader(self.abc.Loader):
+            def create_module(self, spec):
+                module = CustomModule(spec.name)
+                module.__name__ = name
+                return module
+        spec = self.machinery.ModuleSpec('test', Loader())
+        module = self.util.module_from_spec(spec)
+        self.assertIsInstance(module, CustomModule)
+        self.assertEqual(module.__name__, name)
+
+    def test___name__(self):
+        spec = self.machinery.ModuleSpec('test', object())
+        module = self.util.module_from_spec(spec)
+        self.assertEqual(module.__name__, spec.name)
+
+    def test___spec__(self):
+        spec = self.machinery.ModuleSpec('test', object())
+        module = self.util.module_from_spec(spec)
+        self.assertEqual(module.__spec__, spec)
+
+    def test___loader__(self):
+        loader = object()
+        spec = self.machinery.ModuleSpec('test', loader)
+        module = self.util.module_from_spec(spec)
+        self.assertIs(module.__loader__, loader)
+
+    def test___package__(self):
+        spec = self.machinery.ModuleSpec('test.pkg', object())
+        module = self.util.module_from_spec(spec)
+        self.assertEqual(module.__package__, spec.parent)
+
+    def test___path__(self):
+        spec = self.machinery.ModuleSpec('test', object(), is_package=True)
+        module = self.util.module_from_spec(spec)
+        self.assertEqual(module.__path__, spec.submodule_search_locations)
+
+    def test___file__(self):
+        spec = self.machinery.ModuleSpec('test', object(), origin='some/path')
+        spec.has_location = True
+        module = self.util.module_from_spec(spec)
+        self.assertEqual(module.__file__, spec.origin)
+
+    def test___cached__(self):
+        spec = self.machinery.ModuleSpec('test', object())
+        spec.cached = 'some/path'
+        spec.has_location = True
+        module = self.util.module_from_spec(spec)
+        self.assertEqual(module.__cached__, spec.cached)
+
+(Frozen_ModuleFromSpecTests,
+ Source_ModuleFromSpecTests
+) = util.test_both(ModuleFromSpecTests, abc=abc, machinery=machinery,
+                   util=importlib_util)
 
 
 class ModuleForLoaderTests:
@@ -72,7 +150,7 @@
         # Test that when no module exists in sys.modules a new module is
         # created.
         module_name = 'a.b.c'
-        with test_util.uncache(module_name):
+        with util.uncache(module_name):
             module = self.return_module(module_name)
             self.assertIn(module_name, sys.modules)
         self.assertIsInstance(module, types.ModuleType)
@@ -90,7 +168,7 @@
         module = types.ModuleType('a.b.c')
         module.__loader__ = 42
         module.__package__ = 42
-        with test_util.uncache(name):
+        with util.uncache(name):
             sys.modules[name] = module
             loader = FakeLoader()
             returned_module = loader.load_module(name)
@@ -102,7 +180,7 @@
         # Test that a module is removed from sys.modules if added but an
         # exception is raised.
         name = 'a.b.c'
-        with test_util.uncache(name):
+        with util.uncache(name):
             self.raise_exception(name)
             self.assertNotIn(name, sys.modules)
 
@@ -110,7 +188,7 @@
         # Test that a failure on reload leaves the module in-place.
         name = 'a.b.c'
         module = types.ModuleType(name)
-        with test_util.uncache(name):
+        with util.uncache(name):
             sys.modules[name] = module
             self.raise_exception(name)
             self.assertIs(module, sys.modules[name])
@@ -129,7 +207,7 @@
 
         name = 'mod'
         module = FalseModule(name)
-        with test_util.uncache(name):
+        with util.uncache(name):
             self.assertFalse(module)
             sys.modules[name] = module
             given = self.return_module(name)
@@ -148,7 +226,7 @@
                 return module
 
         name = 'pkg.mod'
-        with test_util.uncache(name):
+        with util.uncache(name):
             loader = FakeLoader(False)
             module = loader.load_module(name)
             self.assertEqual(module.__name__, name)
@@ -156,7 +234,7 @@
             self.assertEqual(module.__package__, 'pkg')
 
         name = 'pkg.sub'
-        with test_util.uncache(name):
+        with util.uncache(name):
             loader = FakeLoader(True)
             module = loader.load_module(name)
             self.assertEqual(module.__name__, name)
@@ -166,7 +244,7 @@
 
 (Frozen_ModuleForLoaderTests,
  Source_ModuleForLoaderTests
- ) = test_util.test_both(ModuleForLoaderTests, util=util)
+ ) = util.test_both(ModuleForLoaderTests, util=importlib_util)
 
 
 class SetPackageTests:
@@ -229,7 +307,7 @@
 
 (Frozen_SetPackageTests,
  Source_SetPackageTests
- ) = test_util.test_both(SetPackageTests, util=util)
+ ) = util.test_both(SetPackageTests, util=importlib_util)
 
 
 class SetLoaderTests:
@@ -276,7 +354,7 @@
 
 (Frozen_SetLoaderTests,
  Source_SetLoaderTests
- ) = test_util.test_both(SetLoaderTests, util=util)
+ ) = util.test_both(SetLoaderTests, util=importlib_util)
 
 
 class ResolveNameTests:
@@ -314,7 +392,7 @@
 
 (Frozen_ResolveNameTests,
  Source_ResolveNameTests
- ) = test_util.test_both(ResolveNameTests, util=util)
+ ) = util.test_both(ResolveNameTests, util=importlib_util)
 
 
 class FindSpecTests:
@@ -325,7 +403,7 @@
 
     def test_sys_modules(self):
         name = 'some_mod'
-        with test_util.uncache(name):
+        with util.uncache(name):
             module = types.ModuleType(name)
             loader = 'a loader!'
             spec = self.machinery.ModuleSpec(name, loader)
@@ -337,7 +415,7 @@
 
     def test_sys_modules_without___loader__(self):
         name = 'some_mod'
-        with test_util.uncache(name):
+        with util.uncache(name):
             module = types.ModuleType(name)
             del module.__loader__
             loader = 'a loader!'
@@ -349,7 +427,7 @@
 
     def test_sys_modules_spec_is_None(self):
         name = 'some_mod'
-        with test_util.uncache(name):
+        with util.uncache(name):
             module = types.ModuleType(name)
             module.__spec__ = None
             sys.modules[name] = module
@@ -358,7 +436,7 @@
 
     def test_sys_modules_loader_is_None(self):
         name = 'some_mod'
-        with test_util.uncache(name):
+        with util.uncache(name):
             module = types.ModuleType(name)
             spec = self.machinery.ModuleSpec(name, None)
             module.__spec__ = spec
@@ -368,7 +446,7 @@
 
     def test_sys_modules_spec_is_not_set(self):
         name = 'some_mod'
-        with test_util.uncache(name):
+        with util.uncache(name):
             module = types.ModuleType(name)
             try:
                 del module.__spec__
@@ -380,8 +458,8 @@
 
     def test_success(self):
         name = 'some_mod'
-        with test_util.uncache(name):
-            with test_util.import_state(meta_path=[self.FakeMetaFinder]):
+        with util.uncache(name):
+            with util.import_state(meta_path=[self.FakeMetaFinder]):
                 self.assertEqual((name, None, None),
                                  self.util.find_spec(name))
 
@@ -389,8 +467,8 @@
 #        # Searching on a path should work.
 #        name = 'some_mod'
 #        path = 'path to some place'
-#        with test_util.uncache(name):
-#            with test_util.import_state(meta_path=[self.FakeMetaFinder]):
+#        with util.uncache(name):
+#            with util.import_state(meta_path=[self.FakeMetaFinder]):
 #                self.assertEqual((name, path, None),
 #                                 self.util.find_spec(name, path))
 
@@ -401,8 +479,8 @@
     def test_find_submodule(self):
         name = 'spam'
         subname = 'ham'
-        with test_util.temp_module(name, pkg=True) as pkg_dir:
-            fullname, _ = test_util.submodule(name, subname, pkg_dir)
+        with util.temp_module(name, pkg=True) as pkg_dir:
+            fullname, _ = util.submodule(name, subname, pkg_dir)
             spec = self.util.find_spec(fullname)
             self.assertIsNot(spec, None)
             self.assertIn(name, sorted(sys.modules))
@@ -414,9 +492,9 @@
     def test_find_submodule_parent_already_imported(self):
         name = 'spam'
         subname = 'ham'
-        with test_util.temp_module(name, pkg=True) as pkg_dir:
+        with util.temp_module(name, pkg=True) as pkg_dir:
             self.init.import_module(name)
-            fullname, _ = test_util.submodule(name, subname, pkg_dir)
+            fullname, _ = util.submodule(name, subname, pkg_dir)
             spec = self.util.find_spec(fullname)
             self.assertIsNot(spec, None)
             self.assertIn(name, sorted(sys.modules))
@@ -428,8 +506,8 @@
     def test_find_relative_module(self):
         name = 'spam'
         subname = 'ham'
-        with test_util.temp_module(name, pkg=True) as pkg_dir:
-            fullname, _ = test_util.submodule(name, subname, pkg_dir)
+        with util.temp_module(name, pkg=True) as pkg_dir:
+            fullname, _ = util.submodule(name, subname, pkg_dir)
             relname = '.' + subname
             spec = self.util.find_spec(relname, name)
             self.assertIsNot(spec, None)
@@ -442,8 +520,8 @@
     def test_find_relative_module_missing_package(self):
         name = 'spam'
         subname = 'ham'
-        with test_util.temp_module(name, pkg=True) as pkg_dir:
-            fullname, _ = test_util.submodule(name, subname, pkg_dir)
+        with util.temp_module(name, pkg=True) as pkg_dir:
+            fullname, _ = util.submodule(name, subname, pkg_dir)
             relname = '.' + subname
             with self.assertRaises(ValueError):
                 self.util.find_spec(relname)
@@ -453,7 +531,7 @@
 
 (Frozen_FindSpecTests,
  Source_FindSpecTests
- ) = test_util.test_both(FindSpecTests, init=init, util=util,
+ ) = util.test_both(FindSpecTests, init=init, util=importlib_util,
                          machinery=machinery)
 
 
@@ -470,7 +548,7 @@
 
 (Frozen_MagicNumberTests,
  Source_MagicNumberTests
- ) = test_util.test_both(MagicNumberTests, util=util)
+ ) = util.test_both(MagicNumberTests, util=importlib_util)
 
 
 class PEP3147Tests:
@@ -588,7 +666,7 @@
 
 (Frozen_PEP3147Tests,
  Source_PEP3147Tests
- ) = test_util.test_both(PEP3147Tests, util=util)
+ ) = util.test_both(PEP3147Tests, util=importlib_util)
 
 
 if __name__ == '__main__':
diff --git a/Lib/test/test_tools.py b/Lib/test/test_tools.py
index 1bf7d54..2eb8066 100644
--- a/Lib/test/test_tools.py
+++ b/Lib/test/test_tools.py
@@ -407,7 +407,7 @@
     def setUpClass(self):
         path = os.path.join(scriptsdir, 'pdeps.py')
         spec = importlib.util.spec_from_file_location('pdeps', path)
-        self.pdeps = importlib._bootstrap._SpecMethods(spec).load()
+        self.pdeps = importlib._bootstrap._load(spec)
 
     @classmethod
     def tearDownClass(self):
@@ -432,7 +432,7 @@
     def setUp(self):
         path = os.path.join(scriptsdir, 'gprof2html.py')
         spec = importlib.util.spec_from_file_location('gprof2html', path)
-        self.gprof = importlib._bootstrap._SpecMethods(spec).load()
+        self.gprof = importlib._bootstrap._load(spec)
         oldargv = sys.argv
         def fixup():
             sys.argv = oldargv