summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorÉric Araujo <merwok@netwok.org>2014-03-13 09:59:31 (GMT)
committerÉric Araujo <merwok@netwok.org>2014-03-13 09:59:31 (GMT)
commitf1e8c70cf0ba6082e9b35061c310d708d477556a (patch)
tree21129b346155d659cb9358c9d9d7ea5f5e48260d
parent39930c9ca0e8ad2e1465e7a31b4a400d6f34ccff (diff)
parent45fc8713bda1bfd6c0de3c6f493a4eeff52acbe3 (diff)
downloadcpython-f1e8c70cf0ba6082e9b35061c310d708d477556a.zip
cpython-f1e8c70cf0ba6082e9b35061c310d708d477556a.tar.gz
cpython-f1e8c70cf0ba6082e9b35061c310d708d477556a.tar.bz2
Merge 3.3 (#11599)
-rw-r--r--Doc/distutils/setupscript.rst9
-rw-r--r--Doc/install/index.rst3
-rw-r--r--Lib/distutils/spawn.py55
-rw-r--r--Misc/NEWS4
4 files changed, 52 insertions, 19 deletions
diff --git a/Doc/distutils/setupscript.rst b/Doc/distutils/setupscript.rst
index ee96302..fbe4290 100644
--- a/Doc/distutils/setupscript.rst
+++ b/Doc/distutils/setupscript.rst
@@ -685,6 +685,8 @@ include the following code fragment in your :file:`setup.py` before the
DistributionMetadata.download_url = None
+.. _debug-setup-script:
+
Debugging the setup script
==========================
@@ -700,7 +702,8 @@ installation is broken because they don't read all the way down to the bottom
and see that it's a permission problem.
On the other hand, this doesn't help the developer to find the cause of the
-failure. For this purpose, the DISTUTILS_DEBUG environment variable can be set
+failure. For this purpose, the :envvar:`DISTUTILS_DEBUG` environment variable can be set
to anything except an empty string, and distutils will now print detailed
-information what it is doing, and prints the full traceback in case an exception
-occurs.
+information about what it is doing, dump the full traceback when an exception
+occurs, and print the whole command line when an external program (like a C
+compiler) fails.
diff --git a/Doc/install/index.rst b/Doc/install/index.rst
index 779e923..0c9a9f2 100644
--- a/Doc/install/index.rst
+++ b/Doc/install/index.rst
@@ -58,7 +58,8 @@ new goodies to their toolbox. You don't need to know Python to read this
document; there will be some brief forays into using Python's interactive mode
to explore your installation, but that's it. If you're looking for information
on how to distribute your own Python modules so that others may use them, see
-the :ref:`distutils-index` manual.
+the :ref:`distutils-index` manual. :ref:`debug-setup-script` may also be of
+interest.
.. _inst-trivial-install:
diff --git a/Lib/distutils/spawn.py b/Lib/distutils/spawn.py
index b1c5a44..d9cf950 100644
--- a/Lib/distutils/spawn.py
+++ b/Lib/distutils/spawn.py
@@ -10,6 +10,7 @@ import sys
import os
from distutils.errors import DistutilsPlatformError, DistutilsExecError
+from distutils.debug import DEBUG
from distutils import log
def spawn(cmd, search_path=1, verbose=0, dry_run=0):
@@ -28,10 +29,15 @@ def spawn(cmd, search_path=1, verbose=0, dry_run=0):
Raise DistutilsExecError if running the program fails in any way; just
return on success.
"""
+ # cmd is documented as a list, but just in case some code passes a tuple
+ # in, protect our %-formatting code against horrible death
+ cmd = list(cmd)
if os.name == 'posix':
_spawn_posix(cmd, search_path, dry_run=dry_run)
elif os.name == 'nt':
_spawn_nt(cmd, search_path, dry_run=dry_run)
+ elif os.name == 'os2':
+ _spawn_os2(cmd, search_path, dry_run=dry_run)
else:
raise DistutilsPlatformError(
"don't know how to spawn programs on platform '%s'" % os.name)
@@ -65,12 +71,16 @@ def _spawn_nt(cmd, search_path=1, verbose=0, dry_run=0):
rc = os.spawnv(os.P_WAIT, executable, cmd)
except OSError as exc:
# this seems to happen when the command isn't found
+ if not DEBUG:
+ cmd = executable
raise DistutilsExecError(
- "command '%s' failed: %s" % (cmd[0], exc.args[-1]))
+ "command %r failed: %s" % (cmd, exc.args[-1]))
if rc != 0:
# and this reflects the command running but failing
+ if not DEBUG:
+ cmd = executable
raise DistutilsExecError(
- "command '%s' failed with exit status %d" % (cmd[0], rc))
+ "command %r failed with exit status %d" % (cmd, rc))
if sys.platform == 'darwin':
from distutils import sysconfig
@@ -81,8 +91,9 @@ def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0):
log.info(' '.join(cmd))
if dry_run:
return
+ executable = cmd[0]
exec_fn = search_path and os.execvp or os.execv
- exec_args = [cmd[0], cmd]
+ env = None
if sys.platform == 'darwin':
global _cfg_target, _cfg_target_split
if _cfg_target is None:
@@ -103,17 +114,23 @@ def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0):
env = dict(os.environ,
MACOSX_DEPLOYMENT_TARGET=cur_target)
exec_fn = search_path and os.execvpe or os.execve
- exec_args.append(env)
pid = os.fork()
if pid == 0: # in the child
try:
- exec_fn(*exec_args)
+ if env is None:
+ exec_fn(executable, cmd)
+ else:
+ exec_fn(executable, cmd, env)
except OSError as e:
- sys.stderr.write("unable to execute %s: %s\n"
- % (cmd[0], e.strerror))
+ if not DEBUG:
+ cmd = executable
+ sys.stderr.write("unable to execute %r: %s\n"
+ % (cmd, e.strerror))
os._exit(1)
- sys.stderr.write("unable to execute %s for unknown reasons" % cmd[0])
+ if not DEBUG:
+ cmd = executable
+ sys.stderr.write("unable to execute %r for unknown reasons" % cmd)
os._exit(1)
else: # in the parent
# Loop until the child either exits or is terminated by a signal
@@ -125,26 +142,34 @@ def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0):
import errno
if exc.errno == errno.EINTR:
continue
+ if not DEBUG:
+ cmd = executable
raise DistutilsExecError(
- "command '%s' failed: %s" % (cmd[0], exc.args[-1]))
+ "command %r failed: %s" % (cmd, exc.args[-1]))
if os.WIFSIGNALED(status):
+ if not DEBUG:
+ cmd = executable
raise DistutilsExecError(
- "command '%s' terminated by signal %d"
- % (cmd[0], os.WTERMSIG(status)))
+ "command %r terminated by signal %d"
+ % (cmd, os.WTERMSIG(status)))
elif os.WIFEXITED(status):
exit_status = os.WEXITSTATUS(status)
if exit_status == 0:
return # hey, it succeeded!
else:
+ if not DEBUG:
+ cmd = executable
raise DistutilsExecError(
- "command '%s' failed with exit status %d"
- % (cmd[0], exit_status))
+ "command %r failed with exit status %d"
+ % (cmd, exit_status))
elif os.WIFSTOPPED(status):
continue
else:
+ if not DEBUG:
+ cmd = executable
raise DistutilsExecError(
- "unknown error executing '%s': termination status %d"
- % (cmd[0], status))
+ "unknown error executing %r: termination status %d"
+ % (cmd, status))
def find_executable(executable, path=None):
"""Tries to find 'executable' in the directories listed in 'path'.
diff --git a/Misc/NEWS b/Misc/NEWS
index e69874f..35693c1 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -23,6 +23,10 @@ Library
- Issue #19157: Include the broadcast address in the usuable hosts for IPv6
in ipaddress.
+- Issue #11599: When an external command (e.g. compiler) fails, distutils now
+ prints out the whole command line (instead of just the command name) if the
+ environment variable DISTUTILS_DEBUG is set.
+
- Issue #4931: distutils should not produce unhelpful "error: None" messages
anymore. distutils.util.grok_environment_error is kept but doc-deprecated.