PEP 3147
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index 330eb63..30d5251 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -488,6 +488,16 @@
 
     """Load a module from a source or bytecode file."""
 
+    def _find_path(self, ext_type):
+        """Return PEP 3147 path if ext_type is PY_COMPILED, otherwise
+        super()._find_path() is called."""
+        if ext_type == imp.PY_COMPILED:
+            # We don't really care what the extension on self._base_path is,
+            # as long as it has exactly one dot.
+            bytecode_path = imp.cache_from_source(self._base_path + '.py')
+            return (bytecode_path if _path_exists(bytecode_path) else None)
+        return super()._find_path(ext_type)
+
     @_check_name
     def source_mtime(self, name):
         """Return the modification time of the source for the specified
@@ -515,7 +525,16 @@
         """
         bytecode_path = self.bytecode_path(name)
         if not bytecode_path:
-            bytecode_path = self._base_path + _suffix_list(imp.PY_COMPILED)[0]
+            source_path = self.source_path(name)
+            bytecode_path = imp.cache_from_source(source_path)
+            # Ensure that the __pycache__ directory exists.  We can't use
+            # os.path.dirname() here.
+            dirname, sep, basename = bytecode_path.rpartition(path_sep)
+            try:
+                _os.mkdir(dirname)
+            except OSError as error:
+                if error.errno != errno.EEXIST:
+                    raise
         try:
             # Assuming bytes.
             with _closing(_io.FileIO(bytecode_path, 'w')) as bytecode_file:
diff --git a/Lib/importlib/test/__main__.py b/Lib/importlib/test/__main__.py
index b97e382..8329264 100644
--- a/Lib/importlib/test/__main__.py
+++ b/Lib/importlib/test/__main__.py
@@ -13,7 +13,12 @@
 
 
 def test_main():
-    start_dir = os.path.dirname(__file__)
+    if '__pycache__' in __file__:
+        parts = __file__.split(os.path.sep)
+        start_dir = sep.join(parts[:-2])
+    else:
+        start_dir = os.path.dirname(__file__)
+    # XXX 2010-03-18 barry: Fix __file__
     top_dir = os.path.dirname(os.path.dirname(start_dir))
     test_loader = unittest.TestLoader()
     if '--builtin' in sys.argv:
diff --git a/Lib/importlib/test/source/test_file_loader.py b/Lib/importlib/test/source/test_file_loader.py
index ae4b185..9059405 100644
--- a/Lib/importlib/test/source/test_file_loader.py
+++ b/Lib/importlib/test/source/test_file_loader.py
@@ -127,7 +127,7 @@
         except KeyError:
             pass
         py_compile.compile(mapping[name])
-        bytecode_path = source_util.bytecode_path(mapping[name])
+        bytecode_path = imp.cache_from_source(mapping[name])
         with open(bytecode_path, 'rb') as file:
             bc = file.read()
         new_bc = manipulator(bc)
@@ -226,7 +226,7 @@
         zeros = b'\x00\x00\x00\x00'
         with source_util.create_modules('_temp') as mapping:
             py_compile.compile(mapping['_temp'])
-            bytecode_path = source_util.bytecode_path(mapping['_temp'])
+            bytecode_path = imp.cache_from_source(mapping['_temp'])
             with open(bytecode_path, 'r+b') as bytecode_file:
                 bytecode_file.seek(4)
                 bytecode_file.write(zeros)
@@ -242,9 +242,10 @@
     def test_bad_marshal(self):
         # Bad marshal data should raise a ValueError.
         with source_util.create_modules('_temp') as mapping:
-            bytecode_path = source_util.bytecode_path(mapping['_temp'])
+            bytecode_path = imp.cache_from_source(mapping['_temp'])
             source_mtime = os.path.getmtime(mapping['_temp'])
             source_timestamp = importlib._w_long(source_mtime)
+            source_util.ensure_bytecode_path(bytecode_path)
             with open(bytecode_path, 'wb') as bytecode_file:
                 bytecode_file.write(imp.get_magic())
                 bytecode_file.write(source_timestamp)
@@ -260,7 +261,7 @@
         with source_util.create_modules('_temp') as mapping:
             # Create bytecode that will need to be re-created.
             py_compile.compile(mapping['_temp'])
-            bytecode_path = source_util.bytecode_path(mapping['_temp'])
+            bytecode_path = imp.cache_from_source(mapping['_temp'])
             with open(bytecode_path, 'r+b') as bytecode_file:
                 bytecode_file.seek(0)
                 bytecode_file.write(b'\x00\x00\x00\x00')
diff --git a/Lib/importlib/test/source/test_finder.py b/Lib/importlib/test/source/test_finder.py
index 8f15f62..1673669 100644
--- a/Lib/importlib/test/source/test_finder.py
+++ b/Lib/importlib/test/source/test_finder.py
@@ -1,7 +1,9 @@
 from importlib import _bootstrap
 from .. import abc
 from . import util as source_util
+from test.support import make_legacy_pyc
 import os
+import errno
 import py_compile
 import unittest
 import warnings
@@ -52,6 +54,14 @@
             if unlink:
                 for name in unlink:
                     os.unlink(mapping[name])
+                    try:
+                        make_legacy_pyc(mapping[name])
+                    except OSError as error:
+                        # Some tests do not set compile_=True so the source
+                        # module will not get compiled and there will be no
+                        # PEP 3147 pyc file to rename.
+                        if error.errno != errno.ENOENT:
+                            raise
             loader = self.import_(mapping['.root'], test)
             self.assertTrue(hasattr(loader, 'load_module'))
             return loader
@@ -60,7 +70,8 @@
         # [top-level source]
         self.run_test('top_level')
         # [top-level bc]
-        self.run_test('top_level', compile_={'top_level'}, unlink={'top_level'})
+        self.run_test('top_level', compile_={'top_level'},
+                      unlink={'top_level'})
         # [top-level both]
         self.run_test('top_level', compile_={'top_level'})
 
diff --git a/Lib/importlib/test/source/test_source_encoding.py b/Lib/importlib/test/source/test_source_encoding.py
index fde355f..04aac24 100644
--- a/Lib/importlib/test/source/test_source_encoding.py
+++ b/Lib/importlib/test/source/test_source_encoding.py
@@ -33,7 +33,7 @@
 
     def run_test(self, source):
         with source_util.create_modules(self.module_name) as mapping:
-            with open(mapping[self.module_name], 'wb')as file:
+            with open(mapping[self.module_name], 'wb') as file:
                 file.write(source)
             loader = _bootstrap._PyPycFileLoader(self.module_name,
                                        mapping[self.module_name], False)
diff --git a/Lib/importlib/test/source/util.py b/Lib/importlib/test/source/util.py
index 2b945c5..ae65663 100644
--- a/Lib/importlib/test/source/util.py
+++ b/Lib/importlib/test/source/util.py
@@ -1,5 +1,6 @@
 from .. import util
 import contextlib
+import errno
 import functools
 import imp
 import os
@@ -26,14 +27,16 @@
     return wrapper
 
 
-def bytecode_path(source_path):
-    for suffix, _, type_ in imp.get_suffixes():
-        if type_ == imp.PY_COMPILED:
-            bc_suffix = suffix
-            break
-    else:
-        raise ValueError("no bytecode suffix is defined")
-    return os.path.splitext(source_path)[0] + bc_suffix
+def ensure_bytecode_path(bytecode_path):
+    """Ensure that the __pycache__ directory for PEP 3147 pyc file exists.
+
+    :param bytecode_path: File system path to PEP 3147 pyc file.
+    """
+    try:
+        os.mkdir(os.path.dirname(bytecode_path))
+    except OSError as error:
+        if error.errno != errno.EEXIST:
+            raise
 
 
 @contextlib.contextmanager
diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py
index 3abc6a9..7b44fa1 100644
--- a/Lib/importlib/util.py
+++ b/Lib/importlib/util.py
@@ -1,4 +1,5 @@
 """Utility code for constructing importers, etc."""
+
 from ._bootstrap import module_for_loader
 from ._bootstrap import set_loader
 from ._bootstrap import set_package