diff options
Diffstat (limited to 'Lib/subprocess.py')
-rw-r--r-- | Lib/subprocess.py | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py index d8d6ab2..98f339e 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -372,9 +372,11 @@ class SubprocessError(Exception): pass class CalledProcessError(SubprocessError): - """This exception is raised when a process run by check_call() or - check_output() returns a non-zero exit status. - The exit status will be stored in the returncode attribute; + """Raised when a check_call() or check_output() process returns non-zero. + + The exit status will be stored in the returncode attribute, negative + if it represents a signal number. + check_output() will also store the output in the output attribute. """ def __init__(self, returncode, cmd, output=None, stderr=None): @@ -384,7 +386,16 @@ class CalledProcessError(SubprocessError): self.stderr = stderr def __str__(self): - return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode) + if self.returncode and self.returncode < 0: + try: + return "Command '%s' died with %r." % ( + self.cmd, signal.Signals(-self.returncode)) + except ValueError: + return "Command '%s' died with unknown signal %d." % ( + self.cmd, -self.returncode) + else: + return "Command '%s' returned non-zero exit status %d." % ( + self.cmd, self.returncode) @property def stdout(self): @@ -471,7 +482,8 @@ if _mswindows: __all__.extend(["CREATE_NEW_CONSOLE", "CREATE_NEW_PROCESS_GROUP", "STD_INPUT_HANDLE", "STD_OUTPUT_HANDLE", "STD_ERROR_HANDLE", "SW_HIDE", - "STARTF_USESTDHANDLES", "STARTF_USESHOWWINDOW"]) + "STARTF_USESTDHANDLES", "STARTF_USESHOWWINDOW", + "STARTUPINFO"]) class Handle(int): closed = False @@ -520,6 +532,16 @@ DEVNULL = -3 # but it's here so that it can be imported when Python is compiled without # threads. +def _optim_args_from_interpreter_flags(): + """Return a list of command-line arguments reproducing the current + optimization settings in sys.flags.""" + args = [] + value = sys.flags.optimize + if value > 0: + args.append('-' + 'O' * value) + return args + + def _args_from_interpreter_flags(): """Return a list of command-line arguments reproducing the current settings in sys.flags and sys.warnoptions.""" @@ -527,7 +549,6 @@ def _args_from_interpreter_flags(): 'debug': 'd', # 'inspect': 'i', # 'interactive': 'i', - 'optimize': 'O', 'dont_write_bytecode': 'B', 'no_user_site': 's', 'no_site': 'S', @@ -535,8 +556,9 @@ def _args_from_interpreter_flags(): 'verbose': 'v', 'bytes_warning': 'b', 'quiet': 'q', + # -O is handled in _optim_args_from_interpreter_flags() } - args = [] + args = _optim_args_from_interpreter_flags() for flag, opt in flag_opt_map.items(): v = getattr(sys.flags, flag) if v > 0: @@ -995,6 +1017,9 @@ class Popen(object): if not self._child_created: # We didn't get to successfully create a child process. return + if self.returncode is None: + warnings.warn("running subprocess %r" % self, ResourceWarning, + source=self) # In case the child hasn't been waited on, check if it's done. self._internal_poll(_deadstate=_maxsize) if self.returncode is None and _active is not None: @@ -1520,9 +1545,14 @@ class Popen(object): if errpipe_data: try: - os.waitpid(self.pid, 0) + pid, sts = os.waitpid(self.pid, 0) + if pid == self.pid: + self._handle_exitstatus(sts) + else: + self.returncode = sys.maxsize except ChildProcessError: pass + try: exception_name, hex_errno, err_msg = ( errpipe_data.split(b':', 2)) |