nmbug-status: Decode Popen output using the user's locale

Avoid:

  $ ./nmbug-status --list-views
  Traceback (most recent call last):
    File "./nmbug-status", line 47, in <module>
      'cat-file', 'blob', sha1+':status-config.json'],
  TypeError: can't concat bytes to str

by explicitly converting the byte-stream read from Popen into a
Unicode string.  On Python 2, this conversion is str -> unicode; on
Python 3 it is bytes -> str.

_ENCODING is derived from the user's locale (or system default) in an
attempt to match Git's output encoding.  It may be more robust to skip
the encoding/decoding by using a Python wrapper like pygit2 [1] for
Git access.  That's a fairly heavy dependency though, and using the
locale will probably work.

[1]: http://www.pygit2.org/
This commit is contained in:
W. Trevor King 2014-02-10 10:40:24 -08:00 committed by David Bremner
parent ee6b5c372f
commit fd29d3f4fb

View file

@ -8,8 +8,10 @@
from __future__ import print_function
import codecs
import datetime
import email.utils
import locale
import urllib
import json
import argparse
@ -17,6 +19,10 @@ import os
import sys
import subprocess
_ENCODING = locale.getpreferredencoding() or sys.getdefaultencoding()
# parse command line arguments
parser = argparse.ArgumentParser()
@ -37,15 +43,16 @@ else:
nmbhome = os.getenv('NMBGIT', os.path.expanduser('~/.nmbug'))
# read only the first line from the pipe
sha1 = subprocess.Popen(['git', '--git-dir', nmbhome,
'show-ref', '-s', 'config'],
stdout=subprocess.PIPE).stdout.readline()
sha1_bytes = subprocess.Popen(
['git', '--git-dir', nmbhome, 'show-ref', '-s', 'config'],
stdout=subprocess.PIPE).stdout.readline()
sha1 = sha1_bytes.decode(_ENCODING).rstrip()
sha1 = sha1.rstrip()
fp = subprocess.Popen(['git', '--git-dir', nmbhome,
'cat-file', 'blob', sha1+':status-config.json'],
stdout=subprocess.PIPE).stdout
fp_byte_stream = subprocess.Popen(
['git', '--git-dir', nmbhome, 'cat-file', 'blob',
sha1+':status-config.json'],
stdout=subprocess.PIPE).stdout
fp = codecs.getreader(encoding=_ENCODING)(stream=fp_byte_stream)
config = json.load(fp)