aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml5
-rw-r--r--debian/control6
-rw-r--r--setup.py2
-rw-r--r--sos.spec2
-rw-r--r--sos/archive.py16
-rw-r--r--sos/plugins/__init__.py35
-rw-r--r--sos/plugins/emc.py32
-rw-r--r--sos/plugins/logs.py6
-rw-r--r--sos/plugins/powerpc.py83
-rw-r--r--sos/plugins/veritas.py2
-rw-r--r--sos/policies/__init__.py6
-rw-r--r--sos/policies/osx.py2
-rw-r--r--sos/reporting.py4
-rw-r--r--sos/sosreport.py32
-rw-r--r--sos/utilities.py24
-rw-r--r--tests/archive_tests.py6
-rw-r--r--tests/plugin_tests.py10
-rw-r--r--tests/utilities_tests.py13
18 files changed, 153 insertions, 133 deletions
diff --git a/.travis.yml b/.travis.yml
index 0f923c69..d8eb1624 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,9 +2,6 @@ language: python
python:
- 2.7
- 3.3
-matrix:
- allow_failures:
- - python: 3.3
notifications:
email: false
irc:
@@ -12,7 +9,7 @@ notifications:
- "us.freenode.net#sosreport"
on_success: change
install:
- - "pip install nose nose-cov --use-mirrors"
+ - "pip install six nose nose-cov --use-mirrors"
- "python setup.py install"
script:
- "nosetests -v --with-cover --cover-package=sos --cover-html"
diff --git a/debian/control b/debian/control
index 7311b646..2306a5d7 100644
--- a/debian/control
+++ b/debian/control
@@ -3,13 +3,13 @@ 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 (>=3.3), gettext, python3-nose, python3-six
Homepage: https://github.com/sosreport/sosreport
-XS-Python-Version: 2.7
+XS-Python-Version: 3.3
Package: sosreport
Architecture: any
-Depends: ${python:Depends}, ${misc:Depends}
+Depends: ${python:Depends}, ${misc:Depends}, python3-six
Description: Set of tools to gather troubleshooting data from a system
Sos is a set of tools that gathers information about system
hardware and configuration. The information can then be used for
diff --git a/setup.py b/setup.py
index f24bcae8..eb20a12c 100644
--- a/setup.py
+++ b/setup.py
@@ -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)
diff --git a/sos.spec b/sos.spec
index 6572788c..f6e43aaa 100644
--- a/sos.spec
+++ b/sos.spec
@@ -12,11 +12,13 @@ BuildArch: noarch
Url: http://fedorahosted.org/sos
BuildRequires: python-devel
BuildRequires: gettext
+BuildRequires: python-six
Requires: libxml2-python
Requires: rpm-python
Requires: tar
Requires: bzip2
Requires: xz
+Requires: python-six
%description
Sos is a set of tools that gathers information about system
diff --git a/sos/archive.py b/sos/archive.py
index 095777ba..4c8cceb1 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):
@@ -91,7 +95,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,))
@@ -144,7 +148,7 @@ 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):
@@ -153,7 +157,7 @@ class FileCacheArchive(Archive):
def get_archive_path(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))
@@ -224,7 +228,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_name, mode="w")
tar.add(os.path.split(self._name)[1],
@@ -256,7 +260,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
@@ -309,7 +313,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/plugins/emc.py b/sos/plugins/emc.py
index 89d0734e..6eac7d04 100644
--- a/sos/plugins/emc.py
+++ b/sos/plugins/emc.py
@@ -157,22 +157,22 @@ class Emc(Plugin, RedHatPlugin):
## If PowerPath is installed collect PowerPath specific information
if self.is_installed("EMCpower"):
- print "EMC PowerPath is installed."
- print " Gathering EMC PowerPath information..."
+ print("EMC PowerPath is installed.")
+ print(" Gathering EMC PowerPath information...")
self.add_custom_text("EMC PowerPath is installed.<br>")
self.get_pp_files()
add_about_emc = "yes"
## If PowerPath is running collect additional PowerPath specific information
if os.path.isdir("/proc/emcp"):
- print "EMC PowerPath is running."
- print " Gathering additional EMC PowerPath information..."
+ print("EMC PowerPath is running.")
+ print(" Gathering additional EMC PowerPath information...")
self.get_pp_config()
## If Solutions Enabler is installed collect Symmetrix/DMX specific information
if len(self.policy().package_manager.all_pkgs_by_name_regex('[Ss][Yy][Mm][Cc][Ll][Ii]-[Ss][Yy][Mm][Cc][Ll][Ii]')) > 0:
- print "EMC Solutions Enabler SYMCLI is installed."
- print " Gathering EMC Solutions Enabler SYMCLI information..."
+ print("EMC Solutions Enabler SYMCLI is installed.")
+ print(" Gathering EMC Solutions Enabler SYMCLI information...")
self.add_custom_text("EMC Solutions Enabler is installed.<br>")
self.get_symcli_files()
self.get_symcli_config()
@@ -180,16 +180,16 @@ class Emc(Plugin, RedHatPlugin):
## If Navisphere Host Agent is installed collect CLARiiON specific information
if os.path.isdir("/opt/Navisphere/bin"):
- print ""
- print "The EMC CLARiiON Navisphere Host Agent is installed."
+ print("")
+ print("The EMC CLARiiON Navisphere Host Agent is installed.")
self.add_custom_text("EMC CLARiiON Navisphere Host Agent is installed.<br>")
self.get_navicli_config()
- print " Gathering Navisphere NAVICLI Host Agent information..."
- print " Please enter a CLARiiON SP IP address. In order to collect"
- print " information for both SPA and SPB as well as multiple"
- print " CLARiiON arrays (if desired) you will be prompted multiple times."
- print " To exit simply press [Enter]"
- print ""
+ print(" Gathering Navisphere NAVICLI Host Agent information...")
+ print(" Please enter a CLARiiON SP IP address. In order to collect")
+ print( " information for both SPA and SPB as well as multiple")
+ print(" CLARiiON arrays (if desired) you will be prompted multiple times.")
+ print(" To exit simply press [Enter]")
+ print("")
add_about_emc = "yes"
CLARiiON_IP_address_list = []
CLARiiON_IP_loop = "stay_in"
@@ -202,7 +202,7 @@ class Emc(Plugin, RedHatPlugin):
CLARiiON_IP_address_list.append(ans)
else:
if ans != "":
- print "The IP address you entered, %s, is not to an active CLARiiON SP." % ans
+ print("The IP address you entered, %s, is not to an active CLARiiON SP." % ans)
if ans == "":
CLARiiON_IP_loop = "get_out"
## Sort and dedup the list of CLARiiON IP Addresses
@@ -212,7 +212,7 @@ class Emc(Plugin, RedHatPlugin):
CLARiiON_IP_address_list.remove(SP_address)
for SP_address in CLARiiON_IP_address_list:
if SP_address != "":
- print " Gathering NAVICLI information for %s..." % SP_address
+ print(" Gathering NAVICLI information for %s..." % SP_address)
self.get_navicli_SP_info(SP_address)
## Only provide About EMC if EMC products are installed
diff --git a/sos/plugins/logs.py b/sos/plugins/logs.py
index 8359e063..bdf92067 100644
--- a/sos/plugins/logs.py
+++ b/sos/plugins/logs.py
@@ -38,14 +38,14 @@ class Logs(Plugin):
self.add_copy_spec_limit("/var/log/boot*", sizelimit = self.limit)
if self.get_option('all_logs'):
- print "doing all_logs..."
+ print( "doing all_logs...")
logs = self.do_regex_find_all("^\S+\s+(-?\/.*$)\s+",
"/etc/syslog.conf")
- print logs
+ print(logs)
if self.policy().pkg_by_name("rsyslog") \
or os.path.exists("/etc/rsyslog.conf"):
logs += self.do_regex_find_all("^\S+\s+(-?\/.*$)\s+", "/etc/rsyslog.conf")
- print logs
+ print(logs)
for i in logs:
if i.startswith("-"):
i = i[1:]
diff --git a/sos/plugins/powerpc.py b/sos/plugins/powerpc.py
index 974baa16..dfaacb9b 100644
--- a/sos/plugins/powerpc.py
+++ b/sos/plugins/powerpc.py
@@ -25,49 +25,50 @@ class PowerPC(Plugin, RedHatPlugin, UbuntuPlugin, DebianPlugin):
plugin_name = 'powerpc'
def check_enabled(self):
- return (self.policy().get_arch() == "ppc64")
+ return (self.policy().get_arch() == "ppc64")
def setup(self):
- try:
- with open('/proc/cpuinfo', 'r') as fp:
- contents = fp.read()
- ispSeries = "pSeries" in contents
- isPowerNV = "PowerNV" in contents
- except:
- ispSeries = False
- isPowerNV = False
+ try:
+ with open('/proc/cpuinfo', 'r') as fp:
+ contents = fp.read()
+ ispSeries = "pSeries" in contents
+ isPowerNV = "PowerNV" in contents
+ except:
+ ispSeries = False
+ isPowerNV = False
- if ispSeries or isPowerNV:
- self.add_copy_spec("/proc/device-tree/")
- self.add_copy_spec("/proc/loadavg")
- self.add_copy_spec("/proc/locks")
- self.add_copy_spec("/proc/misc")
- self.add_copy_spec("/proc/swaps")
- self.add_copy_spec("/proc/version")
- self.add_copy_spec("/dev/nvram")
- self.add_copy_spec("/var/log/platform")
- self.add_cmd_output("ppc64_cpu --smt")
- self.add_cmd_output("ppc64_cpu --cores-present")
- self.add_cmd_output("ppc64_cpu --cores-on")
- self.add_cmd_output("ppc64_cpu --run-mode")
- self.add_cmd_output("ppc64_cpu --frequency")
- self.add_cmd_output("ppc64_cpu --dscr")
+ if ispSeries or isPowerNV:
+ self.add_copy_spec("/proc/device-tree/")
+ self.add_copy_spec("/proc/loadavg")
+ self.add_copy_spec("/proc/locks")
+ self.add_copy_spec("/proc/misc")
+ self.add_copy_spec("/proc/swaps")
+ self.add_copy_spec("/proc/version")
+ self.add_copy_spec("/dev/nvram")
+ self.add_copy_spec("/var/log/platform")
+ self.add_cmd_output("ppc64_cpu --smt")
+ self.add_cmd_output("ppc64_cpu --cores-present")
+ self.add_cmd_output("ppc64_cpu --cores-on")
+ self.add_cmd_output("ppc64_cpu --run-mode")
+ self.add_cmd_output("ppc64_cpu --frequency")
+ self.add_cmd_output("ppc64_cpu --dscr")
- if ispSeries:
- self.add_copy_spec("/proc/ppc64/lparcfg")
- self.add_copy_spec("/proc/ppc64/eeh")
- self.add_copy_spec("/proc/ppc64/systemcfg")
- self.add_cmd_output("lscfg -vp")
- self.add_cmd_output("lsmcode -A")
- self.add_cmd_output("lsvpd --debug")
- self.add_cmd_output("lsvio -des")
- self.add_cmd_output("servicelog --dump")
- self.add_cmd_output("servicelog_notify --list")
- self.add_cmd_output("usysattn")
- self.add_cmd_output("usysident")
- self.add_cmd_output("serv_config -l")
- self.add_cmd_output("bootlist -m both -r")
- self.add_cmd_output("lparstat -i")
+ if ispSeries:
+ self.add_copy_spec("/proc/ppc64/lparcfg")
+ self.add_copy_spec("/proc/ppc64/eeh")
+ self.add_copy_spec("/proc/ppc64/systemcfg")
+ self.add_cmd_output("lscfg -vp")
+ self.add_cmd_output("lsmcode -A")
+ self.add_cmd_output("lsvpd --debug")
+ self.add_cmd_output("lsvio -des")
+ self.add_cmd_output("servicelog --dump")
+ self.add_cmd_output("servicelog_notify --list")
+ self.add_cmd_output("usysattn")
+ self.add_cmd_output("usysident")
+ self.add_cmd_output("serv_config -l")
+ self.add_cmd_output("bootlist -m both -r")
+ self.add_cmd_output("lparstat -i")
- if isPowerNV:
- self.add_copy_spec("/proc/ppc64/")
+ if isPowerNV:
+ self.add_copy_spec("/proc/ppc64/")
+
diff --git a/sos/plugins/veritas.py b/sos/plugins/veritas.py
index 176e1d16..4a2ce572 100644
--- a/sos/plugins/veritas.py
+++ b/sos/plugins/veritas.py
@@ -38,5 +38,5 @@ class Veritas(Plugin, RedHatPlugin):
tarfile = self.do_regex_find_all(r"ftp (.*tar.gz)", line)
if len(tarfile) == 1:
self.add_copy_spec(tarfile[0])
- except AttributeError, e:
+ except AttributeError as e:
self.add_alert(e)
diff --git a/sos/policies/__init__.py b/sos/policies/__init__.py
index ba2f14b4..e666f0c7 100644
--- a/sos/policies/__init__.py
+++ b/sos/policies/__init__.py
@@ -338,7 +338,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,)))
@@ -354,9 +354,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/sosreport.py b/sos/sosreport.py
index cab7d0c0..04035a92 100644
--- a/sos/sosreport.py
+++ b/sos/sosreport.py
@@ -70,11 +70,11 @@ class TempFileUtil(object):
try:
f.flush()
f.close()
- except Exception, e:
+ except Exception as e:
pass
try:
os.unlink(fname)
- except Exception, e:
+ except Exception as e:
pass
self.files = []
@@ -84,15 +84,15 @@ class OptionParserExtended(OptionParser):
def print_help(self, out=sys.stdout):
""" Prints help content including examples """
OptionParser.print_help(self, out)
- print
- print "Some examples:"
- print
- print " enable cluster plugin only and collect dlm lockdumps:"
- print " # sosreport -o cluster -k cluster.lockdump"
- print
- print " disable memory and samba plugins, turn off rpm -Va collection:"
- print " # sosreport -n memory,samba -k rpm.rpmva=off"
- print
+ print()
+ print( "Some examples:")
+ print()
+ print( " enable cluster plugin only and collect dlm lockdumps:")
+ print( " # sosreport -o cluster -k cluster.lockdump")
+ print()
+ print( " disable memory and samba plugins, turn off rpm -Va collection:")
+ print( " # sosreport -n memory,samba -k rpm.rpmva=off")
+ print()
class SosOption(Option):
"""Allow to specify comma delimited list of plugins"""
@@ -597,9 +597,9 @@ class SoSReport(object):
self.archive = TarFileArchive(archive_name, self.tmpdir)
def _make_archive_paths(self):
- self.archive.makedirs(self.cmddir, 0755)
- self.archive.makedirs(self.logdir, 0755)
- self.archive.makedirs(self.rptdir, 0755)
+ self.archive.makedirs(self.cmddir, 0o755)
+ self.archive.makedirs(self.logdir, 0o755)
+ self.archive.makedirs(self.rptdir, 0o755)
def _set_directories(self):
self.cmddir = 'sos_commands'
@@ -801,7 +801,7 @@ class SoSReport(object):
continue
self._load(plugin_class)
- except Exception, e:
+ except Exception as e:
self.soslog.warning(_("plugin %s does not install, skipping: %s") % (plug, e))
if self.raise_plugins:
raise
@@ -944,7 +944,7 @@ class SoSReport(object):
self.policy.pre_work()
self._set_archive()
self._make_archive_paths()
- except Exception, e:
+ except Exception as e:
import traceback
traceback.print_exc(e)
self.ui_log.info(e)
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):