diff options
-rw-r--r-- | debian/control | 2 | ||||
-rw-r--r-- | setup.py | 2 | ||||
-rw-r--r-- | sos.spec | 1 | ||||
-rw-r--r-- | sos/archive.py | 16 | ||||
-rw-r--r-- | sos/plugins/__init__.py | 35 | ||||
-rw-r--r-- | sos/policies/__init__.py | 6 | ||||
-rw-r--r-- | sos/policies/osx.py | 2 | ||||
-rw-r--r-- | sos/reporting.py | 4 | ||||
-rw-r--r-- | sos/utilities.py | 24 | ||||
-rw-r--r-- | tests/archive_tests.py | 6 | ||||
-rw-r--r-- | tests/plugin_tests.py | 10 | ||||
-rw-r--r-- | tests/utilities_tests.py | 13 |
12 files changed, 71 insertions, 50 deletions
diff --git a/debian/control b/debian/control index 7311b646..4aa92128 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Maintainer: Adam Stokes <adam.stokes@ubuntu.com> Section: admin Priority: optional Standards-Version: 3.9.4 -Build-Depends: debhelper (>= 9), python (>=2.7), gettext, python-nose +Build-Depends: debhelper (>= 9), python (>=2.7), gettext, python-nose, python-six Homepage: https://github.com/sosreport/sosreport XS-Python-Version: 2.7 @@ -32,7 +32,7 @@ class BuildData(build): rc = subprocess.call(['msgfmt', '-o', mo, po]) if rc != 0: raise Warning("msgfmt returned %d" % (rc,)) - except Exception, e: + except Exception as e: error("Failed gettext.") sys.exit(1) @@ -12,6 +12,7 @@ BuildArch: noarch Url: http://fedorahosted.org/sos BuildRequires: python-devel BuildRequires: gettext +BuildRequires: python-six Requires: libxml2-python Requires: rpm-python Requires: tar diff --git a/sos/archive.py b/sos/archive.py index 080f2593..7e193de1 100644 --- a/sos/archive.py +++ b/sos/archive.py @@ -31,6 +31,10 @@ try: except ImportError: pass +# PYCOMPAT +import six +if six.PY3: + long = int class Archive(object): @@ -82,7 +86,7 @@ class FileCacheArchive(Archive): self._name = name self._tmp_dir = tmpdir self._archive_root = os.path.join(tmpdir, name) - os.makedirs(self._archive_root, 0700) + os.makedirs(self._archive_root, 0o700) self.log.debug("initialised empty FileCacheArchive at %s" % (self._archive_root,)) @@ -135,13 +139,13 @@ class FileCacheArchive(Archive): def add_dir(self, path): self.makedirs(path) - def _makedirs(self, path, mode=0700): + def _makedirs(self, path, mode=0o700): os.makedirs(path, mode) def get_tmp_dir(self): return self._archive_root - def makedirs(self, path, mode=0700): + def makedirs(self, path, mode=0o700): self._makedirs(self.dest_path(path)) self.log.debug("created directory at %s in FileCacheArchive %s" % (path, self._archive_root)) @@ -212,7 +216,7 @@ class TarFileArchive(FileCacheArchive): def _build_archive(self): old_pwd = os.getcwd() - old_umask = os.umask(0077) + old_umask = os.umask(0o077) os.chdir(self._tmp_dir) tar = tarfile.open(self._archive_path, mode="w") tar.add(os.path.split(self._name)[1], @@ -244,7 +248,7 @@ class TarFileArchive(FileCacheArchive): log.error(stderr) self._suffix += suffix return self.name() - except Exception, e: + except Exception as e: last_error = e else: raise last_error @@ -297,7 +301,7 @@ class ZipFileArchive(Archive): info = zipfile.ZipInfo(dest, date_time=time.localtime(time.time())) info.compress_type = self.compression - info.external_attr = 0400 << 16L + info.external_attr = 0o400 << long(16) self.zipfile.writestr(info, content) def open_file(self, name): diff --git a/sos/plugins/__init__.py b/sos/plugins/__init__.py index cbb8e5ae..8a55e6b6 100644 --- a/sos/plugins/__init__.py +++ b/sos/plugins/__init__.py @@ -34,9 +34,12 @@ from stat import * from time import time from itertools import * import logging -import urllib2 import fnmatch +# PYCOMPAT +import six +from six.moves import urllib, zip, filter + try: import json except ImportError: @@ -133,8 +136,8 @@ class Plugin(object): self.copy_strings = [] self.collect_cmds = [] - self.soslog = self.commons['soslog'] if self.commons.has_key('soslog') else logging.getLogger('sos') - self.proflog = self.commons['proflog'] if self.commons.has_key('proflog') else logging.getLogger('sosprofile') + self.soslog = self.commons['soslog'] if 'soslog' in self.commons else logging.getLogger('sos') + self.proflog = self.commons['proflog'] if 'proflog' in self.commons else logging.getLogger('sosprofile') # get the option list into a dictionary for opt in self.option_list: @@ -193,7 +196,7 @@ class Plugin(object): self.archive.add_string(result, path) else: replacements = 0 - except Exception, e: + except Exception as e: msg = 'regex substitution failed for %s in plugin %s with: "%s"' self.soslog.error(msg % (called['exe'], self.name(), e)) replacements = 0 @@ -226,7 +229,7 @@ class Plugin(object): self.archive.add_string(result, srcpath) else: replacements = 0 - except Exception, e: + except Exception as e: msg = 'regex substitution failed for %s in plugin %s with: "%s"' self.soslog.error(msg % (path, self.name(), e)) replacements = 0 @@ -343,7 +346,7 @@ class Plugin(object): try: stat = os.stat(srcpath) # if not readable(srcpath) - if not (stat.st_mode & 0444): + if not (stat.st_mode & 0o444): # FIXME: reflect permissions in archive self.archive.add_string("", dest) else: @@ -357,7 +360,7 @@ class Plugin(object): if self.commons['cmdlineopts'].profiler: time_passed = time() - start_time self.proflog.debug("copied: %-75s time: %f" % (srcpath, time_passed)) - except Exception, e: + except Exception as e: self.soslog.error("Unable to copy %s to %s" % (srcpath, dest)) self.soslog.error(traceback.format_exc()) @@ -376,7 +379,7 @@ class Plugin(object): def set_option(self, optionname, value): '''set the named option to value.''' - for name, parms in izip(self.opt_names, self.opt_parms): + for name, parms in zip(self.opt_names, self.opt_parms): if name == optionname: parms['enabled'] = value return True @@ -402,13 +405,13 @@ class Plugin(object): else: return key == optionname - for name, parms in izip(self.opt_names, self.opt_parms): + for name, parms in zip(self.opt_names, self.opt_parms): if _check(name): val = parms['enabled'] if val != None: return val - for key, value in self.commons.get('global_plugin_options', {}).iteritems(): + for key, value in six.iteritems(self.commons.get('global_plugin_options', {})): if _check(key): return value @@ -421,7 +424,7 @@ class Plugin(object): option = self.get_option(optionname) try: opt_list = [opt.strip() for opt in option.split(delimiter)] - return filter(None, opt_list) + return list(filter(None, opt_list)) except Exception: return default @@ -606,17 +609,17 @@ class Plugin(object): try: self.archive.add_string(string, os.path.join('sos_strings', self.name(), file_name)) - except Exception, e: + except Exception as e: self.soslog.debug("could not create %s, traceback follows: %s" % (file_name, e)) - for progs in izip(self.collect_cmds): + for progs in zip(self.collect_cmds): prog, suggest_filename, root_symlink, timeout = progs[0] self.soslog.debug("collecting output of '%s'" % prog) try: self.get_cmd_output_now(prog, suggest_filename, root_symlink, timeout) - except Exception, e: + except Exception as e: self.soslog.debug("error collecting output of '%s' (%s)" % (prog, e)) @@ -638,10 +641,10 @@ class Plugin(object): """ # some files or packages have been specified for this package if self.files or self.packages: - if isinstance(self.files, basestring): + if isinstance(self.files, six.string_types): self.files = [self.files] - if isinstance(self.packages, basestring): + if isinstance(self.packages, six.string_types): self.packages = [self.packages] return (any(os.path.exists(fname) for fname in self.files) or diff --git a/sos/policies/__init__.py b/sos/policies/__init__.py index 5c2531df..69d310db 100644 --- a/sos/policies/__init__.py +++ b/sos/policies/__init__.py @@ -344,7 +344,7 @@ No changes will be made to system configuration. ftp.set_pasv(True) ftp.storbinary('STOR %s' % upload_name, fp) ftp.quit() - except Exception, e: + except Exception as e: self._print(_("There was a problem uploading your report to Red Hat support. " + str(e))) else: self._print(_("Your report was successfully uploaded to %s with name:" % (upload_url,))) @@ -360,9 +360,9 @@ No changes will be made to system configuration. quiet mode""" if not self.commons['cmdlineopts'].quiet: if msg: - print msg + print(msg) else: - print + print() def get_msg(self): diff --git a/sos/policies/osx.py b/sos/policies/osx.py index 60b7f6a9..767b608c 100644 --- a/sos/policies/osx.py +++ b/sos/policies/osx.py @@ -9,5 +9,5 @@ class OSXPolicy(Policy): def check(class_): try: return "Mac OS X" in shell_out("sw_vers") - except Exception, e: + except Exception as e: return False diff --git a/sos/reporting.py b/sos/reporting.py index bf5addfa..16719196 100644 --- a/sos/reporting.py +++ b/sos/reporting.py @@ -5,6 +5,8 @@ try: except ImportError: import simplejson as json +# PYCOMPAT +from six import iteritems class Node(object): @@ -117,7 +119,7 @@ class PlainTextReport(object): def __str__(self): self.buf = buf = [] - for section_name, section_contents in sorted(self.report_node.data.iteritems()): + for section_name, section_contents in sorted(iteritems(self.report_node.data)): buf.append(section_name + "\n" + self.DIVIDER) for type_, format_, header in self.subsections: self.process_subsection(section_contents, type_.ADDS_TO, header, format_) diff --git a/sos/utilities.py b/sos/utilities.py index fcc78c54..da455a15 100644 --- a/sos/utilities.py +++ b/sos/utilities.py @@ -24,7 +24,6 @@ from __future__ import with_statement import os import re -import string import inspect from stat import * #from itertools import * @@ -37,10 +36,11 @@ import logging import fnmatch from contextlib import closing -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO + +# PYCOMPAT +import six +from six import StringIO + import time def tail(filename, number_of_bytes): @@ -53,7 +53,7 @@ def tail(filename, number_of_bytes): def fileobj(path_or_file, mode='r'): """Returns a file-like object that can be used as a context manager""" - if isinstance(path_or_file, basestring): + if isinstance(path_or_file, six.string_types): try: return open(path_or_file, mode) except: @@ -72,7 +72,7 @@ def checksum(file_, chunk_size=128, algorithm=None): with fileobj(file_, 'rb') as fd: data = fd.read(chunk_size) while data: - digest.update(data) + digest.update(six.b(data)) data = fd.read(chunk_size) return digest.hexdigest() @@ -199,10 +199,10 @@ class DirTree(object): self.buffer.append(s) def printtree(self): - print str(self) + print (six.u(self)) def as_string(self): - return str(self) + return self.__str__() def __str__(self): return "\n".join(self.buffer) @@ -216,14 +216,14 @@ class DirTree(object): import pwd return pwd.getpwuid(stats.st_uid)[0] except: - return str(stats.st_uid) + return six.u(stats.st_uid) def _get_group(self, stats): try: import grp return grp.getgrgid(stats.st_gid)[0] except: - return str(stats.st_uid) + return six.u(stats.st_uid) def _format(self, path): """Conditionally adds detail to paths""" @@ -245,7 +245,7 @@ class DirTree(object): count = 0 files = os.listdir(dir_) - files.sort(key=string.lower) + files.sort(key=str.lower) for f in files: count += 1 path = os.path.join(dir_, f) diff --git a/tests/archive_tests.py b/tests/archive_tests.py index abdce994..9cd7bd1b 100644 --- a/tests/archive_tests.py +++ b/tests/archive_tests.py @@ -9,6 +9,8 @@ import shutil from sos.archive import TarFileArchive, ZipFileArchive +# PYCOMPAT +import six class ZipFileArchiveTest(unittest.TestCase): @@ -66,14 +68,14 @@ class ZipFileArchiveTest(unittest.TestCase): self.zf.add_string('this is my content', 'tests/string_test.txt') afp = self.zf.open_file('tests/string_test.txt') - self.assertEquals('this is my content', afp.read()) + self.assertEquals(six.b('this is my content'), afp.read()) def test_overwrite_file(self): self.zf.add_string('this is my content', 'tests/string_test.txt') self.zf.add_string('this is my new content', 'tests/string_test.txt') afp = self.zf.open_file('tests/string_test.txt') - self.assertEquals('this is my new content', afp.read()) + self.assertEquals(six.b('this is my new content'), afp.read()) # Disabled as new api doesnt provide a add_link routine # def test_make_link(self): diff --git a/tests/plugin_tests.py b/tests/plugin_tests.py index 9f8817d2..c4b540fa 100644 --- a/tests/plugin_tests.py +++ b/tests/plugin_tests.py @@ -1,7 +1,13 @@ import unittest import os import tempfile -from StringIO import StringIO + +# PYCOMPAT +import six +if six.PY2: + from StringIO import StringIO +else: + from io import StringIO from sos.plugins import Plugin, regex_findall, sos_relative_path, mangle_command from sos.archive import TarFileArchive, ZipFileArchive @@ -14,7 +20,7 @@ def j(filename): def create_file(size): f = tempfile.NamedTemporaryFile(delete=False) - f.write("*" * size * 1024 * 1024) + f.write(six.b("*" * size * 1024 * 1024)) f.flush() f.close() return f.name diff --git a/tests/utilities_tests.py b/tests/utilities_tests.py index fc9e858f..3ecf8c2b 100644 --- a/tests/utilities_tests.py +++ b/tests/utilities_tests.py @@ -1,6 +1,9 @@ import os.path import unittest -from StringIO import StringIO + +# PYCOMPAT +import six +from six import StringIO from sos.utilities import grep, DirTree, checksum, get_hash_name, is_executable, sos_get_command_output, find, tail, shell_out import sos @@ -32,12 +35,12 @@ class TailTest(unittest.TestCase): def test_tail(self): t = tail("tests/tail_test.txt", 10) - self.assertEquals(t, "last line\n") + self.assertEquals(t, six.b("last line\n")) def test_tail_too_many(self): t = tail("tests/tail_test.txt", 200) expected = open("tests/tail_test.txt", "r").read() - self.assertEquals(t, expected) + self.assertEquals(t, six.b(expected)) class DirTreeTest(unittest.TestCase): @@ -78,7 +81,7 @@ class ExecutableTest(unittest.TestCase): path = os.path.join(TEST_DIR, 'test_exe.py') ret, out, junk = sos_get_command_output(path) self.assertEquals(ret, 0) - self.assertEquals(out, "executed\n") + self.assertEquals(out, six.b("executed\n")) def test_output_non_exe(self): path = os.path.join(TEST_DIR, 'utility_tests.py') @@ -88,7 +91,7 @@ class ExecutableTest(unittest.TestCase): def test_shell_out(self): path = os.path.join(TEST_DIR, 'test_exe.py') - self.assertEquals("executed\n", shell_out(path)) + self.assertEquals(six.b("executed\n"), shell_out(path)) class FindTest(unittest.TestCase): |