[Reproducible-commits] [diffoscope] 13/21: Propagate failure of commands feeding diff

Jérémy Bobbio lunar at moszumanska.debian.org
Mon Sep 21 17:39:27 UTC 2015


This is an automated email from the git hooks/post-receive script.

lunar pushed a commit to branch master
in repository diffoscope.

commit f2d751b0c498c929054c0d9978be11820bf4673d
Author: Jérémy Bobbio <lunar at debian.org>
Date:   Sat Sep 19 23:58:23 2015 +0200

    Propagate failure of commands feeding diff
    
    We now check the return code once we are done with a command feeding
    diff. In case of failure we raise an exception using CalledProcessError.
    
    CalledProcessError assumes it will get the raw output. So we now capture
    stderr in a BytesIO, make the attribute available, and only decode its content
    when required.
    
    If the command has received SIGTERM it's probably because we terminate commands
    that linger slightly too long after we are done reading the output. So we don't
    want to consider this an error.  Ideally we should wait a little longer for
    them to properly shut down. That will be easily doable in Python 3.3+.
---
 diffoscope/comparators/utils.py | 12 ++++++++----
 diffoscope/difference.py        |  5 ++++-
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/diffoscope/comparators/utils.py b/diffoscope/comparators/utils.py
index d339aed..1997b00 100644
--- a/diffoscope/comparators/utils.py
+++ b/diffoscope/comparators/utils.py
@@ -19,7 +19,7 @@
 
 from abc import ABCMeta, abstractmethod
 from contextlib import contextmanager
-from io import StringIO
+from io import BytesIO
 from itertools import starmap
 # The following would be shutil.which in Python 3.3
 import os
@@ -69,7 +69,7 @@ class Command(object):
         else:
             self._stdin_feeder = None
             self._process.stdin.close()
-        self._stderr = StringIO()
+        self._stderr = BytesIO()
         self._stderr_line_count = 0
         self._stderr_reader = Thread(target=self._read_stderr)
         self._stderr_reader.daemon = True
@@ -100,7 +100,7 @@ class Command(object):
         if self._stdin_feeder:
             self._stdin_feeder.join()
         self._stderr_reader.join()
-        self._process.wait()
+        return self._process.wait()
 
     MAX_STDERR_LINES = 50
 
@@ -115,7 +115,11 @@ class Command(object):
 
     @property
     def stderr_content(self):
-        return self._stderr.getvalue()
+        return self._stderr.getvalue().decode('utf-8', errors='replace')
+
+    @property
+    def stderr(self):
+        return self._stderr
 
     @property
     def stdout(self):
diff --git a/diffoscope/difference.py b/diffoscope/difference.py
index 18d5d27..640b31d 100644
--- a/diffoscope/difference.py
+++ b/diffoscope/difference.py
@@ -22,6 +22,7 @@ from io import StringIO
 import os
 import os.path
 import re
+import signal
 import subprocess
 import sys
 import traceback
@@ -246,7 +247,9 @@ def make_feeder_from_command(command):
         end_nl = make_feeder_from_file(command.stdout, command.filter)(out_file)
         if command.poll() is None:
             command.terminate()
-        command.wait()
+        returncode = command.wait()
+        if returncode not in (0, -signal.SIGTERM):
+            raise subprocess.CalledProcessError(returncode, command.cmdline(), output=command.stderr.getvalue())
         return end_nl
     return feeder
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git



More information about the Reproducible-commits mailing list