mirror of https://github.com/python/cpython.git
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().
This commit is contained in:
parent
9a81697494
commit
b6e8c7e8fb
|
@ -136,6 +136,17 @@ process and user.
|
|||
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.
|
||||
|
|
27
Lib/os.py
27
Lib/os.py
|
@ -342,28 +342,23 @@ def execvpe(file, args, env):
|
|||
|
||||
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 @@ def _execvpe(file, args, env=None):
|
|||
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)
|
||||
|
||||
|
|
|
@ -407,6 +407,27 @@ def test___repr__(self):
|
|||
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()."""
|
||||
|
|
|
@ -701,6 +701,9 @@ Library
|
|||
|
||||
- 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
|
||||
-----------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue