Python 3 compatibility tweaks

This commit is contained in:
Ville Skyttä 2014-02-08 22:34:50 +02:00
parent 7e3861ddec
commit 28ca788345
12 changed files with 114 additions and 82 deletions

View File

@ -10,7 +10,10 @@
import re
import socket
import sys
import urllib2
try:
import urllib2
except:
import urllib.request as urllib2
from Filter import addDetails, printInfo, printWarning
import Config

View File

@ -9,6 +9,7 @@
import re
import stat
import sys
import rpm
@ -175,10 +176,11 @@ class BinaryInfo:
fobj = None
try:
fobj = open(path)
fobj = open(path, 'rb')
fobj.seek(-12, 2) # 2 == os.SEEK_END, for python 2.4 compat (#172)
self.tail = fobj.read()
except Exception, e:
self.tail = fobj.read().decode()
except Exception:
e = sys.exc_info()[1]
printWarning(pkg, 'binaryinfo-tail-failed %s: %s' % (file, e))
if fobj:
fobj.close()
@ -270,9 +272,11 @@ class BinariesCheck(AbstractCheck.AbstractCheck):
has_usr_lib_file = False
multi_pkg = False
res = srcname_regex.search(pkg[rpm.RPMTAG_SOURCERPM] or '')
if res:
multi_pkg = (pkg.name != res.group(1))
srpm = pkg[rpm.RPMTAG_SOURCERPM]
if srpm:
res = srcname_regex.search(srpm.decode())
if res:
multi_pkg = (pkg.name != res.group(1))
for fname, pkgfile in files.items():

View File

@ -43,7 +43,9 @@ class DocFilesCheck(AbstractCheck.AbstractCheck):
core_reqs[dep.N()] = []
# register things which are provided by the package
for i in pkg.header[rpm.RPMTAG_PROVIDES] + files.keys():
for i in pkg.header[rpm.RPMTAG_PROVIDES]:
core_reqs[i.decode()] = []
for i in files:
core_reqs[i] = []
for i in files:

View File

@ -9,16 +9,16 @@
#############################################################################
from datetime import datetime
import commands
import os
import re
import stat
import string
import sys
import rpm
from Filter import addDetails, printError, printWarning
from Pkg import catcmd, is_utf8, is_utf8_str
from Pkg import catcmd, getstatusoutput, is_utf8, is_utf8_str
import AbstractCheck
import Config
@ -253,7 +253,7 @@ scalable_icon_regex = re.compile(r'^/usr(?:/local)?/share/icons/.*/scalable/')
# loosely inspired from Python Cookbook
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/173220
text_characters = "".join(map(chr, range(32, 127)) + list("\n\r\t\b"))
text_characters = "".join(map(chr, range(32, 127))) + "\n\r\t\b"
_null_trans = string.maketrans("", "")
def peek(filename, pkg, length=1024):
@ -265,7 +265,8 @@ def peek(filename, pkg, length=1024):
fobj = open(filename, 'rb')
chunk = fobj.read(length)
fobj.close()
except IOError, e: # eg. https://bugzilla.redhat.com/209876
except IOError: # eg. https://bugzilla.redhat.com/209876
e = sys.exc_info()[1]
printWarning(pkg, 'read-error', e)
if fobj:
fobj.close()
@ -489,7 +490,8 @@ class FilesCheck(AbstractCheck.AbstractCheck):
printError(pkg, 'compressed-symlink-with-wrong-ext',
f, link)
perm = mode & 07777
perm = mode & int("7777", 8)
mode_is_exec = mode & int("111", 8)
if log_regex.search(f):
log_file = f
@ -514,17 +516,17 @@ class FilesCheck(AbstractCheck.AbstractCheck):
pkg[rpm.RPMTAG_GROUP]))):
printError(pkg, 'setgid-binary', f, group,
oct(perm))
if mode & 0777 != 0755:
if mode & int("777", 8) != int("755", 8):
printError(pkg, 'non-standard-executable-perm', f,
oct(perm))
# Prefetch scriptlets, strip quotes from them (#169)
postin = pkg[rpm.RPMTAG_POSTIN] or \
pkg.scriptprog(rpm.RPMTAG_POSTINPROG)
postin = (pkg[rpm.RPMTAG_POSTIN] or \
pkg.scriptprog(rpm.RPMTAG_POSTINPROG)).decode()
if postin:
postin = quotes_regex.sub('', postin)
postun = pkg[rpm.RPMTAG_POSTUN] or \
pkg.scriptprog(rpm.RPMTAG_POSTUNPROG)
postun = (pkg[rpm.RPMTAG_POSTUN] or \
pkg.scriptprog(rpm.RPMTAG_POSTUNPROG)).decode()
if postun:
postun = quotes_regex.sub('', postun)
@ -628,7 +630,7 @@ class FilesCheck(AbstractCheck.AbstractCheck):
res = bin_regex.search(f)
if res:
if mode & 0111 == 0:
if not mode_is_exec:
printWarning(pkg, 'non-executable-in-bin', f, oct(perm))
else:
exe = res.group(1)
@ -639,7 +641,8 @@ class FilesCheck(AbstractCheck.AbstractCheck):
(includefile_regex.search(f) or \
develfile_regex.search(f) or is_buildconfig):
printWarning(pkg, 'devel-file-in-non-devel-package', f)
if mode & 0444 != 0444 and perm & 07000 == 0:
if mode & int("444", 8) != int("444", 8) and \
perm & int("7000", 8) == 0:
ok_nonreadable = False
for regex in non_readable_regexs:
if regex.search(f):
@ -651,7 +654,7 @@ class FilesCheck(AbstractCheck.AbstractCheck):
f not in ghost_files:
printError(pkg, 'zero-length', f)
if mode & 0002 != 0:
if mode & stat.S_IWOTH:
printError(pkg, 'world-writable', f, oct(perm))
if not perl_dep_error:
@ -723,10 +726,10 @@ class FilesCheck(AbstractCheck.AbstractCheck):
printWarning(pkg, 'python-bytecode-without-source', f)
# normal executable check
if mode & stat.S_IXUSR and perm != 0755:
if mode & stat.S_IXUSR and perm != int("755", 8):
printError(pkg, 'non-standard-executable-perm',
f, oct(perm))
if mode & 0111 != 0:
if mode_is_exec:
if f in config_files:
printError(pkg, 'executable-marked-as-config-file', f)
if not nonexec_file:
@ -758,11 +761,12 @@ class FilesCheck(AbstractCheck.AbstractCheck):
man_basenames.add(res.group(1))
if use_utf8 and chunk:
# TODO: better shell escaping or seq based invocation
cmd = commands.getstatusoutput(
cmd = getstatusoutput(
'env LC_ALL=C %s "%s" | gtbl | '
'env LC_ALL=en_US.UTF-8 groff -mtty-char -Tutf8 '
'-P-c -mandoc -w%s >/dev/null' %
(catcmd(f), pkgfile.path, man_warn_category))
(catcmd(f), pkgfile.path, man_warn_category),
shell=True)
for line in cmd[1].split("\n"):
res = man_warn_regex.search(line)
if not res or man_nowarn_regex.search(line):
@ -792,12 +796,11 @@ class FilesCheck(AbstractCheck.AbstractCheck):
printError(pkg,
'sourced-script-with-shebang', f,
interpreter)
if mode & 0111 != 0:
if mode_is_exec:
printError(pkg, 'executable-sourced-script',
f, oct(perm))
# ...but executed ones should
elif interpreter or mode & 0111 != 0 or \
script_regex.search(f):
elif interpreter or mode_is_exec or script_regex.search(f):
if interpreter:
if not interpreter_regex.search(interpreter):
printError(pkg, 'wrong-script-interpreter',
@ -807,7 +810,7 @@ class FilesCheck(AbstractCheck.AbstractCheck):
f.endswith('.la')):
printError(pkg, 'script-without-shebang', f)
if mode & 0111 == 0 and not is_doc:
if not mode_is_exec and not is_doc:
printError(pkg, 'non-executable-script', f,
oct(perm), interpreter)
if '\r' in chunk:
@ -835,9 +838,9 @@ class FilesCheck(AbstractCheck.AbstractCheck):
# normal dir check
elif stat.S_ISDIR(mode):
if mode & 01002 == 2: # world writable without sticky bit
if mode & int("1002", 8) == 2: # world writable w/o sticky bit
printError(pkg, 'world-writable', f, oct(perm))
if perm != 0755:
if perm != int("755", 8):
printError(pkg, 'non-standard-dir-perm', f, oct(perm))
if pkg.name not in filesys_packages and f in STANDARD_DIRS:
printError(pkg, 'standard-dir-owned-by-package', f)
@ -947,7 +950,7 @@ class FilesCheck(AbstractCheck.AbstractCheck):
if stat.S_ISLNK(mode):
printError(pkg, 'symlink-crontab-file', f)
if mode & 0111:
if mode_is_exec:
printError(pkg, 'executable-crontab-file', f)
if stat.S_IWGRP & mode or stat.S_IWOTH & mode:

View File

@ -79,7 +79,7 @@ class I18NCheck(AbstractCheck.AbstractCheck):
if pkg.isSource():
return
files = pkg.files().keys()
files = list(pkg.files().keys())
files.sort()
locales = [] # list of locales for this packages
webapp = False

View File

@ -10,6 +10,7 @@
import os
import re
import sys
import rpm
@ -54,7 +55,7 @@ class InitScriptCheck(AbstractCheck.AbstractCheck):
basename = os.path.basename(fname)
initscript_list.append(basename)
if pkgfile.mode & 0500 != 0500:
if pkgfile.mode & int("500", 8) != int("500", 8):
printError(pkg, 'init-script-non-executable', fname)
if "." in basename:
@ -87,7 +88,8 @@ class InitScriptCheck(AbstractCheck.AbstractCheck):
content = None
try:
content = Pkg.readlines(pkgfile.path)
except Exception, e:
except Exception:
e = sys.exc_info()[1]
printWarning(pkg, 'read-error', e)
continue
content_str = "".join(content)

View File

@ -31,12 +31,16 @@ class LSBCheck(AbstractCheck.AbstractCheck):
printError(pkg, 'non-lsb-compliant-package-name', name)
version = pkg[rpm.RPMTAG_VERSION]
if version and not version_regex.search(version):
printError(pkg, 'non-lsb-compliant-version', version)
if version:
version = version.decode()
if not version_regex.search(version):
printError(pkg, 'non-lsb-compliant-version', version)
release = pkg[rpm.RPMTAG_RELEASE]
if release and not version_regex.search(release):
printError(pkg, 'non-lsb-compliant-release', release)
if release:
release = release.decode()
if not version_regex.search(release):
printError(pkg, 'non-lsb-compliant-release', release)
# Create an object to enable the auto registration of the test
check = LSBCheck()

View File

@ -178,9 +178,9 @@ class MenuCheck(AbstractCheck.AbstractCheck):
else:
if basename != pkg.name:
printWarning(pkg, 'non-coherent-menu-filename', fname)
if mode & 0444 != 0444:
if mode & int("444", 8) != int("444", 8):
printError(pkg, 'non-readable-menu-file', fname)
if mode & 0111 != 0:
if mode & int("111", 8):
printError(pkg, 'executable-menu-file', fname)
menus.append(fname)
else:

View File

@ -9,7 +9,10 @@
from Filter import addDetails, printError, printWarning
from Pkg import getstatusoutput, is_utf8
import AbstractCheck
from ConfigParser import RawConfigParser
try:
from ConfigParser import RawConfigParser
except:
from configparser import RawConfigParser
import os
STANDARD_BIN_DIRS = ['/bin/', '/sbin/', '/usr/bin/', '/usr/sbin/']

26
Pkg.py
View File

@ -85,7 +85,7 @@ def getstatusoutput(cmd, stdoutonly = False, shell = False):
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, close_fds=True)
proc.stdin.close()
text = proc.stdout.read()
text = proc.stdout.read().decode()
sts = proc.wait()
if sts is None:
sts = 0
@ -444,13 +444,13 @@ class Pkg:
os.close(fd)
self.is_source = not self.header[rpm.RPMTAG_SOURCERPM]
self.name = self.header[rpm.RPMTAG_NAME]
self.name = self.header[rpm.RPMTAG_NAME].decode()
if self.isNoSource():
self.arch = 'nosrc'
elif self.isSource():
self.arch = 'src'
else:
self.arch = self.header[rpm.RPMTAG_ARCH]
self.arch = self.header.format("%{ARCH}")
# Return true if the package is a source package
def isSource(self):
@ -530,7 +530,7 @@ class Pkg:
# LANGUAGE trumps other env vars per GNU gettext docs, see also #166
orig = os.environ.get('LANGUAGE')
os.environ['LANGUAGE'] = lang
ret = self[tag]
ret = self[tag].decode()
if orig is not None:
os.environ['LANGUAGE'] = orig
return ret
@ -595,17 +595,17 @@ class Pkg:
modes = self.header[rpm.RPMTAG_FILEMODES]
users = self.header[rpm.RPMTAG_FILEUSERNAME]
groups = self.header[rpm.RPMTAG_FILEGROUPNAME]
links = self.header[rpm.RPMTAG_FILELINKTOS]
links = [x.decode() for x in self.header[rpm.RPMTAG_FILELINKTOS]]
sizes = self.header[rpm.RPMTAG_FILESIZES]
md5s = self.header[rpm.RPMTAG_FILEMD5S]
mtimes = self.header[rpm.RPMTAG_FILEMTIMES]
rdevs = self.header[rpm.RPMTAG_FILERDEVS]
langs = self.header[rpm.RPMTAG_FILELANGS]
inodes = self.header[rpm.RPMTAG_FILEINODES]
requires = self.header[rpm.RPMTAG_FILEREQUIRE]
provides = self.header[rpm.RPMTAG_FILEPROVIDE]
files = self.header[rpm.RPMTAG_FILENAMES]
magics = self.header[rpm.RPMTAG_FILECLASS]
requires = [x.decode() for x in self.header[rpm.RPMTAG_FILEREQUIRE]]
provides = [x.decode() for x in self.header[rpm.RPMTAG_FILEPROVIDE]]
files = [x.decode() for x in self.header[rpm.RPMTAG_FILENAMES]]
magics = [x.decode() for x in self.header[rpm.RPMTAG_FILECLASS]]
try: # rpm >= 4.7.0
filecaps = self.header[rpm.RPMTAG_FILECAPS]
except:
@ -716,12 +716,12 @@ class Pkg:
if versions:
for loop in range(len(versions)):
evr = stringToVersion(versions[loop])
name = names[loop].decode()
evr = stringToVersion(versions[loop].decode())
if prereq is not None and flags[loop] & PREREQ_FLAG:
prereq.append((names[loop], flags[loop] & (~PREREQ_FLAG),
evr))
prereq.append((name, flags[loop] & (~PREREQ_FLAG), evr))
else:
list.append((names[loop], flags[loop], evr))
list.append((name, flags[loop], evr))
def _gatherDepInfo(self):
if self._requires is None:

View File

@ -14,7 +14,7 @@ import AbstractCheck
import Config
DEFAULT_VALID_SRC_PERMS = (0644, 0755)
DEFAULT_VALID_SRC_PERMS = (int("644", 8), int("755", 8))
source_regex = re.compile('\\.(tar|patch|tgz|diff)$')
compress_ext = Config.getOption("CompressExtension", "bz2")
@ -43,7 +43,7 @@ class SourceCheck(AbstractCheck.AbstractCheck):
not fname.endswith(compress_ext):
printWarning(pkg, 'source-or-patch-not-compressed',
compress_ext, fname)
perm = pkgfile.mode & 07777
perm = pkgfile.mode & int("7777", 8)
if perm not in valid_src_perms:
printWarning(pkg, 'strange-permission', fname, oct(perm))

View File

@ -535,7 +535,7 @@ class TagsCheck(AbstractCheck.AbstractCheck):
def _unexpanded_macros(self, pkg, tagname, value, is_url=False):
if not value:
return
for match in AbstractCheck.macro_regex.findall(str(value)):
for match in AbstractCheck.macro_regex.findall(value):
# Do not warn about %XX URL escapes
if is_url and re.match('^%[0-9A-F][0-9A-F]$', match, re.I):
continue
@ -544,28 +544,33 @@ class TagsCheck(AbstractCheck.AbstractCheck):
def check(self, pkg):
packager = pkg[rpm.RPMTAG_PACKAGER]
self._unexpanded_macros(pkg, 'Packager', packager)
if not packager:
if packager:
packager = packager.decode()
self._unexpanded_macros(pkg, 'Packager', packager)
if Config.getOption('Packager') and \
not packager_regex.search(packager):
printWarning(pkg, 'invalid-packager', packager)
else:
printError(pkg, 'no-packager-tag')
elif Config.getOption('Packager') and \
not packager_regex.search(packager):
printWarning(pkg, 'invalid-packager', packager)
version = pkg[rpm.RPMTAG_VERSION]
self._unexpanded_macros(pkg, 'Version', version)
if not version:
printError(pkg, 'no-version-tag')
else:
if version:
version = version.decode()
self._unexpanded_macros(pkg, 'Version', version)
res = invalid_version_regex.search(version)
if res:
printError(pkg, 'invalid-version', version)
else:
printError(pkg, 'no-version-tag')
release = pkg[rpm.RPMTAG_RELEASE]
self._unexpanded_macros(pkg, 'Release', release)
if not release:
if release:
release = release.decode()
self._unexpanded_macros(pkg, 'Release', release)
if release_ext and not extension_regex.search(release):
printWarning(pkg, 'not-standard-release-extension', release)
else:
printError(pkg, 'no-release-tag')
elif release_ext and not extension_regex.search(release):
printWarning(pkg, 'not-standard-release-extension', release)
epoch = pkg[rpm.RPMTAG_EPOCH]
if epoch is None:
@ -593,7 +598,7 @@ class TagsCheck(AbstractCheck.AbstractCheck):
is_devel = FilesCheck.devel_regex.search(name)
is_source = pkg.isSource()
for d in deps:
value = apply(Pkg.formatRequire, d)
value = Pkg.formatRequire(*d)
if use_epoch and d[1] and d[2][0] is None and \
not d[0].startswith('rpmlib('):
printWarning(pkg, 'no-epoch-in-dependency', value)
@ -677,25 +682,31 @@ class TagsCheck(AbstractCheck.AbstractCheck):
ignored_words.update((x[0] for x in pkg.conflicts()))
ignored_words.update((x[0] for x in pkg.obsoletes()))
langs = pkg[rpm.RPMTAG_HEADERI18NTABLE]
if langs:
langs = [x.decode() for x in langs]
summary = pkg[rpm.RPMTAG_SUMMARY]
if not summary:
printError(pkg, 'no-summary-tag')
else:
if not pkg[rpm.RPMTAG_HEADERI18NTABLE]:
if summary:
summary = summary.decode()
if not langs:
self._unexpanded_macros(pkg, 'Summary', summary)
else:
for lang in pkg[rpm.RPMTAG_HEADERI18NTABLE]:
for lang in langs:
self.check_summary(pkg, lang, ignored_words)
else:
printError(pkg, 'no-summary-tag')
description = pkg[rpm.RPMTAG_DESCRIPTION]
if not description:
printError(pkg, 'no-description-tag')
else:
if not pkg[rpm.RPMTAG_HEADERI18NTABLE]:
if description:
description = description.decode()
if not langs:
self._unexpanded_macros(pkg, '%description', description)
else:
for lang in pkg[rpm.RPMTAG_HEADERI18NTABLE]:
for lang in langs:
self.check_description(pkg, lang, ignored_words)
else:
printError(pkg, 'no-description-tag')
group = pkg[rpm.RPMTAG_GROUP]
self._unexpanded_macros(pkg, 'Group', group)