summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2012-10-10 18:10:44 (GMT)
committerBenjamin Peterson <benjamin@python.org>2012-10-10 18:10:44 (GMT)
commitb36a05094d16bfb86c1b113bcab769ca6dbeee7a (patch)
treeb137758b30fa94c2b3f4a5388b69128d159bdaf9 /Lib
parent00f86f2202ca7dc78604b387ae61e269b90f0079 (diff)
parentdb8570349e3a3d02e3fe4300232c3b1ecd9c8259 (diff)
downloadcpython-b36a05094d16bfb86c1b113bcab769ca6dbeee7a.zip
cpython-b36a05094d16bfb86c1b113bcab769ca6dbeee7a.tar.gz
cpython-b36a05094d16bfb86c1b113bcab769ca6dbeee7a.tar.bz2
merge heads
Diffstat (limited to 'Lib')
-rw-r--r--Lib/subprocess.py10
-rw-r--r--Lib/test/test_subprocess.py60
2 files changed, 57 insertions, 13 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 775db50..57cc1a4 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -1327,6 +1327,7 @@ class Popen(object):
if executable is None:
executable = args[0]
+ orig_executable = executable
# For transferring possible exec failure from child to parent.
# Data format: "exception name:hex errno:description"
@@ -1409,10 +1410,17 @@ class Popen(object):
err_msg = err_msg.decode(errors="surrogatepass")
if issubclass(child_exception_type, OSError) and hex_errno:
errno_num = int(hex_errno, 16)
+ child_exec_never_called = (err_msg == "noexec")
+ if child_exec_never_called:
+ err_msg = ""
if errno_num != 0:
err_msg = os.strerror(errno_num)
if errno_num == errno.ENOENT:
- err_msg += ': ' + repr(args[0])
+ if child_exec_never_called:
+ # The error must be from chdir(cwd).
+ err_msg += ': ' + repr(cwd)
+ else:
+ err_msg += ': ' + repr(orig_executable)
raise child_exception_type(errno_num, err_msg)
raise child_exception_type(err_msg)
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 07e2b4b..b260c81 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -200,13 +200,16 @@ class ProcessTestCase(BaseTestCase):
p.wait()
self.assertEqual(47, p.returncode)
- # TODO: make this test work on Linux.
- # This may be failing on Linux because of issue #7774.
- @unittest.skipIf(sys.platform not in ('win32', 'darwin'),
- "possible bug using executable argument on Linux")
def test_executable(self):
# Check that the executable argument works.
- self._assert_python(["doesnotexist", "-c"], executable=sys.executable)
+ #
+ # On Unix (non-Mac and non-Windows), Python looks at args[0] to
+ # determine where its standard library is, so we need the directory
+ # of args[0] to be valid for the Popen() call to Python to succeed.
+ # See also issue #16170 and issue #7774.
+ doesnotexist = os.path.join(os.path.dirname(sys.executable),
+ "doesnotexist")
+ self._assert_python([doesnotexist, "-c"], executable=sys.executable)
def test_executable_takes_precedence(self):
# Check that the executable argument takes precedence over args[0].
@@ -1035,24 +1038,30 @@ class _SuppressCoreFiles(object):
@unittest.skipIf(mswindows, "POSIX specific tests")
class POSIXProcessTestCase(BaseTestCase):
- def test_exceptions(self):
- nonexistent_dir = "/_this/pa.th/does/not/exist"
+ def setUp(self):
+ super().setUp()
+ self._nonexistent_dir = "/_this/pa.th/does/not/exist"
+
+ def _get_chdir_exception(self):
try:
- os.chdir(nonexistent_dir)
+ os.chdir(self._nonexistent_dir)
except OSError as e:
# This avoids hard coding the errno value or the OS perror()
# string and instead capture the exception that we want to see
# below for comparison.
desired_exception = e
- desired_exception.strerror += ': ' + repr(sys.executable)
+ desired_exception.strerror += ': ' + repr(self._nonexistent_dir)
else:
self.fail("chdir to nonexistant directory %s succeeded." %
- nonexistent_dir)
+ self._nonexistent_dir)
+ return desired_exception
- # Error in the child re-raised in the parent.
+ def test_exception_cwd(self):
+ """Test error in the child raised in the parent for a bad cwd."""
+ desired_exception = self._get_chdir_exception()
try:
p = subprocess.Popen([sys.executable, "-c", ""],
- cwd=nonexistent_dir)
+ cwd=self._nonexistent_dir)
except OSError as e:
# Test that the child process chdir failure actually makes
# it up to the parent process as the correct exception.
@@ -1061,6 +1070,33 @@ class POSIXProcessTestCase(BaseTestCase):
else:
self.fail("Expected OSError: %s" % desired_exception)
+ def test_exception_bad_executable(self):
+ """Test error in the child raised in the parent for a bad executable."""
+ desired_exception = self._get_chdir_exception()
+ try:
+ p = subprocess.Popen([sys.executable, "-c", ""],
+ executable=self._nonexistent_dir)
+ except OSError as e:
+ # Test that the child process exec failure actually makes
+ # it up to the parent process as the correct exception.
+ self.assertEqual(desired_exception.errno, e.errno)
+ self.assertEqual(desired_exception.strerror, e.strerror)
+ else:
+ self.fail("Expected OSError: %s" % desired_exception)
+
+ def test_exception_bad_args_0(self):
+ """Test error in the child raised in the parent for a bad args[0]."""
+ desired_exception = self._get_chdir_exception()
+ try:
+ p = subprocess.Popen([self._nonexistent_dir, "-c", ""])
+ except OSError as e:
+ # Test that the child process exec failure actually makes
+ # it up to the parent process as the correct exception.
+ self.assertEqual(desired_exception.errno, e.errno)
+ self.assertEqual(desired_exception.strerror, e.strerror)
+ else:
+ self.fail("Expected OSError: %s" % desired_exception)
+
def test_restore_signals(self):
# Code coverage for both values of restore_signals to make sure it
# at least does not blow up.