From 45709611085ba5f8c9670ce9877fed5031416fc5 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sat, 24 Jul 2010 13:52:44 -0700 Subject: Handle UnicodeDecodeError from subprocess.getstatusoutput() calls, reported with python3.1. --- bin/dispatch-conf | 26 +++++++++++--------------- pym/portage/dispatch_conf.py | 21 ++++++++++++++++++--- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/bin/dispatch-conf b/bin/dispatch-conf index 43fe145ae..fc9cdd513 100755 --- a/bin/dispatch-conf +++ b/bin/dispatch-conf @@ -19,12 +19,7 @@ if not hasattr(__builtins__, "set"): from stat import * from random import * import atexit, re, shutil, stat, sys -try: - from subprocess import getoutput as subprocess_getoutput - from subprocess import getstatusoutput as subprocess_getstatusoutput -except ImportError: - from commands import getoutput as subprocess_getoutput - from commands import getstatusoutput as subprocess_getstatusoutput + try: import portage except ImportError: @@ -35,6 +30,7 @@ except ImportError: from portage import os from portage import dispatch_conf from portage import _unicode_decode +from portage.dispatch_conf import diffstatusoutput_len from portage.process import find_binary FIND_EXTANT_CONFIGS = "find '%s' %s -name '._cfg????_%s' ! -name '.*~' ! -iname '.*.bak' -print" @@ -137,11 +133,11 @@ class dispatch: else: mrgfail = portage.dispatch_conf.file_archive(archive, conf['current'], conf['new'], mrgconf) if os.path.exists(archive + '.dist'): - unmodified = len(subprocess_getoutput(DIFF_CONTENTS % (conf['current'], archive + '.dist'))) == 0 + unmodified = diffstatusoutput_len(DIFF_CONTENTS % (conf['current'], archive + '.dist'))[1] == 0 else: unmodified = 0 if os.path.exists(mrgconf): - if mrgfail or len(subprocess_getoutput(DIFF_CONTENTS % (conf['new'], mrgconf))) == 0: + if mrgfail or diffstatusoutput_len(DIFF_CONTENTS % (conf['new'], mrgconf))[1] == 0: os.unlink(mrgconf) newconf = conf['new'] else: @@ -152,24 +148,24 @@ class dispatch: if newconf == mrgconf and \ self.options.get('ignore-previously-merged') != 'yes' and \ os.path.exists(archive+'.dist') and \ - len(subprocess_getoutput(DIFF_CONTENTS % (archive+'.dist', conf['new']))) == 0: + diffstatusoutput_len(DIFF_CONTENTS % (archive+'.dist', conf['new']))[1] == 0: # The current update is identical to the archived .dist # version that has previously been merged. os.unlink(mrgconf) newconf = conf['new'] - mystatus, myoutput = subprocess_getstatusoutput( + mystatus, myoutput_len = diffstatusoutput_len( DIFF_CONTENTS % (conf ['current'], newconf)) - same_file = 0 == len(myoutput) + same_file = 0 == myoutput_len if mystatus >> 8 == 2: # Binary files differ same_cvs = False same_wsc = False else: - same_cvs = 0 == len(subprocess_getoutput( - DIFF_CVS_INTERP % (conf ['current'], newconf))) - same_wsc = 0 == len(subprocess_getoutput( - DIFF_WSCOMMENTS % (conf ['current'], newconf))) + same_cvs = 0 == diffstatusoutput_len( + DIFF_CVS_INTERP % (conf ['current'], newconf))[1] + same_wsc = 0 == diffstatusoutput_len( + DIFF_WSCOMMENTS % (conf ['current'], newconf))[1] # Do options permit? same_cvs = same_cvs and self.options['replace-cvs'] == 'yes' diff --git a/pym/portage/dispatch_conf.py b/pym/portage/dispatch_conf.py index 956f52373..b4cded266 100644 --- a/pym/portage/dispatch_conf.py +++ b/pym/portage/dispatch_conf.py @@ -10,9 +10,9 @@ from __future__ import print_function import os, sys, shutil try: - from subprocess import getoutput as subprocess_getoutput + from subprocess import getstatusoutput as subprocess_getstatusoutput except ImportError: - from commands import getoutput as subprocess_getoutput + from commands import getstatusoutput as subprocess_getstatusoutput import portage from portage.localization import _ @@ -25,6 +25,21 @@ RCS_MERGE = "rcsmerge -p -r" + RCS_BRANCH + " '%s' > '%s'" DIFF3_MERGE = "diff3 -mE '%s' '%s' '%s' > '%s'" +def diffstatusoutput_len(cmd): + """ + Execute the string cmd in a shell with getstatusoutput() and return a + 2-tuple (status, output_length). If getstatusoutput() raises + UnicodeDecodeError (known to happen with python3.1), return a + 2-tuple (1, 1). This provides a simple way to check for non-zero + output length of diff commands, while providing simple handling of + UnicodeDecodeError when necessary. + """ + try: + status, output = subprocess_getstatusoutput(cmd) + return (status, len(output)) + except UnicodeDecodeError: + return (1, 1) + def read_config(mandatory_opts): loader = portage.env.loaders.KeyValuePairFileLoader( '/etc/dispatch-conf.conf', None) @@ -115,7 +130,7 @@ def file_archive(archive, curconf, newconf, mrgconf): # Archive the current config file if it isn't already saved if os.path.exists(archive) \ - and len(subprocess_getoutput("diff -aq '%s' '%s'" % (curconf,archive))) != 0: + and diffstatusoutput_len("diff -aq '%s' '%s'" % (curconf,archive))[1] != 0: suf = 1 while suf < 9 and os.path.exists(archive + '.' + str(suf)): suf += 1 -- cgit v1.2.3-1-g7c22