Further Python 3 porting

Thanks to Alberto Planas Dominguez <aplanas@suse.com> for sanity
checks and suggestions.
This commit is contained in:
Ville Skyttä 2014-02-27 22:08:30 +02:00
parent 34ca3ba54f
commit d5835d4300
10 changed files with 78 additions and 72 deletions

View File

@ -178,7 +178,7 @@ class BinaryInfo:
try: try:
fobj = open(path, 'rb') fobj = open(path, 'rb')
fobj.seek(-12, 2) # 2 == os.SEEK_END, for python 2.4 compat (#172) fobj.seek(-12, 2) # 2 == os.SEEK_END, for python 2.4 compat (#172)
self.tail = fobj.read().decode() self.tail = Pkg.b2s(fobj.read())
except Exception: except Exception:
e = sys.exc_info()[1] e = sys.exc_info()[1]
printWarning(pkg, 'binaryinfo-tail-failed %s: %s' % (file, e)) printWarning(pkg, 'binaryinfo-tail-failed %s: %s' % (file, e))
@ -274,7 +274,7 @@ class BinariesCheck(AbstractCheck.AbstractCheck):
multi_pkg = False multi_pkg = False
srpm = pkg[rpm.RPMTAG_SOURCERPM] srpm = pkg[rpm.RPMTAG_SOURCERPM]
if srpm: if srpm:
res = srcname_regex.search(srpm.decode()) res = srcname_regex.search(Pkg.b2s(srpm))
if res: if res:
multi_pkg = (pkg.name != res.group(1)) multi_pkg = (pkg.name != res.group(1))

View File

@ -17,6 +17,7 @@
import rpm import rpm
from Filter import addDetails, printWarning from Filter import addDetails, printWarning
from Pkg import b2s
import AbstractCheck import AbstractCheck
@ -44,7 +45,7 @@ class DocFilesCheck(AbstractCheck.AbstractCheck):
# register things which are provided by the package # register things which are provided by the package
for i in pkg.header[rpm.RPMTAG_PROVIDES]: for i in pkg.header[rpm.RPMTAG_PROVIDES]:
core_reqs[i.decode()] = [] core_reqs[b2s(i)] = []
for i in files: for i in files:
core_reqs[i] = [] core_reqs[i] = []

View File

@ -12,13 +12,12 @@ from datetime import datetime
import os import os
import re import re
import stat import stat
import string
import sys import sys
import rpm import rpm
from Filter import addDetails, printError, printWarning from Filter import addDetails, printError, printWarning
from Pkg import catcmd, getstatusoutput, is_utf8, is_utf8_str from Pkg import b2s, catcmd, getstatusoutput, is_utf8, is_utf8_str
import AbstractCheck import AbstractCheck
import Config import Config
@ -211,7 +210,7 @@ lib_path_regex = re.compile('^(/usr(/X11R6)?)?/lib(64)?')
lib_package_regex = re.compile('^(lib|.+-libs)') lib_package_regex = re.compile('^(lib|.+-libs)')
hidden_file_regex = re.compile('/\.[^/]*$') hidden_file_regex = re.compile('/\.[^/]*$')
manifest_perl_regex = re.compile('^/usr/share/doc/perl-.*/MANIFEST(\.SKIP)?$') manifest_perl_regex = re.compile('^/usr/share/doc/perl-.*/MANIFEST(\.SKIP)?$')
shebang_regex = re.compile('^#!\s*(\S+)') shebang_regex = re.compile(b'^#!\s*(\S+)')
interpreter_regex = re.compile('^/(usr/)?(s?bin|games|libexec(/.+)?|(lib(64)?|share)/.+)/[^/]+$') interpreter_regex = re.compile('^/(usr/)?(s?bin|games|libexec(/.+)?|(lib(64)?|share)/.+)/[^/]+$')
script_regex = re.compile('^/((usr/)?s?bin|etc/(rc\.d/init\.d|X11/xinit\.d|cron\.(hourly|daily|monthly|weekly)))/') script_regex = re.compile('^/((usr/)?s?bin|etc/(rc\.d/init\.d|X11/xinit\.d|cron\.(hourly|daily|monthly|weekly)))/')
sourced_script_regex = re.compile('^/etc/(bash_completion\.d|profile\.d)/') sourced_script_regex = re.compile('^/etc/(bash_completion\.d|profile\.d)/')
@ -246,15 +245,21 @@ man_nowarn_regex = re.compile(
r'(can\'t break|cannot adjust) line') r'(can\'t break|cannot adjust) line')
man_warn_category = Config.getOption('ManWarningCategory', 'mac') man_warn_category = Config.getOption('ManWarningCategory', 'mac')
fsf_license_regex = re.compile('(GNU((\s+(Library|Lesser|Affero))?(\s+General)?\s+Public|\s+Free\s+Documentation)\s+Licen[cs]e|(GP|FD)L)', re.IGNORECASE) fsf_license_regex = re.compile(b'(GNU((\s+(Library|Lesser|Affero))?(\s+General)?\s+Public|\s+Free\s+Documentation)\s+Licen[cs]e|(GP|FD)L)', re.IGNORECASE)
fsf_wrong_address_regex = re.compile('(675\s+Mass\s+Ave|59\s+Temple\s+Place|Franklin\s+Steet|02139|02111-1307)', re.IGNORECASE) fsf_wrong_address_regex = re.compile(b'(675\s+Mass\s+Ave|59\s+Temple\s+Place|Franklin\s+Steet|02139|02111-1307)', re.IGNORECASE)
scalable_icon_regex = re.compile(r'^/usr(?:/local)?/share/icons/.*/scalable/') scalable_icon_regex = re.compile(r'^/usr(?:/local)?/share/icons/.*/scalable/')
# loosely inspired from Python Cookbook # "is binary" stuff borrowed from https://pypi.python.org/pypi/binaryornot
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/173220 # TODO: switch to it sometime later instead of embedding our own copy
text_characters = "".join(map(chr, range(32, 127))) + "\n\r\t\b"
_null_trans = string.maketrans("", "") printable_extended_ascii = b'\n\r\t\f\b'
if bytes is str:
# Python 2 means we need to invoke chr() explicitly
printable_extended_ascii += b''.join(map(chr, range(32, 256)))
else:
# Python 3 means bytes accepts integer input directly
printable_extended_ascii += bytes(range(32, 256))
def peek(filename, pkg, length=1024): def peek(filename, pkg, length=1024):
"""Peek into a file, return a chunk from its beginning and a flag if it """Peek into a file, return a chunk from its beginning and a flag if it
@ -272,7 +277,7 @@ def peek(filename, pkg, length=1024):
fobj.close() fobj.close()
return (chunk, False) return (chunk, False)
if "\0" in chunk: if b'\0' in chunk:
return (chunk, False) return (chunk, False)
if not chunk: # Empty files are considered text if not chunk: # Empty files are considered text
@ -281,18 +286,17 @@ def peek(filename, pkg, length=1024):
fl = filename.lower() fl = filename.lower()
# PDF's are binary but often detected as text by the algorithm below # PDF's are binary but often detected as text by the algorithm below
if fl.endswith('.pdf') and chunk.startswith('%PDF-'): if fl.endswith('.pdf') and chunk.startswith(b'%PDF-'):
return (chunk, False) return (chunk, False)
# Ditto RDoc RI files # Ditto RDoc RI files
if fl.endswith('.ri') and '/ri/' in fl: if fl.endswith('.ri') and '/ri/' in fl:
return (chunk, False) return (chunk, False)
# Get the non-text characters (maps a character to itself then # Binary if control chars are > 30% of the string
# use the 'remove' option to get rid of the text characters.) control_chars = chunk.translate(None, printable_extended_ascii)
t = chunk.translate(_null_trans, text_characters) nontext_ratio = float(len(control_chars)) / float(len(chunk))
istext = nontext_ratio <= 0.30
# If more than 30% non-text characters, then consider it a binary file
istext = float(len(t))/len(chunk) <= 0.30
return (chunk, istext) return (chunk, istext)
# See Python sources for a full list of the values here. # See Python sources for a full list of the values here.
@ -523,12 +527,12 @@ class FilesCheck(AbstractCheck.AbstractCheck):
oct(perm)) oct(perm))
# Prefetch scriptlets, strip quotes from them (#169) # Prefetch scriptlets, strip quotes from them (#169)
postin = (pkg[rpm.RPMTAG_POSTIN] or \ postin = b2s(pkg[rpm.RPMTAG_POSTIN]) or \
pkg.scriptprog(rpm.RPMTAG_POSTINPROG)).decode() pkg.scriptprog(rpm.RPMTAG_POSTINPROG)
if postin: if postin:
postin = quotes_regex.sub('', postin) postin = quotes_regex.sub('', postin)
postun = (pkg[rpm.RPMTAG_POSTUN] or \ postun = b2s(pkg[rpm.RPMTAG_POSTUN]) or \
pkg.scriptprog(rpm.RPMTAG_POSTUNPROG)).decode() pkg.scriptprog(rpm.RPMTAG_POSTUNPROG)
if postun: if postun:
postun = quotes_regex.sub('', postun) postun = quotes_regex.sub('', postun)
@ -556,7 +560,7 @@ class FilesCheck(AbstractCheck.AbstractCheck):
if chunk: if chunk:
res = shebang_regex.search(chunk) res = shebang_regex.search(chunk)
if res: if res:
interpreter = res.group(1) interpreter = b2s(res.group(1))
if doc_regex.search(f): if doc_regex.search(f):
if not interpreter: if not interpreter:
@ -608,8 +612,8 @@ class FilesCheck(AbstractCheck.AbstractCheck):
elif not install_info_regex.search(postin): elif not install_info_regex.search(postin):
printError(pkg, 'postin-without-install-info', f) printError(pkg, 'postin-without-install-info', f)
preun = pkg[rpm.RPMTAG_PREUN] or \ preun = b2s(pkg[rpm.RPMTAG_PREUN]) or \
pkg.scriptprog(rpm.RPMTAG_PREUNPROG) pkg.scriptprog(rpm.RPMTAG_PREUNPROG)
if not postun and not preun: if not postun and not preun:
printError(pkg, printError(pkg,
'info-files-without-install-info-postun', f) 'info-files-without-install-info-postun', f)
@ -815,11 +819,11 @@ class FilesCheck(AbstractCheck.AbstractCheck):
if not mode_is_exec and not is_doc: if not mode_is_exec and not is_doc:
printError(pkg, 'non-executable-script', f, printError(pkg, 'non-executable-script', f,
oct(perm), interpreter) oct(perm), interpreter)
if '\r' in chunk: if b'\r' in chunk:
printError( printError(
pkg, 'wrong-script-end-of-line-encoding', f) pkg, 'wrong-script-end-of-line-encoding', f)
elif is_doc and not skipdocs_regex.search(f): elif is_doc and not skipdocs_regex.search(f):
if '\r' in chunk: if b'\r' in chunk:
printWarning( printWarning(
pkg, 'wrong-file-end-of-line-encoding', f) pkg, 'wrong-file-end-of-line-encoding', f)
# We check only doc text files for UTF-8-ness; # We check only doc text files for UTF-8-ness;

View File

@ -1,6 +1,6 @@
You need the following utilities to run rpmlint: You need the following utilities to run rpmlint:
o python 2.x (x >= 4) o python 2.x (x >= 6)
o rpm 4.4.2.2 or newer and its python bindings o rpm 4.4.2.2 or newer and its python bindings
o libmagic and its python bindings (optional) o libmagic and its python bindings (optional)
o readelf o readelf
@ -13,6 +13,6 @@ You need the following utilities to run rpmlint:
and the following programs to install it: and the following programs to install it:
o python 2.x (x >= 4) o python 2.x (x >= 6)
o rpm python bindings 4.4 or newer o rpm python bindings 4.4 or newer
o sed o sed

View File

@ -62,15 +62,15 @@ class InitScriptCheck(AbstractCheck.AbstractCheck):
printError(pkg, 'init-script-name-with-dot', fname) printError(pkg, 'init-script-name-with-dot', fname)
# check chkconfig call in %post and %preun # check chkconfig call in %post and %preun
postin = pkg[rpm.RPMTAG_POSTIN] or \ postin = Pkg.b2s(pkg[rpm.RPMTAG_POSTIN]) or \
pkg.scriptprog(rpm.RPMTAG_POSTINPROG) pkg.scriptprog(rpm.RPMTAG_POSTINPROG)
if not postin: if not postin:
printError(pkg, 'init-script-without-chkconfig-postin', fname) printError(pkg, 'init-script-without-chkconfig-postin', fname)
elif not chkconfig_regex.search(postin): elif not chkconfig_regex.search(postin):
printError(pkg, 'postin-without-chkconfig', fname) printError(pkg, 'postin-without-chkconfig', fname)
preun = pkg[rpm.RPMTAG_PREUN] or \ preun = Pkg.b2s(pkg[rpm.RPMTAG_PREUN]) or \
pkg.scriptprog(rpm.RPMTAG_PREUNPROG) pkg.scriptprog(rpm.RPMTAG_PREUNPROG)
if not preun: if not preun:
printError(pkg, 'init-script-without-chkconfig-preun', fname) printError(pkg, 'init-script-without-chkconfig-preun', fname)
elif not chkconfig_regex.search(preun): elif not chkconfig_regex.search(preun):

View File

@ -13,6 +13,7 @@ import re
import rpm import rpm
from Filter import addDetails, printError from Filter import addDetails, printError
from Pkg import b2s
import AbstractCheck import AbstractCheck
@ -31,15 +32,11 @@ class LSBCheck(AbstractCheck.AbstractCheck):
printError(pkg, 'non-lsb-compliant-package-name', name) printError(pkg, 'non-lsb-compliant-package-name', name)
version = pkg[rpm.RPMTAG_VERSION] version = pkg[rpm.RPMTAG_VERSION]
if version: if version and not version_regex.search(version):
version = version.decode()
if not version_regex.search(version):
printError(pkg, 'non-lsb-compliant-version', version) printError(pkg, 'non-lsb-compliant-version', version)
release = pkg[rpm.RPMTAG_RELEASE] release = pkg[rpm.RPMTAG_RELEASE]
if release: if release and not version_regex.search(release):
release = release.decode()
if not version_regex.search(release):
printError(pkg, 'non-lsb-compliant-release', release) printError(pkg, 'non-lsb-compliant-release', release)
# Create an object to enable the auto registration of the test # Create an object to enable the auto registration of the test

View File

@ -199,15 +199,15 @@ class MenuCheck(AbstractCheck.AbstractCheck):
printError(pkg, 'menu-in-wrong-dir', fname) printError(pkg, 'menu-in-wrong-dir', fname)
if menus: if menus:
postin = pkg[rpm.RPMTAG_POSTIN] or \ postin = Pkg.b2s(pkg[rpm.RPMTAG_POSTIN]) or \
pkg.scriptprog(rpm.RPMTAG_POSTINPROG) pkg.scriptprog(rpm.RPMTAG_POSTINPROG)
if not postin: if not postin:
printError(pkg, 'menu-without-postin') printError(pkg, 'menu-without-postin')
elif not update_menus_regex.search(postin): elif not update_menus_regex.search(postin):
printError(pkg, 'postin-without-update-menus') printError(pkg, 'postin-without-update-menus')
postun = pkg[rpm.RPMTAG_POSTUN] or \ postun = Pkg.b2s(pkg[rpm.RPMTAG_POSTUN]) or \
pkg.scriptprog(rpm.RPMTAG_POSTUNPROG) pkg.scriptprog(rpm.RPMTAG_POSTUNPROG)
if not postun: if not postun:
printError(pkg, 'menu-without-postun') printError(pkg, 'menu-without-postun')
elif not update_menus_regex.search(postun): elif not update_menus_regex.search(postun):

39
Pkg.py
View File

@ -29,14 +29,21 @@ import rpm
import Filter import Filter
# Python 2/3 compatibility/convenience wrapper for printing to stderr with # warn(): 2/3 compatibility/convenience wrapper for printing to stderr with
# less concerns of UnicodeErrors than plain sys.stderr.write. # less concerns of UnicodeErrors than plain sys.stderr.write.
# b2s(): bytes to str
if sys.version_info[0] > 2: if sys.version_info[0] > 2:
# Blows up with Python < 3 without the exec() hack # Blows up with Python < 3 without the exec() hack
exec('def warn(s): print (s, file=sys.stderr)') exec('def warn(s): print (s, file=sys.stderr)')
long = int long = int
def b2s(b):
if b is None:
return None
return b.decode()
else: else:
def warn(s): print >> sys.stderr, s def warn(s): print >> sys.stderr, s
def b2s(b):
return b
# utilities # utilities
@ -86,7 +93,7 @@ def getstatusoutput(cmd, stdoutonly = False, shell = False):
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, close_fds=True) stderr=subprocess.STDOUT, close_fds=True)
proc.stdin.close() proc.stdin.close()
text = proc.stdout.read().decode() text = b2s(proc.stdout.read())
sts = proc.wait() sts = proc.wait()
if sts is None: if sts is None:
sts = 0 sts = 0
@ -445,7 +452,7 @@ class Pkg:
os.close(fd) os.close(fd)
self.is_source = not self.header[rpm.RPMTAG_SOURCERPM] self.is_source = not self.header[rpm.RPMTAG_SOURCERPM]
self.name = self.header[rpm.RPMTAG_NAME].decode() self.name = b2s(self.header[rpm.RPMTAG_NAME])
if self.isNoSource(): if self.isNoSource():
self.arch = 'nosrc' self.arch = 'nosrc'
elif self.isSource(): elif self.isSource():
@ -471,6 +478,8 @@ class Pkg:
if val == []: if val == []:
return None return None
else: else:
if key in (rpm.RPMTAG_VERSION, rpm.RPMTAG_RELEASE, rpm.RPMTAG_ARCH):
val = b2s(val)
return val return val
# return the name of the directory where the package is extracted # return the name of the directory where the package is extracted
@ -531,7 +540,7 @@ class Pkg:
# LANGUAGE trumps other env vars per GNU gettext docs, see also #166 # LANGUAGE trumps other env vars per GNU gettext docs, see also #166
orig = os.environ.get('LANGUAGE') orig = os.environ.get('LANGUAGE')
os.environ['LANGUAGE'] = lang os.environ['LANGUAGE'] = lang
ret = self[tag].decode() ret = b2s(self[tag])
if orig is not None: if orig is not None:
os.environ['LANGUAGE'] = orig os.environ['LANGUAGE'] = orig
return ret return ret
@ -596,17 +605,17 @@ class Pkg:
modes = self.header[rpm.RPMTAG_FILEMODES] modes = self.header[rpm.RPMTAG_FILEMODES]
users = self.header[rpm.RPMTAG_FILEUSERNAME] users = self.header[rpm.RPMTAG_FILEUSERNAME]
groups = self.header[rpm.RPMTAG_FILEGROUPNAME] groups = self.header[rpm.RPMTAG_FILEGROUPNAME]
links = [x.decode() for x in self.header[rpm.RPMTAG_FILELINKTOS]] links = [b2s(x) for x in self.header[rpm.RPMTAG_FILELINKTOS]]
sizes = self.header[rpm.RPMTAG_FILESIZES] sizes = self.header[rpm.RPMTAG_FILESIZES]
md5s = self.header[rpm.RPMTAG_FILEMD5S] md5s = self.header[rpm.RPMTAG_FILEMD5S]
mtimes = self.header[rpm.RPMTAG_FILEMTIMES] mtimes = self.header[rpm.RPMTAG_FILEMTIMES]
rdevs = self.header[rpm.RPMTAG_FILERDEVS] rdevs = self.header[rpm.RPMTAG_FILERDEVS]
langs = self.header[rpm.RPMTAG_FILELANGS] langs = self.header[rpm.RPMTAG_FILELANGS]
inodes = self.header[rpm.RPMTAG_FILEINODES] inodes = self.header[rpm.RPMTAG_FILEINODES]
requires = [x.decode() for x in self.header[rpm.RPMTAG_FILEREQUIRE]] requires = [b2s(x) for x in self.header[rpm.RPMTAG_FILEREQUIRE]]
provides = [x.decode() for x in self.header[rpm.RPMTAG_FILEPROVIDE]] provides = [b2s(x) for x in self.header[rpm.RPMTAG_FILEPROVIDE]]
files = [x.decode() for x in self.header[rpm.RPMTAG_FILENAMES]] files = [b2s(x) for x in self.header[rpm.RPMTAG_FILENAMES]]
magics = [x.decode() for x in self.header[rpm.RPMTAG_FILECLASS]] magics = [b2s(x) for x in self.header[rpm.RPMTAG_FILECLASS]]
try: # rpm >= 4.7.0 try: # rpm >= 4.7.0
filecaps = self.header[rpm.RPMTAG_FILECAPS] filecaps = self.header[rpm.RPMTAG_FILECAPS]
except: except:
@ -717,8 +726,8 @@ class Pkg:
if versions: if versions:
for loop in range(len(versions)): for loop in range(len(versions)):
name = names[loop].decode() name = b2s(names[loop])
evr = stringToVersion(versions[loop].decode()) evr = stringToVersion(b2s(versions[loop]))
if prereq is not None and flags[loop] & PREREQ_FLAG: if prereq is not None and flags[loop] & PREREQ_FLAG:
prereq.append((name, flags[loop] & (~PREREQ_FLAG), evr)) prereq.append((name, flags[loop] & (~PREREQ_FLAG), evr))
else: else:
@ -756,11 +765,11 @@ class Pkg:
interpreter arguments, if any.""" interpreter arguments, if any."""
prog = self[which] prog = self[which]
if prog is None: if prog is None:
prog = "" prog = b''
elif isinstance(prog, (list, tuple)): elif isinstance(prog, (list, tuple)):
# http://rpm.org/ticket/847#comment:2 # http://rpm.org/ticket/847#comment:2
prog = " ".join(prog) prog = b' '.join(prog)
return prog return b2s(prog)
def getInstalledPkgs(name): def getInstalledPkgs(name):
"""Get list of installed package objects by name.""" """Get list of installed package objects by name."""

View File

@ -543,9 +543,8 @@ class TagsCheck(AbstractCheck.AbstractCheck):
def check(self, pkg): def check(self, pkg):
packager = pkg[rpm.RPMTAG_PACKAGER] packager = Pkg.b2s(pkg[rpm.RPMTAG_PACKAGER])
if packager: if packager:
packager = packager.decode()
self._unexpanded_macros(pkg, 'Packager', packager) self._unexpanded_macros(pkg, 'Packager', packager)
if Config.getOption('Packager') and \ if Config.getOption('Packager') and \
not packager_regex.search(packager): not packager_regex.search(packager):
@ -555,7 +554,6 @@ class TagsCheck(AbstractCheck.AbstractCheck):
version = pkg[rpm.RPMTAG_VERSION] version = pkg[rpm.RPMTAG_VERSION]
if version: if version:
version = version.decode()
self._unexpanded_macros(pkg, 'Version', version) self._unexpanded_macros(pkg, 'Version', version)
res = invalid_version_regex.search(version) res = invalid_version_regex.search(version)
if res: if res:
@ -565,7 +563,6 @@ class TagsCheck(AbstractCheck.AbstractCheck):
release = pkg[rpm.RPMTAG_RELEASE] release = pkg[rpm.RPMTAG_RELEASE]
if release: if release:
release = release.decode()
self._unexpanded_macros(pkg, 'Release', release) self._unexpanded_macros(pkg, 'Release', release)
if release_ext and not extension_regex.search(release): if release_ext and not extension_regex.search(release):
printWarning(pkg, 'not-standard-release-extension', release) printWarning(pkg, 'not-standard-release-extension', release)
@ -684,11 +681,10 @@ class TagsCheck(AbstractCheck.AbstractCheck):
langs = pkg[rpm.RPMTAG_HEADERI18NTABLE] langs = pkg[rpm.RPMTAG_HEADERI18NTABLE]
if langs: if langs:
langs = [x.decode() for x in langs] langs = [Pkg.b2s(x) for x in langs]
summary = pkg[rpm.RPMTAG_SUMMARY] summary = Pkg.b2s(pkg[rpm.RPMTAG_SUMMARY])
if summary: if summary:
summary = summary.decode()
if not langs: if not langs:
self._unexpanded_macros(pkg, 'Summary', summary) self._unexpanded_macros(pkg, 'Summary', summary)
else: else:
@ -697,9 +693,8 @@ class TagsCheck(AbstractCheck.AbstractCheck):
else: else:
printError(pkg, 'no-summary-tag') printError(pkg, 'no-summary-tag')
description = pkg[rpm.RPMTAG_DESCRIPTION] description = Pkg.b2s(pkg[rpm.RPMTAG_DESCRIPTION])
if description: if description:
description = description.decode()
if not langs: if not langs:
self._unexpanded_macros(pkg, '%description', description) self._unexpanded_macros(pkg, '%description', description)
else: else:

View File

@ -228,16 +228,16 @@ class Rpmdiff:
if namestr == 'REQUIRES': if namestr == 'REQUIRES':
namestr = self.req2str(oldentry[1]) namestr = self.req2str(oldentry[1])
self.__add(self.DEPFORMAT, self.__add(self.DEPFORMAT,
(self.REMOVED, namestr, oldentry[0].decode(), (self.REMOVED, namestr, Pkg.b2s(oldentry[0]),
self.sense2str(oldentry[1]), oldentry[2].decode())) self.sense2str(oldentry[1]), Pkg.b2s(oldentry[2])))
for newentry in n: for newentry in n:
if not newentry in o: if not newentry in o:
namestr = name namestr = name
if namestr == 'REQUIRES': if namestr == 'REQUIRES':
namestr = self.req2str(newentry[1]) namestr = self.req2str(newentry[1])
self.__add(self.DEPFORMAT, self.__add(self.DEPFORMAT,
(self.ADDED, namestr, newentry[0].decode(), (self.ADDED, namestr, Pkg.b2s(newentry[0]),
self.sense2str(newentry[1]), newentry[2].decode())) self.sense2str(newentry[1]), Pkg.b2s(newentry[2])))
def __fileIteratorToDict(self, fi): def __fileIteratorToDict(self, fi):
result = {} result = {}