diff --git a/requirements-dev.txt b/requirements-dev.txt index 37123724..b2799686 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -5,3 +5,6 @@ diff_cover mock pytest pytest-cov +# dependencies also in setup.py until they can be used +six +future diff --git a/setup.py b/setup.py index 9fb2bd83..08c8200d 100644 --- a/setup.py +++ b/setup.py @@ -35,5 +35,7 @@ ], requires=[ 'branding', + 'six', + 'future', ], ) diff --git a/tests/test_cpio.py b/tests/test_cpio.py index 84763b26..628c54ca 100644 --- a/tests/test_cpio.py +++ b/tests/test_cpio.py @@ -1,3 +1,4 @@ +from __future__ import print_function import os import shutil import subprocess @@ -45,8 +46,9 @@ def setUp(self): check_call("gzip -c < archive.cpio > archive.cpio.gz") check_call("bzip2 -c < archive.cpio > archive.cpio.bz2") try: - import lzma - self.doXZ = subprocess.call("xz --check=crc32 --lzma2=dict=1MiB < archive.cpio > archive.cpio.xz", shell=True) == 0 + import lzma # pylint: disable=unused-variable + self.doXZ = subprocess.call("xz --check=crc32 --lzma2=dict=1MiB" + " < archive.cpio > archive.cpio.xz", shell=True) == 0 except Exception as ex: # FIXME will issue warning even if test_xz is not requested warnings.warn("will not test cpio.xz: %s" % ex) @@ -113,7 +115,7 @@ def test_bz2(self): def test_xz(self): if not self.doXZ: raise unittest.SkipTest("lzma package or xz tool not available") - print 'Running test for XZ' + print('Running test for XZ') self.doArchive('archive.cpio.xz', 'xz') # CpioFileCompat testing diff --git a/tests/test_ifrename_dynamic.py b/tests/test_ifrename_dynamic.py index 1eb28a74..6313b861 100644 --- a/tests/test_ifrename_dynamic.py +++ b/tests/test_ifrename_dynamic.py @@ -1,12 +1,10 @@ +from __future__ import unicode_literals import json import logging import unittest from copy import deepcopy -try: - import cStringIO as StringIO -except ImportError: - import StringIO +from io import StringIO from xcp.net.ifrename.dynamic import DynamicRules from xcp.net.ifrename.macpci import MACPCI @@ -16,7 +14,7 @@ class TestLoadAndParse(unittest.TestCase): def setUp(self): - self.logbuf = StringIO.StringIO() + self.logbuf = StringIO() openLog(self.logbuf, logging.NOTSET) def tearDown(self): @@ -26,7 +24,7 @@ def tearDown(self): def test_null(self): - fd = StringIO.StringIO("") + fd = StringIO("") dr = DynamicRules(fd=fd) self.assertTrue(dr.load_and_parse()) @@ -36,7 +34,7 @@ def test_null(self): def test_empty(self): - fd = StringIO.StringIO( + fd = StringIO( '{"lastboot":[],"old":[]}' ) dr = DynamicRules(fd=fd) @@ -48,7 +46,7 @@ def test_empty(self): def test_one_invalid(self): - fd = StringIO.StringIO( + fd = StringIO( '{"lastboot":[["","",""]],"old":[]}' ) dr = DynamicRules(fd=fd) @@ -60,7 +58,7 @@ def test_one_invalid(self): def test_one_valid_lastboot(self): - fd = StringIO.StringIO( + fd = StringIO( '{"lastboot":[["01:23:45:67:89:0a","00:10.2","eth2"]],"old":[]}' ) dr = DynamicRules(fd=fd) @@ -74,7 +72,7 @@ def test_one_valid_lastboot(self): def test_one_valid_lastboot2(self): - fd = StringIO.StringIO( + fd = StringIO( '{"lastboot":[],"old":[["01:23:45:67:89:0a","00:10.2","eth2"]]}' ) dr = DynamicRules(fd=fd) @@ -88,7 +86,7 @@ def test_one_valid_lastboot2(self): class TestGenerate(unittest.TestCase): def setUp(self): - self.logbuf = StringIO.StringIO() + self.logbuf = StringIO() openLog(self.logbuf, logging.NOTSET) def tearDown(self): @@ -149,7 +147,7 @@ def test_pci_missing(self): class TestSave(unittest.TestCase): def setUp(self): - self.logbuf = StringIO.StringIO() + self.logbuf = StringIO() openLog(self.logbuf, logging.NOTSET) def tearDown(self): diff --git a/tests/test_ifrename_logic.py b/tests/test_ifrename_logic.py index 9fa9255c..a1850c20 100644 --- a/tests/test_ifrename_logic.py +++ b/tests/test_ifrename_logic.py @@ -1,12 +1,11 @@ +from __future__ import print_function +from __future__ import unicode_literals import logging import sys import unittest from copy import deepcopy -try: - import cStringIO as StringIO -except ImportError: - import StringIO +from io import StringIO from xcp.net.ifrename.logic import * from xcp.logger import LOG, openLog, closeLogs @@ -34,7 +33,7 @@ def apply_transactions(lst, trans): class TestSimpleLogic(unittest.TestCase): def setUp(self): - self.siobuff = StringIO.StringIO() + self.siobuff = StringIO() openLog(self.siobuff, logging.NOTSET) def tearDown(self): @@ -43,15 +42,15 @@ def tearDown(self): self.siobuff.close() def debug_state(self, ts): - print >>sys.stderr, "" - print >>sys.stderr, self.siobuff.getvalue() - print >>sys.stderr, "" + print("", file=sys.stderr) + print(self.siobuff.getvalue(), file=sys.stderr) + print("", file=sys.stderr) if len(ts): for (s,d) in ts: - print >>sys.stderr, "'%s' -> '%s'" % (s, d) + print("'%s' -> '%s'" % (s, d), file=sys.stderr) else: - print >>sys.stderr, "No transactions" - print >>sys.stderr, "" + print("No transactions", file=sys.stderr) + print("", file=sys.stderr) def test_newhw_norules_1eth(self): @@ -259,7 +258,7 @@ def test_1drule_1eth_already_complete(self): class TestUseCases(unittest.TestCase): def setUp(self): - self.siobuff = StringIO.StringIO() + self.siobuff = StringIO() openLog(self.siobuff, logging.NOTSET) def tearDown(self): @@ -268,16 +267,16 @@ def tearDown(self): self.siobuff.close() def debug_state(self, ts): - print >>sys.stderr, "" - print >>sys.stderr, self.siobuff.getvalue() - print >>sys.stderr, "" + print("", file=sys.stderr) + print(self.siobuff.getvalue(), file=sys.stderr) + print("", file=sys.stderr) if len(ts): - print >>sys.stderr, "Transactions:" + print("Transactions:", file=sys.stderr) for (s,d) in ts: - print >>sys.stderr, "'%s' -> '%s'" % (s, d) + print("'%s' -> '%s'" % (s, d), file=sys.stderr) else: - print >>sys.stderr, "No transactions" - print >>sys.stderr, "" + print("No transactions", file=sys.stderr) + print("", file=sys.stderr) def test_usecase1(self): """ @@ -533,7 +532,7 @@ def setUp(self): set to None and a tname set to the 'eth' """ - self.siobuff = StringIO.StringIO() + self.siobuff = StringIO() openLog(self.siobuff) @@ -559,7 +558,7 @@ def assertNotRaises(self, excp, fn, *argl, **kwargs): """Because unittest.TestCase seems to be missing this functionality""" try: fn(*argl, **kwargs) - except excp, e: + except excp as e: self.fail("function raised %s unexpectedly: %s" % (excp, e)) diff --git a/tests/test_ifrename_static.py b/tests/test_ifrename_static.py index 16909142..9b11e380 100644 --- a/tests/test_ifrename_static.py +++ b/tests/test_ifrename_static.py @@ -1,11 +1,9 @@ +from __future__ import unicode_literals import logging import unittest from copy import deepcopy -try: - import cStringIO as StringIO -except ImportError: - import StringIO +from io import StringIO from xcp.net.ifrename.static import StaticRules from xcp.net.ifrename.macpci import MACPCI @@ -15,7 +13,7 @@ class TestLoadAndParse(unittest.TestCase): def setUp(self): - self.logbuf = StringIO.StringIO() + self.logbuf = StringIO() openLog(self.logbuf, logging.NOTSET) def tearDown(self): @@ -37,7 +35,7 @@ def test_null(self): def test_empty(self): - fd = StringIO.StringIO("") + fd = StringIO("") sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -46,7 +44,7 @@ def test_empty(self): def test_comment(self): - fd = StringIO.StringIO("#comment") + fd = StringIO("#comment") sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -55,7 +53,7 @@ def test_comment(self): def test_comment_and_empty(self): - fd = StringIO.StringIO("\n # Another Comment\n ") + fd = StringIO("\n # Another Comment\n ") sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -64,7 +62,7 @@ def test_comment_and_empty(self): def test_single_incorrect_mac(self): - fd = StringIO.StringIO('eth0:mac="foo"') + fd = StringIO('eth0:mac="foo"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -73,7 +71,7 @@ def test_single_incorrect_mac(self): def test_single_mac(self): - fd = StringIO.StringIO('eth0:mac="AB:CD:EF:AB:CD:EF"') + fd = StringIO('eth0:mac="AB:CD:EF:AB:CD:EF"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -82,7 +80,7 @@ def test_single_mac(self): def test_single_invalid_pci(self): - fd = StringIO.StringIO('eth0:pci="bar"') + fd = StringIO('eth0:pci="bar"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -91,7 +89,7 @@ def test_single_invalid_pci(self): def test_single_pci(self): - fd = StringIO.StringIO('eth0:pci="0000:00:00.1"') + fd = StringIO('eth0:pci="0000:00:00.1"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -100,7 +98,7 @@ def test_single_pci(self): def test_single_pci_0index(self): - fd = StringIO.StringIO('eth0:pci="0000:00:00.1[0]"') + fd = StringIO('eth0:pci="0000:00:00.1[0]"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -109,7 +107,7 @@ def test_single_pci_0index(self): def test_single_invalid_ppn(self): - fd = StringIO.StringIO('eth0:ppn="baz"') + fd = StringIO('eth0:ppn="baz"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -118,7 +116,7 @@ def test_single_invalid_ppn(self): def test_single_ppn_embedded(self): - fd = StringIO.StringIO('eth0:ppn="em2"') + fd = StringIO('eth0:ppn="em2"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -127,7 +125,7 @@ def test_single_ppn_embedded(self): def test_single_ppn_slot(self): - fd = StringIO.StringIO('eth0:ppn="p2p3"') + fd = StringIO('eth0:ppn="p2p3"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -136,7 +134,7 @@ def test_single_ppn_slot(self): def test_single_oldsytle_ppn_slot(self): # CA-82901 - Accept old-style PPNs but translate them to new-style - fd = StringIO.StringIO('eth0:ppn="pci2p3"') + fd = StringIO('eth0:ppn="pci2p3"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -145,7 +143,7 @@ def test_single_oldsytle_ppn_slot(self): def test_single_label(self): - fd = StringIO.StringIO('eth0:label="somestring"') + fd = StringIO('eth0:label="somestring"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -155,7 +153,7 @@ def test_single_label(self): class TestLoadAndParseGuess(unittest.TestCase): def setUp(self): - self.logbuf = StringIO.StringIO() + self.logbuf = StringIO() openLog(self.logbuf, logging.NOTSET) def tearDown(self): @@ -165,7 +163,7 @@ def tearDown(self): def test_single_explicit_label(self): - fd = StringIO.StringIO("eth0=\"foo\"") + fd = StringIO("eth0=\"foo\"") sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -174,7 +172,7 @@ def test_single_explicit_label(self): def test_single_implicit_label(self): - fd = StringIO.StringIO("eth0=foo") + fd = StringIO("eth0=foo") sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -183,7 +181,7 @@ def test_single_implicit_label(self): def test_single_mac(self): - fd = StringIO.StringIO("eth0=00:00:00:00:00:00") + fd = StringIO("eth0=00:00:00:00:00:00") sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -192,7 +190,7 @@ def test_single_mac(self): def test_single_pci(self): - fd = StringIO.StringIO("eth0=0000:00:00.0") + fd = StringIO("eth0=0000:00:00.0") sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -201,7 +199,7 @@ def test_single_pci(self): def test_single_pci_index(self): - fd = StringIO.StringIO("eth0=0000:00:00.0[1]") + fd = StringIO("eth0=0000:00:00.0[1]") sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -210,7 +208,7 @@ def test_single_pci_index(self): def test_single_ppn_embedded(self): - fd = StringIO.StringIO("eth0=em4") + fd = StringIO("eth0=em4") sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -219,7 +217,7 @@ def test_single_ppn_embedded(self): def test_single_ppn_slot(self): - fd = StringIO.StringIO("eth0=p1p2") + fd = StringIO("eth0=p1p2") sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -230,7 +228,7 @@ def test_single_ppn_slot(self): class TestGenerate(unittest.TestCase): def setUp(self): - self.logbuf = StringIO.StringIO() + self.logbuf = StringIO() openLog(self.logbuf, logging.NOTSET) self.state = [ @@ -251,7 +249,7 @@ def tearDown(self): def test_null(self): - fd = StringIO.StringIO('eth0:label="somestring"') + fd = StringIO('eth0:label="somestring"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) sr.generate([]) @@ -260,7 +258,7 @@ def test_null(self): def test_single_not_matching_state(self): - fd = StringIO.StringIO('eth0:label="somestring"') + fd = StringIO('eth0:label="somestring"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) sr.generate(self.state) @@ -269,7 +267,7 @@ def test_single_not_matching_state(self): def test_single_mac_matching(self): - fd = StringIO.StringIO('eth0:mac="01:23:45:67:89:0a"') + fd = StringIO('eth0:mac="01:23:45:67:89:0a"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -281,7 +279,7 @@ def test_single_mac_matching(self): def test_single_pci_matching(self): - fd = StringIO.StringIO('eth0:pci="0000:00:10.0"') + fd = StringIO('eth0:pci="0000:00:10.0"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -293,7 +291,7 @@ def test_single_pci_matching(self): def test_single_ppn_embedded_matching(self): - fd = StringIO.StringIO('eth0:ppn="em1"') + fd = StringIO('eth0:ppn="em1"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -305,7 +303,7 @@ def test_single_ppn_embedded_matching(self): def test_single_ppn_slot_matching(self): - fd = StringIO.StringIO('eth0:ppn="p2p2"') + fd = StringIO('eth0:ppn="p2p2"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -317,7 +315,7 @@ def test_single_ppn_slot_matching(self): def test_single_label_matching(self): - fd = StringIO.StringIO('eth0:label="Ethernet1"') + fd = StringIO('eth0:label="Ethernet1"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -330,8 +328,8 @@ def test_single_label_matching(self): def test_ppn_quirks(self): # Test case taken from example on CA-75599 - fd = StringIO.StringIO('eth0:ppn="em1"\n' - 'eth1:ppn="em2"') + fd = StringIO('eth0:ppn="em1"\n' + 'eth1:ppn="em2"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -350,7 +348,7 @@ def test_ppn_quirks(self): class TestMultiplePCI(unittest.TestCase): def setUp(self): - self.logbuf = StringIO.StringIO() + self.logbuf = StringIO() openLog(self.logbuf, logging.NOTSET) self.state = [ MACPCI("c8:cb:b8:d3:0c:ca", "0000:03:00.0", kname="eth0", @@ -370,8 +368,8 @@ def tearDown(self): def test_pci_matching(self): - fd = StringIO.StringIO('eth0:pci="0000:04:00.0"\n' - 'eth1:pci="0000:04:00.0[1]"') + fd = StringIO('eth0:pci="0000:04:00.0"\n' + 'eth1:pci="0000:04:00.0[1]"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -384,8 +382,8 @@ def test_pci_matching(self): def test_pci_matching_invert(self): - fd = StringIO.StringIO('eth0:pci="0000:04:00.0[1]"\n' - 'eth1:pci="0000:04:00.0[0]"') + fd = StringIO('eth0:pci="0000:04:00.0[1]"\n' + 'eth1:pci="0000:04:00.0[0]"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -398,8 +396,8 @@ def test_pci_matching_invert(self): def test_pci_matching_mixed(self): - fd = StringIO.StringIO('eth0:ppn="em3"\n' - 'eth1:pci="0000:04:00.0[1]"') + fd = StringIO('eth0:ppn="em3"\n' + 'eth1:pci="0000:04:00.0[1]"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -412,8 +410,8 @@ def test_pci_matching_mixed(self): def test_pci_missing(self): - fd = StringIO.StringIO('eth0:pci="0000:03:00.0"\n' - 'eth4:pci="0000:05:00.0"') + fd = StringIO('eth0:pci="0000:03:00.0"\n' + 'eth4:pci="0000:05:00.0"') sr = StaticRules(fd = fd) self.assertTrue(sr.load_and_parse()) @@ -427,7 +425,7 @@ def test_pci_missing(self): class TestSave(unittest.TestCase): def setUp(self): - self.logbuf = StringIO.StringIO() + self.logbuf = StringIO() openLog(self.logbuf, logging.NOTSET) def tearDown(self): diff --git a/tests/test_pci.py b/tests/test_pci.py index 736b55de..ac03c375 100644 --- a/tests/test_pci.py +++ b/tests/test_pci.py @@ -9,7 +9,6 @@ class TestInvalid(unittest.TestCase): def test_invalid_types(self): self.assertRaises(TypeError, PCI, 0) - self.assertRaises(TypeError, PCI, 0L) self.assertRaises(TypeError, PCI, (0,)) self.assertRaises(TypeError, PCI, []) self.assertRaises(TypeError, PCI, {}) diff --git a/xcp/accessor.py b/xcp/accessor.py index 22f9e24f..6d057927 100644 --- a/xcp/accessor.py +++ b/xcp/accessor.py @@ -25,13 +25,16 @@ """accessor - provide common interface to access methods""" +# pylint: disable=wrong-import-position,wrong-import-order +from future import standard_library +standard_library.install_aliases() + import ftplib import os import tempfile -import types -import urllib -import urllib2 -import urlparse +import urllib.request # pylint: disable=import-error +import urllib.error # pylint: disable=import-error +import urllib.parse # pylint: disable=import-error import errno import xcp.mount as mount @@ -68,7 +71,7 @@ def access(self, name): return True - def openAddress(self, name): + def openAddress(self, address): """should be overloaded""" pass @@ -96,9 +99,9 @@ def __init__(self, location, ro): super(FilesystemAccessor, self).__init__(ro) self.location = location - def openAddress(self, addr): + def openAddress(self, address): try: - file = open(os.path.join(self.location, addr), 'r') + filehandle = open(os.path.join(self.location, address), 'r') except OSError as e: if e.errno == errno.EIO: self.lastError = 5 @@ -114,11 +117,11 @@ def openAddress(self, addr): except Exception as e: self.lastError = 500 return False - return file + return filehandle class MountingAccessor(FilesystemAccessor): - def __init__(self, mount_types, mount_source, mount_options = None): - ro = isinstance(mount_options, types.ListType) and 'ro' in mount_options + def __init__(self, mount_types, mount_source, mount_options=None): + ro = isinstance(mount_options, list) and 'ro' in mount_options super(MountingAccessor, self).__init__(None, ro) self.mount_types = mount_types @@ -135,7 +138,7 @@ def start(self): try: opts = self.mount_options if fs == 'iso9660': - if isinstance(opts, types.ListType): + if isinstance(opts, list): if 'ro' not in opts: opts.append('ro') else: @@ -251,14 +254,14 @@ def rebuild_url(url_parts): host = url_parts.hostname if url_parts.port: host += ':' + str(url_parts.port) - return urlparse.urlunsplit( + return urllib.parse.urlunsplit( (url_parts.scheme, host, url_parts.path, '', '')) class FTPAccessor(Accessor): def __init__(self, baseAddress, ro): super(FTPAccessor, self).__init__(ro) - self.url_parts = urlparse.urlsplit(baseAddress, allow_fragments=False) + self.url_parts = urllib.parse.urlsplit(baseAddress, allow_fragments=False) self.start_count = 0 self.cleanup = False self.ftp = None @@ -281,12 +284,12 @@ def start(self): username = self.url_parts.username password = self.url_parts.password if username: - username = urllib.unquote(username) + username = urllib.parse.unquote(username) if password: - password = urllib.unquote(password) + password = urllib.parse.unquote(password) self.ftp.login(username, password) - directory = urllib.unquote(self.url_parts.path[1:]) + directory = urllib.parse.unquote(self.url_parts.path[1:]) if directory != '': logger.debug("Changing to " + directory) self.ftp.cwd(directory) @@ -306,12 +309,12 @@ def access(self, path): try: logger.debug("Testing "+path) self._cleanup() - url = urllib.unquote(path) + url = urllib.parse.unquote(path) if self.ftp.size(url) is not None: return True lst = self.ftp.nlst(os.path.dirname(url)) - return os.path.basename(url) in map(os.path.basename, lst) + return os.path.basename(url) in list(map(os.path.basename, lst)) except IOError as e: if e.errno == errno.EIO: self.lastError = 5 @@ -331,7 +334,7 @@ def access(self, path): def openAddress(self, address): logger.debug("Opening "+address) self._cleanup() - url = urllib.unquote(address) + url = urllib.parse.unquote(address) self.ftp.voidcmd('TYPE I') s = self.ftp.transfercmd('RETR ' + url).makefile('rb') @@ -340,7 +343,7 @@ def openAddress(self, address): def writeFile(self, in_fh, out_name): self._cleanup() - fname = urllib.unquote(out_name) + fname = urllib.parse.unquote(out_name) logger.debug("Storing as " + fname) self.ftp.storbinary('STOR ' + fname, in_fh) @@ -352,28 +355,28 @@ class HTTPAccessor(Accessor): def __init__(self, baseAddress, ro): assert ro super(HTTPAccessor, self).__init__(ro) - self.url_parts = urlparse.urlsplit(baseAddress, allow_fragments=False) + self.url_parts = urllib.parse.urlsplit(baseAddress, allow_fragments=False) if self.url_parts.username: username = self.url_parts.username if username is not None: - username = urllib.unquote(self.url_parts.username) + username = urllib.parse.unquote(self.url_parts.username) password = self.url_parts.password if password is not None: - password = urllib.unquote(self.url_parts.password) - self.passman = urllib2.HTTPPasswordMgrWithDefaultRealm() + password = urllib.parse.unquote(self.url_parts.password) + self.passman = urllib.request.HTTPPasswordMgrWithDefaultRealm() self.passman.add_password(None, self.url_parts.hostname, username, password) - self.authhandler = urllib2.HTTPBasicAuthHandler(self.passman) - self.opener = urllib2.build_opener(self.authhandler) - urllib2.install_opener(self.opener) + self.authhandler = urllib.request.HTTPBasicAuthHandler(self.passman) + self.opener = urllib.request.build_opener(self.authhandler) + urllib.request.install_opener(self.opener) self.baseAddress = rebuild_url(self.url_parts) def openAddress(self, address): try: - urlFile = urllib2.urlopen(os.path.join(self.baseAddress, address)) - except urllib2.HTTPError as e: + urlFile = urllib.request.urlopen(os.path.join(self.baseAddress, address)) + except urllib.error.HTTPError as e: self.lastError = e.code return False return urlFile @@ -390,7 +393,7 @@ def __repr__(self): } def createAccessor(baseAddress, *args): - url_parts = urlparse.urlsplit(baseAddress, allow_fragments=False) + url_parts = urllib.parse.urlsplit(baseAddress, allow_fragments=False) - assert url_parts.scheme in SUPPORTED_ACCESSORS.keys() + assert url_parts.scheme in SUPPORTED_ACCESSORS return SUPPORTED_ACCESSORS[url_parts.scheme](baseAddress, *args) diff --git a/xcp/bootloader.py b/xcp/bootloader.py index 51e362e8..a1d19709 100644 --- a/xcp/bootloader.py +++ b/xcp/bootloader.py @@ -23,6 +23,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +from __future__ import print_function +from __future__ import division import os import os.path import re @@ -144,13 +146,12 @@ def readExtLinux(cls, src_file): title = l[1:].lstrip() elif keywrd == 'kernel' and len(els) > 1: kernel = els[1] - elif keywrd == 'append' and len(els) > 1 and \ - kernel == 'mboot.c32': + elif keywrd == 'append' and len(els) > 1 and kernel == 'mboot.c32': if 'tboot' in els[1]: # els[2] contains tboot args, hypervisor, # hypervisor args, kernel, # kernel args & initrd - args = map(lambda x: x.strip(), els[2].split('---')) + args = [x.strip() for x in els[2].split('---')] if len(args) == 4: hypervisor = args[1].split(None, 1) kernel = args[2].split(None, 1) @@ -166,7 +167,7 @@ def readExtLinux(cls, src_file): elif 'xen' in els[1]: # els[2] contains hypervisor args, kernel, # kernel args & initrd - args = map(lambda x: x.strip(), els[2].split('---')) + args = [x.strip() for x in els[2].split('---')] if len(args) == 3: kernel = args[1].split(None, 1) if len(kernel) == 2: @@ -431,7 +432,7 @@ def create_label(title): # If this fails, it is probably a string, so leave it unchanged. try: default = menu_order[int(default)] - except ValueError, KeyError: + except (ValueError, KeyError): pass finally: fh.close() @@ -455,47 +456,47 @@ def loadExisting(cls, root = '/'): elif os.path.exists(os.path.join(root, "boot/grub/menu.lst")): return cls.readGrub(os.path.join(root, "boot/grub/menu.lst")) else: - raise RuntimeError, "No existing bootloader configuration found" + raise RuntimeError("No existing bootloader configuration found") def writeExtLinux(self, dst_file = None): if hasattr(dst_file, 'name'): fh = dst_file else: fh = open(dst_file, 'w') - print >> fh, "# location " + self.location + print("# location " + self.location, file=fh) if self.serial: if self.serial.get('flow', None) is None: - print >> fh, "serial %s %s" % (self.serial['port'], - self.serial['baud']) + print("serial %s %s" % (self.serial['port'], + self.serial['baud']), file=fh) else: - print >> fh, "serial %s %s %s" % (self.serial['port'], - self.serial['baud'], - self.serial['flow']) + print("serial %s %s %s" % (self.serial['port'], + self.serial['baud'], + self.serial['flow']), file=fh) if self.default: - print >> fh, "default " + self.default - print >> fh, "prompt 1" + print("default " + self.default, file=fh) + print("prompt 1", file=fh) if self.timeout: - print >> fh, "timeout %d" % self.timeout + print("timeout %d" % self.timeout, file=fh) for label in self.menu_order: - print >> fh, "\nlabel " + label + print("\nlabel " + label, file=fh) m = self.menu[label] if m.title: - print >> fh, " # " + m.title + print(" # " + m.title, file=fh) if m.tboot: - print >> fh, " kernel mboot.c32" - print >> fh, " append %s %s --- %s %s --- %s %s --- %s" % \ - (m.tboot, m.tboot_args, m.hypervisor, m.hypervisor_args, - m.kernel, m.kernel_args, m.initrd) + print(" kernel mboot.c32", file=fh) + print(" append %s %s --- %s %s --- %s %s --- %s" % + (m.tboot, m.tboot_args, m.hypervisor, m.hypervisor_args, + m.kernel, m.kernel_args, m.initrd), file=fh) elif m.hypervisor: - print >> fh, " kernel mboot.c32" - print >> fh, " append %s %s --- %s %s --- %s" % \ - (m.hypervisor, m.hypervisor_args, m.kernel, m.kernel_args, m.initrd) + print(" kernel mboot.c32", file=fh) + print(" append %s %s --- %s %s --- %s" % + (m.hypervisor, m.hypervisor_args, m.kernel, m.kernel_args, m.initrd), file=fh) else: - print >> fh, " kernel " + m.kernel - print >> fh, " append " + m.kernel_args - print >> fh, " initrd " + m.initrd + print(" kernel " + m.kernel, file=fh) + print(" append " + m.kernel_args, file=fh) + print(" initrd " + m.initrd, file=fh) if not hasattr(dst_file, 'name'): fh.close() @@ -504,32 +505,32 @@ def writeGrub(self, dst_file = None): fh = dst_file else: fh = open(dst_file, 'w') - print >> fh, "# location " + self.location + print("# location " + self.location, file=fh) if self.serial: - print >> fh, "serial --unit=%s --speed=%s" % (self.serial['port'], - self.serial['baud']) - print >> fh, "terminal --timeout=10 console serial" + print("serial --unit=%s --speed=%s" % + (self.serial['port'], self.serial['baud']), file=fh) + print("terminal --timeout=10 console serial", file=fh) else: - print >> fh, "terminal console" + print("terminal console", file=fh) if self.default: for i in range(len(self.menu_order)): if self.menu_order[i] == self.default: - print >> fh, "default %d" % i + print("default %d" % i, file=fh) break if self.timeout: - print >> fh, "timeout %d" % (self.timeout / 10) + print("timeout %d" % (self.timeout // 10), file=fh) for label in self.menu_order: m = self.menu[label] - print >> fh, "\ntitle " + m.title + print("\ntitle " + m.title, file=fh) if m.hypervisor: - print >> fh, " kernel " + m.hypervisor + " " + m.hypervisor_args - print >> fh, " module " + m.kernel + " " + m.kernel_args - print >> fh, " module " + m.initrd + print(" kernel " + m.hypervisor + " " + m.hypervisor_args, file=fh) + print(" module " + m.kernel + " " + m.kernel_args, file=fh) + print(" module " + m.initrd, file=fh) else: - print >> fh, " kernel " + m.kernel + " " + m.kernel_args - print >> fh, " initrd " + m.initrd + print(" kernel " + m.kernel + " " + m.kernel_args, file=fh) + print(" initrd " + m.initrd, file=fh) if not hasattr(dst_file, 'name'): fh.close() @@ -540,19 +541,19 @@ def writeGrub2(self, dst_file = None): fh = open(dst_file, 'w') if self.serial: - print >> fh, "serial --unit=%s --speed=%s" % (self.serial['port'], - self.serial['baud']) - print >> fh, "terminal_input serial console" - print >> fh, "terminal_output serial console" + print("serial --unit=%s --speed=%s" % (self.serial['port'], + self.serial['baud']), file=fh) + print("terminal_input serial console", file=fh) + print("terminal_output serial console", file=fh) if self.default: for i in range(len(self.menu_order)): if self.menu_order[i] == self.default: - print >> fh, "set default=%d" % i + print("set default=%d" % i, file=fh) break else: - print >> fh, "set default='%s'" % str(self.default) + print("set default='%s'" % str(self.default), file=fh) if self.timeout: - print >> fh, "set timeout=%d" % (self.timeout / 10) + print("set timeout=%d" % (self.timeout // 10), file=fh) boilerplate = getattr(self, 'boilerplate', [])[:] boilerplate.reverse() @@ -563,41 +564,41 @@ def writeGrub2(self, dst_file = None): if boilerplate: text = boilerplate.pop() if text: - print >> fh, "\n".join(text) + print("\n".join(text), file=fh) extra = ' ' try: extra = m.extra except AttributeError: pass - print >> fh, "menuentry '%s'%s{" % (m.title, extra) + print("menuentry '%s'%s{" % (m.title, extra), file=fh) try: contents = "\n".join(m.contents) if contents: - print >> fh, contents + print(contents, file=fh) except AttributeError: pass if m.root: - print >> fh, "\tsearch --label --set root %s" % m.root + print("\tsearch --label --set root %s" % m.root, file=fh) if m.hypervisor: if m.tboot: - print >> fh, "\tmultiboot2 %s %s" % (m.tboot, m.tboot_args) - print >> fh, "\tmodule2 %s %s" % (m.hypervisor, m.hypervisor_args) + print("\tmultiboot2 %s %s" % (m.tboot, m.tboot_args), file=fh) + print("\tmodule2 %s %s" % (m.hypervisor, m.hypervisor_args), file=fh) else: - print >> fh, "\tmultiboot2 %s %s" % (m.hypervisor, m.hypervisor_args) + print("\tmultiboot2 %s %s" % (m.hypervisor, m.hypervisor_args), file=fh) if m.kernel: - print >> fh, "\tmodule2 %s %s" % (m.kernel, m.kernel_args) + print("\tmodule2 %s %s" % (m.kernel, m.kernel_args), file=fh) if m.initrd: - print >> fh, "\tmodule2 %s" % m.initrd + print("\tmodule2 %s" % m.initrd, file=fh) else: if m.kernel: - print >> fh, "\tlinux %s %s" % (m.kernel, m.kernel_args) + print("\tlinux %s %s" % (m.kernel, m.kernel_args), file=fh) if m.initrd: - print >> fh, "\tinitrd %s" % m.initrd - print >> fh, "}" + print("\tinitrd %s" % m.initrd, file=fh) + print("}", file=fh) if not hasattr(dst_file, 'name'): fh.close() @@ -642,9 +643,9 @@ def newDefault(cls, kernel_link_name, initrd_link_name, root = '/'): if b.menu[b.default].kernel != kernel_link_name: backup = [] if not os.path.exists(os.path.join(root, kernel_link_name[1:])): - raise RuntimeError, "kernel symlink not found" + raise RuntimeError("kernel symlink not found") if not os.path.exists(os.path.join(root, initrd_link_name[1:])): - raise RuntimeError, "initrd symlink not found" + raise RuntimeError("initrd symlink not found") old_kernel_link = b.menu[b.default].kernel old_ver = 'old' m = re.search(r'(-\d+\.\d+)-', old_kernel_link) diff --git a/xcp/cmd.py b/xcp/cmd.py index ff039484..bbd94656 100644 --- a/xcp/cmd.py +++ b/xcp/cmd.py @@ -56,7 +56,7 @@ def runCmd(command, with_stdout = False, with_stderr = False, inputtext = None): return rv, err return rv -class OutputCache: +class OutputCache(object): def __init__(self): self.cache = {} diff --git a/xcp/cpiofile.py b/xcp/cpiofile.py index a490aeff..a3905786 100755 --- a/xcp/cpiofile.py +++ b/xcp/cpiofile.py @@ -33,6 +33,7 @@ Derived from Lars Gustäbel's tarfile.py """ +from __future__ import print_function __version__ = "0.1" __author__ = "Simon Rowe" @@ -50,12 +51,14 @@ import struct import copy +import six + if sys.platform == 'mac': # This module needs work for MacOS9, especially in the area of pathname # handling. In many places it is assumed a simple substitution of / by the # local os.path.sep is good enough to convert pathnames, but this does not # work with the mac rooted:path:name versus :nonrooted:path:name syntax - raise ImportError, "cpiofile does not work for platform==mac" + raise ImportError("cpiofile does not work for platform==mac") try: import grp as GRP, pwd as PWD @@ -78,26 +81,26 @@ #--------------------------------------------------------- # Bits used in the mode field, values in octal. #--------------------------------------------------------- -S_IFLNK = 0120000 # symbolic link -S_IFREG = 0100000 # regular file -S_IFBLK = 0060000 # block device -S_IFDIR = 0040000 # directory -S_IFCHR = 0020000 # character device -S_IFIFO = 0010000 # fifo - -TSUID = 04000 # set UID on execution -TSGID = 02000 # set GID on execution -TSVTX = 01000 # reserved - -TUREAD = 0400 # read by owner -TUWRITE = 0200 # write by owner -TUEXEC = 0100 # execute/search by owner -TGREAD = 0040 # read by group -TGWRITE = 0020 # write by group -TGEXEC = 0010 # execute/search by group -TOREAD = 0004 # read by other -TOWRITE = 0002 # write by other -TOEXEC = 0001 # execute/search by other +S_IFLNK = 0o120000 # symbolic link +S_IFREG = 0o100000 # regular file +S_IFBLK = 0o060000 # block device +S_IFDIR = 0o040000 # directory +S_IFCHR = 0o020000 # character device +S_IFIFO = 0o010000 # fifo + +TSUID = 0o4000 # set UID on execution +TSGID = 0o2000 # set GID on execution +TSVTX = 0o1000 # reserved + +TUREAD = 0o400 # read by owner +TUWRITE = 0o200 # write by owner +TUEXEC = 0o100 # execute/search by owner +TGREAD = 0o040 # read by group +TGWRITE = 0o020 # write by group +TGEXEC = 0o010 # execute/search by group +TOREAD = 0o004 # read by other +TOWRITE = 0o002 # write by other +TOEXEC = 0o001 # execute/search by other #--------------------------------------------------------- # Some useful functions @@ -115,7 +118,7 @@ def copyfileobj(src, dst, length=None): bufsize = 16 * 1024 blocks, remainder = divmod(length, bufsize) - for _ in xrange(blocks): + for b in range(blocks): buf = src.read(bufsize) if len(buf) < bufsize: raise IOError("end of file reached") @@ -253,7 +256,7 @@ def __init__(self, name, mode, comptype, fileobj, bufsize): self.fileobj = fileobj self.bufsize = bufsize self.buf = "" - self.pos = 0L + self.pos = 0 self.closed = False if comptype == "gz": @@ -302,7 +305,7 @@ def _init_write_gz(self): -self.zlib.MAX_WBITS, self.zlib.DEF_MEM_LEVEL, 0) - timestamp = struct.pack("= 0: blocks, remainder = divmod(pos - self.pos, self.bufsize) - for _ in xrange(blocks): + for i in range(blocks): self.read(self.bufsize) self.read(remainder) else: @@ -812,7 +815,7 @@ def __init__(self, name=""): of the member. """ self.ino = 0 # i-node - self.mode = S_IFREG | 0444 + self.mode = S_IFREG | 0o444 self.uid = 0 # user id self.gid = 0 # group id self.nlink = 1 # number of links @@ -916,7 +919,7 @@ def isdev(self): return (stat.S_ISCHR(self.mode) or stat.S_ISBLK(self.mode)) # class CpioInfo -class CpioFile(object): +class CpioFile(six.Iterator): """The CpioFile Class provides an interface to cpio archives. """ @@ -966,22 +969,22 @@ def __init__(self, name=None, mode="r", fileobj=None): self.closed = False self.members = [] # list of members as CpioInfo objects self._loaded = False # flag if all members have been read - self.offset = 0L # current position in the archive file + self.offset = 0 # current position in the archive file self.inodes = {} # dictionary caching the inodes of # archive members already added if self._mode == "r": self.firstmember = None - self.firstmember = self.next() + self.firstmember = next(self) if self._mode == "a": # Move to the end of the archive, # before the trailer. self.firstmember = None - last_offset = 0L + last_offset = 0 while True: try: - cpioinfo = self.next() + cpioinfo = next(self) except ReadError: self.fileobj.seek(0) break @@ -1109,8 +1112,7 @@ def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9): fileobj = file(name, mode + "b") try: - t = cls.cpioopen(name, mode, - gzip.GzipFile(name, mode, compresslevel, fileobj)) + t = cls.cpioopen(name, mode, gzip.GzipFile(name, mode, compresslevel, fileobj)) except IOError: raise ReadError("not a gzip file") t._extfileobj = False @@ -1280,7 +1282,7 @@ def getcpioinfo(self, name=None, arcname=None, fileobj=None): if stat.S_ISREG(stmd): cpioinfo.size = statres.st_size else: - cpioinfo.size = 0L + cpioinfo.size = 0 cpioinfo.devmajor = os.major(statres.st_dev) cpioinfo.devminor = os.minor(statres.st_dev) if stat.S_ISCHR(stmd) or stat.S_ISBLK(stmd): @@ -1302,17 +1304,15 @@ def list(self, verbose=True): for cpioinfo in self: if verbose: - print filemode(cpioinfo.mode), - print "%d/%d" % (cpioinfo.uid, cpioinfo.gid), + print(filemode(cpioinfo.mode), end=' ') + print("%d/%d" % (cpioinfo.uid, cpioinfo.gid), end=' ') if cpioinfo.ischr() or cpioinfo.isblk(): - print "%10s" % ("%d,%d" \ - % (cpioinfo.devmajor, cpioinfo.devminor)), + print("%10s" % ("%d,%d" % (cpioinfo.devmajor, cpioinfo.devminor)), end=' ') else: - print "%10d" % cpioinfo.size, - print "%d-%02d-%02d %02d:%02d:%02d" \ - % time.localtime(cpioinfo.mtime)[:6], + print("%10d" % cpioinfo.size, end=' ') + print("%d-%02d-%02d %02d:%02d:%02d" % time.localtime(cpioinfo.mtime)[:6], end=' ') - print cpioinfo.name + print(cpioinfo.name) def add(self, name, arcname=None, recursive=True): """Add the file `name' to the archive. `name' may be any type of file @@ -1377,7 +1377,7 @@ def addfile(self, cpioinfo, fileobj=None): cpioinfo = copy.copy(cpioinfo) if cpioinfo.nlink > 1: - if self.hardlinks and self.inodes.has_key(cpioinfo.ino): + if self.hardlinks and cpioinfo.ino in self.inodes: # this inode has already been added cpioinfo.size = 0 self.inodes[cpioinfo.ino].append(cpioinfo.name) @@ -1418,7 +1418,7 @@ def extractall(self, path=".", members=None): # Extract directory with a safe mode, so that # all files below can be extracted as well. try: - os.makedirs(os.path.join(path, cpioinfo.name), 0777) + os.makedirs(os.path.join(path, cpioinfo.name), 0o777) except EnvironmentError: pass directories.append(cpioinfo) @@ -1436,7 +1436,7 @@ def extractall(self, path=".", members=None): self.chown(cpioinfo, path) self.utime(cpioinfo, path) self.chmod(cpioinfo, path) - except ExtractError, e: + except ExtractError as e: if self.errorlevel > 1: raise else: @@ -1462,7 +1462,7 @@ def extract(self, member, path=""): try: self._extract_member(cpioinfo, os.path.join(path, cpioinfo.name)) - except EnvironmentError, e: + except EnvironmentError as e: if self.errorlevel > 0: raise else: @@ -1470,7 +1470,7 @@ def extract(self, member, path=""): self._dbg(1, "cpiofile: %s" % e.strerror) else: self._dbg(1, "cpiofile: %s %r" % (e.strerror, e.filename)) - except ExtractError, e: + except ExtractError as e: if self.errorlevel > 1: raise else: @@ -1525,7 +1525,7 @@ def _extract_member(self, cpioinfo, cpiogetpath): if upperdirs and not os.path.exists(upperdirs): ti = CpioInfo() ti.name = upperdirs - ti.mode = S_IFDIR | 0777 + ti.mode = S_IFDIR | 0o777 ti.mtime = cpioinfo.mtime ti.uid = cpioinfo.uid ti.gid = cpioinfo.gid @@ -1567,7 +1567,7 @@ def makedir(self, cpioinfo, cpiogetpath): """ try: os.mkdir(cpiogetpath) - except EnvironmentError, e: + except EnvironmentError as e: if e.errno != errno.EEXIST: raise @@ -1578,7 +1578,7 @@ def makefile(self, cpioinfo, cpiogetpath): if cpioinfo.nlink == 1: extractinfo = cpioinfo else: - if self.inodes.has_key(cpioinfo.ino): + if cpioinfo.ino in self.inodes: # actual file exists, create link # FIXME handle platforms that don't support hardlinks os.link(os.path.join(cpioinfo._link_path, @@ -1697,7 +1697,7 @@ def utime(self, cpioinfo, cpiogetpath): raise ExtractError("could not change modification time") #-------------------------------------------------------------------------- - def next(self): + def __next__(self): """Return the next member of the archive as a CpioInfo object, when CpioFile is opened for reading. Return None if there is no more available. @@ -1738,7 +1738,7 @@ def next(self): cpioinfo = self.proc_member(cpioinfo) - except ValueError, e: + except ValueError as e: if self.offset == 0: raise ReadError("empty, unreadable or compressed " "file: %s" % e) @@ -1794,7 +1794,7 @@ def _getmember(self, name, cpioinfo=None): else: end = members.index(cpioinfo) - for i in xrange(end - 1, -1, -1): + for i in range(end - 1, -1, -1): if name == members[i].name: return members[i] @@ -1803,7 +1803,7 @@ def _load(self): members. """ while True: - cpioinfo = self.next() + cpioinfo = next(self) if cpioinfo is None: break self._loaded = True @@ -1829,10 +1829,10 @@ def _dbg(self, level, msg): """Write debugging output to sys.stderr. """ if level <= self.debug: - print >> sys.stderr, msg + print(msg, file=sys.stderr) # class CpioFile -class CpioIter(object): +class CpioIter(six.Iterator): """Iterator Class. for cpioinfo in CpioFile(...): @@ -1848,7 +1848,7 @@ def __iter__(self): """Return iterator object. """ return self - def next(self): + def __next__(self): """Return the next item using CpioFile's next() method. When all members have been read, set CpioFile as _loaded. """ @@ -1856,7 +1856,7 @@ def next(self): # happen that getmembers() is called during iteration, # which will cause CpioIter to stop prematurely. if not self.cpiofile._loaded: - cpioinfo = self.cpiofile.next() + cpioinfo = next(self.cpiofile) if not cpioinfo: self.cpiofile._loaded = True raise StopIteration @@ -1891,10 +1891,9 @@ def __init__(self, fpath, mode="r", compression=CPIO_PLAIN): m.file_size = m.size m.date_time = time.gmtime(m.mtime)[:6] def namelist(self): - return map(lambda m: m.name, self.infolist()) + return [m.name for m in self.infolist()] def infolist(self): - return filter(lambda m: m.isreg(), - self.cpiofile.getmembers()) + return [m for m in self.cpiofile.getmembers() if m.isreg()] def printdir(self): self.cpiofile.list() def testzip(self): @@ -1905,16 +1904,7 @@ def read(self, name): return self.cpiofile.extractfile(self.cpiofile.getmember(name)).read() def write(self, filename, arcname=None, compress_type=None): self.cpiofile.add(filename, arcname) - def writestr(self, zinfo, bts): - try: - from cStringIO import StringIO - except ImportError: - from StringIO import StringIO - import calendar - zinfo.name = zinfo.filename - zinfo.size = zinfo.file_size - zinfo.mtime = calendar.timegm(zinfo.date_time) - self.cpiofile.addfile(zinfo, StringIO(bts)) + # deleted writestr method def close(self): self.cpiofile.close() #class CpioFileCompat diff --git a/xcp/dom0.py b/xcp/dom0.py index f2ca7097..086a683b 100644 --- a/xcp/dom0.py +++ b/xcp/dom0.py @@ -23,9 +23,11 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +from __future__ import absolute_import +from __future__ import division import re -import version +from . import version import sys def default_memory_v2(host_mem_kib): @@ -39,7 +41,7 @@ def default_memory_v2(host_mem_kib): # # Add a bit extra to account for this. # - gb = (host_mem_kib + 256 * 1024) / 1024 / 1024 + gb = (host_mem_kib + 256 * 1024) // 1024 // 1024 if gb < 24: return 752 * 1024 @@ -61,7 +63,7 @@ def default_memory_v3(host_mem_kib): # # Add a bit extra to account for this. # - mb = (host_mem_kib + 256 * 1024) / 1024 + mb = (host_mem_kib + 256 * 1024) // 1024 # Give dom0 1 GiB + 5% of host memory, rounded to 16 MiB, limited to 8 GiB return min(1024 + int(mb * 0.05) & ~0xF, 8192) * 1024 diff --git a/xcp/environ.py b/xcp/environ.py index 27e57323..8223cca8 100644 --- a/xcp/environ.py +++ b/xcp/environ.py @@ -47,8 +47,8 @@ def readInventory(root = '/'): try: fh = open(os.path.join(root, 'etc/xensource-inventory')) - for line in ( x for x in ( y.strip() for y in fh.xreadlines() ) - if not x.startswith('#') ): + for line in (x for x in (y.strip() for y in fh) + if not x.startswith('#')): vals = line.split('=', 1) @@ -59,7 +59,7 @@ def readInventory(root = '/'): d[vals[0]] = vals[1].strip('"\'') - except IOError, e: + except IOError as e: raise InventoryError("Error reading from file '%s'" % (e,)) finally: diff --git a/xcp/mount.py b/xcp/mount.py index 60d191bc..49b0a2e8 100644 --- a/xcp/mount.py +++ b/xcp/mount.py @@ -52,13 +52,13 @@ def mount(dev, mountpoint, options = None, fstype = None, label = None): rc, out, err = xcp.cmd.runCmd(cmd, with_stdout=True, with_stderr=True) if rc != 0: - raise MountException, "out: '%s' err: '%s'" % (out, err) + raise MountException("out: '%s' err: '%s'" % (out, err)) def bindMount(source, mountpoint): cmd = [ '/bin/mount', '--bind', source, mountpoint] rc, out, err = xcp.cmd.runCmd(cmd, with_stdout=True, with_stderr=True) if rc != 0: - raise MountException, "out: '%s' err: '%s'" % (out, err) + raise MountException("out: '%s' err: '%s'" % (out, err)) def umount(mountpoint, force = False): # -d option also removes the loop device (if present) diff --git a/xcp/net/ifrename/dynamic.py b/xcp/net/ifrename/dynamic.py index 62844848..33040ffd 100644 --- a/xcp/net/ifrename/dynamic.py +++ b/xcp/net/ifrename/dynamic.py @@ -104,7 +104,7 @@ def load_and_parse(self): LOG.error("No source of data to parse") return False - except IOError, e: + except IOError as e: LOG.error("IOError while reading file: %s" % (e,)) return False finally: @@ -137,7 +137,7 @@ def load_and_parse(self): if len(entry) != 3: raise ValueError("Expected 3 entries") macpci = MACPCI(entry[0], entry[1], tname=entry[2]) - except (TypeError, ValueError), e: + except (TypeError, ValueError) as e: LOG.warning("Invalid lastboot data entry: %s" % (e,)) continue @@ -149,7 +149,7 @@ def load_and_parse(self): if len(entry) != 3: raise ValueError("Expected 3 entries") macpci = MACPCI(entry[0], entry[1], tname=entry[2]) - except (TypeError, ValueError), e: + except (TypeError, ValueError) as e: LOG.warning("Invalid old data entry: %s" % (e,)) continue self.old.append(macpci) @@ -170,7 +170,7 @@ def generate(self, state): LOG.warning("Discovered physical policy naming quirks in provided " "state. Disabling 'method=ppn' generation") - for target, (method, value) in self.formulae.iteritems(): + for target, (method, value) in self.formulae.items(): if method == "mac": @@ -178,7 +178,7 @@ def generate(self, state): if nic.mac == value: try: rule = MACPCI(nic.mac, nic.pci, tname=target) - except Exception, e: + except Exception as e: LOG.warning("Error creating rule: %s" % (e,)) continue self.rules.append(rule) @@ -199,7 +199,7 @@ def generate(self, state): if nic.ppn == value: try: rule = MACPCI(nic.mac, nic.pci, tname=target) - except Exception, e: + except Exception as e: LOG.warning("Error creating rule: %s" % (e,)) continue self.rules.append(rule) @@ -213,7 +213,7 @@ def generate(self, state): try: nic = pci_sbdfi_to_nic(value, state) rule = MACPCI(nic.mac, nic.pci, tname=target) - except Exception, e: + except Exception as e: LOG.warning("Error creating rule: %s" % (e,)) continue self.rules.append(rule) @@ -226,7 +226,7 @@ def generate(self, state): if nic.label == value: try: rule = MACPCI(nic.mac, nic.pci, tname=target) - except Exception, e: + except Exception as e: LOG.warning("Error creating rule: %s" % (e,)) continue self.rules.append(rule) @@ -257,13 +257,13 @@ def validate(entry): return False MACPCI(entry[0], entry[1], tname=entry[2]) return True - except Exception, e: + except Exception as e: LOG.warning("Failed to validate '%s' because '%s'" % (entry, e)) return False - lastboot = filter(validate, self.lastboot) - old = filter(validate, self.old) + lastboot = [x for x in self.lastboot if validate(x)] + old = [x for x in self.old if validate(x)] try: res += json.dumps({"lastboot": lastboot, "old": old}, @@ -301,7 +301,7 @@ def save(self, header = True): LOG.error("No source of data to parse") return False - except IOError, e: + except IOError as e: LOG.error("IOError while reading file: %s" % (e,)) return False finally: diff --git a/xcp/net/ifrename/logic.py b/xcp/net/ifrename/logic.py index 2328ca54..e2a3484b 100644 --- a/xcp/net/ifrename/logic.py +++ b/xcp/net/ifrename/logic.py @@ -83,12 +83,12 @@ def __rename_nic(nic, name, transactions, cur_state): # Assert that name is valid assert VALID_ETH_NAME.match(name) is not None # Assert that name is not already taken in the current state - assert name not in map(lambda x: x.tname, cur_state) + assert name not in (x.tname for x in cur_state) # Given the previous assert, only un-renamed nics in the current state can # possibly alias the new name aliased = util.get_nic_with_kname( - filter(lambda x: x.tname is None, cur_state), name) + (x for x in cur_state if x.tname is None), name) if aliased is None: # Using this rule will not alias another currently present NIC @@ -325,9 +325,8 @@ def rename_logic( static_rules, if len(multinic_functions): LOG.debug("New multi-nic logic - attempting to re-order") for fn in multinic_functions: - newnics = util.get_nics_with_pci(filter(util.needs_renaming, cur_state), - fn) - orders = sorted(map(lambda x: x.order, newnics)) + newnics = util.get_nics_with_pci((x for x in cur_state if util.needs_renaming(x)), fn) + orders = sorted(x.order for x in newnics) newnics.sort(key = lambda n: n.mac.integer) for nic, neworder in zip(newnics, orders): LOG.debug("NIC '%s' getting new order '%s'" % (nic, neworder)) @@ -336,10 +335,9 @@ def rename_logic( static_rules, # For completely new network cards which we have never seen before, work out # a safe new number to assign it ethnumbers = sorted( - map(lambda x: int(x[3:]), - filter(lambda x: VALID_ETH_NAME.match(x) is not None, - map(lambda x: x.tname or x.kname, - static_rules + cur_state + last_state)))) + int(x[3:]) + for x in (x.tname or x.kname for x in static_rules + cur_state + last_state) + if VALID_ETH_NAME.match(x) is not None) if len(ethnumbers): nextethnum = ethnumbers[-1]+1 else: @@ -352,8 +350,8 @@ def rename_logic( static_rules, key=lambda x: x.order): LOG.info("Renaming brand new nic '%s'" % (nic,)) - if ( VALID_ETH_NAME.match(nic.kname) is not None and - nic.kname not in map(lambda x: x.tname, cur_state) ): + if (VALID_ETH_NAME.match(nic.kname) is not None and + nic.kname not in (x.tname for x in cur_state)): # User has been messing around with state files but not the udev # rules. If the eth name is still free, give it @@ -411,21 +409,20 @@ def rename( static_rules, "'eth'" % (e, )) # Verify no two static rules refer to the same eth name - _ = frozenset( map(lambda x: x.tname, static_rules) ) + _ = frozenset(x.tname for x in static_rules) if len(_) != len(static_rules): raise StaticRuleError("Some static rules alias the same " "eth name") # Verify no two static rules refer to the same mac address - _ = frozenset( map(lambda x: x.mac, static_rules) ) + _ = frozenset(x.mac for x in static_rules) if len(_) != len(static_rules): raise StaticRuleError("Some static rules alias the same MAC " "address") if len(cur_state): # Filter out iBFT NICs - cur_state = filter(lambda x: VALID_IBFT_NAME.match(x.kname) is None, - cur_state) + cur_state = [x for x in cur_state if VALID_IBFT_NAME.match(x.kname) is None] # Verify types and properties of the list for e in cur_state: @@ -445,13 +442,13 @@ def rename( static_rules, # Verify no two entries of current state refer to the same eth name - _ = frozenset( map(lambda x: x.kname, cur_state) ) + _ = frozenset(x.kname for x in cur_state) if len(_) != len(cur_state): raise CurrentStateError("Some entries of current state alias the " "same eth name") # Verify no two entries of current state refer to the same mac address - _ = frozenset( map(lambda x: x.mac, cur_state) ) + _ = frozenset(x.mac for x in cur_state) if len(_) != len(cur_state): raise CurrentStateError("Some entries of current state alias the " "same MAC address") @@ -474,13 +471,13 @@ def rename( static_rules, # Verify no two entries of last state refer to the same eth name - _ = frozenset( map(lambda x: x.tname, last_state) ) + _ = frozenset(x.tname for x in last_state) if len(_) != len(last_state): raise LastStateError("Some entries of last state alias the " "same eth name") # Verify no two entries of last state refer to the same mac address - _ = frozenset( map(lambda x: x.mac, last_state) ) + _ = frozenset(x.mac for x in last_state) if len(_) != len(last_state): raise LastStateError("Some entries of last state alias the " "same MAC address") diff --git a/xcp/net/ifrename/static.py b/xcp/net/ifrename/static.py index 89a77fda..c1b9b100 100644 --- a/xcp/net/ifrename/static.py +++ b/xcp/net/ifrename/static.py @@ -127,7 +127,7 @@ def load_and_parse(self): LOG.error("No source of data to parse") return False - except IOError, e: + except IOError as e: LOG.error("IOError while reading file: %s" % (e,)) return False finally: @@ -175,7 +175,7 @@ def load_and_parse(self): # If we need to guess the method from the value if method == "guess": - for k, v in StaticRules.validators.iteritems(): + for k, v in StaticRules.validators.items(): if v.match(value) is not None: method = k break @@ -222,7 +222,7 @@ def generate(self, state): LOG.warning("Discovered physical policy naming quirks in provided " "state. Disabling 'method=ppn' generation") - for target, (method, value) in self.formulae.iteritems(): + for target, (method, value) in self.formulae.items(): if method == "mac": @@ -230,7 +230,7 @@ def generate(self, state): if nic.mac == value: try: rule = MACPCI(nic.mac, nic.pci, tname=target) - except Exception, e: + except Exception as e: LOG.warning("Error creating rule: %s" % (e,)) continue self.rules.append(rule) @@ -251,7 +251,7 @@ def generate(self, state): if nic.ppn == value: try: rule = MACPCI(nic.mac, nic.pci, tname=target) - except Exception, e: + except Exception as e: LOG.warning("Error creating rule: %s" % (e,)) continue self.rules.append(rule) @@ -265,7 +265,7 @@ def generate(self, state): try: nic = pci_sbdfi_to_nic(value, state) rule = MACPCI(nic.mac, nic.pci, tname=target) - except Exception, e: + except Exception as e: LOG.warning("Error creating rule: %s" % (e,)) continue self.rules.append(rule) @@ -278,7 +278,7 @@ def generate(self, state): if nic.label == value: try: rule = MACPCI(nic.mac, nic.pci, tname=target) - except Exception, e: + except Exception as e: LOG.warning("Error creating rule: %s" % (e,)) continue self.rules.append(rule) @@ -298,8 +298,7 @@ def write(self, header = True): if header: res += SAVE_HEADER - keys = list(set(( x for x in self.formulae.keys() - if x.startswith("eth") ))) + keys = list(set((x for x in self.formulae if x.startswith("eth")))) keys.sort(key=lambda x: int(x[3:])) for target in keys: @@ -340,7 +339,7 @@ def save(self, header = True): LOG.error("No source of data to parse") return False - except IOError, e: + except IOError as e: LOG.error("IOError while reading file: %s" % (e,)) return False finally: diff --git a/xcp/net/ifrename/util.py b/xcp/net/ifrename/util.py index 72c89fa3..0aad71f1 100644 --- a/xcp/net/ifrename/util.py +++ b/xcp/net/ifrename/util.py @@ -50,7 +50,7 @@ def get_nic_with_kname(nics, kname): def tname_free(nics, name): """Check that name is not taken by any nics""" - return name not in map(lambda x: x.tname, nics) + return name not in (x.tname for x in nics) def get_nic_with_mac(nics, mac): """Search for nic with mac""" diff --git a/xcp/net/mac.py b/xcp/net/mac.py index a675a179..47e586c0 100644 --- a/xcp/net/mac.py +++ b/xcp/net/mac.py @@ -57,7 +57,7 @@ def __init__(self, addr): """Constructor""" self.octets = [] - self.integer = -1L + self.integer = -1 if isinstance(addr, (str, unicode)): @@ -88,8 +88,8 @@ def _set_from_str_octets(self, octets): raise ValueError("Expected 6 octets, got %d" % len(octets)) self.octets = [ int(i, 16) for i in octets ] - self.integer = long(sum(t[0] << t[1] for t in - zip(self.octets, xrange(40, -1, -8)))) + self.integer = sum(t[0] << t[1] for t in + zip(self.octets, range(40, -1, -8))) def _set_from_str_quads(self, quads): """Private helper""" @@ -100,8 +100,8 @@ def _set_from_str_quads(self, quads): for quad in ( int(i, 16) for i in quads ): self.octets.extend([(quad >> 8) & 0xff, quad & 0xff]) - self.integer = long(sum(t[0] << t[1] for t in - zip(self.octets, xrange(40, -1, -8)))) + self.integer = sum(t[0] << t[1] for t in + zip(self.octets, range(40, -1, -8))) def is_unicast(self): """is this a unicast address?""" diff --git a/xcp/pci.py b/xcp/pci.py index 8b371152..1c8e081d 100644 --- a/xcp/pci.py +++ b/xcp/pci.py @@ -124,7 +124,7 @@ def __eq__(self, rhs): else: try: return self.integer == PCI(rhs).integer - except StandardError: + except Exception: return NotImplemented def __ne__(self, rhs): @@ -133,7 +133,7 @@ def __ne__(self, rhs): else: try: return self.integer != PCI(rhs).integer - except StandardError: + except Exception: return NotImplemented def __hash__(self): @@ -145,7 +145,7 @@ def __lt__(self, rhs): else: try: return self.integer < PCI(rhs).integer - except StandardError: + except Exception: return NotImplemented def __le__(self, rhs): @@ -154,7 +154,7 @@ def __le__(self, rhs): else: try: return self.integer <= PCI(rhs).integer - except StandardError: + except Exception: return NotImplemented def __gt__(self, rhs): @@ -163,7 +163,7 @@ def __gt__(self, rhs): else: try: return self.integer > PCI(rhs).integer - except StandardError: + except Exception: return NotImplemented def __ge__(self, rhs): @@ -172,7 +172,7 @@ def __ge__(self, rhs): else: try: return self.integer >= PCI(rhs).integer - except StandardError: + except Exception: return NotImplemented @@ -232,7 +232,7 @@ def read(cls): for f in ['/usr/share/hwdata/pci.ids']: if os.path.exists(f): return cls(f) - raise Exception, 'Failed to open PCI database' + raise Exception('Failed to open PCI database') def findVendor(self, vendor): return vendor in self.vendor_dict and self.vendor_dict[vendor] or None @@ -260,8 +260,7 @@ def __init__(self): stdout = subprocess.PIPE) for l in cmd.stdout: line = l.rstrip() - el = filter(lambda x: not x.startswith('-'), - line.replace('"','').split()) + el = [x for x in line.replace('"', '').split() if not x.startswith('-')] self.devs[el[0]] = {'id': el[0], 'class': el[1][:2], 'subclass': el[1][2:], @@ -279,11 +278,10 @@ def findByClass(self, cls, subcls = None): [class1, class2, ... classN]""" if subcls: assert isinstance(cls, str) - return filter(lambda x: x['class'] == cls and - x['subclass'] == subcls, self.devs.values()) + return [x for x in self.devs.values() if x['class'] == cls and x['subclass'] == subcls] else: assert isinstance(cls, list) - return filter(lambda x: x['class'] in cls, self.devs.values()) + return [x for x in self.devs.values() if x['class'] in cls] def findRelatedFunctions(self, dev): """ return other devices that share the same bus & slot""" @@ -291,8 +289,7 @@ def slot(dev): left, _ = dev.rsplit('.', 1) return left - return filter(lambda x: x != dev and slot(x) == slot(dev), - self.devs.keys()) + return [x for x in self.devs if x != dev and slot(x) == slot(dev)] def pci_sbdfi_to_nic(sbdfi, nics): diff --git a/xcp/repository.py b/xcp/repository.py index 3da2f17b..ca284647 100644 --- a/xcp/repository.py +++ b/xcp/repository.py @@ -28,10 +28,12 @@ import xml.dom.minidom import ConfigParser +import six + import xcp.version as version import xcp.xmlunwrap as xmlunwrap -class Package: +class Package(object): # pylint: disable=too-few-public-methods pass class BzippedPackage(Package): @@ -44,7 +46,7 @@ def __init__(self, repository, label, size, md5sum, optional, fname, root): self.optional, self.filename, self.destination - ) = ( repository, label, long(size), md5sum, (optional==True), fname, root ) + ) = (repository, label, size, md5sum, optional is True, fname, root) def __repr__(self): return "" % self.label @@ -59,7 +61,7 @@ def __init__(self, repository, label, size, md5sum, optional, fname, options): self.optional, self.filename, self.options - ) = ( repository, label, long(size), md5sum, (optional==True), fname, options ) + ) = (repository, label, size, md5sum, optional is True, fname, options) def __repr__(self): return "" % self.label @@ -74,7 +76,7 @@ def __init__(self, repository, label, size, md5sum, fname, kernel, options): self.filename, self.kernel, self.options - ) = ( repository, label, long(size), md5sum, fname, kernel, options ) + ) = (repository, label, size, md5sum, fname, kernel, options) def __repr__(self): return "" % (self.label, self.kernel) @@ -88,7 +90,7 @@ def __init__(self, repository, label, size, md5sum, fname, root): self.md5sum, self.filename, self.destination - ) = ( repository, label, long(size), md5sum, fname, root ) + ) = (repository, label, size, md5sum, fname, root) def __repr__(self): return "" % self.label @@ -101,7 +103,7 @@ def __init__(self, repository, label, size, md5sum, fname): self.size, self.md5sum, self.filename - ) = ( repository, label, long(size), md5sum, fname ) + ) = (repository, label, size, md5sum, fname) def __repr__(self): return "" % self.label @@ -168,8 +170,8 @@ def __init__(self, access, base = ""): def isRepo(cls, access, base): """ Return whether there is a repository at base address 'base' accessible using accessor.""" - return False not in map(lambda x: access.access(os.path.join(base, x)), - [cls.TREEINFO_FILENAME, cls.REPOMD_FILENAME]) + return False not in (access.access(os.path.join(base, x)) + for x in [cls.TREEINFO_FILENAME, cls.REPOMD_FILENAME]) @classmethod def _getVersion(cls, access, category): @@ -187,8 +189,9 @@ def _getVersion(cls, access, category): ver_str = treeinfo.get(category, 'version') repo_ver = version.Version.from_string(ver_str) - except Exception, e: - raise RepoFormatError, "Failed to open %s: %s" % (cls.TREEINFO_FILENAME, str(e)) + except Exception as e: + six.raise_from(RepoFormatError("Failed to open %s: %s" % + (cls.TREEINFO_FILENAME, str(e))), e) access.finish() return repo_ver @@ -230,8 +233,9 @@ def findRepositories(cls, access): for line in extra: package_list.append(line.strip()) extra.close() - except Exception, e: - raise RepoFormatError, "Failed to open %s: %s" % (cls.REPOLIST_FILENAME, str(e)) + except Exception as e: + six.raise_from(RepoFormatError("Failed to open %s: %s" % + (cls.REPOLIST_FILENAME, str(e))), e) for loc in package_list: if cls.isRepo(access, loc): @@ -250,17 +254,17 @@ def __init__(self, access, base, is_group = False): try: repofile = access.openAddress(os.path.join(base, self.REPOSITORY_FILENAME)) - except Exception, e: + except Exception as e: access.finish() - raise NoRepository, e + six.raise_from(NoRepository(), e) self._parse_repofile(repofile) repofile.close() try: pkgfile = access.openAddress(os.path.join(base, self.PKGDATA_FILENAME)) - except Exception, e: + except Exception as e: access.finish() - raise NoRepository, e + six.raise_from(NoRepository(), e) self._parse_packages(pkgfile) pkgfile.close() @@ -289,8 +293,8 @@ def _parse_repofile(self, repofile): # build xml doc object try: xmldoc = xml.dom.minidom.parseString(repofile_contents) - except: - raise RepoFormatError, "%s not in XML" % self.REPOSITORY_FILENAME + except Exception as e: + six.raise_from(RepoFormatError("%s not in XML" % self.REPOSITORY_FILENAME), e) try: repo_node = xmlunwrap.getElementsByTagName(xmldoc, ['repository'], mandatory = True) @@ -313,8 +317,8 @@ def _parse_repofile(self, repofile): del req['build'] assert req['test'] in self.OPER_MAP self.requires.append(req) - except: - raise RepoFormatError, "%s format error" % self.REPOSITORY_FILENAME + except Exception as e: + six.raise_from(RepoFormatError("%s format error" % self.REPOSITORY_FILENAME), e) self.identifier = "%s:%s" % (self.originator, self.name) ver_str = self.version @@ -332,8 +336,8 @@ def _parse_packages(self, pkgfile): # build xml doc object try: xmldoc = xml.dom.minidom.parseString(pkgfile_contents) - except: - raise RepoFormatError, "%s not in XML" % self.PKGDATA_FILENAME + except Exception as e: + six.raise_from(RepoFormatError("%s not in XML" % self.PKGDATA_FILENAME), e) for pkg_node in xmlunwrap.getElementsByTagName(xmldoc, ['package']): pkg = self._create_package(pkg_node) @@ -364,8 +368,8 @@ def _create_package(self, node): def isRepo(cls, access, base): """ Return whether there is a repository at base address 'base' accessible using accessor.""" - return False not in map(lambda x: access.access(os.path.join(base, x)), - [cls.REPOSITORY_FILENAME, cls.PKGDATA_FILENAME]) + return False not in (access.access(os.path.join(base, x)) + for x in [cls.REPOSITORY_FILENAME, cls.PKGDATA_FILENAME]) @classmethod def getRepoVer(cls, access): diff --git a/xcp/version.py b/xcp/version.py index aaa7fcd6..e19d3c96 100644 --- a/xcp/version.py +++ b/xcp/version.py @@ -25,7 +25,7 @@ """version - version comparison methods""" -class Version: +class Version(object): def __init__(self, ver, build = None): self.ver = ver self.build = build @@ -52,7 +52,7 @@ def from_string(cls, ver_str): if '-' in ver_str: ver_str, build = ver_str.split('-', 1) - ver = map(cls.intify, ver_str.split('.')) + ver = [cls.intify(i) for i in ver_str.split('.')] return cls(ver, build) diff --git a/xcp/xmlunwrap.py b/xcp/xmlunwrap.py index 654b84bf..1487afab 100644 --- a/xcp/xmlunwrap.py +++ b/xcp/xmlunwrap.py @@ -23,6 +23,8 @@ """xmlunwrap - general methods to unwrap XML elements & attributes""" +import six + class XmlUnwrapError(Exception): pass @@ -39,7 +41,7 @@ def getElementsByTagName(el, tags, mandatory = False): for tag in tags: matching.extend(el.getElementsByTagName(tag)) if mandatory and len(matching) == 0: - raise XmlUnwrapError, "Missing mandatory element %s" % tags[0] + raise XmlUnwrapError("Missing mandatory element %s" % tags[0]) return matching def getStrAttribute(el, attrs, default = '', mandatory = False): @@ -50,7 +52,7 @@ def getStrAttribute(el, attrs, default = '', mandatory = False): matching.append(val) if len(matching) == 0: if mandatory: - raise XmlUnwrapError, "Missing mandatory attribute %s" % attrs[0] + raise XmlUnwrapError("Missing mandatory attribute %s" % attrs[0]) return default return matching[0] @@ -68,8 +70,8 @@ def getIntAttribute(el, attrs, default = None): return default try: int_val = int(val, 0) - except: - raise XmlUnwrapError, "Invalid integer value for %s" % attrs[0] + except Exception as e: + six.raise_from(XmlUnwrapError("Invalid integer value for %s" % attrs[0]), e) return int_val def getMapAttribute(el, attrs, mapping, default = None): @@ -78,7 +80,7 @@ def getMapAttribute(el, attrs, mapping, default = None): key = getStrAttribute(el, attrs, default, mandatory) if key not in k: - raise XmlUnwrapError, "Unexpected key %s for attribute" % key + raise XmlUnwrapError("Unexpected key %s for attribute" % key) k_list = list(k) return v[k_list.index(key)]