Bug#906967: diffoscope fails on dumb terminals with 'bytes' object has no attribute 'format'

Daniel Kahn Gillmor dkg at fifthhorseman.net
Wed Aug 22 19:53:11 BST 2018


Package: diffoscope
Version: 99
Severity: normal
Tags: patch

The new eraser bar seems to break things when diffoscope is run on a
dumb terminal (or other similar weird environments, such as an emacs
M-x shell buffer).

The attached patches also clean up the spelling of "eraser" :)

    --dkg

-- System Information:
Debian Release: buster/sid
  APT prefers testing-debug
  APT policy: (500, 'testing-debug'), (500, 'testing'), (500, 'oldstable'), (200, 'unstable-debug'), (200, 'unstable'), (1, 'experimental-debug'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.16.0-2-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages diffoscope depends on:
ii  libpython3.6-stdlib    3.6.6-1
ii  python3                3.6.5-3
ii  python3-distro         1.0.1-2
ii  python3-distutils      3.6.6-1
ii  python3-libarchive-c   2.1-3.1
ii  python3-magic          2:0.4.15-2
ii  python3-pkg-resources  39.2.0-1

Versions of packages diffoscope recommends:
pn  abootimg                         <none>
ii  acl                              2.2.52-3+b1
pn  apktool                          <none>
pn  binutils-multiarch               <none>
ii  bzip2                            1.0.6-9
ii  caca-utils                       0.99.beta19-2+b3
pn  colord                           <none>
ii  db-util                          5.3.1
ii  default-jdk [java-sdk]           2:1.10-68
ii  default-jdk-headless             2:1.10-68
pn  device-tree-compiler             <none>
pn  docx2txt                         <none>
ii  e2fsprogs                        1.44.3-1
pn  enjarify                         <none>
ii  fontforge-extras                 0.3-4
pn  fp-utils                         <none>
ii  genisoimage                      9:1.1.11-3+b2
ii  gettext                          0.19.8.1-7
ii  ghc                              8.2.2-4
ii  ghostscript                      9.22~dfsg-2.1
pn  giflib-tools                     <none>
ii  gnumeric                         1.12.41-1
ii  gnupg                            2.2.9-1
ii  imagemagick                      8:6.9.10.8+dfsg-1
ii  imagemagick-6.q16 [imagemagick]  8:6.9.10.8+dfsg-1
pn  jsbeautifier                     <none>
pn  libarchive-tools                 <none>
pn  llvm                             <none>
pn  lz4                              <none>
ii  mono-utils                       4.6.2.7+dfsg-1
ii  odt2txt                          0.5-1+b2
ii  oggvideotools                    0.9.1-4
ii  openjdk-10-jdk [java-sdk]        10.0.2+13-1
ii  openssh-client                   1:7.7p1-4
ii  pgpdump                          0.33-1
ii  poppler-utils                    0.63.0-2
pn  procyon-decompiler               <none>
pn  python3-argcomplete              <none>
pn  python3-binwalk                  <none>
ii  python3-debian                   0.1.33
pn  python3-defusedxml               <none>
pn  python3-guestfs                  <none>
pn  python3-jsondiff                 <none>
ii  python3-progressbar              2.3-4
ii  python3-pyxattr                  0.6.0-2+b2
ii  python3-tlsh                     3.4.4+20151206-1+b4
ii  r-base-core                      3.5.1-1+b1
ii  rpm2cpio                         4.14.1+dfsg1-4
ii  sng                              1.1.0-1+b1
ii  sqlite3                          3.24.0-1
pn  squashfs-tools                   <none>
ii  tcpdump                          4.9.2-3
ii  unzip                            6.0-21
ii  vim-common                       2:8.1.0229-1
pn  xmlbeans                         <none>
ii  xxd                              2:8.1.0229-1
ii  xz-utils                         5.2.2-1.3

Versions of packages diffoscope suggests:
ii  libjs-jquery  3.2.1-1

-- no debconf information
-------------- next part --------------
>From 4e55793aa550e3e3d9fe84f41967c72689a4ca45 Mon Sep 17 00:00:00 2001
From: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
Date: Wed, 22 Aug 2018 14:31:03 -0400
Subject: [PATCH 1/2] correct spelling of ereser to eraser

---
 diffoscope/comparators/__init__.py |  4 ++--
 diffoscope/logging.py              | 14 +++++++-------
 diffoscope/main.py                 |  4 ++--
 diffoscope/progress.py             |  4 ++--
 4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/diffoscope/comparators/__init__.py b/diffoscope/comparators/__init__.py
index 9098006..e885ccb 100644
--- a/diffoscope/comparators/__init__.py
+++ b/diffoscope/comparators/__init__.py
@@ -24,7 +24,7 @@ import logging
 import importlib
 import traceback
 
-from ..logging import line_ereser
+from ..logging import line_eraser
 
 
 logger = logging.getLogger(__name__)
@@ -134,7 +134,7 @@ class ComparatorManager(object):
                 ))
                 for x in errors:
                     logger.error("Original error for %s:", x[0])
-                    sys.stderr.buffer.write(line_ereser())
+                    sys.stderr.buffer.write(line_eraser())
                     traceback.print_exception(None, x[1], x[1].__traceback__)
                 sys.exit(2)
 
diff --git a/diffoscope/logging.py b/diffoscope/logging.py
index 9cf4f1a..013fd3e 100644
--- a/diffoscope/logging.py
+++ b/diffoscope/logging.py
@@ -22,20 +22,20 @@ import contextlib
 import logging
 
 
-def line_ereser(fd=sys.stderr) -> bytes:
-    ereser = b''  # avoid None to avoid 'NoneType + str/bytes' failures
+def line_eraser(fd=sys.stderr) -> bytes:
+    eraser = b''  # avoid None to avoid 'NoneType + str/bytes' failures
     if fd.isatty():
         from curses import tigetstr, setupterm
         setupterm(fd=fd.fileno())
-        ereser = tigetstr('el')
+        eraser = tigetstr('el')
 
-    if not ereser and fd.isatty():
+    if not eraser and fd.isatty():
         # is a tty, but doesn't support the proper scape code, so let's fake it
         from shutil import get_terminal_size
         width = get_terminal_size().columns
-        ereser = b'\r{}\r'.format(b' ' * width)
+        eraser = b'\r{}\r'.format(b' ' * width)
 
-    return ereser
+    return eraser
 
 
 @contextlib.contextmanager
@@ -49,7 +49,7 @@ def setup_logging(debug, log_handler):
     logger.addHandler(ch)
 
     formatter = logging.Formatter(
-        line_ereser().decode('ascii') +
+        line_eraser().decode('ascii') +
         '%(asctime)s %(levelname).1s: %(name)s: %(message)s',
         '%Y-%m-%d %H:%M:%S',
     )
diff --git a/diffoscope/main.py b/diffoscope/main.py
index 36e79a5..41e41a8 100644
--- a/diffoscope/main.py
+++ b/diffoscope/main.py
@@ -33,7 +33,7 @@ from .path import set_path
 from .tools import tool_prepend_prefix, tool_required, OS_NAMES, get_current_os
 from .config import Config
 from .locale import set_locale
-from .logging import line_ereser, setup_logging
+from .logging import line_eraser, setup_logging
 from .progress import ProgressManager, Progress
 from .profiling import ProfileManager, profile
 from .tempfiles import clean_all_temp_files
@@ -464,7 +464,7 @@ def main(args=None):
     except BrokenPipeError:
         sys.exit(2)
     except Exception:
-        sys.stderr.buffer.write(line_ereser())
+        sys.stderr.buffer.write(line_eraser())
         traceback.print_exc()
         if parsed_args and parsed_args.debugger:
             import pdb
diff --git a/diffoscope/progress.py b/diffoscope/progress.py
index dc26db6..ac71406 100644
--- a/diffoscope/progress.py
+++ b/diffoscope/progress.py
@@ -24,7 +24,7 @@ import json
 import signal
 import logging
 
-from .logging import line_ereser
+from .logging import line_eraser
 
 
 logger = logging.getLogger(__name__)
@@ -218,7 +218,7 @@ class ProgressBar(object):
                 kwargs.setdefault('fd', sys.stderr)
                 super().__init__(*args, **kwargs)
                 # Terminal handling after parent init since that sets self.fd
-                self.erase_to_eol = line_ereser(self.fd)
+                self.erase_to_eol = line_eraser(self.fd)
 
             def _need_update(self):
                 return True
-- 
2.18.0

-------------- next part --------------
>From b78e50d3e22b74b4fc563c852aa0b8a02d599f33 Mon Sep 17 00:00:00 2001
From: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
Date: Wed, 22 Aug 2018 14:43:13 -0400
Subject: [PATCH 2/2] avoid error on dumb terminals

Try the following:

    touch a b
    TERM=dumb diffoscope a b

The result is some nasty warnings about:

    AttributeError: 'bytes' object has no attribute 'format'

This patch fixes the problem.
---
 diffoscope/logging.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/diffoscope/logging.py b/diffoscope/logging.py
index 013fd3e..478131d 100644
--- a/diffoscope/logging.py
+++ b/diffoscope/logging.py
@@ -30,10 +30,10 @@ def line_eraser(fd=sys.stderr) -> bytes:
         eraser = tigetstr('el')
 
     if not eraser and fd.isatty():
-        # is a tty, but doesn't support the proper scape code, so let's fake it
+        # is a tty, but doesn't support the proper escape code, so let's fake it
         from shutil import get_terminal_size
         width = get_terminal_size().columns
-        eraser = b'\r{}\r'.format(b' ' * width)
+        eraser = b'\r' + (b' ' * width) + b'\r'
 
     return eraser
 
-- 
2.18.0



More information about the Reproducible-builds mailing list