Add an os.get_exec_path() function to return the list of directories
that launching a subprocess will search for the executable.
Refactors some code in os._execvpe().
diff --git a/Doc/library/os.rst b/Doc/library/os.rst
index d01c8da..0547154 100644
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -136,6 +136,17 @@
    These functions are described in :ref:`os-file-dir`.
 
 
+.. function:: get_exec_path(env=None)
+
+   Returns the list of directories that will be searched for a named
+   executable, similar to a shell, when launching a process.
+   *env*, when specified, should be an environment variable dictionary
+   to lookup the PATH in.
+   By default, when *env* is None, :data:`environ` is used.
+
+   .. versionadded:: 3.2
+
+
 .. function:: ctermid()
 
    Return the filename corresponding to the controlling terminal of the process.
diff --git a/Lib/os.py b/Lib/os.py
index 1c5b5ce..580b983 100644
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -342,28 +342,23 @@
 
 def _execvpe(file, args, env=None):
     if env is not None:
-        func = execve
+        exec_func = execve
         argrest = (args, env)
     else:
-        func = execv
+        exec_func = execv
         argrest = (args,)
         env = environ
 
     head, tail = path.split(file)
     if head:
-        func(file, *argrest)
+        exec_func(file, *argrest)
         return
-    if 'PATH' in env:
-        envpath = env['PATH']
-    else:
-        envpath = defpath
-    PATH = envpath.split(pathsep)
     last_exc = saved_exc = None
     saved_tb = None
-    for dir in PATH:
+    for dir in get_exec_path(env):
         fullname = path.join(dir, file)
         try:
-            func(fullname, *argrest)
+            exec_func(fullname, *argrest)
         except error as e:
             last_exc = e
             tb = sys.exc_info()[2]
@@ -376,6 +371,18 @@
     raise last_exc.with_traceback(tb)
 
 
+def get_exec_path(env=None):
+    """Returns the sequence of directories that will be searched for the
+    named executable (similar to a shell) when launching a process.
+
+    *env* must be an environment variable dict or None.  If *env* is None,
+    os.environ will be used.
+    """
+    if env is None:
+        env = environ
+    return env.get('PATH', defpath).split(pathsep)
+
+
 # Change environ to automatically call putenv(), unsetenv if they exist.
 from _abcoll import MutableMapping  # Can't use collections (bootstrap)
 
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 1ff356c..9846d92 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -407,6 +407,27 @@
         self.assertTrue(isinstance(env.data, dict))
         self.assertEqual(repr(env), 'environ({!r})'.format(env.data))
 
+    def test_get_exec_path(self):
+        defpath_list = os.defpath.split(os.pathsep)
+        test_path = ['/monty', '/python', '', '/flying/circus']
+        test_env = {'PATH': os.pathsep.join(test_path)}
+
+        saved_environ = os.environ
+        try:
+            os.environ = dict(test_env)
+            # Test that defaulting to os.environ works.
+            self.assertSequenceEqual(test_path, os.get_exec_path())
+            self.assertSequenceEqual(test_path, os.get_exec_path(env=None))
+        finally:
+            os.environ = saved_environ
+
+        # No PATH environment variable
+        self.assertSequenceEqual(defpath_list, os.get_exec_path({}))
+        # Empty PATH environment variable
+        self.assertSequenceEqual(('',), os.get_exec_path({'PATH':''}))
+        # Supplied PATH environment variable
+        self.assertSequenceEqual(test_path, os.get_exec_path(test_env))
+
 
 class WalkTests(unittest.TestCase):
     """Tests for os.walk()."""
diff --git a/Misc/NEWS b/Misc/NEWS
index 81dfbc0..8ce22ad 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -701,6 +701,9 @@
 
 - Issue #6218: io.StringIO and io.BytesIO instances are now picklable.
 
+- The os.get_exec_path() function to return the list of directories that will
+  be searched for an executable when launching a subprocess was added.
+
 Extension Modules
 -----------------